gemi 0.58.1 → 0.60.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (231) hide show
  1. package/dist/ai/Agent.d.ts +33 -0
  2. package/dist/ai/Agent.d.ts.map +1 -0
  3. package/dist/ai/AgentController.d.ts +8 -0
  4. package/dist/ai/AgentController.d.ts.map +1 -0
  5. package/dist/ai/useChat.d.ts +12 -0
  6. package/dist/ai/useChat.d.ts.map +1 -0
  7. package/dist/app/index.js +1 -1
  8. package/dist/bin/gemi.js +500 -16
  9. package/dist/bin/gemi.js.map +10 -5
  10. package/dist/broadcasting/index.js +1 -1
  11. package/dist/bun/plugin.js +1 -1
  12. package/dist/bun/preload.js +1 -1
  13. package/dist/{chunk-szss069z.js → chunk-06j6rsew.js} +2 -2
  14. package/dist/{chunk-szss069z.js.map → chunk-06j6rsew.js.map} +1 -1
  15. package/dist/{chunk-yjzs247s.js → chunk-0fm6jh9b.js} +2 -2
  16. package/dist/{chunk-yjzs247s.js.map → chunk-0fm6jh9b.js.map} +1 -1
  17. package/dist/chunk-23h0dmx2.js +5 -0
  18. package/dist/{chunk-87qab82w.js.map → chunk-23h0dmx2.js.map} +3 -3
  19. package/dist/{chunk-m3xy5xyf.js → chunk-2cwcfwg3.js} +2 -2
  20. package/dist/{chunk-m3xy5xyf.js.map → chunk-2cwcfwg3.js.map} +1 -1
  21. package/dist/{chunk-xzk827r3.js → chunk-2khdxyjb.js} +2 -2
  22. package/dist/{chunk-xzk827r3.js.map → chunk-2khdxyjb.js.map} +1 -1
  23. package/dist/{chunk-sy7jbdeb.js → chunk-3296fwss.js} +2 -2
  24. package/dist/{chunk-sy7jbdeb.js.map → chunk-3296fwss.js.map} +1 -1
  25. package/dist/{chunk-xdv1b8mr.js → chunk-3gvjn3q4.js} +2 -2
  26. package/dist/{chunk-xdv1b8mr.js.map → chunk-3gvjn3q4.js.map} +1 -1
  27. package/dist/{chunk-jhkjz9jr.js → chunk-4dan69s4.js} +2 -2
  28. package/dist/{chunk-3zxwscmf.js.map → chunk-4dan69s4.js.map} +1 -1
  29. package/dist/{chunk-hxf1re93.js → chunk-4mcyyh1v.js} +2 -2
  30. package/dist/{chunk-hxf1re93.js.map → chunk-4mcyyh1v.js.map} +1 -1
  31. package/dist/{chunk-w62m5f0n.js → chunk-5gdv4n4a.js} +3 -3
  32. package/dist/{chunk-w62m5f0n.js.map → chunk-5gdv4n4a.js.map} +1 -1
  33. package/dist/{chunk-j0c6ytkj.js → chunk-8kj3zrm9.js} +3 -3
  34. package/dist/{chunk-j0c6ytkj.js.map → chunk-8kj3zrm9.js.map} +1 -1
  35. package/dist/{chunk-0a2xgcj3.js → chunk-98a3k7bp.js} +2 -2
  36. package/dist/{chunk-0a2xgcj3.js.map → chunk-98a3k7bp.js.map} +1 -1
  37. package/dist/{chunk-5athahgr.js → chunk-9gsdcjt7.js} +2 -2
  38. package/dist/{chunk-5athahgr.js.map → chunk-9gsdcjt7.js.map} +1 -1
  39. package/dist/{chunk-pmhd6zfc.js → chunk-b0t4zp6b.js} +2 -2
  40. package/dist/{chunk-pmhd6zfc.js.map → chunk-b0t4zp6b.js.map} +1 -1
  41. package/dist/{chunk-3xadx444.js → chunk-bn1v4sfs.js} +2 -2
  42. package/dist/{chunk-3xadx444.js.map → chunk-bn1v4sfs.js.map} +1 -1
  43. package/dist/{chunk-9m2tbf3n.js → chunk-c40n5r4v.js} +2 -2
  44. package/dist/{chunk-9m2tbf3n.js.map → chunk-c40n5r4v.js.map} +1 -1
  45. package/dist/{chunk-a2sgjpvq.js → chunk-cejf873g.js} +2 -2
  46. package/dist/{chunk-a2sgjpvq.js.map → chunk-cejf873g.js.map} +1 -1
  47. package/dist/{chunk-tss5svjr.js → chunk-cw9y6k15.js} +2 -2
  48. package/dist/{chunk-tss5svjr.js.map → chunk-cw9y6k15.js.map} +1 -1
  49. package/dist/{chunk-5n2rvfh3.js → chunk-cyrxdj6a.js} +2 -2
  50. package/dist/{chunk-5n2rvfh3.js.map → chunk-cyrxdj6a.js.map} +1 -1
  51. package/dist/chunk-dgasxgsm.js +19 -0
  52. package/dist/{chunk-hwa5sqw5.js.map → chunk-dgasxgsm.js.map} +6 -6
  53. package/dist/{chunk-3g5bjvdf.js → chunk-f6dd4gd8.js} +2 -2
  54. package/dist/{chunk-3g5bjvdf.js.map → chunk-f6dd4gd8.js.map} +1 -1
  55. package/dist/{chunk-qgxr0g36.js → chunk-fb4cy6sq.js} +2 -2
  56. package/dist/{chunk-qgxr0g36.js.map → chunk-fb4cy6sq.js.map} +1 -1
  57. package/dist/{chunk-7ef5n8k2.js → chunk-fbvvqf9b.js} +2 -2
  58. package/dist/{chunk-7ef5n8k2.js.map → chunk-fbvvqf9b.js.map} +1 -1
  59. package/dist/{chunk-zbxgbr12.js → chunk-fxy42w6n.js} +2 -2
  60. package/dist/{chunk-zbxgbr12.js.map → chunk-fxy42w6n.js.map} +1 -1
  61. package/dist/{chunk-xey9cbap.js → chunk-get4mkx8.js} +2 -2
  62. package/dist/{chunk-xey9cbap.js.map → chunk-get4mkx8.js.map} +1 -1
  63. package/dist/{chunk-3zxwscmf.js → chunk-gwchvzdp.js} +2 -2
  64. package/dist/{chunk-jhkjz9jr.js.map → chunk-gwchvzdp.js.map} +1 -1
  65. package/dist/{chunk-k0fvsyeh.js → chunk-hsfjt13m.js} +1 -1
  66. package/dist/{chunk-yf7vz71n.js → chunk-hwhw98hc.js} +1 -1
  67. package/dist/{chunk-fjm4y8bn.js → chunk-hxb1eg2z.js} +2 -2
  68. package/dist/{chunk-fjm4y8bn.js.map → chunk-hxb1eg2z.js.map} +1 -1
  69. package/dist/{chunk-7b0x860b.js → chunk-j06g4sqc.js} +2 -2
  70. package/dist/{chunk-7b0x860b.js.map → chunk-j06g4sqc.js.map} +1 -1
  71. package/dist/{chunk-dgsgjg53.js → chunk-j23cengk.js} +2 -2
  72. package/dist/{chunk-dgsgjg53.js.map → chunk-j23cengk.js.map} +1 -1
  73. package/dist/{chunk-vj6f2bmb.js → chunk-khf9xda6.js} +3 -3
  74. package/dist/{chunk-vj6f2bmb.js.map → chunk-khf9xda6.js.map} +1 -1
  75. package/dist/{chunk-437085pe.js → chunk-p3qd0gqa.js} +2 -2
  76. package/dist/{chunk-437085pe.js.map → chunk-p3qd0gqa.js.map} +1 -1
  77. package/dist/{chunk-gw6agevz.js → chunk-pkjq9833.js} +3 -3
  78. package/dist/{chunk-gw6agevz.js.map → chunk-pkjq9833.js.map} +1 -1
  79. package/dist/{chunk-7j6wbv12.js → chunk-q0y0j3ne.js} +2 -2
  80. package/dist/{chunk-7j6wbv12.js.map → chunk-q0y0j3ne.js.map} +1 -1
  81. package/dist/chunk-q6qghsy7.js +5 -0
  82. package/dist/{chunk-b35e128b.js.map → chunk-q6qghsy7.js.map} +1 -1
  83. package/dist/{chunk-wbrj0gya.js → chunk-qva4841r.js} +2 -2
  84. package/dist/{chunk-wbrj0gya.js.map → chunk-qva4841r.js.map} +1 -1
  85. package/dist/{chunk-86jebsm4.js → chunk-rkbv3df7.js} +3 -3
  86. package/dist/{chunk-86jebsm4.js.map → chunk-rkbv3df7.js.map} +1 -1
  87. package/dist/{chunk-keehyx51.js → chunk-rpjsmr41.js} +2 -2
  88. package/dist/{chunk-keehyx51.js.map → chunk-rpjsmr41.js.map} +1 -1
  89. package/dist/{chunk-mwpdp09e.js → chunk-spbgpndn.js} +2 -2
  90. package/dist/{chunk-mwpdp09e.js.map → chunk-spbgpndn.js.map} +1 -1
  91. package/dist/{chunk-yy0eb9wn.js → chunk-stq96kya.js} +2 -2
  92. package/dist/{chunk-yy0eb9wn.js.map → chunk-stq96kya.js.map} +1 -1
  93. package/dist/{chunk-d125j8t0.js → chunk-tds3xq6b.js} +3 -3
  94. package/dist/{chunk-d125j8t0.js.map → chunk-tds3xq6b.js.map} +1 -1
  95. package/dist/{chunk-3337e5g0.js → chunk-tey1xayb.js} +2 -2
  96. package/dist/{chunk-3337e5g0.js.map → chunk-tey1xayb.js.map} +1 -1
  97. package/dist/{chunk-w7rf99w6.js → chunk-vj9538yn.js} +2 -2
  98. package/dist/{chunk-w7rf99w6.js.map → chunk-vj9538yn.js.map} +1 -1
  99. package/dist/{chunk-yed5whgs.js → chunk-wcv6qtpq.js} +3 -3
  100. package/dist/{chunk-yed5whgs.js.map → chunk-wcv6qtpq.js.map} +1 -1
  101. package/dist/{chunk-vr90r27j.js → chunk-wzvs3sym.js} +2 -2
  102. package/dist/{chunk-vr90r27j.js.map → chunk-wzvs3sym.js.map} +1 -1
  103. package/dist/{chunk-cyaz97p5.js → chunk-x6y1z4cq.js} +2 -2
  104. package/dist/{chunk-cyaz97p5.js.map → chunk-x6y1z4cq.js.map} +1 -1
  105. package/dist/chunk-x8beq9c4.js +55 -0
  106. package/dist/chunk-x8beq9c4.js.map +11 -0
  107. package/dist/{chunk-6235kb30.js → chunk-xecj8025.js} +3 -3
  108. package/dist/{chunk-6235kb30.js.map → chunk-xecj8025.js.map} +1 -1
  109. package/dist/chunk-y3zz410b.js +6 -0
  110. package/dist/{chunk-4sz6pwtn.js.map → chunk-y3zz410b.js.map} +2 -2
  111. package/dist/{chunk-eejmhtnc.js → chunk-y64j80v9.js} +2 -2
  112. package/dist/{chunk-eejmhtnc.js.map → chunk-y64j80v9.js.map} +1 -1
  113. package/dist/{chunk-zh2egcyb.js → chunk-ygfwtgvm.js} +2 -2
  114. package/dist/{chunk-zh2egcyb.js.map → chunk-ygfwtgvm.js.map} +1 -1
  115. package/dist/{chunk-4yt5x8s2.js → chunk-ys904esh.js} +2 -2
  116. package/dist/{chunk-4yt5x8s2.js.map → chunk-ys904esh.js.map} +1 -1
  117. package/dist/{chunk-y6a8r2bn.js → chunk-z1e55w67.js} +3 -3
  118. package/dist/{chunk-y6a8r2bn.js.map → chunk-z1e55w67.js.map} +1 -1
  119. package/dist/{chunk-qb5mv6pj.js → chunk-z2tcxwyr.js} +3 -3
  120. package/dist/{chunk-qb5mv6pj.js.map → chunk-z2tcxwyr.js.map} +1 -1
  121. package/dist/{chunk-hppagzz4.js → chunk-zhbrkpb3.js} +4 -4
  122. package/dist/{chunk-hppagzz4.js.map → chunk-zhbrkpb3.js.map} +1 -1
  123. package/dist/{chunk-grdahng8.js → chunk-zqsfanvk.js} +2 -2
  124. package/dist/{chunk-grdahng8.js.map → chunk-zqsfanvk.js.map} +1 -1
  125. package/dist/config/index.d.ts +2 -0
  126. package/dist/config/index.d.ts.map +1 -1
  127. package/dist/config/index.js +2 -2
  128. package/dist/config/index.js.map +3 -3
  129. package/dist/console/run.js +2 -2
  130. package/dist/console/run.js.map +1 -1
  131. package/dist/container/index.js +2 -2
  132. package/dist/container/index.js.map +1 -1
  133. package/dist/database/index.js +2 -2
  134. package/dist/database/index.js.map +1 -1
  135. package/dist/email/index.js +2 -2
  136. package/dist/email/index.js.map +1 -1
  137. package/dist/facades/Features.d.ts +67 -1
  138. package/dist/facades/Features.d.ts.map +1 -1
  139. package/dist/facades/index.js +2 -2
  140. package/dist/facades/index.js.map +1 -1
  141. package/dist/foundation/index.js +2 -2
  142. package/dist/foundation/index.js.map +1 -1
  143. package/dist/http/index.js +2 -2
  144. package/dist/http/index.js.map +1 -1
  145. package/dist/i18n/dictionaryRuntime.js +2 -2
  146. package/dist/i18n/dictionaryRuntime.js.map +1 -1
  147. package/dist/i18n/index.js +2 -2
  148. package/dist/i18n/index.js.map +2 -2
  149. package/dist/kernel/index.js +2 -2
  150. package/dist/kernel/index.js.map +1 -1
  151. package/dist/orm/index.js +2 -2
  152. package/dist/orm/index.js.map +1 -1
  153. package/dist/server/Server.d.ts.map +1 -1
  154. package/dist/server/httpDev.d.ts.map +1 -1
  155. package/dist/server/index.js +2 -2
  156. package/dist/server/index.js.map +3 -3
  157. package/dist/services/events/Event.d.ts +6 -0
  158. package/dist/services/events/Event.d.ts.map +1 -1
  159. package/dist/services/features/FeatureFlagStore.d.ts +56 -0
  160. package/dist/services/features/FeatureFlagStore.d.ts.map +1 -1
  161. package/dist/services/features/FeatureManager.d.ts +35 -1
  162. package/dist/services/features/FeatureManager.d.ts.map +1 -1
  163. package/dist/services/features/types.d.ts +62 -0
  164. package/dist/services/features/types.d.ts.map +1 -1
  165. package/dist/services/index.d.ts +2 -2
  166. package/dist/services/index.d.ts.map +1 -1
  167. package/dist/services/index.js +8 -8
  168. package/dist/services/index.js.map +3 -3
  169. package/dist/services/logging/LogManager.d.ts +10 -1
  170. package/dist/services/logging/LogManager.d.ts.map +1 -1
  171. package/dist/services/logging/LogServiceProvider.d.ts +10 -0
  172. package/dist/services/logging/LogServiceProvider.d.ts.map +1 -1
  173. package/dist/support/index.js +2 -2
  174. package/dist/support/index.js.map +1 -1
  175. package/package.json +3 -2
  176. package/skills/gemi-react-best-practices/SKILL.md +231 -0
  177. package/skills/gemi-react-best-practices/rules/_sections.md +56 -0
  178. package/skills/gemi-react-best-practices/rules/_template.md +28 -0
  179. package/skills/gemi-react-best-practices/rules/bundle-deep-imports.md +48 -0
  180. package/skills/gemi-react-best-practices/rules/bundle-mount-gate-heavy-panels.md +63 -0
  181. package/skills/gemi-react-best-practices/rules/client-form-vs-mutation-hooks.md +57 -0
  182. package/skills/gemi-react-best-practices/rules/client-loading-error-exports.md +54 -0
  183. package/skills/gemi-react-best-practices/rules/client-no-effect-data-flow.md +68 -0
  184. package/skills/gemi-react-best-practices/rules/client-typed-links.md +51 -0
  185. package/skills/gemi-react-best-practices/rules/controller-authorize-every-tenant-read.md +65 -0
  186. package/skills/gemi-react-best-practices/rules/controller-parse-request-at-the-boundary.md +54 -0
  187. package/skills/gemi-react-best-practices/rules/controller-redirect-facade-throws.md +68 -0
  188. package/skills/gemi-react-best-practices/rules/controller-request-schema.md +61 -0
  189. package/skills/gemi-react-best-practices/rules/controller-throw-framework-errors.md +57 -0
  190. package/skills/gemi-react-best-practices/rules/i18n-define-dictionary-inline.md +58 -0
  191. package/skills/gemi-react-best-practices/rules/orm-analytics-connection.md +53 -0
  192. package/skills/gemi-react-best-practices/rules/orm-include-not-n-plus-one.md +56 -0
  193. package/skills/gemi-react-best-practices/rules/orm-paginate-helper.md +69 -0
  194. package/skills/gemi-react-best-practices/rules/orm-plain-rows-by-default.md +55 -0
  195. package/skills/gemi-react-best-practices/rules/orm-select-narrow.md +58 -0
  196. package/skills/gemi-react-best-practices/rules/orm-transaction-no-io.md +54 -0
  197. package/skills/gemi-react-best-practices/rules/orm-transaction-sequential.md +64 -0
  198. package/skills/gemi-react-best-practices/rules/payload-dont-overprefetch.md +54 -0
  199. package/skills/gemi-react-best-practices/rules/payload-instant-vs-prefetch.md +58 -0
  200. package/skills/gemi-react-best-practices/rules/payload-minimal-view-props.md +51 -0
  201. package/skills/gemi-react-best-practices/rules/payload-parallel-controller-work.md +56 -0
  202. package/skills/gemi-react-best-practices/rules/payload-prefetch-late-queries.md +58 -0
  203. package/skills/gemi-react-best-practices/rules/payload-prefetch-mirrors-usequery.md +52 -0
  204. package/skills/gemi-react-best-practices/rules/query-debounce-search-variant.md +52 -0
  205. package/skills/gemi-react-best-practices/rules/query-keep-previous-data.md +40 -0
  206. package/skills/gemi-react-best-practices/rules/query-lazy-vs-mount-gate.md +54 -0
  207. package/skills/gemi-react-best-practices/rules/query-mutate-over-refetch.md +55 -0
  208. package/skills/gemi-react-best-practices/rules/query-no-hand-rolled-fetch.md +60 -0
  209. package/skills/gemi-react-best-practices/rules/query-revalidate-on-focus.md +44 -0
  210. package/skills/gemi-react-best-practices/rules/query-share-cache-key.md +51 -0
  211. package/skills/gemi-react-best-practices/rules/query-suspense-default.md +52 -0
  212. package/skills/gemi-react-best-practices/rules/routing-cache-policy-constants.md +53 -0
  213. package/skills/gemi-react-best-practices/rules/routing-middleware-dsl.md +60 -0
  214. package/skills/gemi-react-best-practices/rules/routing-resource-routes.md +59 -0
  215. package/skills/gemi-react-best-practices/rules/routing-routers-are-classes.md +55 -0
  216. package/skills/gemi-react-best-practices/rules/service-lazy-not-module-scope.md +63 -0
  217. package/skills/gemi-react-best-practices/rules/service-queue-is-in-memory.md +52 -0
  218. package/skills/gemi-react-best-practices/rules/service-static-token-and-name.md +52 -0
  219. package/skills/gemi-react-best-practices/rules/structure-discovered-vs-registered.md +71 -0
  220. package/skills/gemi-react-best-practices/rules/structure-do-not-reinvent-the-framework.md +58 -0
  221. package/skills/gemi-react-best-practices/rules/testing-assert-behaviour-over-markup.md +54 -0
  222. package/skills/gemi-react-best-practices/rules/testing-match-the-suite.md +57 -0
  223. package/skills/gemi-react-best-practices/rules/testing-page-seeds-real-inputs.md +65 -0
  224. package/dist/chunk-01e3gk86.js +0 -55
  225. package/dist/chunk-01e3gk86.js.map +0 -11
  226. package/dist/chunk-4sz6pwtn.js +0 -6
  227. package/dist/chunk-87qab82w.js +0 -5
  228. package/dist/chunk-b35e128b.js +0 -5
  229. package/dist/chunk-hwa5sqw5.js +0 -19
  230. /package/dist/{chunk-k0fvsyeh.js.map → chunk-hsfjt13m.js.map} +0 -0
  231. /package/dist/{chunk-yf7vz71n.js.map → chunk-hwhw98hc.js.map} +0 -0
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{P as re}from"./chunk-tss5svjr.js";import{Ef as _,Hf as a}from"./chunk-jhkjz9jr.js";var I=_((b)=>{Object.defineProperty(b,"__esModule",{value:!0});b.getHomeDir=void 0;var W=a("os"),V=a("path"),x={},G=()=>{if(process&&process.geteuid)return`${process.geteuid()}`;return"DEFAULT"},U=()=>{let{HOME:e,USERPROFILE:t,HOMEPATH:r,HOMEDRIVE:o=`C:${V.sep}`}=process.env;if(e)return e;if(t)return t;if(r)return`${o}${r}`;let i=G();if(!x[i])x[i]=(0,W.homedir)();return x[i]};b.getHomeDir=U});var P=_((j)=>{Object.defineProperty(j,"__esModule",{value:!0});j.getSSOTokenFilepath=void 0;var X=a("crypto"),B=a("path"),J=I(),z=(e)=>{let r=(0,X.createHash)("sha1").update(e).digest("hex");return(0,B.join)((0,J.getHomeDir)(),".aws","sso","cache",`${r}.json`)};j.getSSOTokenFilepath=z});var R=_((C)=>{Object.defineProperty(C,"__esModule",{value:!0});C.getSSOTokenFromFile=C.tokenIntercept=void 0;var Q=a("fs/promises"),Y=P();C.tokenIntercept={};var Z=async(e)=>{if(C.tokenIntercept[e])return C.tokenIntercept[e];let t=(0,Y.getSSOTokenFilepath)(e),r=await(0,Q.readFile)(t,"utf8");return JSON.parse(r)};C.getSSOTokenFromFile=Z});var k=_((L)=>{Object.defineProperty(L,"__esModule",{value:!0});L.readFile=L.fileIntercept=L.filePromises=void 0;var ee=a("fs/promises");L.filePromises={};L.fileIntercept={};var te=(e,t)=>{if(L.fileIntercept[e]!==void 0)return L.fileIntercept[e];if(!L.filePromises[e]||t?.ignoreCache)L.filePromises[e]=(0,ee.readFile)(e,"utf8");return L.filePromises[e]};L.readFile=te});var ye=_((c)=>{var l=I(),O=P(),y=R(),g=a("path"),S=re(),f=k(),q="AWS_PROFILE",$="default",oe=(e)=>e.profile||process.env[q]||$,p=".",ie=(e)=>Object.entries(e).filter(([t])=>{let r=t.indexOf(p);if(r===-1)return!1;return Object.values(S.IniSectionType).includes(t.substring(0,r))}).reduce((t,[r,o])=>{let i=r.indexOf(p),n=r.substring(0,i)===S.IniSectionType.PROFILE?r.substring(i+1):r;return t[n]=o,t},{...e.default&&{default:e.default}}),ne="AWS_CONFIG_FILE",M=()=>process.env[ne]||g.join(l.getHomeDir(),".aws","config"),se="AWS_SHARED_CREDENTIALS_FILE",ce=()=>process.env[se]||g.join(l.getHomeDir(),".aws","credentials"),ae=/^([\w-]+)\s(["'])?([\w-@\+\.%:/]+)\2$/,le=["__proto__","profile __proto__"],T=(e)=>{let t={},r,o;for(let i of e.split(/\r?\n/)){let n=i.split(/(^|\s)[;#]/)[0].trim();if(n[0]==="["&&n[n.length-1]==="]"){r=void 0,o=void 0;let s=n.substring(1,n.length-1),u=ae.exec(s);if(u){let[,d,,m]=u;if(Object.values(S.IniSectionType).includes(d))r=[d,m].join(p)}else r=s;if(le.includes(s))throw Error(`Found invalid profile name "${s}"`)}else if(r){let s=n.indexOf("=");if(![0,-1].includes(s)){let[u,d]=[n.substring(0,s).trim(),n.substring(s+1).trim()];if(d==="")o=u;else{if(o&&i.trimStart()===i)o=void 0;t[r]=t[r]||{};let m=o?[o,u].join(p):u;t[r][m]=d}}}}return t},A=()=>({}),K=async(e={})=>{let{filepath:t=ce(),configFilepath:r=M()}=e,o=l.getHomeDir(),i="~/",n=t;if(t.startsWith("~/"))n=g.join(o,t.slice(2));let h=r;if(r.startsWith("~/"))h=g.join(o,r.slice(2));let s=await Promise.all([f.readFile(h,{ignoreCache:e.ignoreCache}).then(T).then(ie).catch(A),f.readFile(n,{ignoreCache:e.ignoreCache}).then(T).catch(A)]);return{configFile:s[0],credentialsFile:s[1]}},pe=(e)=>Object.entries(e).filter(([t])=>t.startsWith(S.IniSectionType.SSO_SESSION+p)).reduce((t,[r,o])=>({...t,[r.substring(r.indexOf(p)+1)]:o}),{}),ue=()=>({}),fe=async(e={})=>f.readFile(e.configFilepath??M()).then(T).then(pe).catch(ue),de=(...e)=>{let t={};for(let r of e)for(let[o,i]of Object.entries(r))if(t[o]!==void 0)Object.assign(t[o],i);else t[o]=i;return t},_e=async(e)=>{let t=await K(e);return de(t.configFile,t.credentialsFile)},Fe={getFileRecord(){return f.fileIntercept},interceptFile(e,t){f.fileIntercept[e]=Promise.resolve(t)},getTokenRecord(){return y.tokenIntercept},interceptToken(e,t){y.tokenIntercept[e]=t}};c.getSSOTokenFromFile=y.getSSOTokenFromFile;c.readFile=f.readFile;c.CONFIG_PREFIX_SEPARATOR=p;c.DEFAULT_PROFILE=$;c.ENV_PROFILE=q;c.externalDataInterceptor=Fe;c.getProfileName=oe;c.loadSharedConfigFiles=K;c.loadSsoSessionData=fe;c.parseKnownFiles=_e;Object.prototype.hasOwnProperty.call(l,"__proto__")&&!Object.prototype.hasOwnProperty.call(c,"__proto__")&&Object.defineProperty(c,"__proto__",{enumerable:!0,value:l.__proto__});Object.keys(l).forEach(function(e){if(e!=="default"&&!Object.prototype.hasOwnProperty.call(c,e))c[e]=l[e]});Object.prototype.hasOwnProperty.call(O,"__proto__")&&!Object.prototype.hasOwnProperty.call(c,"__proto__")&&Object.defineProperty(c,"__proto__",{enumerable:!0,value:O.__proto__});Object.keys(O).forEach(function(e){if(e!=="default"&&!Object.prototype.hasOwnProperty.call(c,e))c[e]=O[e]})});
2
+ import{P as re}from"./chunk-cw9y6k15.js";import{Ff as _,If as a}from"./chunk-4dan69s4.js";var I=_((b)=>{Object.defineProperty(b,"__esModule",{value:!0});b.getHomeDir=void 0;var W=a("os"),V=a("path"),x={},G=()=>{if(process&&process.geteuid)return`${process.geteuid()}`;return"DEFAULT"},U=()=>{let{HOME:e,USERPROFILE:t,HOMEPATH:r,HOMEDRIVE:o=`C:${V.sep}`}=process.env;if(e)return e;if(t)return t;if(r)return`${o}${r}`;let i=G();if(!x[i])x[i]=(0,W.homedir)();return x[i]};b.getHomeDir=U});var P=_((j)=>{Object.defineProperty(j,"__esModule",{value:!0});j.getSSOTokenFilepath=void 0;var X=a("crypto"),B=a("path"),J=I(),z=(e)=>{let r=(0,X.createHash)("sha1").update(e).digest("hex");return(0,B.join)((0,J.getHomeDir)(),".aws","sso","cache",`${r}.json`)};j.getSSOTokenFilepath=z});var R=_((C)=>{Object.defineProperty(C,"__esModule",{value:!0});C.getSSOTokenFromFile=C.tokenIntercept=void 0;var Q=a("fs/promises"),Y=P();C.tokenIntercept={};var Z=async(e)=>{if(C.tokenIntercept[e])return C.tokenIntercept[e];let t=(0,Y.getSSOTokenFilepath)(e),r=await(0,Q.readFile)(t,"utf8");return JSON.parse(r)};C.getSSOTokenFromFile=Z});var k=_((L)=>{Object.defineProperty(L,"__esModule",{value:!0});L.readFile=L.fileIntercept=L.filePromises=void 0;var ee=a("fs/promises");L.filePromises={};L.fileIntercept={};var te=(e,t)=>{if(L.fileIntercept[e]!==void 0)return L.fileIntercept[e];if(!L.filePromises[e]||t?.ignoreCache)L.filePromises[e]=(0,ee.readFile)(e,"utf8");return L.filePromises[e]};L.readFile=te});var ye=_((c)=>{var l=I(),O=P(),y=R(),g=a("path"),S=re(),f=k(),q="AWS_PROFILE",$="default",oe=(e)=>e.profile||process.env[q]||$,p=".",ie=(e)=>Object.entries(e).filter(([t])=>{let r=t.indexOf(p);if(r===-1)return!1;return Object.values(S.IniSectionType).includes(t.substring(0,r))}).reduce((t,[r,o])=>{let i=r.indexOf(p),n=r.substring(0,i)===S.IniSectionType.PROFILE?r.substring(i+1):r;return t[n]=o,t},{...e.default&&{default:e.default}}),ne="AWS_CONFIG_FILE",M=()=>process.env[ne]||g.join(l.getHomeDir(),".aws","config"),se="AWS_SHARED_CREDENTIALS_FILE",ce=()=>process.env[se]||g.join(l.getHomeDir(),".aws","credentials"),ae=/^([\w-]+)\s(["'])?([\w-@\+\.%:/]+)\2$/,le=["__proto__","profile __proto__"],T=(e)=>{let t={},r,o;for(let i of e.split(/\r?\n/)){let n=i.split(/(^|\s)[;#]/)[0].trim();if(n[0]==="["&&n[n.length-1]==="]"){r=void 0,o=void 0;let s=n.substring(1,n.length-1),u=ae.exec(s);if(u){let[,d,,m]=u;if(Object.values(S.IniSectionType).includes(d))r=[d,m].join(p)}else r=s;if(le.includes(s))throw Error(`Found invalid profile name "${s}"`)}else if(r){let s=n.indexOf("=");if(![0,-1].includes(s)){let[u,d]=[n.substring(0,s).trim(),n.substring(s+1).trim()];if(d==="")o=u;else{if(o&&i.trimStart()===i)o=void 0;t[r]=t[r]||{};let m=o?[o,u].join(p):u;t[r][m]=d}}}}return t},A=()=>({}),K=async(e={})=>{let{filepath:t=ce(),configFilepath:r=M()}=e,o=l.getHomeDir(),i="~/",n=t;if(t.startsWith("~/"))n=g.join(o,t.slice(2));let h=r;if(r.startsWith("~/"))h=g.join(o,r.slice(2));let s=await Promise.all([f.readFile(h,{ignoreCache:e.ignoreCache}).then(T).then(ie).catch(A),f.readFile(n,{ignoreCache:e.ignoreCache}).then(T).catch(A)]);return{configFile:s[0],credentialsFile:s[1]}},pe=(e)=>Object.entries(e).filter(([t])=>t.startsWith(S.IniSectionType.SSO_SESSION+p)).reduce((t,[r,o])=>({...t,[r.substring(r.indexOf(p)+1)]:o}),{}),ue=()=>({}),fe=async(e={})=>f.readFile(e.configFilepath??M()).then(T).then(pe).catch(ue),de=(...e)=>{let t={};for(let r of e)for(let[o,i]of Object.entries(r))if(t[o]!==void 0)Object.assign(t[o],i);else t[o]=i;return t},_e=async(e)=>{let t=await K(e);return de(t.configFile,t.credentialsFile)},Fe={getFileRecord(){return f.fileIntercept},interceptFile(e,t){f.fileIntercept[e]=Promise.resolve(t)},getTokenRecord(){return y.tokenIntercept},interceptToken(e,t){y.tokenIntercept[e]=t}};c.getSSOTokenFromFile=y.getSSOTokenFromFile;c.readFile=f.readFile;c.CONFIG_PREFIX_SEPARATOR=p;c.DEFAULT_PROFILE=$;c.ENV_PROFILE=q;c.externalDataInterceptor=Fe;c.getProfileName=oe;c.loadSharedConfigFiles=K;c.loadSsoSessionData=fe;c.parseKnownFiles=_e;Object.prototype.hasOwnProperty.call(l,"__proto__")&&!Object.prototype.hasOwnProperty.call(c,"__proto__")&&Object.defineProperty(c,"__proto__",{enumerable:!0,value:l.__proto__});Object.keys(l).forEach(function(e){if(e!=="default"&&!Object.prototype.hasOwnProperty.call(c,e))c[e]=l[e]});Object.prototype.hasOwnProperty.call(O,"__proto__")&&!Object.prototype.hasOwnProperty.call(c,"__proto__")&&Object.defineProperty(c,"__proto__",{enumerable:!0,value:O.__proto__});Object.keys(O).forEach(function(e){if(e!=="default"&&!Object.prototype.hasOwnProperty.call(c,e))c[e]=O[e]})});
3
3
  export{ye as O};
4
4
 
5
- //# debugId=6802C5C10A9C2EDE64756E2164756E21
5
+ //# debugId=17DB87712CA336D964756E2164756E21
@@ -9,6 +9,6 @@
9
9
  "'use strict';\n\nvar getHomeDir = require('./getHomeDir');\nvar getSSOTokenFilepath = require('./getSSOTokenFilepath');\nvar getSSOTokenFromFile = require('./getSSOTokenFromFile');\nvar path = require('path');\nvar types = require('@smithy/types');\nvar readFile = require('./readFile');\n\nconst ENV_PROFILE = \"AWS_PROFILE\";\nconst DEFAULT_PROFILE = \"default\";\nconst getProfileName = (init) => init.profile || process.env[ENV_PROFILE] || DEFAULT_PROFILE;\n\nconst CONFIG_PREFIX_SEPARATOR = \".\";\n\nconst getConfigData = (data) => Object.entries(data)\n .filter(([key]) => {\n const indexOfSeparator = key.indexOf(CONFIG_PREFIX_SEPARATOR);\n if (indexOfSeparator === -1) {\n return false;\n }\n return Object.values(types.IniSectionType).includes(key.substring(0, indexOfSeparator));\n})\n .reduce((acc, [key, value]) => {\n const indexOfSeparator = key.indexOf(CONFIG_PREFIX_SEPARATOR);\n const updatedKey = key.substring(0, indexOfSeparator) === types.IniSectionType.PROFILE ? key.substring(indexOfSeparator + 1) : key;\n acc[updatedKey] = value;\n return acc;\n}, {\n ...(data.default && { default: data.default }),\n});\n\nconst ENV_CONFIG_PATH = \"AWS_CONFIG_FILE\";\nconst getConfigFilepath = () => process.env[ENV_CONFIG_PATH] || path.join(getHomeDir.getHomeDir(), \".aws\", \"config\");\n\nconst ENV_CREDENTIALS_PATH = \"AWS_SHARED_CREDENTIALS_FILE\";\nconst getCredentialsFilepath = () => process.env[ENV_CREDENTIALS_PATH] || path.join(getHomeDir.getHomeDir(), \".aws\", \"credentials\");\n\nconst prefixKeyRegex = /^([\\w-]+)\\s([\"'])?([\\w-@\\+\\.%:/]+)\\2$/;\nconst profileNameBlockList = [\"__proto__\", \"profile __proto__\"];\nconst parseIni = (iniData) => {\n const map = {};\n let currentSection;\n let currentSubSection;\n for (const iniLine of iniData.split(/\\r?\\n/)) {\n const trimmedLine = iniLine.split(/(^|\\s)[;#]/)[0].trim();\n const isSection = trimmedLine[0] === \"[\" && trimmedLine[trimmedLine.length - 1] === \"]\";\n if (isSection) {\n currentSection = undefined;\n currentSubSection = undefined;\n const sectionName = trimmedLine.substring(1, trimmedLine.length - 1);\n const matches = prefixKeyRegex.exec(sectionName);\n if (matches) {\n const [, prefix, , name] = matches;\n if (Object.values(types.IniSectionType).includes(prefix)) {\n currentSection = [prefix, name].join(CONFIG_PREFIX_SEPARATOR);\n }\n }\n else {\n currentSection = sectionName;\n }\n if (profileNameBlockList.includes(sectionName)) {\n throw new Error(`Found invalid profile name \"${sectionName}\"`);\n }\n }\n else if (currentSection) {\n const indexOfEqualsSign = trimmedLine.indexOf(\"=\");\n if (![0, -1].includes(indexOfEqualsSign)) {\n const [name, value] = [\n trimmedLine.substring(0, indexOfEqualsSign).trim(),\n trimmedLine.substring(indexOfEqualsSign + 1).trim(),\n ];\n if (value === \"\") {\n currentSubSection = name;\n }\n else {\n if (currentSubSection && iniLine.trimStart() === iniLine) {\n currentSubSection = undefined;\n }\n map[currentSection] = map[currentSection] || {};\n const key = currentSubSection ? [currentSubSection, name].join(CONFIG_PREFIX_SEPARATOR) : name;\n map[currentSection][key] = value;\n }\n }\n }\n }\n return map;\n};\n\nconst swallowError$1 = () => ({});\nconst loadSharedConfigFiles = async (init = {}) => {\n const { filepath = getCredentialsFilepath(), configFilepath = getConfigFilepath() } = init;\n const homeDir = getHomeDir.getHomeDir();\n const relativeHomeDirPrefix = \"~/\";\n let resolvedFilepath = filepath;\n if (filepath.startsWith(relativeHomeDirPrefix)) {\n resolvedFilepath = path.join(homeDir, filepath.slice(2));\n }\n let resolvedConfigFilepath = configFilepath;\n if (configFilepath.startsWith(relativeHomeDirPrefix)) {\n resolvedConfigFilepath = path.join(homeDir, configFilepath.slice(2));\n }\n const parsedFiles = await Promise.all([\n readFile.readFile(resolvedConfigFilepath, {\n ignoreCache: init.ignoreCache,\n })\n .then(parseIni)\n .then(getConfigData)\n .catch(swallowError$1),\n readFile.readFile(resolvedFilepath, {\n ignoreCache: init.ignoreCache,\n })\n .then(parseIni)\n .catch(swallowError$1),\n ]);\n return {\n configFile: parsedFiles[0],\n credentialsFile: parsedFiles[1],\n };\n};\n\nconst getSsoSessionData = (data) => Object.entries(data)\n .filter(([key]) => key.startsWith(types.IniSectionType.SSO_SESSION + CONFIG_PREFIX_SEPARATOR))\n .reduce((acc, [key, value]) => ({ ...acc, [key.substring(key.indexOf(CONFIG_PREFIX_SEPARATOR) + 1)]: value }), {});\n\nconst swallowError = () => ({});\nconst loadSsoSessionData = async (init = {}) => readFile.readFile(init.configFilepath ?? getConfigFilepath())\n .then(parseIni)\n .then(getSsoSessionData)\n .catch(swallowError);\n\nconst mergeConfigFiles = (...files) => {\n const merged = {};\n for (const file of files) {\n for (const [key, values] of Object.entries(file)) {\n if (merged[key] !== undefined) {\n Object.assign(merged[key], values);\n }\n else {\n merged[key] = values;\n }\n }\n }\n return merged;\n};\n\nconst parseKnownFiles = async (init) => {\n const parsedFiles = await loadSharedConfigFiles(init);\n return mergeConfigFiles(parsedFiles.configFile, parsedFiles.credentialsFile);\n};\n\nconst externalDataInterceptor = {\n getFileRecord() {\n return readFile.fileIntercept;\n },\n interceptFile(path, contents) {\n readFile.fileIntercept[path] = Promise.resolve(contents);\n },\n getTokenRecord() {\n return getSSOTokenFromFile.tokenIntercept;\n },\n interceptToken(id, contents) {\n getSSOTokenFromFile.tokenIntercept[id] = contents;\n },\n};\n\nexports.getSSOTokenFromFile = getSSOTokenFromFile.getSSOTokenFromFile;\nexports.readFile = readFile.readFile;\nexports.CONFIG_PREFIX_SEPARATOR = CONFIG_PREFIX_SEPARATOR;\nexports.DEFAULT_PROFILE = DEFAULT_PROFILE;\nexports.ENV_PROFILE = ENV_PROFILE;\nexports.externalDataInterceptor = externalDataInterceptor;\nexports.getProfileName = getProfileName;\nexports.loadSharedConfigFiles = loadSharedConfigFiles;\nexports.loadSsoSessionData = loadSsoSessionData;\nexports.parseKnownFiles = parseKnownFiles;\nObject.prototype.hasOwnProperty.call(getHomeDir, '__proto__') &&\n !Object.prototype.hasOwnProperty.call(exports, '__proto__') &&\n Object.defineProperty(exports, '__proto__', {\n enumerable: true,\n value: getHomeDir['__proto__']\n });\n\nObject.keys(getHomeDir).forEach(function (k) {\n if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) exports[k] = getHomeDir[k];\n});\nObject.prototype.hasOwnProperty.call(getSSOTokenFilepath, '__proto__') &&\n !Object.prototype.hasOwnProperty.call(exports, '__proto__') &&\n Object.defineProperty(exports, '__proto__', {\n enumerable: true,\n value: getSSOTokenFilepath['__proto__']\n });\n\nObject.keys(getSSOTokenFilepath).forEach(function (k) {\n if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) exports[k] = getSSOTokenFilepath[k];\n});\n"
10
10
  ],
11
11
  "mappings": "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",
12
- "debugId": "6802C5C10A9C2EDE64756E2164756E21",
12
+ "debugId": "17DB87712CA336D964756E2164756E21",
13
13
  "names": []
14
14
  }
@@ -1,5 +1,5 @@
1
1
  // @bun
2
2
  class K{config;static token="translator";translations={};isEnabled=!1;constructor(z){this.config=z;let j={};for(let[G,I]of Object.entries(this.config.prefetch))for(let C of this.config.supportedLocales){if(!j[C])j[C]={};j[C][G]={};for(let F of I){j[C][G][F.name]={};for(let[H,J]of Object.entries(F.dictionary))this.isEnabled=!0,j[C][G][F.name][H]=J[C]}}this.translations=j}get isLocaleAware(){return this.isEnabled||this.config.supportedLocales.length>0}get supportedLocales(){return this.config.supportedLocales}get defaultLocale(){return this.config.defaultLocale}get components(){return this.config.components}onLocaleChange(z){return this.config.onLocaleChange(z)}detectLocale(z){let j=this.config.defaultLocale??this.config.supportedLocales[0]??"en-US",G=this.config.detectLocale(z);if(this.config.supportedLocales.includes(G))return G;let C=z.cookies.get("i18n-locale")??(z.headers.get("accept-language")||j),[F]=C.split(",");if(this.config.supportedLocales.includes(F))return F;if(F.length===2){for(let H of this.config.supportedLocales)if(H.startsWith(F))return H}return j}getPageTranslations(z,j){if(this.translations[z][j])return this.translations[z][j];return{}}}
3
- export{K as wf};
3
+ export{K as tf};
4
4
 
5
- //# debugId=6BDD7227EB332BDD64756E2164756E21
5
+ //# debugId=159A625D3445A83364756E2164756E21
@@ -5,6 +5,6 @@
5
5
  "import type { HttpRequest } from \"../http/HttpRequest\";\nimport type { Dictionary } from \"./Dictionary\";\nimport type { TranslationConfig } from \"./config\";\n\nexport class Translator {\n static token = \"translator\";\n\n translations = {};\n isEnabled = false;\n\n constructor(public config: Required<TranslationConfig>) {\n const translations = {};\n\n for (const [route, dicArray] of Object.entries(this.config.prefetch)) {\n for (const locale of this.config.supportedLocales) {\n if (!translations[locale]) {\n translations[locale] = {};\n }\n translations[locale][route] = {};\n for (const dic of dicArray) {\n translations[locale][route][dic.name] = {};\n for (const [key, value] of Object.entries(dic.dictionary)) {\n this.isEnabled = true;\n translations[locale][route][dic.name][key] = value[locale];\n }\n }\n }\n }\n this.translations = translations;\n }\n\n /**\n * Whether the app does locale-aware routing and rendering at all.\n *\n * `isEnabled` only means the legacy `prefetch` config has dictionaries to\n * serve. An app on `defineDictionary` has an empty `prefetch` and declares\n * its locales through `supportedLocales` alone, so gating on `isEnabled`\n * leaves it without locale detection or a locale URL prefix. Both the render\n * path and the redirect read this, because when they disagreed a migrated app\n * rendered a non-default locale at `/` with no redirect and no `Vary` — one\n * cache fill away from serving that document to everyone.\n */\n get isLocaleAware(): boolean {\n return this.isEnabled || this.config.supportedLocales.length > 0;\n }\n\n get supportedLocales(): string[] {\n return this.config.supportedLocales;\n }\n\n get defaultLocale(): string {\n return this.config.defaultLocale;\n }\n\n get components(): Record<string, Dictionary<any>> {\n return this.config.components;\n }\n\n onLocaleChange(locale: string): Promise<void> | void {\n return this.config.onLocaleChange(locale);\n }\n\n detectLocale(req: HttpRequest<any, any>) {\n const fallbackLocale =\n this.config.defaultLocale ?? this.config.supportedLocales[0] ?? \"en-US\";\n const detectedLocale = this.config.detectLocale(req);\n if (this.config.supportedLocales.includes(detectedLocale)) {\n return detectedLocale;\n }\n\n const previousLocale = req.cookies.get(\"i18n-locale\");\n const locale =\n previousLocale ?? (req.headers.get(\"accept-language\") || fallbackLocale);\n\n const [_locale] = locale.split(\",\");\n\n if (this.config.supportedLocales.includes(_locale)) {\n return _locale;\n }\n\n if (_locale.length === 2) {\n for (const supportedLocale of this.config.supportedLocales) {\n if (supportedLocale.startsWith(_locale)) {\n return supportedLocale;\n }\n }\n }\n\n return fallbackLocale;\n }\n\n getPageTranslations(locale: string, scope: string) {\n if (this.translations[locale][scope]) {\n return this.translations[locale][scope];\n }\n return {};\n }\n}\n"
6
6
  ],
7
7
  "mappings": ";AAIO,MAAM,CAAW,CAMH,aALZ,OAAQ,aAEf,aAAe,CAAC,EAChB,UAAY,GAEZ,WAAW,CAAQ,EAAqC,CAArC,cACjB,IAAM,EAAe,CAAC,EAEtB,QAAY,EAAO,KAAa,OAAO,QAAQ,KAAK,OAAO,QAAQ,EACjE,QAAW,KAAU,KAAK,OAAO,iBAAkB,CACjD,GAAI,CAAC,EAAa,GAChB,EAAa,GAAU,CAAC,EAE1B,EAAa,GAAQ,GAAS,CAAC,EAC/B,QAAW,KAAO,EAAU,CAC1B,EAAa,GAAQ,GAAO,EAAI,MAAQ,CAAC,EACzC,QAAY,EAAK,KAAU,OAAO,QAAQ,EAAI,UAAU,EACtD,KAAK,UAAY,GACjB,EAAa,GAAQ,GAAO,EAAI,MAAM,GAAO,EAAM,IAK3D,KAAK,aAAe,KAclB,cAAa,EAAY,CAC3B,OAAO,KAAK,WAAa,KAAK,OAAO,iBAAiB,OAAS,KAG7D,iBAAgB,EAAa,CAC/B,OAAO,KAAK,OAAO,oBAGjB,cAAa,EAAW,CAC1B,OAAO,KAAK,OAAO,iBAGjB,WAAU,EAAoC,CAChD,OAAO,KAAK,OAAO,WAGrB,cAAc,CAAC,EAAsC,CACnD,OAAO,KAAK,OAAO,eAAe,CAAM,EAG1C,YAAY,CAAC,EAA4B,CACvC,IAAM,EACJ,KAAK,OAAO,eAAiB,KAAK,OAAO,iBAAiB,IAAM,QAC5D,EAAiB,KAAK,OAAO,aAAa,CAAG,EACnD,GAAI,KAAK,OAAO,iBAAiB,SAAS,CAAc,EACtD,OAAO,EAIT,IAAM,EADiB,EAAI,QAAQ,IAAI,aAAa,IAE/B,EAAI,QAAQ,IAAI,iBAAiB,GAAK,IAEpD,GAAW,EAAO,MAAM,GAAG,EAElC,GAAI,KAAK,OAAO,iBAAiB,SAAS,CAAO,EAC/C,OAAO,EAGT,GAAI,EAAQ,SAAW,GACrB,QAAW,KAAmB,KAAK,OAAO,iBACxC,GAAI,EAAgB,WAAW,CAAO,EACpC,OAAO,EAKb,OAAO,EAGT,mBAAmB,CAAC,EAAgB,EAAe,CACjD,GAAI,KAAK,aAAa,GAAQ,GAC5B,OAAO,KAAK,aAAa,GAAQ,GAEnC,MAAO,CAAC,EAEZ",
8
- "debugId": "6BDD7227EB332BDD64756E2164756E21",
8
+ "debugId": "159A625D3445A83364756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -0,0 +1,55 @@
1
+ // @bun
2
+ import{$ as f,Z as S}from"./chunk-y3zz410b.js";import{ia as x,ja as D}from"./chunk-v7y8zm61.js";import"./chunk-5ad8era8.js";import"./chunk-ejrcyzx8.js";import"./chunk-tkdxv6cq.js";import"./chunk-xnytbrda.js";import"./chunk-4dan69s4.js";import{IncomingMessage as g,ServerResponse as w}from"http";import{Socket as E}from"net";import{join as k}from"path";import{createServer as q}from"vite";function T(H){return H.replace(/\x1b\[[0-9;]*m/g,"").replace(/\[[0-9;]*m/g,"").replace(/\n\s*\n/g,`
3
+ `).split(`
4
+ `).map((J)=>J.trim()).filter((J)=>J.length>0).join(`
5
+ `).trim()}function b(H){return`
6
+ <!DOCTYPE html>
7
+ <html lang="en">
8
+ <head>
9
+ <meta charset="UTF-8" />
10
+ <meta
11
+ name="viewport"
12
+ content="width=device-width, initial-scale=1.0"
13
+ />
14
+
15
+ <title>Error</title>
16
+ <style>
17
+ body {
18
+ font-family: Arial, sans-serif;
19
+ padding: 20px;
20
+ }
21
+ h1 {
22
+ color: red;
23
+ }
24
+ </style>
25
+ </head>
26
+ <body>
27
+ <div id="overlay"></div>
28
+ <script type="module" src="/refresh.js"></script>
29
+ <script type="module" src="/@vite/client"></script>
30
+ <script>
31
+ ${T.toString()}
32
+ const err = ${JSON.stringify(H,Object.getOwnPropertyNames(H),2)}
33
+
34
+ window.addEventListener('load', () => {
35
+ const container = document.getElementById('overlay')
36
+ const ErrorOverlay = customElements.get('vite-error-overlay')
37
+ if (ErrorOverlay) {
38
+ const overlay = new ErrorOverlay({ ...err, message: cleanupTerminalText(err.message) });
39
+ container.appendChild(overlay)
40
+ }
41
+ })
42
+ </script>
43
+ </body>
44
+ </html>
45
+ `}function d(H,J){let $=new URL(J.url),K=new g(new E);K.url=$.pathname+$.search,K.method=J.method,K.headers=Object.fromEntries(J.headers);let O=new w(K),Q=[];return new Promise((Y)=>{O.write=(Z)=>{if(Z)Q.push(Buffer.from(Z));return!0},O.end=(Z)=>{if(Z&&typeof Z!=="function")Q.push(Buffer.from(Z));let z=new Headers;for(let[_,j]of Object.entries(O.getHeaders())){if(j==null)continue;for(let U of Array.isArray(j)?j:[j])z.append(_,String(U))}return Y(new Response(Q.length?Buffer.concat(Q):null,{status:O.statusCode,headers:z})),O},H.middlewares(K,O,()=>Y(null))})}var L=process.cwd(),y=k(L,"app");function h(H,J,$){let K=String(J),O=" ".repeat(K.length),Q=" ".repeat(Math.max(0,$-1))+"^";return`${K} | ${H}
46
+ ${O} | ${Q}
47
+ `}function R(H){if(H&&typeof H==="object"){let J=H.position;if(J&&typeof J==="object"&&typeof J.file==="string")return{message:typeof H.message==="string"?H.message:String(H),stack:"",frame:typeof J.lineText==="string"?h(J.lineText,J.line,J.column):void 0,loc:{file:J.file,line:J.line,column:J.column}};return{message:typeof H.message==="string"?H.message:String(H),stack:typeof H.stack==="string"?H.stack:""}}return{message:String(H),stack:""}}function X(H){let J=globalThis.__gemiVite;if(!J)return;J.ws.send({type:"error",err:R(H)}),globalThis.__gemiErrorActive=!0}if(!globalThis.__gemiErrorHooked)globalThis.__gemiErrorHooked=!0,process.on("unhandledRejection",(H)=>{console.error(H),X(H)}),process.on("uncaughtException",(H)=>{console.error(H),X(H)});function I(H){let J=H.environments.ssr;if(typeof J?.runner?.import!=="function")throw Error("gemi dev requires a runnable Vite SSR environment.");return J.runner}async function n(H,J){let $=Boolean(globalThis.__gemiVite),K=globalThis.__gemiVite??=await q({configFile:!1,plugins:[D()],server:{middlewareMode:!0,watch:{ignored:(Q)=>{let Y=Q.split(/[/\\]/).pop()??"";return Y===".env"||Y.startsWith(".env.")}}},appType:"custom",resolve:{dedupe:["react","react-dom"]},optimizeDeps:{include:["react","react-dom","react-dom/client"]},ssr:{external:[...x]}});process.env.ROOT_DIR=L,process.env.APP_DIR=y;let O=Bun.serve({port:process.env.PORT||5173,fetch:async(Q)=>{let{pathname:Y,host:Z,protocol:z}=new URL(Q.url);if(Y.startsWith("/render-error.js"))return new Response("window.render_error = true",{headers:{"Content-Type":"application/javascript"}});if(Y.startsWith("/refresh.js"))return new Response(`
48
+ import RefreshRuntime from "${z}//${Z}/@react-refresh";
49
+ RefreshRuntime.injectIntoGlobalHook(window);
50
+ window.$RefreshReg$ = () => {};
51
+ window.$RefreshSig$ = () => (type) => type;
52
+ window.__vite_plugin_react_preamble_installed__ = true;
53
+ `,{headers:{"Content-Type":"application/javascript"}});return await J(Q,async(j)=>{try{let U=H.fetch.bind(H),A=await d(K,j)??await U(j);if(A instanceof Response)return A;let F={},V={},C={},M=(W,B)=>`"${W}": () => import("${B}")`,P=[];for(let W of["404",...H.getFlatComponentTree.call(H)]){if(Bun.env.NODE_ENV==="test")break;let B=`${process.env.APP_DIR}`,G=await I(K).import(`${B}/views/${W}.tsx`);F[W]=G.default,V[W]=G?.OpenGraph,C[W]=G,P.push(M(W,`/app/views/${W}.tsx`))}let N=`{${P.join(",")}}`;return await A({getStyles:async(W)=>await S(y,K,W),bootstrapModules:["/refresh.js","/app/client.tsx","/@vite/client"],viewImportMap:F,viewModules:C,ogMap:V,loaders:N,cssManifest:{}})}catch(U){if(console.error(U),K.ssrFixStacktrace?.(U),X(U),Y.startsWith("/api"))return new Response(JSON.stringify({error:U?.message??String(U)}),{status:500,headers:{"Content-Type":"application/json"}});return globalThis.__gemiErrorPageServed=!0,new Response(b(R(U)),{status:500,headers:{"Content-Type":"text/html"}})}})}});if($)I(K).clearCache();if($)if(globalThis.__gemiErrorActive&&globalThis.__gemiErrorPageServed)globalThis.__gemiErrorActive=!1,globalThis.__gemiErrorPageServed=!1,K.ws.send({type:"full-reload"});else globalThis.__gemiErrorActive=!1,K.ws.send({type:"custom",event:"http-reload"});else f({port:O.port,rootDir:L});return O}export{R as viteErrorPayload,n as httpDev};
54
+
55
+ //# debugId=D1B9E3C03333FFE964756E2164756E21
@@ -0,0 +1,11 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../server/httpDev.ts", "../server/renderErrorPage.ts"],
4
+ "sourcesContent": [
5
+ "import { IncomingMessage, ServerResponse } from \"node:http\";\nimport { Socket } from \"node:net\";\nimport { join } from \"node:path\";\n\nimport { createServer, type RunnableDevEnvironment, type ViteDevServer } from \"vite\";\n\nimport { App } from \"../app\";\nimport gemiVite from \"../vite\";\nimport { createDevStyles } from \"./styles\";\nimport { renderErrorPage } from \"./renderErrorPage\";\nimport { Instrumentation } from \"./types\";\nimport { printStartupBanner } from \"./banner\";\nimport { GEMI_EXTERNAL_SPECIFIERS } from \"../internal/gemiExternals\";\n\n// Run a Web `Request` through Vite's Connect middleware.\n// Resolves to a `Response` when Vite handles the request (module transforms,\n// assets, the HMR client, ...), or `null` when it calls `next()` — which, with\n// `appType: \"custom\"`, it does for everything it doesn't own.\nfunction viteMiddleware(vite: ViteDevServer, request: Request): Promise<Response | null> {\n const url = new URL(request.url);\n\n const req = new IncomingMessage(new Socket());\n req.url = url.pathname + url.search;\n req.method = request.method;\n req.headers = Object.fromEntries(request.headers);\n\n const res = new ServerResponse(req);\n const chunks: Buffer[] = [];\n\n return new Promise((resolve) => {\n res.write = ((chunk: any) => {\n if (chunk) chunks.push(Buffer.from(chunk));\n return true;\n }) as typeof res.write;\n\n res.end = ((chunk?: any) => {\n if (chunk && typeof chunk !== \"function\") chunks.push(Buffer.from(chunk));\n\n const headers = new Headers();\n for (const [key, value] of Object.entries(res.getHeaders())) {\n if (value == null) continue;\n for (const v of Array.isArray(value) ? value : [value]) {\n headers.append(key, String(v));\n }\n }\n\n resolve(\n new Response(chunks.length ? Buffer.concat(chunks) : null, {\n status: res.statusCode,\n headers,\n }),\n );\n return res;\n }) as typeof res.end;\n\n vite.middlewares(req, res, () => resolve(null));\n });\n}\n\nconst rootDir = process.cwd();\nconst appDir = join(rootDir, \"app\");\n\ndeclare global {\n // Created once and reused across `bun --hot` reloads (see below).\n var __gemiVite: ViteDevServer | undefined;\n // Guards one-time registration of the process error hooks across reloads.\n var __gemiErrorHooked: boolean | undefined;\n // An error overlay is currently showing on the client (clear it on recovery).\n var __gemiErrorActive: boolean | undefined;\n // We served a standalone error *page* (not just a pushed overlay), so the\n // visible document has no live app — recovery needs a full page reload.\n var __gemiErrorPageServed: boolean | undefined;\n}\n\n// Build the `> 1 | ...\\n | ^` codeframe Vite's overlay renders — must\n// match its `codeframeRE` (a `<line> | <text>` line followed by a `| ^` line,\n// each ending in a newline).\nfunction codeFrame(lineText: string, line: number, column: number) {\n const gutter = String(line);\n const pad = \" \".repeat(gutter.length);\n const caret = \" \".repeat(Math.max(0, column - 1)) + \"^\";\n return `${gutter} | ${lineText}\\n${pad} | ${caret}\\n`;\n}\n\n// Normalize whatever Bun/JS throws into the { message, stack, frame, loc }\n// shape Vite's error overlay consumes. Two cases matter:\n// - a real `Error` (runtime top-level throw) carries a proper `.stack`;\n// - a Bun `BuildMessage` (syntax error) has NO `.stack`, only a `.position`\n// ({ file, line, column, lineText }) — so synthesize a codeframe + loc from\n// it, otherwise the overlay shows a bare message with no location.\n// (An `Error` instance also JSON-stringifies to `{}`, so fields are copied by\n// hand either way.)\nexport function viteErrorPayload(err: any) {\n if (err && typeof err === \"object\") {\n const pos = err.position;\n if (pos && typeof pos === \"object\" && typeof pos.file === \"string\") {\n return {\n message: typeof err.message === \"string\" ? err.message : String(err),\n stack: \"\",\n frame:\n typeof pos.lineText === \"string\"\n ? codeFrame(pos.lineText, pos.line, pos.column)\n : undefined,\n loc: { file: pos.file, line: pos.line, column: pos.column },\n };\n }\n return {\n message: typeof err.message === \"string\" ? err.message : String(err),\n stack: typeof err.stack === \"string\" ? err.stack : \"\",\n };\n }\n return { message: String(err), stack: \"\" };\n}\n\n// Push an error into the browser via Vite's HMR socket. `__gemiVite` persists\n// across `bun --hot` reloads, so this works even when the reload that produced\n// the error never got far enough to (re)run `httpDev`.\nfunction sendErrorToClient(err: any) {\n const vite = globalThis.__gemiVite;\n if (!vite) return;\n vite.ws.send({ type: \"error\", err: viteErrorPayload(err) as any });\n globalThis.__gemiErrorActive = true;\n}\n\n// `bun --hot` re-evaluates the module graph on every server-code change. A\n// syntax error or top-level throw in app code therefore fails during *module\n// load* — outside any request, and before `httpDev` re-runs — so Bun only\n// prints it to the console. Bun surfaces these as `unhandledRejection` (the\n// reload re-imports the entry and the failing dynamic import rejects), so hook\n// that here and forward it to the client. Registered once; process listeners\n// persist across reloads.\nif (!globalThis.__gemiErrorHooked) {\n globalThis.__gemiErrorHooked = true;\n process.on(\"unhandledRejection\", (reason) => {\n console.error(reason);\n sendErrorToClient(reason);\n });\n process.on(\"uncaughtException\", (err) => {\n console.error(err);\n sendErrorToClient(err);\n });\n}\n\n/**\n * The SSR environment's module runner — what `vite.ssrLoadModule` is a thin\n * (and, in Vite 8, deprecated) wrapper over. Going through it directly is what\n * gives `httpDev` a handle on the evaluated-module cache it has to drop after a\n * `bun --hot` reload; `ssrLoadModule` keeps its own runner private.\n *\n * Duck-typed rather than `isRunnableDevEnvironment(environment)`: this server\n * outlives the module instance that created it, and after a reload the freshly\n * evaluated `vite` brings a *new* `RunnableDevEnvironment` class object, so the\n * `instanceof` that predicate performs is false for a perfectly runnable\n * environment. (The same one-copy-per-reload rule this whole dance is about.)\n */\nfunction ssrRunner(vite: ViteDevServer) {\n const environment = vite.environments.ssr as RunnableDevEnvironment;\n if (typeof environment?.runner?.import !== \"function\") {\n throw new Error(\"gemi dev requires a runnable Vite SSR environment.\");\n }\n return environment.runner;\n}\n\nexport async function httpDev(app: App, instrumentation: Instrumentation) {\n // `bun --hot` re-runs this module on every server-code change, so keep a\n // single Vite server on `globalThis` instead of spawning a new one (and a new\n // HMR socket) on each reload.\n const isReload = Boolean(globalThis.__gemiVite);\n const vite = (globalThis.__gemiVite ??= await createServer({\n // gemi owns the Vite setup — the app has no `vite.config.mjs` to discover.\n // Register the gemi plugin explicitly instead; it loads `gemi.config.ts` and\n // appends the app's Vite plugins (e.g. `@vitejs/plugin-react`, which serves\n // `/@react-refresh` and the HMR preamble referenced below).\n configFile: false,\n plugins: [gemiVite()],\n server: {\n middlewareMode: true,\n // gemi reloads `.env` into process.env itself (see `watchEnv`). Stop Vite\n // from *also* watching env files: Vite's env-change handler restarts the\n // dev server, which closes the SSR module runner — but gemi keeps a single\n // Vite instance across `bun --hot` reloads, so an in-flight view import\n // hits the closed runner (\"Vite module runner has been closed\"). Ignoring\n // env files here only disables the restart; env *loading* at startup (and\n // `import.meta.env`) is unaffected.\n watch: {\n ignored: (file: string) => {\n const base = file.split(/[/\\\\]/).pop() ?? \"\";\n return base === \".env\" || base.startsWith(\".env.\");\n },\n },\n },\n appType: \"custom\",\n // Views are loaded through this SSR graph while the renderer\n // (react-dom/server in ViewRouteDispatcher) is imported by Bun.\n // Dedupe so Vite can never resolve a second React copy — a mismatch makes\n // the SSR dispatcher null (\"Invalid hook call\") after an HMR reload.\n resolve: { dedupe: [\"react\", \"react-dom\"] },\n // Pre-bundle the whole React surface the client uses in one pass. The client\n // imports `react-dom/client` (`init.tsx`) and `react-dom` (`createPortal` in\n // `HttpReload.tsx`); if only the first is discovered at startup, the first\n // request to a module using the second triggers a *second* optimize pass,\n // and the already-served page ends up importing a now-stale dep — surfacing\n // as \"does not provide an export named 't'\". Listing them up front bundles\n // them together so no re-optimization (and no version skew) happens.\n optimizeDeps: { include: [\"react\", \"react-dom\", \"react-dom/client\"] },\n // `gemi` is a linked package, so Vite would otherwise compile its own copy\n // into this graph — giving views a *different* `RouteStateContext` (and\n // other module-level singletons) than the Bun-loaded renderer's `Root`\n // provider, so `useRouteData()` reads the empty default (`i18n` undefined).\n // Externalizing makes view imports of `gemi/*` resolve to the one Bun\n // instance. Vite's `ssr.external` matches exact specifiers (subpaths are NOT\n // covered by the bare name, and regexes are ignored here), so every subpath\n // a view might import must be listed — see `internal/gemiExternals`, the\n // shared source of truth this and the SSR build (`vite/index.ts`) both use.\n ssr: {\n external: [...GEMI_EXTERNAL_SPECIFIERS],\n },\n }));\n\n process.env.ROOT_DIR = rootDir;\n process.env.APP_DIR = appDir;\n\n const server = Bun.serve({\n // Same override the prod server honors (`httpProd.ts`).\n port: process.env.PORT || 5173,\n fetch: async (req) => {\n const { pathname, host, protocol } = new URL(req.url);\n if (pathname.startsWith(\"/render-error.js\")) {\n return new Response(\"window.render_error = true\", {\n headers: {\n \"Content-Type\": \"application/javascript\",\n },\n });\n }\n if (pathname.startsWith(\"/refresh.js\")) {\n return new Response(\n `\n import RefreshRuntime from \"${protocol}//${host}/@react-refresh\";\n RefreshRuntime.injectIntoGlobalHook(window);\n window.$RefreshReg$ = () => {};\n window.$RefreshSig$ = () => (type) => type;\n window.__vite_plugin_react_preamble_installed__ = true;\n `,\n {\n headers: {\n \"Content-Type\": \"application/javascript\",\n },\n },\n );\n }\n const requestHandler = async (req: Request): Promise<Response> => {\n try {\n const handler = app.fetch.bind(app);\n const result = (await viteMiddleware(vite, req)) ?? (await handler(req));\n if (result instanceof Response) {\n return result;\n }\n\n const viewImportMap = {};\n const ogMap = {};\n const viewModules = {};\n const template = (viewName: string, path: string) =>\n `\"${viewName}\": () => import(\"${path}\")`;\n const templates = [];\n\n for (const fileName of [\"404\", ...app.getFlatComponentTree.call(app)]) {\n if (process.env.NODE_ENV === \"test\") {\n break;\n }\n const appDir = `${process.env.APP_DIR}`;\n const mod = await ssrRunner(vite).import(`${appDir}/views/${fileName}.tsx`);\n\n viewImportMap[fileName] = mod.default;\n ogMap[fileName] = mod?.OpenGraph;\n // The whole module, so a streaming render can put the view's\n // `Loading`/`Error` exports into the shell it sends.\n viewModules[fileName] = mod;\n // Emit a root-relative URL (`/app/views/Foo.tsx`), NOT the absolute\n // filesystem path the runner import above uses. The browser's\n // `window.loaders` preload and `client.tsx`'s `import.meta.glob` map\n // must import the exact same URL — otherwise Vite serves the module\n // under two URLs (`/app/views/Foo.tsx` vs `/Users/.../app/views/Foo.tsx`)\n // and loads/instantiates the view twice.\n templates.push(template(fileName, `/app/views/${fileName}.tsx`));\n }\n\n const loaders = `{${templates.join(\",\")}}`;\n\n return await result({\n getStyles: async (currentViews: string[]) =>\n await createDevStyles(appDir, vite, currentViews),\n bootstrapModules: [\"/refresh.js\", \"/app/client.tsx\", \"/@vite/client\"],\n viewImportMap,\n viewModules,\n ogMap,\n loaders,\n cssManifest: {},\n });\n } catch (err: any) {\n // Errors thrown *while handling a request* (a controller throwing, a\n // failing view import, ...) never hit the module-load hooks above,\n // so surface them here: forward to the overlay for any already-open\n // page, and render an error page for this response so a fresh load\n // (which has no live HMR socket yet) still shows the failure.\n console.error(err);\n vite.ssrFixStacktrace?.(err);\n sendErrorToClient(err);\n\n if (pathname.startsWith(\"/api\")) {\n return new Response(JSON.stringify({ error: err?.message ?? String(err) }), {\n status: 500,\n headers: { \"Content-Type\": \"application/json\" },\n });\n }\n\n // This document has no live app (so no HttpReload listener to clear the\n // overlay) — remember that, so recovery forces a full page reload.\n globalThis.__gemiErrorPageServed = true;\n return new Response(renderErrorPage(viteErrorPayload(err)), {\n status: 500,\n headers: { \"Content-Type\": \"text/html\" },\n });\n }\n };\n\n return await instrumentation(req, requestHandler);\n },\n });\n\n // `bun --hot` re-evaluates its *whole* module graph on a server-code change —\n // node_modules included — so after a reload `react`, `react-dom/server` and the\n // Bun-loaded `gemi` are all fresh instances. This Vite server is not reloaded\n // with them (it is deliberately kept on `globalThis` above), and its SSR runner\n // still holds every view module it has evaluated — each bound, through the\n // externalized `gemi/*` imports, to the *previous* `gemi` and therefore the\n // previous `react`. The next render then sets the dispatcher on the new React\n // while a cached view calls hooks on the old one: \"Invalid hook call\", a null\n // `dispatcher.useContext` thrown from `useRouteData` inside a view nobody\n // touched. Editing a *view* never showed it — Vite's own watcher invalidates\n // that module, so it re-evaluates against the new instances. Editing a\n // server-only file (`app/config/*`, a feature declaration, a controller) is\n // the case with nothing to invalidate the views, so drop the evaluated\n // modules here, once per reload.\n //\n // Here and not before `Bun.serve`, with nothing awaited in between, because\n // both sides of the swap have to see a consistent pair. Until that call\n // returns the *previous* fetch handler is still serving — old dispatcher, old\n // `react-dom/server` — and a request landing there after an early clear would\n // re-evaluate its views against the *new* `gemi`: the same mismatch, reversed.\n // After it, the new handler is live and must not be given the stale ones. The\n // two statements are synchronous neighbours, so no request can be dispatched\n // between them.\n //\n // Only the *evaluated* modules go: the server-side transform cache is\n // untouched, so this costs a re-evaluation and not a re-transform. Clearing\n // the module graph as well would not have been enough anyway — externalized\n // deps (`gemi`, and React through it) are cached in the runner by URL and\n // carry no invalidation flag, which is exactly where the stale React hides.\n if (isReload) {\n ssrRunner(vite).clearCache();\n }\n\n // On a reload `app` has already been rebuilt with the new code and Bun.serve\n // above has swapped in the new fetch handler, so the updated controllers are\n // live *now*. Tell the client to re-run its queries only at this point —\n // firing it from Vite's file watcher instead races Bun's reload and leaves\n // the UI one change behind.\n if (isReload) {\n // We got here, so the reload succeeded. Recover from any error that was\n // showing: a standalone error page must be fully reloaded to get the app\n // back, whereas an overlay pushed onto a live page is cleared by the\n // client's `http-reload` handler (no jarring full-page reload). A normal\n // reload just re-runs client queries against the now-live controllers.\n if (globalThis.__gemiErrorActive && globalThis.__gemiErrorPageServed) {\n globalThis.__gemiErrorActive = false;\n globalThis.__gemiErrorPageServed = false;\n vite.ws.send({ type: \"full-reload\" });\n } else {\n globalThis.__gemiErrorActive = false;\n vite.ws.send({ type: \"custom\", event: \"http-reload\" });\n }\n } else {\n // First start (not a `bun --hot` reload) — print the startup banner once.\n printStartupBanner({ port: server.port, rootDir });\n }\n\n return server;\n}\n",
6
+ "function cleanupTerminalText(text) {\n return (\n text\n // Remove ANSI escape sequences (colors, formatting)\n .replace(/\\x1b\\[[0-9;]*m/g, \"\")\n // Remove ANSI escape sequences with different format\n .replace(/\\[[0-9;]*m/g, \"\")\n // Remove excessive whitespace and normalize line breaks\n .replace(/\\n\\s*\\n/g, \"\\n\")\n // Trim each line\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line.length > 0)\n .join(\"\\n\")\n .trim()\n );\n}\n\nexport function renderErrorPage(err: any) {\n return `\n<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta\n name=\"viewport\"\n content=\"width=device-width, initial-scale=1.0\"\n />\n\n <title>Error</title>\n <style>\n body {\n font-family: Arial, sans-serif;\n padding: 20px;\n }\n h1 {\n color: red;\n }\n </style>\n </head>\n <body>\n <div id=\"overlay\"></div>\n <script type=\"module\" src=\"/refresh.js\"></script>\n <script type=\"module\" src=\"/@vite/client\"></script>\n <script>\n ${cleanupTerminalText.toString()}\n const err = ${JSON.stringify(err, Object.getOwnPropertyNames(err), 2)}\n\n window.addEventListener('load', () => {\n const container = document.getElementById('overlay')\n const ErrorOverlay = customElements.get('vite-error-overlay')\n if (ErrorOverlay) {\n const overlay = new ErrorOverlay({ ...err, message: cleanupTerminalText(err.message) });\n container.appendChild(overlay)\n }\n })\n </script>\n </body>\n</html>\n`;\n}\n"
7
+ ],
8
+ "mappings": "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",
9
+ "debugId": "D1B9E3C03333FFE964756E2164756E21",
10
+ "names": []
11
+ }