@alepha/devtools 0.19.1 → 0.19.3

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 (130) hide show
  1. package/assets/ui/200.html +10 -0
  2. package/assets/ui/200.html.br +1 -0
  3. package/assets/ui/404.html +10 -0
  4. package/assets/ui/404.html.br +1 -0
  5. package/assets/ui/CNAME +1 -0
  6. package/assets/ui/asset.CHpVij2M.css +1 -0
  7. package/assets/ui/asset.CHpVij2M.css.br +0 -0
  8. package/assets/ui/asset.Cxu56LSy.css +1 -0
  9. package/assets/ui/asset.Cxu56LSy.css.br +0 -0
  10. package/assets/ui/chunk.9plHAFDW.js +1 -0
  11. package/assets/ui/chunk.9plHAFDW.js.br +0 -0
  12. package/assets/ui/chunk.B82rsdDI.js +1 -0
  13. package/assets/ui/chunk.B82rsdDI.js.br +0 -0
  14. package/assets/ui/chunk.B9jGefQy.js +1 -0
  15. package/assets/ui/chunk.B9jGefQy.js.br +0 -0
  16. package/assets/ui/chunk.BHYZ9sAK.js +1 -0
  17. package/assets/ui/chunk.BHYZ9sAK.js.br +0 -0
  18. package/assets/ui/chunk.Bc7_n90V.js +1 -0
  19. package/assets/ui/chunk.Bc7_n90V.js.br +0 -0
  20. package/assets/ui/chunk.CCbhJSL_.js +1 -0
  21. package/assets/ui/chunk.CCbhJSL_.js.br +0 -0
  22. package/assets/ui/chunk.CJt_09bu.js +1 -0
  23. package/assets/ui/chunk.CJt_09bu.js.br +0 -0
  24. package/assets/ui/chunk.CK6Z-I-W.js +1 -0
  25. package/assets/ui/chunk.CK6Z-I-W.js.br +1 -0
  26. package/assets/ui/chunk.Cj1opA98.js +1 -0
  27. package/assets/ui/chunk.Cj1opA98.js.br +0 -0
  28. package/assets/ui/chunk.CvCu4yZb.js +2 -0
  29. package/assets/ui/chunk.CvCu4yZb.js.br +0 -0
  30. package/assets/ui/chunk.D93ZmnLR.js +1 -0
  31. package/assets/ui/chunk.D93ZmnLR.js.br +6 -0
  32. package/assets/ui/chunk.D9MCnLj_.js +7 -0
  33. package/assets/ui/chunk.D9MCnLj_.js.br +0 -0
  34. package/assets/ui/chunk.DOwjsMaD.js +1 -0
  35. package/assets/ui/chunk.DOwjsMaD.js.br +0 -0
  36. package/assets/ui/chunk.DYIu-C82.js +1 -0
  37. package/assets/ui/chunk.DYIu-C82.js.br +0 -0
  38. package/assets/ui/chunk.D_-fkSwu.js +1 -0
  39. package/assets/ui/chunk.D_-fkSwu.js.br +0 -0
  40. package/assets/ui/chunk.Dc4PCYcb.js +1 -0
  41. package/assets/ui/chunk.Dc4PCYcb.js.br +0 -0
  42. package/assets/ui/chunk.De1vj4hM.js +1 -0
  43. package/assets/ui/chunk.De1vj4hM.js.br +0 -0
  44. package/assets/ui/chunk.DuQak1OK.js +1 -0
  45. package/assets/ui/chunk.DuQak1OK.js.br +0 -0
  46. package/assets/ui/chunk.DxnuHDOY.js +1 -0
  47. package/assets/ui/chunk.DxnuHDOY.js.br +0 -0
  48. package/assets/ui/chunk.TIounDiA.js +1 -0
  49. package/assets/ui/chunk.TIounDiA.js.br +0 -0
  50. package/assets/ui/chunk.p3hCiSrt.js +80 -0
  51. package/assets/ui/chunk.p3hCiSrt.js.br +0 -0
  52. package/assets/ui/chunk.yh4jaMrg.js +1 -0
  53. package/assets/ui/chunk.yh4jaMrg.js.br +0 -0
  54. package/assets/ui/entry.DnXws2rz.js +2 -0
  55. package/assets/ui/entry.DnXws2rz.js.br +0 -0
  56. package/assets/ui/index.html +10 -0
  57. package/assets/ui/index.html.br +1 -0
  58. package/dist/public/200.html +10 -0
  59. package/dist/public/200.html.br +1 -0
  60. package/dist/public/404.html +10 -0
  61. package/dist/public/404.html.br +1 -0
  62. package/dist/public/CNAME +1 -0
  63. package/dist/public/asset.CHpVij2M.css +1 -0
  64. package/dist/public/asset.CHpVij2M.css.br +0 -0
  65. package/dist/public/asset.Cxu56LSy.css +1 -0
  66. package/dist/public/asset.Cxu56LSy.css.br +0 -0
  67. package/dist/public/chunk.9plHAFDW.js +1 -0
  68. package/dist/public/chunk.9plHAFDW.js.br +0 -0
  69. package/dist/public/chunk.B82rsdDI.js +1 -0
  70. package/dist/public/chunk.B82rsdDI.js.br +0 -0
  71. package/dist/public/chunk.B9jGefQy.js +1 -0
  72. package/dist/public/chunk.B9jGefQy.js.br +0 -0
  73. package/dist/public/chunk.BHYZ9sAK.js +1 -0
  74. package/dist/public/chunk.BHYZ9sAK.js.br +0 -0
  75. package/dist/public/chunk.Bc7_n90V.js +1 -0
  76. package/dist/public/chunk.Bc7_n90V.js.br +0 -0
  77. package/dist/public/chunk.CCbhJSL_.js +1 -0
  78. package/dist/public/chunk.CCbhJSL_.js.br +0 -0
  79. package/dist/public/chunk.CJt_09bu.js +1 -0
  80. package/dist/public/chunk.CJt_09bu.js.br +0 -0
  81. package/dist/public/chunk.CK6Z-I-W.js +1 -0
  82. package/dist/public/chunk.CK6Z-I-W.js.br +1 -0
  83. package/dist/public/chunk.Cj1opA98.js +1 -0
  84. package/dist/public/chunk.Cj1opA98.js.br +0 -0
  85. package/dist/public/chunk.CvCu4yZb.js +2 -0
  86. package/dist/public/chunk.CvCu4yZb.js.br +0 -0
  87. package/dist/public/chunk.D93ZmnLR.js +1 -0
  88. package/dist/public/chunk.D93ZmnLR.js.br +6 -0
  89. package/dist/public/chunk.D9MCnLj_.js +7 -0
  90. package/dist/public/chunk.D9MCnLj_.js.br +0 -0
  91. package/dist/public/chunk.DOwjsMaD.js +1 -0
  92. package/dist/public/chunk.DOwjsMaD.js.br +0 -0
  93. package/dist/public/chunk.DYIu-C82.js +1 -0
  94. package/dist/public/chunk.DYIu-C82.js.br +0 -0
  95. package/dist/public/chunk.D_-fkSwu.js +1 -0
  96. package/dist/public/chunk.D_-fkSwu.js.br +0 -0
  97. package/dist/public/chunk.Dc4PCYcb.js +1 -0
  98. package/dist/public/chunk.Dc4PCYcb.js.br +0 -0
  99. package/dist/public/chunk.De1vj4hM.js +1 -0
  100. package/dist/public/chunk.De1vj4hM.js.br +0 -0
  101. package/dist/public/chunk.DuQak1OK.js +1 -0
  102. package/dist/public/chunk.DuQak1OK.js.br +0 -0
  103. package/dist/public/chunk.DxnuHDOY.js +1 -0
  104. package/dist/public/chunk.DxnuHDOY.js.br +0 -0
  105. package/dist/public/chunk.TIounDiA.js +1 -0
  106. package/dist/public/chunk.TIounDiA.js.br +0 -0
  107. package/dist/public/chunk.p3hCiSrt.js +80 -0
  108. package/dist/public/chunk.p3hCiSrt.js.br +0 -0
  109. package/dist/public/chunk.yh4jaMrg.js +1 -0
  110. package/dist/public/chunk.yh4jaMrg.js.br +0 -0
  111. package/dist/public/entry.DnXws2rz.js +2 -0
  112. package/dist/public/entry.DnXws2rz.js.br +0 -0
  113. package/dist/public/index.html +10 -0
  114. package/dist/public/index.html.br +1 -0
  115. package/package.json +18 -17
  116. package/src/providers/DevToolsMetadataProvider.ts +1 -1
  117. package/src/providers/DevToolsProvider.ts +115 -1
  118. package/src/ui/AppRouter.tsx +18 -0
  119. package/src/ui/components/DevLayout.tsx +14 -15
  120. package/src/ui/components/configuration/ConfigEnv.tsx +1 -1
  121. package/src/ui/components/dashboard/DevDashboard.tsx +32 -13
  122. package/src/ui/components/database/DatabaseEditor.tsx +5 -2
  123. package/src/ui/components/emails/DevEmails.tsx +250 -0
  124. package/src/ui/components/explorer/DevExplorer.tsx +1 -1
  125. package/src/ui/components/sms/DevSms.tsx +225 -0
  126. package/dist/index.browser.js +0 -224
  127. package/dist/index.browser.js.map +0 -1
  128. package/dist/index.d.ts +0 -499
  129. package/dist/index.js +0 -782
  130. package/dist/index.js.map +0 -1
Binary file
@@ -0,0 +1 @@
1
+ import{At as e,D as t,E as n,J as r,Lt as i,a,jt as o,tt as s}from"./chunk.p3hCiSrt.js";var c=i(o(),1),l=e(),u=(e,t)=>{if(!t)return e;let n=t.toLowerCase();return e.reduce((e,r)=>{if(r.children){let i=u(r.children,t);i.length>0?e.push({...r,children:i}):r.label.toLowerCase().includes(n)&&e.push(r)}else r.label.toLowerCase().includes(n)&&e.push(r);return e},[])},d=e=>{let t=0;for(let n of e)n.children&&n.children.length>0?t+=d(n.children):t++;return t},f=({nodes:e,selectedId:t,openNodes:n,search:r=``,onSelect:i,onToggle:o,showLeafCount:s=!0})=>(0,l.jsx)(a,{direction:`column`,gap:2,style:{minHeight:0},children:(0,c.useMemo)(()=>u(e,r),[e,r]).map(e=>(0,l.jsx)(p,{node:e,depth:0,selectedId:t,openNodes:n,onSelect:i,onToggle:o,showLeafCount:s},e.id))}),p=({node:e,depth:i,selectedId:o,openNodes:c,onSelect:u,onToggle:f,showLeafCount:m})=>{let h=!!e.children&&e.children.length>0,g=c.has(e.id),_=o===e.id,v=h?d(e.children):0;return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(s,{w:`100%`,py:4,className:`devtools-tree-node`,"data-selected":_||void 0,style:{borderRadius:6,paddingLeft:8+i*20,paddingRight:8,transition:`background 100ms ease`},onClick:()=>{h?f(e.id):u(e.id)},children:(0,l.jsxs)(a,{gap:8,wrap:`nowrap`,children:[h?(0,l.jsx)(a,{style:{width:14,flexShrink:0,display:`flex`,alignItems:`center`},children:g?(0,l.jsx)(t,{size:14,opacity:.5}):(0,l.jsx)(n,{size:14,opacity:.5})}):(0,l.jsx)(a,{style:{width:14,flexShrink:0,display:`flex`,alignItems:`center`}}),e.icon,(0,l.jsx)(r,{fz:12,fw:_?600:400,truncate:!0,style:{flex:1},children:e.label}),e.badge,h&&m&&v>0&&(0,l.jsx)(r,{fz:10,c:`dimmed`,style:{flexShrink:0},children:v})]})}),h&&g&&(0,l.jsx)(a,{direction:`column`,gap:2,style:{minHeight:0},children:e.children.map(e=>(0,l.jsx)(p,{node:e,depth:i+1,selectedId:o,openNodes:c,onSelect:u,onToggle:f,showLeafCount:m},e.id))})]})};export{f as t};
Binary file
@@ -0,0 +1,2 @@
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["chunk.DuQak1OK.js","chunk.p3hCiSrt.js","chunk.DOwjsMaD.js","chunk.CCbhJSL_.js","chunk.BHYZ9sAK.js","chunk.Bc7_n90V.js","chunk.De1vj4hM.js","chunk.TIounDiA.js","chunk.B9jGefQy.js","chunk.D93ZmnLR.js","chunk.yh4jaMrg.js","chunk.CK6Z-I-W.js","chunk.CJt_09bu.js","chunk.D9MCnLj_.js","asset.CHpVij2M.css","chunk.B82rsdDI.js","chunk.DYIu-C82.js","chunk.CvCu4yZb.js","chunk.Cj1opA98.js","chunk.9plHAFDW.js","chunk.Dc4PCYcb.js","chunk.DxnuHDOY.js","chunk.D_-fkSwu.js"])))=>i.map(i=>d[i]);
2
+ import{A as e,At as t,Mt as n,b as r,h as i,j as a,t as o,x as s}from"./chunk.p3hCiSrt.js";(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),e.crossOrigin===`use-credentials`?t.credentials=`include`:e.crossOrigin===`anonymous`?t.credentials=`omit`:t.credentials=`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var c=e(`outline`,`dashboard`,`Dashboard`,[[`path`,{d:`M10 13a2 2 0 1 0 4 0a2 2 0 1 0 -4 0`,key:`svg-0`}],[`path`,{d:`M13.45 11.55l2.05 -2.05`,key:`svg-1`}],[`path`,{d:`M6.4 20a9 9 0 1 1 11.2 0l-11.2 0`,key:`svg-2`}]]),l=e(`outline`,`database`,`Database`,[[`path`,{d:`M4 6a8 3 0 1 0 16 0a8 3 0 1 0 -16 0`,key:`svg-0`}],[`path`,{d:`M4 6v6a8 3 0 0 0 16 0v-6`,key:`svg-1`}],[`path`,{d:`M4 12v6a8 3 0 0 0 16 0v-6`,key:`svg-2`}]]),u=e(`outline`,`message`,`Message`,[[`path`,{d:`M8 9h8`,key:`svg-0`}],[`path`,{d:`M8 13h6`,key:`svg-1`}],[`path`,{d:`M18 4a3 3 0 0 1 3 3v8a3 3 0 0 1 -3 3h-5l-5 3v-3h-2a3 3 0 0 1 -3 -3v-8a3 3 0 0 1 3 -3h12`,key:`svg-2`}]]),d=e(`outline`,`settings`,`Settings`,[[`path`,{d:`M10.325 4.317c.426 -1.756 2.924 -1.756 3.35 0a1.724 1.724 0 0 0 2.573 1.066c1.543 -.94 3.31 .826 2.37 2.37a1.724 1.724 0 0 0 1.065 2.572c1.756 .426 1.756 2.924 0 3.35a1.724 1.724 0 0 0 -1.066 2.573c.94 1.543 -.826 3.31 -2.37 2.37a1.724 1.724 0 0 0 -2.572 1.065c-.426 1.756 -2.924 1.756 -3.35 0a1.724 1.724 0 0 0 -2.573 -1.066c-1.543 .94 -3.31 -.826 -2.37 -2.37a1.724 1.724 0 0 0 -1.065 -2.572c-1.756 -.426 -1.756 -2.924 0 -3.35a1.724 1.724 0 0 0 1.066 -2.573c-.94 -1.543 .826 -3.31 2.37 -2.37c1 .608 2.296 .07 2.572 -1.065`,key:`svg-0`}],[`path`,{d:`M9 12a3 3 0 1 0 6 0a3 3 0 0 0 -6 0`,key:`svg-1`}]]),f=e(`outline`,`sitemap`,`Sitemap`,[[`path`,{d:`M3 17a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v2a2 2 0 0 1 -2 2h-2a2 2 0 0 1 -2 -2l0 -2`,key:`svg-0`}],[`path`,{d:`M15 17a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v2a2 2 0 0 1 -2 2h-2a2 2 0 0 1 -2 -2l0 -2`,key:`svg-1`}],[`path`,{d:`M9 5a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v2a2 2 0 0 1 -2 2h-2a2 2 0 0 1 -2 -2l0 -2`,key:`svg-2`}],[`path`,{d:`M6 15v-1a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v1`,key:`svg-3`}],[`path`,{d:`M12 9l0 3`,key:`svg-4`}]]),p=e(`outline`,`topology-ring`,`TopologyRing`,[[`path`,{d:`M14 20a2 2 0 1 0 -4 0a2 2 0 0 0 4 0`,key:`svg-0`}],[`path`,{d:`M14 4a2 2 0 1 0 -4 0a2 2 0 0 0 4 0`,key:`svg-1`}],[`path`,{d:`M6 12a2 2 0 1 0 -4 0a2 2 0 0 0 4 0`,key:`svg-2`}],[`path`,{d:`M22 12a2 2 0 1 0 -4 0a2 2 0 0 0 4 0`,key:`svg-3`}],[`path`,{d:`M13.5 5.5l5 5`,key:`svg-4`}],[`path`,{d:`M5.5 13.5l5 5`,key:`svg-5`}],[`path`,{d:`M13.5 18.5l5 -5`,key:`svg-6`}],[`path`,{d:`M10.5 5.5l-5 5`,key:`svg-7`}]]),m=t(),h=`modulepreload`,g=function(e){return`/__devtools/`+e},_={},v=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}r=o(t.map(t=>{if(t=g(t,n),t in _)return;_[t]=!0;let r=t.endsWith(`.css`),i=r?`[rel="stylesheet"]`:``;if(n)for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}else if(document.querySelector(`link[href="${t}"]${i}`))return;let o=document.createElement(`link`);if(o.rel=r?`stylesheet`:h,r||(o.as=`script`),o.crossOrigin=``,o.href=t,a&&o.setAttribute(`nonce`,a),document.head.appendChild(o),r)return new Promise((e,n)=>{o.addEventListener(`load`,e),o.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})};n(class{ui=o({themes:[a]});layout=i({parent:this.ui.root,lazy:()=>v(()=>import(`./chunk.DuQak1OK.js`),__vite__mapDeps([0,1,2])),[Symbol.for(`alepha.page.preload`)]:`bfc0f5d4`});dashboard=i({path:`/`,label:`Dashboard`,icon:(0,m.jsx)(c,{}),parent:this.layout,lazy:()=>v(()=>import(`./chunk.CCbhJSL_.js`),__vite__mapDeps([3,1,4,5,6,7,2])),[Symbol.for(`alepha.page.preload`)]:`1465b743`});explorer=i({path:`/explorer`,label:`Explorer`,icon:(0,m.jsx)(f,{}),parent:this.layout,lazy:()=>v(()=>import(`./chunk.B9jGefQy.js`),__vite__mapDeps([8,1,9,4,7,2,10])),[Symbol.for(`alepha.page.preload`)]:`fc9abada`});db=i({path:`/db`,parent:this.layout,lazy:()=>v(()=>import(`./chunk.CK6Z-I-W.js`),__vite__mapDeps([11,1])),[Symbol.for(`alepha.page.preload`)]:`ea7ea43a`});dbErd=i({path:`/erd`,label:`Database`,icon:(0,m.jsx)(l,{}),parent:this.db,lazy:()=>v(()=>import(`./chunk.CJt_09bu.js`),__vite__mapDeps([12,1,13,14,7,2])),[Symbol.for(`alepha.page.preload`)]:`935dbb60`});dbEditor=i({path:`/editor`,label:`Database`,icon:(0,m.jsx)(l,{}),parent:this.db,lazy:()=>v(()=>import(`./chunk.B82rsdDI.js`),__vite__mapDeps([15,1,7,2,10])),[Symbol.for(`alepha.page.preload`)]:`30dd87a0`});dbEditorTable=i({path:`/editor/:table`,parent:this.db,lazy:()=>v(()=>import(`./chunk.B82rsdDI.js`),__vite__mapDeps([15,1,7,2,10])),[Symbol.for(`alepha.page.preload`)]:`30dd87a0`});dbEditorRecord=i({path:`/editor/:table/:id`,parent:this.db,lazy:()=>v(()=>import(`./chunk.B82rsdDI.js`),__vite__mapDeps([15,1,7,2,10])),[Symbol.for(`alepha.page.preload`)]:`30dd87a0`});conf=i({path:`/conf`,parent:this.layout,lazy:()=>v(()=>import(`./chunk.DYIu-C82.js`),__vite__mapDeps([16,1])),[Symbol.for(`alepha.page.preload`)]:`11bf7128`});confEnv=i({path:`/env`,label:`Configuration`,icon:(0,m.jsx)(d,{}),parent:this.conf,lazy:()=>v(()=>import(`./chunk.CvCu4yZb.js`),__vite__mapDeps([17,1,9,6,7,2])),[Symbol.for(`alepha.page.preload`)]:`1e4d954e`});confAtoms=i({path:`/atoms`,label:`Configuration`,icon:(0,m.jsx)(d,{}),parent:this.conf,lazy:()=>v(()=>import(`./chunk.Cj1opA98.js`),__vite__mapDeps([18,1,5,7,2,10])),[Symbol.for(`alepha.page.preload`)]:`1e40f4e0`});graph=i({path:`/graph`,label:`Graph`,icon:(0,m.jsx)(p,{}),parent:this.layout,lazy:()=>v(()=>import(`./chunk.9plHAFDW.js`),__vite__mapDeps([19,1,13,14,7,2])),[Symbol.for(`alepha.page.preload`)]:`4fded5f0`});emails=i({path:`/emails`,label:`Emails`,icon:(0,m.jsx)(r,{}),parent:this.layout,lazy:()=>v(()=>import(`./chunk.Dc4PCYcb.js`),__vite__mapDeps([20,1])),[Symbol.for(`alepha.page.preload`)]:`5a1d01de`});sms=i({path:`/sms`,label:`SMS`,icon:(0,m.jsx)(u,{}),parent:this.layout,lazy:()=>v(()=>import(`./chunk.DxnuHDOY.js`),__vite__mapDeps([21,1])),[Symbol.for(`alepha.page.preload`)]:`ed875639`});logs=i({path:`/logs`,label:`Logs`,icon:(0,m.jsx)(s,{}),parent:this.layout,lazy:()=>v(()=>import(`./chunk.D_-fkSwu.js`),__vite__mapDeps([22,1,9])),[Symbol.for(`alepha.page.preload`)]:`5e261ada`})});export{l as a,u as i,f as n,c as o,d as r,p as t};
Binary file
@@ -0,0 +1,10 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en" data-theme="midnight">
3
+ <head><meta charset="UTF-8">
4
+ <meta name="viewport" content="width=device-width, initial-scale=1">
5
+ <link rel="stylesheet" href="/__devtools/asset.Cxu56LSy.css">
6
+ <script type="module" crossorigin="" src="/__devtools/entry.DnXws2rz.js"></script>
7
+ <title>App</title>
8
+ </head>
9
+ <body><div id="root"></div></body>
10
+ </html>
@@ -0,0 +1 @@
1
+ n��qýlN[�h3�[���F��M!0�r,_[�H`Y�0Dd���-�0���� ��L��޲9DXO�p����n�ZR:��YbA�m�k�b�m3�œJ߰�`�[�)�?U������w����p��C$�ј�L��n�b�/+:��\P���5{_�A�
package/package.json CHANGED
@@ -5,8 +5,8 @@
5
5
  "alepha",
6
6
  "devtools"
7
7
  ],
8
- "author": "Nicolas Foures",
9
- "version": "0.19.1",
8
+ "author": "Feunard",
9
+ "version": "0.19.3",
10
10
  "type": "module",
11
11
  "engines": {
12
12
  "node": ">=22.0.0"
@@ -20,30 +20,30 @@
20
20
  "assets"
21
21
  ],
22
22
  "devDependencies": {
23
- "@alepha/ui": "0.19.1",
24
- "@biomejs/biome": "^2.4.8",
25
- "@mantine/core": "^8.3.18",
26
- "@mantine/hooks": "^8.3.18",
27
- "@tabler/icons-react": "^3.40.0",
28
- "@xyflow/react": "^12.10.1",
29
- "alepha": "0.19.1",
23
+ "@alepha/ui": "0.19.3",
24
+ "@biomejs/biome": "^2.4.10",
25
+ "@mantine/core": "^9.0.0",
26
+ "@mantine/hooks": "^9.0.0",
27
+ "@tabler/icons-react": "^3.41.1",
28
+ "@xyflow/react": "^12.10.2",
29
+ "alepha": "0.19.3",
30
30
  "react": "^19.2.4",
31
31
  "react-dom": "^19.2.4",
32
- "tsdown": "^0.21.4",
33
- "typescript": "^5.9.3",
34
- "vite": "^8.0.0",
35
- "vitest": "^4.1.0"
32
+ "tsdown": "^0.21.7",
33
+ "typescript": "^6.0.2",
34
+ "vite": "^8.0.3",
35
+ "vitest": "^4.1.2"
36
36
  },
37
37
  "peerDependencies": {
38
- "alepha": "0.19.1"
38
+ "alepha": "0.19.3"
39
39
  },
40
40
  "scripts": {
41
41
  "lint": "alepha lint",
42
42
  "typecheck": "alepha typecheck",
43
43
  "test": "alepha test",
44
44
  "dev:ui": "alepha dev --no-devtools",
45
- "build": "tsdown",
46
- "build:ui": "alepha build -t static && rm -rf assets/ui && cp -r dist/public assets/ui"
45
+ "build": "tsdown && yarn build:ui",
46
+ "build:ui": "alepha build -t static && rm -rf assets/ui && mkdir -p assets && cp -r dist/public assets/ui"
47
47
  },
48
48
  "repository": {
49
49
  "type": "git",
@@ -57,6 +57,7 @@
57
57
  "browser": "./dist/index.browser.js",
58
58
  "import": "./dist/index.js",
59
59
  "default": "./dist/index.js"
60
- }
60
+ },
61
+ "./package.json": "./package.json"
61
62
  }
62
63
  }
@@ -421,7 +421,7 @@ export class DevToolsMetadataProvider {
421
421
  mode: this.alepha.isProduction() ? "production" : "development",
422
422
  port,
423
423
  uptime: (this.dateTime.nowMillis() - this.startedAt) / 1000,
424
- memoryUsage: process.memoryUsage?.()?.rss ?? 0,
424
+ memoryUsage: process.memoryUsage?.()?.heapUsed ?? 0,
425
425
  };
426
426
  }
427
427
 
@@ -1,8 +1,10 @@
1
- import { $hook, $inject, Alepha, t } from "alepha";
1
+ import { $hook, $inject, $state, Alepha, t } from "alepha";
2
+ import { localEmailOptions } from "alepha/email";
2
3
  import { $logger, MemoryDestinationProvider } from "alepha/logger";
3
4
  import { RepositoryProvider } from "alepha/orm";
4
5
  import { $route, ServerProvider } from "alepha/server";
5
6
  import { $serve } from "alepha/server/static";
7
+ import { FileSystemProvider } from "alepha/system";
6
8
  import { devtoolsAssets } from "../assets.ts";
7
9
  import { devMetadataSchema } from "../schemas/DevMetadata.ts";
8
10
  import { DevToolsMetadataProvider } from "./DevToolsMetadataProvider.ts";
@@ -13,6 +15,8 @@ export class DevToolsProvider {
13
15
  protected readonly serverProvider = $inject(ServerProvider);
14
16
  protected readonly devCollectorProvider = $inject(DevToolsMetadataProvider);
15
17
  protected readonly memoryDestination = $inject(MemoryDestinationProvider);
18
+ protected readonly fs = $inject(FileSystemProvider);
19
+ protected readonly emailOptions = $state(localEmailOptions);
16
20
 
17
21
  protected readonly onStart = $hook({
18
22
  on: "start",
@@ -166,6 +170,116 @@ export class DevToolsProvider {
166
170
  },
167
171
  });
168
172
 
173
+ // -------------------------------------------------------------------------------------------------------------------
174
+ // Email endpoint
175
+ // -------------------------------------------------------------------------------------------------------------------
176
+
177
+ protected readonly emailsRoute = $route({
178
+ method: "GET",
179
+ path: "/__devtools/api/emails",
180
+ silent: true,
181
+ schema: {
182
+ response: t.object({
183
+ emails: t.array(
184
+ t.object({
185
+ to: t.text(),
186
+ subject: t.text(),
187
+ body: t.string(),
188
+ sentAt: t.text(),
189
+ }),
190
+ ),
191
+ }),
192
+ },
193
+ handler: async () => {
194
+ try {
195
+ const dir = this.emailOptions.directory;
196
+ const exists = await this.fs.exists(dir);
197
+ if (!exists) return { emails: [] };
198
+
199
+ const files = await this.fs.ls(dir);
200
+ const emailFiles = files.filter((f) => f.endsWith(".eml.json"));
201
+
202
+ const emails: Array<{
203
+ to: string;
204
+ subject: string;
205
+ body: string;
206
+ sentAt: string;
207
+ }> = [];
208
+
209
+ for (const file of emailFiles) {
210
+ try {
211
+ const data = await this.fs.readJsonFile<{
212
+ to: string;
213
+ subject: string;
214
+ body: string;
215
+ sentAt: string;
216
+ }>(this.fs.join(dir, file));
217
+ emails.push(data);
218
+ } catch {
219
+ // skip malformed files
220
+ }
221
+ }
222
+
223
+ emails.sort((a, b) => b.sentAt.localeCompare(a.sentAt));
224
+ return { emails };
225
+ } catch {
226
+ return { emails: [] };
227
+ }
228
+ },
229
+ });
230
+
231
+ // -------------------------------------------------------------------------------------------------------------------
232
+ // SMS endpoint
233
+ // -------------------------------------------------------------------------------------------------------------------
234
+
235
+ protected readonly smsRoute = $route({
236
+ method: "GET",
237
+ path: "/__devtools/api/sms",
238
+ silent: true,
239
+ schema: {
240
+ response: t.object({
241
+ messages: t.array(
242
+ t.object({
243
+ to: t.text(),
244
+ message: t.string(),
245
+ sentAt: t.text(),
246
+ }),
247
+ ),
248
+ }),
249
+ },
250
+ handler: async () => {
251
+ try {
252
+ const dir = "node_modules/.alepha/sms";
253
+ const exists = await this.fs.exists(dir);
254
+ if (!exists) return { messages: [] };
255
+
256
+ const files = await this.fs.ls(dir);
257
+ const smsFiles = files.filter((f) => f.endsWith(".sms.json"));
258
+
259
+ const messages: Array<{ to: string; message: string; sentAt: string }> =
260
+ [];
261
+
262
+ for (const file of smsFiles) {
263
+ try {
264
+ const data = await this.fs.readJsonFile<{
265
+ to: string;
266
+ message: string;
267
+ sentAt: string;
268
+ }>(this.fs.join(dir, file));
269
+ messages.push(data);
270
+ } catch {
271
+ // skip malformed files
272
+ }
273
+ }
274
+
275
+ messages.sort((a, b) => b.sentAt.localeCompare(a.sentAt));
276
+ return { messages };
277
+ } catch {
278
+ return { messages: [] };
279
+ }
280
+ },
281
+ });
282
+
169
283
  // -------------------------------------------------------------------------------------------------------------------
170
284
  // DB CRUD endpoints
171
285
  // -------------------------------------------------------------------------------------------------------------------
@@ -3,6 +3,8 @@ import {
3
3
  IconDashboard,
4
4
  IconDatabase,
5
5
  IconList,
6
+ IconMail,
7
+ IconMessage,
6
8
  IconSettings,
7
9
  IconSitemap,
8
10
  IconTopologyRing,
@@ -101,6 +103,22 @@ export class AppRouter {
101
103
  lazy: () => import("./components/graph/DevDependencyGraph.tsx"),
102
104
  });
103
105
 
106
+ emails = $page({
107
+ path: "/emails",
108
+ label: "Emails",
109
+ icon: <IconMail />,
110
+ parent: this.layout,
111
+ lazy: () => import("./components/emails/DevEmails.tsx"),
112
+ });
113
+
114
+ sms = $page({
115
+ path: "/sms",
116
+ label: "SMS",
117
+ icon: <IconMessage />,
118
+ parent: this.layout,
119
+ lazy: () => import("./components/sms/DevSms.tsx"),
120
+ });
121
+
104
122
  logs = $page({
105
123
  path: "/logs",
106
124
  label: "Logs",
@@ -1,15 +1,15 @@
1
1
  import {
2
- ActionButton,
3
2
  DarkModeButton,
4
3
  DashboardShell,
5
4
  Flex,
6
5
  OmnibarButton,
7
6
  } from "@alepha/ui";
8
7
  import {
9
- IconArrowLeft,
10
8
  IconDashboard,
11
9
  IconDatabase,
12
10
  IconList,
11
+ IconMail,
12
+ IconMessage,
13
13
  IconSettings,
14
14
  IconSitemap,
15
15
  IconTopologyRing,
@@ -68,6 +68,17 @@ export const DevLayout = () => {
68
68
  href: "/conf/env",
69
69
  },
70
70
  { type: "divider" },
71
+ {
72
+ label: "Emails",
73
+ icon: <IconMail />,
74
+ href: "/emails",
75
+ },
76
+ {
77
+ label: "SMS",
78
+ icon: <IconMessage />,
79
+ href: "/sms",
80
+ },
81
+ { type: "divider" },
71
82
  {
72
83
  label: "Graph",
73
84
  icon: <IconTopologyRing />,
@@ -96,19 +107,7 @@ export const DevLayout = () => {
96
107
  navbarFooter={<Flex />}
97
108
  footerHeight={24}
98
109
  headerHeight={60}
99
- navbarHeader={() => (
100
- <Flex align="center" justify="center" h="100%" w="100%">
101
- <ActionButton
102
- href="/"
103
- target="_self"
104
- variant="subtle"
105
- color="gray"
106
- size="sm"
107
- >
108
- <IconArrowLeft size={18} />
109
- </ActionButton>
110
- </Flex>
111
- )}
110
+ navbarHeader={() => <Flex />}
112
111
  sidebarProps={{
113
112
  collapsed: true,
114
113
  items: sidebarItems,
@@ -80,7 +80,7 @@ const EnvLine = ({ variable }: { variable: EnvVariable }) => {
80
80
  const sensitive = isSensitive(variable.name);
81
81
 
82
82
  return (
83
- <Flex>
83
+ <Flex direction="column">
84
84
  {/* Description as comment */}
85
85
  {variable.description?.split("\n").map((line, i) => (
86
86
  <Text key={i} fz={11} ff="monospace" c="dimmed" fs="italic" lh={1.6}>
@@ -1,5 +1,5 @@
1
1
  import { devMetadataSchema } from "@alepha/devtools";
2
- import { Flex, ui } from "@alepha/ui";
2
+ import { ActionButton, Flex, ui } from "@alepha/ui";
3
3
  import {
4
4
  Badge,
5
5
  Card,
@@ -19,6 +19,7 @@ import {
19
19
  IconDatabase,
20
20
  IconFileText,
21
21
  IconPlug,
22
+ IconRefresh,
22
23
  IconRoute,
23
24
  IconServer,
24
25
  IconSettings,
@@ -93,6 +94,7 @@ export const DevDashboard = () => {
93
94
  const [metadata, setMetadata] = useState<any>(null);
94
95
  const [logs, setLogs] = useState<LogEntry[]>([]);
95
96
  const [events, setEvents] = useState<LogEntry[]>([]);
97
+ const [reloading, setReloading] = useState(false);
96
98
 
97
99
  const fetchData = useCallback(async () => {
98
100
  if (document.visibilityState !== "visible") return;
@@ -112,6 +114,19 @@ export const DevDashboard = () => {
112
114
  }
113
115
  }, [http]);
114
116
 
117
+ const handleReload = useCallback(async () => {
118
+ setReloading(true);
119
+ try {
120
+ await http.fetch("/__devtools/api/reload", { method: "POST" });
121
+ setTimeout(() => {
122
+ fetchData();
123
+ setReloading(false);
124
+ }, 1000);
125
+ } catch {
126
+ setReloading(false);
127
+ }
128
+ }, [http, fetchData]);
129
+
115
130
  useEffect(() => {
116
131
  fetchData();
117
132
  const interval = setInterval(fetchData, 10_000);
@@ -191,17 +206,21 @@ export const DevDashboard = () => {
191
206
  <Flex direction="column" gap="lg">
192
207
  {/* App Stats */}
193
208
  <div>
194
- <Title
195
- order={5}
196
- mb="sm"
197
- c="dimmed"
198
- tt="uppercase"
199
- fz="xs"
200
- fw={600}
201
- lts={1}
202
- >
203
- System
204
- </Title>
209
+ <Flex justify="space-between" align="center" mb="sm">
210
+ <Title order={5} c="dimmed" tt="uppercase" fz="xs" fw={600} lts={1}>
211
+ System
212
+ </Title>
213
+ <ActionButton
214
+ size="xs"
215
+ variant="subtle"
216
+ color="gray"
217
+ loading={reloading}
218
+ onClick={handleReload}
219
+ icon={<IconRefresh size={14} />}
220
+ >
221
+ Reload
222
+ </ActionButton>
223
+ </Flex>
205
224
  <SimpleGrid cols={{ base: 2, sm: 3, md: 4, lg: 6 }} spacing="sm">
206
225
  {system && (
207
226
  <>
@@ -240,7 +259,7 @@ export const DevDashboard = () => {
240
259
  </SimpleGrid>
241
260
  </div>
242
261
 
243
- <Grid gutter="lg">
262
+ <Grid gap="lg">
244
263
  {/* Recent Events */}
245
264
  <Grid.Col span={{ base: 12, md: 7 }}>
246
265
  <Card
@@ -16,7 +16,7 @@ import {
16
16
  import { jsonSchemaToTypeBox, t } from "alepha";
17
17
  import { useInject } from "alepha/react";
18
18
  import { useForm } from "alepha/react/form";
19
- import { useRouter } from "alepha/react/router";
19
+ import { useRouter, useRouterState } from "alepha/react/router";
20
20
  import { HttpClient } from "alepha/server";
21
21
  import { useCallback, useEffect, useMemo, useState } from "react";
22
22
  import { TreeView, type TreeViewNode } from "../shared/TreeView.tsx";
@@ -107,12 +107,15 @@ const parseEditorPath = (pathname: string) => {
107
107
  export const DatabaseEditor = ({ entities }: { entities: any[] }) => {
108
108
  const http = useInject(HttpClient);
109
109
  const router = useRouter();
110
+ const state = useRouterState();
110
111
  const [records, setRecords] = useState<any[]>([]);
111
112
  const [loading, setLoading] = useState(false);
112
113
  const [search, setSearch] = useState("");
113
114
  const [pageInfo, setPageInfo] = useState<any>(null);
114
115
 
115
- const { table: selectedEntity, recordId } = parseEditorPath(router.pathname);
116
+ const { table: selectedEntity, recordId } = parseEditorPath(
117
+ state.url.pathname,
118
+ );
116
119
  const isNew = recordId === "new";
117
120
 
118
121
  const entity = entities.find((e) => e.name === selectedEntity);