corsair 0.1.113 → 0.1.114

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.
@@ -1,4 +1,4 @@
1
- import { B as BrowserDeliveryPayload } from './index-CsNw9hYU.js';
1
+ import { B as BrowserDeliveryPayload } from './index-CnwB37Yx.js';
2
2
 
3
3
  /**
4
4
  * Browser (client) delivery — hub redirects the user's browser to the app with `?d=<token>`.
@@ -0,0 +1,66 @@
1
+ import{a as io,b as fe,c as so,d as w,e as U,f as ao,g as N,h as F,i as P,j as An,k as uo,l as co,m as Rt,n as lo,o as po}from"./chunk-WDF3YE27.js";import{a as oo}from"./chunk-IGGCNGU2.js";import{ZodBoolean as gc,ZodDate as fc,ZodEnum as yc,ZodNullable as mc,ZodNumber as hc,ZodObject as bc,ZodOptional as kc,ZodRecord as wc,ZodString as Cc,ZodType as vc}from"zod";var xn=["abstract","activetrail","addresszen","agencyzoom","agentmail","agentql","ahrefs","airtable","algolia","alttextai","amplitude","apilabz","asana","bitwarden","bluesky","box","cal","calendly","canva","cloudflare","cloudinary","confluence","cursor","databricks","datadog","deepseek","digitalocean","discord","dodopayments","dropbox","exa","facebook","figma","firecrawl","fireflies","gemini","github","gitlab","gmail","googlebigquery","googlecalendar","googledocs","googledrive","googlemaps","googlemeet","googlesheets","grafana","hackernews","hashnode","heygen","hubspot","insightoai","instagram","intercom","jira","linear","linkedin","mailchimp","monday","neon","notion","ollama","onedrive","onepassword","openai","openweathermap","oura","outlook","pagerduty","perplexityai","posthog","razorpay","reddit","resend","retailed","sentry","sharepoint","slack","spotify","strava","stripe","supabase","tally","tavily","teams","telegram","todoist","trello","twilio","twitter","twitterapiio","typeform","vapi","vercel","whatsapp","wiza","xquik","youtube","zendesk","zohomail","zoom"],go={abstract:"Abstract",activetrail:"Active Trail",addresszen:"Addresszen",agencyzoom:"AgencyZoom",agentmail:"AgentMail",agentql:"AgentQL",ahrefs:"Ahrefs",airtable:"Airtable",algolia:"Algolia",alttextai:"AltText.ai",amplitude:"Amplitude",apilabz:"API Labz",asana:"Asana",bitwarden:"Bitwarden",bluesky:"Bluesky",box:"Box",cal:"Cal",calendly:"Calendly",canva:"Canva",cloudflare:"Cloudflare",cloudinary:"Cloudinary",confluence:"Confluence",cursor:"Cursor",databricks:"Databricks",datadog:"Datadog",deepseek:"DeepSeek",digitalocean:"DigitalOcean",discord:"Discord",dodopayments:"Dodo Payments",dropbox:"Dropbox",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",hashnode:"Hashnode",heygen:"HeyGen",hubspot:"HubSpot",insightoai:"Insighto.ai",instagram:"Instagram",intercom:"Intercom",jira:"Jira",linear:"Linear",linkedin:"LinkedIn",mailchimp:"Mailchimp",monday:"Monday",neon:"Neon",notion:"Notion",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",sentry:"Sentry",sharepoint:"SharePoint",slack:"Slack",spotify:"Spotify",strava:"Strava",stripe:"Stripe",supabase:"Supabase",tally:"Tally",tavily:"Tavily",teams:"Teams",telegram:"Telegram",todoist:"Todoist",trello:"Trello",twilio:"Twilio",twitter:"Twitter",twitterapiio:"Twitter API IO",typeform:"Typeform",vapi:"Vapi",vercel:"Vercel",whatsapp:"WhatsApp",wiza:"Wiza",xquik:"XQuik",youtube:"YouTube",zendesk:"Zendesk",zohomail:"Zoho Mail",zoom:"Zoom"};function ye(e){let n=go[e];return n||e.charAt(0).toUpperCase()+e.slice(1)}import{randomUUID as Ss}from"crypto";var Ts="corsair:client-bridge";function It(e){return new URL(e).origin}function Fe(e){let n=JSON.stringify({type:Ts,requestId:e.requestId,ok:e.ok,body:e.body??null,error:e.error??null}),t=JSON.stringify(It(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 Ps=new Set(["localhost","127.0.0.1","[::1]","::1"]);function St(e){try{let{hostname:n,protocol:t}=new URL(e);return t!=="http:"&&t!=="https:"?!1:Ps.has(n)}catch{return!1}}function rn(e){return e==="development"?"browser":"server"}function fo(e){return rn(e)==="browser"}function yo(e){return St(e)?"Production delivery URL must be a public URL, not localhost":null}import{randomBytes as Is}from"crypto";var me=60*1e3,Re=300*1e3;import{createHmac as As,randomBytes as xs,timingSafeEqual as Rs}from"crypto";function ie(){return xs(16).toString("base64url")}function on(e,n){let t=n.trim();if(!t)throw new Error("Signing secret is required");return As("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(!Rs(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 Rn(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 Rn(e,n,r+Math.floor(t/1e3))}function Ie(e){return decodeURIComponent(e)}function _t(e){return encodeURIComponent(e).replace(/\./g,"%2E")}function mo(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(!mo(n))throw new Error("Signing secret is required for browser delivery tokens");let t=Math.floor(Date.now()/1e3),r={...e,jti:e.jti??Is(16).toString("base64url"),iat:t,exp:t+Math.floor(me/1e3)},o=Buffer.from(JSON.stringify(r)).toString("base64url"),i=on(o,n);return`${o}.${i}`}function he(e,n){return mo(n)?ee(e,n):null}function _s(e){let n=It(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 Et(e){let n=Be(_s(e),e.signingSecret);return Ue(e.deliveryUrl,n)}function ho(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=Ss(),r={...e,hubOrigin:e.hubOrigin,requestId:t};return{transport:"browser",requestId:t,deliveryUrl:Et(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 In(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}}function Es(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||!Es(n))throw new se;return n}function bo(e){return e.replace(/\/$/,"")}function Sn(e){return e.oauthCallbackUrl?bo(e.oauthCallbackUrl.trim()):`${bo(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)")}function x(e){return typeof e=="string"&&e.length>0}function Ds(e){return e==="ready"||e==="partial"||e==="not_started"||e==="missing_integration"}function Os(e){return e==="oauth_2"||e==="api_key"||e==="bot_token"||e==="managed"}function _n(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 En(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)||!Ds(r.status)||!Os(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 Dn(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 On(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 Ms(e){return Array.isArray(e)?e.filter(n=>typeof n=="string"):[]}function Hs(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 Fs(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=Hs(o.fields),a=Ms(o.missingRequiredFields),u=Fs(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 Mn(e){if(!e||typeof e!="object")return null;let n=e;return n.error??n.message??null}var Us="3000",Bs="/api/corsair";function Ls(e){return e.replace(/\/$/,"")}function be(e){let n=e?.deliveryUrl?.trim()||process.env.CORSAIR_DELIVERY_URL?.trim();if(n){let r=/^https?:\/\//i.test(n)?n:`https://${n}`;return Ls(r)}return`http://localhost:${process.env.PORT?.trim()||Us}${Bs}`}function wo(e){return e.replace(/\/$/,"")}function Dt(e){if(!e.projectApiKey.startsWith("ck_dev_"))return null;try{return be()}catch{return null}}function Co(e){let n=Dt(e);return n?{"x-corsair-delivery-url":n}:{}}async function vo(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 To(e,n,t){if(n===404&&t)return t;let r=Mn(e);return r||`Hub API returned HTTP ${n}`}async function _(e){let n=wo(e.hub.apiUrl),t=await fetch(`${n}${e.path}`,{method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${e.hub.projectApiKey}`,...Co(e.hub)},body:JSON.stringify(e.body)}),r=await vo(t);if(!t.ok)throw new Error(To(r,t.status,e.notFoundMessage));return e.parseResponse(r)}async function $(e){let n=wo(e.hub.apiUrl),t=await fetch(`${n}${e.path}`,{method:"GET",headers:{authorization:`Bearer ${e.hub.projectApiKey}`,...Co(e.hub)}}),r=await vo(t);if(!t.ok)throw new Error(To(r,t.status,e.notFoundMessage));return e.parseResponse(r)}import{createCipheriv as Po,createDecipheriv as Ao,randomBytes as Hn,scrypt as Ns}from"crypto";import{promisify as $s}from"util";var xo=$s(Ns),Fn="aes-256-gcm",Ro=12,Un=16,Ws=16,un=32;function ae(){return Hn(un).toString("base64")}async function ue(e,n){let t=Hn(Ws),r=await xo(n,t,un),o=Hn(Ro),i=Po(Fn,r,o,{authTagLength:Un}),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 xo(n,s,un),p=Ao(Fn,c,a,{authTagLength:Un});return p.setAuthTag(u),Buffer.concat([p.update(l),p.final()]).toString("utf8")}function Ot(e,n){let t=Buffer.from(n,"base64"),r=Hn(Ro),o=Po(Fn,t,r,{authTagLength:Un}),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=Ao(Fn,i,s,{authTagLength:Un});return l.setAuthTag(a),Buffer.concat([l.update(u),l.final()]).toString("utf8")}function ke(e,n){let t={};for(let[r,o]of Object.entries(e))t[r]=Ot(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 ke(r,t)}function Io(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 Mt=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:Mt(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},p=async()=>{let h=await u.getIntegration(),m=await c(),k=h.config;return!k||Object.keys(k).length===0?{}:ce(k,m)},d=Promise.resolve(),g=h=>{let m=d.then(()=>f(h));return d=m.catch(()=>{}),m},f=async h=>{let m=await c(),k;try{k=await p()}catch(R){console.error(`[corsair] Failed to decrypt config for integration "${t}", starting fresh:`,R),k={}}let C={...k};for(let[R,E]of Object.entries(h))E===null?delete C[R]:C[R]=E;let S=ke(C,m);await u.updateIntegration({config:S})};return{get_dek:c,issue_new_dek:async()=>{let h=await u.getIntegration(),m=ae(),k={};if(h.dek){let S=await Z(h.dek,r),R=h.config;R&&Object.keys(R).length>0&&(k=ln(R,S,m))}let C=await ue(m,r);return await u.updateIntegration({config:k,dek:C}),l=m,m},...Io(p,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,p=async()=>{if(c)return c;let b=!1;for(;;){let v=await i.db.selectFrom("corsair_integrations").selectAll().where("name","=",t).executeTakeFirst();if(!v){if(!b&&a){b=!0,await a();continue}throw new Error(`Integration "${t}" not found. Make sure to create the integration first.`)}return c={id:v.id,config:Mt(v.config),dek:v.dek??null},c}},d={kek:o,integrationName:t,tenantId:r,getIntegration:p,getAccount:async()=>{if(l)return l;let b=!1;for(;;){let v=await p(),T=await i.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",r).where("integration_id","=",v.id).executeTakeFirst();if(!T){if(!b&&a){b=!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:T.id,config:Mt(T.config),dek:T.dek??null},l}},updateAccount:async b=>{let v=await d.getAccount();await i.db.updateTable("corsair_accounts").set({...b.config!==void 0?{config:b.config}:{},...b.dek!==void 0?{dek:b.dek}:{},updated_at:new Date}).where("id","=",v.id).execute(),l=null}},g=null,f=null,y=async()=>{if(g)return g;let b=await d.getAccount();if(!b.dek)throw new Error(`No DEK found for account (tenant: "${r}", integration: "${t}"). Initialize the account first.`);return g=await Z(b.dek,o),g},h=async()=>{if(f)return f;let b=await d.getIntegration();if(!b.dek)throw new Error(`No DEK found for integration "${t}". Initialize the integration first.`);return f=await Z(b.dek,o),f},m=async()=>{let b=await d.getAccount(),v=await y(),T=b.config;return!T||Object.keys(T).length===0?{}:ce(T,v)},k=async()=>{let b=await d.getIntegration(),v=await h(),T=b.config;return!T||Object.keys(T).length===0?{}:ce(T,v)},C=Promise.resolve(),S=b=>{let v=C.then(()=>R(b));return C=v.catch(()=>{}),v},R=async b=>{let v=await y(),T;try{T=await m()}catch(A){console.error(`[corsair] Failed to decrypt config for account (tenant: "${r}", integration: "${t}"), starting fresh:`,A),T={}}let j={...T};for(let[A,Y]of Object.entries(b))Y===null?delete j[A]:j[A]=Y;let re=ke(j,v);await d.updateAccount({config:re})},E={get_dek:y,issue_new_dek:async()=>{let b=await d.getAccount(),v=ae(),T={};if(b.dek){let re=await Z(b.dek,o),A=b.config;A&&Object.keys(A).length>0&&(T=ln(A,re,v))}let j=await ue(v,o);return await d.updateAccount({config:T,dek:j}),g=v,v},...Io(m,S,u)};return n==="oauth_2"&&(E.get_integration_credentials=async()=>{let b=await k();return{...b,client_id:b.client_id||null,client_secret:b.client_secret||null,redirect_url:b.redirect_url??null}}),E}async function So(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 _o(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 js=new Set(["webhook_signature","expires_at","scope","redirect_url","refresh_token"]);function we(e){return js.has(e)}function Ks(e,n){return we(n)?!1:e==="oauth_2"?n==="client_id"||n==="client_secret":!0}function qs(e){return!we(e)}function Zs(e){switch(e){case"oauth_2":case"managed":return["access_token"];case"api_key":return["api_key"];case"bot_token":return["bot_token"]}}function Gs(e,n){return e!=="oauth_2"&&e!=="managed"?!1:n.some(t=>t.level==="account"&&t.name==="expires_at"&&t.configured)}function zs(e,n){let t=i=>n.find(s=>s.level==="account"&&s.name===i);if(!Zs(e).every(i=>t(i)?.configured))return!1;let o=t("refresh_token");return o?.required?!!o.configured:!0}async function Eo(e,n){if(!e)return!1;let t=N(e,`get_${n}`);if(!t)return!1;try{let r=await t();return typeof r=="string"&&r.length>0}catch{return!1}}function Js(e,n){let r=e.authConfig?.[n]?.integration??[];return[...F[n].integration,...r]}function Vs(e,n){let r=e.authConfig?.[n]?.account??[];return[...F[n].account,...r]}function Ys(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:zs(n,t),fields:t,missingRequiredFields:r}}async function Se(e,n,t){let r=P(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=Js(n,r),p=Vs(n,r),d=[];for(let g of c)d.push({name:g,level:"integration",required:Ks(r,g),configured:await Eo(u,g)});for(let g of p)d.push({name:g,level:"account",required:qs(g),configured:await Eo(l,g)});if(Gs(r,d)){let g=d.find(f=>f.level==="account"&&f.name==="refresh_token");g&&(g.required=!0)}return Ys(n.id,r,d)}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 Bn(e){return e.connected?"connected":e.status==="missing_integration"?"missing_credentials":"not_connected"}var Do=Symbol.for("corsair:internal"),Oo=new WeakMap,Mo=new WeakMap;function Qs(e,n){let t=n.map(r=>r.id).sort().join("\0");return`${e}\0${t}`}function Xs(e){if(e.database){let t=Oo.get(e.database);return t||(t=new Map,Oo.set(e.database,t)),t}let n=Mo.get(e);return n||(n=new Map,Mo.set(e,n)),n}function ea(e){return e.multiTenancy?{withTenant:()=>({}),[Do]:e}:{[Do]:e}}async function Ne(e,n){if(!e.database)return;let t=n.trim()||"default",r=Xs(e),o=Qs(t,e.plugins),i=r.get(o);if(i){await i;return}let s=(async()=>{let{setupCorsair:a}=await import("./setup-3XNSSM42.js");await a(ea(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 Ht(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 Ft=600*1e3;function Ln(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:Ht(r,{maxAgeMs:Ft})}function Ho(e){return{tenantId:e.tenantId,plugin:e.plugin,authType:e.authType??"oauth_2",status:"ready",connected:!0,verified:!0,webhookLink:e.link}}function Fo(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 _({hub:e,path:"/connections/report",body:Ho(n),parseResponse:()=>({ok:!0})}).catch(()=>{})}function na(e,n){try{let t=O(e);_({hub:t,path:"/connections/report",body:n,parseResponse:()=>({ok:!0})}).catch(()=>{})}catch(t){if(t instanceof se)return}}async function ta(e){if(!e.hub||!e.database||!e.kek)return;let n={database:e.database,kek:e.kek,plugins:e.plugins};if(!P(e.plugin))return;let r=e.tenantId?.trim()||"default",o=await Se(n,e.plugin,r);o&&Bo(e.hub,Fo({tenantId:r,plugin:e.plugin.id,authType:o.authType,status:o.status,connected:o.connected,verified:e.verified??o.connected,missingFields:o.missingRequiredFields}))}function Uo(e,n){na(e,n)}function Bo(e,n){_({hub:e,path:"/connections/report",body:n,parseResponse:()=>({ok:!0})}).catch(()=>{})}function gn(e){ta(e).catch(()=>{})}async function le(e,n){let t=w(e);if(!P(n.plugin))return;let o=await Se(t,n.plugin,n.tenantId);o&&Uo(e,Fo({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 Nn(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 Lo=e=>{if(!e)return{};if(typeof e=="string")try{return JSON.parse(e)}catch{return{}}return e};async function ra(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 oa(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=Lo(n.config),o={};Object.keys(r).length>0&&(o=ce(r,t)),o[e.link.linkType]=e.link.externalId;let i=ke(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 ra({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}),p=`set_${i.linkType}`,d=c[p];typeof d=="function"&&(await d(i.externalId),l=!0)}l||await oa({database:n,kek:t,accountId:u,link:i})}async function Ut(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=Lo(a.config)[o];if(!c)continue;if(cn(c,u)===i)return a}catch{continue}return null}async function $n(e){return(await Ut(e))?.tenant_id??null}async function No(e){return $n({database:e.database,kek:e.kek,pluginId:e.pluginId,linkType:e.match.linkType,externalId:e.match.externalId})}import*as $o 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}?${$o.stringify(i)}`}async function Wo(e,n){try{return await $({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 Wo(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 B=class extends Error{code;constructor(n,t){super(t),this.name="OAuthCallbackError",this.code=n}};function jo(e){let n=e.oauthConfig;if(!n)throw new B("plugin_has_no_oauth_config",`Plugin '${e.id}' has no oauthConfig`);return n}async function ia(e,n,t,r){let o=po(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 Bt(e,n,t){let{tenantId:r,redirectUri:o,hubConnect:i=!1}=t,s=w(e,()=>new B("invalid_corsair_instance","Invalid corsair instance"));if(!s.database)throw new Error("No database configured on corsair instance");let a=U(s,n,d=>new B("plugin_not_found",d)),u=jo(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 d=new URL(_e({oauthConfig:u,clientId:c,redirectUri:o,state:""}));return d.searchParams.delete("state"),{url:d.toString(),state:""}}let p=$e(Ce(n,r),s.kek);return{url:_e({oauthConfig:u,clientId:c,redirectUri:o,state:p}),state:p}}function sa(e,n){return{...n??{},...e}}async function fn(e,n){let{code:t,state:r,redirectUri:o}=n,i=w(e,()=>new B("invalid_corsair_instance","Invalid corsair instance")),s,a;if(n.trusted){if(!n.plugin||!n.tenantId)throw new B("invalid_state","trusted callback requires plugin and tenantId");s=n.plugin,a=n.tenantId}else{let y=Ln(r,i.kek);if(!y)throw new B("invalid_state","Invalid or tampered state parameter");s=y.plugin,a=y.tenantId}if(!i.database)throw new B("no_database","No database configured on corsair instance");let u=U(i,s,y=>new B("plugin_not_found",y)),l=jo(u),c=M({authType:"oauth_2",integrationName:s,kek:i.kek,database:i.database}),p=await c.get_client_id(),d=await c.get_client_secret();if(!p||!d)throw new B("credentials_not_configured",`Credentials not configured for '${s}'`);await ia(i.database,s,a,i.kek);let g=await Wn(t,p,d,l,o);if(!g.access_token)throw new B("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=sa(g,n.callbackParams),h=await Nn(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 aa(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=P(u)??"oauth_2",p=D({authType:c,integrationName:u.id,tenantId:a.tenantId,kek:t.kek,database:t.database,extraAccountFields:[...u.authConfig?.[c]?.account??[]]}),d=u.keyBuilder;if(d){let g=Object.create(p,{get_expires_at:{value:async()=>"0"}});await d({authType:c,keys:g,hub:t.hub},"endpoint")}await o(n,u,a.tenantId,p),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 Ko(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 aa({corsair:e,internal:n,rows:t.filter(r=>!!r.tenantId)})}function ua(e,n={}){let t=!1,r=()=>{t||(t=!0,Ko(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 qo(e){if(!w(e).database)throw new Error("A database must be configured to provision Corsair integrations");await jn(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 ca=Symbol.for("corsair:internal"),la=new Set(["access_token","refresh_token","expires_at","scope"]);function da(e){return e==="oauth_2"||e==="managed"?"oauth":e==="bot_token"?"bot_token":"api_key"}function pa(e,n){return e==="oauth_2"||e==="managed"?n.filter(t=>!we(t)&&!la.has(t)):n.filter(t=>!we(t))}function Zo(e){return{plugins:e.plugins,database:e.database,kek:e.kek,multiTenancy:e.multiTenancy??!1}}function ga(e){return{plugins:e.plugins,database:e.database,kek:e.kek,multiTenancy:e.multiTenancy??!1}}function fa(e){return{[ca]:Zo(e)}}async function Kn(e,n,t={}){let r=Sn(e.hub),o=[],i=t.pluginIds?new Set(t.pluginIds):null,s=Zo(e),a=fa(e);for(let u of e.plugins){if(i&&!i.has(u.id))continue;let l=P(u);if(!l)continue;let c=da(l),p=t.providerNameOverrides?.[u.id]??ye(u.id),d=await Se(s,u,n),g=An(u,l),f=pa(l,g),y={plugin:u.id,providerName:p,authKind:c,alreadyConfigured:d?.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 k=await Bt(a,u.id,{tenantId:n,redirectUri:r,hubConnect:!0});y.oauthUrl=k.url}catch(k){y.setupError=k instanceof Error?k.message:`Could not prepare OAuth for ${u.id}`}}o.push(y)}return o}async function md(e,n,t={}){let r=w(e),o=r.hub;if(!o)throw new Error("Hub is not configured");return Kn({plugins:r.plugins,database:r.database,kek:r.kek,hub:o},n,t)}async function Go(e,n){if(!e.database)throw new Error("A database must be configured to provision Corsair for connect");await Ne(e.internalConfig??ga(e),n)}async function zo(e,n){await qe(e,n)}async function Jo(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=be({deliveryUrl:n.deliveryUrl})),_({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:_n})}async function Lt(e,n){let t={plugins:n.plugins,database:n.database,kek:n.kek,hub:e,multiTenancy:n.multiTenancy};await Go(t,n.tenantId);let r=await Kn(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 Jo(e,{tenantId:n.tenantId,plugins:r,deliveryUrl:n.deliveryUrl})}async function qn(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 zo(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 Kn(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 Jo(r,{tenantId:n.tenantId,plugins:u,deliveryUrl:n.deliveryUrl})}async function Zn(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 ya(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 ya(e,n,t){let{buildConnectPluginManifestFromContext:r,ensureConnectAccountRowsFromContext:o}=await import("./setup-introspect-5DPFPZR3.js"),{postHubConnectSession:i}=await import("./connect-ABFKTUPY.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 ma(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 Nt(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=Ln(n,t.kek);if(!o)throw new G("invalid_state","Invalid or tampered state parameter");let{plugin:i,tenantId:s}=o,a=U(t,i,d=>new G("plugin_not_found",d)),u=ma(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 p=_e({oauthConfig:u,clientId:c,redirectUri:r,state:n});return{plugin:i,tenantId:s,providerName:u.providerName,oauthUrl:p,state:n}}import{AsyncLocalStorage as ba}from"async_hooks";import{randomBytes as ka}from"crypto";import{v4 as wa}from"uuid";async function Gn(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=be({deliveryUrl:n.deliveryUrl})),_({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:Dn})}function zn(e){return`Approval required. Visit ${e} to approve or deny, then tell the agent to retry this action.`}var $t="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 jt(e){return e?e.approvalBaseUrl!==void 0||e.onApprovalRequired!==void 0:!1}function Vo(e,n){return`${e.replace(/\/+$/,"")}/${n}`}function Wt(e){return zn(e)}async function Kt(e,n){if(jt(e.manual)){let r=e.manual?.approvalBaseUrl?.trim();return r?Vo(r,n.token):null}let t=e.hub;if(!t)return null;try{return(await Gn(t,{permissionId:n.id,permissionToken:n.token,plugin:n.plugin,endpoint:n.endpoint,args:ha(n.args),tenantId:n.tenant_id,expiresAt:n.expires_at})).approvalUrl}catch{return null}}function ha(e){try{return JSON.parse(e)}catch{return e}}async function Jn(e,n){if(!(n.status==="pending"||n.status==="approved"))return{...n,approvalUrl:null};let r=await Kt(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:p}=e;if(n?.formatAsyncMessage)return n.formatAsyncMessage({token:i,id:o,plugin:s,endpoint:a,args:u});let g=await Kt({manual:t,hub:r},{id:o,token:i,plugin:s,endpoint:a,args:JSON.stringify(u),tenant_id:l,expires_at:c});return jt(t)?g?t?.onApprovalRequired?t.onApprovalRequired({approvalUrl:g}):Wt(g):$t:r?g?Wt(g):`Action '${p}' requires user approval before it can run. Could not create approval link. Check hub configuration and server logs.`:$t}var Ge=class extends Error{constructor(n){super(n),Object.setPrototypeOf(this,new.target.prototype),this.name="PermissionRequiredError"}};var Qo=new ba,Vn=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 Zt(e){return Qo.run(!0,e)}function Xo(){return Qo.getStore()===!0}function Gt(e,n){if(Xo()&&n!=="read")throw new Vn(e,n)}var Ca={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 va(e,n,t){return t!==void 0?t:Ca[n][e]}function zt(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 ei(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 Yo(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 ni(e){let n=va(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"?Yo(e.db,a.id,e.timeoutMs??600*1e3):{result:"blocked",reason:"pending",id:a.id,token:a.token,expiresAt:a.expires_at})}let u=wa(),l=ka(32).toString("hex"),c=e.timeoutMs??600*1e3,p=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:p}).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: ${p}`,`
19
+ Use the token to approve or deny this request.`),(typeof e.approvalMode=="function"?e.approvalMode():e.approvalMode)==="synchronous"?Yo(e.db,u,c):{result:"blocked",reason:"pending",id:u,token:l,expiresAt:p}}var I=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 ti(e){let n={error:e.code,message:e.message,...e.extra};return H(e.status,n)}function ve(e){return new I(404,"not_found",e)}function de(e,n={}){return new I(400,"bad_request",e,n)}function ri(e,n){return U(e,n,t=>ve(t))}async function oi(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 ii(e,n){let t=e.options?.authType??null,r=e.oauthConfig,{configured:o,missingFields:i}=await oi(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 Yn(){return{ok:!0}}async function ze(e){return Promise.all(e.plugins.map(n=>ii(n,e)))}async function Qn(e,n){let t=ri(e,n);return ii(t,e)}async function Ta(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 si(e,n){let t=await Ta(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 Xn(e,n){if(!n)throw de("Tenant id must be a non-empty string");return si(e,n)}async function et(e,n){let t=n?.id?.trim();if(!t)throw de("Tenant id is required",{missingFields:["id"]});return si(e,t)}async function nt(e,n){let t=n?.trim()||"default",r={},o=await dn(e,t);for(let i of o)r[i.plugin]=Bn(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 Jt(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 Jn(e,t)}function Pa(e){if(!e.oauthConfig)throw de(`Plugin '${e.id}' has no oauthConfig`)}function Aa(e){if(!e.manual)throw new I(500,"connect_not_configured","createCorsair was not given manual config. Set { manual: { baseUrl, redirectUri } } to enable manual connect routes.");return e.manual}function Vt(e){let n=Aa(e);if(!n.baseUrl?.trim()||!n.redirectUri?.trim())throw new I(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 xa(e){let n=!!e.hub,t=Ze(e.manual);if(!n&&!t)throw new I(500,"connect_not_configured","createCorsair was not given connect config. Set hub: { ... } for Hub mode, or manual: { baseUrl, redirectUri } for manual connect.")}function ai(e){if(!e.database||!e.kek)throw new I(500,"database_not_configured","A database and kek are required to issue connect links.")}async function Ra(e,n){let t=n?.plugin?.trim();if(!t)throw de("Plugin id is required",{missingFields:["plugin"]});let r=n.tenantId?.trim()||"default",o=ri(e,t);Pa(o);let i=Vt(e);ai(e);let s=await oi(o,e);if(!s.configured)throw new I(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 I(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()+Ft).toISOString()}}async function Ia(e,n,t){ai(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 qn(e,o);return{connectUrl:a.connectUrl,expiresAt:a.expiresAt}}async function tt(e,n,t){return xa(n),n.hub?Ia(e,n,t):Ra(n,t)}async function rt(e,n,t){if(n.hub&&!Ze(n.manual))throw new I(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"]});Vt(n);try{return await Nt(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 I(400,"missing_credentials","OAuth client_id is not configured for this plugin",{missingFields:["client_id"]});case"no_redirect_uri":break}throw new I(500,"resolve_failed","Could not resolve connect link. Check server logs for details.")}}async function ot(e,n,t){if(n.hub&&!Ze(n.manual))throw new I(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=Vt(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 I(400,"missing_credentials","OAuth client credentials are not configured for this plugin",{missingFields:["client_id","client_secret"]})}throw new I(502,"oauth_callback_failed","OAuth callback did not complete. Check server logs for details.")}}async function Yt(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 Jn(e,t)}async function ui(e,n){return"id"in n?Jt(e,n.id):Yt(e,n.token)}import{createCipheriv as Ha,createDecipheriv as cp,randomBytes as pi,scryptSync as Fa}from"crypto";import{createHmac as Qt,randomUUID as Sa,timingSafeEqual as li}from"crypto";function Xt(e){return e.run??null}function er(e){return e.probe??null}function di(e){if(e)return e.startsWith("sha256=")?e.slice(7):e}function it(e){let n=JSON.stringify({type:e.type,payload:e.payload}),t=Math.floor(Date.now()/1e3).toString(),r=Qt("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":Sa()}}}function nr(e){let n=e.signingSecret.trim();if(!n)return!1;let t=di(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=Qt("sha256",n).update(e.body).digest("hex");try{return li(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=di(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=Qt("sha256",n).update(e.body).digest("hex");try{if(!li(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 st(e){return e.httpOk&&(e.status===204||e.body.status==="ok"||e.body.ok===!0)}function at(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 tr(e){return yn(Ye(e))}async function rr(e){let n=await lt({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=st({httpOk:n.ok,status:n.status,body:t}),o=yn(t);if(!r||!o)throw new Error(ct({deliveryUrl:e.deliveryUrl,status:n.status,body:n.body,ack:t}));return o}function ut(e){return at(Ye(e))}function _a(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 ci(e,n=200){let t=e.trim();return t.length<=n?t:`${t.slice(0,n)}\u2026`}var Ea="Verify hub.signingSecret in your app matches the signing secret shown in Hub project settings.",Da="Check the delivery URL configured for this environment.";function Oa(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})`}. ${Ea}`}function Ma(e){return`${e.ack.error?`${e.ack.error} (HTTP 404 from ${e.deliveryUrl})`:`Delivery endpoint not found at ${e.deliveryUrl} (HTTP 404)`}. ${Da}`}function mn(e,n){let t=_a(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 ct(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 Oa(e);if(e.status===404)return Ma(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}): ${ci(t)}`:`App failed while processing the delivery (HTTP ${e.status} from ${e.deliveryUrl})`}let n=e.body.trim();return n?`${ci(n)} (HTTP ${e.status} from ${e.deliveryUrl})`:`Delivery failed with HTTP ${e.status} from ${e.deliveryUrl}`}async function lt(e){let{body:n,headers:t}=it(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 Ua="aes-256-gcm",Ba=12,La=16,Na=16,$a=32;function Wa(e,n){return Fa(e.trim(),n,$a)}function or(e,n){let t=n.trim();if(!t)throw new Error("Signing secret is required to encrypt sync manifest");let r=pi(Na),o=Wa(t,r),i=pi(Ba),s=Ha(Ua,o,i,{authTagLength:La}),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 ja=["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 ir(e){if(e instanceof io)return!1;if(!(e instanceof Error))return!0;let n=e.message.toLowerCase();return!ja.some(t=>n.includes(t))}function Ka(e){if(!e)return[];let n=P(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 jn(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=Ka(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 or(i,n)}var ne=class extends Error{code;constructor(n,t){super(t),this.name="AuthCredentialsDeliveryError",this.code=n}};async function dt(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=U(t,n.plugin,c=>new ne("plugin_not_found",c)),o=P(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,p]of Object.entries(n.credentials)){if(!p.trim())continue;if(!i.has(c))throw new ne("invalid_credentials",`Unknown credential field '${c}' for plugin '${n.plugin}'`);let d=N(u,`set_${c}`);if(!d)throw new ne("invalid_credentials",`Cannot set credential field '${c}' for plugin '${n.plugin}'`);await d(p.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 sr(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=U(t,n.plugin,c=>new te("plugin_not_found",c)),o=P(r);if(!o)throw new te("invalid_credentials",`Plugin '${r.id}' has no authType configured`);await qo(e);let i=new Set(uo(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,p]of Object.entries(n.credentials)){if(!p.trim())continue;if(!i.has(c))throw new te("invalid_credentials",`Unknown integration credential field '${c}' for plugin '${n.plugin}'`);let d=N(u,`set_${c}`);if(!d)throw new te("invalid_credentials",`Cannot set integration field '${c}' for plugin '${n.plugin}'`);await d(p.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 pt=new Map;function qa(e){for(let[n,t]of pt)t<=e&&pt.delete(n)}function gt(e,n){let t=e.trim();if(!t)return{ok:!1,error:"Delivery replay key is required"};let r=Date.now();return qa(r),pt.has(t)?{ok:!1,error:"Delivery request already consumed"}:(pt.set(t,r+n),{ok:!0})}var Te=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 Te("no_access_token","Managed OAuth delivery missing access_token");let u=w(e,()=>new Te("invalid_corsair_instance","Invalid corsair instance"));if(!u.database)throw new Te("no_database","No database configured on corsair instance");let l=U(u,t,p=>new Te("plugin_not_found",p));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 p=await Nn(u.plugins,t,{access_token:o,refresh_token:i,scope:a});if(p){try{let d=l.authConfig?.managed?.account??[];await je({database:u.database,kek:u.kek,pluginId:t,tenantId:r,link:p,authType:"managed",extraAccountFields:d})}catch(d){console.warn(`[corsair:managed-oauth] Failed to persist webhook tenant link for '${t}' tenant '${r}':`,d)}u.hub&&We(u.hub,{plugin:t,tenantId:r,link:p,authType:"managed"})}}catch(p){console.warn(`[corsair:managed-oauth] Failed to resolve webhook tenant link for '${t}' tenant '${r}':`,p)}return await Ke(e,l,r,c).catch(p=>{console.warn(`[corsair:managed-oauth] subscribe failed for '${t}' tenant '${r}':`,p)}),{plugin:t,tenantId:r}}function Za(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function gi(e,n,t=[]){for(let[r,o]of Object.entries(e))if(Za(o)){if(o.match(n))return{webhook:o,path:[...t,r]}}else if(o&&typeof o=="object"){let i=gi(o,n,[...t,r]);if(i)return i}return null}function Ga(e){let n={};for(let[t,r]of Object.entries(e))n[t.toLowerCase()]=Array.isArray(r)?r[0]:r;return n}function za(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 fi(e,n,t,r,o){let i=Ga(n),s=typeof t=="string"?JSON.parse(t):t;(!s||typeof s=="object"&&Object.keys(s).length===0)&&i["x-goog-resource-uri"]&&(s=za(i)||s);let u={headers:i,body:s,...r?{query:r}:{}},l=r?.tenantId||"default",c=e.withTenant?e.withTenant(l):e,p=o?.plugin,d=p?[p]:xn;for(let g of d){let f=c[g];if(!f||!f.webhooks||!p&&f.pluginWebhookMatcher&&!f.pluginWebhookMatcher(u))continue;let y=gi(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 k=await y.webhook.handler(m),C=!!Object.keys(k.returnToSender||{})?.length;return{plugin:g,action:h,body:s,response:C?{...k?.returnToSender,success:!0}:{success:!0},...k.responseHeaders&&{responseHeaders:k.responseHeaders}}}catch(k){return console.error(`Error executing webhook handler for ${g}.${h}:`,k),{plugin:g,action:h,body:s,response:{success:!1,error:k instanceof Error?k.message:"Unknown error"}}}}return{plugin:null,action:null,body:null}}import{createHash as Ja}from"crypto";import*as Ee from"vm";var yi="__corsairFailedStep",Va=3e4,ar=class{constructor(n,t){this.wakeAt=n;this.stepName=t}__corsairSleep=!0};function mi(e){return typeof e=="object"&&e!==null&&e.__corsairSleep===!0}function hi(e,n){return`st_${Ja("sha256").update(`${n} ${e}`).digest("hex").slice(0,16)}`}function ft(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 bi=new Set(["constructor","prototype","__proto__"]);function pe(e,n){if(e===null)return null;let t=typeof e;return t==="function"?Qa(e,n):t==="object"?Ya(e):e}function Ya(e){return new Proxy(e,{get(n,t){if(!bi.has(t))return pe(Reflect.get(n,t,n),n)},getPrototypeOf:()=>null,setPrototypeOf:()=>!1,defineProperty:()=>!1,set:()=>!1,deleteProperty:()=>!1})}function Qa(e,n){return new Proxy(e,{apply:(t,r,o)=>Xa(Reflect.apply(t,n,o)),construct(){throw new Error("Workflow code may not construct host objects")},get(t,r){if(!bi.has(r))return pe(Reflect.get(t,r,t),t)},getPrototypeOf:()=>null,setPrototypeOf:()=>!1,defineProperty:()=>!1,set:()=>!1,deleteProperty:()=>!1})}function Xa(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 eu(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"})((d,g)=>e.step(d,g),(d,g)=>e.step.sleep(d,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"})((d,g)=>{let f=console[d]??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,p=new Promise((d,g)=>{c=setTimeout(()=>g(new Error(`Workflow exceeded ${e.timeoutMs}ms time limit`)),e.timeoutMs)});return Promise.race([l,p]).finally(()=>clearTimeout(c))}async function ur(e){let n=e.memoizedSteps??{},t=[],r=0,o=null,i=(async(s,a)=>{if(o)throw o;let u=r++,l=hi(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(mi(c))throw c;let p=ft(c);t.push({stepId:l,name:s,seq:u,status:"failed",error:p});let d=new Error(p);throw d[yi]=s,d}});i.sleep=async(s,a)=>{if(o)throw o;let u=r++,l=hi(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 ar(Date.now()+c,s),o};try{await eu({code:e.code,corsair:e.corsair,payload:e.payload,step:i,timeoutMs:e.timeoutMs??Va});let s=o;return s?{status:"sleeping",steps:t,sleepUntil:new Date(s.wakeAt).toISOString()}:{status:"completed",steps:t}}catch(s){if(mi(s))return{status:"sleeping",steps:t,sleepUntil:new Date(s.wakeAt).toISOString()};let a=ft(s),u=s!==null&&typeof s=="object"?s[yi]:void 0;return{status:"failed",steps:t,error:{message:a,...u?{failedStep:u}:{}}}}}import*as yt from"vm";var ki=1e4;async function cr(e){let n=Object.create(null),t=yt.createContext(n,{name:"corsair-probe",codeGeneration:{strings:!1,wasm:!1}});n.corsair=pe(e.corsair,void 0);let r=tu(e.timeoutMs),o=`(async () => {
43
+ const __result = await (async () => {
44
+ ${e.code}
45
+ })();
46
+ return JSON.stringify(__result) ?? 'null';
47
+ })()`;try{let i=await Zt(()=>{let s=yt.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:nu(i)}}catch(i){return{status:"error",error:ft(i)}}}function nu(e){if(typeof e!="string")throw new Error(`Probe returned a non-string result (${typeof e})`);return JSON.parse(e)}function tu(e){return typeof e!="number"||!Number.isFinite(e)||e<=0?ki:Math.min(e,ki)}function De(e){return e.deliveryMode==="auth.credentials"}function bn(e){return e.deliveryMode==="connections.sync"}function mt(e){return e.deliveryMode==="connect.create_link"}function kn(e){return e.deliveryMode==="permission.approve"||e.deliveryMode==="permission.deny"}function wn(e){return e.deliveryMode==="oauth.tokens"}function ht(e){return e.deliveryMode==="oauth.callback"||e.deliveryMode===void 0&&!De(e)&&!bn(e)&&!mt(e)&&!kn(e)&&!wn(e)}function ru(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 ou(e,n){try{return{status:"ok",webhookResponse:{status:200,body:{status:"ok",sync:{encrypted:await hn(e,n)}}}}}catch(t){return{status:"failed",retryable:ir(t),error:t instanceof Error?t.message:"Connections sync delivery failed"}}}async function iu(e,n){try{let t=await Zn(e,n);return ru(t)}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Connect link delivery failed"}}}function lr(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 su(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 $n({database:n.database,kek:n.kek,pluginId:t.plugin,linkType:t.linkType,externalId:t.externalId})??void 0)}async function au(e,n,t){let r=await su(e,n,t),o={...t.query??{},...r?{tenantId:r}:{}},i=await fi(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 uu(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 cu(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 pr(e,n,t){let r=await dr(e,{token:n},t);if(r.status!=="ok")throw new Error(r.error??"Permission decision failed")}async function dr(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 lu(e,n){try{return await dt(e,n),{status:"ok"}}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Credential delivery failed"}}}async function du(e,n){try{return await sr(e,n),{status:"ok"}}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Integration credential delivery failed"}}}function wi(e,n){let t=e;return n&&typeof t?.withTenant=="function"?t.withTenant(n):e}async function pu(e,n){try{let t=wi(e,n.tenantId);return{status:"ok",webhookResponse:{status:200,body:{status:"ok",run:await ur({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 gu(e,n){try{let t=wi(e,n.tenantId);return{status:"ok",webhookResponse:{status:200,body:{status:"ok",probe:await cr({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=lr(n.headers,"x-corsair-signature"),i=lr(n.headers,"x-corsair-timestamp"),s=lr(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=gt(`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 au(e,r,a.payload);case"oauth.callback":return uu(e,a.payload);case"oauth.tokens":return cu(e,a.payload);case"permission.approve":return dr(e,a.payload,"approved");case"permission.deny":return dr(e,a.payload,"denied");case"auth.credentials":return lu(e,a.payload);case"integration.credentials":return du(e,a.payload);case"connect.create_link":return iu(e,a.payload);case"connections.sync":{let u=t.signingSecret?.trim();return u?ou(e,u):{status:"failed",retryable:!1,error:"Tunnel signing secret is required for connections.sync"}}case"run":return t.allowWorkflowExecution?pu(e,a.payload):{status:"failed",retryable:!1,error:"Workflow execution is not enabled (set allowWorkflowExecution: true)"};case"probe":return t.allowWorkflowExecution?gu(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 fu(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 gr=3,yu=250;function mu(e){return e?.name==="AbortError"}async function hu(e){try{return(await e.json())?.ok!==!1}catch{return!0}}async function bu(e,n,t,r,o){for(let i=1;i<=gr;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 hu(s)||console.warn(`[corsair] hub did not record delivery ${r.deliveryId} (already timed out); the run may be retried`),!0}catch(s){if(mu(s))throw s}i<gr&&await vi(yu)}return console.warn(`[corsair] failed to acknowledge delivery ${r.deliveryId} after ${gr} attempts; the run may be retried`),!1}async function ku(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:p}=fu(l);return await bu(n,t,o,{deliveryId:s,status:c,body:p},r)?"handled":"error"}var Ci=1e3,wu=5e3,Cu=3e4;function vi(e){return new Promise(n=>setTimeout(n,e))}var bt=globalThis.__corsairConnectLoops??=new Map;function vu(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=Ci,c=!1,p=async d=>{c||(console.warn("[corsair] connect loop error; retrying",d),c=!0),s||await vi(l),l=Math.min(l*2,wu)};try{for(;!s;){a=new AbortController;let d=setTimeout(()=>a?.abort(),Cu);try{await ku(e,t,n,a.signal)==="error"?await p("pull or ack failed"):(c=!1,l=Ci)}catch(g){if(s)break;await p(g instanceof Error?g.message:g)}finally{clearTimeout(d)}}}finally{i()}})(),{stop:()=>{s=!0,a?.abort(),i()}}}function Ti(e){return e==="oauth_2"||e==="managed"?"oauth":e==="bot_token"?"bot_token":"api_key"}function Tu(e,n){return n&&!n.has(e.id)?!1:P(e)!==null}async function Pi(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=>Tu(l,i)).map(l=>{let c=P(l),p=a.get(l.id);return p?{plugin:l.id,providerName:ye(l.id),authKind:Ti(c),status:p.status,connected:p.connected,fields:p.fields.map(d=>({name:d.name,level:d.level,required:d.required,configured:d.configured})),missingRequiredFields:p.missingRequiredFields}:{plugin:l.id,providerName:ye(l.id),authKind:Ti(c),status:"not_started",connected:!1,fields:[],missingRequiredFields:[]}});return{tenantId:o,plugins:u}}async function Ai(e,n){let t=O(e);return $({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:En})}var fr=new Map;function xi(e){let n;try{n=O(e)}catch{return}let t=Dt(n);t&&fr.get(n.projectApiKey)!==t&&(fr.set(n.projectApiKey,t),_({hub:n,path:"/apps/announce",body:{deliveryUrl:t},parseResponse:()=>({ok:!0})}).catch(()=>{fr.delete(n.projectApiKey)}))}var Pu=[".corsair.dev"];function Au(e){return e==="localhost"||e==="127.0.0.1"||e==="[::1]"||e==="::1"}function xu(e){try{let{hostname:n,protocol:t}=new URL(e);return t!=="http:"&&t!=="https:"?!1:Au(n)?!0:Pu.some(r=>n===r.slice(1)||n.endsWith(r))}catch{return!1}}function Ri(e){return!e||!xu(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 Ii(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 yr(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 mr(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=he(o,t.signingSecret);if(!i)return{type:"json",status:400,body:{error:"Invalid or expired delivery token"}};let s=gt(`browser:${i.jti}`,me);if(!s.ok)return{type:"json",status:400,body:{error:s.error}};try{if(bn(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(mt(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 Zn(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 dt(e,{plugin:i.plugin,tenantId:i.tenantId,credentials:i.credentials}),{type:"redirect",url:yr(i.hubSuccessUrl,{connectedPlugin:i.plugin})}):{type:"redirect",url:yr(i.hubSuccessUrl,{error:"Credential delivery missing credentials"})}:{type:"json",status:400,body:{error:"Credential delivery missing hubSuccessUrl"}};if(kn(i)){if(!i.permissionToken)return{type:"json",status:400,body:{error:"Permission delivery missing permission token"}};await pr(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(!ht(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 bn(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})}:mt(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:yr(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 hr(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 br(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 kr(e,n){return n.method==="GET"?mr(e,n.url):hr(e,{headers:n.headers,body:n.body??""})}async function wr(e,n){try{let t=await kr(e,n);return br(t)}catch(t){if(t instanceof se)return Response.json({error:t.message},{status:503});throw t}}async function Oe(e,n){xi(e);let t=n.method.toUpperCase(),r=Ri(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 wr(e,{method:t,url:n.url,headers:n.headers,body:t==="POST"?await n.text():void 0});return Ii(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 Si=300;async function Cr(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+Si)return{accessToken:a,expiresAt:Number(u),refreshed:!1};if(!l&&a&&!s){let g=u?Number(u):null;if(g===null||g>c+Si)return{accessToken:a,expiresAt:g??c+3600,refreshed:!1}}let p=await Iu(r,o,i),d=p.expires_in?c+p.expires_in:u?Number(u):c+3600;return await t.set_access_token(p.access_token),await t.set_expires_at(String(d)),p.refresh_token&&await t.set_refresh_token(p.refresh_token),p.scope&&await t.set_scope(p.scope),{accessToken:p.access_token,expiresAt:d,refreshed:!0}}function Ru(e){return e.includes("Managed OAuth connection not found")||e.includes("Managed OAuth connection has no tokens")}async function Iu(e,n,t){try{return await _({hub:e,path:"/oauth/refresh",body:{plugin:n,tenantId:t},parseResponse:On})}catch(r){let o=r instanceof Error?r.message:"";throw Ru(o)?new W(n,"managed"):r}}async function _i(e,n){e._refreshAuth=async()=>(await Cr(n,{forceRefresh:!0})).accessToken}function Ei(e){return{delivery:n=>Oe(e,n),deliveryOptions:n=>Oe(e,n)}}var Di=1200*1e3;function vr(){return ie()}function Tr(){return Di}function Pr(e,n){return sn(e,n,Di)}function Ar(e,n){return ee(e,n)}function xr(e){return Ie(e)}var Oi=600*1e3;function Rr(){return ie()}function Ir(){return Oi}function Sr(e,n){return sn(e,n,Oi)}function _r(e,n){return ee(e,n)}function Er(e){return _t(e)}function Dr(e){return Ie(e)}function Or(){return ie()}function Mr(e,n,t){return Rn(e,n,Math.floor(t.getTime()/1e3))}function Hr(e,n){return ee(e,n)}function Fr(e){return Ie(e)}function Mi(e){return e&&typeof e=="object"?e:{}}async function Ur(e,n){return _({hub:e,path:"/threads",body:{tenantId:n.tenantId,message:n.message},parseResponse:t=>t})}async function Br(e,n){return _({hub:e,path:`/threads/${encodeURIComponent(n.threadId)}/messages`,body:{tenantId:n.tenantId,message:n.message},notFoundMessage:`Thread "${n.threadId}" not found`,parseResponse:t=>t})}async function Lr(e,n){return $({hub:e,path:`/threads?tenantId=${encodeURIComponent(n.tenantId)}`,parseResponse:t=>{let r=Mi(t).threads;return Array.isArray(r)?r:[]}})}async function kt(e,n){return $({hub:e,path:`/threads/${encodeURIComponent(n.threadId)}/messages?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Thread "${n.threadId}" not found`,parseResponse:t=>{let r=Mi(t).messages;return Array.isArray(r)?r:[]}})}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 Su(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 Hi(e){let{integrationId:n,accountId:t}=await Su(e);return{integrationId:n,accountId:t}}function Nr(e,n){return`[auth-missing:${e}] Authentication required. Direct the user to connect their account: ${n}`}async function _u(e,n){let t=e.hub;if(!t||!n.database||!n.kek)return null;try{return(await Lt(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 Eu(e){let n=e.hub;if(n&&e.database&&e.kek)try{let r=await Lt(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}):Nr(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 _u({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?Nr(e.pluginId,t):`[auth-missing:${e.pluginId}:${e.authType}]`}function Du(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}):Nr(e,i)}async function Ou(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"?Du(t,{...e.manual,baseUrl:e.manual.baseUrl,kek:e.manual.kek},e.tenantId):e.hub&&e.plugin&&e.kek&&e.database&&e.plugins?Eu({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 Fi(e){let n=await Ou(e);throw new W(e.error.pluginId,e.error.authType,n)}var Mu=async(e,n)=>(console.error(`[corsair:${n.pluginId}:${n.operation}]`,{error:e.message,input:n.input}),{maxRetries:0});async function Ui(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||Mu)(e,i)}function Hu(e){return typeof e=="function"}function $r({endpoints:e,hooks:n,ctx:t,tree:r,pluginId:o,errorHandlers:i,currentPath:s=[],keyBuilder:a,permissionsConfig:u,endpointMeta:l,database:c,permissionsOptions:p,tenantId:d,manualConfig:g,hubConfig:f,plugin:y,kek:h,allPlugins:m,multiTenancy:k}){for(let[C,S]of Object.entries(e)){let R=n?.[C];if(Hu(S)){let E=R,b=[...s,C].join("."),v=async(T={})=>{let j=l?.[b];Gt(b,j?.riskLevel??"write");let re;if(u){let K=j,{result:Pn,reason:Q,onComplete:tn,token:oe,id:xe,expiresAt:q}=await ni({pluginId:o,endpointPath:b,args:T,mode:u.mode,override:u.overrides?.[b],riskLevel:K?.riskLevel??"write",meta:K,db:c,timeoutMs:p?zt(p.timeout):void 0,tenantId:d,approvalMode:p?.mode});if(Pn==="blocked"){let X;throw Q==="denied"?X=`Action '${b}' was denied by the user. Await further instructions before proceeding.`:Q==="policy"?X=`Action '${b}' is blocked by the permission policy. Update the corsair config to allow it.`:Q==="timeout"?X=`Action '${b}' timed out waiting for approval.`:oe&&xe?X=await qt({permissionsOptions:p,manual:g,hub:f,permissionId:xe,permissionToken:oe,plugin:o,endpoint:b,args:T,tenantId:d??"default",expiresAt:q??new Date(Date.now()+(p?zt(p.timeout):600*1e3)).toISOString(),operationPath:b}):X=`Action '${b}' requires user approval before it can run.`,new Ge(X)}re=tn}let A=async(K,Pn,Q)=>{try{return await S(Pn,Q)}catch(tn){if(tn instanceof Error){let oe=await Ui(tn,o,b,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,vs=(Math.random()-.5)*1e3;q=Math.max(0,X+vs);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,Pn,Q),console.log(`[corsair:${o}:${b}] 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:d,verified:!1}),await Fi({error:K,manual:g,hub:f,plugin:y,tenantId:d,database:c,kek:h,plugins:m,multiTenancy:k})),K}if(!E?.before&&!E?.after){let K=await A(0,{...t,key:Y},T);return await re?.(),y&&f&&gn({hub:f,database:c,kek:h,plugins:m??[],plugin:y,tenantId:d,verified:!0}),K}let nn={...t,key:Y},Ae=E.before?await E.before(nn,T):{ctx:nn,args:T,continue:!0,passToAfter:void 0};if(Ae.continue===!1)return;let ro=await A(0,Ae.ctx,Ae.args);return await E.after?.(Ae.ctx,ro,Ae.passToAfter),await re?.(),y&&f&&gn({hub:f,database:c,kek:h,plugins:m??[],plugin:y,tenantId:d,verified:!0}),ro};r[C]=v}else if(S&&typeof S=="object"){let E={};$r({endpoints:S,hooks:R,ctx:t,tree:E,pluginId:o,errorHandlers:i,currentPath:[...s,C],keyBuilder:a,permissionsConfig:u,endpointMeta:l,database:c,permissionsOptions:p,tenantId:d,manualConfig:g,hubConfig:f,plugin:y,kek:h,allPlugins:m,multiTenancy:k}),r[C]=E}}}function Bi(e){return e&&typeof e=="object"?e:{}}async function Li(e,n){let t=new URLSearchParams({tenantId:n.tenantId});return n.limit!=null&&t.set("limit",String(n.limit)),$({hub:e,path:`/runs?${t.toString()}`,parseResponse:r=>{let o=Bi(r).runs;return Array.isArray(o)?o:[]}})}async function Wr(e,n){return $({hub:e,path:`/runs/${encodeURIComponent(n.runId)}?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Run "${n.runId}" not found`,parseResponse:t=>Bi(t).run})}async function jr(e,n,t){await _({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 Ni=(e,n)=>jr(e,"approve",n),$i=(e,n)=>jr(e,"deny",n),Wi=(e,n)=>jr(e,"cancel",n);function ji(e,n){let t=()=>{if(!e)throw new Error("corsair.runs requires Hub to be configured. Pass `hub` to createCorsair({ hub: { projectApiKey, ... } }).");return e},r=(o=>({get:()=>Wr(t(),{runId:o,tenantId:n}),approve:()=>Ni(t(),{runId:o,tenantId:n}),deny:()=>$i(t(),{runId:o,tenantId:n}),cancel:()=>Wi(t(),{runId:o,tenantId:n})}));return r.list=o=>Li(t(),{tenantId:n,limit:o?.limit}),r.get=o=>Wr(t(),{runId:o,tenantId:n}),r}function Ki(e,n){let t=()=>{if(!e)throw new Error("corsair.threads requires Hub to be configured. Pass `hub` to createCorsair({ hub: { projectApiKey, ... } }).");return e},r=(o=>({message:i=>Br(t(),{threadId:o,tenantId:n,message:i}),listMessages:()=>kt(t(),{threadId:o,tenantId:n})}));return r.create=o=>Ur(t(),{tenantId:n,message:o}),r.list=()=>Lr(t(),{tenantId:n}),r.listMessages=o=>kt(t(),{threadId:o,tenantId:n}),r}function Fu(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function Kr({webhooks:e,hooks:n,ctx:t,webhooksTree:r,keyBuilder:o}){for(let[i,s]of Object.entries(e)){let a=n?.[i];if(Fu(s)){let u=a,l=async c=>{let p=(g,f)=>s.handler(g,f),d=o?await o(t,"webhook"):void 0;return!u?.before&&!u?.after?p({...t,key:d},c):(async()=>{let g={...t,key:d},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 p(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={};Kr({webhooks:s,hooks:a,ctx:t,webhooksTree:u,keyBuilder:o}),r[i]=u}}}function Uu(e){return e&&typeof e=="object"?e:{}}async function qi(e,n){return $({hub:e,path:`/workflows?tenantId=${encodeURIComponent(n.tenantId)}`,parseResponse:t=>{let r=Uu(t).workflows;return Array.isArray(r)?r:[]}})}async function Zi(e,n){return _({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 Gi(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=>({run:i=>Zi(t(),{workflowId:o,tenantId:n,payload:i?.payload,idempotencyKey:i?.idempotencyKey})}));return r.list=()=>qi(t(),{tenantId:n}),r}function Bu(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 Hi({database:e,integrationName:n,tenantId:t,ensureProvisioned:r});return o=i,o}}function Lu(e,n,t,r,o){return e?Rt(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 qr(e,n){let{database:t,tenantId:r,kek:o,rootErrorHandlers:i,permissionsOptions:s,manualConfig:a,hubConfig:u,internalConfig:l}=n,c=r??"default",p=l&&t?()=>Ne(l,c):void 0,d={},g={};for(let f of e)d[f.id]={},g[f.id]={};for(let f of e){let y=f.schema,h=Bu(t,f.id,c,p);if(y?.entities){let A={};for(let[Y,nn]of Object.entries(y.entities)){let Ae=t?Rt(t.db,h,Y,y.version,nn):Lu(void 0,h,Y,y.version,nn);A[Y]=Ae}g[f.id].db=A,d[f.id].db=A}let m=f.options,k=f.authConfig,C;if(t&&o&&m?.authType){let A=k?.[m.authType]?.account??[];C=D({authType:m.authType,integrationName:f.id,tenantId:c,kek:o,database:t,extraAccountFields:A,ensureProvisioned:p}),d[f.id].keys=C}let S={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}:{}},R=f.endpoints??{},E=f.hooks,b={...i,...f.errorHandlers},v={},T=f.options?.permissions;$r({endpoints:R,hooks:E,ctx:S,tree:v,pluginId:f.id,errorHandlers:b,currentPath:[],keyBuilder:f.keyBuilder,permissionsConfig:T,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&&(d[f.id].api=v),S.endpoints=v;let j=f.webhooks??{},re=f.webhookHooks;if(Object.keys(j).length>0){let A={};Kr({webhooks:j,hooks:re,ctx:S,webhooksTree:A,keyBuilder:f.keyBuilder}),d[f.id].webhooks=A,f.pluginWebhookMatcher&&(d[f.id].pluginWebhookMatcher=f.pluginWebhookMatcher),f.pluginTenantWebhookMatcher&&(d[f.id].pluginTenantWebhookMatcher=f.pluginTenantWebhookMatcher)}}return d.threads=Ki(u,c),d.runs=ji(u,c),d.workflows=Gi(u,c),d}function zi(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 Nu="createCorsair({ approval: ... }) is deprecated. Rename to permissions: { timeout, onTimeout, mode }.";function Ji(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] ${Nu}`),t):n}var Vi=[{method:"GET",pattern:"/ok",handler:async()=>H(200,Yn())},{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 et(e,n))},{method:"GET",pattern:"/tenants/:id",handler:async({internal:e,params:n})=>H(200,await Xn(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 Qn(e,n.id))},{method:"GET",pattern:"/connection-status",handler:async({internal:e,query:n})=>H(200,await nt(e,n.tenantId))},{method:"GET",pattern:"/permissions/:id",handler:async({internal:e,params:n})=>H(200,await Jt(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 Yt(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 tt(e,n,t))},{method:"GET",pattern:"/connect/resolve",handler:async({corsair:e,internal:n,query:t})=>H(200,await rt(e,n,t.state??""))},{method:"POST",pattern:"/connect/oauth/callback",handler:async({corsair:e,internal:n,body:t})=>H(200,await ot(e,n,t))}];(()=>{let e=new Set;for(let n of Vi){let t=`${n.method} ${n.pattern}`;if(e.has(t))throw new Error(`Duplicate management route registered: ${t}`);e.add(t)}})();function $u(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 Wu(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 I(400,"invalid_json","Request body is not valid JSON")}}var Ku="/api/corsair";function Me(e,n={}){let t=n.basePath??Ku,r=w(e,()=>new Error("managementHandler: invalid corsair instance (missing internal config)"));return async o=>{try{let i=new URL(o.url),s=Wu(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 Vi){if(l.method!==a)continue;let c=$u(l.pattern,s);if(!c)continue;let p=await ju(o);return await l.handler({corsair:e,internal:r,req:o,params:c,query:u,body:p})}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 I)return ti(i);let s=i instanceof Error?i.message:"Internal server error";return H(500,{error:"internal_error",message:s})}}}function qu(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 Zu(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 Yi(e,n){let t=Me(e,n);return async(r,o,i)=>{try{let s=await t(qu(r));await Zu(o,s)}catch(s){i(s)}}}function Qi(e,n){let t=Me(e,n);return r=>t(r.req.raw)}function Xi(e,n){let t=Me(e,n);return{GET:t,POST:t,OPTIONS:t}}function es(e){let n={[vn]:e};return{ok:Yn,tenants:{list:()=>Je(e),create:t=>et(e,t),get:t=>Xn(e,t)},plugins:{list:()=>ze(e),get:t=>Qn(e,t)},connectionStatus:{get:t=>nt(e,t?.tenantId)},permissions:{get:t=>ui(e,t)},connect:{createLink:t=>tt(n,e,t),resolve:t=>rt(n,e,t),oauthCallback:t=>ot(n,e,t)}}}async function ns(e,n,t,r,o="pending"){if(!e)return null;try{let i=co(),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 Gu(e,n,t,r="pending"){try{let o=await e.$getAccountId();return ns(e.database,o,n,t,r)}catch(o){return console.warn("Failed to log event:",o),null}}import*as rs from"https";import*as Ct from"querystring";var zu=["expires_in","refresh_token_expires_in"];function ts(e){let n={...e};for(let t of zu){let r=e[t];if(typeof r=="string"){let o=Number(r);n[t]=Number.isFinite(o)?o:void 0}}return n}function Ju(e){try{return ts(JSON.parse(e))}catch{}if(!e.includes("="))return null;let n=Ct.parse(e);return!n.access_token&&!n.error?null:ts({...n})}function Wn(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),p={"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json","Content-Length":Buffer.byteLength(c).toString()};s&&(p.Authorization=`Basic ${Buffer.from(`${n}:${t}`).toString("base64")}`);let d=rs.request({hostname:i.hostname,...i.port?{port:Number(i.port)}:{},path:i.pathname+i.search,method:"POST",headers:p},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=Ju(f);y?a(y):u(new Error(`Token endpoint returned non-JSON response: ${f}`))})});d.on("error",g=>u(new Error(`Request failed: ${g.message}`))),d.write(c),d.end()})}var os=" ";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 ss(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 as(e){let n=e.type;return e.element??(typeof n=="string"?void 0:n)}function Tt(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 us(e,n){return e.description??n.description}function Vu(e){let n=e;for(;n;){let t=J(n),r=us(n,t);if(r)return r;let o=V(t);if(Vr(o)||o==="ZodPipe"||o==="ZodEffects"||o==="ZodTransform"){n=ss(t,o);continue}break}}function Vr(e){return e==="ZodOptional"||e==="ZodNullable"||e==="ZodDefault"||e==="ZodCatch"}function L(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?L(r):"unknown"}case"ZodNullable":{let r=z(n);return`${r?L(r):"unknown"} | null`}case"ZodDefault":case"ZodCatch":{let r=z(n);return r?L(r):"unknown"}case"ZodArray":{let r=as(n);if(!r)return"unknown[]";let o=J(r),i=V(o)==="ZodUnion",s=L(r);return`${i?`(${s})`:s}[]`}case"ZodRecord":return"{}";case"ZodObject":{let r=Tt(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}: ${L(a)}`}).join(", ")} }`}case"ZodUnion":return Xe(n).map(r=>L(r)).join(" | ");case"ZodIntersection":return`${L(n.left)} & ${L(n.right)}`;case"ZodPipe":case"ZodTransform":case"ZodEffects":{let r=ss(n,t);return r?L(r):"unknown"}default:return(t??"unknown").replace("Zod","").toLowerCase()}}function ge(e){let n=J(e),t=V(n),r=us(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=as(n);return{kind:"array",optional:!1,description:r,items:o?ge(o):{kind:"unknown",optional:!1}}}case"ZodObject":{let o=Tt(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 lm(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=Pe(s.endpointMeta,a),l=Pe(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 Yr=["equals","contains","startsWith","endsWith","in"],Yu=["equals","gt","gte","lt","lte","in"],Qu=["equals"],Xu=["equals","before","after","between"];function cs(e){let n=J(e);switch(V(n)){case"ZodOptional":case"ZodNullable":case"ZodDefault":case"ZodCatch":{let r=z(n);return r?cs(r):null}case"ZodString":return"string";case"ZodNumber":return"number";case"ZodBoolean":return"boolean";case"ZodDate":return"date";default:return null}}function Qr(e){let n=J(e),t=V(n);if(Vr(t)){let i=z(n);return i?Qr(i):{}}if(t!=="ZodObject")return{};let r=Tt(e,n),o={};for(let[i,s]of Object.entries(r)){let a=cs(s);a==="string"?o[i]={type:"string",operators:Yr}:a==="number"?o[i]={type:"number",operators:Yu}:a==="boolean"?o[i]={type:"boolean",operators:Qu}:a==="date"&&(o[i]={type:"date",operators:Xu})}return o}function ls(e,n){for(let[t,r]of Object.entries(e))if(t.toLowerCase()===n)return[t,r]}function Gr(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"&&Gr(o,i,t)}}function zr(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function Jr(e,n,t){for(let[r,o]of Object.entries(e)){let i=[...n,r];zr(o)?t.push(i.join(".")):o!==null&&typeof o=="object"&&Jr(o,i,t)}}function Xr(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 zr(s)?[i]:null;if(s!==null&&typeof s=="object"&&!zr(s)){let a=Xr(s,r);if(a!==null)return[i,...a]}return null}function ds(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 ec=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 ec.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 Jr(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 Gr(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=[];Jr(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=[];Gr(i.endpoints,[],s),o[i.id]=s.map(a=>`${i.id}.api.${a}`)}return o}function Pe(e,n){if(e){for(let[t,r]of Object.entries(e))if(t.toLowerCase()===n)return r}}function nc(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 Zr(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 dm(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),p=c.lastIndexOf(".");if(p!==-1){let d=c.slice(0,p),g=c.slice(p+1),f=s.schema?.entities;if(g==="search"&&f){let y=ls(f,d);if(y){let[h,m]=y,k=Qr(m),C=[`Search ${o} ${h} stored in the local database.`,"Pass limit and offset as numbers for pagination.","","filters {",` entity_id: string [${Yr.join(", ")}]`];for(let[S,R]of Object.entries(k))C.push(` ${S}?: ${R.type} [${R.operators.join(", ")}]`);return C.push("}"),C.join(`
54
+ `)}}}return Zr(He(e,{type:"db"}),"Path not found. Available db operations")}if(i.startsWith("webhooks.")){let c=i.slice(9);if(s.webhooks){let p=Xr(s.webhooks,c.split("."));if(p!==null){let d=p.join("."),g=Pe(s.webhookSchemas,d.toLowerCase()),f=g?.response?L(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
+ ${ds(o,p)}`),y.join(`
56
+
57
+ `)}}return Zr(He(e,{type:"webhooks"}),"Path not found. Available webhooks")}let a=i;a.startsWith("api.")&&(a=a.slice(4));let u=Pe(s.endpointMeta,a),l=Pe(s.endpointSchemas,a);if(u||l){let c=[],p=[u?.riskLevel?`[${u.riskLevel}]`:"",u?.irreversible?"[irreversible]":""].filter(Boolean).join(" "),d=[u?.description,p].filter(Boolean).join(" ");return d&&c.push(d),l?.input&&c.push(`input ${vt(en(l.input))}`),l?.output&&c.push(`output ${vt(en(l.output))}`),c.join(`
58
+
59
+ `)}}}return Zr(He(e),"Path not found. Available operations")}function is(e){let n=e;for(;;){let t=J(n),r=V(t);if(Vr(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=is(e),t=J(n);if(V(t)==="ZodObject"){let o=Tt(n,t),i=[];for(let[s,a]of Object.entries(o)){let u=J(a),l=V(u),c=l==="ZodOptional"||l==="ZodNullable",p=is(a),d=Vu(a);i.push({key:s,optional:c,type:L(p),...d!==void 0?{description:d}:{}})}return{kind:"object",fields:i}}return{kind:"inline",type:L(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=os.repeat(n+1),r=os.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 tc(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:p,lookupKey:d}=nc(c,n),g=Pe(r.endpointMeta,d),f=Pe(r.endpointSchemas,d);!g&&!f||o.push({path:c,shortPath:p,description:g?.description,riskLevel:g?.riskLevel,irreversible:g?.irreversible,input:en(f?.input),output:en(f?.output)})}o.sort((c,p)=>c.path.localeCompare(p.path));let i=[],s=He(e,{plugin:n,type:"webhooks"});if(Array.isArray(s)&&r.webhooks)for(let c of s){let d=c.toLowerCase().slice(n.length+1),g=d.startsWith(".")?d.slice(1):d;if(!g.startsWith("webhooks."))continue;let f=g.slice(9),y=Xr(r.webhooks,f.split("."));if(y===null)continue;let h=y.join("."),m=Pe(r.webhookSchemas,h.toLowerCase()),k=m?.response?L(m.response):void 0;i.push({path:c,description:m?.description,payload:en(m?.payload),responseType:k,usageExample:ds(n,y)})}i.sort((c,p)=>c.path.localeCompare(p.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 d=c.toLowerCase().slice(n.length+1),g=d.startsWith(".")?d.slice(1):d;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 k=ls(l,h);if(!k)continue;let[C,S]=k,R=Qr(S),E=Object.entries(R).map(([b,v])=>({field:b,type:v.type,operators:v.operators}));a.push({path:c,entityName:C,filters:[{field:"entity_id",type:"string",operators:Yr},...E]})}return a.sort((c,p)=>c.path.localeCompare(p.path)),{ok:!0,data:{pluginId:n,api:o,webhooks:i,db:a}}}import{randomUUID as ps}from"crypto";async function rc(e,n){let t=await e.keys.get_access_token();if(!t)return null;let r=ps(),o=ps(),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 oc}from"crypto";var Pt="https://graph.microsoft.com/v1.0",eo=2e4,ic=60;async function sc(e,n){let t=await e.keys.get_access_token();if(!t)return null;let r={authorization:`Bearer ${t}`};try{let u=await fetch(`${Pt}/subscriptions`,{headers:r,signal:AbortSignal.timeout(eo)});if(u.ok){let{value:l}=await u.json(),c=(l??[]).filter(p=>p.notificationUrl===n.webhookUrl);await Promise.all(c.map(p=>fetch(`${Pt}/subscriptions/${p.id}`,{method:"DELETE",headers:r,signal:AbortSignal.timeout(eo)}).catch(()=>{})))}}catch{}let o=oc(),i=new Date(Date.now()+ic*6e4).toISOString(),s=await fetch(`${Pt}/subscriptions`,{method:"POST",headers:{...r,"content-type":"application/json"},signal:AbortSignal.timeout(eo),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 gs(e,n){for(let[t,r]of Object.entries(e))if(r?.pluginWebhookMatcher&&r.pluginWebhookMatcher(n))return t;return null}function ac(e,n){let t=gs(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 uc(e){let n={};for(let t of e)!t.pluginWebhookMatcher&&!t.pluginTenantWebhookMatcher||(n[t.id]={pluginWebhookMatcher:t.pluginWebhookMatcher,pluginTenantWebhookMatcher:t.pluginTenantWebhookMatcher});return n}function fs(e,n){let t=n.toLowerCase(),r=e[t]??e[n];return Array.isArray(r)?r[0]:typeof r=="string"?r:void 0}function ys(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 Tn(e){return!e||typeof e!="object"||Array.isArray(e)?null:e}function cc(e){return Tn(e.body)}function ms(e,n){let t=e.query;if(!t)return;let r=t[n]??t[n.toLowerCase()];return At(Array.isArray(r)?r:[r])}function hs(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=ms({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 d=(c.startsWith("http")?new URL(c):new URL(`https://example.invalid${c.startsWith("/")?c:`/${c}`}`)).searchParams.get("validationToken");if(d?.trim())return d.trim()}catch{continue}}let i=e.payload!==void 0?e.payload:e.body!==void 0?e.body:void 0,s=Tn(typeof i=="string"?(()=>{try{return JSON.parse(i)}catch{return i}})():i);return At([s?.validationToken])??null}function lc(e){if(hs(e))return!0;let n=Tn(e.body??e.payload);return fs(e.headers??{},"content-type")?.includes("text/plain")?!n||Object.keys(n).length===0:!1}function At(e){for(let n of e){let t=ys(n);if(t)return t}}function dc(e){let t=Tn(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 ks(e){let n=e.database?oo(e.database):void 0,t=n&&e.kek?zi(e.plugins,n,e.kek):wt(!!n,!!e.kek),r=Ji(e),o={plugins:e.plugins,database:n,kek:e.kek,multiTenancy:!!e.multiTenancy,permissions:r,manual:e.manual,hub:e.hub?In(e.hub):void 0},i=ei(n),s=es(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 p=qr(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(p,{[vn]:o})},keys:t,permissions:i,manage:s},{[vn]:o});return bs(l,o.hub),l}let a=qr(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 bs(u,o.hub),u}function bs(e,n){n?.projectApiKey?.startsWith("ck_dev_")&&import("./loop-KGDZGXUO.js").then(t=>t.startConnectLoop(e)).catch(()=>{})}var pc={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:{}}}},no=pc;async function jn(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=so(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=Pc(e,a.plugins,n),l={...a,database:a.database},c=l.database.db;await Rc(c,i);let p=await Ic(c,l,u.tenantId,u.provisionAccounts,o);n?.credentials&&Object.keys(n.credentials).length>0&&await Ec(e,u,n.credentials,l,o,i);let d=await Oc(p,u,o,s);if(n?.backfill){o("[corsair:setup] Starting backfill...");let g=ks({plugins:a.plugins,database:c,kek:a.kek,multiTenancy:!0}).withTenant(u.tenantId);await Mc(g,a.plugins,d,o,i),o("[corsair:setup] Backfill complete.")}return t.join(`
63
+ `)}function to(e,n,t){let r=t==="integration"?e.authConfig?.[n]?.integration??[]:e.authConfig?.[n]?.account??[];return new Set([...F[n][t],...r])}function Tc(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=P(o);if(!i)continue;let s=to(o,i,"account");for(let a of Object.keys(r))if(s.has(a))return!0}return!1}function Pc(e,n,t){let r=ao(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&&Tc(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 Cs(e,n){return fe(e)?n===0?!0:Object.values(e).every(t=>Cs(t,n-1)):!1}function Ac(e){return Cs(e,4)}var xc={...lo};function xt(e){if(e instanceof bc){let n={};for(let[t,r]of Object.entries(e.shape))n[t]=r instanceof vc?xt(r):"unknown";return n}return e instanceof mc?`${xt(e.unwrap())} | null`:e instanceof kc?`${xt(e.unwrap())} | undefined`:e instanceof yc?e.options.join(" | "):e instanceof Cc?"string":e instanceof hc?"number":e instanceof gc?"boolean":e instanceof fc?"date":e instanceof wc?"jsonb":"unknown"}async function Rc(e,n){let t=await e.introspection.getTables(),r=new Set(t.map(o=>o.name));for(let[o,i]of Object.entries(xc))r.has(o)||n(`[corsair:setup] Table "${o}" does not exist. Run your database migrations before calling setupCorsair.
64
+ Schema: ${JSON.stringify(xt(i),null,2)}`)}async function Ic(e,n,t,r,o){let i=new Date,s=new Map;for(let a of n.plugins){let u=a.id,l=P(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 p=l?a.authConfig?.[l]?.integration??[]:[],d=l?a.authConfig?.[l]?.account??[]:[],g=l&&c?M({authType:l,integrationName:u,kek:n.kek,database:n.database,extraIntegrationFields:p}):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:d}),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,...p],accountFields:r?[...F[l].account,...d]:[]})}return s}function Sc(e){if(!fe(e))return;let n=e.keys;return fe(n)?n:void 0}function _c(e,n){return"withTenant"in e&&typeof e.withTenant=="function"?e.withTenant(n):e}async function Ec(e,n,t,r,o,i){let s=Sc(e),a=n.provisionAccounts?_c(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 p=P(c);if(!p){i(`[corsair:setup] Plugin '${u}' has no auth type \u2014 skipping credentials.`);continue}let d=to(c,p,"integration"),g=to(c,p,"account"),f=s?.[u],y=a?.[u],h=fe(y)?y.keys:void 0;for(let[m,k]of Object.entries(l))if(k){if(d.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=N(f,`set_${m}`);if(!C){i(`[corsair:setup] Cannot set integration field '${m}' for '${u}'.`);continue}await C(k),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=N(h,`set_${m}`);if(!C){i(`[corsair:setup] Cannot set account field '${m}' for '${u}'.`);continue}await C(k),o(`[corsair:setup] Set ${u} account.${m} (tenant=${n.tenantId})`);continue}i(`[corsair:setup] Unknown credential field '${m}' for plugin '${u}'.`)}}}var ws=new Set(["webhook_signature","expires_at","scope","redirect_url"]);async function Dc(e,n,t,r,o,i,s,a,u){let l=[],c=[];for(let d of o){if(ws.has(d))continue;let g=N(t,`get_${d}`);if(!g)continue;let f=null;try{let y=await g();f=typeof y=="string"?y:null}catch{}f||l.push(d)}if(r&&i.length>0)for(let d of i){if(ws.has(d))continue;let g=N(r,`get_${d}`);if(!g)continue;let f=null;try{let y=await g();f=typeof y=="string"?y:null}catch{}f||c.push(d)}let p=l.length===0&&c.length===0;if(p)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 d=[...l,...c];if(u==="cli"){let g=d.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 p}async function Oc(e,n,t,r){let o=new Set;for(let i of e.values())await Dc(i.pluginId,i.authType,i.integration,i.account,i.integrationFields,i.accountFields,n,t,r)&&o.add(i.pluginId);return o}async function Mc(e,n,t,r,o){if(!Ac(no)){o("[corsair:setup] Backfill config is invalid - skipping backfill.");return}let i=no,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=fe(e)?e[a]:void 0,c=fe(l)?l.api:void 0;if(c)for(let[p,d]of Object.entries(u))for(let[g,f]of Object.entries(d)){r(`[corsair:setup] Backfilling ${a} \u203A ${p}.${g}...`);try{let y=fe(c)?c[p]:void 0;await N(y,g)?.(f)}catch(y){o(`[corsair:setup] ${a} \u203A ${p}.${g} failed: `+(y instanceof Error?y.message:String(y)))}}}}export{go as a,ye as b,St as c,rn as d,fo as e,yo as f,me as g,Re as h,ie as i,Ue as j,Be as k,he as l,Et as m,ho as n,an as o,se as p,In as q,O as r,Sn as s,Le as t,_n as u,En as v,Dn as w,On as x,ko as y,Mn as z,be as A,ae as B,ue as C,Z as D,Ot as E,cn as F,ke as G,ce as H,ln as I,M as J,D as K,So as L,_o as M,jn as N,Ec as O,Ce as P,Ht as Q,We as R,je as S,Ut as T,$n as U,No as V,_e as W,B as X,Bt as Y,fn as Z,Ko as _,ua as $,Kn as aa,md as ba,Go as ca,zo as da,Jo as ea,Lt as fa,qn as ga,Nt as ha,Gn as ia,zn as ja,Ge as ka,Vn as la,Zt as ma,Xo as na,Gt as oa,Xt as pa,er as qa,it as ra,nr as sa,Ve as ta,Ye as ua,st as va,at as wa,yn as xa,tr as ya,rr as za,ut as Aa,mn as Ba,ct as Ca,lt as Da,Te as Ea,Qe as Fa,fi as Ga,ur as Ha,cr as Ia,De as Ja,kn as Ka,wn as La,ht as Ma,pr as Na,Cn as Oa,fu as Pa,ku as Qa,vu as Ra,Pi as Sa,Ai as Ta,mr as Ua,hr as Va,br as Wa,kr as Xa,wr as Ya,Oe as Za,W as _a,Cr as $a,_i as ab,Ei as bb,vr as cb,Tr as db,Pr as eb,Ar as fb,xr as gb,Rr as hb,Ir as ib,Sr as jb,_r as kb,Er as lb,Dr as mb,Or as nb,Mr as ob,Hr as pb,Fr as qb,Me as rb,Yi as sb,Qi as tb,Xi as ub,ns as vb,Gu as wb,Wn as xb,lm as yb,He as zb,dm as Ab,vt as Bb,tc as Cb,rc as Db,Pt as Eb,sc as Fb,gs as Gb,ac as Hb,uc as Ib,fs as Jb,ys as Kb,Tn as Lb,cc as Mb,ms as Nb,hs as Ob,lc as Pb,At as Qb,dc as Rb,vn as Sb,ks as Tb};
@@ -1,6 +1,6 @@
1
- import { T as Tenant, C as CreateTenantInput, P as PluginInfo, a as ConnectionStatus, b as PermissionRecord, c as ConnectLink, d as CreateConnectLinkInput, O as OAuthCallbackResult, e as OAuthCallbackInput } from '../../types-C24LhkXl.js';
2
- export { f as PermissionLookupInput } from '../../types-C24LhkXl.js';
3
- import { C as CorsairClientOptions, a as CorsairManagementClient } from '../../types-Dt339hBs.js';
1
+ import { T as Tenant, C as CreateTenantInput, P as PluginInfo, a as ConnectionStatus, b as PermissionRecord, c as ConnectLink, d as CreateConnectLinkInput, O as OAuthCallbackResult, e as OAuthCallbackInput } from '../../types-DL6dIM3d.js';
2
+ export { f as PermissionLookupInput } from '../../types-DL6dIM3d.js';
3
+ import { C as CorsairClientOptions, a as CorsairManagementClient } from '../../types-xjNcJIhf.js';
4
4
  import '../../index-eydqYIn0.js';
5
5
  import 'zod';
6
6
 
@@ -1 +1 @@
1
- import{ea as a,fa as b,ga as c}from"./chunk-VOB4G3KC.js";import"./chunk-WDF3YE27.js";import"./chunk-IGGCNGU2.js";import"./chunk-QAIKSQAD.js";export{c as createHubConnectSession,b as createHubConnectSessionForPlugin,a as postHubConnectSession};
1
+ import{ea as a,fa as b,ga as c}from"./chunk-6PCMHFQJ.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,10 +1,10 @@
1
- export { C as CORSAIR_INTERNAL, a as CorsairInternalConfig, c as createCorsair } from './index-B_P6rcu8.js';
1
+ export { C as CORSAIR_INTERNAL, a as CorsairInternalConfig, c as createCorsair } from './index-BFEVZoVE.js';
2
2
  import { CorsairDatabase } from './db.js';
3
- import { A as AccountKeyManagerFor, I as IntegrationKeyManagerFor, f as CorsairPluginSubscribeResult } from './index-DcJhvFt7.js';
4
- export { g as AccountFieldNames, a6 as AgentReply, k as BASE_AUTH_FIELDS, B as BaseAuthFieldConfig, h as BaseKeyManager, M as BeforeHookResult, n as BindEndpoints, ae as BindWebhooks, ac as Bivariant, o as BoundEndpointFn, p as BoundEndpointTree, af as BoundWebhook, ag as BoundWebhookTree, m as CorsairClient, q as CorsairContext, r as CorsairEndpoint, t as CorsairErrorHandler, c as CorsairIntegration, N as CorsairKeyBuilder, Q as CorsairKeyBuilderBase, ah as CorsairOAuthWebhookTenantLinkResolver, z as CorsairPermissionsNamespace, C as CorsairPlugin, S as CorsairPluginContext, U as CorsairPluginSubscribe, e as CorsairSingleTenantClient, d as CorsairTenantWrapper, a7 as CorsairThreadsNamespace, ai as CorsairWebhook, aj as CorsairWebhookHandler, ak as CorsairWebhookMatcher, al as CorsairWebhookTenantMatcher, a8 as CreateThreadResult, V as EndpointHooks, X as EndpointMetaEntry, E as EndpointPathsOf, Y as EndpointRiskLevel, s as EndpointTree, D as EnforcePermissionOptions, F as EnforcePermissionResult, u as ErrorContext, v as ErrorHandler, w as ErrorHandlerAndMatchFunction, x as ErrorMatcher, i as IntegrationFieldNames, Z as KeyBuilderContext, j as OAuth2IntegrationCredentials, O as OAuthConfig, _ as PermissionMode, $ as PermissionPolicy, P as PluginAuthConfig, a0 as PluginEndpointMeta, a1 as PluginPermissionsConfig, am as RawWebhookRequest, K as ReadonlyForbiddenError, a2 as RequiredPluginEndpointMeta, a3 as RequiredPluginEndpointSchemas, a4 as RequiredPluginWebhookSchemas, R as RetryStrategies, y as RetryStrategy, a9 as ThreadHandle, aa as ThreadMessage, ab as ThreadSummary, T as TokenResponse, ad as UnionToIntersection, a5 as WebhookHooks, an as WebhookPathsOf, ao as WebhookRequest, ap as WebhookResponse, W as WebhookTenantMatch, aq as WebhookTree, G as assertReadonlyAllowed, l as exchangeCodeForTokens, J as isReadonlyScopeActive, L as runReadonly } from './index-DcJhvFt7.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-Dq3dd_Zs.js';
6
- import { A as AuthTypes } from './types-C24LhkXl.js';
7
- export { g as AllProviders, B as BaseProviders, h as PickAuth, j as ProviderDisplayNames, i as formatProviderDisplayName } from './types-C24LhkXl.js';
3
+ import { A as AccountKeyManagerFor, I as IntegrationKeyManagerFor, f as CorsairPluginSubscribeResult } from './index-BUk1NYnu.js';
4
+ export { g as AccountFieldNames, a6 as AgentReply, k as BASE_AUTH_FIELDS, B as BaseAuthFieldConfig, h as BaseKeyManager, M as BeforeHookResult, n as BindEndpoints, ae as BindWebhooks, ac as Bivariant, o as BoundEndpointFn, p as BoundEndpointTree, af as BoundWebhook, ag as BoundWebhookTree, m as CorsairClient, q as CorsairContext, r as CorsairEndpoint, t as CorsairErrorHandler, c as CorsairIntegration, N as CorsairKeyBuilder, Q as CorsairKeyBuilderBase, ah as CorsairOAuthWebhookTenantLinkResolver, z as CorsairPermissionsNamespace, C as CorsairPlugin, S as CorsairPluginContext, U as CorsairPluginSubscribe, e as CorsairSingleTenantClient, d as CorsairTenantWrapper, a7 as CorsairThreadsNamespace, ai as CorsairWebhook, aj as CorsairWebhookHandler, ak as CorsairWebhookMatcher, al as CorsairWebhookTenantMatcher, a8 as CreateThreadResult, V as EndpointHooks, X as EndpointMetaEntry, E as EndpointPathsOf, Y as EndpointRiskLevel, s as EndpointTree, D as EnforcePermissionOptions, F as EnforcePermissionResult, u as ErrorContext, v as ErrorHandler, w as ErrorHandlerAndMatchFunction, x as ErrorMatcher, i as IntegrationFieldNames, Z as KeyBuilderContext, j as OAuth2IntegrationCredentials, O as OAuthConfig, _ as PermissionMode, $ as PermissionPolicy, P as PluginAuthConfig, a0 as PluginEndpointMeta, a1 as PluginPermissionsConfig, am as RawWebhookRequest, K as ReadonlyForbiddenError, a2 as RequiredPluginEndpointMeta, a3 as RequiredPluginEndpointSchemas, a4 as RequiredPluginWebhookSchemas, R as RetryStrategies, y as RetryStrategy, a9 as ThreadHandle, aa as ThreadMessage, ab as ThreadSummary, T as TokenResponse, ad as UnionToIntersection, a5 as WebhookHooks, an as WebhookPathsOf, ao as WebhookRequest, ap as WebhookResponse, W as WebhookTenantMatch, aq as WebhookTree, G as assertReadonlyAllowed, l as exchangeCodeForTokens, J as isReadonlyScopeActive, L as runReadonly } from './index-BUk1NYnu.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-aY9d2Vje.js';
6
+ import { A as AuthTypes } from './types-DL6dIM3d.js';
7
+ export { g as AllProviders, B as BaseProviders, h as PickAuth, j as ProviderDisplayNames, i as formatProviderDisplayName } from './types-DL6dIM3d.js';
8
8
  import 'kysely';
9
9
  import './index-eydqYIn0.js';
10
10
  import 'zod';
package/dist/core.js CHANGED
@@ -1 +1 @@
1
- import{Ab as B,B as d,Bb as C,C as e,Cb as D,D as f,Db as E,E as g,Eb as F,F as h,Fb as G,G as i,Gb as H,H as j,Hb as I,I as k,Ib as J,J as l,Jb as K,K as m,Kb as L,L as n,Lb as M,M as o,Mb as N,Nb as O,Ob as P,Pb as Q,Qb as R,Xa as v,a,b,ja as p,ma as q,na as r,oa as s,pa as t,qa as u,sb as w,tb as x,ub as y,yb as z,zb as A}from"./chunk-VOB4G3KC.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,I as toExternalId};
1
+ import{B as d,Bb as z,C as e,Cb as A,D as f,Db as B,E as g,Eb as C,F as h,Fb as D,G as i,Gb as E,H as j,Hb as F,I as k,Ib as G,J as l,Jb as H,K as m,Kb as I,L as n,Lb as J,M as o,Mb as K,Nb as L,Ob as M,Pb as N,Qb as O,Rb as P,Sb as Q,Tb as R,_a as v,a,b,ha as p,ka as q,la as r,ma as s,na as t,oa as u,vb as w,wb as x,xb as y}from"./chunk-6PCMHFQJ.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,I as toExternalId};
package/dist/http.js CHANGED
@@ -1 +1 @@
1
- var c=class extends Error{url;status;statusText;body;request;retryAfter;rateLimitReset;rateLimitRemaining;rateLimitLimit;constructor(e,i,n,r){super(n),this.name="ApiError",this.url=i.url,this.status=i.status,this.statusText=i.statusText,this.body=i.body,this.request=e,this.retryAfter=r?.retryAfter,this.rateLimitReset=r?.rateLimitReset,this.rateLimitRemaining=r?.rateLimitRemaining,this.rateLimitLimit=r?.rateLimitLimit}isRateLimitError(){return this.status===429}};var g=class extends Error{constructor(e){super(e),this.name="CancelError"}get isCancelled(){return!0}},p=class{#t;#r;#e;#i;#s;#a;#n;constructor(e){this.#t=!1,this.#r=!1,this.#e=!1,this.#i=[],this.#s=new Promise((i,n)=>{this.#a=i,this.#n=n;let r=o=>{this.#t||this.#r||this.#e||(this.#t=!0,this.#a&&this.#a(o))},a=o=>{this.#t||this.#r||this.#e||(this.#r=!0,this.#n&&this.#n(o))},s=o=>{this.#t||this.#r||this.#e||this.#i.push(o)};return Object.defineProperty(s,"isResolved",{get:()=>this.#t}),Object.defineProperty(s,"isRejected",{get:()=>this.#r}),Object.defineProperty(s,"isCancelled",{get:()=>this.#e}),e(r,a,s)})}get[Symbol.toStringTag](){return"Cancellable Promise"}then(e,i){return this.#s.then(e,i)}catch(e){return this.#s.catch(e)}finally(e){return this.#s.finally(e)}cancel(){if(!(this.#t||this.#r||this.#e)){if(this.#e=!0,this.#i.length)try{for(let e of this.#i)e()}catch(e){console.warn("Cancellation threw an error",e);return}this.#i.length=0,this.#n&&this.#n(new g("Request aborted"))}}get isCancelled(){return this.#e}};var v={enabled:!0,maxRetries:3,initialRetryDelay:1e3,backoffMultiplier:2,headerNames:{retryAfter:"retry-after",resetTime:"x-ratelimit-reset",remaining:"x-ratelimit-remaining",limit:"x-ratelimit-limit"}};function S(t,e){let i={};if(e.headerNames.retryAfter){let n=t.headers.get(e.headerNames.retryAfter);if(n){let r=parseInt(n,10);isNaN(r)||(i.retryAfter=r*1e3)}}if(e.headerNames.resetTime){let n=t.headers.get(e.headerNames.resetTime);if(n){let r=parseInt(n,10);if(!isNaN(r)){let a=Date.now(),s=r>1e12?r:r*1e3;i.rateLimitReset=s,s>a&&(i.retryAfter=s-a)}}}if(e.headerNames.remaining){let n=t.headers.get(e.headerNames.remaining);if(n){let r=parseInt(n,10);isNaN(r)||(i.rateLimitRemaining=r)}}if(e.headerNames.limit){let n=t.headers.get(e.headerNames.limit);if(n){let r=parseInt(n,10);isNaN(r)||(i.rateLimitLimit=r)}}return i}function C(t,e,i){return i.enabled?t===429?!0:i.isRateLimitError?i.isRateLimitError(t,e):!1:!1}function R(t,e,i){if(e.retryAfter)return e.retryAfter;let n=i.initialRetryDelay*Math.pow(i.backoffMultiplier,t-1);return Math.min(n,6e4)}async function T(t){return new Promise(e=>setTimeout(e,t))}var x=t=>t!=null,d=t=>typeof t=="string",A=t=>d(t)&&t!=="",E=t=>typeof t=="object"&&typeof t.type=="string"&&typeof t.stream=="function"&&typeof t.arrayBuffer=="function"&&typeof t.constructor=="function"&&typeof t.constructor.name=="string"&&/^(Blob|File)$/.test(t.constructor.name)&&/^(Blob|File)$/.test(t[Symbol.toStringTag]),N=t=>t instanceof FormData,j=t=>{try{return btoa(t)}catch{return Buffer.from(t).toString("base64")}},k=t=>{let e=[],i=(r,a)=>{e.push(`${encodeURIComponent(r)}=${encodeURIComponent(String(a))}`)},n=(r,a)=>{x(a)&&(Array.isArray(a)?a.forEach(s=>{n(r,s)}):typeof a=="object"?Object.entries(a).forEach(([s,o])=>{n(`${r}[${s}]`,o)}):i(r,a))};return Object.entries(t).forEach(([r,a])=>{n(r,a)}),e.length>0?`?${e.join("&")}`:""},$=(t,e)=>{let i=t.ENCODE_PATH||encodeURI,n=e.url.replace("{api-version}",t.VERSION).replace(/{(.*?)}/g,(o,l)=>e.path?.hasOwnProperty(l)?i(String(e.path[l])):o),r=t.BASE.endsWith("/")?t.BASE.slice(0,-1):t.BASE,a=n.startsWith("/")?n.slice(1):n,s=`${r}/${a}`;return e.query?`${s}${k(e.query)}`:s},W=t=>{if(t.formData){let e=new FormData,i=(n,r)=>{d(r)||E(r)?e.append(n,r):e.append(n,JSON.stringify(r))};return Object.entries(t.formData).filter(([n,r])=>x(r)).forEach(([n,r])=>{Array.isArray(r)?r.forEach(a=>i(n,a)):i(n,r)}),e}},h=async(t,e)=>typeof e=="function"?e(t):e,M=async(t,e)=>{let[i,n,r,a]=await Promise.all([h(e,t.TOKEN),h(e,t.USERNAME),h(e,t.PASSWORD),h(e,t.HEADERS)]),s=Object.entries({Accept:"application/json",...a,...e.headers}).filter(([o,l])=>x(l)).reduce((o,[l,u])=>({...o,[l]:String(u)}),{});if(A(i)&&(s.Authorization=`Bearer ${i}`),A(n)&&A(r)){let o=j(`${n}:${r}`);s.Authorization=`Basic ${o}`}return e.body!==void 0&&(e.mediaType?s["Content-Type"]=e.mediaType:E(e.body)?s["Content-Type"]=e.body.type||"application/octet-stream":d(e.body)?s["Content-Type"]="text/plain":N(e.body)||(s["Content-Type"]="application/json")),new Headers(s)},F=t=>{if(t.body!==void 0)return t.mediaType?.includes("/json")?JSON.stringify(t.body):d(t.body)||E(t.body)||N(t.body)?t.body:JSON.stringify(t.body)},U=async(t,e,i,n,r,a,s)=>{let o=new AbortController,l=t.TIMEOUT??2e4,u={headers:a,body:n??r,method:e.method,signal:AbortSignal.any([o.signal,AbortSignal.timeout(l)])};return t.WITH_CREDENTIALS&&(u.credentials=t.CREDENTIALS),s(()=>o.abort()),await fetch(i,u)},_=(t,e)=>{if(e){let i=t.headers.get(e);if(d(i))return i}},J=async t=>{if(t.status!==204)try{let e=t.headers.get("Content-Type");if(e)return["application/json","application/problem+json"].some(r=>e.toLowerCase().startsWith(r))?await t.json():await t.text()}catch(e){console.error(e)}},P=(t,e,i)=>{let r={400:"Bad Request",401:"Unauthorized",403:"Forbidden",404:"Not Found",429:"Too Many Requests",500:"Internal Server Error",502:"Bad Gateway",503:"Service Unavailable",...t.errors}[e.status];if(r)throw new c(t,e,r,i);if(!e.ok){let a=e.status??"unknown",s=e.statusText??"unknown",o=(()=>{try{return JSON.stringify(e.body,null,2)}catch{return}})(),l=e.body?.message||e.body?.error||e.body?.detail||`Generic Error: status: ${a}; status text: ${s}; body: ${o}`;throw new c(t,e,l,i)}},G=(t,e,i)=>{let n=i?.rateLimitConfig||v;return new p(async(r,a,s)=>{let o=0,l=n.maxRetries+1;for(;o<l;){o++;try{let u=$(t,e),b=W(e),w=F(e),H=await M(t,e);if(s.isCancelled)return;let f=await U(t,e,u,w,b,H,s),I=await J(f),B=_(f,e.responseHeader),y={url:u,ok:f.ok,status:f.status,statusText:f.statusText,body:B??I};if(n.enabled&&C(f.status,y.body,n)){let O=S(f,n);if(o<l){let D=R(o,O,n);await T(D);continue}P(e,y,O)}P(e,y),r(y.body);return}catch(u){if(u instanceof c&&u.isRateLimitError()&&o<l){let b=u.retryAfter?u.retryAfter:R(o,{retryAfter:u.retryAfter,rateLimitReset:u.rateLimitReset},n);await T(b);continue}if(o>=l){a(u);return}if(u instanceof c&&u.isRateLimitError())continue;a(u);return}}})};var L=class{handlers=new Map;on(e,i){let n=this.handlers.get(e)||[];return n.push(i),this.handlers.set(e,n),this}off(e,i){let n=this.handlers.get(e)||[],r=n.indexOf(i);return r!==-1&&(n.splice(r,1),this.handlers.set(e,n)),this}getRegisteredEvents(){return Array.from(this.handlers.keys())}hasHandlers(e){let i=this.handlers.get(e);return!!i&&i.length>0}clearHandlers(e){return e?this.handlers.delete(e):this.handlers.clear(),this}async executeHandlers(e,i){let n=this.handlers.get(e)||[];for(let r of n)await r(i)}};import*as m from"crypto";function z(t,e,i,n="sha256"){if(!i||!e)return!1;let r=m.createHmac(n,e).update(t).digest("hex");try{return m.timingSafeEqual(Buffer.from(i),Buffer.from(r))}catch{return!1}}function V(t,e,i,n,r="sha256"){if(!i||!e||!i.startsWith(n))return!1;let a=i.slice(n.length),s=m.createHmac(r,e).update(t).digest("hex");try{return m.timingSafeEqual(Buffer.from(a),Buffer.from(s))}catch{return!1}}function q(t,e,i,n,r=300){if(!e||!n||!i)return!1;let a=Math.floor(Date.now()/1e3),s=parseInt(i,10);if(Math.abs(a-s)>r)return!1;let o=`v0:${i}:${t}`,l="v0="+m.createHmac("sha256",e).update(o).digest("hex");try{return m.timingSafeEqual(Buffer.from(n),Buffer.from(l))}catch{return!1}}function K(t,e,i,n,r=300){return q(t,e,i,n,r)}export{c as ApiError,L as BaseWebhookHandler,G as request,q as verifyHmacSha256Signature,z as verifyHmacSignature,V as verifyHmacSignatureWithPrefix,K as verifySlackSignature};
1
+ var $=new Set(["api_key","key","token","appid"]);function g(t){let e=t;try{e=decodeURIComponent(t)}catch{e=t}return $.has(e.toLowerCase())}function W(t){let e=t.indexOf("?");if(e===-1)return t;let n=t.indexOf("#",e),r=t.slice(0,e+1),i=n===-1?t.slice(e+1):t.slice(e+1,n),s=n===-1?"":t.slice(n),a=!1,o=i.split("&").map(c=>{if(!c)return c;let u=c.indexOf("="),d=u===-1?c:c.slice(0,u);return g(d)?(a=!0,`${d}=[REDACTED]`):c}).join("&");return a?r+o+s:t}function C(t){if(!t)return t;try{let e=/^[a-z]+:\/\//i.test(t),n=e?void 0:"http://localhost",r=new URL(t,n),i=!1;for(let s of[...r.searchParams.keys()])g(s)&&(r.searchParams.set(s,"[REDACTED]"),i=!0);return i?e?r.toString():r.pathname+r.search+r.hash:t}catch{return W(t)}}function M(t){let e=C(t.url),n=!1,r=t.query;if(t.query){r={...t.query};for(let i of Object.keys(r))g(i)&&(r[i]="[REDACTED]",n=!0)}return!n&&e===t.url?t:{...t,url:e,...n?{query:r}:{}}}var l=class extends Error{url;status;statusText;body;request;retryAfter;rateLimitReset;rateLimitRemaining;rateLimitLimit;constructor(e,n,r,i){super(r),this.name="ApiError",this.url=C(n.url),this.status=n.status,this.statusText=n.statusText,this.body=n.body,this.request=M(e),this.retryAfter=i?.retryAfter,this.rateLimitReset=i?.rateLimitReset,this.rateLimitRemaining=i?.rateLimitRemaining,this.rateLimitLimit=i?.rateLimitLimit}isRateLimitError(){return this.status===429}};var R=class extends Error{constructor(e){super(e),this.name="CancelError"}get isCancelled(){return!0}},h=class{#t;#r;#e;#n;#s;#a;#i;constructor(e){this.#t=!1,this.#r=!1,this.#e=!1,this.#n=[],this.#s=new Promise((n,r)=>{this.#a=n,this.#i=r;let i=o=>{this.#t||this.#r||this.#e||(this.#t=!0,this.#a&&this.#a(o))},s=o=>{this.#t||this.#r||this.#e||(this.#r=!0,this.#i&&this.#i(o))},a=o=>{this.#t||this.#r||this.#e||this.#n.push(o)};return Object.defineProperty(a,"isResolved",{get:()=>this.#t}),Object.defineProperty(a,"isRejected",{get:()=>this.#r}),Object.defineProperty(a,"isCancelled",{get:()=>this.#e}),e(i,s,a)})}get[Symbol.toStringTag](){return"Cancellable Promise"}then(e,n){return this.#s.then(e,n)}catch(e){return this.#s.catch(e)}finally(e){return this.#s.finally(e)}cancel(){if(!(this.#t||this.#r||this.#e)){if(this.#e=!0,this.#n.length)try{for(let e of this.#n)e()}catch(e){console.warn("Cancellation threw an error",e);return}this.#n.length=0,this.#i&&this.#i(new R("Request aborted"))}}get isCancelled(){return this.#e}};var P={enabled:!0,maxRetries:3,initialRetryDelay:1e3,backoffMultiplier:2,headerNames:{retryAfter:"retry-after",resetTime:"x-ratelimit-reset",remaining:"x-ratelimit-remaining",limit:"x-ratelimit-limit"}};function S(t,e){let n={};if(e.headerNames.retryAfter){let r=t.headers.get(e.headerNames.retryAfter);if(r){let i=parseInt(r,10);isNaN(i)||(n.retryAfter=i*1e3)}}if(e.headerNames.resetTime){let r=t.headers.get(e.headerNames.resetTime);if(r){let i=parseInt(r,10);if(!isNaN(i)){let s=Date.now(),a=i>1e12?i:i*1e3;n.rateLimitReset=a,a>s&&(n.retryAfter=a-s)}}}if(e.headerNames.remaining){let r=t.headers.get(e.headerNames.remaining);if(r){let i=parseInt(r,10);isNaN(i)||(n.rateLimitRemaining=i)}}if(e.headerNames.limit){let r=t.headers.get(e.headerNames.limit);if(r){let i=parseInt(r,10);isNaN(i)||(n.rateLimitLimit=i)}}return n}function q(t,e,n){return n.enabled?t===429?!0:n.isRateLimitError?n.isRateLimitError(t,e):!1:!1}function T(t,e,n){if(e.retryAfter)return e.retryAfter;let r=n.initialRetryDelay*Math.pow(n.backoffMultiplier,t-1);return Math.min(r,6e4)}async function A(t){return new Promise(e=>setTimeout(e,t))}var x=t=>t!=null,y=t=>typeof t=="string",E=t=>y(t)&&t!=="",L=t=>typeof t=="object"&&typeof t.type=="string"&&typeof t.stream=="function"&&typeof t.arrayBuffer=="function"&&typeof t.constructor=="function"&&typeof t.constructor.name=="string"&&/^(Blob|File)$/.test(t.constructor.name)&&/^(Blob|File)$/.test(t[Symbol.toStringTag]),N=t=>t instanceof FormData,F=t=>{try{return btoa(t)}catch{return Buffer.from(t).toString("base64")}},U=t=>{let e=[],n=(i,s)=>{e.push(`${encodeURIComponent(i)}=${encodeURIComponent(String(s))}`)},r=(i,s)=>{x(s)&&(Array.isArray(s)?s.forEach(a=>{r(i,a)}):typeof s=="object"?Object.entries(s).forEach(([a,o])=>{r(`${i}[${a}]`,o)}):n(i,s))};return Object.entries(t).forEach(([i,s])=>{r(i,s)}),e.length>0?`?${e.join("&")}`:""},_=(t,e)=>{let n=t.ENCODE_PATH||encodeURI,r=e.url.replace("{api-version}",t.VERSION).replace(/{(.*?)}/g,(o,c)=>e.path?.hasOwnProperty(c)?n(String(e.path[c])):o),i=t.BASE.endsWith("/")?t.BASE.slice(0,-1):t.BASE,s=r.startsWith("/")?r.slice(1):r,a=`${i}/${s}`;return e.query?`${a}${U(e.query)}`:a},J=t=>{if(t.formData){let e=new FormData,n=(r,i)=>{y(i)||L(i)?e.append(r,i):e.append(r,JSON.stringify(i))};return Object.entries(t.formData).filter(([r,i])=>x(i)).forEach(([r,i])=>{Array.isArray(i)?i.forEach(s=>n(r,s)):n(r,i)}),e}},b=async(t,e)=>typeof e=="function"?e(t):e,z=async(t,e)=>{let[n,r,i,s]=await Promise.all([b(e,t.TOKEN),b(e,t.USERNAME),b(e,t.PASSWORD),b(e,t.HEADERS)]),a=Object.entries({Accept:"application/json",...s,...e.headers}).filter(([o,c])=>x(c)).reduce((o,[c,u])=>({...o,[c]:String(u)}),{});if(E(n)&&(a.Authorization=`Bearer ${n}`),E(r)&&E(i)){let o=F(`${r}:${i}`);a.Authorization=`Basic ${o}`}return e.body!==void 0&&(e.mediaType?a["Content-Type"]=e.mediaType:L(e.body)?a["Content-Type"]=e.body.type||"application/octet-stream":y(e.body)?a["Content-Type"]="text/plain":N(e.body)||(a["Content-Type"]="application/json")),new Headers(a)},Q=t=>{if(t.body!==void 0)return t.mediaType?.includes("/json")?JSON.stringify(t.body):y(t.body)||L(t.body)||N(t.body)?t.body:JSON.stringify(t.body)},G=async(t,e,n,r,i,s,a)=>{let o=new AbortController,c=t.TIMEOUT??2e4,u={headers:s,body:r??i,method:e.method,signal:AbortSignal.any([o.signal,AbortSignal.timeout(c)])};return t.WITH_CREDENTIALS&&(u.credentials=t.CREDENTIALS),a(()=>o.abort()),await fetch(n,u)},V=(t,e)=>{if(e){let n=t.headers.get(e);if(y(n))return n}},K=async t=>{if(t.status!==204)try{let e=t.headers.get("Content-Type");if(e)return["application/json","application/problem+json"].some(i=>e.toLowerCase().startsWith(i))?await t.json():await t.text()}catch(e){console.error(e)}},w=(t,e,n)=>{let i={400:"Bad Request",401:"Unauthorized",403:"Forbidden",404:"Not Found",429:"Too Many Requests",500:"Internal Server Error",502:"Bad Gateway",503:"Service Unavailable",...t.errors}[e.status];if(i)throw new l(t,e,i,n);if(!e.ok){let s=e.status??"unknown",a=e.statusText??"unknown",o=(()=>{try{return JSON.stringify(e.body,null,2)}catch{return}})(),c=e.body?.message||e.body?.error||e.body?.detail||`Generic Error: status: ${s}; status text: ${a}; body: ${o}`;throw new l(t,e,c,n)}},Y=(t,e,n)=>{let r=n?.rateLimitConfig||P;return new h(async(i,s,a)=>{let o=0,c=r.maxRetries+1;for(;o<c;){o++;try{let u=_(t,e),d=J(e),D=Q(e),H=await z(t,e);if(a.isCancelled)return;let m=await G(t,e,u,D,d,H,a),k=await K(m),B=V(m,e.responseHeader),p={url:u,ok:m.ok,status:m.status,statusText:m.statusText,body:B??k};if(r.enabled&&q(m.status,p.body,r)){let v=S(m,r);if(o<c){let j=T(o,v,r);await A(j);continue}w(e,p,v)}w(e,p),i(p.body);return}catch(u){if(u instanceof l&&u.isRateLimitError()&&o<c){let d=u.retryAfter?u.retryAfter:T(o,{retryAfter:u.retryAfter,rateLimitReset:u.rateLimitReset},r);await A(d);continue}if(o>=c){s(u);return}if(u instanceof l&&u.isRateLimitError())continue;s(u);return}}})};var O=class{handlers=new Map;on(e,n){let r=this.handlers.get(e)||[];return r.push(n),this.handlers.set(e,r),this}off(e,n){let r=this.handlers.get(e)||[],i=r.indexOf(n);return i!==-1&&(r.splice(i,1),this.handlers.set(e,r)),this}getRegisteredEvents(){return Array.from(this.handlers.keys())}hasHandlers(e){let n=this.handlers.get(e);return!!n&&n.length>0}clearHandlers(e){return e?this.handlers.delete(e):this.handlers.clear(),this}async executeHandlers(e,n){let r=this.handlers.get(e)||[];for(let i of r)await i(n)}};import*as f from"crypto";function X(t,e,n,r="sha256"){if(!n||!e)return!1;let i=f.createHmac(r,e).update(t).digest("hex");try{return f.timingSafeEqual(Buffer.from(n),Buffer.from(i))}catch{return!1}}function Z(t,e,n,r,i="sha256"){if(!n||!e||!n.startsWith(r))return!1;let s=n.slice(r.length),a=f.createHmac(i,e).update(t).digest("hex");try{return f.timingSafeEqual(Buffer.from(s),Buffer.from(a))}catch{return!1}}function I(t,e,n,r,i=300){if(!e||!r||!n)return!1;let s=Math.floor(Date.now()/1e3),a=parseInt(n,10);if(Math.abs(s-a)>i)return!1;let o=`v0:${n}:${t}`,c="v0="+f.createHmac("sha256",e).update(o).digest("hex");try{return f.timingSafeEqual(Buffer.from(r),Buffer.from(c))}catch{return!1}}function ee(t,e,n,r,i=300){return I(t,e,n,r,i)}export{l as ApiError,O as BaseWebhookHandler,Y as request,I as verifyHmacSha256Signature,X as verifyHmacSignature,Z as verifyHmacSignatureWithPrefix,ee as verifySlackSignature};
package/dist/hub.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { A as AuthTypes } from './types-C24LhkXl.js';
2
- export { i as formatProviderDisplayName } from './types-C24LhkXl.js';
3
- import { as as HubOAuthMode, at as HubConnectSessionResult, au as HubPermissionSessionResult, H as HubConfig, av as HubConfigInput, aw as HubConnectSessionInput, ax as HubListProjectConnectionsInput, A as AccountKeyManagerFor, ay as HubPermissionSessionInput } from './index-DcJhvFt7.js';
4
- export { az as DEFAULT_HUB_API_URL, aA as HubEnvironmentSlug } from './index-DcJhvFt7.js';
5
- import { k as TunnelType, R as RunResultPayload, P as ProbeResultPayload, g as ProcessCorsairRequest, m as WebhookTenantLink } from './index-CsNw9hYU.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-CsNw9hYU.js';
7
- export { b as buildBrowserDeliveryRedirectUrl, s as signBrowserDeliveryToken, v as verifyBrowserDeliveryToken } from './browser-delivery-BJtn0HMO.js';
1
+ import { A as AuthTypes } from './types-DL6dIM3d.js';
2
+ export { i as formatProviderDisplayName } from './types-DL6dIM3d.js';
3
+ import { as as HubOAuthMode, at as HubConnectSessionResult, au as HubPermissionSessionResult, H as HubConfig, av as HubConfigInput, aw as HubConnectSessionInput, ax as HubListProjectConnectionsInput, A as AccountKeyManagerFor, ay as HubPermissionSessionInput } from './index-BUk1NYnu.js';
4
+ export { az as DEFAULT_HUB_API_URL, aA as HubEnvironmentSlug } from './index-BUk1NYnu.js';
5
+ import { k as TunnelType, R as RunResultPayload, P as ProbeResultPayload, g as ProcessCorsairRequest, m as WebhookTenantLink } from './index-CnwB37Yx.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-CnwB37Yx.js';
7
+ export { b as buildBrowserDeliveryRedirectUrl, s as signBrowserDeliveryToken, v as verifyBrowserDeliveryToken } from './browser-delivery-CmVn1y2T.js';
8
8
  import './index-eydqYIn0.js';
9
9
  import 'zod';
10
10
  import './db.js';
@@ -160,12 +160,6 @@ type ConnectCreateLinkDeliveryResult = {
160
160
  expiresAt?: string;
161
161
  };
162
162
 
163
- declare function getConnectStatusForTenant(corsair: unknown, tenantId: string, options?: {
164
- pluginIds?: string[];
165
- }): Promise<ConnectStatusResponse>;
166
-
167
- declare function listHubProjectConnections(corsair: unknown, input: HubListProjectConnectionsInput): Promise<HubProjectConnection[]>;
168
-
169
163
  /**
170
164
  * Server (production) delivery — hub POSTs a signed JSON envelope to the app's public delivery URL.
171
165
  *
@@ -349,6 +343,12 @@ declare function deliverSignedEnvelope(input: {
349
343
  payload: unknown;
350
344
  }): Promise<SignedEnvelopeDeliveryResult>;
351
345
 
346
+ declare function getConnectStatusForTenant(corsair: unknown, tenantId: string, options?: {
347
+ pluginIds?: string[];
348
+ }): Promise<ConnectStatusResponse>;
349
+
350
+ declare function listHubProjectConnections(corsair: unknown, input: HubListProjectConnectionsInput): Promise<HubProjectConnection[]>;
351
+
352
352
  type HubDeliveryResult = {
353
353
  type: 'redirect';
354
354
  url: string;