@flexkit/studio 0.2.23 → 0.2.24

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 (82) hide show
  1. package/dist/{activity-nav-button-7RLCHOFV.js → activity-nav-button-4VTYGP4T.js} +2 -2
  2. package/dist/{activity-nav-button-7RLCHOFV.js.map → activity-nav-button-4VTYGP4T.js.map} +1 -1
  3. package/dist/chat-page-A7FG7WTN.js +4 -0
  4. package/dist/chat-page-A7FG7WTN.js.map +1 -0
  5. package/dist/{chunk-DAM7JM5J.js → chunk-3COXA5QH.js} +2 -2
  6. package/dist/{chunk-DAM7JM5J.js.map → chunk-3COXA5QH.js.map} +1 -1
  7. package/dist/{chunk-7HBT6L4U.js → chunk-3IUKXOKF.js} +2 -2
  8. package/dist/{chunk-7HBT6L4U.js.map → chunk-3IUKXOKF.js.map} +1 -1
  9. package/dist/{chunk-7ERLYAPR.js → chunk-5OGT6WGZ.js} +2 -2
  10. package/dist/{chunk-7ERLYAPR.js.map → chunk-5OGT6WGZ.js.map} +1 -1
  11. package/dist/{chunk-E2NDJLAI.js → chunk-AKW7EKYI.js} +3 -3
  12. package/dist/{chunk-E2NDJLAI.js.map → chunk-AKW7EKYI.js.map} +1 -1
  13. package/dist/{chunk-CJHMUEOB.js → chunk-HTSMODQB.js} +2 -2
  14. package/dist/{chunk-CJHMUEOB.js.map → chunk-HTSMODQB.js.map} +1 -1
  15. package/dist/chunk-I6Z3WLAX.js +2 -0
  16. package/dist/chunk-I6Z3WLAX.js.map +1 -0
  17. package/dist/{chunk-KQVLLOWJ.js → chunk-IQ2F2FFF.js} +2 -2
  18. package/dist/{chunk-KQVLLOWJ.js.map → chunk-IQ2F2FFF.js.map} +1 -1
  19. package/dist/{chunk-YRPFCYLR.js → chunk-JSJZKPXU.js} +3 -3
  20. package/dist/{chunk-YRPFCYLR.js.map → chunk-JSJZKPXU.js.map} +1 -1
  21. package/dist/{chunk-ZIHC7WWT.js → chunk-L3GBAK54.js} +3 -3
  22. package/dist/{chunk-ZIHC7WWT.js.map → chunk-L3GBAK54.js.map} +1 -1
  23. package/dist/chunk-MNLYE7DK.js +3 -0
  24. package/dist/chunk-MNLYE7DK.js.map +1 -0
  25. package/dist/{chunk-CAMLITJT.js → chunk-NO3AH2M3.js} +3 -3
  26. package/dist/{chunk-CAMLITJT.js.map → chunk-NO3AH2M3.js.map} +1 -1
  27. package/dist/{chunk-EYIV4KVY.js → chunk-NSVX6HEN.js} +3 -3
  28. package/dist/{chunk-EYIV4KVY.js.map → chunk-NSVX6HEN.js.map} +1 -1
  29. package/dist/chunk-SZOEW2TL.js +8 -0
  30. package/dist/chunk-SZOEW2TL.js.map +1 -0
  31. package/dist/chunk-U6E7GNQW.js +2 -0
  32. package/dist/chunk-U6E7GNQW.js.map +1 -0
  33. package/dist/{chunk-YEWTJHKW.js → chunk-UBFBXBPG.js} +2 -2
  34. package/dist/{chunk-YEWTJHKW.js.map → chunk-UBFBXBPG.js.map} +1 -1
  35. package/dist/{chunk-AMUTDCI7.js → chunk-XV2B3W6Z.js} +3 -3
  36. package/dist/{chunk-AMUTDCI7.js.map → chunk-XV2B3W6Z.js.map} +1 -1
  37. package/dist/{entry-O75LJP6A.js → entry-RMRLV3NM.js} +2 -2
  38. package/dist/{entry-O75LJP6A.js.map → entry-RMRLV3NM.js.map} +1 -1
  39. package/dist/index.js +7 -7
  40. package/dist/index.js.map +1 -1
  41. package/dist/{list-R3FH7CYE.js → list-GVATECOW.js} +2 -2
  42. package/dist/{list-R3FH7CYE.js.map → list-GVATECOW.js.map} +1 -1
  43. package/dist/{list-RZROVSNS.js → list-HR55TZQX.js} +3 -3
  44. package/dist/{list-RZROVSNS.js.map → list-HR55TZQX.js.map} +1 -1
  45. package/dist/pages-OJYYLSI3.js +5 -0
  46. package/dist/pages-OJYYLSI3.js.map +1 -0
  47. package/dist/{plugin-pages-IPEYHBKC.js → plugin-pages-BS2IMNRU.js} +2 -2
  48. package/dist/{plugin-pages-IPEYHBKC.js.map → plugin-pages-BS2IMNRU.js.map} +1 -1
  49. package/dist/record-links-2QWJFFZF.js +2 -0
  50. package/dist/{record-links-D5GJWZIK.js.map → record-links-2QWJFFZF.js.map} +1 -1
  51. package/dist/{root-LWFZRWNO.js → root-54BI6S4V.js} +3 -3
  52. package/dist/{root-LWFZRWNO.js.map → root-54BI6S4V.js.map} +1 -1
  53. package/dist/{root-QRSWWD23.js → root-E35GZ7SV.js} +3 -3
  54. package/dist/{root-QRSWWD23.js.map → root-E35GZ7SV.js.map} +1 -1
  55. package/dist/{root-QKNPDDE4.js → root-GAB2SFFF.js} +2 -2
  56. package/dist/{root-QKNPDDE4.js.map → root-GAB2SFFF.js.map} +1 -1
  57. package/dist/{root-XXHLLKQS.js → root-JWXXF653.js} +3 -3
  58. package/dist/{root-XXHLLKQS.js.map → root-JWXXF653.js.map} +1 -1
  59. package/dist/{root-TL5U37VT.js → root-U52KZQSD.js} +2 -2
  60. package/dist/{root-TL5U37VT.js.map → root-U52KZQSD.js.map} +1 -1
  61. package/dist/{root-3J3XAFUX.js → root-ZCXGZCUT.js} +2 -2
  62. package/dist/{root-3J3XAFUX.js.map → root-ZCXGZCUT.js.map} +1 -1
  63. package/dist/{search-KXTZNQCX.js → search-IOYOKT6M.js} +2 -2
  64. package/dist/{search-KXTZNQCX.js.map → search-IOYOKT6M.js.map} +1 -1
  65. package/dist/{skills-pages-CDOGI5ZZ.js → skills-pages-MA6JLBB4.js} +2 -2
  66. package/dist/{skills-pages-CDOGI5ZZ.js.map → skills-pages-MA6JLBB4.js.map} +1 -1
  67. package/dist/{source-HTBEV3UC.js → source-3YZNNITL.js} +2 -2
  68. package/dist/{source-HTBEV3UC.js.map → source-3YZNNITL.js.map} +1 -1
  69. package/package.json +3 -3
  70. package/dist/chat-page-ASH67R6B.js +0 -4
  71. package/dist/chat-page-ASH67R6B.js.map +0 -1
  72. package/dist/chunk-7HEARTFH.js +0 -2
  73. package/dist/chunk-7HEARTFH.js.map +0 -1
  74. package/dist/chunk-FUX7UG36.js +0 -8
  75. package/dist/chunk-FUX7UG36.js.map +0 -1
  76. package/dist/chunk-QCVQJN5O.js +0 -2
  77. package/dist/chunk-QCVQJN5O.js.map +0 -1
  78. package/dist/chunk-SY67F62K.js +0 -3
  79. package/dist/chunk-SY67F62K.js.map +0 -1
  80. package/dist/pages-NBXY5WPW.js +0 -5
  81. package/dist/pages-NBXY5WPW.js.map +0 -1
  82. package/dist/record-links-D5GJWZIK.js +0 -2
@@ -0,0 +1,2 @@
1
+ import'./index.css';import {b as b$1}from'./chunk-MNLYE7DK.js';import {s}from'./chunk-DGIY4SKN.js';import {c,h,i,k,l,j as j$1}from'./chunk-32ZU4MLE.js';import {b}from'./chunk-6NRQMG26.js';import {useSyncExternalStore,useId,useState}from'react';import {ExternalLinkIcon,LoaderCircle}from'lucide-react';import {jsx,jsxs}from'react/jsx-runtime';var $="/plugins/oauth/start",P=class extends Error{code="account_mismatch";constructor(){super('You signed in with a different account. Use "Connect another account" to add it.'),this.name="PluginAccountMismatchError";}};function O(e){let t;try{t=new URL(e);}catch{return null}return t.protocol!=="https:"||t.username!==""||t.password!==""?null:t}function M(e,t){let r=b$1(),i=O(e),n=O(t);return !i||!n||i.origin!==r||i.pathname!==$||n.origin!==r||n.pathname!=="/"?null:{href:i.href,origin:r}}async function _(e,t,r,i){let n=window.open("about:blank",`flexkit-plugin-${crypto.randomUUID()}`,"popup,width=560,height=720");if(!n)throw new Error("Allow popups for Studio, then connect again.");let o;try{o=await e.connectPlugins({pluginId:t,scope:r,studioOrigin:window.location.origin,...i?.connectionId?{connectionId:i.connectionId}:{}});}catch(l){throw n.close(),l}let s=M(o.authorizeUrl,o.completionOrigin);if(!s)throw n.close(),new Error("Connection could not be started.");let u=s.origin;await new Promise((l,w)=>{let g=false,k=false,c=false,f=a=>{if(!k){if(k=true,window.clearInterval(N),window.clearTimeout(z),window.removeEventListener("message",I),n.close(),a){w(a);return}l();}},h=async()=>{if(g||k)return;g=true;let a;try{a=await e.pluginOAuthStatus(o.transactionId);}catch{g=false;return}if(g=false,a.status==="complete"){f();return}if(!c&&n.closed&&a.status==="pending"){f(new Error("Connection window was closed."));return}(a.status==="failed"||new Date(a.expires_at).getTime()<Date.now())&&f(new Error("Connection was not completed. Please try again."));},I=a=>{if(a.origin!==u||a.source!==n||!a.data||typeof a.data!="object")return;let m=a.data;if(m.type==="flexkit:plugin-oauth-ready"&&m.transactionId===o.transactionId){c=true,n.postMessage({type:"flexkit:plugin-oauth-start",transactionId:o.transactionId,ticket:o.launchTicket},u);return}if(m.type==="flexkit:plugin-oauth"&&m.transactionId===o.transactionId){if(m.status==="failed"&&m.error==="account_mismatch"){f(new P);return}h();}},N=window.setInterval(()=>{h();},2e3),z=window.setTimeout(()=>f(new Error("Connection timed out. Please try again.")),6e5);window.addEventListener("message",I),n.location.href=s.href;});}function H(e,t){if(!t)return true;try{return new RegExp(t,"u").test(e)}catch{return true}}function B(e){if(!e)return null;try{return new RegExp(e,"u")}catch{return null}}function Z(e,t){let r=e.split(/[\s"'`()<>[\]{},;:=!?&]+/).map(o=>o.replace(/\.+$/,"")).filter(Boolean),i=null,n=new Set;for(let o of t){let s=B(o.connect?.type==="api-token"?o.connect.pattern:null);for(let u of s?r:[])s.test(u)&&(i??=o,n.add(u));}return i?{plugin:i,tokens:[...n]}:null}var T=null,v=0,C=null,x=new Set;function F(e){T=e,x.forEach(t=>t());}function j(e){return x.add(e),()=>x.delete(e)}function le(e,t,r,i){let{connect:n}=t;if(n?.type!=="api-token")return _(e,t.id,r,i).then(()=>true);C?.();let o=++v;return new Promise(s=>{let u={id:o,plugin:{...t,connect:n},submit:async l=>{await e.connectPluginToken({pluginId:t.id,scope:r,token:l,...i?.connectionId?{connectionId:i.connectionId}:{}});},settle:l=>{T?.id===o&&F(null),v===o&&(C=null),s(l);}};C=()=>u.settle(false),setTimeout(()=>{v===o&&F(u);});})}function K(e){if(!e)return null;try{let t=new URL(e);return t.protocol==="https:"?t.href:null}catch{return null}}function ae(){let e=useSyncExternalStore(j,()=>T,()=>null);return e?jsx(Q,{request:e},e.id):null}function Q({request:e}){let{connect:t,name:r}=e.plugin,i$1=useId(),[n,o]=useState(""),[s$1,u]=useState(null),[l$1,w]=useState(false),g=K(t.helpUrl);async function k$1(c){c.preventDefault();let f=n.trim();if(!(l$1||!f)){if(!H(f,t.pattern)){u(`That does not look like a ${t.tokenLabel}.`);return}w(true),u(null);try{await e.submit(f),o(""),e.settle(!0);}catch(h){u(h instanceof Error?h.message:`${r} could not be connected.`);}finally{w(false);}}}return jsx(c,{open:true,onOpenChange:c=>{!c&&!l$1&&e.settle(false);},children:jsx(h,{children:jsxs("form",{className:"fk:flex fk:flex-col fk:gap-4",onSubmit:c=>{k$1(c);},children:[jsxs(i,{children:[jsxs(k,{children:["Connect ",r]}),jsxs(l,{children:["Paste a ",t.tokenLabel,". Flexkit stores it encrypted and sends it only to ",r,"; the agent can use"," ",r,"'s tools but never sees the token. Give it read access only, unless the agent should change things in ",r,"."]})]}),jsxs("div",{className:"fk:flex fk:flex-col fk:gap-2",children:[jsx("label",{className:"fk:text-sm fk:font-medium",htmlFor:i$1,children:t.tokenLabel}),jsx(s,{"aria-describedby":s$1?`${i$1}-error`:void 0,"aria-invalid":s$1?true:void 0,autoComplete:"off",autoFocus:true,disabled:l$1,id:i$1,placeholder:t.placeholder??void 0,spellCheck:false,type:"password",value:n,onChange:c=>{o(c.target.value),u(null);}}),s$1?jsx("p",{className:"fk:text-sm fk:text-destructive",id:`${i$1}-error`,children:s$1}):null,g?jsxs("a",{className:"fk:inline-flex fk:items-center fk:gap-1 fk:text-sm fk:text-muted-foreground fk:underline-offset-4 fk:hover:underline",href:g,rel:"noreferrer",target:"_blank",children:["How to create a ",t.tokenLabel,jsx(ExternalLinkIcon,{className:"fk:size-3.5"})]}):null]}),jsxs(j$1,{children:[jsx(b,{disabled:l$1,size:"sm",type:"button",variant:"outline",onClick:()=>e.settle(false),children:"Cancel"}),jsxs(b,{disabled:l$1||!n.trim(),size:"sm",type:"submit",children:[l$1?jsx(LoaderCircle,{className:"fk:size-4 fk:animate-spin"}):null,"Connect"]})]})]})})})}export{P as a,_ as b,Z as c,le as d,ae as e};//# sourceMappingURL=chunk-U6E7GNQW.js.map
2
+ //# sourceMappingURL=chunk-U6E7GNQW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/apps/ai/plugin-oauth.ts","../src/apps/ai/plugin-token-format.ts","../src/apps/ai/plugin-token.tsx"],"names":["OAUTH_START_PATH","PluginAccountMismatchError","httpsUrl","value","url","trustedPluginOAuthTargets","authorizeUrl","completionOrigin","origin","getPlatformOrigin","authorize","completion","connectPluginPopup","api","pluginId","scope","options","popup","transaction","error","targets","expectedOrigin","resolve","reject","polling","finished","handedOff","finish","interval","timeout","onMessage","poll","status","event","payload","matchesTokenPattern","token","pattern","compileTokenPattern","findPastedPluginToken","text","plugins","words","word","found","tokens","plugin","request","lastRequestId","cancelLatest","listeners","setRequest","next","listener","subscribe","connectPlugin","connect","id","connected","httpsHref","PluginTokenDialogHost","current","useSyncExternalStore","jsx","PluginTokenDialog","name","inputId","useId","setToken","useState","setError","saving","setSaving","helpHref","save","failure","Dialog","open","DialogContent","jsxs","DialogHeader","DialogTitle","DialogDescription","Input","ExternalLinkIcon","DialogFooter","Button","LoaderCircle"],"mappings":"sVAGA,IAAMA,CAAAA,CAAmB,sBAAA,CAGZC,CAAAA,CAAN,cAAyC,KAAM,CAC3C,IAAA,CAAO,kBAAA,CAEhB,WAAA,EAAc,CACZ,KAAA,CAAM,kFAAkF,EACxF,IAAA,CAAK,IAAA,CAAO,6BACd,CACF,EAEA,SAASC,CAAAA,CAASC,CAAAA,CAA2B,CAC3C,IAAIC,CAAAA,CAEJ,GAAI,CACFA,CAAAA,CAAM,IAAI,GAAA,CAAID,CAAK,EACrB,CAAA,KAAQ,CACN,OAAO,IACT,CAEA,OAAIC,CAAAA,CAAI,QAAA,GAAa,QAAA,EAAYA,CAAAA,CAAI,QAAA,GAAa,EAAA,EAAMA,CAAAA,CAAI,QAAA,GAAa,EAAA,CAChE,KAGFA,CACT,CAGA,SAASC,CAAAA,CACPC,CAAAA,CACAC,CAAAA,CACyC,CACzC,IAAMC,CAAAA,CAASC,GAAAA,EAAkB,CAC3BC,CAAAA,CAAYR,CAAAA,CAASI,CAAY,CAAA,CACjCK,CAAAA,CAAaT,EAASK,CAAgB,CAAA,CAU5C,OARI,CAACG,CAAAA,EAAa,CAACC,CAAAA,EAIfD,CAAAA,CAAU,MAAA,GAAWF,CAAAA,EAAUE,CAAAA,CAAU,QAAA,GAAaV,CAAAA,EAItDW,CAAAA,CAAW,MAAA,GAAWH,CAAAA,EAAUG,EAAW,QAAA,GAAa,GAAA,CACnD,IAAA,CAGF,CAAE,IAAA,CAAMD,CAAAA,CAAU,IAAA,CAAM,MAAA,CAAAF,CAAO,CACxC,CAGA,eAAsBI,CAAAA,CACpBC,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CACAC,EACe,CACf,IAAMC,CAAAA,CAAQ,MAAA,CAAO,IAAA,CAAK,aAAA,CAAe,CAAA,eAAA,EAAkB,MAAA,CAAO,UAAA,EAAY,CAAA,CAAA,CAAI,4BAA4B,CAAA,CAE9G,GAAI,CAACA,CAAAA,CACH,MAAM,IAAI,KAAA,CAAM,8CAA8C,CAAA,CAGhE,IAAIC,CAAAA,CAEJ,GAAI,CACFA,CAAAA,CAAc,MAAML,CAAAA,CAAI,cAAA,CAAe,CACrC,QAAA,CAAAC,CAAAA,CACA,KAAA,CAAAC,EACA,YAAA,CAAc,MAAA,CAAO,QAAA,CAAS,MAAA,CAC9B,GAAIC,CAAAA,EAAS,YAAA,CAAe,CAAE,YAAA,CAAcA,CAAAA,CAAQ,YAAa,CAAA,CAAI,EACvE,CAAC,EACH,OAASG,CAAAA,CAAO,CACd,MAAAF,CAAAA,CAAM,KAAA,EAAM,CACNE,CACR,CAEA,IAAMC,CAAAA,CAAUf,CAAAA,CAA0Ba,CAAAA,CAAY,YAAA,CAAcA,CAAAA,CAAY,gBAAgB,CAAA,CAEhG,GAAI,CAACE,CAAAA,CACH,MAAAH,CAAAA,CAAM,KAAA,EAAM,CACN,IAAI,KAAA,CAAM,kCAAkC,CAAA,CAGpD,IAAMI,CAAAA,CAAiBD,CAAAA,CAAQ,MAAA,CAE/B,MAAM,IAAI,QAAc,CAACE,CAAAA,CAASC,CAAAA,GAAW,CAC3C,IAAIC,CAAAA,CAAU,KAAA,CACVC,CAAAA,CAAW,KAAA,CAKXC,CAAAA,CAAY,KAAA,CACVC,CAAAA,CAAUR,CAAAA,EAAkB,CAChC,GAAI,CAAAM,EAUJ,CAAA,GANAA,CAAAA,CAAW,IAAA,CACX,MAAA,CAAO,aAAA,CAAcG,CAAQ,CAAA,CAC7B,MAAA,CAAO,YAAA,CAAaC,CAAO,CAAA,CAC3B,MAAA,CAAO,mBAAA,CAAoB,SAAA,CAAWC,CAAS,CAAA,CAC/Cb,EAAM,KAAA,EAAM,CAERE,CAAAA,CAAO,CACTI,CAAAA,CAAOJ,CAAK,CAAA,CAEZ,MACF,CAEAG,CAAAA,GAAQ,CACV,CAAA,CACMS,CAAAA,CAAO,SAAY,CACvB,GAAIP,GAAWC,CAAAA,CACb,OAGFD,CAAAA,CAAU,IAAA,CACV,IAAIQ,CAAAA,CAEJ,GAAI,CACFA,CAAAA,CAAS,MAAMnB,CAAAA,CAAI,iBAAA,CAAkBK,CAAAA,CAAY,aAAa,EAChE,CAAA,KAAQ,CACNM,CAAAA,CAAU,KAAA,CAEV,MACF,CAIA,GAFAA,CAAAA,CAAU,KAAA,CAENQ,CAAAA,CAAO,MAAA,GAAW,UAAA,CAAY,CAChCL,CAAAA,EAAO,CAEP,MACF,CAEA,GAAI,CAACD,CAAAA,EAAaT,CAAAA,CAAM,MAAA,EAAUe,CAAAA,CAAO,MAAA,GAAW,SAAA,CAAW,CAC7DL,CAAAA,CAAO,IAAI,KAAA,CAAM,+BAA+B,CAAC,CAAA,CAEjD,MACF,CAAA,CAEIK,CAAAA,CAAO,SAAW,QAAA,EAAY,IAAI,IAAA,CAAKA,CAAAA,CAAO,UAAU,CAAA,CAAE,OAAA,EAAQ,CAAI,IAAA,CAAK,GAAA,EAAI,GACjFL,CAAAA,CAAO,IAAI,KAAA,CAAM,iDAAiD,CAAC,EAEvE,CAAA,CACMG,CAAAA,CAAaG,CAAAA,EAAiC,CAClD,GAAIA,CAAAA,CAAM,MAAA,GAAWZ,CAAAA,EAAkBY,CAAAA,CAAM,MAAA,GAAWhB,CAAAA,EAAS,CAACgB,CAAAA,CAAM,IAAA,EAAQ,OAAOA,CAAAA,CAAM,MAAS,QAAA,CACpG,OAGF,IAAMC,CAAAA,CAAUD,CAAAA,CAAM,IAAA,CAEtB,GAAIC,CAAAA,CAAQ,IAAA,GAAS,4BAAA,EAAgCA,CAAAA,CAAQ,aAAA,GAAkBhB,CAAAA,CAAY,aAAA,CAAe,CACxGQ,CAAAA,CAAY,KACZT,CAAAA,CAAM,WAAA,CACJ,CACE,IAAA,CAAM,4BAAA,CACN,aAAA,CAAeC,CAAAA,CAAY,aAAA,CAC3B,MAAA,CAAQA,CAAAA,CAAY,YACtB,CAAA,CACAG,CACF,CAAA,CAEA,MACF,CAEA,GAAIa,CAAAA,CAAQ,IAAA,GAAS,sBAAA,EAA0BA,CAAAA,CAAQ,aAAA,GAAkBhB,CAAAA,CAAY,aAAA,CAAe,CAClG,GAAIgB,CAAAA,CAAQ,MAAA,GAAW,QAAA,EAAYA,CAAAA,CAAQ,KAAA,GAAU,kBAAA,CAAoB,CACvEP,EAAO,IAAI1B,CAA4B,CAAA,CAEvC,MACF,CAEK8B,CAAAA,GACP,CACF,CAAA,CACMH,CAAAA,CAAW,MAAA,CAAO,WAAA,CAAY,IAAM,CACnCG,CAAAA,GACP,EAAG,GAAI,CAAA,CACDF,CAAAA,CAAU,MAAA,CAAO,UAAA,CAAW,IAAMF,CAAAA,CAAO,IAAI,KAAA,CAAM,yCAAyC,CAAC,CAAA,CAAG,GAAO,CAAA,CAC7G,MAAA,CAAO,gBAAA,CAAiB,UAAWG,CAAS,CAAA,CAC5Cb,CAAAA,CAAM,QAAA,CAAS,IAAA,CAAOG,CAAAA,CAAQ,KAChC,CAAC,EACH,CC1LO,SAASe,CAAAA,CAAoBC,CAAAA,CAAeC,CAAAA,CAAiC,CAClF,GAAI,CAACA,CAAAA,CACH,OAAO,KAAA,CAGT,GAAI,CACF,OAAO,IAAI,MAAA,CAAOA,CAAAA,CAAS,GAAG,CAAA,CAAE,IAAA,CAAKD,CAAK,CAC5C,CAAA,KAAQ,CAEN,OAAO,KACT,CACF,CAGA,SAASE,CAAAA,CAAoBD,CAAAA,CAAuC,CAClE,GAAI,CAACA,CAAAA,CACH,OAAO,IAAA,CAGT,GAAI,CACF,OAAO,IAAI,OAAOA,CAAAA,CAAS,GAAG,CAChC,CAAA,KAAQ,CACN,OAAO,IACT,CACF,CAOO,SAASE,CAAAA,CACdC,CAAAA,CACAC,CAAAA,CACwD,CAGxD,IAAMC,CAAAA,CAAQF,EACX,KAAA,CAAM,0BAA0B,CAAA,CAChC,GAAA,CAAKG,CAAAA,EAASA,CAAAA,CAAK,OAAA,CAAQ,MAAA,CAAQ,EAAE,CAAC,CAAA,CACtC,MAAA,CAAO,OAAO,CAAA,CACbC,CAAAA,CAAkC,IAAA,CAChCC,EAAS,IAAI,GAAA,CAEnB,IAAA,IAAWC,CAAAA,IAAUL,CAAAA,CAAS,CAC5B,IAAMJ,CAAAA,CAAUC,CAAAA,CAAoBQ,CAAAA,CAAO,OAAA,EAAS,IAAA,GAAS,WAAA,CAAcA,CAAAA,CAAO,OAAA,CAAQ,OAAA,CAAU,IAAI,CAAA,CAExG,IAAA,IAAWH,CAAAA,IAAQN,CAAAA,CAAUK,CAAAA,CAAQ,EAAC,CAChCL,CAAAA,CAAS,IAAA,CAAKM,CAAI,CAAA,GACpBC,CAAAA,GAAUE,CAAAA,CACVD,CAAAA,CAAO,GAAA,CAAIF,CAAI,GAGrB,CAEA,OAAOC,CAAAA,CAAQ,CAAE,MAAA,CAAQA,CAAAA,CAAO,MAAA,CAAQ,CAAC,GAAGC,CAAM,CAAE,CAAA,CAAI,IAC1D,CCjCA,IAAIE,EAA+B,IAAA,CAC/BC,CAAAA,CAAgB,CAAA,CAEhBC,CAAAA,CAAoC,IAAA,CAClCC,CAAAA,CAAY,IAAI,GAAA,CAEtB,SAASC,CAAAA,CAAWC,CAAAA,CAAiC,CACnDL,CAAAA,CAAUK,CAAAA,CACVF,CAAAA,CAAU,OAAA,CAASG,GAAaA,CAAAA,EAAU,EAC5C,CAEA,SAASC,CAAAA,CAAUD,CAAAA,CAAkC,CACnD,OAAAH,CAAAA,CAAU,GAAA,CAAIG,CAAQ,CAAA,CAEf,IAAMH,CAAAA,CAAU,MAAA,CAAOG,CAAQ,CACxC,CASO,SAASE,EAAAA,CACd1C,CAAAA,CACAiC,CAAAA,CACA/B,CAAAA,CACAC,CAAAA,CACkB,CAClB,GAAM,CAAE,OAAA,CAAAwC,CAAQ,CAAA,CAAIV,CAAAA,CAEpB,GAAIU,GAAS,IAAA,GAAS,WAAA,CACpB,OAAO5C,CAAAA,CAAmBC,CAAAA,CAAKiC,CAAAA,CAAO,EAAA,CAAI/B,CAAAA,CAAOC,CAAO,CAAA,CAAE,IAAA,CAAK,IAAM,IAAI,CAAA,CAI3EiC,CAAAA,IAAe,CAEf,IAAMQ,CAAAA,CAAK,EAAET,CAAAA,CAEb,OAAO,IAAI,OAAA,CAAkB1B,CAAAA,EAAY,CACvC,IAAM8B,CAAAA,CAAqB,CACzB,EAAA,CAAAK,CAAAA,CACA,MAAA,CAAQ,CAAE,GAAGX,EAAQ,OAAA,CAAAU,CAAQ,CAAA,CAC7B,MAAA,CAAQ,MAAOpB,CAAAA,EAAU,CACvB,MAAMvB,CAAAA,CAAI,kBAAA,CAAmB,CAC3B,QAAA,CAAUiC,CAAAA,CAAO,EAAA,CACjB,KAAA,CAAA/B,CAAAA,CACA,MAAAqB,CAAAA,CACA,GAAIpB,CAAAA,EAAS,YAAA,CAAe,CAAE,YAAA,CAAcA,CAAAA,CAAQ,YAAa,CAAA,CAAI,EACvE,CAAC,EACH,CAAA,CACA,MAAA,CAAS0C,CAAAA,EAAc,CAEjBX,CAAAA,EAAS,EAAA,GAAOU,CAAAA,EAClBN,CAAAA,CAAW,IAAI,CAAA,CAGbH,CAAAA,GAAkBS,CAAAA,GACpBR,CAAAA,CAAe,IAAA,CAAA,CAGjB3B,CAAAA,CAAQoC,CAAS,EACnB,CACF,CAAA,CAEAT,CAAAA,CAAe,IAAMG,CAAAA,CAAK,MAAA,CAAO,KAAK,CAAA,CAItC,UAAA,CAAW,IAAM,CACXJ,CAAAA,GAAkBS,CAAAA,EACpBN,CAAAA,CAAWC,CAAI,EAEnB,CAAC,EACH,CAAC,CACH,CAEA,SAASO,CAAAA,CAAUxD,CAAAA,CAAqC,CACtD,GAAI,CAACA,CAAAA,CACH,OAAO,IAAA,CAGT,GAAI,CACF,IAAMC,CAAAA,CAAM,IAAI,GAAA,CAAID,CAAK,EAEzB,OAAOC,CAAAA,CAAI,QAAA,GAAa,QAAA,CAAWA,CAAAA,CAAI,IAAA,CAAO,IAChD,CAAA,KAAQ,CACN,OAAO,IACT,CACF,CAGO,SAASwD,EAAAA,EAA4C,CAC1D,IAAMC,CAAAA,CAAUC,oBAAAA,CACdR,CAAAA,CACA,IAAMP,CAAAA,CACN,IAAM,IACR,CAAA,CAGA,OAAOc,CAAAA,CAAUE,GAAAA,CAACC,CAAAA,CAAA,CAAmC,OAAA,CAASH,CAAAA,CAAAA,CAArBA,CAAAA,CAAQ,EAAsB,CAAA,CAAK,IAC9E,CAEA,SAASG,CAAAA,CAAkB,CAAE,OAAA,CAASH,CAAQ,CAAA,CAA2C,CACvF,GAAM,CAAE,OAAA,CAAAL,CAAAA,CAAS,IAAA,CAAAS,CAAK,EAAIJ,CAAAA,CAAQ,MAAA,CAC5BK,GAAAA,CAAUC,KAAAA,EAAM,CAChB,CAAC/B,CAAAA,CAAOgC,CAAQ,CAAA,CAAIC,QAAAA,CAAS,EAAE,CAAA,CAC/B,CAAClD,GAAAA,CAAOmD,CAAQ,CAAA,CAAID,SAAwB,IAAI,CAAA,CAChD,CAACE,GAAAA,CAAQC,CAAS,CAAA,CAAIH,QAAAA,CAAS,KAAK,EACpCI,CAAAA,CAAWd,CAAAA,CAAUH,CAAAA,CAAQ,OAAO,CAAA,CAE1C,eAAekB,GAAAA,CAAKzC,CAAAA,CAAiC,CACnDA,CAAAA,CAAM,cAAA,EAAe,CACrB,IAAM9B,CAAAA,CAAQiC,CAAAA,CAAM,IAAA,EAAK,CAEzB,GAAI,EAAAmC,GAAAA,EAAU,CAACpE,CAAAA,CAAAA,CAIf,CAAA,GAAI,CAACgC,CAAAA,CAAoBhC,EAAOqD,CAAAA,CAAQ,OAAO,CAAA,CAAG,CAChDc,CAAAA,CAAS,CAAA,0BAAA,EAA6Bd,CAAAA,CAAQ,UAAU,CAAA,CAAA,CAAG,CAAA,CAE3D,MACF,CAEAgB,CAAAA,CAAU,IAAI,CAAA,CACdF,CAAAA,CAAS,IAAI,CAAA,CAEb,GAAI,CACF,MAAMT,CAAAA,CAAQ,MAAA,CAAO1D,CAAK,CAAA,CAC1BiE,CAAAA,CAAS,EAAE,CAAA,CACXP,CAAAA,CAAQ,MAAA,CAAO,CAAA,CAAI,EACrB,CAAA,MAASc,EAAS,CAChBL,CAAAA,CAASK,CAAAA,YAAmB,KAAA,CAAQA,CAAAA,CAAQ,OAAA,CAAU,CAAA,EAAGV,CAAI,CAAA,wBAAA,CAA0B,EACzF,CAAA,OAAE,CACAO,CAAAA,CAAU,KAAK,EACjB,CAAA,CACF,CAEA,OACET,GAAAA,CAACa,CAAAA,CAAA,CACC,IAAA,CAAI,IAAA,CACJ,YAAA,CAAeC,CAAAA,EAAS,CAClB,CAACA,CAAAA,EAAQ,CAACN,GAAAA,EACZV,CAAAA,CAAQ,MAAA,CAAO,KAAK,EAExB,CAAA,CAEA,QAAA,CAAAE,GAAAA,CAACe,CAAAA,CAAA,CACC,QAAA,CAAAC,IAAAA,CAAC,MAAA,CAAA,CAAK,SAAA,CAAU,8BAAA,CAA+B,QAAA,CAAW9C,CAAAA,EAAO,CAAQyC,GAAAA,CAAKzC,CAAK,EAAA,CAAA,CACjF,UAAA8C,IAAAA,CAACC,CAAAA,CAAA,CACC,QAAA,CAAA,CAAAD,IAAAA,CAACE,CAAAA,CAAA,CAAY,QAAA,CAAA,CAAA,UAAA,CAAShB,CAAAA,CAAAA,CAAK,CAAA,CAC3Bc,IAAAA,CAACG,CAAAA,CAAA,CAAkB,QAAA,CAAA,CAAA,UAAA,CACR1B,CAAAA,CAAQ,UAAA,CAAW,sDAAoDS,CAAAA,CAAK,qBAAA,CAAoB,GAAA,CACxGA,CAAAA,CAAK,wGAAA,CACKA,CAAAA,CAAK,GAAA,CAAA,CAClB,CAAA,CAAA,CACF,CAAA,CACAc,IAAAA,CAAC,KAAA,CAAA,CAAI,SAAA,CAAU,8BAAA,CACb,QAAA,CAAA,CAAAhB,GAAAA,CAAC,OAAA,CAAA,CAAM,UAAU,2BAAA,CAA4B,OAAA,CAASG,GAAAA,CACnD,QAAA,CAAAV,CAAAA,CAAQ,UAAA,CACX,CAAA,CACAO,GAAAA,CAACoB,CAAAA,CAAA,CACC,kBAAA,CAAkBhE,GAAAA,CAAQ,CAAA,EAAG+C,GAAO,CAAA,MAAA,CAAA,CAAW,MAAA,CAC/C,eAAc/C,GAAAA,CAAQ,IAAA,CAAO,MAAA,CAC7B,YAAA,CAAa,KAAA,CACb,SAAA,CAAS,IAAA,CACT,QAAA,CAAUoD,GAAAA,CACV,EAAA,CAAIL,GAAAA,CACJ,WAAA,CAAaV,CAAAA,CAAQ,WAAA,EAAe,MAAA,CACpC,UAAA,CAAY,MACZ,IAAA,CAAK,UAAA,CACL,KAAA,CAAOpB,CAAAA,CACP,QAAA,CAAWH,CAAAA,EAAU,CACnBmC,CAAAA,CAASnC,CAAAA,CAAM,MAAA,CAAO,KAAK,CAAA,CAC3BqC,CAAAA,CAAS,IAAI,EACf,CAAA,CACF,EACCnD,GAAAA,CACC4C,GAAAA,CAAC,GAAA,CAAA,CAAE,SAAA,CAAU,gCAAA,CAAiC,EAAA,CAAI,CAAA,EAAGG,GAAO,CAAA,MAAA,CAAA,CACzD,QAAA,CAAA/C,GAAAA,CACH,CAAA,CACE,IAAA,CACHsD,CAAAA,CACCM,IAAAA,CAAC,GAAA,CAAA,CACC,UAAU,sHAAA,CACV,IAAA,CAAMN,CAAAA,CACN,GAAA,CAAI,YAAA,CACJ,MAAA,CAAO,QAAA,CACR,QAAA,CAAA,CAAA,kBAAA,CACkBjB,CAAAA,CAAQ,UAAA,CACzBO,GAAAA,CAACqB,gBAAAA,CAAA,CAAiB,SAAA,CAAU,aAAA,CAAc,CAAA,CAAA,CAC5C,EACE,IAAA,CAAA,CACN,CAAA,CACAL,IAAAA,CAACM,GAAAA,CAAA,CACC,QAAA,CAAA,CAAAtB,GAAAA,CAACuB,CAAAA,CAAA,CAAO,QAAA,CAAUf,GAAAA,CAAQ,IAAA,CAAK,IAAA,CAAK,IAAA,CAAK,QAAA,CAAS,OAAA,CAAQ,UAAU,OAAA,CAAS,IAAMV,CAAAA,CAAQ,MAAA,CAAO,KAAK,CAAA,CAAG,QAAA,CAAA,QAAA,CAE1G,CAAA,CACAkB,IAAAA,CAACO,CAAAA,CAAA,CAAO,QAAA,CAAUf,GAAAA,EAAU,CAACnC,CAAAA,CAAM,IAAA,GAAQ,IAAA,CAAK,IAAA,CAAK,IAAA,CAAK,QAAA,CACvD,QAAA,CAAA,CAAAmC,GAAAA,CAASR,GAAAA,CAACwB,YAAAA,CAAA,CAAa,SAAA,CAAU,2BAAA,CAA4B,CAAA,CAAK,IAAA,CAAK,SAAA,CAAA,CAE1E,CAAA,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CACF,EACF,CAEJ","file":"chunk-U6E7GNQW.js","sourcesContent":["import { getPlatformOrigin, type ApiClient } from './api';\nimport type { PluginScope } from './plugin-types';\n\nconst OAUTH_START_PATH = '/plugins/oauth/start';\n\n/** A Reconnect was completed with a different provider account than the one being reconnected. */\nexport class PluginAccountMismatchError extends Error {\n readonly code = 'account_mismatch';\n\n constructor() {\n super('You signed in with a different account. Use \"Connect another account\" to add it.');\n this.name = 'PluginAccountMismatchError';\n }\n}\n\nfunction httpsUrl(value: string): URL | null {\n let url: URL;\n\n try {\n url = new URL(value);\n } catch {\n return null;\n }\n\n if (url.protocol !== 'https:' || url.username !== '' || url.password !== '') {\n return null;\n }\n\n return url;\n}\n\n/** Popup navigation and postMessage stay on the platform OAuth start page. */\nfunction trustedPluginOAuthTargets(\n authorizeUrl: string,\n completionOrigin: string\n): { href: string; origin: string } | null {\n const origin = getPlatformOrigin();\n const authorize = httpsUrl(authorizeUrl);\n const completion = httpsUrl(completionOrigin);\n\n if (!authorize || !completion) {\n return null;\n }\n\n if (authorize.origin !== origin || authorize.pathname !== OAUTH_START_PATH) {\n return null;\n }\n\n if (completion.origin !== origin || completion.pathname !== '/') {\n return null;\n }\n\n return { href: authorize.href, origin };\n}\n\n/** Must be called directly from the click handler so browsers allow the popup. */\nexport async function connectPluginPopup(\n api: ApiClient,\n pluginId: string,\n scope: PluginScope,\n options?: { connectionId?: string }\n): Promise<void> {\n const popup = window.open('about:blank', `flexkit-plugin-${crypto.randomUUID()}`, 'popup,width=560,height=720');\n\n if (!popup) {\n throw new Error('Allow popups for Studio, then connect again.');\n }\n\n let transaction: Awaited<ReturnType<ApiClient['connectPlugins']>>;\n\n try {\n transaction = await api.connectPlugins({\n pluginId,\n scope,\n studioOrigin: window.location.origin,\n ...(options?.connectionId ? { connectionId: options.connectionId } : {}),\n });\n } catch (error) {\n popup.close();\n throw error;\n }\n\n const targets = trustedPluginOAuthTargets(transaction.authorizeUrl, transaction.completionOrigin);\n\n if (!targets) {\n popup.close();\n throw new Error('Connection could not be started.');\n }\n\n const expectedOrigin = targets.origin;\n\n await new Promise<void>((resolve, reject) => {\n let polling = false;\n let finished = false;\n // Once the popup leaves for the provider, `popup.closed` says nothing:\n // providers isolate their pages (Cross-Origin-Opener-Policy), which severs\n // the opener and reports the window as closed while it is open. From then\n // on only the transaction's status (and the timeout) ends the wait.\n let handedOff = false;\n const finish = (error?: Error) => {\n if (finished) {\n return;\n }\n\n finished = true;\n window.clearInterval(interval);\n window.clearTimeout(timeout);\n window.removeEventListener('message', onMessage);\n popup.close();\n\n if (error) {\n reject(error);\n\n return;\n }\n\n resolve();\n };\n const poll = async () => {\n if (polling || finished) {\n return;\n }\n\n polling = true;\n let status: Awaited<ReturnType<ApiClient['pluginOAuthStatus']>>;\n\n try {\n status = await api.pluginOAuthStatus(transaction.transactionId);\n } catch {\n polling = false;\n\n return;\n }\n\n polling = false;\n\n if (status.status === 'complete') {\n finish();\n\n return;\n }\n\n if (!handedOff && popup.closed && status.status === 'pending') {\n finish(new Error('Connection window was closed.'));\n\n return;\n }\n\n if (status.status === 'failed' || new Date(status.expires_at).getTime() < Date.now()) {\n finish(new Error('Connection was not completed. Please try again.'));\n }\n };\n const onMessage = (event: MessageEvent<unknown>) => {\n if (event.origin !== expectedOrigin || event.source !== popup || !event.data || typeof event.data !== 'object') {\n return;\n }\n\n const payload = event.data as { type?: string; transactionId?: string; status?: string; error?: string };\n\n if (payload.type === 'flexkit:plugin-oauth-ready' && payload.transactionId === transaction.transactionId) {\n handedOff = true;\n popup.postMessage(\n {\n type: 'flexkit:plugin-oauth-start',\n transactionId: transaction.transactionId,\n ticket: transaction.launchTicket,\n },\n expectedOrigin\n );\n\n return;\n }\n\n if (payload.type === 'flexkit:plugin-oauth' && payload.transactionId === transaction.transactionId) {\n if (payload.status === 'failed' && payload.error === 'account_mismatch') {\n finish(new PluginAccountMismatchError());\n\n return;\n }\n\n void poll();\n }\n };\n const interval = window.setInterval(() => {\n void poll();\n }, 2000);\n const timeout = window.setTimeout(() => finish(new Error('Connection timed out. Please try again.')), 600_000);\n window.addEventListener('message', onMessage);\n popup.location.href = targets.href;\n });\n}\n","import type { MarketplacePlugin } from './plugin-types';\n\nexport type ConnectablePlugin = Pick<MarketplacePlugin, 'connect' | 'id' | 'name'>;\n\nexport function matchesTokenPattern(token: string, pattern: string | null): boolean {\n if (!pattern) {\n return true;\n }\n\n try {\n return new RegExp(pattern, 'u').test(token);\n } catch {\n // The server validates the pattern when it admits the plugin; never block on a bad one here.\n return true;\n }\n}\n\n/** A pattern that compiles; an empty or broken one detects nothing rather than every word. */\nfunction compileTokenPattern(pattern: string | null): RegExp | null {\n if (!pattern) {\n return null;\n }\n\n try {\n return new RegExp(pattern, 'u');\n } catch {\n return null;\n }\n}\n\n/**\n * The first plugin whose token format `text` contains, if any, with every\n * token-shaped word in the message: a token pasted into the chat would be\n * stored in the conversation and sent to the model.\n */\nexport function findPastedPluginToken(\n text: string,\n plugins: readonly ConnectablePlugin[]\n): { plugin: ConnectablePlugin; tokens: string[] } | null {\n // A token is often glued to a label (`token=…`, `key: …`) or wrapped in\n // brackets, quotes or a sentence's punctuation; none of those are part of it.\n const words = text\n .split(/[\\s\"'`()<>[\\]{},;:=!?&]+/)\n .map((word) => word.replace(/\\.+$/, ''))\n .filter(Boolean);\n let found: ConnectablePlugin | null = null;\n const tokens = new Set<string>();\n\n for (const plugin of plugins) {\n const pattern = compileTokenPattern(plugin.connect?.type === 'api-token' ? plugin.connect.pattern : null);\n\n for (const word of pattern ? words : []) {\n if (pattern!.test(word)) {\n found ??= plugin;\n tokens.add(word);\n }\n }\n }\n\n return found ? { plugin: found, tokens: [...tokens] } : null;\n}\n","import type { FormEvent, JSX } from 'react';\nimport { useId, useState, useSyncExternalStore } from 'react';\nimport { ExternalLinkIcon, LoaderCircle } from 'lucide-react';\nimport {\n Button,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n Input,\n} from '../../ui';\nimport type { ApiClient } from './api';\nimport { connectPluginPopup } from './plugin-oauth';\nimport { matchesTokenPattern, type ConnectablePlugin } from './plugin-token-format';\nimport type { PluginApiTokenConnect, PluginScope } from './plugin-types';\n\ninterface TokenRequest {\n id: number;\n plugin: ConnectablePlugin & { connect: PluginApiTokenConnect };\n /** Saves the token; rejects with a message the dialog shows next to the field. */\n submit: (_token: string) => Promise<void>;\n settle: (_connected: boolean) => void;\n}\n\n/** The one open token dialog, outside React so any connect button can open it. */\nlet request: TokenRequest | null = null;\nlet lastRequestId = 0;\n/** Cancels the latest request, whether its dialog has opened yet or not. */\nlet cancelLatest: (() => void) | null = null;\nconst listeners = new Set<() => void>();\n\nfunction setRequest(next: TokenRequest | null): void {\n request = next;\n listeners.forEach((listener) => listener());\n}\n\nfunction subscribe(listener: () => void): () => void {\n listeners.add(listener);\n\n return () => listeners.delete(listener);\n}\n\n/**\n * Connects a plugin: a sign-in popup for OAuth plugins, the token dialog for\n * plugins that take a pasted token. Resolves `false` when the user closes the\n * token dialog without connecting.\n *\n * Call it straight from a click handler: browsers only allow the popup there.\n */\nexport function connectPlugin(\n api: ApiClient,\n plugin: ConnectablePlugin,\n scope: PluginScope,\n options?: { connectionId?: string }\n): Promise<boolean> {\n const { connect } = plugin;\n\n if (connect?.type !== 'api-token') {\n return connectPluginPopup(api, plugin.id, scope, options).then(() => true);\n }\n\n // Opening a second dialog closes the first, as if cancelled.\n cancelLatest?.();\n\n const id = ++lastRequestId;\n\n return new Promise<boolean>((resolve) => {\n const next: TokenRequest = {\n id,\n plugin: { ...plugin, connect },\n submit: async (token) => {\n await api.connectPluginToken({\n pluginId: plugin.id,\n scope,\n token,\n ...(options?.connectionId ? { connectionId: options.connectionId } : {}),\n });\n },\n settle: (connected) => {\n // A save still running for a replaced dialog must not close its successor.\n if (request?.id === id) {\n setRequest(null);\n }\n\n if (lastRequestId === id) {\n cancelLatest = null;\n }\n\n resolve(connected);\n },\n };\n\n cancelLatest = () => next.settle(false);\n\n // Open after the current event: a menu item that started this closes first\n // and returns focus to its trigger, which would take it from the token field.\n setTimeout(() => {\n if (lastRequestId === id) {\n setRequest(next);\n }\n });\n });\n}\n\nfunction httpsHref(value: string | null): string | null {\n if (!value) {\n return null;\n }\n\n try {\n const url = new URL(value);\n\n return url.protocol === 'https:' ? url.href : null;\n } catch {\n return null;\n }\n}\n\n/** Mounted once by the Studio layout; renders the dialog `connectPlugin` opens for token plugins. */\nexport function PluginTokenDialogHost(): JSX.Element | null {\n const current = useSyncExternalStore(\n subscribe,\n () => request,\n () => null\n );\n\n // A new key per request resets the field, so a token never outlives its dialog.\n return current ? <PluginTokenDialog key={current.id} request={current} /> : null;\n}\n\nfunction PluginTokenDialog({ request: current }: { request: TokenRequest }): JSX.Element {\n const { connect, name } = current.plugin;\n const inputId = useId();\n const [token, setToken] = useState('');\n const [error, setError] = useState<string | null>(null);\n const [saving, setSaving] = useState(false);\n const helpHref = httpsHref(connect.helpUrl);\n\n async function save(event: FormEvent): Promise<void> {\n event.preventDefault();\n const value = token.trim();\n\n if (saving || !value) {\n return;\n }\n\n if (!matchesTokenPattern(value, connect.pattern)) {\n setError(`That does not look like a ${connect.tokenLabel}.`);\n\n return;\n }\n\n setSaving(true);\n setError(null);\n\n try {\n await current.submit(value);\n setToken('');\n current.settle(true);\n } catch (failure) {\n setError(failure instanceof Error ? failure.message : `${name} could not be connected.`);\n } finally {\n setSaving(false);\n }\n }\n\n return (\n <Dialog\n open\n onOpenChange={(open) => {\n if (!open && !saving) {\n current.settle(false);\n }\n }}\n >\n <DialogContent>\n <form className=\"fk:flex fk:flex-col fk:gap-4\" onSubmit={(event) => void save(event)}>\n <DialogHeader>\n <DialogTitle>Connect {name}</DialogTitle>\n <DialogDescription>\n Paste a {connect.tokenLabel}. Flexkit stores it encrypted and sends it only to {name}; the agent can use{' '}\n {name}&apos;s tools but never sees the token. Give it read access only, unless the agent should change\n things in {name}.\n </DialogDescription>\n </DialogHeader>\n <div className=\"fk:flex fk:flex-col fk:gap-2\">\n <label className=\"fk:text-sm fk:font-medium\" htmlFor={inputId}>\n {connect.tokenLabel}\n </label>\n <Input\n aria-describedby={error ? `${inputId}-error` : undefined}\n aria-invalid={error ? true : undefined}\n autoComplete=\"off\"\n autoFocus\n disabled={saving}\n id={inputId}\n placeholder={connect.placeholder ?? undefined}\n spellCheck={false}\n type=\"password\"\n value={token}\n onChange={(event) => {\n setToken(event.target.value);\n setError(null);\n }}\n />\n {error ? (\n <p className=\"fk:text-sm fk:text-destructive\" id={`${inputId}-error`}>\n {error}\n </p>\n ) : null}\n {helpHref ? (\n <a\n className=\"fk:inline-flex fk:items-center fk:gap-1 fk:text-sm fk:text-muted-foreground fk:underline-offset-4 fk:hover:underline\"\n href={helpHref}\n rel=\"noreferrer\"\n target=\"_blank\"\n >\n How to create a {connect.tokenLabel}\n <ExternalLinkIcon className=\"fk:size-3.5\" />\n </a>\n ) : null}\n </div>\n <DialogFooter>\n <Button disabled={saving} size=\"sm\" type=\"button\" variant=\"outline\" onClick={() => current.settle(false)}>\n Cancel\n </Button>\n <Button disabled={saving || !token.trim()} size=\"sm\" type=\"submit\">\n {saving ? <LoaderCircle className=\"fk:size-4 fk:animate-spin\" /> : null}\n Connect\n </Button>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n );\n}\n"]}
@@ -1,2 +1,2 @@
1
- import'./index.css';import {q as q$1,o,r}from'./chunk-AMUTDCI7.js';import {f}from'./chunk-EYIV4KVY.js';import {d}from'./chunk-WPCPL2TQ.js';import {useCallback}from'react';import {toast}from'sonner';import {useApolloClient}from'@apollo/client/react';function E(i){let{currentProjectSchema:t}=f();return useCallback(a=>{t&&q$1(o(i,t),a);},[i,t])}var g=["image/jpeg","image/png","image/webp","image/vnd.microsoft.icon","image/bmp","image/gif","image/tiff","image/svg+xml","image/avif","image/heic","image/heif","image/heic-sequence","image/heif-sequence","image/apng","audio/aac","audio/mpeg","audio/wav","audio/webm","audio/midi","audio/x-midi","audio/ogg","video/x-msvideo","video/mp4","video/mpeg","video/webm","video/quicktime","video/ogg","video/mp2t","video/3gpp","video/3gpp2","application/x-7z-compressed","application/zip","application/vnd.amazon.ebook","application/octet-stream","application/epub+zip","application/pdf","application/msword","application/vnd.openxmlformats-officedocument.wordprocessingml.document","application/vnd.ms-fontobject","application/gzip","application/x-gzip","application/java-archive","application/json","application/ld+json","text/javascript","application/vnd.oasis.opendocument.presentation","application/vnd.oasis.opendocument.spreadsheet","application/vnd.oasis.opendocument.text","application/ogg","application/vnd.ms-powerpoint","application/vnd.openxmlformats-officedocument.presentationml.presentation","application/vnd.rar","application/x-tar","application/vnd.visio","application/xhtml+xml","application/vnd.ms-excel","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","application/xml"];function F(i,t){if(!i.type)return true;let a=t?t.split(",").map(e=>e.trim()).filter(Boolean):g;return a.length===0?true:a.some(e=>e.endsWith("/*")?i.type.startsWith(e.slice(0,-1)):i.type===e)}async function x(i,t){let a=new URLSearchParams({filename:i.name}),e=await fetch(`${d(t).assets}?${a.toString()}`,{method:"POST",headers:{"Content-Type":i.type||"application/octet-stream"},body:i});if(!e.ok)throw new Error(`Upload failed for ${i.name}`);let n=await e.json(),o={_id:n._id,path:n.path??"",originalFilename:n.originalFilename??i.name,size:n.size??i.size,mimeType:n.mimeType??i.type,lqip:n.lqip??"",width:n.width??0,height:n.height??0};return {pathname:o.path,lqip:o.lqip||void 0,originalFilename:o.originalFilename,size:o.size,mimeType:o.mimeType,width:o.width||void 0,height:o.height||void 0,_id:o._id,asset:o}}async function h(i,t){let{projectId:a,accept:e,maxBytes:n=4*1024*1024,onUploadStart:o}=t,l=[];for(let p of Array.from(i)){if(p.size>n){toast.error(`File size too big (max ${(n/(1024*1024)).toFixed(0)}MB): ${p.name}`);continue}if(!F(p,e)){toast.error(`Unsupported file type: ${p.name}`);continue}l.push(p);}if(l.length===0)return [];o?.();try{let p=await Promise.all(l.map(async f=>x(f,a)));return p.length>0&&toast.success(`Uploaded ${p.length} file${p.length>1?"s":""}`),p}catch(p){return console.error(p),toast.error("Upload failed. Please try again."),[]}}async function b(i){let{accept:t,multiple:a=true}=i,e=document.createElement("input");e.type="file",e.accept=t??g.join(","),e.multiple=a,e.style.display="none",document.body.appendChild(e);try{let n=await new Promise(o=>{e.addEventListener("change",()=>o(e.files),{once:!0}),e.addEventListener("cancel",()=>o(null),{once:!0}),e.click();});return !n||n.length===0?[]:h(n,i)}finally{document.body.removeChild(e);}}function q(){let i=useApolloClient();return useCallback(async t=>{let a=t.files?await h(t.files,t):await b(t);return a.length>0&&await r(i,"GetAssets").catch(e=>{console.error("Error refreshing asset lists after upload:",e);}),a},[i])}export{E as a,x as b,q as c};//# sourceMappingURL=chunk-YEWTJHKW.js.map
2
- //# sourceMappingURL=chunk-YEWTJHKW.js.map
1
+ import'./index.css';import {q as q$1,o,r}from'./chunk-XV2B3W6Z.js';import {f}from'./chunk-NSVX6HEN.js';import {d}from'./chunk-WPCPL2TQ.js';import {useCallback}from'react';import {toast}from'sonner';import {useApolloClient}from'@apollo/client/react';function E(i){let{currentProjectSchema:t}=f();return useCallback(a=>{t&&q$1(o(i,t),a);},[i,t])}var g=["image/jpeg","image/png","image/webp","image/vnd.microsoft.icon","image/bmp","image/gif","image/tiff","image/svg+xml","image/avif","image/heic","image/heif","image/heic-sequence","image/heif-sequence","image/apng","audio/aac","audio/mpeg","audio/wav","audio/webm","audio/midi","audio/x-midi","audio/ogg","video/x-msvideo","video/mp4","video/mpeg","video/webm","video/quicktime","video/ogg","video/mp2t","video/3gpp","video/3gpp2","application/x-7z-compressed","application/zip","application/vnd.amazon.ebook","application/octet-stream","application/epub+zip","application/pdf","application/msword","application/vnd.openxmlformats-officedocument.wordprocessingml.document","application/vnd.ms-fontobject","application/gzip","application/x-gzip","application/java-archive","application/json","application/ld+json","text/javascript","application/vnd.oasis.opendocument.presentation","application/vnd.oasis.opendocument.spreadsheet","application/vnd.oasis.opendocument.text","application/ogg","application/vnd.ms-powerpoint","application/vnd.openxmlformats-officedocument.presentationml.presentation","application/vnd.rar","application/x-tar","application/vnd.visio","application/xhtml+xml","application/vnd.ms-excel","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","application/xml"];function F(i,t){if(!i.type)return true;let a=t?t.split(",").map(e=>e.trim()).filter(Boolean):g;return a.length===0?true:a.some(e=>e.endsWith("/*")?i.type.startsWith(e.slice(0,-1)):i.type===e)}async function x(i,t){let a=new URLSearchParams({filename:i.name}),e=await fetch(`${d(t).assets}?${a.toString()}`,{method:"POST",headers:{"Content-Type":i.type||"application/octet-stream"},body:i});if(!e.ok)throw new Error(`Upload failed for ${i.name}`);let n=await e.json(),o={_id:n._id,path:n.path??"",originalFilename:n.originalFilename??i.name,size:n.size??i.size,mimeType:n.mimeType??i.type,lqip:n.lqip??"",width:n.width??0,height:n.height??0};return {pathname:o.path,lqip:o.lqip||void 0,originalFilename:o.originalFilename,size:o.size,mimeType:o.mimeType,width:o.width||void 0,height:o.height||void 0,_id:o._id,asset:o}}async function h(i,t){let{projectId:a,accept:e,maxBytes:n=4*1024*1024,onUploadStart:o}=t,l=[];for(let p of Array.from(i)){if(p.size>n){toast.error(`File size too big (max ${(n/(1024*1024)).toFixed(0)}MB): ${p.name}`);continue}if(!F(p,e)){toast.error(`Unsupported file type: ${p.name}`);continue}l.push(p);}if(l.length===0)return [];o?.();try{let p=await Promise.all(l.map(async f=>x(f,a)));return p.length>0&&toast.success(`Uploaded ${p.length} file${p.length>1?"s":""}`),p}catch(p){return console.error(p),toast.error("Upload failed. Please try again."),[]}}async function b(i){let{accept:t,multiple:a=true}=i,e=document.createElement("input");e.type="file",e.accept=t??g.join(","),e.multiple=a,e.style.display="none",document.body.appendChild(e);try{let n=await new Promise(o=>{e.addEventListener("change",()=>o(e.files),{once:!0}),e.addEventListener("cancel",()=>o(null),{once:!0}),e.click();});return !n||n.length===0?[]:h(n,i)}finally{document.body.removeChild(e);}}function q(){let i=useApolloClient();return useCallback(async t=>{let a=t.files?await h(t.files,t):await b(t);return a.length>0&&await r(i,"GetAssets").catch(e=>{console.error("Error refreshing asset lists after upload:",e);}),a},[i])}export{E as a,x as b,q as c};//# sourceMappingURL=chunk-UBFBXBPG.js.map
2
+ //# sourceMappingURL=chunk-UBFBXBPG.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/graphql-client/use-patch-entity-list.ts","../src/core/upload.ts"],"names":["usePatchEntityList","entityNameOrPlural","schema","useConfig","useCallback","patches","scheduleEntityListPatch","getEntityListQueryName","ACCEPTED_MIME_TYPES","isAcceptedMimeType","file","accept","allowed","pattern","uploadAssetFile","projectId","params","response","apiPaths","data","asset","uploadSelectedFiles","files","options","maxBytes","onUploadStart","validFiles","toast","uploads","error","openFileDialogAndUpload","multiple","input","resolve","useUploadAssets","apolloClient","useApolloClient","scheduleEntityListRefetch"],"mappings":"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","file":"chunk-YEWTJHKW.js","sourcesContent":["import { useCallback } from 'react';\nimport { useConfig } from '../core/config/config-context';\nimport {\n getEntityListQueryName,\n scheduleEntityListPatch,\n type EntityListRowPatch,\n} from './refetch-entity-lists';\n\n/**\n * Patch active list rows for an entity without a soft-refetch.\n * Prefer this after mutations that only change row fields (e.g. tag connect/disconnect).\n */\nexport function usePatchEntityList(entityNameOrPlural: string): (patches: EntityListRowPatch[]) => void {\n const { currentProjectSchema: schema } = useConfig();\n\n return useCallback(\n (patches: EntityListRowPatch[]) => {\n if (!schema) {\n return;\n }\n\n scheduleEntityListPatch(getEntityListQueryName(entityNameOrPlural, schema), patches);\n },\n [entityNameOrPlural, schema]\n );\n}\n","import { useCallback } from 'react';\nimport { toast } from 'sonner';\nimport { useApolloClient } from '@apollo/client/react';\nimport { apiPaths } from './api-paths';\nimport { scheduleEntityListRefetch } from '../graphql-client/refetch-entity-lists';\nimport type { OrderedAssetValue } from '../graphql-client/types';\n\nexport const ACCEPTED_MIME_TYPES = [\n 'image/jpeg',\n 'image/png',\n 'image/webp',\n 'image/vnd.microsoft.icon',\n 'image/bmp',\n 'image/gif',\n 'image/tiff',\n 'image/svg+xml',\n 'image/avif',\n 'image/heic',\n 'image/heif',\n 'image/heic-sequence',\n 'image/heif-sequence',\n 'image/apng',\n 'audio/aac',\n 'audio/mpeg',\n 'audio/wav',\n 'audio/webm',\n 'audio/midi',\n 'audio/x-midi',\n 'audio/ogg',\n 'video/x-msvideo',\n 'video/mp4',\n 'video/mpeg',\n 'video/webm',\n 'video/quicktime',\n 'video/ogg',\n 'video/mp2t',\n 'video/3gpp',\n 'video/3gpp2',\n 'application/x-7z-compressed',\n 'application/zip',\n 'application/vnd.amazon.ebook',\n 'application/octet-stream',\n 'application/epub+zip',\n 'application/pdf',\n 'application/msword',\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n 'application/vnd.ms-fontobject',\n 'application/gzip',\n 'application/x-gzip',\n 'application/java-archive',\n 'application/json',\n 'application/ld+json',\n 'text/javascript',\n 'application/vnd.oasis.opendocument.presentation',\n 'application/vnd.oasis.opendocument.spreadsheet',\n 'application/vnd.oasis.opendocument.text',\n 'application/ogg',\n 'application/vnd.ms-powerpoint',\n 'application/vnd.openxmlformats-officedocument.presentationml.presentation',\n 'application/vnd.rar',\n 'application/x-tar',\n 'application/vnd.visio',\n 'application/xhtml+xml',\n 'application/vnd.ms-excel',\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n 'application/xml',\n];\n\nexport type UploadedFileResult = {\n pathname: string;\n lqip?: string;\n size: number;\n mimeType: string;\n originalFilename: string;\n width?: number;\n height?: number;\n};\n\nexport type UploadedAssetResult = UploadedFileResult & {\n asset: OrderedAssetValue;\n _id: string;\n};\n\ntype AssetUploadResponse = {\n _id: string;\n path: string | null;\n mimeType: string | null;\n originalFilename: string | null;\n size: number | null;\n width: number | null;\n height: number | null;\n lqip: string | null;\n sha256: string | null;\n deduped: boolean;\n};\n\nexport type OpenFileDialogAndUploadOptions = {\n projectId: string | undefined;\n accept?: string;\n files?: File[] | FileList;\n multiple?: boolean;\n maxBytes?: number;\n onUploadStart?: () => void;\n};\n\nfunction isAcceptedMimeType(file: File, accept?: string): boolean {\n if (!file.type) {\n return true;\n }\n\n const allowed = accept\n ? accept\n .split(',')\n .map((pattern) => pattern.trim())\n .filter(Boolean)\n : ACCEPTED_MIME_TYPES;\n\n if (allowed.length === 0) {\n return true;\n }\n\n return allowed.some((pattern) => {\n if (pattern.endsWith('/*')) {\n return file.type.startsWith(pattern.slice(0, -1));\n }\n\n return file.type === pattern;\n });\n}\n\n/**\n * Uploads a single file to the one-shot /assets endpoint, which stores the\n * blob and creates the _asset node in a single request.\n */\nexport async function uploadAssetFile(file: File, projectId: string | undefined): Promise<UploadedAssetResult> {\n const params = new URLSearchParams({ filename: file.name });\n const response = await fetch(`${apiPaths(projectId).assets}?${params.toString()}`, {\n method: 'POST',\n headers: { 'Content-Type': file.type || 'application/octet-stream' },\n body: file,\n });\n\n if (!response.ok) {\n throw new Error(`Upload failed for ${file.name}`);\n }\n\n const data = (await response.json()) as AssetUploadResponse;\n const asset: OrderedAssetValue = {\n _id: data._id,\n path: data.path ?? '',\n originalFilename: data.originalFilename ?? file.name,\n size: data.size ?? file.size,\n mimeType: data.mimeType ?? file.type,\n lqip: data.lqip ?? '',\n width: data.width ?? 0,\n height: data.height ?? 0,\n };\n\n return {\n pathname: asset.path,\n lqip: asset.lqip || undefined,\n originalFilename: asset.originalFilename,\n size: asset.size,\n mimeType: asset.mimeType,\n width: asset.width || undefined,\n height: asset.height || undefined,\n _id: asset._id,\n asset,\n };\n}\n\nasync function uploadSelectedFiles(\n files: File[] | FileList,\n options: OpenFileDialogAndUploadOptions\n): Promise<UploadedAssetResult[]> {\n const { projectId, accept, maxBytes = 4 * 1024 * 1024, onUploadStart } = options;\n const validFiles: File[] = [];\n\n for (const file of Array.from(files)) {\n if (file.size > maxBytes) {\n toast.error(`File size too big (max ${(maxBytes / (1024 * 1024)).toFixed(0)}MB): ${file.name}`);\n\n continue;\n }\n\n if (!isAcceptedMimeType(file, accept)) {\n toast.error(`Unsupported file type: ${file.name}`);\n\n continue;\n }\n\n validFiles.push(file);\n }\n\n if (validFiles.length === 0) {\n return [];\n }\n\n onUploadStart?.();\n\n try {\n const uploads = await Promise.all(validFiles.map(async (file) => uploadAssetFile(file, projectId)));\n\n if (uploads.length > 0) {\n toast.success(`Uploaded ${uploads.length} file${uploads.length > 1 ? 's' : ''}`);\n }\n\n return uploads;\n } catch (error) {\n console.error(error);\n toast.error('Upload failed. Please try again.');\n\n return [];\n }\n}\n\n/**\n * Opens a native file picker and uploads selected files to the Flexkit assets\n * endpoint, which also creates an asset node in the database.\n * Returns a list of uploaded file results. Skips files that exceed maxBytes.\n */\nasync function openFileDialogAndUpload(options: OpenFileDialogAndUploadOptions): Promise<UploadedAssetResult[]> {\n const { accept, multiple = true } = options;\n const input = document.createElement('input');\n input.type = 'file';\n input.accept = accept ?? ACCEPTED_MIME_TYPES.join(',');\n input.multiple = multiple;\n input.style.display = 'none';\n document.body.appendChild(input);\n\n try {\n const files = await new Promise<FileList | null>((resolve) => {\n input.addEventListener('change', () => resolve(input.files), { once: true });\n input.addEventListener('cancel', () => resolve(null), { once: true });\n input.click();\n });\n\n if (!files || files.length === 0) {\n return [];\n }\n\n return uploadSelectedFiles(files, options);\n } finally {\n document.body.removeChild(input);\n }\n}\n\nexport function useUploadAssets(): (options: OpenFileDialogAndUploadOptions) => Promise<UploadedAssetResult[]> {\n const apolloClient = useApolloClient();\n\n return useCallback(\n async (options: OpenFileDialogAndUploadOptions) => {\n const uploads = options.files\n ? await uploadSelectedFiles(options.files, options)\n : await openFileDialogAndUpload(options);\n\n if (uploads.length > 0) {\n // Upload is outside Apollo; soft-refresh mounted asset lists via useEntityQuery.\n await scheduleEntityListRefetch(apolloClient, 'GetAssets').catch((error: unknown) => {\n console.error('Error refreshing asset lists after upload:', error);\n });\n }\n\n return uploads;\n },\n [apolloClient]\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/graphql-client/use-patch-entity-list.ts","../src/core/upload.ts"],"names":["usePatchEntityList","entityNameOrPlural","schema","useConfig","useCallback","patches","scheduleEntityListPatch","getEntityListQueryName","ACCEPTED_MIME_TYPES","isAcceptedMimeType","file","accept","allowed","pattern","uploadAssetFile","projectId","params","response","apiPaths","data","asset","uploadSelectedFiles","files","options","maxBytes","onUploadStart","validFiles","toast","uploads","error","openFileDialogAndUpload","multiple","input","resolve","useUploadAssets","apolloClient","useApolloClient","scheduleEntityListRefetch"],"mappings":"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","file":"chunk-UBFBXBPG.js","sourcesContent":["import { useCallback } from 'react';\nimport { useConfig } from '../core/config/config-context';\nimport {\n getEntityListQueryName,\n scheduleEntityListPatch,\n type EntityListRowPatch,\n} from './refetch-entity-lists';\n\n/**\n * Patch active list rows for an entity without a soft-refetch.\n * Prefer this after mutations that only change row fields (e.g. tag connect/disconnect).\n */\nexport function usePatchEntityList(entityNameOrPlural: string): (patches: EntityListRowPatch[]) => void {\n const { currentProjectSchema: schema } = useConfig();\n\n return useCallback(\n (patches: EntityListRowPatch[]) => {\n if (!schema) {\n return;\n }\n\n scheduleEntityListPatch(getEntityListQueryName(entityNameOrPlural, schema), patches);\n },\n [entityNameOrPlural, schema]\n );\n}\n","import { useCallback } from 'react';\nimport { toast } from 'sonner';\nimport { useApolloClient } from '@apollo/client/react';\nimport { apiPaths } from './api-paths';\nimport { scheduleEntityListRefetch } from '../graphql-client/refetch-entity-lists';\nimport type { OrderedAssetValue } from '../graphql-client/types';\n\nexport const ACCEPTED_MIME_TYPES = [\n 'image/jpeg',\n 'image/png',\n 'image/webp',\n 'image/vnd.microsoft.icon',\n 'image/bmp',\n 'image/gif',\n 'image/tiff',\n 'image/svg+xml',\n 'image/avif',\n 'image/heic',\n 'image/heif',\n 'image/heic-sequence',\n 'image/heif-sequence',\n 'image/apng',\n 'audio/aac',\n 'audio/mpeg',\n 'audio/wav',\n 'audio/webm',\n 'audio/midi',\n 'audio/x-midi',\n 'audio/ogg',\n 'video/x-msvideo',\n 'video/mp4',\n 'video/mpeg',\n 'video/webm',\n 'video/quicktime',\n 'video/ogg',\n 'video/mp2t',\n 'video/3gpp',\n 'video/3gpp2',\n 'application/x-7z-compressed',\n 'application/zip',\n 'application/vnd.amazon.ebook',\n 'application/octet-stream',\n 'application/epub+zip',\n 'application/pdf',\n 'application/msword',\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n 'application/vnd.ms-fontobject',\n 'application/gzip',\n 'application/x-gzip',\n 'application/java-archive',\n 'application/json',\n 'application/ld+json',\n 'text/javascript',\n 'application/vnd.oasis.opendocument.presentation',\n 'application/vnd.oasis.opendocument.spreadsheet',\n 'application/vnd.oasis.opendocument.text',\n 'application/ogg',\n 'application/vnd.ms-powerpoint',\n 'application/vnd.openxmlformats-officedocument.presentationml.presentation',\n 'application/vnd.rar',\n 'application/x-tar',\n 'application/vnd.visio',\n 'application/xhtml+xml',\n 'application/vnd.ms-excel',\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n 'application/xml',\n];\n\nexport type UploadedFileResult = {\n pathname: string;\n lqip?: string;\n size: number;\n mimeType: string;\n originalFilename: string;\n width?: number;\n height?: number;\n};\n\nexport type UploadedAssetResult = UploadedFileResult & {\n asset: OrderedAssetValue;\n _id: string;\n};\n\ntype AssetUploadResponse = {\n _id: string;\n path: string | null;\n mimeType: string | null;\n originalFilename: string | null;\n size: number | null;\n width: number | null;\n height: number | null;\n lqip: string | null;\n sha256: string | null;\n deduped: boolean;\n};\n\nexport type OpenFileDialogAndUploadOptions = {\n projectId: string | undefined;\n accept?: string;\n files?: File[] | FileList;\n multiple?: boolean;\n maxBytes?: number;\n onUploadStart?: () => void;\n};\n\nfunction isAcceptedMimeType(file: File, accept?: string): boolean {\n if (!file.type) {\n return true;\n }\n\n const allowed = accept\n ? accept\n .split(',')\n .map((pattern) => pattern.trim())\n .filter(Boolean)\n : ACCEPTED_MIME_TYPES;\n\n if (allowed.length === 0) {\n return true;\n }\n\n return allowed.some((pattern) => {\n if (pattern.endsWith('/*')) {\n return file.type.startsWith(pattern.slice(0, -1));\n }\n\n return file.type === pattern;\n });\n}\n\n/**\n * Uploads a single file to the one-shot /assets endpoint, which stores the\n * blob and creates the _asset node in a single request.\n */\nexport async function uploadAssetFile(file: File, projectId: string | undefined): Promise<UploadedAssetResult> {\n const params = new URLSearchParams({ filename: file.name });\n const response = await fetch(`${apiPaths(projectId).assets}?${params.toString()}`, {\n method: 'POST',\n headers: { 'Content-Type': file.type || 'application/octet-stream' },\n body: file,\n });\n\n if (!response.ok) {\n throw new Error(`Upload failed for ${file.name}`);\n }\n\n const data = (await response.json()) as AssetUploadResponse;\n const asset: OrderedAssetValue = {\n _id: data._id,\n path: data.path ?? '',\n originalFilename: data.originalFilename ?? file.name,\n size: data.size ?? file.size,\n mimeType: data.mimeType ?? file.type,\n lqip: data.lqip ?? '',\n width: data.width ?? 0,\n height: data.height ?? 0,\n };\n\n return {\n pathname: asset.path,\n lqip: asset.lqip || undefined,\n originalFilename: asset.originalFilename,\n size: asset.size,\n mimeType: asset.mimeType,\n width: asset.width || undefined,\n height: asset.height || undefined,\n _id: asset._id,\n asset,\n };\n}\n\nasync function uploadSelectedFiles(\n files: File[] | FileList,\n options: OpenFileDialogAndUploadOptions\n): Promise<UploadedAssetResult[]> {\n const { projectId, accept, maxBytes = 4 * 1024 * 1024, onUploadStart } = options;\n const validFiles: File[] = [];\n\n for (const file of Array.from(files)) {\n if (file.size > maxBytes) {\n toast.error(`File size too big (max ${(maxBytes / (1024 * 1024)).toFixed(0)}MB): ${file.name}`);\n\n continue;\n }\n\n if (!isAcceptedMimeType(file, accept)) {\n toast.error(`Unsupported file type: ${file.name}`);\n\n continue;\n }\n\n validFiles.push(file);\n }\n\n if (validFiles.length === 0) {\n return [];\n }\n\n onUploadStart?.();\n\n try {\n const uploads = await Promise.all(validFiles.map(async (file) => uploadAssetFile(file, projectId)));\n\n if (uploads.length > 0) {\n toast.success(`Uploaded ${uploads.length} file${uploads.length > 1 ? 's' : ''}`);\n }\n\n return uploads;\n } catch (error) {\n console.error(error);\n toast.error('Upload failed. Please try again.');\n\n return [];\n }\n}\n\n/**\n * Opens a native file picker and uploads selected files to the Flexkit assets\n * endpoint, which also creates an asset node in the database.\n * Returns a list of uploaded file results. Skips files that exceed maxBytes.\n */\nasync function openFileDialogAndUpload(options: OpenFileDialogAndUploadOptions): Promise<UploadedAssetResult[]> {\n const { accept, multiple = true } = options;\n const input = document.createElement('input');\n input.type = 'file';\n input.accept = accept ?? ACCEPTED_MIME_TYPES.join(',');\n input.multiple = multiple;\n input.style.display = 'none';\n document.body.appendChild(input);\n\n try {\n const files = await new Promise<FileList | null>((resolve) => {\n input.addEventListener('change', () => resolve(input.files), { once: true });\n input.addEventListener('cancel', () => resolve(null), { once: true });\n input.click();\n });\n\n if (!files || files.length === 0) {\n return [];\n }\n\n return uploadSelectedFiles(files, options);\n } finally {\n document.body.removeChild(input);\n }\n}\n\nexport function useUploadAssets(): (options: OpenFileDialogAndUploadOptions) => Promise<UploadedAssetResult[]> {\n const apolloClient = useApolloClient();\n\n return useCallback(\n async (options: OpenFileDialogAndUploadOptions) => {\n const uploads = options.files\n ? await uploadSelectedFiles(options.files, options)\n : await openFileDialogAndUpload(options);\n\n if (uploads.length > 0) {\n // Upload is outside Apollo; soft-refresh mounted asset lists via useEntityQuery.\n await scheduleEntityListRefetch(apolloClient, 'GetAssets').catch((error: unknown) => {\n console.error('Error refreshing asset lists after upload:', error);\n });\n }\n\n return uploads;\n },\n [apolloClient]\n );\n}\n"]}
@@ -1,4 +1,4 @@
1
- import'./index.css';import {e,d,a as a$2,c,b as b$1}from'./chunk-E2NDJLAI.js';import {a}from'./chunk-YDVO6XWD.js';import {a as a$1}from'./chunk-ERDARDGB.js';import {b,c as c$1}from'./chunk-EYIV4KVY.js';import {find,propEq,omit,pick,toPairs,uniq,uniqBy,prop}from'ramda';import {useState,useRef,useMemo,useEffect,useCallback}from'react';import {gql,NetworkStatus}from'@apollo/client';import {useQuery}from'@apollo/client/react';var Gt=25,yn=3,Wt=3,mn=["id","string"],hn=["date","datetime","duration","time"],$t=`_id
1
+ import'./index.css';import {e,d,a as a$2,c,b as b$1}from'./chunk-AKW7EKYI.js';import {a}from'./chunk-YDVO6XWD.js';import {a as a$1}from'./chunk-ERDARDGB.js';import {b,c as c$1}from'./chunk-NSVX6HEN.js';import {find,propEq,omit,pick,toPairs,uniq,uniqBy,prop}from'ramda';import {useState,useRef,useMemo,useEffect,useCallback}from'react';import {gql,NetworkStatus}from'@apollo/client';import {useQuery}from'@apollo/client/react';var Gt=25,yn=3,Wt=3,mn=["id","string"],hn=["date","datetime","duration","time"],$t=`_id
2
2
  originalFilename
3
3
  mimeType
4
4
  path
@@ -374,5 +374,5 @@ ${A} ]
374
374
  }
375
375
  }
376
376
  }
377
- `}}var nt=t=>t.charAt(0).toUpperCase()+t.slice(1);function v(t){let n=t.split(/[^0-9A-Za-z]+/).filter(Boolean).map(nt).join("");return n?/^[A-Za-z_]/.test(n)?n:`Entity${n}`:"Entity"}function U(t,n){return n==="_assets"?b:find(propEq(n,"plural"))(t)}function ee(t,n,e){if(!t||typeof t!="object")return {};let r=U(e,n);if(!r)return {};let i=`update${nt(n)}`,s=t[i];if(!s||typeof s!="object")return {};let o=s[n],c=Array.isArray(o)?o[0]:void 0;return !c||typeof c!="object"?{}:r.attributes.reduce((u,l)=>{if(a(l)!=="local")return u;let d=B(c[l.name])?._id;return typeof d!="string"||d.length===0?u:{...u,[l.name]:d}},{})}var dt=null,_t=new Set,en=[],Rt=new Set,It=new Set,wt=new Set;function oe(t,n){if(t==="_asset"||t==="_assets")return `Get${v(b.plural)}`;let e=n.find(s=>s.plural===t),r=n.find(s=>s.name===t),i=e?.plural??r?.plural??t;return `Get${v(i)}`}function rn(t){return Rt.add(t),()=>{Rt.delete(t);}}function sn(t){return It.add(t),()=>{It.delete(t);}}function on(t){return wt.add(t),()=>{wt.delete(t);}}function ue(t,n,e){let r=new Set(e.filter(Boolean));if(r.size>0)for(let i of It)i(n,r);return jn(t,n)}function le(t,n){let e=n.filter(r=>!!r._id);if(e.length!==0)for(let r of wt)r(t,e);}function jn(t,n){return _t.add(n),new Promise((e,r)=>{en.push({resolve:e,reject:r}),dt&&clearTimeout(dt),dt=setTimeout(()=>{let i=new Set(_t),s=en.splice(0);_t.clear(),dt=null,Promise.all([...Rt].map(o=>Promise.resolve(o(i)))).then(()=>{for(let{resolve:o}of s)o();}).catch(o=>{console.error("Error refreshing entity lists:",o);for(let{reject:c}of s)c(o);});},50);})}function $e({entityNamePlural:t,schema:n,scope:e$1,variables:r,isForm:i,selection:s="full",includeCount:o=true}){let[c$1,u]=useState({count:0,results:[]}),[l,a]=useState(false),[d$1,f]=useState(false),[g,h]=useState(null),y=useRef(false),A=useRef(false),p=useRef(0),m=useRef(null),E=useRef(null),T=`${t}Total`,F=U(n,t),Q=r?.where===void 0&&(F?.spaces?.length??0)===0&&(g?.field!==T||g.schema!==n)?"total":"aggregate",J=useMemo(()=>gql(at(t,e$1,n,{selection:s,countMode:Q,includeCount:o}).query),[t,e$1,n,s,Q,o]),z=useMemo(()=>gql(at(t,e$1,n,{selection:s,includeCount:false}).query),[t,e$1,n,s]),{schemaErrorMessage:$,setSchemaErrorMessage:R}=e(),{loading:q,data:j,fetchMore:it,refetch:st,error:ot,networkStatus:H}=useQuery(J,{variables:r,notifyOnNetworkStatusChange:true}),Lt=useRef(it),gt=useRef(st),Ft=useRef(z),Ct=useRef(H),Tt=useRef(r);Lt.current=it,gt.current=st,Ft.current=z,Tt.current=r;let yt=o&&d(ot,T),Mt=Q==="total"&&yt,G=yt?void 0:ot,Y=yt&&!j?.[t],Qt=a$2(G),P=c(G),{isProjectDisabled:an,isProjectReadOnly:dn}=(()=>{if(Qt?.statusCode===403){let I=b$1(Qt.bodyText);if(I&&typeof I.code=="string"){if(I.code==="PROJECT_PAUSED")return {isProjectDisabled:true,isProjectReadOnly:false};if(I.code==="READ_ONLY_MODE")return {isProjectDisabled:false,isProjectReadOnly:true}}return {isProjectDisabled:true,isProjectReadOnly:false}}return {isProjectDisabled:false,isProjectReadOnly:false}})();useEffect(()=>{Mt&&h({field:T,schema:n});},[n,Mt,T]);let fn=useCallback(I=>{if(y.current||A.current)return;y.current=true,a(true);let{limit:x}=I.variables,k=p.current;Lt.current({...I,query:Ft.current,variables:{...Tt.current,...I.variables,offset:k,limit:x}}).then(({data:X})=>{let M=rt({data:X,entityNamePlural:t,isForm:i,schema:n,scope:e$1}),D=M.results.length;p.current=k+(D===0?0:Math.min(D,x)),u(C=>{let W=uniqBy(prop("_id"),[...C.results,...M.results]);return W.length===C.results.length?{count:C.results.length,results:C.results}:{count:M.count||C.count,results:W}});}).catch(X=>{console.error("Error fetching more data:",X);}).finally(()=>{y.current=false,a(false);});},[t,i,n,e$1]),pn=useCallback(I=>{if(A.current)return Promise.resolve();let x=I?.preserve===true;return A.current=true,y.current=false,a(false),x||(m.current=null,E.current=null,p.current=0,f(true),u({count:0,results:[]})),gt.current().then(({data:k})=>{let X=JSON.stringify({entityNamePlural:t,scope:e$1,selection:s,includeCount:o,variables:r}),M=rt({data:k,entityNamePlural:t,isForm:i,schema:n,scope:e$1});m.current=X,E.current=null,p.current=pt(r)+M.results.length,u(M);}).catch(k=>{console.error("Error reloading data:",k);}).finally(()=>{A.current=false,f(false);})},[t,i,n,e$1,s,o,r]);return useEffect(()=>{if(P){R(P);return}j&&$&&!G&&R(null);},[j,G,$,P,R]),useEffect(()=>{if(G||P||Y)return;let I=JSON.stringify({entityNamePlural:t,scope:e$1,selection:s,includeCount:o,variables:r});if(m.current===I)return;if(q&&E.current!==I){E.current=I,p.current=0,u({count:0,results:[]});return}if(q)return;let x=rt({data:j,entityNamePlural:t,isForm:i,schema:n,scope:e$1});m.current=I,E.current=null,p.current=pt(r)+x.results.length,u(x);},[j,G,t,i,q,Y,n,P,e$1,s,o,r]),useEffect(()=>{let I=Ct.current;if(Ct.current=H,G||P||A.current||Y||I!==NetworkStatus.refetch||H!==NetworkStatus.ready||!j)return;let x=JSON.stringify({entityNamePlural:t,scope:e$1,selection:s,includeCount:o,variables:r}),k=rt({data:j,entityNamePlural:t,isForm:i,schema:n,scope:e$1});m.current=x,E.current=null,p.current=pt(r)+k.results.length,u(k);},[j,G,t,i,Y,H,n,P,e$1,s,o,r]),useEffect(()=>{if(i)return;let I=`Get${v(t)}`,x=rn(M=>{if(!(!M.has(I)||y.current||A.current))return gt.current().then(({data:D})=>{let C=JSON.stringify({entityNamePlural:t,scope:e$1,selection:s,includeCount:o,variables:r}),W=rt({data:D,entityNamePlural:t,isForm:i,schema:n,scope:e$1});m.current=C,E.current=null,p.current=pt(r)+W.results.length,u(W);}).catch(D=>{console.error("Error soft-refreshing entity list:",D);})}),k=sn((M,D)=>{M===I&&u(C=>{let W=C.results.filter(xt=>{let kt=typeof xt._id=="string"?xt._id:void 0;return !kt||!D.has(kt)}),qt=C.results.length-W.length;return qt===0?C:{count:Math.max(0,C.count-qt),results:W}});}),X=on((M,D)=>{M===I&&u(C=>Bn(C,D,r?.sort));});return ()=>{x(),k(),X();}},[t,i,n,e$1,s,o,r]),{isLoading:q&&H!==NetworkStatus.refetch||d$1||Y,isLoadingMore:l,fetchMore:fn,reload:pn,count:c$1.count,data:c$1.results,isProjectDisabled:an,isProjectReadOnly:dn,schemaErrorMessage:$}}function pt(t){let n=t?.offset;return typeof n=="number"&&Number.isFinite(n)?n:0}function rt(t){let n=t.entityNamePlural;return t.data?.[n]?t.isForm?Ht(t.entityNamePlural,t.scope,t.data,t.schema):Zt(t.entityNamePlural,t.scope,t.data,t.schema):{count:0,results:[]}}function Bn(t,n,e){let r=new Map(n.map(o=>[o._id,o])),i=false,s=t.results.map(o=>{let c=typeof o._id=="string"?o._id:void 0;if(!c)return o;let u=r.get(c);return u?(i=true,{...o,...u.attributes}):o});return i?{count:t.count,results:zn(s,e)}:t}function zn(t,n){if(!Array.isArray(n)||n.length===0)return t;let[e]=n;if(!e||typeof e!="object")return t;let[r]=Object.entries(e),[i,s]=r??[];if(!i||s!=="ASC"&&s!=="DESC")return t;let o=s==="DESC"?-1:1;return [...t].sort((c,u)=>{let l=c[i],a=u[i],d=typeof l=="string"?l:"",f=typeof a=="string"?a:"";return d.localeCompare(f)*o})}export{Gt as a,Kt as b,An as c,Xn as d,at as e,Zt as f,Zn as g,Hn as h,Yn as i,Nn as j,te as k,ne as l,U as m,ee as n,oe as o,ue as p,le as q,jn as r,$e as s};//# sourceMappingURL=chunk-AMUTDCI7.js.map
378
- //# sourceMappingURL=chunk-AMUTDCI7.js.map
377
+ `}}var nt=t=>t.charAt(0).toUpperCase()+t.slice(1);function v(t){let n=t.split(/[^0-9A-Za-z]+/).filter(Boolean).map(nt).join("");return n?/^[A-Za-z_]/.test(n)?n:`Entity${n}`:"Entity"}function U(t,n){return n==="_assets"?b:find(propEq(n,"plural"))(t)}function ee(t,n,e){if(!t||typeof t!="object")return {};let r=U(e,n);if(!r)return {};let i=`update${nt(n)}`,s=t[i];if(!s||typeof s!="object")return {};let o=s[n],c=Array.isArray(o)?o[0]:void 0;return !c||typeof c!="object"?{}:r.attributes.reduce((u,l)=>{if(a(l)!=="local")return u;let d=B(c[l.name])?._id;return typeof d!="string"||d.length===0?u:{...u,[l.name]:d}},{})}var dt=null,_t=new Set,en=[],Rt=new Set,It=new Set,wt=new Set;function oe(t,n){if(t==="_asset"||t==="_assets")return `Get${v(b.plural)}`;let e=n.find(s=>s.plural===t),r=n.find(s=>s.name===t),i=e?.plural??r?.plural??t;return `Get${v(i)}`}function rn(t){return Rt.add(t),()=>{Rt.delete(t);}}function sn(t){return It.add(t),()=>{It.delete(t);}}function on(t){return wt.add(t),()=>{wt.delete(t);}}function ue(t,n,e){let r=new Set(e.filter(Boolean));if(r.size>0)for(let i of It)i(n,r);return jn(t,n)}function le(t,n){let e=n.filter(r=>!!r._id);if(e.length!==0)for(let r of wt)r(t,e);}function jn(t,n){return _t.add(n),new Promise((e,r)=>{en.push({resolve:e,reject:r}),dt&&clearTimeout(dt),dt=setTimeout(()=>{let i=new Set(_t),s=en.splice(0);_t.clear(),dt=null,Promise.all([...Rt].map(o=>Promise.resolve(o(i)))).then(()=>{for(let{resolve:o}of s)o();}).catch(o=>{console.error("Error refreshing entity lists:",o);for(let{reject:c}of s)c(o);});},50);})}function $e({entityNamePlural:t,schema:n,scope:e$1,variables:r,isForm:i,selection:s="full",includeCount:o=true}){let[c$1,u]=useState({count:0,results:[]}),[l,a]=useState(false),[d$1,f]=useState(false),[g,h]=useState(null),y=useRef(false),A=useRef(false),p=useRef(0),m=useRef(null),E=useRef(null),T=`${t}Total`,F=U(n,t),Q=r?.where===void 0&&(F?.spaces?.length??0)===0&&(g?.field!==T||g.schema!==n)?"total":"aggregate",J=useMemo(()=>gql(at(t,e$1,n,{selection:s,countMode:Q,includeCount:o}).query),[t,e$1,n,s,Q,o]),z=useMemo(()=>gql(at(t,e$1,n,{selection:s,includeCount:false}).query),[t,e$1,n,s]),{schemaErrorMessage:$,setSchemaErrorMessage:R}=e(),{loading:q,data:j,fetchMore:it,refetch:st,error:ot,networkStatus:H}=useQuery(J,{variables:r,notifyOnNetworkStatusChange:true}),Lt=useRef(it),gt=useRef(st),Ft=useRef(z),Ct=useRef(H),Tt=useRef(r);Lt.current=it,gt.current=st,Ft.current=z,Tt.current=r;let yt=o&&d(ot,T),Mt=Q==="total"&&yt,G=yt?void 0:ot,Y=yt&&!j?.[t],Qt=a$2(G),P=c(G),{isProjectDisabled:an,isProjectReadOnly:dn}=(()=>{if(Qt?.statusCode===403){let I=b$1(Qt.bodyText);if(I&&typeof I.code=="string"){if(I.code==="PROJECT_PAUSED")return {isProjectDisabled:true,isProjectReadOnly:false};if(I.code==="READ_ONLY_MODE")return {isProjectDisabled:false,isProjectReadOnly:true}}return {isProjectDisabled:true,isProjectReadOnly:false}}return {isProjectDisabled:false,isProjectReadOnly:false}})();useEffect(()=>{Mt&&h({field:T,schema:n});},[n,Mt,T]);let fn=useCallback(I=>{if(y.current||A.current)return;y.current=true,a(true);let{limit:x}=I.variables,k=p.current;Lt.current({...I,query:Ft.current,variables:{...Tt.current,...I.variables,offset:k,limit:x}}).then(({data:X})=>{let M=rt({data:X,entityNamePlural:t,isForm:i,schema:n,scope:e$1}),D=M.results.length;p.current=k+(D===0?0:Math.min(D,x)),u(C=>{let W=uniqBy(prop("_id"),[...C.results,...M.results]);return W.length===C.results.length?{count:C.results.length,results:C.results}:{count:M.count||C.count,results:W}});}).catch(X=>{console.error("Error fetching more data:",X);}).finally(()=>{y.current=false,a(false);});},[t,i,n,e$1]),pn=useCallback(I=>{if(A.current)return Promise.resolve();let x=I?.preserve===true;return A.current=true,y.current=false,a(false),x||(m.current=null,E.current=null,p.current=0,f(true),u({count:0,results:[]})),gt.current().then(({data:k})=>{let X=JSON.stringify({entityNamePlural:t,scope:e$1,selection:s,includeCount:o,variables:r}),M=rt({data:k,entityNamePlural:t,isForm:i,schema:n,scope:e$1});m.current=X,E.current=null,p.current=pt(r)+M.results.length,u(M);}).catch(k=>{console.error("Error reloading data:",k);}).finally(()=>{A.current=false,f(false);})},[t,i,n,e$1,s,o,r]);return useEffect(()=>{if(P){R(P);return}j&&$&&!G&&R(null);},[j,G,$,P,R]),useEffect(()=>{if(G||P||Y)return;let I=JSON.stringify({entityNamePlural:t,scope:e$1,selection:s,includeCount:o,variables:r});if(m.current===I)return;if(q&&E.current!==I){E.current=I,p.current=0,u({count:0,results:[]});return}if(q)return;let x=rt({data:j,entityNamePlural:t,isForm:i,schema:n,scope:e$1});m.current=I,E.current=null,p.current=pt(r)+x.results.length,u(x);},[j,G,t,i,q,Y,n,P,e$1,s,o,r]),useEffect(()=>{let I=Ct.current;if(Ct.current=H,G||P||A.current||Y||I!==NetworkStatus.refetch||H!==NetworkStatus.ready||!j)return;let x=JSON.stringify({entityNamePlural:t,scope:e$1,selection:s,includeCount:o,variables:r}),k=rt({data:j,entityNamePlural:t,isForm:i,schema:n,scope:e$1});m.current=x,E.current=null,p.current=pt(r)+k.results.length,u(k);},[j,G,t,i,Y,H,n,P,e$1,s,o,r]),useEffect(()=>{if(i)return;let I=`Get${v(t)}`,x=rn(M=>{if(!(!M.has(I)||y.current||A.current))return gt.current().then(({data:D})=>{let C=JSON.stringify({entityNamePlural:t,scope:e$1,selection:s,includeCount:o,variables:r}),W=rt({data:D,entityNamePlural:t,isForm:i,schema:n,scope:e$1});m.current=C,E.current=null,p.current=pt(r)+W.results.length,u(W);}).catch(D=>{console.error("Error soft-refreshing entity list:",D);})}),k=sn((M,D)=>{M===I&&u(C=>{let W=C.results.filter(xt=>{let kt=typeof xt._id=="string"?xt._id:void 0;return !kt||!D.has(kt)}),qt=C.results.length-W.length;return qt===0?C:{count:Math.max(0,C.count-qt),results:W}});}),X=on((M,D)=>{M===I&&u(C=>Bn(C,D,r?.sort));});return ()=>{x(),k(),X();}},[t,i,n,e$1,s,o,r]),{isLoading:q&&H!==NetworkStatus.refetch||d$1||Y,isLoadingMore:l,fetchMore:fn,reload:pn,count:c$1.count,data:c$1.results,isProjectDisabled:an,isProjectReadOnly:dn,schemaErrorMessage:$}}function pt(t){let n=t?.offset;return typeof n=="number"&&Number.isFinite(n)?n:0}function rt(t){let n=t.entityNamePlural;return t.data?.[n]?t.isForm?Ht(t.entityNamePlural,t.scope,t.data,t.schema):Zt(t.entityNamePlural,t.scope,t.data,t.schema):{count:0,results:[]}}function Bn(t,n,e){let r=new Map(n.map(o=>[o._id,o])),i=false,s=t.results.map(o=>{let c=typeof o._id=="string"?o._id:void 0;if(!c)return o;let u=r.get(c);return u?(i=true,{...o,...u.attributes}):o});return i?{count:t.count,results:zn(s,e)}:t}function zn(t,n){if(!Array.isArray(n)||n.length===0)return t;let[e]=n;if(!e||typeof e!="object")return t;let[r]=Object.entries(e),[i,s]=r??[];if(!i||s!=="ASC"&&s!=="DESC")return t;let o=s==="DESC"?-1:1;return [...t].sort((c,u)=>{let l=c[i],a=u[i],d=typeof l=="string"?l:"",f=typeof a=="string"?a:"";return d.localeCompare(f)*o})}export{Gt as a,Kt as b,An as c,Xn as d,at as e,Zt as f,Zn as g,Hn as h,Yn as i,Nn as j,te as k,ne as l,U as m,ee as n,oe as o,ue as p,le as q,jn as r,$e as s};//# sourceMappingURL=chunk-XV2B3W6Z.js.map
378
+ //# sourceMappingURL=chunk-XV2B3W6Z.js.map