corsair 0.1.115 → 0.1.116
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/{browser-delivery-DzIPy41I.d.ts → browser-delivery-Bvf8JqTz.d.ts} +1 -1
- package/dist/chunk-EF32RW4S.js +66 -0
- package/dist/{connect-LFLJCALJ.js → connect-ZKP43YRG.js} +1 -1
- package/dist/core.d.ts +4 -4
- package/dist/core.js +1 -1
- package/dist/hub.d.ts +56 -56
- package/dist/hub.js +1 -1
- package/dist/{index-By4SUsQO.d.ts → index-B-FvI2-D.d.ts} +124 -113
- package/dist/{index-BjzfHSPn.d.ts → index-B2XsUjnW.d.ts} +1 -1
- package/dist/{index--jxBUCjh.d.ts → index-z0tnVuER.d.ts} +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.js +1 -1
- package/dist/{loop-I2YLSQ54.js → loop-CNEPJ4DI.js} +1 -1
- package/dist/oauth.d.ts +1 -1
- package/dist/oauth.js +1 -1
- package/dist/{setup-HUAVSMIY.js → setup-DZKKWGRZ.js} +1 -1
- package/dist/{setup-introspect-46SQYJEX.js → setup-introspect-WIGEWC7Z.js} +1 -1
- package/dist/setup.d.ts +2 -2
- package/dist/setup.js +1 -1
- package/dist/{tenant-match-utils-B-L5MHWg.d.ts → tenant-match-utils-Bu6w6L7r.d.ts} +1 -1
- package/dist/tunnel.d.ts +4 -4
- package/dist/tunnel.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-YDI4KN5B.js +0 -66
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import{a as fe,b as St,c as _t}from"./chunk-3EPM4FJ3.js";import{a as co,b as ye,c as lo,d as w,e as B,f as po,g as $,h as F,i as T,j as An,k as go,l as fo,m as It,n as yo,o as mo}from"./chunk-WDF3YE27.js";import{a as uo}from"./chunk-IGGCNGU2.js";import{ZodBoolean as wc,ZodDate as Cc,ZodEnum as vc,ZodNullable as Pc,ZodNumber as Tc,ZodObject as Ac,ZodOptional as xc,ZodRecord as Rc,ZodString as Ic,ZodType as Sc}from"zod";var xn=["abstract","activetrail","addresszen","affinda","agencyzoom","agentmail","agenty","agentql","ahrefs","aimlapi","airtable","alchemy","algolia","alphavantage","alttextai","amara","ambientweather","ambee","amcards","amplitude","apibible","apify","apilabz","apisports","asana","ayrshare","bitwarden","bluesky","boloforms","box","canvas","cal","calendly","canva","cloudflare","cloudinary","confluence","cursor","databricks","datadog","deepseek","digitalocean","discord","dockerhub","dodopayments","dropbox","epicgames","exa","facebook","figma","firecrawl","fireflies","gemini","github","gitlab","gmail","googlebigquery","googlecalendar","googledocs","googledrive","googlemaps","googlemeet","googlesheets","grafana","hackernews","harvest","hashnode","heygen","hubspot","huggingface","insightoai","instagram","intercom","jira","linear","linkedin","loyverse","mailchimp","monday","neon","notion","ocrspace","ollama","onedrive","onepassword","openai","openweathermap","oura","outlook","pagerduty","perplexityai","posthog","razorpay","reddit","resend","retailed","salesforce","sentry","sharepoint","slack","spotify","strava","stripe","supabase","tally","tavily","teams","telegram","todoist","toggl","trello","twilio","twitter","twitterapiio","twochat","typeform","vapi","vercel","whatsapp","wiza","workday","xquik","youcom","youtube","zendesk","zohomail","zoom"],ho={abstract:"Abstract",activetrail:"Active Trail",addresszen:"Addresszen",affinda:"Affinda",agencyzoom:"AgencyZoom",agentmail:"AgentMail",agenty:"Agenty",agentql:"AgentQL",ahrefs:"Ahrefs",aimlapi:"AI/ML API",airtable:"Airtable",alchemy:"Alchemy",algolia:"Algolia",alphavantage:"Alpha Vantage",alttextai:"AltText.ai",amara:"Amara",ambientweather:"Ambient Weather",ambee:"Ambee",amcards:"AMcards",amplitude:"Amplitude",apibible:"API.Bible",apify:"Apify",apilabz:"API Labz",apisports:"API-Sports",asana:"Asana",ayrshare:"Ayrshare",bitwarden:"Bitwarden",bluesky:"Bluesky",boloforms:"Boloforms",box:"Box",canvas:"Canvas LMS",cal:"Cal",calendly:"Calendly",canva:"Canva",cloudflare:"Cloudflare",cloudinary:"Cloudinary",confluence:"Confluence",cursor:"Cursor",databricks:"Databricks",datadog:"Datadog",deepseek:"DeepSeek",digitalocean:"DigitalOcean",discord:"Discord",dockerhub:"Docker Hub",dodopayments:"Dodo Payments",dropbox:"Dropbox",epicgames:"Epic Games",exa:"Exa",facebook:"Facebook",figma:"Figma",firecrawl:"Firecrawl",fireflies:"Fireflies",gemini:"Gemini",github:"GitHub",gitlab:"GitLab",gmail:"Gmail",googlebigquery:"Google BigQuery",googlecalendar:"Google Calendar",googledocs:"Google Docs",googledrive:"Google Drive",googlemaps:"Google Maps",googlemeet:"Google Meet",googlesheets:"Google Sheets",grafana:"Grafana",hackernews:"Hacker News",harvest:"Harvest",hashnode:"Hashnode",heygen:"HeyGen",hubspot:"HubSpot",huggingface:"Hugging Face",insightoai:"Insighto.ai",instagram:"Instagram",intercom:"Intercom",jira:"Jira",linear:"Linear",linkedin:"LinkedIn",loyverse:"Loyverse",mailchimp:"Mailchimp",monday:"Monday",neon:"Neon",notion:"Notion",ocrspace:"OCR.space",ollama:"Ollama",onedrive:"OneDrive",onepassword:"1Password",openai:"OpenAI",openweathermap:"OpenWeatherMap",oura:"Oura",outlook:"Outlook",pagerduty:"PagerDuty",perplexityai:"Perplexity AI",posthog:"PostHog",razorpay:"Razorpay",reddit:"Reddit",resend:"Resend",retailed:"Retailed",salesforce:"Salesforce",sentry:"Sentry",sharepoint:"SharePoint",slack:"Slack",spotify:"Spotify",strava:"Strava",stripe:"Stripe",supabase:"Supabase",tally:"Tally",tavily:"Tavily",teams:"Teams",telegram:"Telegram",todoist:"Todoist",toggl:"Toggl",trello:"Trello",twilio:"Twilio",twitter:"Twitter",twitterapiio:"Twitter API IO",twochat:"TwoChat",typeform:"Typeform",vapi:"Vapi",vercel:"Vercel",whatsapp:"WhatsApp",wiza:"Wiza",workday:"Workday",xquik:"XQuik",youcom:"You.com",youtube:"YouTube",zendesk:"Zendesk",zohomail:"Zoho Mail",zoom:"Zoom"};function me(e){let n=ho[e];return n||e.charAt(0).toUpperCase()+e.slice(1)}function x(e){return typeof e=="string"&&e.length>0}function Os(e){return e==="ready"||e==="partial"||e==="not_started"||e==="missing_integration"}function Ms(e){return e==="oauth_2"||e==="api_key"||e==="bot_token"||e==="managed"}function Rn(e){if(!e||typeof e!="object")throw new Error("Hub API returned an empty connect session");let n=e;if(!x(n.connectUrl)||!x(n.token)||!x(n.projectId))throw new Error("Hub API returned an incomplete connect session (expected connectUrl, token, and projectId)");let t={connectUrl:n.connectUrl,token:n.token,projectId:n.projectId,environmentId:x(n.environmentId)?n.environmentId:n.projectId};return x(n.expiresAt)&&(t.expiresAt=n.expiresAt),t}function In(e){if(!Array.isArray(e))throw new Error("Hub API returned an invalid connections response (expected array)");let n=[];for(let t of e){if(!t||typeof t!="object")continue;let r=t;if(!x(r.tenantId)||!x(r.plugin)||!Os(r.status)||!Ms(r.authType)||typeof r.connected!="boolean"||typeof r.verified!="boolean")continue;let o=Array.isArray(r.missingFields)?r.missingFields.filter(i=>typeof i=="string"):[];n.push({tenantId:r.tenantId,plugin:r.plugin,status:r.status,authType:r.authType,connected:r.connected,verified:r.verified,missingFields:o,reportedAt:x(r.reportedAt)?r.reportedAt:new Date().toISOString()})}return n}function Sn(e){if(!e||typeof e!="object")throw new Error("Hub API returned an empty permission session");let n=e;if(!x(n.approvalUrl)||!x(n.token)||!x(n.projectId)||!x(n.expiresAt))throw new Error("Hub API returned an incomplete permission session (expected approvalUrl, token, projectId, and expiresAt)");return{approvalUrl:n.approvalUrl,token:n.token,projectId:n.projectId,expiresAt:n.expiresAt}}function _n(e){if(!e||typeof e!="object")throw new Error("Hub token refresh returned an empty response");let n=e;if(x(n.access_token))return{access_token:n.access_token,refresh_token:x(n.refresh_token)?n.refresh_token:void 0,expires_in:(()=>{if(typeof n.expires_in=="number")return n.expires_in;if(typeof n.expires_in=="string"&&n.expires_in.trim().length>0){let t=Number(n.expires_in);return Number.isFinite(t)?t:void 0}})(),scope:x(n.scope)?n.scope:void 0};throw new Error(x(n.error)?x(n.error_description)?n.error_description:n.error:"Hub token refresh returned no access_token")}function Hs(e){return Array.isArray(e)?e.filter(n=>typeof n=="string"):[]}function Fs(e){if(!Array.isArray(e))return[];let n=[];for(let t of e){if(!t||typeof t!="object")continue;let r=t;x(r.name)&&n.push({name:r.name,level:r.level==="integration"||r.level==="account"?r.level:"account",required:r.required===!0,configured:r.configured===!0})}return n}function Us(e,n,t,r){return e==="ready"||e==="partial"||e==="not_started"||e==="missing_integration"?e:n?"ready":t.some(i=>i.level==="integration"&&i.required&&!i.configured)?"missing_integration":t.some(i=>i.level==="account"&&i.required&&i.configured)?"partial":(r.length>0,"not_started")}function ko(e){if(!e||typeof e!="object")throw new Error("Connect status response was empty");let n=e;if(!x(n.tenantId)||!Array.isArray(n.plugins))throw new Error("Connect status response was incomplete (expected tenantId and plugins)");let t=[];for(let r of n.plugins){if(!r||typeof r!="object")continue;let o=r;if(!x(o.plugin)||typeof o.connected!="boolean")continue;let i=o.authKind==="oauth"||o.authKind==="api_key"||o.authKind==="bot_token"?o.authKind:"api_key",s=Fs(o.fields),a=Hs(o.missingRequiredFields),u=Us(o.status,o.connected,s,a);t.push({plugin:o.plugin,providerName:x(o.providerName)?o.providerName:o.plugin,authKind:i,status:u,connected:o.connected,fields:s,missingRequiredFields:a})}return{tenantId:n.tenantId,plugins:t}}function En(e){if(!e||typeof e!="object")return null;let n=e;return n.error??n.message??null}function bo(e){return e.replace(/\/$/,"")}function Et(e){if(!e.projectApiKey.startsWith("ck_dev_"))return null;try{return fe()}catch{return null}}function wo(e){let n=Et(e);return n?{"x-corsair-delivery-url":n}:{}}async function Co(e){let n=e.headers.get("content-type")??"",t=await e.text();if(!t)return null;if(!n.includes("application/json")&&t.trimStart().startsWith("<"))throw new Error(`Hub API returned HTML instead of JSON (HTTP ${e.status}). Check HUB_API_URL and deploy the latest hub API.`);try{return JSON.parse(t)}catch{throw new Error(`Hub API returned invalid JSON (HTTP ${e.status})`)}}function vo(e,n,t){if(n===404&&t)return t;let r=En(e);return r||`Hub API returned HTTP ${n}`}async function R(e){let n=bo(e.hub.apiUrl),t=await fetch(`${n}${e.path}`,{method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${e.hub.projectApiKey}`,...wo(e.hub)},body:JSON.stringify(e.body)}),r=await Co(t);if(!t.ok)throw new Error(vo(r,t.status,e.notFoundMessage));return e.parseResponse(r)}async function U(e){let n=bo(e.hub.apiUrl),t=await fetch(`${n}${e.path}`,{method:"GET",headers:{authorization:`Bearer ${e.hub.projectApiKey}`,...wo(e.hub)}}),r=await Co(t);if(!t.ok)throw new Error(vo(r,t.status,e.notFoundMessage));return e.parseResponse(r)}function Dn(e){return e&&typeof e=="object"?e:{}}function Po(e){let n=Dn(e);return{chatId:n.threadId,message:n.message,workflowId:n.workflowId??null,action:n.action}}async function Dt(e,n){return R({hub:e,path:"/threads",body:{tenantId:n.tenantId,message:n.message},parseResponse:t=>{let r=Dn(t);return{chat:r.thread,reply:Po(r.reply)}}})}async function Ot(e,n){return R({hub:e,path:`/threads/${encodeURIComponent(n.chatId)}/messages`,body:{tenantId:n.tenantId,message:n.message},notFoundMessage:`Chat "${n.chatId}" not found`,parseResponse:Po})}async function Mt(e,n){return U({hub:e,path:`/threads?tenantId=${encodeURIComponent(n.tenantId)}`,parseResponse:t=>{let r=Dn(t).threads;return Array.isArray(r)?r:[]}})}async function Ht(e,n){return U({hub:e,path:`/threads/${encodeURIComponent(n.chatId)}/messages?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Chat "${n.chatId}" not found`,parseResponse:t=>{let r=Dn(t).messages;return Array.isArray(r)?r:[]}})}import{randomUUID as Ks}from"crypto";var Bs="corsair:client-bridge";function Ft(e){return new URL(e).origin}function Fe(e){let n=JSON.stringify({type:Bs,requestId:e.requestId,ok:e.ok,body:e.body??null,error:e.error??null}),t=JSON.stringify(Ft(e.hubOrigin));return`<!DOCTYPE html><html><head><meta charset="utf-8"></head><body><script>
|
|
2
|
+
(function () {
|
|
3
|
+
var message = ${n};
|
|
4
|
+
var targetOrigin = ${t};
|
|
5
|
+
if (window.parent && window.parent !== window) {
|
|
6
|
+
window.parent.postMessage(message, targetOrigin);
|
|
7
|
+
}
|
|
8
|
+
})();
|
|
9
|
+
</script></body></html>`}var Ls=new Set(["localhost","127.0.0.1","[::1]","::1"]);function Ut(e){try{let{hostname:n,protocol:t}=new URL(e);return t!=="http:"&&t!=="https:"?!1:Ls.has(n)}catch{return!1}}function rn(e){return e==="development"?"browser":"server"}function To(e){return rn(e)==="browser"}function Ao(e){return Ut(e)?"Production delivery URL must be a public URL, not localhost":null}import{randomBytes as js}from"crypto";var he=60*1e3,Re=300*1e3;import{createHmac as Ns,randomBytes as $s,timingSafeEqual as Ws}from"crypto";function ie(){return $s(16).toString("base64url")}function on(e,n){let t=n.trim();if(!t)throw new Error("Signing secret is required");return Ns("sha256",t).update(e).digest("base64url")}function ee(e,n){let t=n.trim();if(!t)return null;let r=e.split(".");if(r.length!==2)return null;let[o,i]=r;if(!o||!i)return null;let s=on(o,t);try{if(!Ws(Buffer.from(i,"utf8"),Buffer.from(s,"utf8")))return null}catch{return null}let a;try{a=JSON.parse(Buffer.from(o,"base64url").toString("utf8"))}catch{return null}return a.exp*1e3<Date.now()?null:a}function On(e,n,t){let r=Math.floor(Date.now()/1e3),o={...e,iat:r,exp:t},i=Buffer.from(JSON.stringify(o)).toString("base64url"),s=on(i,n);return`${i}.${s}`}function sn(e,n,t){let r=Math.floor(Date.now()/1e3);return On(e,n,r+Math.floor(t/1e3))}function Ie(e){return decodeURIComponent(e)}function Bt(e){return encodeURIComponent(e).replace(/\./g,"%2E")}function xo(e){let n=e.trim();return n.length>0?n:null}function Ue(e,n){let t=new URL(e);return t.searchParams.set("d",n),t.toString()}function Be(e,n){if(!xo(n))throw new Error("Signing secret is required for browser delivery tokens");let t=Math.floor(Date.now()/1e3),r={...e,jti:e.jti??js(16).toString("base64url"),iat:t,exp:t+Math.floor(he/1e3)},o=Buffer.from(JSON.stringify(r)).toString("base64url"),i=on(o,n);return`${o}.${i}`}function ke(e,n){return xo(n)?ee(e,n):null}function qs(e){let n=Ft(e.hubOrigin),t={connectJti:e.requestId,projectId:e.projectId,hubSuccessUrl:e.hubOrigin,deliveryMode:e.deliveryMode,hubOrigin:n,requestId:e.requestId};switch(e.deliveryMode){case"connections.sync":return{...t,plugin:"connections.sync",tenantId:"*"};case"connect.create_link":return{...t,plugin:"connect.create_link",tenantId:e.tenantId,connectLinkPlugins:e.plugins}}}function Lt(e){let n=Be(qs(e),e.signingSecret);return Ue(e.deliveryUrl,n)}function Ro(e){if(rn(e.environmentSlug)==="server")return{transport:"server"};if(!e.hubOrigin)throw new Error(`hubOrigin is required for development ${e.deliveryMode} delivery`);let t=Ks(),r={...e,hubOrigin:e.hubOrigin,requestId:t};return{transport:"browser",requestId:t,deliveryUrl:Lt(r)}}var an="https://auth.corsair.dev";var se=class extends Error{constructor(){super("Hub is not configured. Pass hub: { projectApiKey, signingSecret } to createCorsair()."),this.name="HubNotConfiguredError"}};function Mn(e){let n=(e.apiUrl?.trim()||an).replace(/\/$/,""),t=e.projectApiKey.trim(),r=e.signingSecret.trim();if(!t||!r)throw new Error("Hub config requires non-empty projectApiKey and signingSecret");return{apiUrl:n,projectApiKey:t,signingSecret:r,oauthCallbackUrl:e.oauthCallbackUrl?.trim().replace(/\/$/,""),redirectURL:e.redirectURL?.trim()||void 0,allowWorkflowExecution:e.allowWorkflowExecution??!1,tunnel:e.tunnel}}function Zs(e){return e.apiUrl.trim().length>0&&e.projectApiKey.trim().length>0&&e.signingSecret.trim().length>0}function O(e){let n=w(e).hub;if(!n||!Zs(n))throw new se;return n}function Io(e){return e.replace(/\/$/,"")}function Hn(e){return e.oauthCallbackUrl?Io(e.oauthCallbackUrl.trim()):`${Io(e.apiUrl)}/oauth/callback`}function Le(e){if(e.startsWith("ck_dev_"))return"development";if(e.startsWith("ck_prod_"))return"production";throw new Error("Hub API key must start with ck_dev_ (development) or ck_prod_ (production)")}import{createCipheriv as So,createDecipheriv as _o,randomBytes as Fn,scrypt as Gs}from"crypto";import{promisify as zs}from"util";var Eo=zs(Gs),Un="aes-256-gcm",Do=12,Bn=16,Js=16,un=32;function ae(){return Fn(un).toString("base64")}async function ue(e,n){let t=Fn(Js),r=await Eo(n,t,un),o=Fn(Do),i=So(Un,r,o,{authTagLength:Bn}),s=Buffer.concat([i.update(e,"utf8"),i.final()]),a=i.getAuthTag();return[t.toString("base64"),o.toString("base64"),a.toString("base64"),s.toString("base64")].join(":")}async function Z(e,n){let[t,r,o,i]=e.split(":");if(!t||!r||!o||!i)throw new Error("Invalid encrypted DEK format");let s=Buffer.from(t,"base64"),a=Buffer.from(r,"base64"),u=Buffer.from(o,"base64"),l=Buffer.from(i,"base64"),c=await Eo(n,s,un),d=_o(Un,c,a,{authTagLength:Bn});return d.setAuthTag(u),Buffer.concat([d.update(l),d.final()]).toString("utf8")}function Nt(e,n){let t=Buffer.from(n,"base64"),r=Fn(Do),o=So(Un,t,r,{authTagLength:Bn}),i=Buffer.concat([o.update(e,"utf8"),o.final()]),s=o.getAuthTag();return[r.toString("base64"),s.toString("base64"),i.toString("base64")].join(":")}function cn(e,n){let[t,r,o]=e.split(":");if(!t||!r||!o)throw new Error("Invalid encrypted data format");let i=Buffer.from(n,"base64"),s=Buffer.from(t,"base64"),a=Buffer.from(r,"base64"),u=Buffer.from(o,"base64"),l=_o(Un,i,s,{authTagLength:Bn});return l.setAuthTag(a),Buffer.concat([l.update(u),l.final()]).toString("utf8")}function be(e,n){let t={};for(let[r,o]of Object.entries(e))t[r]=Nt(o,n);return t}function ce(e,n){let t={};for(let[r,o]of Object.entries(e))t[r]=cn(o,n);return t}function ln(e,n,t){let r=ce(e,n);return be(r,t)}function Oo(e,n,t){let r={};for(let o of t)r[`get_${o}`]=async()=>(await e())[o]??null,r[`set_${o}`]=async i=>{let s=[null,void 0,""].includes(i)?null:i;await n({[o]:s})};return r}var $t=e=>{if(!e)return{};if(typeof e=="string")try{return JSON.parse(e)}catch{return{}}return e};function M(e){let{authType:n,integrationName:t,kek:r,database:o,extraIntegrationFields:i=[]}=e,s=[...F[n].integration,...i],a=null,u={kek:r,integrationName:t,getIntegration:async()=>{if(a)return a;let h=await o.db.selectFrom("corsair_integrations").selectAll().where("name","=",t).executeTakeFirst();if(!h)throw new Error(`Integration "${t}" not found. Make sure to create the integration first.`);return a={id:h.id,config:$t(h.config),dek:h.dek??null},a},updateIntegration:async h=>{let m=await u.getIntegration();await o.db.updateTable("corsair_integrations").set({...h.config!==void 0?{config:h.config}:{},...h.dek!==void 0?{dek:h.dek}:{},updated_at:new Date}).where("id","=",m.id).execute(),a=null}},l=null,c=async()=>{if(l)return l;let h=await u.getIntegration();if(!h.dek)throw new Error(`No DEK found for integration "${t}". Initialize the integration first.`);return l=await Z(h.dek,r),l},d=async()=>{let h=await u.getIntegration(),m=await c(),b=h.config;return!b||Object.keys(b).length===0?{}:ce(b,m)},p=Promise.resolve(),g=h=>{let m=p.then(()=>f(h));return p=m.catch(()=>{}),m},f=async h=>{let m=await c(),b;try{b=await d()}catch(I){console.error(`[corsair] Failed to decrypt config for integration "${t}", starting fresh:`,I),b={}}let C={...b};for(let[I,E]of Object.entries(h))E===null?delete C[I]:C[I]=E;let _=be(C,m);await u.updateIntegration({config:_})};return{get_dek:c,issue_new_dek:async()=>{let h=await u.getIntegration(),m=ae(),b={};if(h.dek){let _=await Z(h.dek,r),I=h.config;I&&Object.keys(I).length>0&&(b=ln(I,_,m))}let C=await ue(m,r);return await u.updateIntegration({config:b,dek:C}),l=m,m},...Oo(d,g,s)}}function D(e){let{authType:n,integrationName:t,tenantId:r,kek:o,database:i,extraAccountFields:s=[],ensureProvisioned:a}=e,u=[...F[n].account,...s],l=null,c=null,d=async()=>{if(c)return c;let k=!1;for(;;){let v=await i.db.selectFrom("corsair_integrations").selectAll().where("name","=",t).executeTakeFirst();if(!v){if(!k&&a){k=!0,await a();continue}throw new Error(`Integration "${t}" not found. Make sure to create the integration first.`)}return c={id:v.id,config:$t(v.config),dek:v.dek??null},c}},p={kek:o,integrationName:t,tenantId:r,getIntegration:d,getAccount:async()=>{if(l)return l;let k=!1;for(;;){let v=await d(),P=await i.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",r).where("integration_id","=",v.id).executeTakeFirst();if(!P){if(!k&&a){k=!0,await a();continue}throw new Error(`Account not found for tenant "${r}" and integration "${t}". Make sure to create the account first.`)}return l={id:P.id,config:$t(P.config),dek:P.dek??null},l}},updateAccount:async k=>{let v=await p.getAccount();await i.db.updateTable("corsair_accounts").set({...k.config!==void 0?{config:k.config}:{},...k.dek!==void 0?{dek:k.dek}:{},updated_at:new Date}).where("id","=",v.id).execute(),l=null}},g=null,f=null,y=async()=>{if(g)return g;let k=await p.getAccount();if(!k.dek)throw new Error(`No DEK found for account (tenant: "${r}", integration: "${t}"). Initialize the account first.`);return g=await Z(k.dek,o),g},h=async()=>{if(f)return f;let k=await p.getIntegration();if(!k.dek)throw new Error(`No DEK found for integration "${t}". Initialize the integration first.`);return f=await Z(k.dek,o),f},m=async()=>{let k=await p.getAccount(),v=await y(),P=k.config;return!P||Object.keys(P).length===0?{}:ce(P,v)},b=async()=>{let k=await p.getIntegration(),v=await h(),P=k.config;return!P||Object.keys(P).length===0?{}:ce(P,v)},C=Promise.resolve(),_=k=>{let v=C.then(()=>I(k));return C=v.catch(()=>{}),v},I=async k=>{let v=await y(),P;try{P=await m()}catch(A){console.error(`[corsair] Failed to decrypt config for account (tenant: "${r}", integration: "${t}"), starting fresh:`,A),P={}}let j={...P};for(let[A,Y]of Object.entries(k))Y===null?delete j[A]:j[A]=Y;let re=be(j,v);await p.updateAccount({config:re})},E={get_dek:y,issue_new_dek:async()=>{let k=await p.getAccount(),v=ae(),P={};if(k.dek){let re=await Z(k.dek,o),A=k.config;A&&Object.keys(A).length>0&&(P=ln(A,re,v))}let j=await ue(v,o);return await p.updateAccount({config:P,dek:j}),g=v,v},...Oo(m,_,u)};return n==="oauth_2"&&(E.get_integration_credentials=async()=>{let k=await b();return{...k,client_id:k.client_id||null,client_secret:k.client_secret||null,redirect_url:k.redirect_url??null}}),E}async function Mo(e,n,t){let r=await e.db.selectFrom("corsair_integrations").selectAll().where("name","=",n).executeTakeFirst();if(!r)throw new Error(`Integration "${n}" not found.`);let o=ae(),i=await ue(o,t);return await e.db.updateTable("corsair_integrations").set({dek:i,updated_at:new Date}).where("id","=",r.id).execute(),o}async function Ho(e,n,t,r){let o=await e.db.selectFrom("corsair_integrations").selectAll().where("name","=",n).executeTakeFirst();if(!o)throw new Error(`Integration "${n}" not found.`);let i=await e.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",t).where("integration_id","=",o.id).executeTakeFirst();if(!i)throw new Error(`Account not found for tenant "${t}" and integration "${n}".`);let s=ae(),a=await ue(s,r);return await e.db.updateTable("corsair_accounts").set({dek:a,updated_at:new Date}).where("id","=",i.id).execute(),s}var Vs=new Set(["webhook_signature","expires_at","scope","redirect_url","refresh_token"]);function we(e){return Vs.has(e)}function Ys(e,n){return we(n)?!1:e==="oauth_2"?n==="client_id"||n==="client_secret":!0}function Qs(e){return!we(e)}function Xs(e){switch(e){case"oauth_2":case"managed":return["access_token"];case"api_key":return["api_key"];case"bot_token":return["bot_token"]}}function ea(e,n){return e!=="oauth_2"&&e!=="managed"?!1:n.some(t=>t.level==="account"&&t.name==="expires_at"&&t.configured)}function na(e,n){let t=i=>n.find(s=>s.level==="account"&&s.name===i);if(!Xs(e).every(i=>t(i)?.configured))return!1;let o=t("refresh_token");return o?.required?!!o.configured:!0}async function Fo(e,n){if(!e)return!1;let t=$(e,`get_${n}`);if(!t)return!1;try{let r=await t();return typeof r=="string"&&r.length>0}catch{return!1}}function ta(e,n){let r=e.authConfig?.[n]?.integration??[];return[...F[n].integration,...r]}function ra(e,n){let r=e.authConfig?.[n]?.account??[];return[...F[n].account,...r]}function oa(e,n,t){let r=t.filter(a=>a.required&&!a.configured).map(a=>a.name),o=t.filter(a=>a.level==="integration"&&a.required&&!a.configured).map(a=>a.name),i=t.filter(a=>a.level==="account"&&a.required&&a.configured),s;return o.length>0?s="missing_integration":r.length===0?s="ready":i.length>0?s="partial":s="not_started",{plugin:e,authType:n,status:s,connected:na(n,t),fields:t,missingRequiredFields:r}}async function Se(e,n,t){let r=T(n);if(!r||!e.database||!e.kek)return null;let o=t.trim()||"default",i=n.authConfig,s=i?.[r]?.integration??[],a=i?.[r]?.account??[],u=M({authType:r,integrationName:n.id,kek:e.kek,database:e.database,extraIntegrationFields:s}),l=D({authType:r,integrationName:n.id,tenantId:o,kek:e.kek,database:e.database,extraAccountFields:a}),c=ta(n,r),d=ra(n,r),p=[];for(let g of c)p.push({name:g,level:"integration",required:Ys(r,g),configured:await Fo(u,g)});for(let g of d)p.push({name:g,level:"account",required:Qs(g),configured:await Fo(l,g)});if(ea(r,p)){let g=p.find(f=>f.level==="account"&&f.name==="refresh_token");g&&(g.required=!0)}return oa(n.id,r,p)}async function dn(e,n,t={}){let r=n.trim()||"default",o=t.pluginIds?.length?new Set(t.pluginIds):null,i=[];for(let s of e.plugins){if(o&&!o.has(s.id))continue;let a=await Se(e,s,r);a&&i.push(a)}return i}function Ln(e){return e.connected?"connected":e.status==="missing_integration"?"missing_credentials":"not_connected"}var Uo=Symbol.for("corsair:internal"),Bo=new WeakMap,Lo=new WeakMap;function ia(e,n){let t=n.map(r=>r.id).sort().join("\0");return`${e}\0${t}`}function sa(e){if(e.database){let t=Bo.get(e.database);return t||(t=new Map,Bo.set(e.database,t)),t}let n=Lo.get(e);return n||(n=new Map,Lo.set(e,n)),n}function aa(e){return e.multiTenancy?{withTenant:()=>({}),[Uo]:e}:{[Uo]:e}}async function Ne(e,n){if(!e.database)return;let t=n.trim()||"default",r=sa(e),o=ia(t,e.plugins),i=r.get(o);if(i){await i;return}let s=(async()=>{let{setupCorsair:a}=await import("./setup-DZKKWGRZ.js");await a(aa(e),{tenantId:e.multiTenancy?t:void 0,silent:!0})})().finally(()=>{r.delete(o)});r.set(o,s),await s}import*as pn from"crypto";function Ce(e,n){return Buffer.from(JSON.stringify({plugin:e,tenantId:n,iat:Date.now()})).toString("base64url")}function Wt(e,{maxAgeMs:n}={}){try{let t=e.includes(".")?e.split(".")[0]:e,r=JSON.parse(Buffer.from(t,"base64url").toString("utf-8"));if(r!==null&&typeof r=="object"&&"plugin"in r&&"tenantId"in r&&typeof r.plugin=="string"&&typeof r.tenantId=="string"){let o=r;return n!==void 0&&typeof o.iat=="number"&&Date.now()-o.iat>n?null:o}return null}catch{return null}}function $e(e,n){let t=pn.createHmac("sha256",n).update(e).digest("base64url");return`${e}.${t}`}var jt=600*1e3;function Nn(e,n){let t=e.lastIndexOf(".");if(t===-1)return null;let r=e.slice(0,t),o=e.slice(t+1),i=pn.createHmac("sha256",n).update(r).digest("base64url"),s=Buffer.from(o,"base64url"),a=Buffer.from(i,"base64url");return s.length!==a.length||!pn.timingSafeEqual(s,a)?null:Wt(r,{maxAgeMs:jt})}function No(e){return{tenantId:e.tenantId,plugin:e.plugin,authType:e.authType??"oauth_2",status:"ready",connected:!0,verified:!0,webhookLink:e.link}}function $o(e){return{tenantId:e.tenantId,plugin:e.plugin,authType:e.authType,status:e.status,connected:e.connected,verified:e.verified,missingFields:e.missingFields,webhookLink:e.webhookLink,webhookSecret:e.webhookSecret}}async function We(e,n){await R({hub:e,path:"/connections/report",body:No(n),parseResponse:()=>({ok:!0})}).catch(()=>{})}function ua(e,n){try{let t=O(e);R({hub:t,path:"/connections/report",body:n,parseResponse:()=>({ok:!0})}).catch(()=>{})}catch(t){if(t instanceof se)return}}async function ca(e){if(!e.hub||!e.database||!e.kek)return;let n={database:e.database,kek:e.kek,plugins:e.plugins};if(!T(e.plugin))return;let r=e.tenantId?.trim()||"default",o=await Se(n,e.plugin,r);o&&jo(e.hub,$o({tenantId:r,plugin:e.plugin.id,authType:o.authType,status:o.status,connected:o.connected,verified:e.verified??o.connected,missingFields:o.missingRequiredFields}))}function Wo(e,n){ua(e,n)}function jo(e,n){R({hub:e,path:"/connections/report",body:n,parseResponse:()=>({ok:!0})}).catch(()=>{})}function gn(e){ca(e).catch(()=>{})}async function le(e,n){let t=w(e);if(!T(n.plugin))return;let o=await Se(t,n.plugin,n.tenantId);o&&Wo(e,$o({tenantId:n.tenantId.trim()||"default",plugin:n.plugin.id,authType:o.authType,status:o.status,connected:o.connected,verified:n.verified??o.connected,missingFields:o.missingRequiredFields,webhookLink:n.webhookLink,webhookSecret:n.webhookSecret}))}async function $n(e,n,t){for(let r of e){if(r.id!==n)continue;let o=r.oauthWebhookTenantLinkResolver;return o?o(t):null}return null}var Ko=e=>{if(!e)return{};if(typeof e=="string")try{return JSON.parse(e)}catch{return{}}return e};async function la(e){let n=await e.database.db.selectFrom("corsair_integrations").selectAll().where("name","=",e.pluginId).executeTakeFirst();if(!n)throw new Error(`Integration '${e.pluginId}' not found. Run setupCorsair before registering webhook tenant links.`);let t=await e.database.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",e.tenantId).where("integration_id","=",n.id).executeTakeFirst();if(!t)throw new Error(`Account not found for tenant '${e.tenantId}' and integration '${e.pluginId}'.`);return{integrationId:n.id,accountId:t.id}}async function da(e){let n=await e.database.db.selectFrom("corsair_accounts").selectAll().where("id","=",e.accountId).executeTakeFirst();if(!n?.dek)throw new Error(`Account '${e.accountId}' has no DEK.`);let t=await Z(n.dek,e.kek),r=Ko(n.config),o={};Object.keys(r).length>0&&(o=ce(r,t)),o[e.link.linkType]=e.link.externalId;let i=be(o,t);await e.database.db.updateTable("corsair_accounts").set({config:i,updated_at:new Date}).where("id","=",n.id).execute()}async function je(e){let{database:n,kek:t,pluginId:r,tenantId:o,link:i,authType:s,extraAccountFields:a=[]}=e,{accountId:u}=await la({database:n,pluginId:r,tenantId:o}),l=!1;if(s){let c=D({authType:s,integrationName:r,tenantId:o,kek:t,database:n,extraAccountFields:a}),d=`set_${i.linkType}`,p=c[d];typeof p=="function"&&(await p(i.externalId),l=!0)}l||await da({database:n,kek:t,accountId:u,link:i})}async function Kt(e){let{database:n,kek:t,pluginId:r,linkType:o,externalId:i}=e,s=await n.db.selectFrom("corsair_accounts as accounts").innerJoin("corsair_integrations as integrations","integrations.id","accounts.integration_id").selectAll("accounts").where("integrations.name","=",r).execute();for(let a of s)if(a.dek)try{let u=await Z(a.dek,t),c=Ko(a.config)[o];if(!c)continue;if(cn(c,u)===i)return a}catch{continue}return null}async function Wn(e){return(await Kt(e))?.tenant_id??null}async function qo(e){return Wn({database:e.database,kek:e.kek,pluginId:e.pluginId,linkType:e.match.linkType,externalId:e.match.externalId})}import*as Zo from"querystring";function _e(e){let{oauthConfig:n,clientId:t,redirectUri:r,state:o}=e,i={...n.authParams,client_id:t,redirect_uri:r,response_type:"code",scope:n.scopes.join(" "),state:o};return`${n.authUrl}?${Zo.stringify(i)}`}async function Go(e,n){try{return await U({hub:e,path:`/webhooks/endpoint?plugin=${encodeURIComponent(n)}`,parseResponse:t=>t?.url??null})}catch{return null}}async function Ke(e,n,t,r){if(!n.subscribe)return;let o=O(e),i=await Go(o,n.id);if(!i)return;let s=await n.subscribe({keys:r},{webhookUrl:i});s&&await le(e,{plugin:n,tenantId:t,verified:!0,webhookLink:s.webhookLink,webhookSecret:s.webhookSecret})}var L=class extends Error{code;constructor(n,t){super(t),this.name="OAuthCallbackError",this.code=n}};function zo(e){let n=e.oauthConfig;if(!n)throw new L("plugin_has_no_oauth_config",`Plugin '${e.id}' has no oauthConfig`);return n}async function pa(e,n,t,r){let o=mo(e),i=await o.integrations.findByName(n);if(!i)throw new Error(`Integration '${n}' not found. Run setupCorsair first.`);if(await o.accounts.findOne({tenant_id:t,integration_id:i.id}))return;let a=ae(),u=await ue(a,r);await o.accounts.create({tenant_id:t,integration_id:i.id,config:{},dek:u})}async function qt(e,n,t){let{tenantId:r,redirectUri:o,hubConnect:i=!1}=t,s=w(e,()=>new L("invalid_corsair_instance","Invalid corsair instance"));if(!s.database)throw new Error("No database configured on corsair instance");let a=B(s,n,p=>new L("plugin_not_found",p)),u=zo(a),c=await M({authType:"oauth_2",integrationName:n,kek:s.kek,database:s.database}).get_client_id();if(!c)throw new Error(`client_id not configured for '${n}'`);if(i){let p=new URL(_e({oauthConfig:u,clientId:c,redirectUri:o,state:""}));return p.searchParams.delete("state"),{url:p.toString(),state:""}}let d=$e(Ce(n,r),s.kek);return{url:_e({oauthConfig:u,clientId:c,redirectUri:o,state:d}),state:d}}function ga(e,n){return{...n??{},...e}}async function fn(e,n){let{code:t,state:r,redirectUri:o}=n,i=w(e,()=>new L("invalid_corsair_instance","Invalid corsair instance")),s,a;if(n.trusted){if(!n.plugin||!n.tenantId)throw new L("invalid_state","trusted callback requires plugin and tenantId");s=n.plugin,a=n.tenantId}else{let y=Nn(r,i.kek);if(!y)throw new L("invalid_state","Invalid or tampered state parameter");s=y.plugin,a=y.tenantId}if(!i.database)throw new L("no_database","No database configured on corsair instance");let u=B(i,s,y=>new L("plugin_not_found",y)),l=zo(u),c=M({authType:"oauth_2",integrationName:s,kek:i.kek,database:i.database}),d=await c.get_client_id(),p=await c.get_client_secret();if(!d||!p)throw new L("credentials_not_configured",`Credentials not configured for '${s}'`);await pa(i.database,s,a,i.kek);let g=await jn(t,d,p,l,o);if(!g.access_token)throw new L("no_access_token",`No access_token returned from ${l.providerName}`);let f=D({authType:"oauth_2",integrationName:s,tenantId:a,kek:i.kek,database:i.database,extraAccountFields:[...u.authConfig?.oauth_2?.account??[]]});await f.set_access_token(g.access_token),g.refresh_token&&await f.set_refresh_token(g.refresh_token),g.expires_in&&await f.set_expires_at(String(Math.floor(Date.now()/1e3)+g.expires_in)),await le(e,{plugin:u,tenantId:a}).catch(()=>{});try{let y=ga(g,n.callbackParams),h=await $n(i.plugins,s,y);if(h){try{let m=u.authConfig?.oauth_2?.account??[];await je({database:i.database,kek:i.kek,pluginId:s,tenantId:a,link:h,authType:"oauth_2",extraAccountFields:m})}catch(m){console.warn(`[corsair:oauth] Failed to persist webhook tenant link for '${s}' tenant '${a}':`,m)}i.hub&&We(i.hub,{plugin:s,tenantId:a,link:h,authType:"oauth_2"})}}catch(y){console.warn(`[corsair:oauth] Failed to resolve webhook tenant link for '${s}' tenant '${a}':`,y)}if(u.subscribe)try{await Ke(e,u,a,f)}catch(y){console.warn(`[corsair:oauth] BYO subscribe failed for '${s}' tenant '${a}':`,y)}return{plugin:s,tenantId:a}}async function fa(e){let{corsair:n,internal:t,rows:r}=e,o=e.subscribeAndReport??Ke,i=[],s=[];if(!t.database)return{renewed:i,failed:s};for(let a of r){let u=t.plugins.find(c=>c.id===a.integrationName);if(!u?.subscribe)continue;let l=`${u.id}/${a.tenantId}`;try{let c=T(u)??"oauth_2",d=D({authType:c,integrationName:u.id,tenantId:a.tenantId,kek:t.kek,database:t.database,extraAccountFields:[...u.authConfig?.[c]?.account??[]]}),p=u.keyBuilder;if(p){let g=Object.create(d,{get_expires_at:{value:async()=>"0"}});await p({authType:c,keys:g,hub:t.hub},"endpoint")}await o(n,u,a.tenantId,d),i.push(l)}catch(c){console.warn(`[corsair:renewal] re-subscribe failed for '${l}':`,c),s.push(l)}}return{renewed:i,failed:s}}async function Jo(e){let n=w(e);if(!n.database)return{renewed:[],failed:[]};let t=await n.database.db.selectFrom("corsair_accounts as a").innerJoin("corsair_integrations as i","i.id","a.integration_id").select(["a.tenant_id as tenantId","i.name as integrationName"]).where("a.dek","is not",null).execute();return fa({corsair:e,internal:n,rows:t.filter(r=>!!r.tenantId)})}function ya(e,n={}){let t=!1,r=()=>{t||(t=!0,Jo(e).catch(i=>console.warn("[corsair:renewal] renewal pass failed:",i)).finally(()=>{t=!1}))};r();let o=setInterval(r,(n.intervalMinutes??45)*6e4);return o.unref?.(),()=>clearInterval(o)}async function Vo(e){if(!w(e).database)throw new Error("A database must be configured to provision Corsair integrations");await Kn(e,{silent:!0})}async function qe(e,n){let t=w(e);if(!t.database)throw new Error("A database must be configured to provision Corsair for connect");await Ne(t,n)}var ma=Symbol.for("corsair:internal"),ha=new Set(["access_token","refresh_token","expires_at","scope"]);function ka(e){return e==="oauth_2"||e==="managed"?"oauth":e==="bot_token"?"bot_token":"api_key"}function ba(e,n){return e==="oauth_2"||e==="managed"?n.filter(t=>!we(t)&&!ha.has(t)):n.filter(t=>!we(t))}function Yo(e){return{plugins:e.plugins,database:e.database,kek:e.kek,multiTenancy:e.multiTenancy??!1}}function wa(e){return{plugins:e.plugins,database:e.database,kek:e.kek,multiTenancy:e.multiTenancy??!1}}function Ca(e){return{[ma]:Yo(e)}}async function qn(e,n,t={}){let r=Hn(e.hub),o=[],i=t.pluginIds?new Set(t.pluginIds):null,s=Yo(e),a=Ca(e);for(let u of e.plugins){if(i&&!i.has(u.id))continue;let l=T(u);if(!l)continue;let c=ka(l),d=t.providerNameOverrides?.[u.id]??me(u.id),p=await Se(s,u,n),g=An(u,l),f=ba(l,g),y={plugin:u.id,providerName:d,authKind:c,alreadyConfigured:p?.connected??!1};if(f.length>0&&(y.credentialFields=f),c==="oauth"){let m=t.oauthModeOverrides?.[u.id]??(l==="managed"?"managed":"byo");if(y.oauthMode=m,!t.skipOAuthUrlGeneration&&m!=="managed")try{let b=await qt(a,u.id,{tenantId:n,redirectUri:r,hubConnect:!0});y.oauthUrl=b.url}catch(b){y.setupError=b instanceof Error?b.message:`Could not prepare OAuth for ${u.id}`}}o.push(y)}return o}async function Td(e,n,t={}){let r=w(e),o=r.hub;if(!o)throw new Error("Hub is not configured");return qn({plugins:r.plugins,database:r.database,kek:r.kek,hub:o},n,t)}async function Qo(e,n){if(!e.database)throw new Error("A database must be configured to provision Corsair for connect");await Ne(e.internalConfig??wa(e),n)}async function Xo(e,n){await qe(e,n)}async function ei(e,n){let t=Le(e.projectApiKey),r={tenantId:n.tenantId,plugins:n.plugins};return e.redirectURL&&(r.redirectUri=e.redirectURL),t==="development"&&(r.deliveryUrl=fe({deliveryUrl:n.deliveryUrl})),R({hub:e,path:"/connect/sessions",notFoundMessage:"Hub REST API not found at /connect/sessions. Check HUB_API_URL and ensure the Hub API is deployed.",body:r,parseResponse:Rn})}async function Zt(e,n){let t={plugins:n.plugins,database:n.database,kek:n.kek,hub:e,multiTenancy:n.multiTenancy};await Qo(t,n.tenantId);let r=await qn(t,n.tenantId,{pluginIds:[n.plugin.id]});if(r.length===0)throw new Error(`Plugin '${n.plugin.id}' is not configured on this Corsair instance`);return ei(e,{tenantId:n.tenantId,plugins:r,deliveryUrl:n.deliveryUrl})}async function Zn(e,n){let t=w(e),r=O(e),o={plugins:t.plugins,database:t.database,kek:t.kek,hub:r,multiTenancy:t.multiTenancy,internalConfig:t};await Xo(e,n.tenantId);let i=n.plugin?[n.plugin]:void 0,s=n.plugin&&n.oauthMode?{[n.plugin]:n.oauthMode}:void 0,a=n.plugin&&n.providerName?{[n.plugin]:n.providerName}:void 0,u=await qn(o,n.tenantId,{pluginIds:i,oauthModeOverrides:s,providerNameOverrides:a});if(u.length===0)throw new Error(n.plugin?`Plugin '${n.plugin}' is not configured on this Corsair instance`:"No plugins are configured on this Corsair instance");return ei(r,{tenantId:n.tenantId,plugins:u,deliveryUrl:n.deliveryUrl})}async function Gn(e,n){let t=n.tenantId.trim();if(!t)throw new Error("tenantId is required");let r=n.plugins.map(s=>s.trim()).filter(Boolean);if(r.length===0)throw new Error("At least one plugin is required");let o=w(e);if(!o.hub)throw new Error("Hub is not configured on this Corsair instance");if(!o.database)throw new Error("Database not configured");let i=await va(o.hub,{plugins:o.plugins,database:o.database,kek:o.kek,multiTenancy:o.multiTenancy},{tenantId:t,pluginIds:r});return{connectUrl:i.connectUrl,expiresAt:i.expiresAt}}async function va(e,n,t){let{buildConnectPluginManifestFromContext:r,ensureConnectAccountRowsFromContext:o}=await import("./setup-introspect-WIGEWC7Z.js"),{postHubConnectSession:i}=await import("./connect-ZKP43YRG.js"),s={plugins:n.plugins,database:n.database,kek:n.kek,hub:e,multiTenancy:n.multiTenancy};await o(s,t.tenantId);let a=await r(s,t.tenantId,{pluginIds:t.pluginIds});if(a.length===0)throw new Error("No connectable plugins found for this tenant");let u=a.find(l=>l.setupError);if(u)throw new Error(u.setupError??`Could not prepare connect link for ${u.plugin}`);return i(e,{tenantId:t.tenantId,plugins:a})}function Ze(e){return!!(e?.baseUrl?.trim()&&e?.redirectUri?.trim())}var G=class extends Error{code;constructor(n,t){super(t),this.name="ConnectError",this.code=n}};function Pa(e){let n=e.oauthConfig;if(!n)throw new G("plugin_has_no_oauth_config",`Plugin '${e.id}' has no oauthConfig`);return n}async function Gt(e,n){let t=w(e,()=>new G("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new G("no_database","No database configured on corsair instance");let r=t.manual?.redirectUri;if(!r)throw new G("no_redirect_uri","No redirectUri configured. Set manual.redirectUri in createCorsair().");let o=Nn(n,t.kek);if(!o)throw new G("invalid_state","Invalid or tampered state parameter");let{plugin:i,tenantId:s}=o,a=B(t,i,p=>new G("plugin_not_found",p)),u=Pa(a),c=await M({authType:"oauth_2",integrationName:i,kek:t.kek,database:t.database}).get_client_id();if(!c)throw new G("client_id_not_configured",`client_id not configured for '${i}'`);let d=_e({oauthConfig:u,clientId:c,redirectUri:r,state:n});return{plugin:i,tenantId:s,providerName:u.providerName,oauthUrl:d,state:n}}import{AsyncLocalStorage as Aa}from"async_hooks";import{randomBytes as xa}from"crypto";import{v4 as Ra}from"uuid";async function zn(e,n){let t=Le(e.projectApiKey),r={permissionId:n.permissionId,permissionToken:n.permissionToken,plugin:n.plugin,endpoint:n.endpoint,args:n.args,tenantId:n.tenantId,expiresAt:n.expiresAt};return e.redirectURL&&(r.redirectUri=e.redirectURL),t==="development"&&(r.deliveryUrl=fe({deliveryUrl:n.deliveryUrl})),R({hub:e,path:"/permission/sessions",notFoundMessage:"Hub REST API not found at /permission/sessions. Check HUB_API_URL and ensure the Hub API is deployed.",body:r,parseResponse:Sn})}function Jn(e){return`Approval required. Visit ${e} to approve or deny, then tell the agent to retry this action.`}var zt="Permission approval required. Set manual.approvalBaseUrl (or use hub for hosted approval) so an approval URL can be generated. Optionally set manual.onApprovalRequired to customize the agent message.";function Vt(e){return e?e.approvalBaseUrl!==void 0||e.onApprovalRequired!==void 0:!1}function ni(e,n){return`${e.replace(/\/+$/,"")}/${n}`}function Jt(e){return Jn(e)}async function Yt(e,n){if(Vt(e.manual)){let r=e.manual?.approvalBaseUrl?.trim();return r?ni(r,n.token):null}let t=e.hub;if(!t)return null;try{return(await zn(t,{permissionId:n.id,permissionToken:n.token,plugin:n.plugin,endpoint:n.endpoint,args:Ta(n.args),tenantId:n.tenant_id,expiresAt:n.expires_at})).approvalUrl}catch{return null}}function Ta(e){try{return JSON.parse(e)}catch{return e}}async function Vn(e,n){if(!(n.status==="pending"||n.status==="approved"))return{...n,approvalUrl:null};let r=await Yt(e,n);return{...n,approvalUrl:r}}async function Qt(e){let{permissionsOptions:n,manual:t,hub:r,permissionId:o,permissionToken:i,plugin:s,endpoint:a,args:u,tenantId:l,expiresAt:c,operationPath:d}=e;if(n?.formatAsyncMessage)return n.formatAsyncMessage({token:i,id:o,plugin:s,endpoint:a,args:u});let g=await Yt({manual:t,hub:r},{id:o,token:i,plugin:s,endpoint:a,args:JSON.stringify(u),tenant_id:l,expires_at:c});return Vt(t)?g?t?.onApprovalRequired?t.onApprovalRequired({approvalUrl:g}):Jt(g):zt:r?g?Jt(g):`Action '${d}' requires user approval before it can run. Could not create approval link. Check hub configuration and server logs.`:zt}var Ge=class extends Error{constructor(n){super(n),Object.setPrototypeOf(this,new.target.prototype),this.name="PermissionRequiredError"}};var ri=new Aa,Yn=class extends Error{endpointPath;riskLevel;constructor(n,t){super(`Action '${n}' is a '${t}' operation and is forbidden in readonly mode. Only read operations are permitted \u2014 rewrite the script to avoid write/destructive actions.`),this.name="ReadonlyForbiddenError",this.endpointPath=n,this.riskLevel=t}};function Xt(e){return ri.run(!0,e)}function oi(){return ri.getStore()===!0}function er(e,n){if(oi()&&n!=="read")throw new Yn(e,n)}var Ia={open:{read:"allow",write:"allow",destructive:"allow"},cautious:{read:"allow",write:"allow",destructive:"require_approval"},strict:{read:"allow",write:"require_approval",destructive:"deny"},readonly:{read:"allow",write:"deny",destructive:"deny"}};function Sa(e,n,t){return t!==void 0?t:Ia[n][e]}function nr(e){let n=/(\d+)(d|h|m|s)/g,t=0,r;for(;(r=n.exec(e))!==null;){let o=parseInt(r[1],10);switch(r[2]){case"d":t+=o*864e5;break;case"h":t+=o*36e5;break;case"m":t+=o*6e4;break;case"s":t+=o*1e3;break}}return t>0?t:600*1e3}function ii(e){return{async find_by_permission_id(n){if(e)return e.db.selectFrom("corsair_permissions").selectAll().where("id","=",n).executeTakeFirst()},async find_by_token(n){if(e)return e.db.selectFrom("corsair_permissions").selectAll().where("token","=",n).executeTakeFirst()},async set_executing(n){e&&await e.db.updateTable("corsair_permissions").set({status:"executing",updated_at:new Date}).where("id","=",n).execute()},async set_completed(n){e&&await e.db.updateTable("corsair_permissions").set({status:"completed",updated_at:new Date}).where("id","=",n).execute()}}}async function ti(e,n,t){let r=Date.now()+t;for(;Date.now()<r;){let o=await e.db.selectFrom("corsair_permissions").select(["id","status"]).where("id","=",n).executeTakeFirst();if(!o)return{result:"blocked",reason:"pending"};if(o.status==="approved")return{result:"allow",onComplete:async()=>{await e.db.updateTable("corsair_permissions").set({status:"completed",updated_at:new Date}).where("id","=",n).execute()}};if(o.status==="denied")return{result:"blocked",reason:"denied"};if(o.status==="expired"||o.status==="failed")return{result:"blocked",reason:"timeout"};await new Promise(i=>setTimeout(i,500))}return{result:"blocked",reason:"timeout"}}async function si(e){let n=Sa(e.riskLevel,e.mode,e.override);if(n==="allow")return{result:"allow"};let t=e.meta?.irreversible?" (irreversible)":"",r=e.meta?.description?`${e.meta.description}${t}`:`${e.pluginId}.${e.endpointPath}${t}`;if(n==="deny"||!e.db)return console.log(`[corsair/${e.pluginId}] '${e.endpointPath}' blocked \u2014 denied by permission mode '${e.mode}'.`,`
|
|
10
|
+
Action: ${r}`,`
|
|
11
|
+
To allow this, update the permission mode or add an override in your corsair config.`),{result:"blocked",reason:"policy"};let o=JSON.stringify(e.args),i=new Date().toISOString(),s=e.tenantId??"default",a=await e.db.db.selectFrom("corsair_permissions").selectAll().where("plugin","=",e.pluginId).where("endpoint","=",e.endpointPath).where("args","=",o).where("tenant_id","=",s).where("expires_at",">",i).where("status","in",["pending","approved","executing"]).orderBy("created_at","desc").limit(1).executeTakeFirst();if(a){if(a.status==="approved"){let f=e.db,y=a.id;return{result:"allow",onComplete:async()=>{await f.db.updateTable("corsair_permissions").set({status:"completed",updated_at:new Date}).where("id","=",y).execute()}}}return a.status==="executing"?{result:"allow"}:(console.log(`[corsair/${e.pluginId}] '${e.endpointPath}' blocked \u2014 approval already pending.`,`
|
|
12
|
+
Action: ${r}`,`
|
|
13
|
+
Permission ID: ${a.id}`,`
|
|
14
|
+
Use the token to approve or deny this request.`),(typeof e.approvalMode=="function"?e.approvalMode():e.approvalMode)==="synchronous"?ti(e.db,a.id,e.timeoutMs??600*1e3):{result:"blocked",reason:"pending",id:a.id,token:a.token,expiresAt:a.expires_at})}let u=Ra(),l=xa(32).toString("hex"),c=e.timeoutMs??600*1e3,d=new Date(Date.now()+c).toISOString();return await e.db.db.insertInto("corsair_permissions").values({id:u,created_at:new Date,updated_at:new Date,token:l,plugin:e.pluginId,endpoint:e.endpointPath,args:o,tenant_id:s,status:"pending",expires_at:d}).execute(),console.log(`[corsair/${e.pluginId}] '${e.endpointPath}' blocked \u2014 approval required.`,`
|
|
15
|
+
Action: ${r}`,`
|
|
16
|
+
Permission ID: ${u}`,`
|
|
17
|
+
Permission token: ${l}`,`
|
|
18
|
+
Expires at: ${d}`,`
|
|
19
|
+
Use the token to approve or deny this request.`),(typeof e.approvalMode=="function"?e.approvalMode():e.approvalMode)==="synchronous"?ti(e.db,u,c):{result:"blocked",reason:"pending",id:u,token:l,expiresAt:d}}var S=class extends Error{status;code;extra;constructor(n,t,r,o={}){super(r??t),this.name="ManagementApiError",this.status=n,this.code=t,this.extra=o}};function H(e,n){return new Response(JSON.stringify(n),{status:e,headers:{"content-type":"application/json"}})}function ai(e){let n={error:e.code,message:e.message,...e.extra};return H(e.status,n)}function ve(e){return new S(404,"not_found",e)}function de(e,n={}){return new S(400,"bad_request",e,n)}function ui(e,n){return B(e,n,t=>ve(t))}async function ci(e,n){let t=e.options?.authType;if(!t||!n.database||!n.kek)return{configured:!1,missingFields:[]};let r=M({authType:t,integrationName:e.id,kek:n.kek,database:n.database}),o=F[t].integration,i=r,s;try{s=await Promise.all(o.map(l=>i[`get_${l}`]()))}catch{s=o.map(()=>null)}let a=o.filter((l,c)=>s[c]==null),u;return t==="oauth_2"?u=!a.includes("client_id")&&!a.includes("client_secret"):u=a.length===0,{configured:u,missingFields:a}}async function li(e,n){let t=e.options?.authType??null,r=e.oauthConfig,{configured:o,missingFields:i}=await ci(e,n);return{id:e.id,authType:t,configured:o,missingFields:i,oauth:r?{providerName:r.providerName,scopes:r.scopes,requiresRegisteredRedirect:!!r.requiresRegisteredRedirect}:null}}function Qn(){return{ok:!0}}async function ze(e){return Promise.all(e.plugins.map(n=>li(n,e)))}async function Xn(e,n){let t=ui(e,n);return li(t,e)}async function _a(e,n){return e.database?(await e.database.db.selectFrom("corsair_accounts as a").innerJoin("corsair_integrations as i","i.id","a.integration_id").select(["a.id as accountId","a.dek as dek","i.name as integrationName"]).where("a.tenant_id","=",n).execute()).map(r=>({integrationName:r.integrationName,hasCredentials:!!r.dek})):[]}async function di(e,n){let t=await _a(e,n),r=t.filter(o=>o.hasCredentials).map(o=>o.integrationName);return{id:n,accounts:t,connectedPlugins:r}}async function Je(e){let n=new Map;if(n.set("default",{id:"default",accounts:[],connectedPlugins:[]}),e.database){let t=await e.database.db.selectFrom("corsair_accounts as a").innerJoin("corsair_integrations as i","i.id","a.integration_id").select(["a.tenant_id","a.dek as dek","i.name as integrationName"]).execute();for(let r of t){let o=r.tenant_id;if(!o)continue;let i=n.get(o);i||(i={id:o,accounts:[],connectedPlugins:[]},n.set(o,i));let s=!!r.dek;i.accounts.push({integrationName:r.integrationName,hasCredentials:s}),s&&i.connectedPlugins.push(r.integrationName)}}return[...n.values()]}async function et(e,n){if(!n)throw de("Tenant id must be a non-empty string");return di(e,n)}async function nt(e,n){let t=n?.id?.trim();if(!t)throw de("Tenant id is required",{missingFields:["id"]});return di(e,t)}async function tt(e,n){let t=n?.trim()||"default",r={},o=await dn(e,t);for(let i of o)r[i.plugin]=Ln(i);for(let i of e.plugins)i.id in r||(!i.options?.authType||!e.database||!e.kek?r[i.id]="missing_credentials":r[i.id]="not_connected");return r}async function tr(e,n){if(!e.database)throw ve(`Permission '${n}' not found`);let t=await e.database.db.selectFrom("corsair_permissions").selectAll().where("id","=",n).executeTakeFirst();if(!t)throw ve(`Permission '${n}' not found`);return Vn(e,t)}function Ea(e){if(!e.oauthConfig)throw de(`Plugin '${e.id}' has no oauthConfig`)}function Da(e){if(!e.manual)throw new S(500,"connect_not_configured","createCorsair was not given manual config. Set { manual: { baseUrl, redirectUri } } to enable manual connect routes.");return e.manual}function rr(e){let n=Da(e);if(!n.baseUrl?.trim()||!n.redirectUri?.trim())throw new S(500,"connect_not_configured","Manual connect requires manual.baseUrl and manual.redirectUri. Use hub for hosted connect, or set both URLs for manual OAuth.");return n}function Oa(e){let n=!!e.hub,t=Ze(e.manual);if(!n&&!t)throw new S(500,"connect_not_configured","createCorsair was not given connect config. Set hub: { ... } for Hub mode, or manual: { baseUrl, redirectUri } for manual connect.")}function pi(e){if(!e.database||!e.kek)throw new S(500,"database_not_configured","A database and kek are required to issue connect links.")}async function Ma(e,n){let t=n?.plugin?.trim();if(!t)throw de("Plugin id is required",{missingFields:["plugin"]});let r=n.tenantId?.trim()||"default",o=ui(e,t);Ea(o);let i=rr(e);pi(e);let s=await ci(o,e);if(!s.configured)throw new S(400,"missing_credentials",`Plugin '${t}' is missing OAuth client credentials`,{missingFields:s.missingFields});let a=$e(Ce(t,r),e.kek),u;try{u=new URL(i.baseUrl)}catch{throw new S(500,"connect_misconfigured","manual.baseUrl is not a valid URL. Set a full URL including protocol (e.g. https://app.example.com/connect).")}return u.searchParams.set("state",a),{connectUrl:u.toString(),expiresAt:new Date(Date.now()+jt).toISOString()}}async function Ha(e,n,t){pi(n);let o={tenantId:t.tenantId?.trim()||"default",oauthMode:t.oauthMode},i=t.plugin?.trim();i&&(o.plugin=i);let s=t.providerName?.trim();s&&(o.providerName=s);let a=await Zn(e,o);return{connectUrl:a.connectUrl,expiresAt:a.expiresAt}}async function rt(e,n,t){return Oa(n),n.hub?Ha(e,n,t):Ma(n,t)}async function ot(e,n,t){if(n.hub&&!Ze(n.manual))throw new S(400,"hub_mode","resolve is not used with hub config. Redirect users to connectUrl from createLink.");let r=t?.trim();if(!r)throw de("state is required",{missingFields:["state"]});rr(n);try{return await Gt(e,r)}catch(o){if(o instanceof G)switch(o.code){case"invalid_state":throw de("Invalid or expired state");case"client_id_not_configured":throw new S(400,"missing_credentials","OAuth client_id is not configured for this plugin",{missingFields:["client_id"]});case"no_redirect_uri":break}throw new S(500,"resolve_failed","Could not resolve connect link. Check server logs for details.")}}async function it(e,n,t){if(n.hub&&!Ze(n.manual))throw new S(400,"hub_mode","oauthCallback is not used with hub config. Hub delivers tokens to your deliveryUrl.");let r=t?.code?.trim(),o=t?.state?.trim(),i=[];if(r||i.push("code"),o||i.push("state"),i.length)throw de("Missing required fields",{missingFields:i});let s=rr(n),{processOAuthCallback:a}=await import("./oauth.js");try{return await a(e,{code:r,state:o,redirectUri:s.redirectUri,callbackParams:t.callbackParams})}catch(u){if(u instanceof Error&&u.name==="OAuthCallbackError")switch(u.code){case"invalid_state":throw de("Invalid or expired state");case"credentials_not_configured":throw new S(400,"missing_credentials","OAuth client credentials are not configured for this plugin",{missingFields:["client_id","client_secret"]})}throw new S(502,"oauth_callback_failed","OAuth callback did not complete. Check server logs for details.")}}async function or(e,n){if(!e.database)throw ve("Permission not found");let t=await e.database.db.selectFrom("corsair_permissions").selectAll().where("token","=",n).executeTakeFirst();if(!t)throw ve("Permission not found");return Vn(e,t)}async function gi(e,n){return"id"in n?tr(e,n.id):or(e,n.token)}import{createCipheriv as Wa,createDecipheriv as hp,randomBytes as hi,scryptSync as ja}from"crypto";import{createHmac as ir,randomUUID as Fa,timingSafeEqual as yi}from"crypto";function sr(e){return e.run??null}function ar(e){return e.probe??null}function mi(e){if(e)return e.startsWith("sha256=")?e.slice(7):e}function st(e){let n=JSON.stringify({type:e.type,payload:e.payload}),t=Math.floor(Date.now()/1e3).toString(),r=ir("sha256",e.signingSecret.trim()).update(n).digest("hex");return{body:n,headers:{"content-type":"application/json","x-corsair-signature":`sha256=${r}`,"x-corsair-timestamp":t,"x-corsair-project":e.projectId,"x-corsair-nonce":Fa()}}}function ur(e){let n=e.signingSecret.trim();if(!n)return!1;let t=mi(e.signatureHeader);if(!t)return!1;let r=Number(e.timestampHeader);if(!Number.isFinite(r)||Math.abs(Date.now()-r*1e3)>Re)return!1;let i=ir("sha256",n).update(e.body).digest("hex");try{return yi(Buffer.from(i,"utf8"),Buffer.from(t,"utf8"))}catch{return!1}}function Ve(e){let n=e.signingSecret.trim();if(!n)return{ok:!1,error:"Tunnel signing secret is required"};let t=mi(e.signatureHeader);if(!t)return{ok:!1,error:"Invalid tunnel signature"};let r=Number(e.timestampHeader);if(!Number.isFinite(r))return{ok:!1,error:"Invalid or missing tunnel timestamp"};if(Math.abs(Date.now()-r*1e3)>Re)return{ok:!1,error:"Tunnel request timestamp is outside the allowed window"};let i=ir("sha256",n).update(e.body).digest("hex");try{if(!yi(Buffer.from(i,"utf8"),Buffer.from(t,"utf8")))return{ok:!1,error:"Invalid tunnel signature"}}catch{return{ok:!1,error:"Invalid tunnel signature"}}return{ok:!0}}function Ye(e){if(!e)return{};try{return JSON.parse(e)}catch{return{}}}function at(e){return e.httpOk&&(e.status===204||e.body.status==="ok"||e.body.ok===!0)}function ut(e){let n=e.sync?.encrypted;return typeof n!="string"||!n.trim()?null:{encrypted:n.trim()}}function yn(e){let n=e.connectUrl?.trim();return n?{connectUrl:n,expiresAt:e.expiresAt}:null}function cr(e){return yn(Ye(e))}async function lr(e){let n=await dt({deliveryUrl:e.deliveryUrl,projectId:e.projectId,signingSecret:e.signingSecret,type:"connect.create_link",payload:{tenantId:e.tenantId,plugins:e.plugins}}),t=Ye(n.body),r=at({httpOk:n.ok,status:n.status,body:t}),o=yn(t);if(!r||!o)throw new Error(lt({deliveryUrl:e.deliveryUrl,status:n.status,body:n.body,ack:t}));return o}function ct(e){return ut(Ye(e))}function Ua(e){let n=e;for(;n;){if(n instanceof Error){let t=n.code;if(typeof t=="string")return t;n=n.cause;continue}if(typeof n=="object"&&n!==null&&"code"in n){let t=n.code;if(typeof t=="string")return t}break}}function fi(e,n=200){let t=e.trim();return t.length<=n?t:`${t.slice(0,n)}\u2026`}var Ba="Verify hub.signingSecret in your app matches the signing secret shown in Hub project settings.",La="Check the delivery URL configured for this environment.";function Na(e){return`${e.ack.error?`${e.ack.error} (HTTP ${e.status} from ${e.deliveryUrl})`:`App rejected the signed delivery (HTTP ${e.status} from ${e.deliveryUrl})`}. ${Ba}`}function $a(e){return`${e.ack.error?`${e.ack.error} (HTTP 404 from ${e.deliveryUrl})`:`Delivery endpoint not found at ${e.deliveryUrl} (HTTP 404)`}. ${La}`}function mn(e,n){let t=Ua(n),r=n instanceof Error?n.message:"Delivery request failed",o;switch(t){case"ECONNREFUSED":o="connection refused \u2014 nothing accepted a TCP connection on that host and port";break;case"ENOTFOUND":o="host not found \u2014 DNS could not resolve the hostname";break;case"ETIMEDOUT":case"UND_ERR_CONNECT_TIMEOUT":o="connection timed out before the app responded";break;case"ECONNRESET":o="connection reset while talking to the app";break;case"CERT_HAS_EXPIRED":case"UNABLE_TO_VERIFY_LEAF_SIGNATURE":case"DEPTH_ZERO_SELF_SIGNED_CERT":o=`TLS certificate error (${t})`;break;default:o=r==="fetch failed"&&t?`${r} (${t})`:r}return[`Could not reach ${e}`,o].join(". ")}function lt(e){if(e.status===0)return e.ack.error?e.ack.error:e.body.startsWith("Could not reach")?e.body:mn(e.deliveryUrl,new Error(e.body||"Delivery request failed"));if(e.status===401||e.status===403)return Na(e);if(e.status===404)return $a(e);if(e.ack.error)return`${e.ack.error} (HTTP ${e.status} from ${e.deliveryUrl})`;if(e.status>=500){let t=e.body.trim();return t?`App failed while processing the delivery (HTTP ${e.status} from ${e.deliveryUrl}): ${fi(t)}`:`App failed while processing the delivery (HTTP ${e.status} from ${e.deliveryUrl})`}let n=e.body.trim();return n?`${fi(n)} (HTTP ${e.status} from ${e.deliveryUrl})`:`Delivery failed with HTTP ${e.status} from ${e.deliveryUrl}`}async function dt(e){let{body:n,headers:t}=st(e);try{let r=await fetch(e.deliveryUrl,{method:"POST",headers:t,body:n}),o=await r.text();return{ok:r.ok,status:r.status,body:o}}catch(r){return{ok:!1,status:0,body:mn(e.deliveryUrl,r)}}}var Ka="aes-256-gcm",qa=12,Za=16,Ga=16,za=32;function Ja(e,n){return ja(e.trim(),n,za)}function dr(e,n){let t=n.trim();if(!t)throw new Error("Signing secret is required to encrypt sync manifest");let r=hi(Ga),o=Ja(t,r),i=hi(qa),s=Wa(Ka,o,i,{authTagLength:Za}),a=JSON.stringify(e),u=Buffer.concat([s.update(a,"utf8"),s.final()]),l=s.getAuthTag();return[r.toString("base64"),i.toString("base64"),l.toString("base64"),u.toString("base64")].join(":")}var Va=["invalid corsair instance","a database must be configured to sync connections from the app","a database must be configured on the corsair instance","signing secret is required to encrypt sync manifest"];function pr(e){if(e instanceof co)return!1;if(!(e instanceof Error))return!0;let n=e.message.toLowerCase();return!Va.some(t=>n.includes(t))}function Ya(e){if(!e)return[];let n=T(e);return n?(e.authConfig?.[n]?.integration??[]).filter(r=>!we(r)):[]}async function hn(e,n){let t=w(e);if(!t.database)throw new Error("A database must be configured to sync connections from the app");await Kn(e,{silent:!0});let[r,o]=await Promise.all([Je(t),ze(t)]),i={tenants:r.map(s=>({id:s.id})),plugins:o.map(s=>{let a=Ya(t.plugins.find(u=>u.id===s.id));return{id:s.id,authType:s.authType,configured:s.configured,missingFields:s.missingFields,...a.length>0?{integrationCredentialFields:a}:{}}}),syncedAt:new Date().toISOString()};return dr(i,n)}var ne=class extends Error{code;constructor(n,t){super(t),this.name="AuthCredentialsDeliveryError",this.code=n}};async function pt(e,n){let t=w(e,()=>new ne("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new ne("no_database","Database not configured");let r=B(t,n.plugin,c=>new ne("plugin_not_found",c)),o=T(r);if(!o)throw new ne("invalid_credentials",`Plugin '${r.id}' has no authType configured`);if(o==="oauth_2"||o==="managed")throw new ne("invalid_credentials","OAuth plugins must be connected via sign-in, not credentials delivery");await qe(e,n.tenantId);let i=new Set(An(r,o)),a=r.authConfig?.[o]?.account??[],u=D({authType:o,integrationName:n.plugin,tenantId:n.tenantId,kek:t.kek,database:t.database,extraAccountFields:a}),l=0;for(let[c,d]of Object.entries(n.credentials)){if(!d.trim())continue;if(!i.has(c))throw new ne("invalid_credentials",`Unknown credential field '${c}' for plugin '${n.plugin}'`);let p=$(u,`set_${c}`);if(!p)throw new ne("invalid_credentials",`Cannot set credential field '${c}' for plugin '${n.plugin}'`);await p(d.trim()),l+=1}if(l===0)throw new ne("invalid_credentials","Provide at least one credential field to save");return await le(e,{plugin:r,tenantId:n.tenantId}).catch(()=>{}),{plugin:n.plugin,tenantId:n.tenantId}}var te=class extends Error{code;constructor(n,t){super(t),this.name="IntegrationCredentialsDeliveryError",this.code=n}};async function gr(e,n){let t=w(e,()=>new te("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new te("no_database","Database not configured");let r=B(t,n.plugin,c=>new te("plugin_not_found",c)),o=T(r);if(!o)throw new te("invalid_credentials",`Plugin '${r.id}' has no authType configured`);await Vo(e);let i=new Set(go(r,o)),a=r.authConfig?.[o]?.integration??[],u=M({authType:o,integrationName:n.plugin,kek:t.kek,database:t.database,extraIntegrationFields:a}),l=0;for(let[c,d]of Object.entries(n.credentials)){if(!d.trim())continue;if(!i.has(c))throw new te("invalid_credentials",`Unknown integration credential field '${c}' for plugin '${n.plugin}'`);let p=$(u,`set_${c}`);if(!p)throw new te("invalid_credentials",`Cannot set integration field '${c}' for plugin '${n.plugin}'`);await p(d.trim()),l+=1}if(l===0)throw new te("invalid_credentials","Provide at least one integration credential field to save");return{plugin:n.plugin}}var gt=new Map;function Qa(e){for(let[n,t]of gt)t<=e&>.delete(n)}function ft(e,n){let t=e.trim();if(!t)return{ok:!1,error:"Delivery replay key is required"};if(!Number.isFinite(n)||n<=0)return{ok:!1,error:"Delivery replay TTL must be a positive number"};let r=Date.now();Qa(r);let o=gt.get(t);return o!==void 0&&o>r?{ok:!1,error:"Delivery request already consumed"}:(gt.set(t,r+n),{ok:!0})}var Pe=class extends Error{code;constructor(n,t){super(t),this.name="ManagedOAuthDeliveryError",this.code=n}};async function Qe(e,n){let{plugin:t,tenantId:r,accessToken:o,refreshToken:i,expiresIn:s,scope:a}=n;if(!o.trim())throw new Pe("no_access_token","Managed OAuth delivery missing access_token");let u=w(e,()=>new Pe("invalid_corsair_instance","Invalid corsair instance"));if(!u.database)throw new Pe("no_database","No database configured on corsair instance");let l=B(u,t,d=>new Pe("plugin_not_found",d));await qe(e,r);let c=D({authType:"managed",integrationName:t,tenantId:r,kek:u.kek,database:u.database});await c.set_access_token(o),i&&await c.set_refresh_token(i),s&&await c.set_expires_at(String(Math.floor(Date.now()/1e3)+s)),a&&await c.set_scope(a),await le(e,{plugin:l,tenantId:r}).catch(()=>{});try{let d=await $n(u.plugins,t,{access_token:o,refresh_token:i,scope:a});if(d){try{let p=l.authConfig?.managed?.account??[];await je({database:u.database,kek:u.kek,pluginId:t,tenantId:r,link:d,authType:"managed",extraAccountFields:p})}catch(p){console.warn(`[corsair:managed-oauth] Failed to persist webhook tenant link for '${t}' tenant '${r}':`,p)}u.hub&&We(u.hub,{plugin:t,tenantId:r,link:d,authType:"managed"})}}catch(d){console.warn(`[corsair:managed-oauth] Failed to resolve webhook tenant link for '${t}' tenant '${r}':`,d)}return await Ke(e,l,r,c).catch(d=>{console.warn(`[corsair:managed-oauth] subscribe failed for '${t}' tenant '${r}':`,d)}),{plugin:t,tenantId:r}}function Xa(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function ki(e,n,t=[]){for(let[r,o]of Object.entries(e))if(Xa(o)){if(o.match(n))return{webhook:o,path:[...t,r]}}else if(o&&typeof o=="object"){let i=ki(o,n,[...t,r]);if(i)return i}return null}function eu(e){let n={};for(let[t,r]of Object.entries(e))n[t.toLowerCase()]=Array.isArray(r)?r[0]:r;return n}function nu(e){let n=e["x-goog-resource-uri"],t=e["x-goog-channel-id"];if(!n||!t)return null;let r={resourceId:e["x-goog-resource-id"]||"",resourceState:e["x-goog-resource-state"]||"",resourceUri:n,channelId:t,channelExpiration:e["x-goog-channel-expiration"]||""};return n.includes("/drive/")&&(r.kind="drive#change"),{message:{data:Buffer.from(JSON.stringify(r)).toString("base64"),messageId:e["x-goog-message-number"]||""}}}async function bi(e,n,t,r,o){let i=eu(n),s=typeof t=="string"?JSON.parse(t):t;(!s||typeof s=="object"&&Object.keys(s).length===0)&&i["x-goog-resource-uri"]&&(s=nu(i)||s);let u={headers:i,body:s,...r?{query:r}:{}},l=r?.tenantId||"default",c=e.withTenant?e.withTenant(l):e,d=o?.plugin,p=d?[d]:xn;for(let g of p){let f=c[g];if(!f||!f.webhooks||!d&&f.pluginWebhookMatcher&&!f.pluginWebhookMatcher(u))continue;let y=ki(f.webhooks,u);if(!y)continue;let h=y.path.join("."),m={payload:s,headers:i,rawBody:typeof t=="string"?t:JSON.stringify(t),...r?{query:r}:{}};try{let b=await y.webhook.handler(m),C=!!Object.keys(b.returnToSender||{})?.length;return{plugin:g,action:h,body:s,response:C?{...b?.returnToSender,success:!0}:{success:!0},...b.responseHeaders&&{responseHeaders:b.responseHeaders}}}catch(b){return console.error(`Error executing webhook handler for ${g}.${h}:`,b),{plugin:g,action:h,body:s,response:{success:!1,error:b instanceof Error?b.message:"Unknown error"}}}}return{plugin:null,action:null,body:null}}import{createHash as tu}from"crypto";import*as Ee from"vm";var wi="__corsairFailedStep",ru=3e4,fr=class{constructor(n,t){this.wakeAt=n;this.stepName=t}__corsairSleep=!0};function Ci(e){return typeof e=="object"&&e!==null&&e.__corsairSleep===!0}function vi(e,n){return`st_${tu("sha256").update(`${n} ${e}`).digest("hex").slice(0,16)}`}function yt(e){if(e instanceof Error)return e.message;if(e!==null&&typeof e=="object"&&"message"in e){let n=e.message;if(typeof n=="string")return n}return String(e)}var Pi=new Set(["constructor","prototype","__proto__"]);function pe(e,n){if(e===null)return null;let t=typeof e;return t==="function"?iu(e,n):t==="object"?ou(e):e}function ou(e){return new Proxy(e,{get(n,t){if(!Pi.has(t))return pe(Reflect.get(n,t,n),n)},getPrototypeOf:()=>null,setPrototypeOf:()=>!1,defineProperty:()=>!1,set:()=>!1,deleteProperty:()=>!1})}function iu(e,n){return new Proxy(e,{apply:(t,r,o)=>su(Reflect.apply(t,n,o)),construct(){throw new Error("Workflow code may not construct host objects")},get(t,r){if(!Pi.has(r))return pe(Reflect.get(t,r,t),t)},getPrototypeOf:()=>null,setPrototypeOf:()=>!1,defineProperty:()=>!1,set:()=>!1,deleteProperty:()=>!1})}function su(e){return e!==null&&typeof e=="object"&&typeof e.then=="function"?Promise.resolve(e).then(n=>pe(n,void 0),n=>{throw pe(n,void 0)}):pe(e,void 0)}function au(e){let n=Object.create(null),t=Ee.createContext(n,{name:"corsair-workflow",codeGeneration:{strings:!1,wasm:!1}}),o=Ee.runInContext("(s) => JSON.parse(s)",t,{filename:"corsair:sandbox:json"})(JSON.stringify(e.payload??null)),s=Ee.runInContext(`(function (hostRun, hostSleep) {
|
|
20
|
+
const step = function step(name, fn) { return hostRun(name, fn); };
|
|
21
|
+
step.sleep = function sleep(name, ms) { return hostSleep(name, ms); };
|
|
22
|
+
return step;
|
|
23
|
+
})`,t,{filename:"corsair:sandbox:step"})((p,g)=>e.step(p,g),(p,g)=>e.step.sleep(p,g)),u=Ee.runInContext(`(function (sink) {
|
|
24
|
+
const fwd = (level) => function () {
|
|
25
|
+
try { sink(level, Array.prototype.slice.call(arguments)); } catch (_e) {}
|
|
26
|
+
};
|
|
27
|
+
return { log: fwd('log'), info: fwd('info'), warn: fwd('warn'), error: fwd('error'), debug: fwd('debug') };
|
|
28
|
+
})`,t,{filename:"corsair:sandbox:console"})((p,g)=>{let f=console[p]??console.log;try{f(...g)}catch{}});n.__corsair=pe(e.corsair,void 0),n.__payload=o,n.__step=s,n.__console=u;let l=Ee.runInContext(`(function () {
|
|
29
|
+
'use strict';
|
|
30
|
+
const module = { exports: {} };
|
|
31
|
+
const require = function (id) {
|
|
32
|
+
throw new Error('Workflow code may not import modules (attempted to require "' + id + '")');
|
|
33
|
+
};
|
|
34
|
+
(function (exports, module, require, console) {
|
|
35
|
+
${e.code}
|
|
36
|
+
})(module.exports, module, require, __console);
|
|
37
|
+
const main = module.exports.main;
|
|
38
|
+
if (typeof main !== 'function') {
|
|
39
|
+
throw new Error('Workflow code must export a \`main\` function');
|
|
40
|
+
}
|
|
41
|
+
return main(__corsair, __payload, __step);
|
|
42
|
+
})()`,t,{filename:"corsair:workflow",timeout:e.timeoutMs});l.catch(()=>{});let c,d=new Promise((p,g)=>{c=setTimeout(()=>g(new Error(`Workflow exceeded ${e.timeoutMs}ms time limit`)),e.timeoutMs)});return Promise.race([l,d]).finally(()=>clearTimeout(c))}async function yr(e){let n=e.memoizedSteps??{},t=[],r=0,o=null,i=(async(s,a)=>{if(o)throw o;let u=r++,l=vi(s,u);if(Object.hasOwn(n,l))return pe(n[l].output,void 0);try{let c=await a();return t.push({stepId:l,name:s,seq:u,status:"completed",output:c}),c}catch(c){if(Ci(c))throw c;let d=yt(c);t.push({stepId:l,name:s,seq:u,status:"failed",error:d});let p=new Error(d);throw p[wi]=s,p}});i.sleep=async(s,a)=>{if(o)throw o;let u=r++,l=vi(s,u);if(Object.hasOwn(n,l))return;t.push({stepId:l,name:s,seq:u,status:"completed",output:null});let c=Number.isFinite(a)?Math.max(0,a):0;throw o=new fr(Date.now()+c,s),o};try{await au({code:e.code,corsair:e.corsair,payload:e.payload,step:i,timeoutMs:e.timeoutMs??ru});let s=o;return s?{status:"sleeping",steps:t,sleepUntil:new Date(s.wakeAt).toISOString()}:{status:"completed",steps:t}}catch(s){if(Ci(s))return{status:"sleeping",steps:t,sleepUntil:new Date(s.wakeAt).toISOString()};let a=yt(s),u=s!==null&&typeof s=="object"?s[wi]:void 0;return{status:"failed",steps:t,error:{message:a,...u?{failedStep:u}:{}}}}}import*as mt from"vm";var Ti=1e4;async function mr(e){let n=Object.create(null),t=mt.createContext(n,{name:"corsair-probe",codeGeneration:{strings:!1,wasm:!1}});n.corsair=pe(e.corsair,void 0);let r=cu(e.timeoutMs),o=`(async () => {
|
|
43
|
+
const __result = await (async () => {
|
|
44
|
+
${e.code}
|
|
45
|
+
})();
|
|
46
|
+
return JSON.stringify(__result) ?? 'null';
|
|
47
|
+
})()`;try{let i=await Xt(()=>{let s=mt.runInContext(o,t,{filename:"corsair:probe",timeout:r});s.catch(()=>{});let a,u=new Promise((l,c)=>{a=setTimeout(()=>c(new Error(`Probe exceeded ${r}ms time limit`)),r)});return Promise.race([s,u]).finally(()=>clearTimeout(a))});return{status:"ok",value:uu(i)}}catch(i){return{status:"error",error:yt(i)}}}function uu(e){if(typeof e!="string")throw new Error(`Probe returned a non-string result (${typeof e})`);return JSON.parse(e)}function cu(e){return typeof e!="number"||!Number.isFinite(e)||e<=0?Ti:Math.min(e,Ti)}function De(e){return e.deliveryMode==="auth.credentials"}function kn(e){return e.deliveryMode==="connections.sync"}function ht(e){return e.deliveryMode==="connect.create_link"}function bn(e){return e.deliveryMode==="permission.approve"||e.deliveryMode==="permission.deny"}function wn(e){return e.deliveryMode==="oauth.tokens"}function kt(e){return e.deliveryMode==="oauth.callback"||e.deliveryMode===void 0&&!De(e)&&!kn(e)&&!ht(e)&&!bn(e)&&!wn(e)}function lu(e){return{status:"ok",connectLink:{connectUrl:e.connectUrl,expiresAt:e.expiresAt},webhookResponse:{status:200,body:{status:"ok",connectUrl:e.connectUrl,expiresAt:e.expiresAt}}}}async function du(e,n){try{return{status:"ok",webhookResponse:{status:200,body:{status:"ok",sync:{encrypted:await hn(e,n)}}}}}catch(t){return{status:"failed",retryable:pr(t),error:t instanceof Error?t.message:"Connections sync delivery failed"}}}async function pu(e,n){try{let t=await Gn(e,n);return lu(t)}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Connect link delivery failed"}}}function hr(e,n){if(e instanceof Headers)return e.get(n)??void 0;let t=e[n]??e[n.toLowerCase()];return Array.isArray(t)?t[0]:typeof t=="string"?t:void 0}async function gu(e,n,t){let r=typeof t.tenantId=="string"?t.tenantId:typeof t.query?.tenantId=="string"?t.query.tenantId:void 0;return r||(!n.database||!t.plugin||!t.linkType||!t.externalId?void 0:await Wn({database:n.database,kek:n.kek,pluginId:t.plugin,linkType:t.linkType,externalId:t.externalId})??void 0)}async function fu(e,n,t){let r=await gu(e,n,t),o={...t.query??{},...r?{tenantId:r}:{}},i=await bi(e,t.headers,t.body,o,t.plugin?{plugin:t.plugin}:void 0);if(!i.plugin)return{status:"failed",retryable:!1,error:"No matching webhook handler found"};if(i.response&&i.response.success===!1)return{status:"failed",retryable:!1,error:typeof i.response.error=="string"?i.response.error:"Webhook handler failed"};let s=i.response?.returnToSender,a=s&&typeof s=="object"&&typeof s.validationToken=="string"&&Object.keys(s).length===1?s.validationToken:s||(i.response?.data??i.response);return{status:"ok",webhookResponse:{status:i.response?.statusCode??200,body:a,headers:i.responseHeaders}}}async function yu(e,n){return await fn(e,{code:n.code,state:n.state,redirectUri:n.redirectUri,callbackParams:n.callbackParams,...n.plugin&&n.tenantId?{trusted:!0,plugin:n.plugin,tenantId:n.tenantId}:{}}),{status:"ok"}}async function mu(e,n){return await Qe(e,{plugin:n.plugin,tenantId:n.tenantId,accessToken:n.accessToken,refreshToken:n.refreshToken,expiresIn:n.expiresIn,scope:n.scope}),{status:"ok"}}async function br(e,n,t){let r=await kr(e,{token:n},t);if(r.status!=="ok")throw new Error(r.error??"Permission decision failed")}async function kr(e,n,t){let r=w(e),o=n.token?.trim();if(!o)return{status:"failed",retryable:!1,error:"Permission token is required"};if(!r.database)return{status:"failed",retryable:!1,error:"Database not configured"};let i=new Date().toISOString(),s=await r.database.db.selectFrom("corsair_permissions").selectAll().where("token","=",o).executeTakeFirst();return s?s.status!=="pending"?{status:"ok"}:s.expires_at<i?(await r.database.db.updateTable("corsair_permissions").set({status:"expired",updated_at:new Date}).where("id","=",s.id).execute(),{status:"failed",retryable:!1,error:"Permission has expired"}):(await r.database.db.updateTable("corsair_permissions").set({status:t,updated_at:new Date}).where("id","=",s.id).execute(),{status:"ok"}):{status:"failed",retryable:!1,error:"Permission not found"}}async function hu(e,n){try{return await pt(e,n),{status:"ok"}}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Credential delivery failed"}}}async function ku(e,n){try{return await gr(e,n),{status:"ok"}}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Integration credential delivery failed"}}}function Ai(e,n){let t=e;return n&&typeof t?.withTenant=="function"?t.withTenant(n):e}async function bu(e,n){try{let t=Ai(e,n.tenantId);return{status:"ok",webhookResponse:{status:200,body:{status:"ok",run:await yr({corsair:t,code:n.code,payload:n.trigger?.payload??null,memoizedSteps:n.memoizedSteps})}}}}catch(t){return{status:"failed",retryable:!0,error:t instanceof Error?t.message:"Workflow run failed"}}}async function wu(e,n){try{let t=Ai(e,n.tenantId);return{status:"ok",webhookResponse:{status:200,body:{status:"ok",probe:await mr({corsair:t,code:n.code,timeoutMs:n.timeoutMs})}}}}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Probe failed"}}}async function Cn(e,n,t={}){let r=w(e),o=hr(n.headers,"x-corsair-signature"),i=hr(n.headers,"x-corsair-timestamp"),s=hr(n.headers,"x-corsair-nonce");if(t.signingSecret?.trim()){let u=Ve({body:n.body,signatureHeader:o,timestampHeader:i,signingSecret:t.signingSecret});if(!u.ok)return{status:"failed",retryable:!1,error:u.error};if(!s?.trim())return{status:"failed",retryable:!1,error:"Missing tunnel nonce"};let l=ft(`nonce:${s.trim()}`,Re);if(!l.ok)return{status:"failed",retryable:!1,error:l.error}}else if(!t.allowUnsignedTunnel)return{status:"failed",retryable:!1,error:"Tunnel signing secret is required"};let a;try{a=JSON.parse(n.body)}catch{return{status:"failed",retryable:!1,error:"Invalid tunnel envelope JSON"}}if(a.type==="connect.status")return{status:"failed",retryable:!1,error:"connect.status is deprecated; use connections.sync signed delivery instead"};switch(a.type){case"webhook":return fu(e,r,a.payload);case"oauth.callback":return yu(e,a.payload);case"oauth.tokens":return mu(e,a.payload);case"permission.approve":return kr(e,a.payload,"approved");case"permission.deny":return kr(e,a.payload,"denied");case"auth.credentials":return hu(e,a.payload);case"integration.credentials":return ku(e,a.payload);case"connect.create_link":return pu(e,a.payload);case"connections.sync":{let u=t.signingSecret?.trim();return u?du(e,u):{status:"failed",retryable:!1,error:"Tunnel signing secret is required for connections.sync"}}case"run":return t.allowWorkflowExecution?bu(e,a.payload):{status:"failed",retryable:!1,error:"Workflow execution is not enabled (set allowWorkflowExecution: true)"};case"probe":return t.allowWorkflowExecution?wu(e,a.payload):{status:"failed",retryable:!1,error:"Workflow execution is not enabled (set allowWorkflowExecution: true)"};default:return{status:"failed",retryable:!1,error:`Unsupported tunnel type: ${String(a.type)}`}}}function Cu(e){let n=e.webhookResponse;return e.status==="ok"?{status:n?.status??200,body:n?.body??{status:"ok"}}:{status:n?.status??502,body:n?.body??{status:"error",error:e.error??"delivery failed"}}}var wr=3,vu=250;function Pu(e){return e?.name==="AbortError"}async function Tu(e){try{return(await e.json())?.ok!==!1}catch{return!0}}async function Au(e,n,t,r,o){for(let i=1;i<=wr;i++){try{let s=await n.fetch(`${e.apiUrl}/api/dev/ack`,{method:"POST",headers:{...t,"content-type":"application/json"},body:JSON.stringify(r),signal:o});if(s.ok)return await Tu(s)||console.warn(`[corsair] hub did not record delivery ${r.deliveryId} (already timed out); the run may be retried`),!0}catch(s){if(Pu(s))throw s}i<wr&&await Ri(vu)}return console.warn(`[corsair] failed to acknowledge delivery ${r.deliveryId} after ${wr} attempts; the run may be retried`),!1}async function xu(e,n,t,r){let o={authorization:`Bearer ${n.projectApiKey}`},i=await t.fetch(`${n.apiUrl}/api/dev/pull`,{headers:o,signal:r});if(i.status===204)return"idle";if(!i.ok)return"error";let{deliveryId:s,body:a,headers:u}=await i.json(),l=await t.process(e,{headers:u,body:a},{signingSecret:n.signingSecret,allowWorkflowExecution:n.allowWorkflowExecution}),{status:c,body:d}=Cu(l);return await Au(n,t,o,{deliveryId:s,status:c,body:d},r)?"handled":"error"}var xi=1e3,Ru=5e3,Iu=3e4;function Ri(e){return new Promise(n=>setTimeout(n,e))}var bt=globalThis.__corsairConnectLoops??=new Map;function Su(e,n={fetch,process:Cn}){let t;try{t=O(e)}catch{return{stop:()=>{}}}if(!t.projectApiKey.startsWith("ck_dev_"))return{stop:()=>{}};if(!t.allowWorkflowExecution)return console.warn("[corsair] workflow executions not enabled. Please set hub: { ..., allowWorkflowExecution: true }"),{stop:()=>{}};let r=t.projectApiKey;if(bt.has(r))return{stop:()=>{}};let o=Symbol("corsair-connect-loop");bt.set(r,o);let i=()=>{bt.get(r)===o&&bt.delete(r)},s=!1,a=null;return(async()=>{let l=xi,c=!1,d=async p=>{c||(console.warn("[corsair] connect loop error; retrying",p),c=!0),s||await Ri(l),l=Math.min(l*2,Ru)};try{for(;!s;){a=new AbortController;let p=setTimeout(()=>a?.abort(),Iu);try{await xu(e,t,n,a.signal)==="error"?await d("pull or ack failed"):(c=!1,l=xi)}catch(g){if(s)break;await d(g instanceof Error?g.message:g)}finally{clearTimeout(p)}}}finally{i()}})(),{stop:()=>{s=!0,a?.abort(),i()}}}function Ii(e){return e==="oauth_2"||e==="managed"?"oauth":e==="bot_token"?"bot_token":"api_key"}function _u(e,n){return n&&!n.has(e.id)?!1:T(e)!==null}async function Si(e,n,t={}){let r=w(e),o=n.trim()||"default",i=t.pluginIds?.length?new Set(t.pluginIds):null,s=await dn(r,o,{pluginIds:t.pluginIds}),a=new Map(s.map(l=>[l.plugin,l])),u=r.plugins.filter(l=>_u(l,i)).map(l=>{let c=T(l),d=a.get(l.id);return d?{plugin:l.id,providerName:me(l.id),authKind:Ii(c),status:d.status,connected:d.connected,fields:d.fields.map(p=>({name:p.name,level:p.level,required:p.required,configured:p.configured})),missingRequiredFields:d.missingRequiredFields}:{plugin:l.id,providerName:me(l.id),authKind:Ii(c),status:"not_started",connected:!1,fields:[],missingRequiredFields:[]}});return{tenantId:o,plugins:u}}async function _i(e,n){let t=O(e);return U({hub:t,path:`/projects/${encodeURIComponent(n.projectId)}/connections`,notFoundMessage:"Hub REST API not found at /projects/:id/connections. Check HUB_API_URL and ensure the Hub API is deployed.",parseResponse:In})}var Cr=new Map;function Ei(e){let n;try{n=O(e)}catch{return}let t=Et(n);t&&Cr.get(n.projectApiKey)!==t&&(Cr.set(n.projectApiKey,t),R({hub:n,path:"/apps/announce",body:{deliveryUrl:t},parseResponse:()=>({ok:!0})}).catch(()=>{Cr.delete(n.projectApiKey)}))}var Eu=[".corsair.dev"];function Du(e){return e==="localhost"||e==="127.0.0.1"||e==="[::1]"||e==="::1"}function Ou(e){try{let{hostname:n,protocol:t}=new URL(e);return t!=="http:"&&t!=="https:"?!1:Du(n)?!0:Eu.some(r=>n===r.slice(1)||n.endsWith(r))}catch{return!1}}function Di(e){return!e||!Ou(e)?null:{"Access-Control-Allow-Origin":e,"Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"content-type, x-corsair-signature, x-corsair-timestamp, x-corsair-project, x-corsair-nonce, access-control-request-private-network","Access-Control-Allow-Private-Network":"true","Access-Control-Max-Age":"0",Vary:"Origin"}}function Oi(e,n){if(!n)return e;let t=new Headers(e.headers);for(let[r,o]of Object.entries(n))t.set(r,o);return new Response(e.body,{status:e.status,statusText:e.statusText,headers:t})}function vr(e,n){let t=new URL(e);return n.error?(t.searchParams.set("error",n.error),t.toString()):n.connectedPlugin?(t.searchParams.set("connected",n.connectedPlugin),t.toString()):(n.status!==void 0&&t.searchParams.set("status",Buffer.from(JSON.stringify(n.status)).toString("base64url")),t.toString())}async function Pr(e,n){let t=O(e),o=new URL(n).searchParams.get("d");if(!o)return{type:"json",status:200,body:{status:"ok",message:"Corsair tunnel endpoint is active",timestamp:new Date().toISOString()}};let i=ke(o,t.signingSecret);if(!i)return{type:"json",status:400,body:{error:"Invalid or expired delivery token"}};let s=ft(`browser:${i.jti}`,he);if(!s.ok)return{type:"json",status:400,body:{error:s.error}};try{if(kn(i)){if(!i.hubOrigin||!i.requestId)return{type:"json",status:400,body:{error:"Connections sync delivery requires hubOrigin and requestId for client bridge"}};let a=await hn(e,t.signingSecret);return{type:"text",status:200,headers:{"Content-Type":"text/html; charset=utf-8"},body:Fe({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!0,body:{status:"ok",sync:{encrypted:a}}})}}if(ht(i)){if(!i.hubOrigin||!i.requestId)return{type:"json",status:400,body:{error:"Connect link delivery requires hubOrigin and requestId for client bridge"}};let a=i.connectLinkPlugins?.filter(Boolean)??[];if(a.length===0)return{type:"json",status:400,body:{error:"Connect link delivery requires at least one plugin in connectLinkPlugins"}};let u=await Gn(e,{tenantId:i.tenantId,plugins:a});return{type:"text",status:200,headers:{"Content-Type":"text/html; charset=utf-8"},body:Fe({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!0,body:{status:"ok",connectUrl:u.connectUrl,expiresAt:u.expiresAt}})}}if(De(i))return i.hubSuccessUrl?i.credentials?(await pt(e,{plugin:i.plugin,tenantId:i.tenantId,credentials:i.credentials}),{type:"redirect",url:vr(i.hubSuccessUrl,{connectedPlugin:i.plugin})}):{type:"redirect",url:vr(i.hubSuccessUrl,{error:"Credential delivery missing credentials"})}:{type:"json",status:400,body:{error:"Credential delivery missing hubSuccessUrl"}};if(bn(i)){if(!i.permissionToken)return{type:"json",status:400,body:{error:"Permission delivery missing permission token"}};await br(e,i.permissionToken,i.deliveryMode==="permission.approve"?"approved":"denied")}else if(wn(i)){if(!i.accessToken)return{type:"json",status:400,body:{error:"Managed OAuth delivery missing access_token"}};await Qe(e,{plugin:i.plugin,tenantId:i.tenantId,accessToken:i.accessToken,refreshToken:i.refreshToken,expiresIn:i.expiresIn,scope:i.scope})}else{if(!kt(i)||!i.code||!i.state||!i.redirectUri)return{type:"json",status:400,body:{error:"Invalid BYO OAuth delivery token"}};await fn(e,{code:i.code,state:i.state,redirectUri:i.redirectUri,trusted:!0,plugin:i.plugin,tenantId:i.tenantId})}}catch(a){let u=a instanceof Error?a.message:"Hub delivery failed";return kn(i)&&i.hubOrigin&&i.requestId?{type:"text",status:400,headers:{"Content-Type":"text/html; charset=utf-8"},body:Fe({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!1,error:u})}:ht(i)&&i.hubOrigin&&i.requestId?{type:"text",status:400,headers:{"Content-Type":"text/html; charset=utf-8"},body:Fe({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!1,error:u})}:De(i)&&i.hubSuccessUrl?{type:"redirect",url:vr(i.hubSuccessUrl,{error:u})}:De(i)&&i.hubOrigin&&i.requestId?{type:"text",status:400,headers:{"Content-Type":"text/html; charset=utf-8"},body:Fe({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!1,error:u})}:{type:"json",status:400,body:{error:u}}}return{type:"redirect",url:i.hubSuccessUrl}}async function Tr(e,n){let t=O(e),r=await Cn(e,n,{signingSecret:t.signingSecret,allowWorkflowExecution:t.allowWorkflowExecution});if(r.status!=="ok")return{type:"json",status:r.retryable===!1?400:502,body:{error:r.error??"Tunnel processing failed"}};let o=r.webhookResponse;if(!o)return{type:"json",status:200,body:{status:"ok"}};let i=o.status??200,s=o.headers;return o.body&&typeof o.body=="object"&&!(o.body instanceof ArrayBuffer)?{type:"json",status:i,body:o.body,headers:s}:{type:"text",status:i,body:typeof o.body=="string"?o.body:o.body?JSON.stringify(o.body):null,headers:s}}function Ar(e){if(e.type==="redirect")return Response.redirect(e.url,302);let n=new Headers;for(let[t,r]of Object.entries(e.headers??{}))typeof r=="string"&&n.set(t,r);return e.type==="json"?Response.json(e.body,{status:e.status,headers:n}):new Response(e.body,{status:e.status,headers:n})}async function xr(e,n){return n.method==="GET"?Pr(e,n.url):Tr(e,{headers:n.headers,body:n.body??""})}async function Rr(e,n){try{let t=await xr(e,n);return Ar(t)}catch(t){if(t instanceof se)return Response.json({error:t.message},{status:503});throw t}}async function Oe(e,n){Ei(e);let t=n.method.toUpperCase(),r=Di(n.headers.get("origin"));if(t==="OPTIONS")return r?new Response(null,{status:204,headers:r}):Response.json({error:"Method not allowed"},{status:405});if(t!=="GET"&&t!=="POST")return Response.json({error:"Method not allowed"},{status:405});let o=await Rr(e,{method:t,url:n.url,headers:n.headers,body:t==="POST"?await n.text():void 0});return Oi(o,r)}var W=class extends Error{pluginId;authType;constructor(n,t,r){super(r??`[auth-missing:${n}:${t}]`),Object.setPrototypeOf(this,new.target.prototype),this.name="AuthMissingError",this.pluginId=n,this.authType=t}};var Mi=300;async function Ir(e,n){let{keys:t,hub:r,plugin:o,tenantId:i}=e,s=n?.forceRefresh??!1,[a,u,l]=await Promise.all([t.get_access_token(),t.get_expires_at(),t.get_refresh_token()]);if(!a&&!l)throw new W(o,"managed");let c=Math.floor(Date.now()/1e3);if(!s&&a&&u&&Number(u)>c+Mi)return{accessToken:a,expiresAt:Number(u),refreshed:!1};if(!l&&a&&!s){let g=u?Number(u):null;if(g===null||g>c+Mi)return{accessToken:a,expiresAt:g??c+3600,refreshed:!1}}let d=await Hu(r,o,i),p=d.expires_in?c+d.expires_in:u?Number(u):c+3600;return await t.set_access_token(d.access_token),await t.set_expires_at(String(p)),d.refresh_token&&await t.set_refresh_token(d.refresh_token),d.scope&&await t.set_scope(d.scope),{accessToken:d.access_token,expiresAt:p,refreshed:!0}}function Mu(e){return e.includes("Managed OAuth connection not found")||e.includes("Managed OAuth connection has no tokens")}async function Hu(e,n,t){try{return await R({hub:e,path:"/oauth/refresh",body:{plugin:n,tenantId:t},parseResponse:_n})}catch(r){let o=r instanceof Error?r.message:"";throw Mu(o)?new W(n,"managed"):r}}async function Hi(e,n){e._refreshAuth=async()=>(await Ir(n,{forceRefresh:!0})).accessToken}function Fi(e){return{delivery:n=>Oe(e,n),deliveryOptions:n=>Oe(e,n)}}var Ui=1200*1e3;function Sr(){return ie()}function _r(){return Ui}function Er(e,n){return sn(e,n,Ui)}function Dr(e,n){return ee(e,n)}function Or(e){return Ie(e)}var Bi=600*1e3;function Mr(){return ie()}function Hr(){return Bi}function Fr(e,n){return sn(e,n,Bi)}function Ur(e,n){return ee(e,n)}function Br(e){return Bt(e)}function Lr(e){return Ie(e)}function Nr(){return ie()}function $r(e,n,t){return On(e,n,Math.floor(t.getTime()/1e3))}function Wr(e,n){return ee(e,n)}function jr(e){return Ie(e)}function wt(e,n){let t=[];e||t.push("database"),n||t.push("kek");let r={};return new Proxy(r,{get(o,i){let s=t.length>1;throw new Error(`corsair.keys.${String(i)}: Cannot access keys because ${t.join(" and ")} ${s?"are":"is"} not configured. Provide both 'database' and 'kek' in createCorsair() to enable key management.
|
|
48
|
+
|
|
49
|
+
To generate a KEK, run: openssl rand -base64 ${un}`)}})}async function Fu(e){let n=!1;for(;;){let t=await e.database.db.selectFrom("corsair_integrations").selectAll().where("name","=",e.integrationName).executeTakeFirst();if(!t){if(!n&&e.ensureProvisioned){n=!0,await e.ensureProvisioned();continue}throw new Error(`Integration "${e.integrationName}" not found. Make sure to create the integration first.`)}let r=await e.database.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",e.tenantId).where("integration_id","=",t.id).executeTakeFirst();if(!r){if(!n&&e.ensureProvisioned){n=!0,await e.ensureProvisioned();continue}throw new Error(`Account not found for tenant "${e.tenantId}" and integration "${e.integrationName}". Make sure to create the account first.`)}return{integrationId:t.id,accountId:r.id,integration:{id:t.id,config:t.config,dek:t.dek??null},account:{id:r.id,config:r.config,dek:r.dek??null}}}}async function Li(e){let{integrationId:n,accountId:t}=await Fu(e);return{integrationId:n,accountId:t}}function Ni(e,n){let t=()=>{if(!e)throw new Error("corsair.chats requires Hub to be configured. Pass `hub` to createCorsair({ hub: { projectApiKey, ... } }).");return e};return{create:r=>Dt(t(),{tenantId:n,message:r}),list:()=>Mt(t(),{tenantId:n}),get:r=>({message:o=>Ot(t(),{chatId:r,tenantId:n,message:o}),listMessages:()=>Ht(t(),{chatId:r,tenantId:n})})}}function Kr(e,n){return`[auth-missing:${e}] Authentication required. Direct the user to connect their account: ${n}`}async function Uu(e,n){let t=e.hub;if(!t||!n.database||!n.kek)return null;try{return(await Zt(t,{tenantId:n.tenantId,plugin:n.plugin,database:n.database,kek:n.kek,plugins:n.plugins,multiTenancy:n.multiTenancy})).connectUrl}catch{return null}}async function Bu(e){let n=e.hub;if(n&&e.database&&e.kek)try{let r=await Zt(n,{tenantId:e.tenantId,plugin:e.plugin,database:e.database,kek:e.kek,plugins:e.plugins,multiTenancy:e.multiTenancy});return e.manual?.onAuthMissing?e.manual.onAuthMissing({plugin:e.pluginId,connectUrl:r.connectUrl,state:r.token}):Kr(e.pluginId,r.connectUrl)}catch{return`[auth-missing:${e.pluginId}:${e.authType}] Authentication required. Could not create connect link. Check hub configuration and server logs.`}let t=await Uu({manual:e.manual,hub:e.hub},{plugin:e.plugin,tenantId:e.tenantId,database:e.database,kek:e.kek,plugins:e.plugins,multiTenancy:e.multiTenancy});return t?Kr(e.pluginId,t):`[auth-missing:${e.pluginId}:${e.authType}]`}function Lu(e,n,t){let r=$e(Ce(e,n.tenantId??t??"default"),n.kek),o=new URL(n.baseUrl);o.searchParams.set("state",r);let i=o.toString();return n.onAuthMissing?n.onAuthMissing({plugin:e,connectUrl:i,state:r}):Kr(e,i)}async function Nu(e){let n=e.tenantId??"default",t=e.error.pluginId;return e.manual&&Ze(e.manual)&&e.manual.oauthConfig&&e.manual.kek&&e.error.authType==="oauth_2"?Lu(t,{...e.manual,baseUrl:e.manual.baseUrl,kek:e.manual.kek},e.tenantId):e.hub&&e.plugin&&e.kek&&e.database&&e.plugins?Bu({manual:e.manual,hub:e.hub,plugin:e.plugin,pluginId:t,tenantId:n,authType:e.error.authType,database:e.database,kek:e.kek,plugins:e.plugins,multiTenancy:e.multiTenancy}):e.error.message}async function $i(e){let n=await Nu(e);throw new W(e.error.pluginId,e.error.authType,n)}var $u=async(e,n)=>(console.error(`[corsair:${n.pluginId}:${n.operation}]`,{error:e.message,input:n.input}),{maxRetries:0});async function Wi(e,n,t,r,o){let i={pluginId:n,operation:t,input:r,originalError:e},s=Object.keys(o).find(l=>o[l]?.match(e,i));return await(o[s||"DEFAULT"]?.handler||$u)(e,i)}function Wu(e){return typeof e=="function"}function qr({endpoints:e,hooks:n,ctx:t,tree:r,pluginId:o,errorHandlers:i,currentPath:s=[],keyBuilder:a,permissionsConfig:u,endpointMeta:l,database:c,permissionsOptions:d,tenantId:p,manualConfig:g,hubConfig:f,plugin:y,kek:h,allPlugins:m,multiTenancy:b}){for(let[C,_]of Object.entries(e)){let I=n?.[C];if(Wu(_)){let E=I,k=[...s,C].join("."),v=async(P={})=>{let j=l?.[k];er(k,j?.riskLevel??"write");let re;if(u){let K=j,{result:Tn,reason:Q,onComplete:tn,token:oe,id:xe,expiresAt:q}=await si({pluginId:o,endpointPath:k,args:P,mode:u.mode,override:u.overrides?.[k],riskLevel:K?.riskLevel??"write",meta:K,db:c,timeoutMs:d?nr(d.timeout):void 0,tenantId:p,approvalMode:d?.mode});if(Tn==="blocked"){let X;throw Q==="denied"?X=`Action '${k}' was denied by the user. Await further instructions before proceeding.`:Q==="policy"?X=`Action '${k}' is blocked by the permission policy. Update the corsair config to allow it.`:Q==="timeout"?X=`Action '${k}' timed out waiting for approval.`:oe&&xe?X=await Qt({permissionsOptions:d,manual:g,hub:f,permissionId:xe,permissionToken:oe,plugin:o,endpoint:k,args:P,tenantId:p??"default",expiresAt:q??new Date(Date.now()+(d?nr(d.timeout):600*1e3)).toISOString(),operationPath:k}):X=`Action '${k}' requires user approval before it can run.`,new Ge(X)}re=tn}let A=async(K,Tn,Q)=>{try{return await _(Tn,Q)}catch(tn){if(tn instanceof Error){let oe=await Wi(tn,o,k,typeof Q=="object"&&Q!==null?Q:{args:Q},i);if(K<(oe.maxRetries||0)){let xe=K+1;console.log(`Retrying (${xe} / ${oe.maxRetries})...`);let q;if(oe.headersRetryAfterMs)q=oe.headersRetryAfterMs;else switch(oe.retryStrategy){case"exponential_backoff":q=Math.pow(2,xe-1)*1e3;break;case"exponential_backoff_jitter":let X=Math.pow(2,xe-1)*1e3,Ds=(Math.random()-.5)*1e3;q=Math.max(0,X+Ds);break;case"linear_1s":q=1e3;break;case"linear_2s":q=2e3;break;case"linear_3s":q=3e3;break;case"linear_4s":q=4e3;break;default:q=1e3;break}await new Promise(X=>setTimeout(X,q)),await A(xe,Tn,Q),console.log(`[corsair:${o}:${k}] Retry strategy:`,oe)}}throw tn}},Y;try{Y=a?await a(t,"endpoint"):void 0}catch(K){throw K instanceof W&&(y&&f&&gn({hub:f,database:c,kek:h,plugins:m??[],plugin:y,tenantId:p,verified:!1}),await $i({error:K,manual:g,hub:f,plugin:y,tenantId:p,database:c,kek:h,plugins:m,multiTenancy:b})),K}if(!E?.before&&!E?.after){let K=await A(0,{...t,key:Y},P);return await re?.(),y&&f&&gn({hub:f,database:c,kek:h,plugins:m??[],plugin:y,tenantId:p,verified:!0}),K}let nn={...t,key:Y},Ae=E.before?await E.before(nn,P):{ctx:nn,args:P,continue:!0,passToAfter:void 0};if(Ae.continue===!1)return;let ao=await A(0,Ae.ctx,Ae.args);return await E.after?.(Ae.ctx,ao,Ae.passToAfter),await re?.(),y&&f&&gn({hub:f,database:c,kek:h,plugins:m??[],plugin:y,tenantId:p,verified:!0}),ao};r[C]=v}else if(_&&typeof _=="object"){let E={};qr({endpoints:_,hooks:I,ctx:t,tree:E,pluginId:o,errorHandlers:i,currentPath:[...s,C],keyBuilder:a,permissionsConfig:u,endpointMeta:l,database:c,permissionsOptions:d,tenantId:p,manualConfig:g,hubConfig:f,plugin:y,kek:h,allPlugins:m,multiTenancy:b}),r[C]=E}}}function ju(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function Zr({webhooks:e,hooks:n,ctx:t,webhooksTree:r,keyBuilder:o}){for(let[i,s]of Object.entries(e)){let a=n?.[i];if(ju(s)){let u=a,l=async c=>{let d=(g,f)=>s.handler(g,f),p=o?await o(t,"webhook"):void 0;return!u?.before&&!u?.after?d({...t,key:p},c):(async()=>{let g={...t,key:p},f=u.before?await u.before(g,c):{ctx:g,args:c,continue:!0,passToAfter:void 0};if(f.continue===!1)return;let y=await d(f.ctx,f.args);return y?.success===!0&&await u.after?.(f.ctx,y,f.passToAfter),y})()};r[i]={match:s.match,handler:l}}else if(s&&typeof s=="object"){let u={};Zr({webhooks:s,hooks:a,ctx:t,webhooksTree:u,keyBuilder:o}),r[i]=u}}}function ji(e){return e&&typeof e=="object"?e:{}}async function Ki(e,n){return U({hub:e,path:`/workflows?tenantId=${encodeURIComponent(n.tenantId)}`,parseResponse:t=>{let r=ji(t).workflows;return Array.isArray(r)?r:[]}})}async function qi(e,n){return U({hub:e,path:`/workflows/${encodeURIComponent(n.workflowId)}?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Workflow "${n.workflowId}" not found`,parseResponse:t=>ji(t).workflow})}async function Zi(e,n){await R({hub:e,path:`/workflows/${encodeURIComponent(n.workflowId)}/status?tenantId=${encodeURIComponent(n.tenantId)}`,body:{status:n.status},notFoundMessage:`Workflow "${n.workflowId}" not found`,parseResponse:t=>t})}async function Gi(e,n){await R({hub:e,path:`/workflows/${encodeURIComponent(n.workflowId)}/rename?tenantId=${encodeURIComponent(n.tenantId)}`,body:{name:n.name},notFoundMessage:`Workflow "${n.workflowId}" not found`,parseResponse:t=>t})}async function zi(e,n){return R({hub:e,path:`/workflows/${encodeURIComponent(n.workflowId)}/run?tenantId=${encodeURIComponent(n.tenantId)}`,body:{payload:n.payload,idempotencyKey:n.idempotencyKey},notFoundMessage:`Workflow "${n.workflowId}" not found`,parseResponse:t=>t})}function Gr(e){return e&&typeof e=="object"?e:{}}async function Ji(e,n){return U({hub:e,path:`/runs?tenantId=${encodeURIComponent(n.tenantId)}`,parseResponse:t=>{let r=Gr(t).runs;return Array.isArray(r)?r:[]}})}async function Vi(e,n){return U({hub:e,path:`/workflows/${encodeURIComponent(n.workflowId)}/runs?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Workflow "${n.workflowId}" not found`,parseResponse:t=>{let r=Gr(t).runs;return Array.isArray(r)?r:[]}})}async function Yi(e,n){return U({hub:e,path:`/runs/${encodeURIComponent(n.runId)}?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Run "${n.runId}" not found`,parseResponse:t=>Gr(t).run})}async function zr(e,n,t){await R({hub:e,path:`/runs/${encodeURIComponent(t.runId)}/${n}?tenantId=${encodeURIComponent(t.tenantId)}`,body:{},notFoundMessage:`Run "${t.runId}" cannot be ${n==="cancel"?"canceled":`${n}d`} in its current state`,parseResponse:r=>r})}var Qi=(e,n)=>zr(e,"approve",n),Xi=(e,n)=>zr(e,"deny",n),es=(e,n)=>zr(e,"cancel",n);function ns(e,n){let t=()=>{if(!e)throw new Error("corsair.workflows.runs requires Hub to be configured. Pass `hub` to createCorsair({ hub: { projectApiKey, ... } }).");return e};return{list:r=>r?.workflowId?Vi(t(),{workflowId:r.workflowId,tenantId:n}):Ji(t(),{tenantId:n}),get:r=>Yi(t(),{runId:r,tenantId:n}),approve:r=>Qi(t(),{runId:r,tenantId:n}),deny:r=>Xi(t(),{runId:r,tenantId:n}),cancel:r=>es(t(),{runId:r,tenantId:n})}}function ts(e,n){let t=()=>{if(!e)throw new Error("corsair.workflows requires Hub to be configured. Pass `hub` to createCorsair({ hub: { projectApiKey, ... } }).");return e},r=(o,i)=>Zi(t(),{workflowId:o,tenantId:n,status:i});return{list:()=>Ki(t(),{tenantId:n}),get:o=>qi(t(),{workflowId:o,tenantId:n}),run:(o,i)=>zi(t(),{workflowId:o,tenantId:n,payload:i?.payload,idempotencyKey:i?.idempotencyKey}),runs:ns(e,n),disable:o=>r(o,"inactive"),enable:o=>r(o,"active"),archive:o=>r(o,"archived"),unarchive:o=>r(o,"inactive"),rename:(o,i)=>Gi(t(),{workflowId:o,tenantId:n,name:i})}}function Ku(e,n,t,r){let o=null;return async()=>{if(o)return o;if(!e)throw new Error("Database not configured");let{accountId:i}=await Li({database:e,integrationName:n,tenantId:t,ensureProvisioned:r});return o=i,o}}function qu(e,n,t,r,o){return e?It(e.db,n,t,r,o):{findByEntityId:async()=>null,existsByEntityId:async()=>!1,findIdByEntityId:async()=>null,findById:async()=>null,findManyByEntityIds:async()=>[],list:async()=>[],search:async()=>[],upsertByEntityId:async()=>{throw new Error("Database not configured")},deleteById:async()=>!1,deleteByEntityId:async()=>!1,count:async()=>0}}function Jr(e,n){let{database:t,tenantId:r,kek:o,rootErrorHandlers:i,permissionsOptions:s,manualConfig:a,hubConfig:u,internalConfig:l}=n,c=r??"default",d=l&&t?()=>Ne(l,c):void 0,p={},g={};for(let f of e)p[f.id]={},g[f.id]={};for(let f of e){let y=f.schema,h=Ku(t,f.id,c,d);if(y?.entities){let A={};for(let[Y,nn]of Object.entries(y.entities)){let Ae=t?It(t.db,h,Y,y.version,nn):qu(void 0,h,Y,y.version,nn);A[Y]=Ae}g[f.id].db=A,p[f.id].db=A}let m=f.options,b=f.authConfig,C;if(t&&o&&m?.authType){let A=b?.[m.authType]?.account??[];C=D({authType:m.authType,integrationName:f.id,tenantId:c,kek:o,database:t,extraAccountFields:A,ensureProvisioned:d}),p[f.id].keys=C}let _={database:t,db:g[f.id]?.db??{},$getAccountId:h,...f.options?{options:f.options}:{},...C?{keys:C,authType:m?.authType}:{},tenantId:c,...u?{hub:u}:{}},I=f.endpoints??{},E=f.hooks,k={...i,...f.errorHandlers},v={},P=f.options?.permissions;qr({endpoints:I,hooks:E,ctx:_,tree:v,pluginId:f.id,errorHandlers:k,currentPath:[],keyBuilder:f.keyBuilder,permissionsConfig:P,endpointMeta:f.endpointMeta,database:t,permissionsOptions:s,tenantId:r,manualConfig:a?{...a,oauthConfig:f.oauthConfig,kek:o,tenantId:c}:void 0,hubConfig:u,plugin:f,kek:o,allPlugins:e,multiTenancy:l?.multiTenancy}),Object.keys(v).length>0&&(p[f.id].api=v),_.endpoints=v;let j=f.webhooks??{},re=f.webhookHooks;if(Object.keys(j).length>0){let A={};Zr({webhooks:j,hooks:re,ctx:_,webhooksTree:A,keyBuilder:f.keyBuilder}),p[f.id].webhooks=A,f.pluginWebhookMatcher&&(p[f.id].pluginWebhookMatcher=f.pluginWebhookMatcher),f.pluginTenantWebhookMatcher&&(p[f.id].pluginTenantWebhookMatcher=f.pluginTenantWebhookMatcher)}}return p.chats=Ni(u,c),p.workflows=ts(u,c),p}function rs(e,n,t){let r={};for(let o of e){let i=o.options,s=o.authConfig;if(i?.authType){let a=s?.[i.authType]?.integration??[],u=M({authType:i.authType,integrationName:o.id,kek:t,database:n,extraIntegrationFields:a});r[o.id]=u}}return r}var Zu="createCorsair({ approval: ... }) is deprecated. Rename to permissions: { timeout, onTimeout, mode }.";function os(e){let{permissions:n,approval:t}=e;if(n&&t)throw new Error("createCorsair was given both permissions and approval config. Use permissions only \u2014 approval is deprecated.");return t?(console.warn(`[corsair] ${Zu}`),t):n}var is=[{method:"GET",pattern:"/ok",handler:async()=>H(200,Qn())},{method:"GET",pattern:"/tenants",handler:async({internal:e})=>H(200,await Je(e))},{method:"POST",pattern:"/tenants",handler:async({internal:e,body:n})=>H(201,await nt(e,n))},{method:"GET",pattern:"/tenants/:id",handler:async({internal:e,params:n})=>H(200,await et(e,n.id))},{method:"GET",pattern:"/plugins",handler:async({internal:e})=>H(200,await ze(e))},{method:"GET",pattern:"/plugins/:id",handler:async({internal:e,params:n})=>H(200,await Xn(e,n.id))},{method:"GET",pattern:"/connection-status",handler:async({internal:e,query:n})=>H(200,await tt(e,n.tenantId))},{method:"GET",pattern:"/permissions/:id",handler:async({internal:e,params:n})=>H(200,await tr(e,n.id))},{method:"POST",pattern:"/permissions/lookup-by-token",handler:async({internal:e,body:n})=>{let t=n?.token?.trim();return t?H(200,await or(e,t)):H(400,{error:"bad_request",message:"token is required",missingFields:["token"]})}},{method:"POST",pattern:"/connect/links",handler:async({corsair:e,internal:n,body:t})=>H(200,await rt(e,n,t))},{method:"GET",pattern:"/connect/resolve",handler:async({corsair:e,internal:n,query:t})=>H(200,await ot(e,n,t.state??""))},{method:"POST",pattern:"/connect/oauth/callback",handler:async({corsair:e,internal:n,body:t})=>H(200,await it(e,n,t))}];(()=>{let e=new Set;for(let n of is){let t=`${n.method} ${n.pattern}`;if(e.has(t))throw new Error(`Duplicate management route registered: ${t}`);e.add(t)}})();function Gu(e,n){let t=e.split("/").filter(Boolean),r=n.split("/").filter(Boolean);if(t.length!==r.length)return null;let o={};for(let i=0;i<t.length;i++){let s=t[i],a=r[i];if(s.startsWith(":"))o[s.slice(1)]=decodeURIComponent(a);else if(s!==a)return null}return o}function zu(e,n){if(!n)return e;let t=n.endsWith("/")?n.slice(0,-1):n;return e===t?"/":e.startsWith(`${t}/`)?e.slice(t.length):e}async function Ju(e){if(!(e.method==="GET"||e.method==="HEAD"||!(e.headers.get("content-type")??"").includes("application/json")))try{let t=await e.text();return t?JSON.parse(t):void 0}catch{throw new S(400,"invalid_json","Request body is not valid JSON")}}var Vu="/api/corsair";function Me(e,n={}){let t=n.basePath??Vu,r=w(e,()=>new Error("managementHandler: invalid corsair instance (missing internal config)"));return async o=>{try{let i=new URL(o.url),s=zu(i.pathname,t),a=o.method.toUpperCase();if(a==="OPTIONS"||s==="/"||s==="")return await Oe(e,o);if(a!=="GET"&&a!=="POST")return H(405,{error:"method_not_allowed",message:`Method ${a} not allowed`});let u=Object.fromEntries(i.searchParams);for(let l of is){if(l.method!==a)continue;let c=Gu(l.pattern,s);if(!c)continue;let d=await Ju(o);return await l.handler({corsair:e,internal:r,req:o,params:c,query:u,body:d})}throw ve(`No route for ${a} ${s}`)}catch(i){if(n.onError){let a=await n.onError(i,o);if(a)return a}if(i instanceof S)return ai(i);let s=i instanceof Error?i.message:"Internal server error";return H(500,{error:"internal_error",message:s})}}}function Yu(e){let n=e.get?.("host")??"localhost",t=e.protocol??"http",r=e.originalUrl??e.url,o=`${t}://${n}${r}`,i=new Headers;for(let[u,l]of Object.entries(e.headers))if(l!=null)if(Array.isArray(l))for(let c of l)i.append(u,c);else i.set(u,l);let s=e.method!=="GET"&&e.method!=="HEAD",a={method:e.method,headers:i};return s&&e.body!==void 0&&(a.body=typeof e.body=="string"?e.body:JSON.stringify(e.body),i.has("content-type")||i.set("content-type","application/json")),new Request(o,a)}async function Qu(e,n){e.status(n.status),n.headers.forEach((r,o)=>e.setHeader(o,r));let t=Buffer.from(await n.arrayBuffer());e.send(t)}function ss(e,n){let t=Me(e,n);return async(r,o,i)=>{try{let s=await t(Yu(r));await Qu(o,s)}catch(s){i(s)}}}function as(e,n){let t=Me(e,n);return r=>t(r.req.raw)}function us(e,n){let t=Me(e,n);return{GET:t,POST:t,OPTIONS:t}}function cs(e){let n={[vn]:e};return{ok:Qn,tenants:{list:()=>Je(e),create:t=>nt(e,t),get:t=>et(e,t)},plugins:{list:()=>ze(e),get:t=>Xn(e,t)},connectionStatus:{get:t=>tt(e,t?.tenantId)},permissions:{get:t=>gi(e,t)},connect:{createLink:t=>rt(n,e,t),resolve:t=>ot(n,e,t),oauthCallback:t=>it(n,e,t)}}}async function ls(e,n,t,r,o="pending"){if(!e)return null;try{let i=fo(),s=new Date;return await e.db.insertInto("corsair_events").values({id:i,created_at:s,updated_at:s,account_id:n,event_type:t,payload:r,status:o}).execute(),i}catch(i){return console.warn("Failed to log event:",i),null}}async function Xu(e,n,t,r="pending"){try{let o=await e.$getAccountId();return ls(e.database,o,n,t,r)}catch(o){return console.warn("Failed to log event:",o),null}}import*as ps from"https";import*as Ct from"querystring";var ec=["expires_in","refresh_token_expires_in"];function ds(e){let n={...e};for(let t of ec){let r=e[t];if(typeof r=="string"){let o=Number(r);n[t]=Number.isFinite(o)?o:void 0}}return n}function nc(e){try{return ds(JSON.parse(e))}catch{}if(!e.includes("="))return null;let n=Ct.parse(e);return!n.access_token&&!n.error?null:ds({...n})}function jn(e,n,t,r,o){let i=new URL(r.tokenUrl),s=r.tokenAuthMethod==="basic";return new Promise((a,u)=>{let l={code:e.trim(),redirect_uri:o,grant_type:"authorization_code"};s||(l.client_id=n,l.client_secret=t);let c=Ct.stringify(l),d={"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json","Content-Length":Buffer.byteLength(c).toString()};s&&(d.Authorization=`Basic ${Buffer.from(`${n}:${t}`).toString("base64")}`);let p=ps.request({hostname:i.hostname,...i.port?{port:Number(i.port)}:{},path:i.pathname+i.search,method:"POST",headers:d},g=>{let f="";g.on("data",y=>{f+=y}),g.on("end",()=>{if(g.statusCode!==200){u(new Error(`Token exchange failed (${g.statusCode}): ${f}`));return}let y=nc(f);y?a(y):u(new Error(`Token endpoint returned non-JSON response: ${f}`))})});p.on("error",g=>u(new Error(`Request failed: ${g.message}`))),p.write(c),p.end()})}var gs=" ";function J(e){let n=e;return n._def??n.def??{}}function V(e){let n=e.typeName;if(n)return n;let t=e.type;if(t)return`Zod${t.split("_").map(r=>r.charAt(0).toUpperCase()+r.slice(1)).join("")}`}function z(e){return e.innerType??e.schema??e.out??e.in}function ys(e,n){switch(n){case"ZodPipe":return e.in??e.innerType;case"ZodEffects":return e.schema??e.innerType;case"ZodTransform":return e.schema??e.innerType??e.in;default:return z(e)}}function ms(e){let n=e.type;return e.element??(typeof n=="string"?void 0:n)}function Pt(e,n){let t=n.shape??e.shape;return typeof t=="function"?t():t}function Xe(e){return Array.isArray(e.options)?e.options:Array.isArray(e.values)?e.values:e.entries!==null&&typeof e.entries=="object"&&!Array.isArray(e.entries)?Object.values(e.entries):[]}function hs(e,n){return e.description??n.description}function tc(e){let n=e;for(;n;){let t=J(n),r=hs(n,t);if(r)return r;let o=V(t);if(eo(o)||o==="ZodPipe"||o==="ZodEffects"||o==="ZodTransform"){n=ys(t,o);continue}break}}function eo(e){return e==="ZodOptional"||e==="ZodNullable"||e==="ZodDefault"||e==="ZodCatch"}function N(e){let n=J(e),t=V(n);switch(t){case"ZodString":return"string";case"ZodNumber":return"number";case"ZodBoolean":return"boolean";case"ZodDate":return"Date";case"ZodNull":return"null";case"ZodUnknown":case"ZodAny":return"any";case"ZodLiteral":return String(n.value??Xe(n)[0]??"unknown");case"ZodEnum":return Xe(n).map(r=>String(r)).join(" | ");case"ZodOptional":{let r=z(n);return r?N(r):"unknown"}case"ZodNullable":{let r=z(n);return`${r?N(r):"unknown"} | null`}case"ZodDefault":case"ZodCatch":{let r=z(n);return r?N(r):"unknown"}case"ZodArray":{let r=ms(n);if(!r)return"unknown[]";let o=J(r),i=V(o)==="ZodUnion",s=N(r);return`${i?`(${s})`:s}[]`}case"ZodRecord":return"{}";case"ZodObject":{let r=Pt(e,n),o=Object.entries(r);return o.length===0?"{}":`{ ${o.map(([s,a])=>{let u=V(J(a));return`${u==="ZodOptional"||u==="ZodNullable"?s+"?":s}: ${N(a)}`}).join(", ")} }`}case"ZodUnion":return Xe(n).map(r=>N(r)).join(" | ");case"ZodIntersection":return`${N(n.left)} & ${N(n.right)}`;case"ZodPipe":case"ZodTransform":case"ZodEffects":{let r=ys(n,t);return r?N(r):"unknown"}default:return(t??"unknown").replace("Zod","").toLowerCase()}}function ge(e){let n=J(e),t=V(n),r=hs(e,n);switch(t){case"ZodString":return{kind:"string",optional:!1,description:r};case"ZodNumber":return{kind:"number",optional:!1,description:r};case"ZodBoolean":return{kind:"boolean",optional:!1,description:r};case"ZodLiteral":{let o=n.value??Xe(n)[0],i=typeof o=="string"||typeof o=="number"||typeof o=="boolean"?o:String(o??"");return{kind:"literal",optional:!1,description:r,value:i}}case"ZodEnum":{let o=Xe(n).map(i=>String(i));return{kind:"string",optional:!1,description:r,enum:o}}case"ZodOptional":{let o=z(n),i=o?ge(o):{kind:"unknown",optional:!1};return{...i,optional:!0,description:r??i.description}}case"ZodNullable":{let o=z(n),i=o?ge(o):{kind:"unknown",optional:!1};return{...i,optional:!0,description:r??i.description}}case"ZodDefault":case"ZodCatch":{let o=z(n);return o?{...ge(o),description:r}:{kind:"unknown",optional:!1,description:r}}case"ZodArray":{let o=ms(n);return{kind:"array",optional:!1,description:r,items:o?ge(o):{kind:"unknown",optional:!1}}}case"ZodObject":{let o=Pt(e,n),i={};for(let[s,a]of Object.entries(o))i[s]=ge(a);return{kind:"object",optional:!1,description:r,fields:i}}case"ZodRecord":return{kind:"unknown",optional:!1,description:r};case"ZodUnion":{let o=Xe(n);for(let i of o){let s=J(i);if(V(s)==="ZodObject")return{...ge(i),description:r}}return{kind:"unknown",optional:!1,description:r}}case"ZodIntersection":case"ZodPipe":case"ZodTransform":case"ZodEffects":{let o=z(n);return o?{...ge(o),description:r}:{kind:"unknown",optional:!1,description:r}}default:return{kind:"unknown",optional:!1,description:r}}}function Cm(e,n){let t=n.toLowerCase(),r=t.indexOf(".");if(r===-1)return null;let o=t.slice(0,r),i=t.slice(r+1),s=e.find(c=>c.id===o);if(!s)return null;let a=i;a.startsWith("api.")&&(a=a.slice(4));let u=Te(s.endpointMeta,a),l=Te(s.endpointSchemas,a);return!u&&!l?null:{input:l?.input?ge(l.input):null,output:l?.output?ge(l.output):null,description:u?.description}}var no=["equals","contains","startsWith","endsWith","in"],rc=["equals","gt","gte","lt","lte","in"],oc=["equals"],ic=["equals","before","after","between"];function ks(e){let n=J(e);switch(V(n)){case"ZodOptional":case"ZodNullable":case"ZodDefault":case"ZodCatch":{let r=z(n);return r?ks(r):null}case"ZodString":return"string";case"ZodNumber":return"number";case"ZodBoolean":return"boolean";case"ZodDate":return"date";default:return null}}function to(e){let n=J(e),t=V(n);if(eo(t)){let i=z(n);return i?to(i):{}}if(t!=="ZodObject")return{};let r=Pt(e,n),o={};for(let[i,s]of Object.entries(r)){let a=ks(s);a==="string"?o[i]={type:"string",operators:no}:a==="number"?o[i]={type:"number",operators:rc}:a==="boolean"?o[i]={type:"boolean",operators:oc}:a==="date"&&(o[i]={type:"date",operators:ic})}return o}function bs(e,n){for(let[t,r]of Object.entries(e))if(t.toLowerCase()===n)return[t,r]}function Yr(e,n,t){for(let[r,o]of Object.entries(e)){let i=[...n,r];typeof o=="function"?t.push(i.join(".")):o!==null&&typeof o=="object"&&Yr(o,i,t)}}function Qr(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function Xr(e,n,t){for(let[r,o]of Object.entries(e)){let i=[...n,r];Qr(o)?t.push(i.join(".")):o!==null&&typeof o=="object"&&Xr(o,i,t)}}function ro(e,n){if(n.length===0)return null;let[t,...r]=n,o=Object.entries(e).find(([a])=>a.toLowerCase()===t);if(!o)return null;let[i,s]=o;if(r.length===0)return Qr(s)?[i]:null;if(s!==null&&typeof s=="object"&&!Qr(s)){let a=ro(s,r);if(a!==null)return[i,...a]}return null}function ws(e,n){let t=[];t.push(`${e}({`),t.push(" webhookHooks: {");for(let i=0;i<n.length;i++){let s=" ".repeat(i+2);t.push(`${s}${n[i]}: {`)}let r=" ".repeat(n.length+2),o=r+" ";t.push(`${r}before(ctx, args) {`),t.push(`${o}return { ctx, args };`),t.push(`${r}},`),t.push(`${r}after(ctx, response) {`),t.push(`${r}},`);for(let i=n.length-1;i>=0;i--){let s=" ".repeat(i+2);t.push(`${s}},`)}return t.push(" },"),t.push("})"),t.join(`
|
|
50
|
+
`)}var sc=new Set(xn);function He(e,n){let t=n?.type??"api",r=n?.plugin;if(r!==void 0){let i=e.find(a=>a.id===r);if(!i)return sc.has(r)?`This plugin (${r}) is not configured. Please add it to the Corsair instance to see its associated methods.`:He(e);if(t==="webhooks"){if(!i.webhooks)return[];let a=[];return Xr(i.webhooks,[],a),a.map(u=>`${i.id}.webhooks.${u}`)}if(t==="db"){let a=i.schema?.entities;return a?Object.keys(a).map(u=>`${i.id}.db.${u}.search`):[]}if(!i.endpoints)return[];let s=[];return Yr(i.endpoints,[],s),s.map(a=>`${i.id}.api.${a}`)}let o={};if(t==="webhooks")for(let i of e){if(!i.webhooks)continue;let s=[];Xr(i.webhooks,[],s),o[i.id]=s.map(a=>`${i.id}.webhooks.${a}`)}else if(t==="db")for(let i of e){let s=i.schema?.entities;s&&(o[i.id]=Object.keys(s).map(a=>`${i.id}.db.${a}.search`))}else for(let i of e){if(!i.endpoints)continue;let s=[];Yr(i.endpoints,[],s),o[i.id]=s.map(a=>`${i.id}.api.${a}`)}return o}function Te(e,n){if(e){for(let[t,r]of Object.entries(e))if(t.toLowerCase()===n)return r}}function ac(e,n){let t=e.toLowerCase(),r=n.toLowerCase();if(!t.startsWith(`${r}.`)){let i=t.slice(n.length+1),s=i.startsWith(".")?i.slice(1):i;return s.startsWith("api.")&&(s=s.slice(4)),{shortPath:s,lookupKey:s}}let o=e.slice(n.length+1);return o.toLowerCase().startsWith("api.")&&(o=o.slice(4)),{shortPath:o,lookupKey:o.toLowerCase()}}function Vr(e,n){return typeof e=="string"?e:Array.isArray(e)?`${n}:
|
|
51
|
+
${e.join(", ")}`:`${n}:
|
|
52
|
+
`+Object.entries(e).map(([t,r])=>` ${t}: ${r.join(", ")}`).join(`
|
|
53
|
+
`)}function vm(e,n){let t=n.toLowerCase(),r=t.indexOf(".");if(r!==-1){let o=t.slice(0,r),i=t.slice(r+1),s=e.find(a=>a.id===o);if(s){if(i.startsWith("db.")){let c=i.slice(3),d=c.lastIndexOf(".");if(d!==-1){let p=c.slice(0,d),g=c.slice(d+1),f=s.schema?.entities;if(g==="search"&&f){let y=bs(f,p);if(y){let[h,m]=y,b=to(m),C=[`Search ${o} ${h} stored in the local database.`,"Pass limit and offset as numbers for pagination.","","filters {",` entity_id: string [${no.join(", ")}]`];for(let[_,I]of Object.entries(b))C.push(` ${_}?: ${I.type} [${I.operators.join(", ")}]`);return C.push("}"),C.join(`
|
|
54
|
+
`)}}}return Vr(He(e,{type:"db"}),"Path not found. Available db operations")}if(i.startsWith("webhooks.")){let c=i.slice(9);if(s.webhooks){let d=ro(s.webhooks,c.split("."));if(d!==null){let p=d.join("."),g=Te(s.webhookSchemas,p.toLowerCase()),f=g?.response?N(g.response):null,y=[];return g?.description&&y.push(g.description),g?.payload&&y.push(`payload ${vt(en(g.payload))}`),f&&y.push(`response: ${f}`),y.push(`usage:
|
|
55
|
+
${ws(o,d)}`),y.join(`
|
|
56
|
+
|
|
57
|
+
`)}}return Vr(He(e,{type:"webhooks"}),"Path not found. Available webhooks")}let a=i;a.startsWith("api.")&&(a=a.slice(4));let u=Te(s.endpointMeta,a),l=Te(s.endpointSchemas,a);if(u||l){let c=[],d=[u?.riskLevel?`[${u.riskLevel}]`:"",u?.irreversible?"[irreversible]":""].filter(Boolean).join(" "),p=[u?.description,d].filter(Boolean).join(" ");return p&&c.push(p),l?.input&&c.push(`input ${vt(en(l.input))}`),l?.output&&c.push(`output ${vt(en(l.output))}`),c.join(`
|
|
58
|
+
|
|
59
|
+
`)}}}return Vr(He(e),"Path not found. Available operations")}function fs(e){let n=e;for(;;){let t=J(n),r=V(t);if(eo(r)){let o=z(t);if(!o)return n;n=o;continue}return n}}function en(e){if(e===void 0)return{kind:"inline",type:"unknown"};let n=fs(e),t=J(n);if(V(t)==="ZodObject"){let o=Pt(n,t),i=[];for(let[s,a]of Object.entries(o)){let u=J(a),l=V(u),c=l==="ZodOptional"||l==="ZodNullable",d=fs(a),p=tc(a);i.push({key:s,optional:c,type:N(d),...p!==void 0?{description:p}:{}})}return{kind:"object",fields:i}}return{kind:"inline",type:N(n)}}function vt(e,n=0){if(e===void 0)return"{}";if(e.kind==="inline")return e.type;if(e.kind==="object"){if(e.fields.length===0)return"{}";let t=gs.repeat(n+1),r=gs.repeat(n);return`{
|
|
60
|
+
${e.fields.map(i=>{let s=i.optional?`${i.key}?`:i.key,a=i.description?` // ${i.description}`:"";return`${t}${s}: ${i.type}${a}`}).join(`
|
|
61
|
+
`)}
|
|
62
|
+
${r}}`}return"unknown"}function uc(e,n){let t=He(e,{plugin:n,type:"api"});if(typeof t=="string")return{ok:!1,error:t};if(!Array.isArray(t))return{ok:!1,error:"list_operations did not return a path array \u2014 pass a configured plugin id."};let r=e.find(c=>c.id===n);if(!r)return{ok:!1,error:`Plugin "${n}" is not configured on this instance.`};let o=[];for(let c of t){let{shortPath:d,lookupKey:p}=ac(c,n),g=Te(r.endpointMeta,p),f=Te(r.endpointSchemas,p);!g&&!f||o.push({path:c,shortPath:d,description:g?.description,riskLevel:g?.riskLevel,irreversible:g?.irreversible,input:en(f?.input),output:en(f?.output)})}o.sort((c,d)=>c.path.localeCompare(d.path));let i=[],s=He(e,{plugin:n,type:"webhooks"});if(Array.isArray(s)&&r.webhooks)for(let c of s){let p=c.toLowerCase().slice(n.length+1),g=p.startsWith(".")?p.slice(1):p;if(!g.startsWith("webhooks."))continue;let f=g.slice(9),y=ro(r.webhooks,f.split("."));if(y===null)continue;let h=y.join("."),m=Te(r.webhookSchemas,h.toLowerCase()),b=m?.response?N(m.response):void 0;i.push({path:c,description:m?.description,payload:en(m?.payload),responseType:b,usageExample:ws(n,y)})}i.sort((c,d)=>c.path.localeCompare(d.path));let a=[],u=He(e,{plugin:n,type:"db"}),l=r.schema?.entities;if(Array.isArray(u)&&l)for(let c of u){let p=c.toLowerCase().slice(n.length+1),g=p.startsWith(".")?p.slice(1):p;if(!g.startsWith("db."))continue;let f=g.slice(3),y=f.lastIndexOf(".");if(y===-1)continue;let h=f.slice(0,y);if(f.slice(y+1)!=="search")continue;let b=bs(l,h);if(!b)continue;let[C,_]=b,I=to(_),E=Object.entries(I).map(([k,v])=>({field:k,type:v.type,operators:v.operators}));a.push({path:c,entityName:C,filters:[{field:"entity_id",type:"string",operators:no},...E]})}return a.sort((c,d)=>c.path.localeCompare(d.path)),{ok:!0,data:{pluginId:n,api:o,webhooks:i,db:a}}}import{randomUUID as Cs}from"crypto";async function cc(e,n){let t=await e.keys.get_access_token();if(!t)return null;let r=Cs(),o=Cs(),i=await fetch(n.watchUrl,{method:"POST",signal:AbortSignal.timeout(2e4),headers:{authorization:`Bearer ${t}`,"content-type":"application/json"},body:JSON.stringify({id:r,type:"web_hook",address:n.webhookUrl,token:o,...n.body})});if(!i.ok)throw new Error(`Google channel watch failed (${i.status}): ${await i.text()}`);return{webhookLink:{linkType:"channel_id",externalId:r},webhookSecret:o}}import{randomUUID as lc}from"crypto";var Tt="https://graph.microsoft.com/v1.0",oo=2e4,dc=60;async function pc(e,n){let t=await e.keys.get_access_token();if(!t)return null;let r={authorization:`Bearer ${t}`};try{let u=await fetch(`${Tt}/subscriptions`,{headers:r,signal:AbortSignal.timeout(oo)});if(u.ok){let{value:l}=await u.json(),c=(l??[]).filter(d=>d.notificationUrl===n.webhookUrl);await Promise.all(c.map(d=>fetch(`${Tt}/subscriptions/${d.id}`,{method:"DELETE",headers:r,signal:AbortSignal.timeout(oo)}).catch(()=>{})))}}catch{}let o=lc(),i=new Date(Date.now()+dc*6e4).toISOString(),s=await fetch(`${Tt}/subscriptions`,{method:"POST",headers:{...r,"content-type":"application/json"},signal:AbortSignal.timeout(oo),body:JSON.stringify({changeType:n.changeType,notificationUrl:n.webhookUrl,resource:n.resource,expirationDateTime:i,clientState:o})});if(!s.ok)throw new Error(`MS Graph subscribe failed (${s.status}): ${await s.text()}`);let a=await s.json();return a.id?(await e.keys.set_webhook_signature(o),{webhookLink:{linkType:"subscription_id",externalId:a.id},webhookSecret:o}):null}function vs(e,n){for(let[t,r]of Object.entries(e))if(r?.pluginWebhookMatcher&&r.pluginWebhookMatcher(n))return t;return null}function gc(e,n){let t=vs(e,n);if(!t)return null;let r=e[t];if(!r?.pluginTenantWebhookMatcher)return null;let o=r.pluginTenantWebhookMatcher(n);return o?{plugin:t,tenantMatch:o}:null}function fc(e){let n={};for(let t of e)!t.pluginWebhookMatcher&&!t.pluginTenantWebhookMatcher||(n[t.id]={pluginWebhookMatcher:t.pluginWebhookMatcher,pluginTenantWebhookMatcher:t.pluginTenantWebhookMatcher});return n}function Ps(e,n){let t=n.toLowerCase(),r=e[t]??e[n];return Array.isArray(r)?r[0]:typeof r=="string"?r:void 0}function Ts(e){if(typeof e=="string"){let n=e.trim();return n.length>0?n:void 0}if(typeof e=="number"&&Number.isFinite(e))return String(e)}function Pn(e){return!e||typeof e!="object"||Array.isArray(e)?null:e}function yc(e){return Pn(e.body)}function As(e,n){let t=e.query;if(!t)return;let r=t[n]??t[n.toLowerCase()];return At(Array.isArray(r)?r:[r])}function xs(e){let n=e.headers??{},t=[n.validationtoken,n.validationToken,n["validation-token"],n["ms-validation-token"]];for(let u of t){let l=At(Array.isArray(u)?u:[u]);if(l)return decodeURIComponent(l)}let r=As({query:e.query},"validationToken");if(r)return r;let o=["x-forwarded-uri","x-original-uri","x-rewrite-url","x-envoy-original-path","referer"];for(let u of o){let l=n[u],c=Array.isArray(l)?l[0]:l;if(!(!c||typeof c!="string"))try{let p=(c.startsWith("http")?new URL(c):new URL(`https://example.invalid${c.startsWith("/")?c:`/${c}`}`)).searchParams.get("validationToken");if(p?.trim())return p.trim()}catch{continue}}let i=e.payload!==void 0?e.payload:e.body!==void 0?e.body:void 0,s=Pn(typeof i=="string"?(()=>{try{return JSON.parse(i)}catch{return i}})():i);return At([s?.validationToken])??null}function mc(e){if(xs(e))return!0;let n=Pn(e.body??e.payload);return Ps(e.headers??{},"content-type")?.includes("text/plain")?!n||Object.keys(n).length===0:!1}function At(e){for(let n of e){let t=Ts(n);if(t)return t}}function hc(e){let t=Pn(e.message)?.data;if(typeof t!="string")return null;try{return JSON.parse(Buffer.from(t,"base64").toString("utf8"))}catch{return null}}var vn=Symbol.for("corsair:internal");function Ss(e){let n=e.database?uo(e.database):void 0,t=n&&e.kek?rs(e.plugins,n,e.kek):wt(!!n,!!e.kek),r=os(e),o={plugins:e.plugins,database:n,kek:e.kek,multiTenancy:!!e.multiTenancy,permissions:r,manual:e.manual,hub:e.hub?Mn(e.hub):void 0},i=ii(n),s=cs(o);if(e.multiTenancy){let l=Object.assign({withTenant:c=>{if(!c)throw new Error("corsair.withTenant(tenantId): tenantId must be a non-empty string");let d=Jr(e.plugins,{database:n,tenantId:c,kek:e.kek,rootErrorHandlers:e.errorHandlers,permissionsOptions:r,manualConfig:e.manual,hubConfig:o.hub,internalConfig:o});return Object.assign(d,{[vn]:o})},keys:t,permissions:i,manage:s},{[vn]:o});return Rs(l,o.hub),Is(l,o.hub),l}let a=Jr(e.plugins,{database:n,tenantId:void 0,kek:e.kek,rootErrorHandlers:e.errorHandlers,permissionsOptions:r,manualConfig:e.manual,hubConfig:o.hub,internalConfig:o}),u=Object.assign({},a,{keys:t,permissions:i,manage:s,[vn]:o});return Rs(u,o.hub),Is(u,o.hub),u}function Rs(e,n){n?.projectApiKey?.startsWith("ck_dev_")&&import("./loop-CNEPJ4DI.js").then(t=>t.startConnectLoop(e)).catch(()=>{})}function kc(e){return e?.projectApiKey?.startsWith("ck_dev_")?e.tunnel!==!1&&process.env.CORSAIR_TUNNEL!=="0":!1}var xt=globalThis.__corsairTunnels??=new Set;function Is(e,n){if(!kc(n))return;let t=n.projectApiKey;if(xt.has(t))return;let r=Number(process.env.PORT);if(!Number.isInteger(r)||r<1||r>65535){console.error("[corsair] PORT is not set \u2014 dev tunnel skipped. Set PORT to your app port, or run `corsair http <port>`.");return}xt.add(t);let o=typeof n.tunnel=="object"?n.tunnel:{},i=process.env.CORSAIR_FRP_HOST??o.shareHost??St;import("./hub/tunnel/run-tunnel.js").then(s=>s.runTunnel({port:r,apiUrl:n.apiUrl,apiKey:t,shareHost:i,onClose:()=>xt.delete(t)})).then(({url:s})=>{console.log(`[corsair] tunnel active: ${s}${_t}`)}).catch(s=>{xt.delete(t),console.warn(`[corsair] tunnel failed to start: ${s instanceof Error?s.message:String(s)}. Run \`corsair setup\` to enable your dev tunnel.`)})}var bc={slack:{channels:{list:{}},users:{list:{}}},linear:{projects:{list:{}},issues:{list:{}},users:{list:{}}},github:{issues:{list:{}},repositories:{list:{}}},discord:{guilds:{list:{}},channels:{list:{}}},hubspot:{contacts:{getMany:{}},companies:{getMany:{}},deals:{getMany:{}}},gmail:{messages:{list:{}},labels:{list:{}},drafts:{list:{}},threads:{list:{}}},googlecalendar:{events:{getMany:{}}},googlemeet:{conferenceRecords:{list:{}}},googledrive:{files:{list:{}},folders:{list:{}},sharedDrives:{list:{}}},notion:{databases:{getManyDatabases:{}},databasePages:{getManyDatabasePages:{}},users:{getManyUsers:{}}},airtable:{bases:{getMany:{}}},todoist:{projects:{getMany:{}},tasks:{getMany:{}}},cal:{bookings:{list:{}}},zohomail:{folders:{list:{}},messages:{list:{}}}},io=bc;async function Kn(e,n){let t=[],r=n?.silent??!1,o=g=>{t.push(g),r||console.log(g)},i=g=>{t.push(g),r||console.warn(g)},s=n?.caller??"script",a=lo(e);if(!a)throw new Error("setupCorsair: invalid corsair instance");if(!a.database)throw new Error("setupCorsair: a database must be configured on the corsair instance");let u=Ec(e,a.plugins,n),l={...a,database:a.database},c=l.database.db;await Mc(c,i);let d=await Hc(c,l,u.tenantId,u.provisionAccounts,o);n?.credentials&&Object.keys(n.credentials).length>0&&await Bc(e,u,n.credentials,l,o,i);let p=await Nc(d,u,o,s);if(n?.backfill){o("[corsair:setup] Starting backfill...");let g=Ss({plugins:a.plugins,database:c,kek:a.kek,multiTenancy:!0}).withTenant(u.tenantId);await $c(g,a.plugins,p,o,i),o("[corsair:setup] Backfill complete.")}return t.join(`
|
|
63
|
+
`)}function so(e,n,t){let r=t==="integration"?e.authConfig?.[n]?.integration??[]:e.authConfig?.[n]?.account??[];return new Set([...F[n][t],...r])}function _c(e,n){if(!e)return!1;for(let[t,r]of Object.entries(e)){let o=n.find(a=>a.id===t);if(!o)continue;let i=T(o);if(!i)continue;let s=so(o,i,"account");for(let a of Object.keys(r))if(s.has(a))return!0}return!1}function Ec(e,n,t){let r=po(e),o=t?.tenantId?.trim(),i=o!==void 0&&o.length>0;if(r&&t?.backfill&&!i)throw new Error("setupCorsair: tenantId is required for backfill on a multi-tenant instance");if(r&&_c(t?.credentials,n)&&!i)throw new Error("setupCorsair: tenantId is required when setting account-level credentials on a multi-tenant instance");if(i&&!o)throw new Error("setupCorsair: tenantId must be a non-empty string");return{multiTenant:r,tenantIdProvided:i,tenantId:i?o:"default",provisionAccounts:!r||i}}function Es(e,n){return ye(e)?n===0?!0:Object.values(e).every(t=>Es(t,n-1)):!1}function Dc(e){return Es(e,4)}var Oc={...yo};function Rt(e){if(e instanceof Ac){let n={};for(let[t,r]of Object.entries(e.shape))n[t]=r instanceof Sc?Rt(r):"unknown";return n}return e instanceof Pc?`${Rt(e.unwrap())} | null`:e instanceof xc?`${Rt(e.unwrap())} | undefined`:e instanceof vc?e.options.join(" | "):e instanceof Ic?"string":e instanceof Tc?"number":e instanceof wc?"boolean":e instanceof Cc?"date":e instanceof Rc?"jsonb":"unknown"}async function Mc(e,n){let t=await e.introspection.getTables(),r=new Set(t.map(o=>o.name));for(let[o,i]of Object.entries(Oc))r.has(o)||n(`[corsair:setup] Table "${o}" does not exist. Run your database migrations before calling setupCorsair.
|
|
64
|
+
Schema: ${JSON.stringify(Rt(i),null,2)}`)}async function Hc(e,n,t,r,o){let i=new Date,s=new Map;for(let a of n.plugins){let u=a.id,l=T(a),c=await e.selectFrom("corsair_integrations").selectAll().where("name","=",u).executeTakeFirst();if(!c){let y=crypto.randomUUID();await e.insertInto("corsair_integrations").values({id:y,name:u,config:{},created_at:i,updated_at:i}).execute(),c=await e.selectFrom("corsair_integrations").selectAll().where("id","=",y).executeTakeFirst(),o(`[corsair:setup] Created integration: ${u}`)}let d=l?a.authConfig?.[l]?.integration??[]:[],p=l?a.authConfig?.[l]?.account??[]:[],g=l&&c?M({authType:l,integrationName:u,kek:n.kek,database:n.database,extraIntegrationFields:d}):void 0;if(c&&!c.dek&&g&&(await g.issue_new_dek(),o(`[corsair:setup] Issued integration DEK: ${u}`)),!c||!l||!g)continue;let f;if(r){let y=await e.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",t).where("integration_id","=",c.id).executeTakeFirst();if(!y){let h=crypto.randomUUID();await e.insertInto("corsair_accounts").values({id:h,tenant_id:t,integration_id:c.id,config:{},created_at:i,updated_at:i}).execute(),y=await e.selectFrom("corsair_accounts").selectAll().where("id","=",h).executeTakeFirst(),o(`[corsair:setup] Created account: ${u}`)}f=y&&D({authType:l,integrationName:u,tenantId:t,kek:n.kek,database:n.database,extraAccountFields:p}),y&&f&&!y.dek&&(await f.issue_new_dek(),o(`[corsair:setup] Issued account DEK: ${u}`))}s.set(u,{pluginId:u,authType:l,integration:g,account:f,integrationFields:[...F[l].integration,...d],accountFields:r?[...F[l].account,...p]:[]})}return s}function Fc(e){if(!ye(e))return;let n=e.keys;return ye(n)?n:void 0}function Uc(e,n){return"withTenant"in e&&typeof e.withTenant=="function"?e.withTenant(n):e}async function Bc(e,n,t,r,o,i){let s=Fc(e),a=n.provisionAccounts?Uc(e,n.tenantId):void 0;for(let[u,l]of Object.entries(t)){let c=r.plugins.find(m=>m.id===u);if(!c){i(`[corsair:setup] Unknown plugin '${u}' \u2014 skipping credentials.`);continue}let d=T(c);if(!d){i(`[corsair:setup] Plugin '${u}' has no auth type \u2014 skipping credentials.`);continue}let p=so(c,d,"integration"),g=so(c,d,"account"),f=s?.[u],y=a?.[u],h=ye(y)?y.keys:void 0;for(let[m,b]of Object.entries(l))if(b){if(p.has(m)){if(n.multiTenant&&n.tenantIdProvided)throw new Error(`[corsair:setup] '${u}.${m}' is an integration-level credential shared across all tenants. You passed tenantId="${n.tenantId}", which only scopes account-level credentials. Run setup without --tenant if you intend to change this credential globally.`);let C=$(f,`set_${m}`);if(!C){i(`[corsair:setup] Cannot set integration field '${m}' for '${u}'.`);continue}await C(b),o(`[corsair:setup] Set ${u} integration.${m}`);continue}if(g.has(m)){if(n.multiTenant&&!n.tenantIdProvided)throw new Error(`setupCorsair: tenantId is required to set account-level credential '${u}.${m}' on a multi-tenant instance`);let C=$(h,`set_${m}`);if(!C){i(`[corsair:setup] Cannot set account field '${m}' for '${u}'.`);continue}await C(b),o(`[corsair:setup] Set ${u} account.${m} (tenant=${n.tenantId})`);continue}i(`[corsair:setup] Unknown credential field '${m}' for plugin '${u}'.`)}}}var _s=new Set(["webhook_signature","expires_at","scope","redirect_url"]);async function Lc(e,n,t,r,o,i,s,a,u){let l=[],c=[];for(let p of o){if(_s.has(p))continue;let g=$(t,`get_${p}`);if(!g)continue;let f=null;try{let y=await g();f=typeof y=="string"?y:null}catch{}f||l.push(p)}if(r&&i.length>0)for(let p of i){if(_s.has(p))continue;let g=$(r,`get_${p}`);if(!g)continue;let f=null;try{let y=await g();f=typeof y=="string"?y:null}catch{}f||c.push(p)}let d=l.length===0&&c.length===0;if(d)a(`[corsair:setup] '${e}' (${n}) is configured \u2713`);else if(n==="managed")a(`[corsair:setup] '${e}' (managed) is not connected yet. Use Connect in your app \u2014 Corsair Hub delivers OAuth tokens after authorization.`);else{let p=[...l,...c];if(u==="cli"){let g=p.map(f=>`${f}=VALUE`).join(" ");a(`[corsair:setup] '${e}' (${n}) needs credentials. Run:
|
|
65
|
+
corsair setup --${e} ${g}`)}else{let g=[`[corsair:setup] '${e}' (${n}) needs credentials. Call:`];for(let f of l)g.push(` await corsair.keys.${e}.set_${f}(value)`);for(let f of c){let y=s.provisionAccounts?s.tenantId==="default"?`corsair.${e}`:`corsair.withTenant(${JSON.stringify(s.tenantId)}).${e}`:`corsair.withTenant(<tenant>).${e}`;g.push(` await ${y}.keys.set_${f}(value)`)}a(g.join(`
|
|
66
|
+
`))}}return d}async function Nc(e,n,t,r){let o=new Set;for(let i of e.values())await Lc(i.pluginId,i.authType,i.integration,i.account,i.integrationFields,i.accountFields,n,t,r)&&o.add(i.pluginId);return o}async function $c(e,n,t,r,o){if(!Dc(io)){o("[corsair:setup] Backfill config is invalid - skipping backfill.");return}let i=io,s=new Set(n.map(a=>a.id));for(let[a,u]of Object.entries(i)){if(!s.has(a))continue;if(!t.has(a)){r(`[corsair:setup] Skipping backfill for '${a}' \u2014 auth not configured.`);continue}let l=ye(e)?e[a]:void 0,c=ye(l)?l.api:void 0;if(c)for(let[d,p]of Object.entries(u))for(let[g,f]of Object.entries(p)){r(`[corsair:setup] Backfilling ${a} \u203A ${d}.${g}...`);try{let y=ye(c)?c[d]:void 0;await $(y,g)?.(f)}catch(y){o(`[corsair:setup] ${a} \u203A ${d}.${g} failed: `+(y instanceof Error?y.message:String(y)))}}}}export{ho as a,me as b,Rn as c,In as d,Sn as e,_n as f,ko as g,En as h,Ut as i,rn as j,To as k,Ao as l,he as m,Re as n,ie as o,Ue as p,Be as q,ke as r,Lt as s,Ro as t,an as u,se as v,Mn as w,O as x,Hn as y,Le as z,ae as A,ue as B,Z as C,Nt as D,cn as E,be as F,ce as G,ln as H,M as I,D as J,Mo as K,Ho as L,Kn as M,Bc as N,Ce as O,Wt as P,We as Q,je as R,Kt as S,Wn as T,qo as U,_e as V,L as W,qt as X,fn as Y,Jo as Z,ya as _,qn as $,Td as aa,Qo as ba,Xo as ca,ei as da,Zt as ea,Zn as fa,Gt as ga,zn as ha,Jn as ia,Ge as ja,Yn as ka,Xt as la,oi as ma,er as na,sr as oa,ar as pa,st as qa,ur as ra,Ve as sa,Ye as ta,at as ua,ut as va,yn as wa,cr as xa,lr as ya,ct as za,mn as Aa,lt as Ba,dt as Ca,Pe as Da,Qe as Ea,bi as Fa,yr as Ga,mr as Ha,De as Ia,bn as Ja,wn as Ka,kt as La,br as Ma,Cn as Na,Cu as Oa,xu as Pa,Su as Qa,Si as Ra,_i as Sa,Pr as Ta,Tr as Ua,Ar as Va,xr as Wa,Rr as Xa,Oe as Ya,W as Za,Ir as _a,Hi as $a,Fi as ab,Sr as bb,_r as cb,Er as db,Dr as eb,Or as fb,Mr as gb,Hr as hb,Fr as ib,Ur as jb,Br as kb,Lr as lb,Nr as mb,$r as nb,Wr as ob,jr as pb,Me as qb,ss as rb,as as sb,us as tb,ls as ub,Xu as vb,jn as wb,Cm as xb,He as yb,vm as zb,vt as Ab,uc as Bb,cc as Cb,Tt as Db,pc as Eb,vs as Fb,gc as Gb,fc as Hb,Ps as Ib,Ts as Jb,Pn as Kb,yc as Lb,As as Mb,xs as Nb,mc as Ob,At as Pb,hc as Qb,vn as Rb,Ss as Sb,kc as Tb};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{da as a,ea as b,fa as c}from"./chunk-
|
|
1
|
+
import{da as a,ea as b,fa as c}from"./chunk-EF32RW4S.js";import"./chunk-3EPM4FJ3.js";import"./chunk-WDF3YE27.js";import"./chunk-IGGCNGU2.js";import"./chunk-QAIKSQAD.js";export{c as createHubConnectSession,b as createHubConnectSessionForPlugin,a as postHubConnectSession};
|
package/dist/core.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export { C as CORSAIR_INTERNAL, a as CorsairInternalConfig, c as createCorsair, s as shouldStartTunnel } from './index-
|
|
1
|
+
export { C as CORSAIR_INTERNAL, a as CorsairInternalConfig, c as createCorsair, s as shouldStartTunnel } from './index-B2XsUjnW.js';
|
|
2
2
|
import { CorsairDatabase } from './db.js';
|
|
3
|
-
import { A as AccountKeyManagerFor, I as IntegrationKeyManagerFor, f as CorsairPluginSubscribeResult } from './index-
|
|
4
|
-
export { g as AccountFieldNames,
|
|
5
|
-
export { A as AuthMissingError, D as DocSchemaFieldRow, a as DocSchemaShape, b as DocsApiEndpoint, c as DocsDbEntity, d as DocsDbFilterField, e as DocsWebhook, E as EndpointSchemaResult, I as IntrospectPluginForDocsResult, L as ListOperationsOptions, g as PermissionRequiredError, P as PluginDocsIntrospection, k as PluginWebhookMatchers, R as ResolveConnectLinkResult, W as WebhookPluginTenantMatch, l as asRecord, h as collectPluginWebhookMatchers, n as decodePubSubData, o as extractMicrosoftGraphValidationToken, p as firstString, f as formatDocSchemaShape, q as getHeader, i as introspectPluginForDocs, s as isMicrosoftGraphValidationHandshake, m as matchWebhookPlugin, j as matchWebhookPluginAndTenant, t as readBodyRecord, u as readQueryParam, r as resolveConnectLink, v as toExternalId } from './tenant-match-utils-
|
|
3
|
+
import { A as AccountKeyManagerFor, I as IntegrationKeyManagerFor, f as CorsairPluginSubscribeResult } from './index-B-FvI2-D.js';
|
|
4
|
+
export { g as AccountFieldNames, m as AgentMessageRole, n as AgentReply, k as BASE_AUTH_FIELDS, B as BaseAuthFieldConfig, h as BaseKeyManager, Y as BeforeHookResult, u as BindEndpoints, aj as BindWebhooks, ah as Bivariant, v as BoundEndpointFn, w as BoundEndpointTree, ak as BoundWebhook, al as BoundWebhookTree, o as ChatHandle, p as ChatMessage, q as ChatSummary, r as CorsairChatsNamespace, t as CorsairClient, x as CorsairContext, y as CorsairEndpoint, D as CorsairErrorHandler, c as CorsairIntegration, Z as CorsairKeyBuilder, _ as CorsairKeyBuilderBase, am as CorsairOAuthWebhookTenantLinkResolver, M as CorsairPermissionsNamespace, C as CorsairPlugin, $ as CorsairPluginContext, a0 as CorsairPluginSubscribe, ad as CorsairRunsNamespace, e as CorsairSingleTenantClient, d as CorsairTenantWrapper, an as CorsairWebhook, ao as CorsairWebhookHandler, ap as CorsairWebhookMatcher, aq as CorsairWebhookTenantMatcher, aw as CorsairWorkflowsNamespace, s as CreateChatResult, a1 as EndpointHooks, a2 as EndpointMetaEntry, E as EndpointPathsOf, a3 as EndpointRiskLevel, z as EndpointTree, N as EnforcePermissionOptions, Q as EnforcePermissionResult, F as ErrorContext, G as ErrorHandler, J as ErrorHandlerAndMatchFunction, K as ErrorMatcher, i as IntegrationFieldNames, a4 as KeyBuilderContext, j as OAuth2IntegrationCredentials, O as OAuthConfig, a5 as PermissionMode, a6 as PermissionPolicy, P as PluginAuthConfig, a7 as PluginEndpointMeta, a8 as PluginPermissionsConfig, ar as RawWebhookRequest, V as ReadonlyForbiddenError, a9 as RequiredPluginEndpointMeta, aa as RequiredPluginEndpointSchemas, ab as RequiredPluginWebhookSchemas, R as RetryStrategies, L as RetryStrategy, T as TokenResponse, ax as TriggerRunResult, ai as UnionToIntersection, ac as WebhookHooks, as as WebhookPathsOf, at as WebhookRequest, au as WebhookResponse, W as WebhookTenantMatch, av as WebhookTree, ae as WorkflowRun, af as WorkflowRunStatus, ag as WorkflowRunStep, ay as WorkflowStatus, az as WorkflowSummary, S as assertReadonlyAllowed, l as exchangeCodeForTokens, U as isReadonlyScopeActive, X as runReadonly } from './index-B-FvI2-D.js';
|
|
5
|
+
export { A as AuthMissingError, D as DocSchemaFieldRow, a as DocSchemaShape, b as DocsApiEndpoint, c as DocsDbEntity, d as DocsDbFilterField, e as DocsWebhook, E as EndpointSchemaResult, I as IntrospectPluginForDocsResult, L as ListOperationsOptions, g as PermissionRequiredError, P as PluginDocsIntrospection, k as PluginWebhookMatchers, R as ResolveConnectLinkResult, W as WebhookPluginTenantMatch, l as asRecord, h as collectPluginWebhookMatchers, n as decodePubSubData, o as extractMicrosoftGraphValidationToken, p as firstString, f as formatDocSchemaShape, q as getHeader, i as introspectPluginForDocs, s as isMicrosoftGraphValidationHandshake, m as matchWebhookPlugin, j as matchWebhookPluginAndTenant, t as readBodyRecord, u as readQueryParam, r as resolveConnectLink, v as toExternalId } from './tenant-match-utils-Bu6w6L7r.js';
|
|
6
6
|
import { A as AuthTypes } from './types-3hs1SH6L.js';
|
|
7
7
|
export { g as AllProviders, B as BaseProviders, h as PickAuth, j as ProviderDisplayNames, i as formatProviderDisplayName } from './types-3hs1SH6L.js';
|
|
8
8
|
import 'kysely';
|
package/dist/core.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{A as d,Ab as z,B as e,Bb as A,C as f,Cb as B,D as g,Db as C,E as h,Eb as D,F as i,Fb as E,G as j,Gb as F,H as k,Hb as G,I as l,Ib as H,J as m,Jb as I,K as n,Kb as J,L as o,Lb as K,Mb as L,Nb as M,Ob as N,Pb as O,Qb as P,Rb as Q,Sb as R,Tb as S,Za as v,a,b,ga as p,ja as q,ka as r,la as s,ma as t,na as u,ub as w,vb as x,wb as y}from"./chunk-
|
|
1
|
+
import{A as d,Ab as z,B as e,Bb as A,C as f,Cb as B,D as g,Db as C,E as h,Eb as D,F as i,Fb as E,G as j,Gb as F,H as k,Hb as G,I as l,Ib as H,J as m,Jb as I,K as n,Kb as J,L as o,Lb as K,Mb as L,Nb as M,Ob as N,Pb as O,Qb as P,Rb as Q,Sb as R,Tb as S,Za as v,a,b,ga as p,ja as q,ka as r,la as s,ma as t,na as u,ub as w,vb as x,wb as y}from"./chunk-EF32RW4S.js";import"./chunk-3EPM4FJ3.js";import{h as c}from"./chunk-WDF3YE27.js";import"./chunk-IGGCNGU2.js";import"./chunk-QAIKSQAD.js";export{v as AuthMissingError,c as BASE_AUTH_FIELDS,Q as CORSAIR_INTERNAL,C as MS_GRAPH_API_BASE,q as PermissionRequiredError,a as ProviderDisplayNames,r as ReadonlyForbiddenError,J as asRecord,u as assertReadonlyAllowed,G as collectPluginWebhookMatchers,m as createAccountKeyManager,R as createCorsair,l as createIntegrationKeyManager,P as decodePubSubData,j as decryptConfig,f as decryptDEK,h as decryptWithDEK,i as encryptConfig,e as encryptDEK,g as encryptWithDEK,y as exchangeCodeForTokens,M as extractMicrosoftGraphValidationToken,O as firstString,z as formatDocSchemaShape,b as formatProviderDisplayName,d as generateDEK,H as getHeader,B as googleChannelSubscribe,o as initializeAccountDEK,n as initializeIntegrationDEK,A as introspectPluginForDocs,N as isMicrosoftGraphValidationHandshake,t as isReadonlyScopeActive,w as logEvent,x as logEventFromContext,E as matchWebhookPlugin,F as matchWebhookPluginAndTenant,D as msGraphSubscribe,k as reEncryptConfig,K as readBodyRecord,L as readQueryParam,p as resolveConnectLink,s as runReadonly,S as shouldStartTunnel,I as toExternalId};
|
package/dist/hub.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { A as AuthTypes } from './types-3hs1SH6L.js';
|
|
2
2
|
export { i as formatProviderDisplayName } from './types-3hs1SH6L.js';
|
|
3
|
-
import {
|
|
4
|
-
export {
|
|
5
|
-
import { k as TunnelType, R as RunResultPayload, P as ProbeResultPayload, g as ProcessCorsairRequest, m as WebhookTenantLink } from './index
|
|
6
|
-
export { n as BROWSER_DELIVERY_TTL_MS, o as BrowserDeliveryMode, B as BrowserDeliveryPayload, S as SIGNED_TUNNEL_REPLAY_WINDOW_MS, j as TunnelEnvelope } from './index
|
|
7
|
-
export { b as buildBrowserDeliveryRedirectUrl, s as signBrowserDeliveryToken, v as verifyBrowserDeliveryToken } from './browser-delivery-
|
|
3
|
+
import { aB as HubOAuthMode, aC as HubConnectSessionResult, aD as HubPermissionSessionResult, H as HubConfig, aE as HubConfigInput, aF as HubConnectSessionInput, aG as HubListProjectConnectionsInput, A as AccountKeyManagerFor, aH as HubPermissionSessionInput } from './index-B-FvI2-D.js';
|
|
4
|
+
export { aI as DEFAULT_HUB_API_URL, aJ as HubEnvironmentSlug } from './index-B-FvI2-D.js';
|
|
5
|
+
import { k as TunnelType, R as RunResultPayload, P as ProbeResultPayload, g as ProcessCorsairRequest, m as WebhookTenantLink } from './index-z0tnVuER.js';
|
|
6
|
+
export { n as BROWSER_DELIVERY_TTL_MS, o as BrowserDeliveryMode, B as BrowserDeliveryPayload, S as SIGNED_TUNNEL_REPLAY_WINDOW_MS, j as TunnelEnvelope } from './index-z0tnVuER.js';
|
|
7
|
+
export { b as buildBrowserDeliveryRedirectUrl, s as signBrowserDeliveryToken, v as verifyBrowserDeliveryToken } from './browser-delivery-Bvf8JqTz.js';
|
|
8
8
|
import './index-eydqYIn0.js';
|
|
9
9
|
import 'zod';
|
|
10
10
|
import './db.js';
|
|
@@ -13,57 +13,6 @@ import 'pg';
|
|
|
13
13
|
import 'postgres';
|
|
14
14
|
import './orm.js';
|
|
15
15
|
|
|
16
|
-
type HubEnvironmentSlug = 'development' | 'production';
|
|
17
|
-
type DeliveryTransport = 'browser' | 'server';
|
|
18
|
-
declare function isLoopbackUrl(url: string): boolean;
|
|
19
|
-
declare function resolveDeliveryTransport(slug: HubEnvironmentSlug): DeliveryTransport;
|
|
20
|
-
declare function usesBrowserDelivery(slug: HubEnvironmentSlug): boolean;
|
|
21
|
-
declare function validateProductionDeliveryUrl(deliveryUrl: string): string | null;
|
|
22
|
-
|
|
23
|
-
type ClientBridgeDeliverySpec = {
|
|
24
|
-
deliveryMode: 'connections.sync';
|
|
25
|
-
deliveryUrl: string;
|
|
26
|
-
projectId: string;
|
|
27
|
-
signingSecret: string;
|
|
28
|
-
hubOrigin: string;
|
|
29
|
-
requestId: string;
|
|
30
|
-
} | {
|
|
31
|
-
deliveryMode: 'connect.create_link';
|
|
32
|
-
deliveryUrl: string;
|
|
33
|
-
projectId: string;
|
|
34
|
-
signingSecret: string;
|
|
35
|
-
hubOrigin: string;
|
|
36
|
-
requestId: string;
|
|
37
|
-
tenantId: string;
|
|
38
|
-
plugins: string[];
|
|
39
|
-
};
|
|
40
|
-
type ClientBridgeTransportResult = {
|
|
41
|
-
transport: 'server';
|
|
42
|
-
} | {
|
|
43
|
-
transport: 'browser';
|
|
44
|
-
deliveryUrl: string;
|
|
45
|
-
requestId: string;
|
|
46
|
-
};
|
|
47
|
-
declare function buildClientBridgeBrowserDeliveryUrl(spec: ClientBridgeDeliverySpec): string;
|
|
48
|
-
type PrepareClientBridgeDeliveryTransportInput = {
|
|
49
|
-
deliveryMode: 'connections.sync';
|
|
50
|
-
deliveryUrl: string;
|
|
51
|
-
projectId: string;
|
|
52
|
-
signingSecret: string;
|
|
53
|
-
hubOrigin?: string;
|
|
54
|
-
environmentSlug: HubEnvironmentSlug;
|
|
55
|
-
} | {
|
|
56
|
-
deliveryMode: 'connect.create_link';
|
|
57
|
-
deliveryUrl: string;
|
|
58
|
-
projectId: string;
|
|
59
|
-
signingSecret: string;
|
|
60
|
-
hubOrigin?: string;
|
|
61
|
-
environmentSlug: HubEnvironmentSlug;
|
|
62
|
-
tenantId: string;
|
|
63
|
-
plugins: string[];
|
|
64
|
-
};
|
|
65
|
-
declare function prepareClientBridgeDeliveryTransport(spec: PrepareClientBridgeDeliveryTransportInput): ClientBridgeTransportResult;
|
|
66
|
-
|
|
67
16
|
type ConnectAuthKind = 'oauth' | 'api_key' | 'bot_token';
|
|
68
17
|
type ConnectPluginManifestEntry = {
|
|
69
18
|
plugin: string;
|
|
@@ -135,6 +84,57 @@ declare function parseOAuthRefreshResponse(payload: unknown): HubOAuthRefreshRes
|
|
|
135
84
|
declare function parseConnectStatusResponse(payload: unknown): ConnectStatusResponse;
|
|
136
85
|
declare function parseHubApiErrorBody(payload: unknown): string | null;
|
|
137
86
|
|
|
87
|
+
type HubEnvironmentSlug = 'development' | 'production';
|
|
88
|
+
type DeliveryTransport = 'browser' | 'server';
|
|
89
|
+
declare function isLoopbackUrl(url: string): boolean;
|
|
90
|
+
declare function resolveDeliveryTransport(slug: HubEnvironmentSlug): DeliveryTransport;
|
|
91
|
+
declare function usesBrowserDelivery(slug: HubEnvironmentSlug): boolean;
|
|
92
|
+
declare function validateProductionDeliveryUrl(deliveryUrl: string): string | null;
|
|
93
|
+
|
|
94
|
+
type ClientBridgeDeliverySpec = {
|
|
95
|
+
deliveryMode: 'connections.sync';
|
|
96
|
+
deliveryUrl: string;
|
|
97
|
+
projectId: string;
|
|
98
|
+
signingSecret: string;
|
|
99
|
+
hubOrigin: string;
|
|
100
|
+
requestId: string;
|
|
101
|
+
} | {
|
|
102
|
+
deliveryMode: 'connect.create_link';
|
|
103
|
+
deliveryUrl: string;
|
|
104
|
+
projectId: string;
|
|
105
|
+
signingSecret: string;
|
|
106
|
+
hubOrigin: string;
|
|
107
|
+
requestId: string;
|
|
108
|
+
tenantId: string;
|
|
109
|
+
plugins: string[];
|
|
110
|
+
};
|
|
111
|
+
type ClientBridgeTransportResult = {
|
|
112
|
+
transport: 'server';
|
|
113
|
+
} | {
|
|
114
|
+
transport: 'browser';
|
|
115
|
+
deliveryUrl: string;
|
|
116
|
+
requestId: string;
|
|
117
|
+
};
|
|
118
|
+
declare function buildClientBridgeBrowserDeliveryUrl(spec: ClientBridgeDeliverySpec): string;
|
|
119
|
+
type PrepareClientBridgeDeliveryTransportInput = {
|
|
120
|
+
deliveryMode: 'connections.sync';
|
|
121
|
+
deliveryUrl: string;
|
|
122
|
+
projectId: string;
|
|
123
|
+
signingSecret: string;
|
|
124
|
+
hubOrigin?: string;
|
|
125
|
+
environmentSlug: HubEnvironmentSlug;
|
|
126
|
+
} | {
|
|
127
|
+
deliveryMode: 'connect.create_link';
|
|
128
|
+
deliveryUrl: string;
|
|
129
|
+
projectId: string;
|
|
130
|
+
signingSecret: string;
|
|
131
|
+
hubOrigin?: string;
|
|
132
|
+
environmentSlug: HubEnvironmentSlug;
|
|
133
|
+
tenantId: string;
|
|
134
|
+
plugins: string[];
|
|
135
|
+
};
|
|
136
|
+
declare function prepareClientBridgeDeliveryTransport(spec: PrepareClientBridgeDeliveryTransportInput): ClientBridgeTransportResult;
|
|
137
|
+
|
|
138
138
|
declare class HubNotConfiguredError extends Error {
|
|
139
139
|
constructor();
|
|
140
140
|
}
|