@vercel/board 0.27.0 → 0.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{a2-B8P8hjOT.mjs → a2-HUbQJ0RD.mjs} +16 -192
- package/dist/access.d.mts +1 -1
- package/dist/access.mjs +3 -3
- package/dist/{actors-BLXVp4oZ.mjs → actors-DcJhFbwJ.mjs} +2 -2
- package/dist/{auth-lTkOgvcE.mjs → auth-JO22iIwr.mjs} +1 -1
- package/dist/{backend-ZKYTe3xa.d.mts → backend-CPC_vyOo.d.mts} +5 -5
- package/dist/backend-a2/blob-vercel.d.mts +1 -1
- package/dist/backend-a2/contract.d.mts +1 -1
- package/dist/backend-a2/contract.mjs +3 -3
- package/dist/backend-a2/store-memory.d.mts +1 -1
- package/dist/backend-a2/store-memory.mjs +2 -2
- package/dist/backend-a2/store-postgres.d.mts +1 -1
- package/dist/backend-a2/store-postgres.mjs +1 -1
- package/dist/backend-a2/store-redis-http.d.mts +1 -1
- package/dist/backend-a2/store-redis-http.mjs +1 -1
- package/dist/backend-a2/store-redis.d.mts +1 -1
- package/dist/backend-a2/store-redis.mjs +1 -1
- package/dist/backend-a2/store-sqlite.d.mts +1 -1
- package/dist/backend-a2/store-sqlite.mjs +2 -2
- package/dist/backend-a2.d.mts +8 -5
- package/dist/backend-a2.mjs +2 -1
- package/dist/{backend-http-nppEk8gC.mjs → backend-http-Bmp0IgD3.mjs} +2 -2
- package/dist/{backend-http-E7YU0qhn.d.mts → backend-http-CqfKhrnn.d.mts} +5 -3
- package/dist/{backend-http-DEMvX2ht.mjs → backend-http-CzIJMm58.mjs} +3 -3
- package/dist/backend-http.d.mts +1 -1
- package/dist/backend-http.mjs +1 -1
- package/dist/backend-http.node.d.mts +1 -1
- package/dist/backend-http.node.mjs +1 -1
- package/dist/{backend-vercel-CIRObA0t.d.mts → backend-vercel-4tvcPKqX.d.mts} +7 -3
- package/dist/{backend-vercel-K5rDrMxZ.mjs → backend-vercel-BNauAs7w.mjs} +68 -10
- package/dist/{backend-vercel-CnViBZYT.mjs → backend-vercel-DQc_TaHp.mjs} +5 -3
- package/dist/backend-vercel.d.mts +1 -1
- package/dist/backend-vercel.mjs +1 -1
- package/dist/backend-vercel.node.d.mts +1 -1
- package/dist/backend-vercel.node.mjs +1 -1
- package/dist/blob-DdbpJqN1.mjs +182 -0
- package/dist/{blob-B-9AvYis.d.mts → blob-DmiQjrYy.d.mts} +2 -2
- package/dist/{chat-provider-DsNEBQiA.d.mts → chat-provider-BWHbChcQ.d.mts} +5 -3
- package/dist/{chat-provider-DnHibqnM.mjs → chat-provider-COtsU5jB.mjs} +2 -2
- package/dist/cli-commands.mjs +1 -1
- package/dist/cli-embedded.d.mts +5 -3
- package/dist/cli-embedded.mjs +6 -4
- package/dist/cli.mjs +5 -5
- package/dist/{client-xLxeDz0f.d.mts → client-BqAjk0Q4.d.mts} +8 -1
- package/dist/{commands-BFookFtn.mjs → commands-C3R1AWgm.mjs} +4 -1
- package/dist/conformance.d.mts +1 -1
- package/dist/{engine-Bfe6pcXb.mjs → engine-DQxXk7dX.mjs} +20 -12
- package/dist/{errors-CB4tnZGz.d.mts → errors-DDktVeUa.d.mts} +1 -1
- package/dist/{events-CewD4kw7.mjs → events-qf5XG5VQ.mjs} +2 -2
- package/dist/{exports-uiRQD2-i.mjs → exports-BG-0Wyn-.mjs} +9 -9
- package/dist/exports-mhAYiU4i.d.mts +5 -0
- package/dist/{external-BV_cUncs.mjs → external-D3p5T57R.mjs} +4 -2
- package/dist/{folds-Dyjput8M.mjs → folds-BDMSxBUf.mjs} +2 -2
- package/dist/{folds-jS9wlh9_.d.mts → folds-ZkHM4M-v.d.mts} +2 -0
- package/dist/{index-C05it0mC.d.mts → index-D3VvNfh_.d.mts} +2 -2
- package/dist/index.d.mts +5 -5
- package/dist/{index.default-RaGMBzNu.mjs → index.default-rB8sJ9RX.mjs} +1 -1
- package/dist/index.mjs +4 -4
- package/dist/index.node.d.mts +5 -5
- package/dist/index.node.mjs +2 -2
- package/dist/inspect/app.js +3 -3
- package/dist/inspect/engine.js +5 -5
- package/dist/{main-CRHQQFgN.mjs → main-CVBqe3VO.mjs} +14 -9
- package/dist/{middleware-ChKM1zuu.mjs → middleware-CXjEeef4.mjs} +1 -1
- package/dist/{node-Ybi9E6bO.mjs → node-Zd_C-gxP.mjs} +34 -17
- package/dist/{project-DMDST9kl.mjs → project-CBXlLftU.mjs} +1 -1
- package/dist/{provider-poIkXapd.mjs → provider-BaVmi4Hi.mjs} +3 -1
- package/dist/{provider-Cdg1qadh.d.mts → provider-DmSTp9lI.d.mts} +9 -2
- package/dist/{redis-tables-DN9PfIDi.mjs → redis-tables-BJQVUspu.mjs} +2 -2
- package/dist/{reducers-BcmSs4qf.mjs → reducers-DJzVpXwM.mjs} +3 -3
- package/dist/{schemas-Be08nyfW.mjs → schemas-DBmUO6pr.mjs} +2 -1
- package/dist/{serve-BsbHOJFN.mjs → serve-G9RuaDSr.mjs} +5 -4
- package/dist/{server-C0DVYiHm.mjs → server-BixV_byP.mjs} +4 -4
- package/dist/{serving-CvOWEym2.mjs → serving-B75Y4BF-.mjs} +1 -1
- package/dist/{sql-U9WTxrwJ.mjs → sql-D4Z_efJX.mjs} +2 -2
- package/dist/{sqlite-db-Ds4majtT.mjs → sqlite-db-Bz2JkfCU.mjs} +1 -1
- package/dist/sync-github.d.mts +4 -2
- package/dist/sync-github.mjs +4 -14
- package/dist/sync-kapso.d.mts +3 -2
- package/dist/sync-kapso.mjs +3 -3
- package/dist/sync-linear.d.mts +12 -2
- package/dist/sync-linear.mjs +189 -9
- package/dist/sync-slack.d.mts +41 -5
- package/dist/sync-slack.mjs +70 -11
- package/dist/sync.chat.d.mts +1 -1
- package/dist/sync.chat.mjs +1 -1
- package/dist/sync.d.mts +2 -2
- package/dist/sync.mjs +3 -3
- package/dist/tags-BpFo6q0_.mjs +14 -0
- package/dist/{targets-C-wdR5wP.mjs → targets-Cgjs29T0.mjs} +1 -1
- package/dist/{tokens-BuCU-61R.mjs → tokens-CC3izSNr.mjs} +1 -1
- package/dist/{types-aCAf6lGU.d.mts → types-No0WdhE5.d.mts} +1 -1
- package/dist/{watchers-hash-qSMYlljN.mjs → watchers-hash-BDhLVkV5.mjs} +7 -5
- package/docs/02-sync/03-slack.md +6 -2
- package/docs/02-sync/07-linear.md +28 -6
- package/docs/04-reference/01-cli.md +7 -2
- package/package.json +1 -1
- package/dist/exports-D22M68rk.d.mts +0 -5
package/dist/inspect/engine.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{C as e,D as t,E as n,O as r,S as i,T as a,_ as o,a as s,b as c,c as l,d as u,f as d,g as f,h as p,i as m,k as h,l as g,m as _,n as v,o as y,p as b,r as x,s as ee,t as te,u as S,v as C,w,x as T,y as E}from"./app.js";const D=/^\[vc\]: #\S*\r?\n/,O=/\[([^\]]+)\]\((https?:\/\/[^)\s]+)\)/g,
|
|
2
|
-
`,r)+1||e.length,!i.startsWith(`|`)||/^\|\s*(Project|Name)\s*\|/.test(i)||/^\|\s*:?-/.test(i))continue;let o=i.split(`|`).slice(1,-1).map(e=>e.trim());if(o.length<2)continue;let s=
|
|
3
|
-
`)}function
|
|
4
|
-
`)}`:e,
|
|
5
|
-
`).filter(e=>/^📎 .* didn't come over: /u.test(e)),V=e=>JSON.stringify([e.url,e.message,e.snapshot,e.unavailable]),de=(e,t)=>e.length===t.length&&e.every((e,n)=>V(e)===V(t[n])),fe=/^\s*`?(vb-[a-z0-9]{4}-[a-z0-9]{4})`?\s*$/i,H=6e4,pe=new AbortController().signal,me=e=>{try{return JSON.parse(JSON.stringify(e??null))}catch{return null}},U=e=>typeof e==`string`?o(e):Array.isArray(e)?e.map(U):typeof e==`object`&&e?Object.fromEntries(Object.entries(e).map(([e,t])=>[o(e),U(t)])):e,W=e=>{let t=e?.data?.error,n=typeof t==`string`?t:e instanceof Error?e.message:String(e);return o(n.slice(0,500))||`unknown error`},G=e=>e instanceof m&&e.status===404;function he(e){let i=null,o=()=>{if(!i)throw Error(`sync used before board() bound it`);return i},c={self:`sync`,origin:{via:{kind:`engine`}}};function l(e,t,n=pe,r=c){let i=o().backend;return i[e].call(i,r,t,n)}let f=t=>{let n=e[t];if(!n)throw s(`no sync entry named ${t}`);return n},p=e=>e.slice(0,e.indexOf(`:`)),g=t=>e[p(t)]!==void 0,_=e=>e.slice(e.indexOf(`:`)+1);async function C(e){try{return await l(`syncThread`,{thread:e})}catch(e){if(G(e))return null;throw e}}async function w(e){try{let{message:t,replies:n}=await l(`message`,{id:e});return[t,...n]}catch(e){if(G(e))return[];throw e}}async function T(e){return(await w(e)).find(t=>t.id===e)??null}async function E(e){return e.length===0?{}:(await l(`syncCopies`,{message:[...new Set(e)]})).copies}let D=(e,t)=>l(`syncFind`,e,t);async function O(){let{actors:e}=await l(`actors`,{}),t={byId:{},links:{}};for(let{person:n,...r}of e)t.byId[r.id]={id:r.id,kind:r.kind,handle:r.handle,name:r.name,avatar:r.avatar},n&&(t.links[r.id]=n.id);return t}let ne=(e,t)=>Object.entries(e.links).filter(([,e])=>e===t).map(([e])=>e),k=/* @__PURE__ */ new Map;function A(e,t){let n=`${e}:${t}`,r=k.get(n);if(r&&(!r.failed||Date.now()-r.at<6e4))return r.id;let i={id:f(e).resolveChannel(t),failed:!1,at:Date.now()};return i.id.catch(r=>{i.failed=!0;let a=oe(r);!a&&k.get(n)===i&&k.delete(n),console.warn(`[board] sync ${e}: ${a?`skipping`:`couldn't resolve`} ${t}: ${r.message}`)}),k.set(n,i),i.id}function j(e,t){if(!d(t))return _(t);try{let n=f(e).inboxChannel(e,t);return n===null?null:_(n)}catch{return null}}async function re(t){for(let n of Object.values(e)){let e=await n.findByEmail(t).catch(()=>null);if(e)return{id:e.id,kind:`external`,handle:e.handle,name:e.name,avatar:e.avatar}}return null}async function I(e){let t=e.indexOf(`:`);if(t<=0)throw s(`sync targets look like <key>:<channel or thread>, got: ${e}`);let n=e.slice(0,t),r=f(n);try{let i=ae.parse(await r.resolveTarget(e.slice(t+1)));if(i.kind===`channel`&&!r.canStartThreads)throw Error(`${r.platform} cannot start threads; use an existing thread`);return{target:`${n}:${i.target}`,kind:i.kind}}catch(t){throw s(`can't sync to ${e}: ${t.message}`)}}async function V(e,t){let{event:n,raw:r,dedupe:i}=se.parse(U({...t,raw:me(t.raw)}));for(let t of[n.channel,n.thread,`subthread`in n?n.subthread:null])if(t!==null&&!t.startsWith(`${e}:`))throw s(`provider locations must belong to sync entry ${e}`);let a=ce(f(e));(!a||await a(_(n.channel),t=>A(e,t))||await he(n.thread))&&await l(`inboxPush`,{key:e,events:[{id:i,event:n,raw:r}]})}async function he(e){try{return(await D({thread:e},AbortSignal.timeout(2e3))).thread!==null}catch(e){let t=e?.name;if(t===`TimeoutError`||t===`AbortError`)return!0;throw e}}async function ge(t,n){let r=e[t];if(!r)throw y(`no sync entry named ${t}`);let i;try{i=await r.receive(t,n,e=>V(t,e))}catch(e){return console.error(`[board] intake failed`,e),new Response(`intake failed`,{status:500})}let a=_e([t]).catch(e=>console.error(`[board] couldn't pull ${t}'s inbox:`,W(e)));return x(a),i}async function _e(t=Object.keys(e)){let n=0,r=Date.now()+24e4;for(let e of t)for(;Date.now()<r;){let{items:t}=await l(`inboxNext`,{key:e,limit:10});if(t.length===0)break;await Promise.all(t.map(t=>ve(e,t))),n+=t.length}return n}async function ve(e,t){let n;try{await xe(e,{event:t.event,raw:t.raw},{id:t.id,attempt:t.attempt+1})}catch(r){console.error(`[board] sync ${e} couldn't import ${t.id}:`,W(r)),n=W(r)}await l(`inboxAck`,{key:e,id:t.id,lease:t.lease,...n===void 0?{}:{error:n}}).catch(e=>console.error(`[board] couldn't ack an inbox event:`,W(e)))}async function ye(e,t,n,r=[]){if(t.length===0)return[];let i=[];for(let a of t){if(i.some(e=>e.url===a.url))continue;let t=(await D({thread:a.thread,message:a.message})).message,o=t===null?null:await T(t);if(o&&!o.deleted&&o.channel===n){i.push({url:a.url,message:o.id,unavailable:null,snapshot:{author:o.author?.name??o.by.actor,text:o.text,createdAt:o.createdAt,files:o.attachments.map(e=>({name:e.name,url:null}))}});continue}if(a.snapshot){i.push({url:a.url,message:null,snapshot:a.snapshot,unavailable:null});continue}let s=r.find(e=>e.url===a.url&&e.snapshot&&e.message===null);if(s){i.push(s);continue}let c=await e.fetchLink(a).catch(e=>({snapshot:null,unavailable:W(e)}));i.push({url:a.url,message:null,snapshot:c.snapshot,unavailable:c.snapshot?null:(c.unavailable??`unknown`).slice(0,300)})}return U(i)}async function be(e,t,i){let o=[],s=[],c=!1;for(let u of t.slice(0,10)){if(c){s.push(le(u));continue}if(u.size!==void 0&&u.size>26214400){s.push(R(u,`over ${n/1024/1024} MB`));continue}let t;try{let n=await e.fetchFile(u);if(n===null){s.push(R(u,`${e.platform} can't hand it over`));continue}t=n}catch(t){if(i<3)throw t;console.warn(`[board] couldn't fetch ${u.name??`a file`} from ${e.platform}:`,W(t)),s.push(R(u,`${e.platform} wouldn't hand it over`));continue}if(t.byteLength>26214400){s.push(R(u,`over ${n/1024/1024} MB`));continue}if(t.byteLength===0){s.push(R(u,`it was empty`));continue}let d=u.name??`${u.type}`;try{o.push((await l(`upload`,{data:t,name:d,type:u.mimeType||r(d)})).attachment)}catch(e){if(e instanceof m&&(e.code===`too_large`||e.code===`no_direct_uploads`)){s.push(R(u,`over ${a/1024/1024} MB`));continue}if(!z(e))throw e;c=!0,s.push(le(u))}}for(let e of t.slice(10))s.push(R(e,`a message carries at most 10`));return{attachments:o,notes:s}}async function xe(e,t,n){let{event:r,raw:i}=t,a=f(e),c=(await D({thread:r.thread})).thread??void 0;if(r.kind===`message`){let t=(await D({thread:r.subthread??r.thread,message:r.message})).message;if(t!==null){let e=(await T(t))?.origin;if(!e||e.message!==r.message||(e.subthread??e.thread)!==(r.subthread??r.thread))return}else if(a.users&&n.attempt<6&&await we(c,r))throw Error(`holding ${r.message} until ${r.author.id}'s board message there has its receipt`);let i=r.author.isBot?void 0:fe.exec(r.text)?.[1];if(i&&await Te(e,r,i))return}let l=`author`in r?r.author:{id:`${a.platform}:system`,handle:a.platform,name:a.platform,avatar:null,isBot:!0},u,d=()=>u??=P(a.event({id:n.id,key:e,event:r,raw:i})),p,m,h=!0,g={direction:`in`,key:e,channel:_(r.channel),get event(){return d()},board:o().client({author:l,key:e,...Ce(e,r)},n.id),import(r,i={}){if(!h)throw s(`the sync function has finished`);return p??=Se(e,t,n,c,r,i),p},permalink(){let e=m??a.permalink(d());return m=e,e.catch(()=>{m===e&&(m=void 0)}),e},resolve:t=>A(e,t)};try{await a.sync(g),await p}finally{h=!1}}async function Se(e,t,n,r,i,a){let o=i??(r?(await C(r))?.channel:void 0);if(o===void 0)return{root:null,message:null};try{return await Ae(e,t,n,b.parse(o),N.parse(a))}catch(e){if(!(e instanceof te))throw e;let n=(await D({thread:t.event.thread})).thread;return{root:n===null?null:(await C(n))?.root??null,message:null}}}function Ce(e,t){let n=f(e),r=(`subthread`in t?t.subthread:null)??t.thread;return{via:{kind:`sync`,key:e,platform:n.platform,channel:t.channel,thread:r},respond:async e=>{await n.post(_(r),`thread`,{markdown:e})}}}async function we(e,t){let n=(await D({account:t.author.id})).person;if(!n||n.method!==`consent`)return!1;let r=Date.now(),i=(e,t,i)=>e.by.principal===n.id&&e.by.profile===null&&e.from===null&&!e.deleted&&!e.noSync&&r-Date.parse(e.createdAt)<H&&!i[t]&&!e.undelivered[t];if(e!==void 0){let n=await C(e);if(!n)return!1;let r=n.targets.filter(e=>n.external[e]===t.thread),a=await w(n.root),o=await E(a.map(e=>e.id));return a.some(e=>r.some(t=>i(e,t,o[e.id]??{})))}let{roots:a}=await l(`syncRoots`,{by:n.id,since:r-H}),o=await E(a.map(e=>e.id));for(let e of a){let n=await C(e.thread);if(n?.targets.includes(t.channel)&&!n.external[t.channel]&&i(e,t.channel,o[e.id]??{}))return!0}return!1}async function Te(e,t,n){try{await l(`syncAccount`,{sync:e,account:t.author,code:n,message:u(t.subthread??t.thread,t.message)})}catch(e){if(G(e))return!1;throw e}return await f(e).react(_(t.subthread??t.thread),t.message,`check`,!0).catch(t=>console.warn(`[board] couldn't confirm a linking code on ${e}:`,W(t))),!0}let Ee=e=>f(e).users!==null;async function De(e,t,n){let r=f(e);if(!r.users)throw s(`${e} can't sign people in: link it with a code`);return r.users.authorize(t,n?{callback:n}:{})}async function Oe(e,t){let n=f(e);if(!n.users)throw s(`${e} can't sign people in: link it with a code`);let r=await n.users.token(t);if(!r)return null;let i=await n.whoAmI(r);if(!i.id.startsWith(`${n.platform}:user:`))throw s(`${e} named an account that isn't a ${n.platform} user`);return i}async function ke(e,t,n){let r=await Oe(e,t);return r?(await l(`syncAccount`,{sync:e,account:r,code:n,method:`consent`})).link:null}async function Ae(e,t,n,r,i){let{event:a,raw:o}=t,c=Ce(e,a),u=f(e),d=(await D({thread:a.thread})).thread??void 0,p=d?await C(d):null,m=p?.root,g=e=>ee(`board-inbound`,n.id,String(e)),v={key:e,channel:c.via.channel,thread:c.via.thread},y=async e=>{if(!e.dropped)return e.message;for(let t of e.dropped)await c.respond(t);throw new te(e.dropped)},b=async({attachments:t=[],...n})=>({id:await y(await l(`syncImport`,{op:`post`,from:e,source:v,...n,origin:n.origin??null,...t.length?{attachments:t.map(e=>e.id)}:{}})),re:n.re??null}),x=e=>({root:e.re??e.id,message:e.id}),S=(e={})=>{let t={...e,...i.labels};for(let e of i.unset??[])delete t[e];return t},w=e=>{if(!i.root)return e;let t=i.root(P(structuredClone(e)));if(t&&typeof t==`object`&&`then`in t)throw s(`root overrides must be synchronous`);let n=N.pick({text:!0,labels:!0}).parse(t);return{...e,text:n.text??e.text,labels:{...e.labels,...n.labels}}},E=(t,n,r)=>l(`syncImport`,{op:`labels`,author:t,from:e,origin:{thread:a.thread},set:n,unset:r}),O=async(e,t)=>{if(!i.labels&&!i.unset)return;let n=await T(t),r=Object.fromEntries(Object.entries(i.labels??{}).filter(([e,t])=>n?.labels[e]!==t)),a=(i.unset??[]).filter(e=>n?.labels[e]!==void 0);(Object.keys(r).length||a.length)&&await E(e,r,a)};switch(a.kind){case`message`:{let e=(await D({thread:a.subthread??a.thread,message:a.message})).message;if(e!==null)return{root:m??e,message:e};let{attachments:t,notes:s}=a.files?.length?await be(u,a.files,n.attempt):{attachments:[],notes:[]},c=await ye(u,a.links??[],p?.channel??r),l={...c.length?{links:c}:{},author:a.author,text:L(B(i.text??a.text,s),t.length>0),...t.length?{attachments:t}:{},origin:{channel:a.channel,thread:a.thread,subthread:a.subthread,message:a.message,context:a.context},id:await g(0)},d={...l,...i.noSync?{noSync:!0}:{}};if(m!==void 0)return await O(a.author,m),x(await b({...d,re:m}));let f=await u.fetchRoot(_(a.thread));if(f===null){let e=w({text:a.text,labels:{},author:a.author,raw:o});return x(await b({...l,channel:r,text:L(B(i.text??e.text,s),t.length>0),labels:S(e.labels)}))}let h=w({...f,raw:f.raw??null}),v=await b({author:f.author,channel:r,text:L(h.text),labels:S(h.labels),origin:{channel:a.channel,thread:a.thread,subthread:null,message:`root:${n.id}`,context:null},id:await g(1)});return x(await b({...d,re:v.id}))}case`edited`:case`deleted`:case`reaction`:{let t=(await D({thread:a.subthread??a.thread,message:a.message})).message;if(t===null)return{root:m??null,message:null};let n=`author`in a?a.author:{id:`${u.platform}:system`,handle:u.platform,name:u.platform,avatar:null,isBot:!0},r={thread:a.subthread??a.thread,message:a.message};if(m!==void 0&&await O(n,m),a.kind===`deleted`)await l(`syncImport`,{op:`delete`,author:n,from:e,origin:r});else if(a.kind===`edited`){let o=await T(t),s=L(B(i.text??a.text,o?ue(o.text):[]),(o?.attachments.length??0)>0);o&&!a.linksOnly&&o.text!==s&&await y(await l(`syncImport`,{op:`edit`,author:n,from:e,origin:r,text:s,source:v}));let c=o?await ye(u,a.links??[],o.channel,o.links):[];o&&!de(c,o.links)&&await l(`syncImport`,{op:`links`,author:n,from:e,origin:r,links:c})}else{if(u.singleReaction){let i=h(a.emoji);for(let[o,s]of Object.entries((await T(t))?.reactions??{}))s.includes(n.id)&&!(a.added&&o===i)&&await l(`syncImport`,{op:`react`,author:n,from:e,origin:r,emoji:o,remove:!0})}(!u.singleReaction||a.added)&&await l(`syncImport`,{op:`react`,author:n,from:e,origin:r,emoji:a.emoji,remove:!a.added})}return{root:m??null,message:t}}case`lifecycle`:{if(m!==void 0){let t=await T(m),r=t?.origin?.message===`lifecycle:${n.id}`,s=S((r?w({text:a.url?`${a.title}\n${a.url}`:a.title,labels:a.labels,author:a.author,raw:o}):null)?.labels??a.labels),c=e=>a.owns?.some(t=>e.startsWith(t))??!1,u=Object.fromEntries(Object.entries(s).filter(([e,n])=>t?.labels[e]!==n)),d=Object.keys(t?.labels??{}).filter(e=>!(e in s)&&(a.unset.includes(e)||i.unset?.includes(e)||c(e)));if(t&&!t.deleted&&(Object.keys(u).length||d.length)&&await E(a.author,u,d),a.retitled&&t&&!t.deleted&&t.from===e&&t.origin?.thread===a.thread){let n=L(i.text??w({text:a.url?`${a.title}\n${a.url}`:a.title,labels:t.labels,author:a.author,raw:o}).text);t.text!==n&&await y(await l(`syncImport`,{op:`edit`,author:a.author,from:e,origin:{thread:t.origin.thread,message:t.origin.message},text:n}))}return a.reply?x(await b({author:a.author,re:m,text:L(i.text??a.reply),...i.noSync?{noSync:!0}:{},id:await g(1)})):{root:m,message:r?m:null}}if(!a.createRoot)return{root:null,message:null};let t=w({text:a.url?`${a.title}\n${a.url}`:a.title,labels:a.labels,author:a.author,raw:o}),s=await b({author:a.author,channel:r,text:L(a.reply?t.text:i.text??t.text),labels:S(t.labels),origin:{channel:a.channel,thread:a.thread,subthread:null,message:`lifecycle:${n.id}`,context:null},id:await g(0)});return a.reply?x(await b({author:a.author,re:s.id,text:L(i.text??a.reply),...i.noSync?{noSync:!0}:{},id:await g(1)})):x(s)}}}function je(e,t,n,r=t.text){let i=t.mentions.map(e=>n.byId[e]).filter(e=>e!==void 0);return v(r,(t,r)=>{let a=t.kind===`actor`?i.find(e=>e.id===t.actor):i.find(e=>e.handle.toLowerCase()===t.handle);return a?K(e,a.id,n)??a.name:null})}function K(e,t,n){let r=t=>{let r=n.byId[t];return r?e.mention(r):null},i=n.links[t]??t,a=r(t)??(i===t?null:r(i));if(a)return a;for(let e of ne(n,i)){let t=r(e);if(t)return t}return null}async function Me(e,t,n){if(!e.users||t.from!==null||t.by.profile!==null||!t.by.principal.startsWith(`vercel:user:`))return null;if(n){let{accounts:n}=await D({person:t.by.principal});if(!n.some(t=>t.method===`consent`&&t.id.startsWith(`${e.platform}:user:`)))return null}try{return await e.users.token(t.by.principal)}catch(n){return console.warn(`[board] no ${e.platform} token for ${t.by.principal}; posting #${t.id} as the app:`,W(n)),null}}function Ne(e,t,n){let r=f(p(e)),i=je(r,t,n,M(t.text,t.by.actor));return{markdown:t.attachments.length>0&&!r.uploadsFiles?`${i}\n${Le(t)}`:i}}async function Pe(e,t,n,r,i){let a=f(p(e));if(!r.text.trim())return null;let o=await Me(a,r,!0);if(!o)return null;try{return await a.postAs(o,_(t),n,Ne(e,r,i))}catch(t){return console.warn(`[board] couldn't post #${r.id} to ${e} as its author; posting as the app:`,W(t)),null}}function Fe(t,n,r,i,a){let o=i.byId[r.by.actor],c=o?.name??r.by.actor;r.by.profile&&o?.handle.includes(`/`)&&(c=`${o.name} via ${o.handle.split(`/`)[0]}`),r.from&&(c=`${c} (${e[r.from]?.platform??r.by.actor.slice(0,r.by.actor.indexOf(`:`))})`);let l=f(t),u=(a??(e=>l.render(e)))(P({message:{...structuredClone(r),text:M(r.text,r.by.actor)},author:o?{...o}:null,mentionOf:e=>K(l,e,i),label:c,target:n}));if(typeof u!=`string`)throw s(`a provider renderer must return markdown`);let d=je(l,r,i,u);return r.by.profile&&!r.from?{markdown:d,as:{name:c,avatar:Ie(r,o,i)}}:{markdown:d}}function Ie(e,t,n){let r=e=>!e||/\/avatars\/[a-z0-9-]+$/.test(e),i=t?.avatar??null;if(!r(i))return i;let a=n.byId[e.by.principal]?.avatar;if(!r(a))return a;let o=t?.handle.split(`/`)[0]??``;return!e.by.principal.startsWith(`vercel:user:`)||!o||/^user-/.test(o)?i:`https://vercel.com/api/www/avatar?u=${encodeURIComponent(o)}&s=64&format=png`}let Le=e=>e.attachments.map(n=>`\n📎 ${n.name} (${t(n.size)}, on the board: #${e.id})`).join(``),q=(e,t,n,r=!1,i)=>{let a=p(e),{markdown:o,as:s}=Fe(a,e,t,n,i);return{markdown:t.attachments.length>0&&(r||!f(a).uploadsFiles)?`${o}\n${Le(t)}`:o,...s?{as:s}:{}}};async function Re(e,t,n,r,i){let a=e.replyTo===null?void 0:(await E([e.replyTo]))[e.replyTo]?.[t],o=a!==void 0&&a.thread!==n?a.thread:n,c=f(p(t)),l=q(t,e,r,!1,i),u,d;if(!l.markdown.trim()&&e.attachments.length&&c.uploadsFiles)try{let n=await Be(e,t,o);d=n.message,u=n.files}catch(n){if(!c.refusesFiles(n)&&!z(n))throw n;l=q(t,e,r,!0,i),d=(await c.post(_(o),`thread`,l)).message,u=null}else{let n=await Pe(t,o,`thread`,e,r);if(n){let r={thread:o,message:n.message,asUser:!0};return await J(e,t,r),r}if(!l.markdown.trim())throw s(`a renderer must return text unless the message has media`);d=(await c.post(_(o),`thread`,l)).message}let m={thread:o,message:d,...u===void 0?{}:{files:u}};return await J(e,t,m),m}async function J(e,t,n){await l(`syncReceipt`,{kind:`message`,message:e.id,target:t,external:{thread:n.thread,message:n.message,...n.asUser?{asUser:!0}:{}},...n.files===void 0?{}:{files:n.files}})}async function ze(e){return Promise.all(e.attachments.map(async e=>{let{data:t}=await l(`attachment`,{id:e.id});return{data:t instanceof Uint8Array?t:new Uint8Array(await new Response(t).arrayBuffer()),filename:e.name,mimeType:e.type}}))}async function Be(e,t,n){return f(p(t)).uploadFiles(_(n),await ze(e))}async function Y(e,t,n,r,i){let a=f(p(t));if(!a.uploadsFiles||e.attachments.length===0||n.files!==void 0)return;let o;try{o=(await Be(e,t,n.thread)).files}catch(s){if(!a.refusesFiles(s)&&!z(s))throw Object.assign(/* @__PURE__ */ Error(`files: ${W(s)}`),{cause:s,data:{error:`files: ${W(s)}`}});console.warn(`[board] ${t} won't take #${e.id}'s files (${W(s)}); noting them in its text`),o=null,await a.edit(_(n.thread),n.message,q(t,e,r,!0,i)).catch(n=>console.warn(`[board] couldn't note #${e.id}'s files on ${t}:`,W(n)))}await l(`syncReceipt`,{kind:`files`,message:e.id,target:t,files:o})}let X=(e,t,n,r)=>{e.some(e=>e.error===r)||e.push({id:t,target:n,error:r})};async function Z(e,t){if(t.length!==0){if(e<5||ie(e))throw t[0].error;for(let{id:e,target:n,error:r}of t)console.error(`[board] gave up ${n===null?`syncing #${e}`:`delivering #${e} to ${n}`}:`,W(r)),n!==null&&await l(`syncReceipt`,{kind:`failed`,message:e,target:n,error:W(r)})}}async function Q(e,t,n,r,i){let a,o=!0,c=()=>s(`the sync function has finished`),l={direction:`out`,key:e,channel:r===null?null:j(e,r),event:P(structuredClone(t)),message:P(structuredClone(n)),target:r,deliver(e={}){if(!o)throw c();return a??=r===null?Promise.resolve():i(e.render),a},start(t){if(!o)throw c();return Ve(e,n,t)},resolve:t=>A(e,t)};try{await f(e).sync(l),await a}finally{o=!1}}async function Ve(e,t,n){let{target:r,kind:i}=await I(`${e}:${n}`),a=t.re===null?t:await T(t.re);!a||a.deleted||a.noSync||r!==(a.origin?a.origin.channel??S(a.origin.thread):null)&&await l(`syncReceipt`,{kind:`thread`,message:a.id,target:r,targetKind:i,cause:`config`})}async function He(t,n){let r=Object.keys(e).filter(t=>e[t].canStartThreads);if(t.payload.noSync||r.length===0)return;let i=await T(t.message.id);if(!i||i.deleted)return;let a=[];for(let e of r)try{await Q(e,t,i,null,async()=>{})}catch(e){X(a,i.id,null,e)}await Z(n,a)}async function Ue(e,t){let{thread:n,target:r}=e.payload;if(!g(r)||(e.payload.kind??(d(r)?`thread`:`channel`))===`thread`)return;let i=await C(n),[a,...o]=i?await w(i.root):[];if(!i||!a||a.id!==i.root||a.deleted)return;let s=[];try{await Q(p(r),e,a,r,e=>We(i,a,o,r,s,e))}catch(e){X(s,a.id,r,e)}await Z(t,s)}async function We(e,t,n,r,i,a){let o=await O(),c=await E([t.id,...n.map(e=>e.id)]),l=e=>(i.push({id:t.id,target:r,error:e}),e),u=e.external[r];if(u){let e=c[t.id]?.[r];if(e)try{await Y(t,r,e,o,a)}catch(e){throw l(e)}}else try{let e=f(p(r)),n=q(r,t,o,!1,a),i=!n.markdown.trim()&&t.attachments.length>0&&e.uploadsFiles;if(!n.markdown.trim()&&!i)throw s(`a renderer must return text unless the message has media`);let c,l=!1,d=await(async()=>{if(!i){let i=await Pe(r,r,`channel`,t,o);return i?(l=!0,i):e.post(_(r),`channel`,n)}try{let i=await e.post(_(r),`channel`,{...n,files:await ze(t)});return c=i.files??[],i}catch(n){if(!e.refusesFiles(n)&&!z(n))throw n;return c=null,e.post(_(r),`channel`,q(r,t,o,!0,a))}})();u=`${p(r)}:${d.thread}`;let m={thread:u,message:d.message,...c===void 0?{}:{files:c},...l?{asUser:!0}:{}};await J(t,r,m),await Y(t,r,m,o,a)}catch(e){throw l(e)}let d=[];for(let e of n)if(!(e.deleted||e.noSync||Ge(e,r)))try{await Y(e,r,c[e.id]?.[r]??await Re(e,r,u,o,a),o,a)}catch(t){d.push({id:e.id,target:r,error:t})}if(i.push(...d),d.length)throw d[0].error}let Ge=(e,t)=>e.origin?.thread===t||e.from!==null&&p(t)===e.from;async function Ke(e,t){if(!e.message)return;if(e.message.re===null)return He(e,t);if(e.payload.noSync)return;let n=await C(e.payload.thread);if(!n||n.targets.length===0)return;let r=await T(e.message.id);if(!r||r.deleted)return;let i=await O(),a=[];for(let t of n.targets){let o=n.external[t];if(g(t)&&o&&!Ge(r,t))try{await Q(p(t),e,r,t,async e=>{let n=(await E([r.id]))[r.id]?.[t]??await Re(r,t,o,i,e);await Y(r,t,n,i,e)})}catch(e){X(a,r.id,t,e)}}await Z(t,a)}async function qe(e){let t=(await E([e.payload.id]))[e.payload.id]??{};if(Object.keys(t).length===0)return;let n=e.type===`message.edited`?await T(e.payload.id):e.message??await T(e.payload.id);if(!n||e.type===`message.edited`&&n.deleted)return;let r=await O();for(let[i,a]of Object.entries(t))if(!(!g(i)||e.payload.from!==null&&p(i)===e.payload.from))try{await Q(p(i),e,n,i,async t=>{let o=f(p(i)),s=_(a.thread),c=a.asUser&&(e.type===`message.edited`||e.type===`message.deleted`),l=c?await Me(o,n,!1):null;if(c&&!l){console.warn(`[board] skipped ${e.type} on ${i}: #${n.id} was posted as its author, and their token is gone`);return}e.type===`message.edited`?l?await o.editAs(l,s,a.message,Ne(i,n,r)):await o.edit(s,a.message,q(i,n,r,a.files===null,t)):e.type===`message.deleted`?(l?await o.deleteAs(l,s,a.message):await o.delete(s,a.message),a.files?.length&&await o.deleteFiles(a.files)):e.type===`reaction.added`?await o.react(s,a.message,h(e.payload.emoji),!0):await o.react(s,a.message,h(e.payload.emoji),!1)})}catch(t){console.warn(`[board] skipped ${e.type} on ${i}:`,t.message)}}async function Je(e){let{id:t}=e.payload,n=(await E([t]))[t]??{},r=e.message;if(!r||Object.keys(n).length===0)return;let i=await T(t);if(!i||i.deleted)return;let a=await O(),o={...i,labels:r.labels},s={...i,labels:e.before?.labels??{}};for(let[t,r]of Object.entries(n))if(g(t))try{await Q(p(t),e,o,t,async e=>{let n=q(t,o,a,r.files===null,e);n.markdown!==q(t,s,a,r.files===null,e).markdown&&await f(p(t)).edit(_(r.thread),r.message,n)})}catch(e){console.warn(`[board] skipped labels.changed on ${t}:`,W(e))}}async function Ye(e,{attempt:t}){switch(e.type){case`thread.synced`:return Ue(e,t);case`message.posted`:return Ke(e,t);case`message.edited`:case`message.deleted`:case`reaction.added`:case`reaction.removed`:return qe(e);case`labels.changed`:return Je(e)}}async function Xe(e,t){let n=e[0]?await C(e[0].thread):null;if(!n)return[];let r=[...new Set(Object.values(n.external))].filter(g);return(await Promise.all(r.map(async n=>{let r=p(n);try{let i=f(r),a=null;for(let t=e.length-1;t>=0&&a===null;t--){let r=e[t];!r.deleted&&r.origin?.thread===n&&(a=r.origin.message)}return await i.startTyping(_(n),a,t),n}catch(e){return console.warn(`[board] skipped typing on ${n}:`,W(e)),null}}))).filter(e=>e!==null)}async function Ze(e,t){try{return`${e}:${await f(e).resolveChannel(t)}`}catch(e){throw s(`can't resolve inbox channel: ${e.message}`)}}let $=e=>e===`unsupported`||e===`invalid_target`?400:e===`channel_not_found`?404:e===`ratelimited`?429:[`no_client`,`list_failed`,`internal_error`,`fatal_error`,`service_unavailable`,`request_timeout`].includes(e)?502:403;async function Qe(e,t,n){let r=f(e);try{return await r.read(t,{limit:n})}catch(n){throw n instanceof F?new m($(n.code),n.code,n.message):s(`can't read ${t} from ${e}: ${W(n)}`,`platform_error`)}}async function $e(e,t){let n=f(e);try{return await n.join(t)}catch(n){throw n instanceof F?new m($(n.code),n.code,n.message):s(`can't join ${t} on ${e}: ${W(n)}`,`platform_error`)}}return{entries:e,bind(e){i=e},caller:c,deliver:Ye,receive:xe,pull:_e,normalizeTarget:I,findByEmail:re,handleWebhook:ge,inboxChannel:Ze,signsIn:Ee,signIn:De,signedIn:Oe,redeemSignIn:ke,typing:Xe,readSource:Qe,joinSource:$e}}export{he as createSyncEngine};
|
|
1
|
+
import{C as e,D as t,E as n,O as r,S as i,T as a,_ as o,a as s,b as c,c as l,d as u,f as d,g as f,h as p,i as m,k as h,l as g,m as _,n as v,o as y,p as b,r as x,s as ee,t as te,u as S,v as C,w,x as T,y as E}from"./app.js";const D=/^\[vc\]: #\S*\r?\n/,O=/\[([^\]]+)\]\((https?:\/\/[^)\s]+)\)/g,k=/!\[([^\]]+)\]\(https:\/\/vercel\.com\/static\/status\/[^)]+\)\s*(?:\[[^\]]*\]\((https?:\/\/[^)\s]+)\))?/;function A(e){if(!D.test(e))return null;let t=e.search(/<details><summary>\d+ Skipped Deployments?<\/summary>/),n=[],r=0;for(let i of e.split(/\r?\n/)){let a=r;if(r=e.indexOf(`
|
|
2
|
+
`,r)+1||e.length,!i.startsWith(`|`)||/^\|\s*(Project|Name)\s*\|/.test(i)||/^\|\s*:?-/.test(i))continue;let o=i.split(`|`).slice(1,-1).map(e=>e.trim());if(o.length<2)continue;let s=k.exec(o[1]);if(!s)continue;let c=[...o[0].matchAll(O)].at(-1),l=c?.[1]??o[0].replace(/<[^>]*>/g,``).trim();if(!l)continue;let u=o[2]?[...o[2].matchAll(O)].find(e=>/preview/i.test(e[1])):void 0,d=o[3]?.match(/<relative-time[^>]*>([^<]+)<\/relative-time>/)?.[1]?.trim()??(o[3]?.replace(/<[^>]*>/g,``).trim()||null);n.push({project:l,projectUrl:c?.[2]??null,status:s[1].trim(),deploymentUrl:s[2]??null,previewUrl:u?.[2]??null,updated:d,skipped:t!==-1&&a>t})}return n.length>0?n:null}const j={ready:`✅`,building:`⏳`,queued:`⏳`,initializing:`⏳`,error:`❌`,failed:`❌`,canceled:`⚪`,ignored:`⚪`},M=(e,t)=>t?`[${e}](${t})`:e;function N(e){return e.map(e=>`- ${[`${j[e.status.toLowerCase()]??`▲`} **${M(e.project,e.projectUrl)}**`,`${M(e.status,e.deploymentUrl)}${e.skipped?` (skipped)`:``}`,...e.previewUrl?[M(`Preview`,e.previewUrl)]:[],...e.updated?[e.updated]:[]].join(` · `)}`).join(`
|
|
3
|
+
`)}function ne(e,t){let n=t===`github:user:35613825`?A(e):null;return n?`**▲ Vercel**\n${N(n)}`:e}const re=e=>e>10;i({id:e().min(1),platform:e().min(1),key:e().min(1),...g.shape,raw:w()});const ie=i({root:T(e=>typeof e==`function`).optional(),text:e().optional(),labels:p.optional(),unset:E(_).optional(),noSync:c().optional()}).strict();function P(e){if(e&&typeof e==`object`){for(let t of Object.values(e))P(t);Object.freeze(e)}return e}const ae=i({target:e().min(1),channel:e().min(1),kind:C([`channel`,`thread`])}).strict();var F=class extends Error{code;constructor(e,t){super(t),this.code=e}};const oe=e=>e instanceof F&&e.code===`channel_not_found`,se=i({event:l,raw:w(),dedupe:e().min(1)}),I=/* @__PURE__ */ new WeakMap,ce=e=>I.get(e),L=(e,t=!1)=>{let n=o(e),r=n.trim()===``?t?``:`(no text)`:n;return r.length>1e4?`${r.slice(0,f-1).toWellFormed()}…`:r},R=(e,n,r=e.name??`a file`)=>`📎 ${r}${e.size===void 0?``:` (${t(e.size)})`} didn't come over: ${n}`,z=e=>e instanceof m&&e.code===`no_files`,B=e=>{let t=e.name??`a file`;if(!e.url||!/^https?:\/\//.test(e.url))return R(e,`this board keeps no files`);let n=t.replace(/[[\]\\]/g,e=>`\\${e}`),r=e.url.replace(/[ ()]/g,e=>`%${e.charCodeAt(0).toString(16).toUpperCase()}`);return R(e,`this board keeps no files`,`[${n}](${r})`)},V=(e,t)=>t.length?`${e.trim()?`${e}\n\n`:``}${t.join(`
|
|
4
|
+
`)}`:e,le=e=>e.split(`
|
|
5
|
+
`).filter(e=>/^📎 .* didn't come over: /u.test(e)),H=e=>JSON.stringify([e.url,e.message,e.snapshot,e.unavailable]),ue=(e,t)=>e.length===t.length&&e.every((e,n)=>H(e)===H(t[n])),de=/^\s*`?(vb-[a-z0-9]{4}-[a-z0-9]{4})`?\s*$/i,fe=6e4,pe=new AbortController().signal,me=e=>{try{return JSON.parse(JSON.stringify(e??null))}catch{return null}},U=e=>typeof e==`string`?o(e):Array.isArray(e)?e.map(U):typeof e==`object`&&e?Object.fromEntries(Object.entries(e).map(([e,t])=>[o(e),U(t)])):e,W=e=>{let t=e?.data?.error,n=typeof t==`string`?t:e instanceof Error?e.message:String(e);return o(n.slice(0,500))||`unknown error`},G=e=>e instanceof m&&e.status===404;function he(e){let i=null,o=()=>{if(!i)throw Error(`sync used before board() bound it`);return i},c={self:`sync`,origin:{via:{kind:`engine`}}};function l(e,t,n=pe,r=c){let i=o().backend;return i[e].call(i,r,t,n)}let f=t=>{let n=e[t];if(!n)throw s(`no sync entry named ${t}`);return n},p=e=>e.slice(0,e.indexOf(`:`)),g=t=>e[p(t)]!==void 0,_=e=>e.slice(e.indexOf(`:`)+1);async function C(e){try{return await l(`syncThread`,{thread:e})}catch(e){if(G(e))return null;throw e}}async function w(e){try{let{message:t,replies:n}=await l(`message`,{id:e});return[t,...n]}catch(e){if(G(e))return[];throw e}}async function T(e){return(await w(e)).find(t=>t.id===e)??null}async function E(e){return e.length===0?{}:(await l(`syncCopies`,{message:[...new Set(e)]})).copies}let D=(e,t)=>l(`syncFind`,e,t);async function O(){let{actors:e}=await l(`actors`,{}),t={byId:{},links:{}};for(let{person:n,...r}of e)t.byId[r.id]={id:r.id,kind:r.kind,handle:r.handle,name:r.name,avatar:r.avatar},n&&(t.links[r.id]=n.id);return t}let k=(e,t)=>Object.entries(e.links).filter(([,e])=>e===t).map(([e])=>e),A=/* @__PURE__ */ new Map;function j(e,t){let n=`${e}:${t}`,r=A.get(n);if(r&&(!r.failed||Date.now()-r.at<6e4))return r.id;let i={id:f(e).resolveChannel(t),failed:!1,at:Date.now()};return i.id.catch(r=>{i.failed=!0;let a=oe(r);!a&&A.get(n)===i&&A.delete(n),console.warn(`[board] sync ${e}: ${a?`skipping`:`couldn't resolve`} ${t}: ${r.message}`)}),A.set(n,i),i.id}function M(e,t){if(!d(t))return _(t);try{let n=f(e).inboxChannel(e,t);return n===null?null:_(n)}catch{return null}}async function N(t){for(let n of Object.values(e)){let e=await n.findByEmail(t).catch(()=>null);if(e)return{id:e.id,kind:`external`,handle:e.handle,name:e.name,avatar:e.avatar}}return null}async function I(e){let t=e.indexOf(`:`);if(t<=0)throw s(`sync targets look like <key>:<channel or thread>, got: ${e}`);let n=e.slice(0,t),r=f(n);try{let i=ae.parse(await r.resolveTarget(e.slice(t+1)));if(i.kind===`channel`&&!r.canStartThreads)throw Error(`${r.platform} cannot start threads; use an existing thread`);return{target:`${n}:${i.target}`,kind:i.kind}}catch(t){throw s(`can't sync to ${e}: ${t.message}`)}}async function H(e,t){let{event:n,raw:r,dedupe:i}=se.parse(U({...t,raw:me(t.raw)}));for(let t of[n.channel,n.thread,`subthread`in n?n.subthread:null])if(t!==null&&!t.startsWith(`${e}:`))throw s(`provider locations must belong to sync entry ${e}`);let a=ce(f(e));(!a||await a(_(n.channel),t=>j(e,t))||await he(n.thread))&&await l(`inboxPush`,{key:e,events:[{id:i,event:n,raw:r}]})}async function he(e){try{return(await D({thread:e},AbortSignal.timeout(2e3))).thread!==null}catch(e){let t=e?.name;if(t===`TimeoutError`||t===`AbortError`)return!0;throw e}}async function ge(t,n){let r=e[t];if(!r)throw y(`no sync entry named ${t}`);let i;try{i=await r.receive(t,n,e=>H(t,e))}catch(e){return console.error(`[board] intake failed`,e),new Response(`intake failed`,{status:500})}let a=_e([t]).catch(e=>console.error(`[board] couldn't pull ${t}'s inbox:`,W(e)));return x(a),i}async function _e(t=Object.keys(e)){let n=0,r=Date.now()+24e4;for(let e of t)for(;Date.now()<r;){let{items:t}=await l(`inboxNext`,{key:e,limit:10});if(t.length===0)break;await Promise.all(t.map(t=>ve(e,t))),n+=t.length}return n}async function ve(e,t){let n;try{await xe(e,{event:t.event,raw:t.raw},{id:t.id,attempt:t.attempt+1})}catch(r){console.error(`[board] sync ${e} couldn't import ${t.id}:`,W(r)),n=W(r)}await l(`inboxAck`,{key:e,id:t.id,lease:t.lease,...n===void 0?{}:{error:n}}).catch(e=>console.error(`[board] couldn't ack an inbox event:`,W(e)))}async function ye(e,t,n,r=[]){if(t.length===0)return[];let i=[];for(let a of t){if(i.some(e=>e.url===a.url))continue;let t=(await D({thread:a.thread,message:a.message})).message,o=t===null?null:await T(t);if(o&&!o.deleted&&o.channel===n){i.push({url:a.url,message:o.id,unavailable:null,snapshot:{author:o.author?.name??o.by.actor,text:o.text,createdAt:o.createdAt,files:o.attachments.map(e=>({name:e.name,url:null}))}});continue}if(a.snapshot){i.push({url:a.url,message:null,snapshot:a.snapshot,unavailable:null});continue}let s=r.find(e=>e.url===a.url&&e.snapshot&&e.message===null);if(s){i.push(s);continue}let c=await e.fetchLink(a).catch(e=>({snapshot:null,unavailable:W(e)}));i.push({url:a.url,message:null,snapshot:c.snapshot,unavailable:c.snapshot?null:(c.unavailable??`unknown`).slice(0,300)})}return U(i)}async function be(e,t,i){let o=[],s=[],c=!1;for(let u of t.slice(0,10)){if(c){s.push(B(u));continue}if(u.size!==void 0&&u.size>26214400){s.push(R(u,`over ${n/1024/1024} MB`));continue}let t;try{let n=await e.fetchFile(u);if(n===null){s.push(R(u,`${e.platform} can't hand it over`));continue}t=n}catch(t){if(i<3)throw t;console.warn(`[board] couldn't fetch ${u.name??`a file`} from ${e.platform}:`,W(t)),s.push(R(u,`${e.platform} wouldn't hand it over`));continue}if(t.byteLength>26214400){s.push(R(u,`over ${n/1024/1024} MB`));continue}if(t.byteLength===0){s.push(R(u,`it was empty`));continue}let d=u.name??`${u.type}`;try{o.push((await l(`upload`,{data:t,name:d,type:u.mimeType||r(d)})).attachment)}catch(e){if(e instanceof m&&(e.code===`too_large`||e.code===`no_direct_uploads`)){s.push(R(u,`over ${a/1024/1024} MB`));continue}if(!z(e))throw e;c=!0,s.push(B(u))}}for(let e of t.slice(10))s.push(R(e,`a message carries at most 10`));return{attachments:o,notes:s}}async function xe(e,t,n){let{event:r,raw:i}=t,a=f(e),c=(await D({thread:r.thread})).thread??void 0;if(r.kind===`message`){let t=(await D({thread:r.subthread??r.thread,message:r.message})).message;if(t!==null){let e=(await T(t))?.origin;if(!e||e.message!==r.message||(e.subthread??e.thread)!==(r.subthread??r.thread))return}else if(a.users&&n.attempt<6&&await we(c,r))throw Error(`holding ${r.message} until ${r.author.id}'s board message there has its receipt`);let i=r.author.isBot?void 0:de.exec(r.text)?.[1];if(i&&await Te(e,r,i))return}let l=`author`in r?r.author:{id:`${a.platform}:system`,handle:a.platform,name:a.platform,avatar:null,isBot:!0},u,d=()=>u??=P(a.event({id:n.id,key:e,event:r,raw:i})),p,m,h=!0,g={direction:`in`,key:e,channel:_(r.channel),get event(){return d()},board:o().client({author:l,key:e,...Ce(e,r)},n.id),import(r,i={}){if(!h)throw s(`the sync function has finished`);return p??=Se(e,t,n,c,r,i),p},permalink(){let e=m??a.permalink(d());return m=e,e.catch(()=>{m===e&&(m=void 0)}),e},resolve:t=>j(e,t)};try{await a.sync(g),await p}finally{h=!1}}async function Se(e,t,n,r,i,a){let o=i??(r?(await C(r))?.channel:void 0);if(o===void 0)return{root:null,message:null};try{return await Ae(e,t,n,b.parse(o),ie.parse(a))}catch(e){if(!(e instanceof te))throw e;let n=(await D({thread:t.event.thread})).thread;return{root:n===null?null:(await C(n))?.root??null,message:null}}}function Ce(e,t){let n=f(e),r=(`subthread`in t?t.subthread:null)??t.thread;return{via:{kind:`sync`,key:e,platform:n.platform,channel:t.channel,thread:r},respond:async e=>{await n.post(_(r),`thread`,{markdown:e})}}}async function we(e,t){let n=(await D({account:t.author.id})).person;if(!n||n.method!==`consent`)return!1;let r=Date.now(),i=(e,t,i)=>e.by.principal===n.id&&e.by.profile===null&&e.from===null&&!e.deleted&&!e.noSync&&r-Date.parse(e.createdAt)<fe&&!i[t]&&!e.undelivered[t];if(e!==void 0){let n=await C(e);if(!n)return!1;let r=n.targets.filter(e=>n.external[e]===t.thread),a=await w(n.root),o=await E(a.map(e=>e.id));return a.some(e=>r.some(t=>i(e,t,o[e.id]??{})))}let{roots:a}=await l(`syncRoots`,{by:n.id,since:r-fe}),o=await E(a.map(e=>e.id));for(let e of a){let n=await C(e.thread);if(n?.targets.includes(t.channel)&&!n.external[t.channel]&&i(e,t.channel,o[e.id]??{}))return!0}return!1}async function Te(e,t,n){try{await l(`syncAccount`,{sync:e,account:t.author,code:n,message:u(t.subthread??t.thread,t.message)})}catch(e){if(G(e))return!1;throw e}return await f(e).react(_(t.subthread??t.thread),t.message,`check`,!0).catch(t=>console.warn(`[board] couldn't confirm a linking code on ${e}:`,W(t))),!0}let Ee=e=>f(e).users!==null;async function De(e,t,n){let r=f(e);if(!r.users)throw s(`${e} can't sign people in: link it with a code`);return r.users.authorize(t,n?{callback:n}:{})}async function Oe(e,t){let n=f(e);if(!n.users)throw s(`${e} can't sign people in: link it with a code`);let r=await n.users.token(t);if(!r)return null;let i=await n.whoAmI(r);if(!i.id.startsWith(`${n.platform}:user:`))throw s(`${e} named an account that isn't a ${n.platform} user`);return i}async function ke(e,t,n){let r=await Oe(e,t);return r?(await l(`syncAccount`,{sync:e,account:r,code:n,method:`consent`})).link:null}async function Ae(e,t,n,r,i){let{event:a,raw:o}=t,c=Ce(e,a),u=f(e),d=(await D({thread:a.thread})).thread??void 0,p=d?await C(d):null,m=p?.root,g=e=>ee(`board-inbound`,n.id,String(e)),v={key:e,channel:c.via.channel,thread:c.via.thread},y=async e=>{if(!e.dropped)return e.message;for(let t of e.dropped)await c.respond(t);throw new te(e.dropped)},b=async({attachments:t=[],...n})=>({id:await y(await l(`syncImport`,{op:`post`,from:e,source:v,...n,origin:n.origin??null,...t.length?{attachments:t.map(e=>e.id)}:{}})),re:n.re??null}),x=e=>({root:e.re??e.id,message:e.id}),S=(e={})=>{let t={...e,...i.labels};for(let e of i.unset??[])delete t[e];return t},w=e=>{if(!i.root)return e;let t=i.root(P(structuredClone(e)));if(t&&typeof t==`object`&&`then`in t)throw s(`root overrides must be synchronous`);let n=ie.pick({text:!0,labels:!0}).parse(t);return{...e,text:n.text??e.text,labels:{...e.labels,...n.labels}}},E=(t,n,r)=>l(`syncImport`,{op:`labels`,author:t,from:e,origin:{thread:a.thread},set:n,unset:r}),O=async(e,t)=>{if(!i.labels&&!i.unset)return;let n=await T(t),r=Object.fromEntries(Object.entries(i.labels??{}).filter(([e,t])=>n?.labels[e]!==t)),a=(i.unset??[]).filter(e=>n?.labels[e]!==void 0);(Object.keys(r).length||a.length)&&await E(e,r,a)};switch(a.kind){case`message`:{let e=(await D({thread:a.subthread??a.thread,message:a.message})).message;if(e!==null)return{root:m??e,message:e};let{attachments:t,notes:s}=a.files?.length?await be(u,a.files,n.attempt):{attachments:[],notes:[]},c=await ye(u,a.links??[],p?.channel??r),l={...c.length?{links:c}:{},author:a.author,text:L(V(i.text??a.text,s),t.length>0),...t.length?{attachments:t}:{},origin:{channel:a.channel,thread:a.thread,subthread:a.subthread,message:a.message,context:a.context},id:await g(0)},d={...l,...i.noSync?{noSync:!0}:{}};if(m!==void 0)return await O(a.author,m),x(await b({...d,re:m}));let f=await u.fetchRoot(_(a.thread));if(f===null){let e=w({text:a.text,labels:{},author:a.author,raw:o});return x(await b({...l,channel:r,text:L(V(i.text??e.text,s),t.length>0),labels:S(e.labels)}))}let h=w({...f,raw:f.raw??null}),v=await b({author:f.author,channel:r,text:L(h.text),labels:S(h.labels),origin:{channel:a.channel,thread:a.thread,subthread:null,message:`root:${n.id}`,context:null},id:await g(1)});return x(await b({...d,re:v.id}))}case`edited`:case`deleted`:case`reaction`:{let t=(await D({thread:a.subthread??a.thread,message:a.message})).message;if(t===null)return{root:m??null,message:null};let n=`author`in a?a.author:{id:`${u.platform}:system`,handle:u.platform,name:u.platform,avatar:null,isBot:!0},r={thread:a.subthread??a.thread,message:a.message};if(m!==void 0&&await O(n,m),a.kind===`deleted`)await l(`syncImport`,{op:`delete`,author:n,from:e,origin:r});else if(a.kind===`edited`){let o=await T(t),s=L(V(i.text??a.text,o?le(o.text):[]),(o?.attachments.length??0)>0);o&&!a.linksOnly&&o.text!==s&&await y(await l(`syncImport`,{op:`edit`,author:n,from:e,origin:r,text:s,source:v}));let c=o?await ye(u,a.links??[],o.channel,o.links):[];o&&!ue(c,o.links)&&await l(`syncImport`,{op:`links`,author:n,from:e,origin:r,links:c})}else{if(u.singleReaction){let i=h(a.emoji);for(let[o,s]of Object.entries((await T(t))?.reactions??{}))s.includes(n.id)&&!(a.added&&o===i)&&await l(`syncImport`,{op:`react`,author:n,from:e,origin:r,emoji:o,remove:!0})}(!u.singleReaction||a.added)&&await l(`syncImport`,{op:`react`,author:n,from:e,origin:r,emoji:a.emoji,remove:!a.added})}return{root:m??null,message:t}}case`lifecycle`:{if(m!==void 0){let t=await T(m),r=t?.origin?.message===`lifecycle:${n.id}`,s=S((r?w({text:K(a),labels:a.labels,author:a.author,raw:o}):null)?.labels??a.labels),c=e=>a.owns?.some(t=>e.startsWith(t))??!1,u=Object.fromEntries(Object.entries(s).filter(([e,n])=>t?.labels[e]!==n)),d=Object.keys(t?.labels??{}).filter(e=>!(e in s)&&(a.unset.includes(e)||i.unset?.includes(e)||c(e)));if(t&&!t.deleted&&(Object.keys(u).length||d.length)&&await E(a.author,u,d),a.retitled&&t&&!t.deleted&&t.from===e&&t.origin?.thread===a.thread){let n=L(i.text??w({text:K(a),labels:t.labels,author:a.author,raw:o}).text);t.text!==n&&await y(await l(`syncImport`,{op:`edit`,author:a.author,from:e,origin:{thread:t.origin.thread,message:t.origin.message},text:n}))}return a.reply?x(await b({author:a.author,re:m,text:L(i.text??a.reply),...i.noSync?{noSync:!0}:{},id:await g(1)})):{root:m,message:r?m:null}}if(!a.createRoot)return{root:null,message:null};let t=w({text:K(a),labels:a.labels,author:a.author,raw:o}),s=await b({author:a.author,channel:r,text:L(a.reply?t.text:i.text??t.text),labels:S(t.labels),origin:{channel:a.channel,thread:a.thread,subthread:null,message:`lifecycle:${n.id}`,context:null},id:await g(0)});return a.reply?x(await b({author:a.author,re:s.id,text:L(i.text??a.reply),...i.noSync?{noSync:!0}:{},id:await g(1)})):x(s)}}}function je(e,t,n,r=t.text){let i=t.mentions.map(e=>n.byId[e]).filter(e=>e!==void 0);return v(r,(t,r)=>{let a=t.kind===`actor`?i.find(e=>e.id===t.actor):i.find(e=>e.handle.toLowerCase()===t.handle);return a?Me(e,a.id,n)??a.name:null})}function Me(e,t,n){let r=t=>{let r=n.byId[t];return r?e.mention(r):null},i=n.links[t]??t,a=r(t)??(i===t?null:r(i));if(a)return a;for(let e of k(n,i)){let t=r(e);if(t)return t}return null}async function Ne(e,t,n){if(!e.users||t.from!==null||t.by.profile!==null||!t.by.principal.startsWith(`vercel:user:`))return null;if(n){let{accounts:n}=await D({person:t.by.principal});if(!n.some(t=>t.method===`consent`&&t.id.startsWith(`${e.platform}:user:`)))return null}try{return await e.users.token(t.by.principal)}catch(n){return console.warn(`[board] no ${e.platform} token for ${t.by.principal}; posting #${t.id} as the app:`,W(n)),null}}function Pe(e,t,n){let r=f(p(e)),i=je(r,t,n,ne(t.text,t.by.actor));return{markdown:t.attachments.length>0&&!r.uploadsFiles?`${i}\n${Re(t)}`:i}}async function Fe(e,t,n,r,i){let a=f(p(e));if(!r.text.trim())return null;let o=await Ne(a,r,!0);if(!o)return null;try{return await a.postAs(o,_(t),n,Pe(e,r,i))}catch(t){return console.warn(`[board] couldn't post #${r.id} to ${e} as its author; posting as the app:`,W(t)),null}}function Ie(t,n,r,i,a){let o=i.byId[r.by.actor],c=o?.name??r.by.actor;r.by.profile&&o?.handle.includes(`/`)&&(c=`${o.name} via ${o.handle.split(`/`)[0]}`),r.from&&(c=`${c} (${e[r.from]?.platform??r.by.actor.slice(0,r.by.actor.indexOf(`:`))})`);let l=f(t),u=(a??(e=>l.render(e)))(P({message:{...structuredClone(r),text:ne(r.text,r.by.actor)},author:o?{...o}:null,mentionOf:e=>Me(l,e,i),label:c,target:n}));if(typeof u!=`string`)throw s(`a provider renderer must return markdown`);let d=je(l,r,i,u);return r.by.profile&&!r.from?{markdown:d,as:{name:c,avatar:Le(r,o,i)}}:{markdown:d}}function Le(e,t,n){let r=e=>!e||/\/avatars\/[a-z0-9-]+$/.test(e),i=t?.avatar??null;if(!r(i))return i;let a=n.byId[e.by.principal]?.avatar;if(!r(a))return a;let o=t?.handle.split(`/`)[0]??``;return!e.by.principal.startsWith(`vercel:user:`)||!o||/^user-/.test(o)?i:`https://vercel.com/api/www/avatar?u=${encodeURIComponent(o)}&s=64&format=png`}let Re=e=>e.attachments.map(n=>`\n📎 ${n.name} (${t(n.size)}, on the board: #${e.id})`).join(``),q=(e,t,n,r=!1,i)=>{let a=p(e),{markdown:o,as:s}=Ie(a,e,t,n,i);return{markdown:t.attachments.length>0&&(r||!f(a).uploadsFiles)?`${o}\n${Re(t)}`:o,...s?{as:s}:{}}};async function ze(e,t,n,r,i){let a=e.replyTo===null?void 0:(await E([e.replyTo]))[e.replyTo]?.[t],o=a!==void 0&&a.thread!==n?a.thread:n,c=f(p(t)),l=q(t,e,r,!1,i),u,d;if(!l.markdown.trim()&&e.attachments.length&&c.uploadsFiles)try{let n=await Ve(e,t,o);d=n.message,u=n.files}catch(n){if(!c.refusesFiles(n)&&!z(n))throw n;l=q(t,e,r,!0,i),d=(await c.post(_(o),`thread`,l)).message,u=null}else{let n=await Fe(t,o,`thread`,e,r);if(n){let r={thread:o,message:n.message,asUser:!0};return await J(e,t,r),r}if(!l.markdown.trim())throw s(`a renderer must return text unless the message has media`);d=(await c.post(_(o),`thread`,l)).message}let m={thread:o,message:d,...u===void 0?{}:{files:u}};return await J(e,t,m),m}async function J(e,t,n){await l(`syncReceipt`,{kind:`message`,message:e.id,target:t,external:{thread:n.thread,message:n.message,...n.asUser?{asUser:!0}:{}},...n.files===void 0?{}:{files:n.files}})}async function Be(e){return Promise.all(e.attachments.map(async e=>{let{data:t}=await l(`attachment`,{id:e.id});return{data:t instanceof Uint8Array?t:new Uint8Array(await new Response(t).arrayBuffer()),filename:e.name,mimeType:e.type}}))}async function Ve(e,t,n){return f(p(t)).uploadFiles(_(n),await Be(e))}async function Y(e,t,n,r,i){let a=f(p(t));if(!a.uploadsFiles||e.attachments.length===0||n.files!==void 0)return;let o;try{o=(await Ve(e,t,n.thread)).files}catch(s){if(!a.refusesFiles(s)&&!z(s))throw Object.assign(/* @__PURE__ */ Error(`files: ${W(s)}`),{cause:s,data:{error:`files: ${W(s)}`}});console.warn(`[board] ${t} won't take #${e.id}'s files (${W(s)}); noting them in its text`),o=null,await a.edit(_(n.thread),n.message,q(t,e,r,!0,i)).catch(n=>console.warn(`[board] couldn't note #${e.id}'s files on ${t}:`,W(n)))}await l(`syncReceipt`,{kind:`files`,message:e.id,target:t,files:o})}let X=(e,t,n,r)=>{e.some(e=>e.error===r)||e.push({id:t,target:n,error:r})};async function Z(e,t){if(t.length!==0){if(e<5||re(e))throw t[0].error;for(let{id:e,target:n,error:r}of t)console.error(`[board] gave up ${n===null?`syncing #${e}`:`delivering #${e} to ${n}`}:`,W(r)),n!==null&&await l(`syncReceipt`,{kind:`failed`,message:e,target:n,error:W(r)})}}async function Q(e,t,n,r,i){let a,o=!0,c=()=>s(`the sync function has finished`),l={direction:`out`,key:e,channel:r===null?null:M(e,r),event:P(structuredClone(t)),message:P(structuredClone(n)),target:r,deliver(e={}){if(!o)throw c();return a??=r===null?Promise.resolve():i(e.render),a},start(t){if(!o)throw c();return He(e,n,t)},resolve:t=>j(e,t)};try{await f(e).sync(l),await a}finally{o=!1}}async function He(e,t,n){let{target:r,kind:i}=await I(`${e}:${n}`),a=t.re===null?t:await T(t.re);!a||a.deleted||a.noSync||r!==(a.origin?a.origin.channel??S(a.origin.thread):null)&&await l(`syncReceipt`,{kind:`thread`,message:a.id,target:r,targetKind:i,cause:`config`})}async function Ue(t,n){let r=Object.keys(e).filter(t=>e[t].canStartThreads);if(t.payload.noSync||r.length===0)return;let i=await T(t.message.id);if(!i||i.deleted)return;let a=[];for(let e of r)try{await Q(e,t,i,null,async()=>{})}catch(e){X(a,i.id,null,e)}await Z(n,a)}async function We(e,t){let{thread:n,target:r}=e.payload;if(!g(r)||(e.payload.kind??(d(r)?`thread`:`channel`))===`thread`)return;let i=await C(n),[a,...o]=i?await w(i.root):[];if(!i||!a||a.id!==i.root||a.deleted)return;let s=[];try{await Q(p(r),e,a,r,e=>Ge(i,a,o,r,s,e))}catch(e){X(s,a.id,r,e)}await Z(t,s)}async function Ge(e,t,n,r,i,a){let o=await O(),c=await E([t.id,...n.map(e=>e.id)]),l=e=>(i.push({id:t.id,target:r,error:e}),e),u=e.external[r];if(u){let e=c[t.id]?.[r];if(e)try{await Y(t,r,e,o,a)}catch(e){throw l(e)}}else try{let e=f(p(r)),n=q(r,t,o,!1,a),i=!n.markdown.trim()&&t.attachments.length>0&&e.uploadsFiles;if(!n.markdown.trim()&&!i)throw s(`a renderer must return text unless the message has media`);let c,l=!1,d=await(async()=>{if(!i){let i=await Fe(r,r,`channel`,t,o);if(i)return l=!0,i;if(t.attachments.length===0||!e.startsThreadsWithFiles)return e.post(_(r),`channel`,n)}try{let a=await e.post(_(r),`channel`,{...n,files:await Be(t)});return c=i?a.files??[]:a.files,a}catch(n){if(!e.refusesFiles(n)&&!z(n))throw n;return c=null,e.post(_(r),`channel`,q(r,t,o,!0,a))}})();u=`${p(r)}:${d.thread}`;let m={thread:u,message:d.message,...c===void 0?{}:{files:c},...l?{asUser:!0}:{}};await J(t,r,m),await Y(t,r,m,o,a)}catch(e){throw l(e)}let d=[];for(let e of n)if(!(e.deleted||e.noSync||Ke(e,r)))try{await Y(e,r,c[e.id]?.[r]??await ze(e,r,u,o,a),o,a)}catch(t){d.push({id:e.id,target:r,error:t})}if(i.push(...d),d.length)throw d[0].error}let Ke=(e,t)=>e.origin?.thread===t||e.from!==null&&p(t)===e.from;async function qe(e,t){if(!e.message)return;if(e.message.re===null)return Ue(e,t);if(e.payload.noSync)return;let n=await C(e.payload.thread);if(!n||n.targets.length===0)return;let r=await T(e.message.id);if(!r||r.deleted)return;let i=await O(),a=[];for(let t of n.targets){let o=n.external[t];if(g(t)&&o&&!Ke(r,t))try{await Q(p(t),e,r,t,async e=>{let n=(await E([r.id]))[r.id]?.[t]??await ze(r,t,o,i,e);await Y(r,t,n,i,e)})}catch(e){X(a,r.id,t,e)}}await Z(t,a)}async function Je(e){let t=(await E([e.payload.id]))[e.payload.id]??{};if(Object.keys(t).length===0)return;let n=e.type===`message.edited`?await T(e.payload.id):e.message??await T(e.payload.id);if(!n||e.type===`message.edited`&&n.deleted)return;let r=await O();for(let[i,a]of Object.entries(t))if(!(!g(i)||e.payload.from!==null&&p(i)===e.payload.from))try{await Q(p(i),e,n,i,async t=>{let o=f(p(i)),s=_(a.thread),c=a.asUser&&(e.type===`message.edited`||e.type===`message.deleted`),l=c?await Ne(o,n,!1):null;if(c&&!l){console.warn(`[board] skipped ${e.type} on ${i}: #${n.id} was posted as its author, and their token is gone`);return}e.type===`message.edited`?l?await o.editAs(l,s,a.message,Pe(i,n,r)):await o.edit(s,a.message,q(i,n,r,a.files===null,t)):e.type===`message.deleted`?(l?await o.deleteAs(l,s,a.message):await o.delete(s,a.message),a.files?.length&&await o.deleteFiles(a.files)):e.type===`reaction.added`?await o.react(s,a.message,h(e.payload.emoji),!0):await o.react(s,a.message,h(e.payload.emoji),!1)})}catch(t){console.warn(`[board] skipped ${e.type} on ${i}:`,t.message)}}async function Ye(e){let{id:t}=e.payload,n=(await E([t]))[t]??{},r=e.message;if(!r||Object.keys(n).length===0)return;let i=await T(t);if(!i||i.deleted)return;let a=await O(),o={...i,labels:r.labels},s={...i,labels:e.before?.labels??{}};for(let[t,r]of Object.entries(n))if(g(t))try{await Q(p(t),e,o,t,async e=>{let n=q(t,o,a,r.files===null,e);n.markdown!==q(t,s,a,r.files===null,e).markdown&&await f(p(t)).edit(_(r.thread),r.message,n)})}catch(e){console.warn(`[board] skipped labels.changed on ${t}:`,W(e))}}async function Xe(e,{attempt:t}){switch(e.type){case`thread.synced`:return We(e,t);case`message.posted`:return qe(e,t);case`message.edited`:case`message.deleted`:case`reaction.added`:case`reaction.removed`:return Je(e);case`labels.changed`:return Ye(e)}}async function Ze(e,t){let n=e[0]?await C(e[0].thread):null;if(!n)return[];let r=[...new Set(Object.values(n.external))].filter(g);return(await Promise.all(r.map(async n=>{let r=p(n);try{let i=f(r),a=null;for(let t=e.length-1;t>=0&&a===null;t--){let r=e[t];!r.deleted&&r.origin?.thread===n&&(a=r.origin.message)}return await i.startTyping(_(n),a,t),n}catch(e){return console.warn(`[board] skipped typing on ${n}:`,W(e)),null}}))).filter(e=>e!==null)}async function Qe(e,t){try{return`${e}:${await f(e).resolveChannel(t)}`}catch(e){throw s(`can't resolve inbox channel: ${e.message}`)}}let $=e=>e===`unsupported`||e===`invalid_target`?400:e===`channel_not_found`?404:e===`ratelimited`?429:[`no_client`,`list_failed`,`internal_error`,`fatal_error`,`service_unavailable`,`request_timeout`].includes(e)?502:403;async function $e(e,t,n,r){let i=f(e);try{return await i.read(t,{limit:n,after:r})}catch(n){throw n instanceof F?new m($(n.code),n.code,n.message):s(`can't read ${t} from ${e}: ${W(n)}`,`platform_error`)}}async function et(e,t){let n=f(e);try{return await n.join(t)}catch(n){throw n instanceof F?new m($(n.code),n.code,n.message):s(`can't join ${t} on ${e}: ${W(n)}`,`platform_error`)}}return{entries:e,bind(e){i=e},caller:c,deliver:Xe,receive:xe,pull:_e,normalizeTarget:I,findByEmail:N,handleWebhook:ge,inboxChannel:Qe,signsIn:Ee,signIn:De,signedIn:Oe,redeemSignIn:ke,typing:Ze,readSource:$e,joinSource:et}}function K(e){let t=e.url?`${e.title}\n${e.url}`:e.title;return e.body?`${t}\n\n${e.body}`:t}export{he as createSyncEngine};
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { i as fileSize, n as DIRECT_UPLOAD_BYTES_MAX } from "./files-SniSmeEr.mjs";
|
|
2
|
-
import { a as AttachmentId } from "./schemas-
|
|
3
|
-
import { d as VERSION, i as withMentions } from "./watchers-hash-
|
|
2
|
+
import { a as AttachmentId } from "./schemas-DBmUO6pr.mjs";
|
|
3
|
+
import { d as VERSION, i as withMentions } from "./watchers-hash-BDhLVkV5.mjs";
|
|
4
4
|
import { n as displayEmoji, r as normalizeEmoji } from "./emoji-CTLpvH-A.mjs";
|
|
5
5
|
import { t as BoardError } from "./client-D0Px7KzF.mjs";
|
|
6
|
-
import { i as groups, n as filters$1, o as options, r as globalOptions, s as usage$1, t as commands } from "./commands-
|
|
7
|
-
import {
|
|
8
|
-
import { t as http } from "./backend-http-
|
|
9
|
-
import { t as board } from "./server-
|
|
6
|
+
import { i as groups, n as filters$1, o as options, r as globalOptions, s as usage$1, t as commands } from "./commands-C3R1AWgm.mjs";
|
|
7
|
+
import { a as handFetch, d as vercelProjectFile, n as boardUrl, o as handLogin, r as connect } from "./node-Zd_C-gxP.mjs";
|
|
8
|
+
import { t as http } from "./backend-http-Bmp0IgD3.mjs";
|
|
9
|
+
import { t as board } from "./server-BixV_byP.mjs";
|
|
10
10
|
import { t as conformance } from "./conformance-DlnfuzEB.mjs";
|
|
11
|
-
import { n as handTeam, r as vercel, t as credentialSource } from "./backend-vercel-
|
|
11
|
+
import { n as handTeam, r as vercel, t as credentialSource } from "./backend-vercel-DQc_TaHp.mjs";
|
|
12
12
|
import { t as displayText } from "./bots-CGkO76qH.mjs";
|
|
13
13
|
import { spawn } from "node:child_process";
|
|
14
14
|
import { readFile, stat, writeFile } from "node:fs/promises";
|
|
@@ -251,7 +251,7 @@ function formatSourceRead(key, read, now = Date.now(), cli = "vb") {
|
|
|
251
251
|
...message.files.map((file) => `${pad}file ${file.name}${file.url ? ` ${file.url}` : ""}`)
|
|
252
252
|
].join("\n");
|
|
253
253
|
});
|
|
254
|
-
const more = read.more ? [`(${read.thread ? "later replies" : "older messages"} not shown: raise --limit, up to 200)`] : [];
|
|
254
|
+
const more = read.next ? [`(more not shown: ${cli} sources ${key} read ${read.thread ?? read.channel} --after ${read.next})`] : read.more ? [`(${read.thread ? "later replies" : "older messages"} not shown: raise --limit, up to 200)`] : [];
|
|
255
255
|
return [
|
|
256
256
|
where,
|
|
257
257
|
...blocks,
|
|
@@ -1743,7 +1743,10 @@ async function run(command, args) {
|
|
|
1743
1743
|
}
|
|
1744
1744
|
if (sub !== "read" && sub !== "join") throw usage(sub === void 0 ? `Missing what to do with ${key}: read or join.` : `Unknown command ${sub} for ${named()} sources.`, { reason: sub === void 0 ? "missing_arguments" : "unknown_command" });
|
|
1745
1745
|
if (!target) throw usage(`Missing the channel, thread, or link to ${sub}.`, { reason: "missing_arguments" });
|
|
1746
|
-
const read = await client().readSource(key, target,
|
|
1746
|
+
const read = await client().readSource(key, target, {
|
|
1747
|
+
...flags.limit ? { limit: Number(flags.limit) } : {},
|
|
1748
|
+
...flags.after ? { after: String(flags.after) } : {}
|
|
1749
|
+
});
|
|
1747
1750
|
if (flags.json) return result(read), 0;
|
|
1748
1751
|
return out(formatSourceRead(key, read, Date.now(), named())), 0;
|
|
1749
1752
|
}
|
|
@@ -1836,11 +1839,13 @@ const context = () => ({
|
|
|
1836
1839
|
async function main(argv, options) {
|
|
1837
1840
|
handLogin(options.login ?? null);
|
|
1838
1841
|
handTeam(options.team ?? null);
|
|
1842
|
+
handFetch(options.fetch ?? null);
|
|
1839
1843
|
try {
|
|
1840
1844
|
return await runOnce(argv, options);
|
|
1841
1845
|
} finally {
|
|
1842
1846
|
handLogin(null);
|
|
1843
1847
|
handTeam(null);
|
|
1848
|
+
handFetch(null);
|
|
1844
1849
|
}
|
|
1845
1850
|
}
|
|
1846
1851
|
async function runOnce(argv, options) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { m as MESSAGE_TEXT_MAX, p as Labels } from "./schemas-
|
|
1
|
+
import { m as MESSAGE_TEXT_MAX, p as Labels } from "./schemas-DBmUO6pr.mjs";
|
|
2
2
|
import { t as HttpError } from "./errors-CusN4x2l.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
//#region src/server/middleware.ts
|
|
@@ -157,6 +157,30 @@ let handed = null;
|
|
|
157
157
|
function handLogin(login) {
|
|
158
158
|
handed = login;
|
|
159
159
|
}
|
|
160
|
+
/** The fetch a CLI that runs board's hands it for Vercel's API (`vercel board`'s), while one does. */
|
|
161
|
+
let handedFetch = null;
|
|
162
|
+
/**
|
|
163
|
+
* Hands board the fetch that sends its requests to Vercel's API with the login it's handed, adding
|
|
164
|
+
* that login's credentials itself, as `vercel board` does: a DPoP login's proof is signed for each
|
|
165
|
+
* request's method and URL, so a token alone can't make one. Null takes it back.
|
|
166
|
+
*/
|
|
167
|
+
function handFetch(send) {
|
|
168
|
+
handedFetch = send;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* A request to Vercel's API as you: through the fetch the CLI that runs board's hands it with its
|
|
172
|
+
* login, which adds its credentials, or with `login` as a Bearer token, through `send`.
|
|
173
|
+
*/
|
|
174
|
+
function asYou(input, init, login, send = fetch) {
|
|
175
|
+
if (handedFetch && loginHanded()) return handedFetch(input, init);
|
|
176
|
+
const headers = new Headers(input instanceof Request ? input.headers : void 0);
|
|
177
|
+
new Headers(init.headers).forEach((value, name) => headers.set(name, value));
|
|
178
|
+
headers.set("authorization", `Bearer ${login}`);
|
|
179
|
+
return send(input, {
|
|
180
|
+
...init,
|
|
181
|
+
headers
|
|
182
|
+
});
|
|
183
|
+
}
|
|
160
184
|
/** Whether the login is one a CLI handed over (`createApp`'s `login`, or `VERCEL_AUTH_TOKEN`). */
|
|
161
185
|
const loginHanded = () => handed !== null || !!process.env.VERCEL_AUTH_TOKEN;
|
|
162
186
|
/**
|
|
@@ -205,10 +229,7 @@ async function personToken(audience, discovery) {
|
|
|
205
229
|
let development;
|
|
206
230
|
try {
|
|
207
231
|
if (!authToken) throw new Error("no Vercel CLI credentials file");
|
|
208
|
-
const response = await
|
|
209
|
-
method: "POST",
|
|
210
|
-
headers: { authorization: `Bearer ${authToken}` }
|
|
211
|
-
});
|
|
232
|
+
const response = await asYou(`https://api.vercel.com/v1/projects/${project.id}/token?source=board${project.team ? `&teamId=${project.team}` : ""}`, { method: "POST" }, authToken);
|
|
212
233
|
if (response.status === 403 || response.status === 404) throw new BoardError("no_access", "Your Vercel account can't access this board's project.", response.status, { hint: "Ask someone on the project's team for access to it." });
|
|
213
234
|
if (!response.ok) throw new Error(`${response.status} ${response.statusText}`);
|
|
214
235
|
development = (await response.json()).token;
|
|
@@ -246,10 +267,7 @@ async function boardProject(url, discovery, authToken) {
|
|
|
246
267
|
team: discovery.team_id
|
|
247
268
|
};
|
|
248
269
|
const found = await findProject(authToken ? async (method, path) => {
|
|
249
|
-
const response = await
|
|
250
|
-
method,
|
|
251
|
-
headers: { authorization: `Bearer ${authToken}` }
|
|
252
|
-
});
|
|
270
|
+
const response = await asYou(`https://api.vercel.com${path}`, { method }, authToken);
|
|
253
271
|
return response.ok ? await response.json() : null;
|
|
254
272
|
} : vercelCliApi, host);
|
|
255
273
|
if (!found) throw new BoardError("no_access", `Your Vercel login can't see the project ${host} belongs to.`, 0, { hint: "Log in as someone on the project's team (vercel login), or ask for access to it." });
|
|
@@ -278,7 +296,7 @@ async function tokenFromVercelCli(project) {
|
|
|
278
296
|
/** Your Vercel username, display name, and avatar (Vercel serves avatars publicly). */
|
|
279
297
|
async function vercelUser(authToken) {
|
|
280
298
|
try {
|
|
281
|
-
const response = await
|
|
299
|
+
const response = await asYou("https://api.vercel.com/v2/user", {}, authToken);
|
|
282
300
|
if (!response.ok) return null;
|
|
283
301
|
const { user } = await response.json();
|
|
284
302
|
return {
|
|
@@ -583,14 +601,13 @@ async function projectBypass(url, host, doFetch) {
|
|
|
583
601
|
const blocked = (why, fix) => new BoardError("protected", `${url} is behind Vercel Deployment Protection, and your Vercel login ${why}.`, 0, { hint: `${fix}, or set VERCEL_AUTOMATION_BYPASS_SECRET (${WHERE}).` });
|
|
584
602
|
const token = await apiLogin(await handedToken());
|
|
585
603
|
const api = token ? async (method, path) => {
|
|
586
|
-
const response = await
|
|
604
|
+
const response = await asYou(`https://api.vercel.com${path}`, {
|
|
587
605
|
method,
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
});
|
|
606
|
+
...method === "PATCH" ? {
|
|
607
|
+
headers: { "content-type": "application/json" },
|
|
608
|
+
body: "{}"
|
|
609
|
+
} : {}
|
|
610
|
+
}, token, doFetch);
|
|
594
611
|
return response.ok ? await response.json() : null;
|
|
595
612
|
} : vercelCliApi;
|
|
596
613
|
const project = await findProject(api, host);
|
|
@@ -658,4 +675,4 @@ const vercelCliApi = async (method, path) => {
|
|
|
658
675
|
}
|
|
659
676
|
};
|
|
660
677
|
//#endregion
|
|
661
|
-
export {
|
|
678
|
+
export { handFetch as a, loginHanded as c, vercelProjectFile as d, environmentProfile as i, projectDir as l, boardUrl as n, handLogin as o, connect as r, localTokenFile as s, asYou as t, vercelLogin as u };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as setOwn, t as own } from "./own-OwgPWdmh.mjs";
|
|
2
|
-
import { n as foldMessages, r as foldSync } from "./folds-
|
|
2
|
+
import { n as foldMessages, r as foldSync } from "./folds-BDMSxBUf.mjs";
|
|
3
3
|
//#region src/store/project.ts
|
|
4
4
|
/** The message an event concerns, if any. */
|
|
5
5
|
function concernedMessageId(event) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as ExternalEvent } from "./external-
|
|
1
|
+
import { n as ExternalEvent } from "./external-D3p5T57R.mjs";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
//#region src/sync/fn.ts
|
|
4
4
|
const ROUTES = Symbol.for("board.syncRoutes");
|
|
@@ -120,6 +120,7 @@ var SyncProvider = class {
|
|
|
120
120
|
canStartThreads;
|
|
121
121
|
singleReaction;
|
|
122
122
|
uploadsFiles;
|
|
123
|
+
startsThreadsWithFiles;
|
|
123
124
|
fn;
|
|
124
125
|
/** People's tokens, when the adapter has them: messages they write post as them. */
|
|
125
126
|
users;
|
|
@@ -135,6 +136,7 @@ var SyncProvider = class {
|
|
|
135
136
|
this.canStartThreads = options.canStartThreads ?? false;
|
|
136
137
|
this.singleReaction = options.singleReaction ?? false;
|
|
137
138
|
this.uploadsFiles = options.uploadsFiles ?? false;
|
|
139
|
+
this.startsThreadsWithFiles = this.uploadsFiles && (options.startsThreadsWithFiles ?? false);
|
|
138
140
|
}
|
|
139
141
|
/** The platform account a person's token belongs to. */
|
|
140
142
|
async whoAmI(_token) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { d as ExternalFile, f as ExternalLink, l as ExternalAuthor, p as Link, t as Actor, u as ExternalEvent } from "./folds-
|
|
2
|
-
import { V as MessageView, _ as BoardEventView, dt as SourceJoin, mt as SourceRead, t as BoardClient } from "./client-
|
|
1
|
+
import { d as ExternalFile, f as ExternalLink, l as ExternalAuthor, p as Link, t as Actor, u as ExternalEvent } from "./folds-ZkHM4M-v.mjs";
|
|
2
|
+
import { V as MessageView, _ as BoardEventView, dt as SourceJoin, mt as SourceRead, t as BoardClient } from "./client-BqAjk0Q4.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
//#region src/sync/events.d.ts
|
|
5
5
|
declare const EventBase: z.ZodObject<{
|
|
@@ -132,6 +132,7 @@ declare function envelope(platform: string, key: string, event: ExternalEvent, r
|
|
|
132
132
|
kind: "lifecycle";
|
|
133
133
|
title: string;
|
|
134
134
|
url: string | null;
|
|
135
|
+
body?: string | null | undefined;
|
|
135
136
|
labels: Record<string, string>;
|
|
136
137
|
unset: string[];
|
|
137
138
|
owns?: string[] | undefined;
|
|
@@ -275,6 +276,7 @@ declare function eventSchema<P extends string, M extends string>(platform: P, me
|
|
|
275
276
|
type: z.ZodString;
|
|
276
277
|
title: z.ZodString;
|
|
277
278
|
url: z.ZodNullable<z.ZodString>;
|
|
279
|
+
body: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
278
280
|
labels: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
279
281
|
unset: z.ZodArray<z.ZodString>;
|
|
280
282
|
owns: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -494,6 +496,8 @@ type ProviderOptions = {
|
|
|
494
496
|
canStartThreads?: boolean;
|
|
495
497
|
singleReaction?: boolean;
|
|
496
498
|
uploadsFiles?: boolean;
|
|
499
|
+
/** Whether a new thread's root can carry its files in the same message as its text. */
|
|
500
|
+
startsThreadsWithFiles?: boolean;
|
|
497
501
|
/** People's own tokens, to post as them and to link accounts by signing in. */
|
|
498
502
|
users?: UserTokens | null;
|
|
499
503
|
};
|
|
@@ -598,6 +602,7 @@ declare const ReceivedEvent: z.ZodObject<{
|
|
|
598
602
|
type: z.ZodString;
|
|
599
603
|
title: z.ZodString;
|
|
600
604
|
url: z.ZodNullable<z.ZodString>;
|
|
605
|
+
body: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
601
606
|
labels: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
602
607
|
unset: z.ZodArray<z.ZodString>;
|
|
603
608
|
owns: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -622,6 +627,7 @@ declare abstract class SyncProvider<E extends ProviderEvent = ProviderEvent> {
|
|
|
622
627
|
readonly canStartThreads: boolean;
|
|
623
628
|
readonly singleReaction: boolean;
|
|
624
629
|
readonly uploadsFiles: boolean;
|
|
630
|
+
readonly startsThreadsWithFiles: boolean;
|
|
625
631
|
private readonly fn;
|
|
626
632
|
/** People's tokens, when the adapter has them: messages they write post as them. */
|
|
627
633
|
readonly users: UserTokens | null;
|
|
@@ -662,6 +668,7 @@ declare abstract class SyncProvider<E extends ProviderEvent = ProviderEvent> {
|
|
|
662
668
|
*/
|
|
663
669
|
read(_target: string, _options: {
|
|
664
670
|
limit: number;
|
|
671
|
+
after: string | null;
|
|
665
672
|
}): Promise<SourceRead>;
|
|
666
673
|
/** Adds the board's app to a channel so `read` can read it, where the board opted in. Throws `UnreadableError` otherwise. */
|
|
667
674
|
join(_target: string): Promise<SourceJoin>;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { c as externalMessageKey } from "./external-
|
|
1
|
+
import { c as externalMessageKey } from "./external-D3p5T57R.mjs";
|
|
2
2
|
import { n as setOwn } from "./own-OwgPWdmh.mjs";
|
|
3
3
|
import { n as CLEAR_EVENT_TYPE, o as sessionClearedError, s as supersededAttemptError, t as A2Error } from "./session-clear-wHd5GCpZ-BnKSxReK.mjs";
|
|
4
4
|
import { m as nullProtoRecord, n as NOTIFY_TIMINGS, v as stateTailReaders } from "./internal-CvsrprnU-CRY89I-b.mjs";
|
|
5
5
|
import { i as presenceTombstones, n as isSerializedEvent, r as parseSerializedEvent, t as bufferedEvents } from "./stream-buffer-DrTyiIuo-BKy-vI14.mjs";
|
|
6
6
|
import { i as streamActivities, n as defaultSleep, r as pollingStream, t as createStreamActivity } from "./store-polling-BZt2Rf3D-BiEM6_HB.mjs";
|
|
7
7
|
import { t as retryableLazy } from "./retryable-lazy-DZWmHpii-Bye-W8q7.mjs";
|
|
8
|
-
import { i as syncReads, n as project, r as projectSync, t as concernedMessageId } from "./project-
|
|
8
|
+
import { i as syncReads, n as project, r as projectSync, t as concernedMessageId } from "./project-CBXlLftU.mjs";
|
|
9
9
|
import { i as idempotentReplay, n as decodeCause } from "./store-codec-DwrWlgQx-CYxGW0aD.mjs";
|
|
10
10
|
import { t as pollPresence } from "./store-presence-polling-JuAy2Ck2-CYpuK75X.mjs";
|
|
11
11
|
//#region ../../node_modules/.pnpm/experimental-a2@0.22.0_@upstash+qstash@2.12.0_@vercel+queue@0.7.0_ai@7.0.130_zod@4.6.5__52060f00b21aecfab049c27fa3abd2f9/node_modules/experimental-a2/dist/store-redis-notify-CsJw_hfD.js
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { S as storable, _ as RemoteWatcherId, c as ChannelPath, d as LabelKey, g as MessageText, h as MessageId, i as Attachment, l as Emoji, n as ActorId, o as Author, p as Labels, u as Handle, v as SCOPE_MAX, y as SeenActorKind } from "./schemas-
|
|
2
|
-
import { a as Link, i as ExternalTarget, n as ExternalEvent, o as Origin } from "./external-
|
|
1
|
+
import { S as storable, _ as RemoteWatcherId, c as ChannelPath, d as LabelKey, g as MessageText, h as MessageId, i as Attachment, l as Emoji, n as ActorId, o as Author, p as Labels, u as Handle, v as SCOPE_MAX, y as SeenActorKind } from "./schemas-DBmUO6pr.mjs";
|
|
2
|
+
import { a as Link, i as ExternalTarget, n as ExternalEvent, o as Origin } from "./external-D3p5T57R.mjs";
|
|
3
3
|
import { n as setOwn, t as own } from "./own-OwgPWdmh.mjs";
|
|
4
4
|
import { a as reducer, i as makeReducerBuilder, t as assertSyncSchema } from "./reducer-CjmvZSAb-D_OSISmj.mjs";
|
|
5
|
-
import { n as foldMessages, t as foldActors } from "./folds-
|
|
5
|
+
import { n as foldMessages, t as foldActors } from "./folds-BDMSxBUf.mjs";
|
|
6
6
|
import { z } from "zod";
|
|
7
7
|
//#region ../../node_modules/.pnpm/experimental-a2@0.22.0_@upstash+qstash@2.12.0_@vercel+queue@0.7.0_ai@7.0.130_zod@4.6.5__52060f00b21aecfab049c27fa3abd2f9/node_modules/experimental-a2/dist/contract-CWukt01d.js
|
|
8
8
|
function contract(options) {
|
|
@@ -60,7 +60,8 @@ const Author = z.object({
|
|
|
60
60
|
session: z.string().nullable()
|
|
61
61
|
});
|
|
62
62
|
/** 128 random bits, base64url: an attachment is named by an ID nobody can guess. */
|
|
63
|
-
|
|
63
|
+
/** 128 random bits, base64url, as A2 makes them; or `att_` and a UUID, as Vercel's board does. */
|
|
64
|
+
const AttachmentId = z.string().regex(/^(?:[A-Za-z0-9_-]{22}|att_[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/, "invalid attachment id");
|
|
64
65
|
/** A file on a message. The board records `type` and `size` from what it stored, never from the request. */
|
|
65
66
|
const Attachment = z.object({
|
|
66
67
|
id: AttachmentId,
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { t as BoardError } from "./client-D0Px7KzF.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import { t as board } from "./server-
|
|
4
|
-
import { t as oidcTokens } from "./tokens-
|
|
5
|
-
import {
|
|
2
|
+
import { s as localTokenFile } from "./node-Zd_C-gxP.mjs";
|
|
3
|
+
import { t as board } from "./server-BixV_byP.mjs";
|
|
4
|
+
import { t as oidcTokens } from "./tokens-CC3izSNr.mjs";
|
|
5
|
+
import { t as a2 } from "./a2-HUbQJ0RD.mjs";
|
|
6
|
+
import { a as fsBlob } from "./blob-DdbpJqN1.mjs";
|
|
6
7
|
import { t as localScheduler } from "./local-DhkrAqPP.mjs";
|
|
7
8
|
import { mkdir, rm, writeFile } from "node:fs/promises";
|
|
8
9
|
import { userInfo } from "node:os";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as createBoard } from "./exports-
|
|
2
|
-
import { t as http } from "./backend-http-
|
|
1
|
+
import { t as createBoard } from "./exports-BG-0Wyn-.mjs";
|
|
2
|
+
import { t as http } from "./backend-http-Bmp0IgD3.mjs";
|
|
3
3
|
//#region src/server/index.ts
|
|
4
4
|
/**
|
|
5
5
|
* The handle on a board. With a `backend`, the board lives there: `a2()` keeps it in this
|
|
@@ -9,8 +9,8 @@ import { t as http } from "./backend-http-nppEk8gC.mjs";
|
|
|
9
9
|
function board(options = {}) {
|
|
10
10
|
return createBoard(options, {
|
|
11
11
|
http: () => http(),
|
|
12
|
-
sync: () => import("./engine-
|
|
13
|
-
serving: () => import("./serving-
|
|
12
|
+
sync: () => import("./engine-DQxXk7dX.mjs"),
|
|
13
|
+
serving: () => import("./serving-B75Y4BF-.mjs")
|
|
14
14
|
});
|
|
15
15
|
}
|
|
16
16
|
//#endregion
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as ownTeamId, n as discoveryIdentity, r as ownProjectId, t as oidcTokens } from "./tokens-
|
|
1
|
+
import { i as ownTeamId, n as discoveryIdentity, r as ownProjectId, t as oidcTokens } from "./tokens-CC3izSNr.mjs";
|
|
2
2
|
export { discoveryIdentity, oidcTokens, ownProjectId, ownTeamId };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { c as externalMessageKey } from "./external-
|
|
1
|
+
import { c as externalMessageKey } from "./external-D3p5T57R.mjs";
|
|
2
2
|
import { n as setOwn } from "./own-OwgPWdmh.mjs";
|
|
3
|
-
import { i as syncReads, n as project, r as projectSync, t as concernedMessageId } from "./project-
|
|
3
|
+
import { i as syncReads, n as project, r as projectSync, t as concernedMessageId } from "./project-CBXlLftU.mjs";
|
|
4
4
|
//#region src/store/sql.ts
|
|
5
5
|
/** The projection's name in `board_positions`, and the A2 consumer that runs it. */
|
|
6
6
|
const TABLES_CONSUMER = "board-tables";
|
package/dist/sync-github.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as SyncUnit, _ as withUserTokens, d as ResolvedTarget, f as SyncContext, h as UserTokens, o as ProviderPost, r as ProviderDelivery, y as SyncFn } from "./provider-
|
|
2
|
-
import { n as ChatSyncProvider } from "./chat-provider-
|
|
1
|
+
import { S as SyncUnit, _ as withUserTokens, d as ResolvedTarget, f as SyncContext, h as UserTokens, o as ProviderPost, r as ProviderDelivery, y as SyncFn } from "./provider-DmSTp9lI.mjs";
|
|
2
|
+
import { n as ChatSyncProvider } from "./chat-provider-BWHbChcQ.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { Adapter } from "chat";
|
|
5
5
|
//#region src/sync/github.d.ts
|
|
@@ -309,6 +309,7 @@ export declare const GitHubEvent: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
309
309
|
kind: z.ZodLiteral<"lifecycle">;
|
|
310
310
|
title: z.ZodString;
|
|
311
311
|
url: z.ZodNullable<z.ZodString>;
|
|
312
|
+
body: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
312
313
|
labels: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
313
314
|
unset: z.ZodArray<z.ZodString>;
|
|
314
315
|
owns: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -369,6 +370,7 @@ export declare const GitHubEvent: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
369
370
|
kind: z.ZodLiteral<"lifecycle">;
|
|
370
371
|
title: z.ZodString;
|
|
371
372
|
url: z.ZodNullable<z.ZodString>;
|
|
373
|
+
body: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
372
374
|
labels: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
373
375
|
unset: z.ZodArray<z.ZodString>;
|
|
374
376
|
owns: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
package/dist/sync-github.mjs
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { c as into, d as withRoutes } from "./provider-
|
|
2
|
-
import { i as eventSchema, r as envelope } from "./events-
|
|
1
|
+
import { c as into, d as withRoutes } from "./provider-BaVmi4Hi.mjs";
|
|
2
|
+
import { i as eventSchema, r as envelope } from "./events-qf5XG5VQ.mjs";
|
|
3
3
|
import { r as withUserTokens, t as connectUserTokens } from "./users-yryHKFMo.mjs";
|
|
4
|
-
import { r as markdownOf, t as ChatSyncProvider } from "./chat-provider-
|
|
4
|
+
import { r as markdownOf, t as ChatSyncProvider } from "./chat-provider-COtsU5jB.mjs";
|
|
5
|
+
import { n as tagOf } from "./tags-BpFo6q0_.mjs";
|
|
5
6
|
import { z } from "zod";
|
|
6
7
|
import { connectGitHubAdapter } from "@vercel/connect/chat";
|
|
7
8
|
import { createGitHubAdapter } from "@chat-adapter/github";
|
|
@@ -18,17 +19,6 @@ const author = (user) => ({
|
|
|
18
19
|
avatar: user?.avatar_url ?? null,
|
|
19
20
|
isBot: user?.type === "Bot"
|
|
20
21
|
});
|
|
21
|
-
/** `good first issue` → `good-first-issue`: the part of a label key a name gives. Empty when nothing's left. */
|
|
22
|
-
const slug = (name) => name.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9_.-]+/g, "-").replace(/^[-_.]+|-+$/g, "");
|
|
23
|
-
/**
|
|
24
|
-
* A GitHub label or assignee as a board label: `bug` → `tag.bug=bug`,
|
|
25
|
-
* `julianbenegas` → `assignee.julianbenegas=julianbenegas`. The keys don't
|
|
26
|
-
* name GitHub, so a filter like `--label tag.bug` holds for any platform.
|
|
27
|
-
*/
|
|
28
|
-
function tagOf(prefix, name) {
|
|
29
|
-
const key = name ? slug(name) : "";
|
|
30
|
-
return key ? [`${prefix}.${key}`.slice(0, 64), name.slice(0, 256)] : null;
|
|
31
|
-
}
|
|
32
22
|
/** A PR's or issue's current labels and assignees, as board labels. */
|
|
33
23
|
function tagsOf(item) {
|
|
34
24
|
const tags = [...(item.labels ?? []).map((label) => tagOf("tag", label.name)), ...(item.assignees ?? []).map((user) => tagOf("assignee", user.login))];
|
package/dist/sync-kapso.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as SyncUnit, f as SyncContext, y as SyncFn } from "./provider-
|
|
2
|
-
import { n as ChatSyncProvider, t as ChatInput } from "./chat-provider-
|
|
1
|
+
import { S as SyncUnit, f as SyncContext, y as SyncFn } from "./provider-DmSTp9lI.mjs";
|
|
2
|
+
import { n as ChatSyncProvider, t as ChatInput } from "./chat-provider-BWHbChcQ.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { Adapter } from "chat";
|
|
5
5
|
//#region src/sync/kapso.d.ts
|
|
@@ -127,6 +127,7 @@ export declare const WhatsAppEvent: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
127
127
|
type: z.ZodString;
|
|
128
128
|
title: z.ZodString;
|
|
129
129
|
url: z.ZodNullable<z.ZodString>;
|
|
130
|
+
body: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
130
131
|
labels: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
131
132
|
unset: z.ZodArray<z.ZodString>;
|
|
132
133
|
owns: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
package/dist/sync-kapso.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { s as channels } from "./provider-
|
|
2
|
-
import { i as eventSchema, r as envelope } from "./events-
|
|
3
|
-
import { r as markdownOf, t as ChatSyncProvider } from "./chat-provider-
|
|
1
|
+
import { s as channels } from "./provider-BaVmi4Hi.mjs";
|
|
2
|
+
import { i as eventSchema, r as envelope } from "./events-qf5XG5VQ.mjs";
|
|
3
|
+
import { r as markdownOf, t as ChatSyncProvider } from "./chat-provider-COtsU5jB.mjs";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
//#region src/sync/kapso.ts
|
|
6
6
|
const decode = (id) => id.split(":").map((part) => Buffer.from(part, "base64url").toString("utf8")).join(":");
|
package/dist/sync-linear.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { mt as SourceRead } from "./client-BqAjk0Q4.mjs";
|
|
2
|
+
import { S as SyncUnit, c as ReceivedEvent, d as ResolvedTarget, f as SyncContext, o as ProviderPost, r as ProviderDelivery, y as SyncFn } from "./provider-DmSTp9lI.mjs";
|
|
3
|
+
import { n as ChatSyncProvider, t as ChatInput } from "./chat-provider-BWHbChcQ.mjs";
|
|
3
4
|
import { z } from "zod";
|
|
4
5
|
import { Adapter } from "chat";
|
|
5
6
|
//#region src/sync/linear.d.ts
|
|
@@ -127,6 +128,7 @@ export declare const LinearEvent: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
127
128
|
type: z.ZodString;
|
|
128
129
|
title: z.ZodString;
|
|
129
130
|
url: z.ZodNullable<z.ZodString>;
|
|
131
|
+
body: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
130
132
|
labels: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
131
133
|
unset: z.ZodArray<z.ZodString>;
|
|
132
134
|
owns: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -174,6 +176,14 @@ export declare class LinearProvider extends ChatSyncProvider<LinearEvent> {
|
|
|
174
176
|
* webhook sets up: anything else (a delivery, a root fetched on a later pull) asks for one here.
|
|
175
177
|
*/
|
|
176
178
|
private api;
|
|
179
|
+
/**
|
|
180
|
+
* A project's or team's issues, newest first, or one issue and its comments, read on demand:
|
|
181
|
+
* nothing is synced or stored. `next` pages past a read's `limit`.
|
|
182
|
+
*/
|
|
183
|
+
read(target: string, { limit, after }: {
|
|
184
|
+
limit: number;
|
|
185
|
+
after: string | null;
|
|
186
|
+
}): Promise<SourceRead>;
|
|
177
187
|
resolveChannel(key: string): Promise<string>;
|
|
178
188
|
/**
|
|
179
189
|
* `ENG` is a team; `ENG:<uuid>`, a bare UUID, or `ENG-12` is an issue, by its team and UUID:
|