corsair 0.1.136 → 0.1.138

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-CkaSwl1Q.js';
1
+ import { B as BrowserDeliveryPayload } from './index-B24Mpoel.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 xe,b as ir,c as sr}from"./chunk-6IURNA4L.js";import{a as Zo,b as zn}from"./chunk-QAK6BJXE.js";import{a as zo,b as Ie,c as Jo,d as T,e as K,f as Vo,g as ee,h as j,i as S,j as Jn,k as Yo,l as en,m as or,n as Qo}from"./chunk-7AYINDN2.js";import{a as Go}from"./chunk-N66TLOH2.js";import{ZodBoolean as hd,ZodDate as bd,ZodEnum as kd,ZodNullable as wd,ZodNumber as Cd,ZodObject as vd,ZodOptional as Td,ZodRecord as Pd,ZodString as Rd,ZodType as Ad}from"zod";var Vn=["ably","abstract","abuseipdb","abyssale","accrediblecertificates","activecampaign","activetrail","addresszen","aeroleads","affinda","agencyzoom","agentmail","agentql","agenty","agiled","agilitycms","ahrefs","aimlapi","airtable","aivoov","alchemy","algolia","allimagesai","alphavantage","altoviz","alttextai","amara","ambee","ambientweather","amcards","amplitude","anchorbrowser","anonyflow","anthropicadministrator","apaleo","api2pdf","apibible","apify","apilabz","apininjas","apipie","apisports","appointo","aryn","asana","ascora","ashby","asindataapi","asticaai","asyncinterview","attio","autom","ayrshare","backendless","bannerbear","bart","basecamp","baselinker","basin","beaconstac","beamer","beeminder","benchmarkemail","bestbuy","bettercontact","betterproposals","betterstack","bigdatacloud","bigmailer","bigml","bigpictureio","bitbucket","bitwarden","blazemeter","blocknative","bluesky","boldsign","boloforms","boltiot","bonsai","bookingmood","booqable","borneo","botbaba","botpress","botsonic","bouncer","box","boxhero","brandfetch","breathehr","brevo","brex","brightdata","browseai","browserless","browsertool","bubble","bugsnag","buildkite","bunnycdn","byteforms","cal","calendly","campaigncleaner","campayn","canny","canva","canvas","capsulecrm","carbone","castingwords","cdrplatform","certifier","chaser","chatbotkit","chatfai","chmeetings","cincopa","circleci","classmarker","clickhouse","clickmeeting","clientary","clockify","cloudcart","cloudflare","cloudflareapikey","cloudinary","cody","coinbase","collegefootballdata","confluence","connecteam","contentfulgraphql","contextsevenmcp","convoloai","cosmic","countdownapi","crowterminal","currentsapi","cursor","customerio","customgpt","dadataru","databricks","datadog","datarobot","deepseek","devinmcp","diffbot","digitalocean","discord","dockerhub","docupost","dodopayments","doppler","dovetail","dreamstudio","dripcel","dropbox","dropboxsign","dynapictures","emelia","epicgames","everhour","exa","exist","extractaai","facebook","faraday","figma","filevine","filloutforms","firecrawl","fireflies","flexisign","flutterwave","formbricks","gemini","giphy","github","gitlab","gladia","gmail","googleaddressvalidation","googleanalytics","googlebigquery","googlecalendar","googlecloudvision","googledocs","googledrive","googlemaps","googlemeet","googlesheets","grafana","griptape","groqcloud","habitica","hackernews","harvest","hashnode","here","heygen","hookdeck","htmltoimage","hubspot","huggingface","imagior","humanitix","imejisio","imgbb","insightoai","instagram","intercom","jigsawstack","jira","kaggle","kibana","leexi","linear","linkedin","loyverse","mailboxlayer","mailcheck","mailchimp","mailtrap","marketstack","merriamwebsterdict","monday","neon","nextdns","northflank","notion","ocrspace","ocrwebservice","ollama","onedrive","onepassword","openai","openrouter","openweathermap","oura","outlook","pagerduty","parseur","pdfco","pdfmonkey","perplexityai","phantombuster","pinecone","plain","posthog","postman","prisma","pushbullet","razorpay","reddit","replicate","removebg","replyio","resend","retailed","rootly","runpod","salesforce","sapsuccessfactors","scaleai","scrapegraphai","securitytrails","semanticscholar","sendgrid","sentry","serpapi","sharepoint","slack","snapchat","slackbot","sourcegraph","spoki","spotify","strava","streamtime","stripe","studiobyai21labs","supabase","supadata","synthflowai","tally","tavily","tavilymcp","teams","telegram","textrazor","ticktick","timecamp","timelink","tinyurl","tisane","todoist","toggl","tokenmetrics","tpscheck","trello","tripadvisor","twentyonerisk","twilio","twitter","twitterapiio","twochat","typeform","unione","uniswapapi","uploadcare","vapi","vercel","veriphone","vestaboard","waboxapp","wakatime","webflow","webscrapingai","webvizio","whatsapp","whoisfreaks","whautomate","winstonai","witai","wix","wiza","workday","workiom","worldnewsapi","xero","writer","xquik","youcom","youtube","zendesk","zenserp","zohobigin","zohoinventory","zohomail","zoom","zoominfo"],Xo={ably:"Ably",abstract:"Abstract",abuseipdb:"AbuseIPDB",abyssale:"Abyssale",accrediblecertificates:"Accredible Certificates",activecampaign:"ActiveCampaign",activetrail:"Active Trail",addresszen:"Addresszen",aeroleads:"Aeroleads",affinda:"Affinda",agencyzoom:"AgencyZoom",agentmail:"AgentMail",agentql:"AgentQL",agenty:"Agenty",agiled:"Agiled",agilitycms:"Agility CMS",ahrefs:"Ahrefs",aimlapi:"AI/ML API",airtable:"Airtable",aivoov:"AiVOOV",alchemy:"Alchemy",algolia:"Algolia",allimagesai:"All Images AI",alphavantage:"Alpha Vantage",altoviz:"Altoviz",alttextai:"AltText.ai",amara:"Amara",ambee:"Ambee",ambientweather:"Ambient Weather",amcards:"AMcards",amplitude:"Amplitude",anchorbrowser:"Anchor Browser",anonyflow:"Anonyflow",anthropicadministrator:"Anthropic Administrator",apaleo:"Apaleo",api2pdf:"API2PDF",apibible:"API.Bible",apify:"Apify",apilabz:"API Labz",apininjas:"API Ninjas",apipie:"APIpie AI",apisports:"API-Sports",appointo:"Appointo",aryn:"Aryn",asana:"Asana",ascora:"Ascora",ashby:"Ashby",asindataapi:"ASIN Data API",asticaai:"Astica AI",asyncinterview:"Async Interview",attio:"Attio",autom:"Autom",ayrshare:"Ayrshare",backendless:"Backendless",bannerbear:"Bannerbear",bart:"BART",basecamp:"Basecamp",baselinker:"BaseLinker",basin:"Basin",beaconstac:"Beaconstac",beamer:"Beamer",beeminder:"Beeminder",benchmarkemail:"BenchmarkEmail",bestbuy:"Best Buy",bettercontact:"BetterContact",betterproposals:"Better Proposals",betterstack:"Better Stack",bigdatacloud:"BigDataCloud",bigmailer:"BigMailer",bigml:"BigML",bigpictureio:"BigPicture.io",bitbucket:"Bitbucket",bitwarden:"Bitwarden",blazemeter:"BlazeMeter",blocknative:"Blocknative",bluesky:"Bluesky",boldsign:"Boldsign",boloforms:"Boloforms",boltiot:"Bolt IoT",bonsai:"Bonsai",bookingmood:"Bookingmood",booqable:"Booqable",borneo:"Borneo",botbaba:"Botbaba",botpress:"Botpress",botsonic:"Botsonic",bouncer:"Bouncer",box:"Box",boxhero:"BoxHero",brandfetch:"Brandfetch",breathehr:"Breathe HR",brevo:"Brevo",brex:"Brex",brightdata:"Bright Data",browseai:"Browse AI",browserless:"Browserless",browsertool:"Browser Tool",bubble:"Bubble",bugsnag:"BugSnag",buildkite:"Buildkite",bunnycdn:"Bunnycdn",byteforms:"ByteForms",cal:"Cal",calendly:"Calendly",campaigncleaner:"Campaign Cleaner",campayn:"Campayn",canny:"Canny",canva:"Canva",canvas:"Canvas LMS",capsulecrm:"Capsule CRM",carbone:"Carbone",castingwords:"CastingWords",cdrplatform:"CDR Platform",certifier:"Certifier",chaser:"Chaser",chatbotkit:"ChatBotKit",chatfai:"ChatFAI",chmeetings:"ChMeetings",cincopa:"Cincopa",circleci:"CircleCI",classmarker:"ClassMarker",clickhouse:"Clickhouse",clickmeeting:"ClickMeeting",clientary:"Clientary",clockify:"Clockify",cloudcart:"CloudCart",cloudflare:"Cloudflare",cloudflareapikey:"Cloudflare API Key",cloudinary:"Cloudinary",cody:"Cody",coinbase:"Coinbase",collegefootballdata:"College Football Data",confluence:"Confluence",connecteam:"Connecteam",contentfulgraphql:"Contentful GraphQL",contextsevenmcp:"Context7",convoloai:"ConvoloAi",cosmic:"Cosmic",countdownapi:"Countdown API",crowterminal:"CrowTerminal",currentsapi:"CurrentsApi",cursor:"Cursor",customerio:"Customer.io",customgpt:"CustomGPT",dadataru:"Dadataru",databricks:"Databricks",datadog:"Datadog",datarobot:"DataRobot",deepseek:"DeepSeek",devinmcp:"Devin MCP",diffbot:"Diffbot",digitalocean:"DigitalOcean",discord:"Discord",dockerhub:"Docker Hub",docupost:"Docupost",dodopayments:"Dodo Payments",doppler:"Doppler",dovetail:"Dovetail",dreamstudio:"DreamStudio",dripcel:"Dripcel",dropbox:"Dropbox",dropboxsign:"Dropbox Sign",dynapictures:"Dynapictures",emelia:"Emelia",epicgames:"Epic Games",everhour:"Everhour",exa:"Exa",exist:"Exist",extractaai:"Extracta.ai",facebook:"Facebook",faraday:"Faraday",figma:"Figma",filevine:"Filevine",filloutforms:"FilloutForms",firecrawl:"Firecrawl",fireflies:"Fireflies",flexisign:"Flexisign",flutterwave:"Flutterwave",formbricks:"Formbricks",gemini:"Gemini",giphy:"Giphy",github:"GitHub",gitlab:"GitLab",gladia:"Gladia",gmail:"Gmail",googleaddressvalidation:"Google Address Validation",googleanalytics:"Google Analytics",googlebigquery:"Google BigQuery",googlecalendar:"Google Calendar",googlecloudvision:"Google Cloud Vision",googledocs:"Google Docs",googledrive:"Google Drive",googlemaps:"Google Maps",googlemeet:"Google Meet",googlesheets:"Google Sheets",grafana:"Grafana",griptape:"Griptape",groqcloud:"GroqCloud",habitica:"Habitica",hackernews:"Hacker News",harvest:"Harvest",hashnode:"Hashnode",here:"HERE",heygen:"HeyGen",hookdeck:"Hookdeck",htmltoimage:"HtmlToImage",hubspot:"HubSpot",huggingface:"Hugging Face",imagior:"Imagior",humanitix:"Humanitix",imejisio:"Imejis.io",imgbb:"ImgBB",insightoai:"Insighto.ai",instagram:"Instagram",intercom:"Intercom",jigsawstack:"JigsawStack",jira:"Jira",kaggle:"Kaggle",kibana:"Kibana",leexi:"Leexi",linear:"Linear",linkedin:"LinkedIn",loyverse:"Loyverse",mailboxlayer:"MailboxLayer",mailcheck:"Mailcheck",mailchimp:"Mailchimp",mailtrap:"Mailtrap",marketstack:"Marketstack",merriamwebsterdict:"Merriam-Webster Dictionary",monday:"Monday",neon:"Neon",nextdns:"NextDNS",northflank:"Northflank",notion:"Notion",ocrspace:"OCR.space",ocrwebservice:"OcrWebService",ollama:"Ollama",onedrive:"OneDrive",onepassword:"1Password",openai:"OpenAI",openrouter:"OpenRouter",openweathermap:"OpenWeatherMap",oura:"Oura",outlook:"Outlook",pagerduty:"PagerDuty",parseur:"Parseur",pdfco:"PDF.co",pdfmonkey:"PDFMonkey",perplexityai:"Perplexity AI",phantombuster:"PhantomBuster",pinecone:"Pinecone",plain:"Plain",posthog:"PostHog",postman:"Postman",prisma:"Prisma",pushbullet:"Pushbullet",razorpay:"Razorpay",reddit:"Reddit",replicate:"Replicate",removebg:"remove.bg",replyio:"Reply.io",resend:"Resend",retailed:"Retailed",rootly:"Rootly",runpod:"RunPod",salesforce:"Salesforce",sapsuccessfactors:"SAP SuccessFactors",scaleai:"Scale AI",scrapegraphai:"ScrapeGraphAI",securitytrails:"SecurityTrails",semanticscholar:"Semantic Scholar",sendgrid:"SendGrid",sentry:"Sentry",serpapi:"Serpapi",sharepoint:"SharePoint",slack:"Slack",snapchat:"Snapchat",slackbot:"Slackbot",sourcegraph:"Sourcegraph",spoki:"Spoki",spotify:"Spotify",strava:"Strava",streamtime:"Streamtime",stripe:"Stripe",studiobyai21labs:"StudioByAI21Labs",supabase:"Supabase",supadata:"Supadata",synthflowai:"Synthflow AI",tally:"Tally",tavily:"Tavily",tavilymcp:"Tavily MCP",teams:"Teams",telegram:"Telegram",textrazor:"TextRazor",ticktick:"TickTick",timecamp:"TimeCamp",timelink:"Timelink",tinyurl:"TinyURL",tisane:"Tisane",todoist:"Todoist",toggl:"Toggl",tokenmetrics:"Token Metrics",tpscheck:"TPSCheck",trello:"Trello",tripadvisor:"Tripadvisor",twentyonerisk:"TwentyOneRisk",twilio:"Twilio",twitter:"Twitter",twitterapiio:"Twitter API IO",twochat:"TwoChat",typeform:"Typeform",unione:"Unione",uniswapapi:"Uniswap",uploadcare:"Uploadcare",vapi:"Vapi",vercel:"Vercel",veriphone:"Veriphone",vestaboard:"Vestaboard",waboxapp:"Waboxapp",wakatime:"WakaTime",webflow:"Webflow",webscrapingai:"WebScraping.AI",webvizio:"Webvizio",whatsapp:"WhatsApp",whoisfreaks:"Whoisfreaks",whautomate:"Whautomate",winstonai:"Winston AI",witai:"WitAi",wix:"Wix",wiza:"Wiza",workday:"Workday",workiom:"Workiom",worldnewsapi:"World News API",xero:"Xero",writer:"Writer",xquik:"XQuik",youcom:"You.com",youtube:"YouTube",zendesk:"Zendesk",zenserp:"Zenserp",zohobigin:"Zoho Bigin",zohoinventory:"Zoho Inventory",zohomail:"Zoho Mail",zoom:"Zoom",zoominfo:"ZoomInfo"};function Se(e){let n=Xo[e];return n||e.charAt(0).toUpperCase()+e.slice(1)}var ye=class extends Error{connectUrl;plugin;tenantId;reason;constructor(n){super(n.message??"Reconnect required"),Object.setPrototypeOf(this,new.target.prototype),this.name="ReconnectRequiredError",this.connectUrl=n.connectUrl,this.plugin=n.plugin,this.tenantId=n.tenantId,this.reason=n.reason}};function _(e){return typeof e=="string"&&e.length>0}function Ka(e){return e==="ready"||e==="partial"||e==="not_started"||e==="missing_integration"}function Za(e){return e==="oauth_2"||e==="api_key"||e==="bot_token"||e==="managed"}function Yn(e){if(!e||typeof e!="object")throw new Error("Hub API returned an empty connect session");let n=e;if(!_(n.connectUrl)||!_(n.token)||!_(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:_(n.environmentId)?n.environmentId:n.projectId};return _(n.expiresAt)&&(t.expiresAt=n.expiresAt),t}function Qn(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(!_(r.tenantId)||!_(r.plugin)||!Ka(r.status)||!Za(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:_(r.reportedAt)?r.reportedAt:new Date().toISOString()})}return n}function Xn(e){if(!e||typeof e!="object")throw new Error("Hub API returned an empty permission session");let n=e;if(!_(n.approvalUrl)||!_(n.token)||!_(n.projectId)||!_(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 nn(e){if(!e||typeof e!="object")throw new Error("Hub token refresh returned an empty response");let n=e;if(_(n.access_token))return{access_token:n.access_token,refresh_token:_(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:_(n.scope)?n.scope:void 0};throw new Error(_(n.error)?_(n.error_description)?n.error_description:n.error:"Hub token refresh returned no access_token")}function Ga(e){return Array.isArray(e)?e.filter(n=>typeof n=="string"):[]}function za(e){if(!Array.isArray(e))return[];let n=[];for(let t of e){if(!t||typeof t!="object")continue;let r=t;_(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 Ja(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 ei(e){if(!e||typeof e!="object")throw new Error("Connect status response was empty");let n=e;if(!_(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(!_(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=za(o.fields),a=Ga(o.missingRequiredFields),c=Ja(o.status,o.connected,s,a);t.push({plugin:o.plugin,providerName:_(o.providerName)?o.providerName:o.plugin,authKind:i,status:c,connected:o.connected,fields:s,missingRequiredFields:a})}return{tenantId:n.tenantId,plugins:t}}function et(e){if(!e||typeof e!="object")return null;let n=e;return n.error??n.message??null}function ni(e){if(!e||typeof e!="object")return null;let n=e;if(n.errorType!=="reconnect_required")return null;let t=r=>typeof r=="string"&&r.length>0?r:null;return{message:t(n.error),connectUrl:t(n.connectUrl),plugin:t(n.plugin),tenantId:t(n.tenantId),reason:t(n.reason)}}function ti(e){return e.replace(/\/$/,"")}function ar(e){if(!e.projectApiKey.startsWith("ck_dev_"))return null;try{return xe()}catch{return null}}function ri(e){let n=ar(e);return n?{"x-corsair-delivery-url":n}:{}}async function oi(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 Va(e,n,t){if(n===404&&t)return t;let r=et(e);return r||`Hub API returned HTTP ${n}`}function ii(e,n,t){let r=ni(e);throw r?new ye({message:r.message??void 0,connectUrl:r.connectUrl,plugin:r.plugin,tenantId:r.tenantId,reason:r.reason??void 0}):new Error(Va(e,n,t))}async function I(e){let n=ti(e.hub.apiUrl),t=await fetch(`${n}${e.path}`,{method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${e.hub.projectApiKey}`,...ri(e.hub)},body:JSON.stringify(e.body)}),r=await oi(t);return t.ok||ii(r,t.status,e.notFoundMessage),e.parseResponse(r)}async function q(e){let n=ti(e.hub.apiUrl),t=await fetch(`${n}${e.path}`,{method:"GET",headers:{authorization:`Bearer ${e.hub.projectApiKey}`,...ri(e.hub)}}),r=await oi(t);return t.ok||ii(r,t.status,e.notFoundMessage),e.parseResponse(r)}function nt(e){return e&&typeof e=="object"?e:{}}function si(e){let n=nt(e);return{chatId:n.threadId,message:n.message,workflowId:n.workflowId??null,action:n.action}}async function cr(e,n){return I({hub:e,path:"/threads",body:{tenantId:n.tenantId,message:n.message},parseResponse:t=>{let r=nt(t);return{chat:r.thread,reply:si(r.reply)}}})}async function ur(e,n){return I({hub:e,path:`/threads/${encodeURIComponent(n.chatId)}/messages`,body:{tenantId:n.tenantId,message:n.message},notFoundMessage:`Chat "${n.chatId}" not found`,parseResponse:si})}async function lr(e,n){return q({hub:e,path:`/threads?tenantId=${encodeURIComponent(n.tenantId)}`,parseResponse:t=>{let r=nt(t).threads;return Array.isArray(r)?r:[]}})}async function dr(e,n){return q({hub:e,path:`/threads/${encodeURIComponent(n.chatId)}/messages?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Chat "${n.chatId}" not found`,parseResponse:t=>{let r=nt(t).messages;return Array.isArray(r)?r:[]}})}import{randomUUID as rc}from"crypto";var Ya="corsair:client-bridge";function pr(e){return new URL(e).origin}function tn(e){let n=JSON.stringify({type:Ya,requestId:e.requestId,ok:e.ok,body:e.body??null,error:e.error??null}),t=JSON.stringify(pr(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 Qa=new Set(["localhost","127.0.0.1","[::1]","::1"]);function gr(e){try{let{hostname:n,protocol:t}=new URL(e);return t!=="http:"&&t!=="https:"?!1:Qa.has(n)}catch{return!1}}function In(e){return e==="development"?"browser":"server"}function ai(e){return In(e)==="browser"}function ci(e){return gr(e)?"Production delivery URL must be a public URL, not localhost":null}import{randomBytes as tc}from"crypto";var _e=60*1e3,We=300*1e3;import{createHmac as Xa,randomBytes as ec,timingSafeEqual as nc}from"crypto";function me(){return ec(16).toString("base64url")}function Sn(e,n){let t=n.trim();if(!t)throw new Error("Signing secret is required");return Xa("sha256",t).update(e).digest("base64url")}function le(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=Sn(o,t);try{if(!nc(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 tt(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=Sn(i,n);return`${i}.${s}`}function _n(e,n,t){let r=Math.floor(Date.now()/1e3);return tt(e,n,r+Math.floor(t/1e3))}function je(e){return decodeURIComponent(e)}function fr(e){return encodeURIComponent(e).replace(/\./g,"%2E")}function ui(e){let n=e.trim();return n.length>0?n:null}function rn(e,n){let t=new URL(e);return t.searchParams.set("d",n),t.toString()}function on(e,n){if(!ui(n))throw new Error("Signing secret is required for browser delivery tokens");let t=Math.floor(Date.now()/1e3),r={...e,jti:e.jti??tc(16).toString("base64url"),iat:t,exp:t+Math.floor(_e/1e3)},o=Buffer.from(JSON.stringify(r)).toString("base64url"),i=Sn(o,n);return`${o}.${i}`}function Ee(e,n){return ui(n)?le(e,n):null}function oc(e){let n=pr(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 yr(e){let n=on(oc(e),e.signingSecret);return rn(e.deliveryUrl,n)}function li(e){if(In(e.environmentSlug)==="server")return{transport:"server"};if(!e.hubOrigin)throw new Error(`hubOrigin is required for development ${e.deliveryMode} delivery`);let t=rc(),r={...e,hubOrigin:e.hubOrigin,requestId:t};return{transport:"browser",requestId:t,deliveryUrl:yr(r)}}var En="https://auth.corsair.dev";var he=class extends Error{constructor(){super("Hub is not configured. Pass hub: { projectApiKey, signingSecret } to createCorsair()."),this.name="HubNotConfiguredError"}},Dn=class extends Error{constructor(){super("Hub credentials are missing. Pass hub: { projectApiKey, signingSecret } to createCorsair() with non-empty values, or omit `hub` entirely if you are not using Corsair Hub."),this.name="HubCredentialsMissingError"}};function mr(e){let n=(e.apiUrl?.trim()||En).replace(/\/$/,""),t=e.projectApiKey?.trim()??"",r=e.signingSecret?.trim()??"",o=t.startsWith("ck_cloud_");if(!t||!r&&!o)throw new Dn;return{apiUrl:n,projectApiKey:t,signingSecret:r,oauthCallbackUrl:e.oauthCallbackUrl?.trim().replace(/\/$/,""),redirectURL:e.redirectURL?.trim()||void 0,allowWorkflowExecution:e.allowWorkflowExecution??!1,tunnel:e.tunnel}}function rt(e){return mr(e)}function ic(e){let n=e.projectApiKey.startsWith("ck_cloud_");return e.apiUrl.trim().length>0&&e.projectApiKey.trim().length>0&&(n||e.signingSecret.trim().length>0)}function U(e){let n=T(e).hub;if(!n||!ic(n))throw new he;return n}function di(e){return e.replace(/\/$/,"")}function ot(e){return e.oauthCallbackUrl?di(e.oauthCallbackUrl.trim()):`${di(e.apiUrl)}/oauth/callback`}function sn(e){if(e.startsWith("ck_dev_"))return"development";if(e.startsWith("ck_prod_"))return"production";if(e.startsWith("ck_cloud_"))return"cloud";throw new Error("Hub API key must start with ck_dev_ (development), ck_prod_ (production), or ck_cloud_ (cloud)")}import{createCipheriv as pi,createDecipheriv as gi,randomBytes as it,scrypt as sc}from"crypto";import{promisify as ac}from"util";var fi=ac(sc),st="aes-256-gcm",yi=12,at=16,cc=16,qe=32;function be(){return it(qe).toString("base64")}async function ke(e,n){let t=it(cc),r=await fi(n,t,qe),o=it(yi),i=pi(st,r,o,{authTagLength:at}),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 ne(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"),c=Buffer.from(o,"base64"),l=Buffer.from(i,"base64"),u=await fi(n,s,qe),d=gi(st,u,a,{authTagLength:at});return d.setAuthTag(c),Buffer.concat([d.update(l),d.final()]).toString("utf8")}function hr(e,n){let t=Buffer.from(n,"base64"),r=it(yi),o=pi(st,t,r,{authTagLength:at}),i=Buffer.concat([o.update(e,"utf8"),o.final()]),s=o.getAuthTag();return[r.toString("base64"),s.toString("base64"),i.toString("base64")].join(":")}function On(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"),c=Buffer.from(o,"base64"),l=gi(st,i,s,{authTagLength:at});return l.setAuthTag(a),Buffer.concat([l.update(c),l.final()]).toString("utf8")}function De(e,n){let t={};for(let[r,o]of Object.entries(e))t[r]=hr(o,n);return t}function de(e,n){let t={};for(let[r,o]of Object.entries(e))t[r]=On(o,n);return t}function Mn(e,n,t){let r=de(e,n);return De(r,t)}function mi(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 br=e=>{if(!e)return{};if(typeof e=="string")try{return JSON.parse(e)}catch{return{}}return e};function F(e){let{authType:n,integrationName:t,kek:r,database:o,extraIntegrationFields:i=[]}=e,s=[...j[n].integration,...i],a=null,c={kek:r,integrationName:t,getIntegration:async()=>{if(a)return a;let b=await o.db.selectFrom("corsair_integrations").selectAll().where("name","=",t).executeTakeFirst();if(!b)throw new Error(`Integration "${t}" not found. Make sure to create the integration first.`);return a={id:b.id,config:br(b.config),dek:b.dek??null},a},updateIntegration:async b=>{let k=await c.getIntegration();await o.db.updateTable("corsair_integrations").set({...b.config!==void 0?{config:b.config}:{},...b.dek!==void 0?{dek:b.dek}:{},updated_at:new Date}).where("id","=",k.id).execute(),a=null}},l=null,u=async()=>{if(l)return l;let b=await c.getIntegration();if(!b.dek)throw new Error(`No DEK found for integration "${t}". Initialize the integration first.`);return l=await ne(b.dek,r),l},d=async()=>{let b=await c.getIntegration(),k=await u(),v=b.config;return!v||Object.keys(v).length===0?{}:de(v,k)},p=Promise.resolve(),g=b=>{let k=p.then(()=>f(b));return p=k.catch(()=>{}),k},f=async b=>{let k=await u(),v;try{v=await d()}catch(D){console.error(`[corsair] Failed to decrypt config for integration "${t}", starting fresh:`,D),v={}}let P={...v};for(let[D,M]of Object.entries(b))M===null?delete P[D]:P[D]=M;let O=De(P,k);await c.updateIntegration({config:O})};return{get_dek:u,issue_new_dek:async()=>{let b=await c.getIntegration(),k=be(),v={};if(b.dek){let O=await ne(b.dek,r),D=b.config;D&&Object.keys(D).length>0&&(v=Mn(D,O,k))}let P=await ke(k,r);return await c.updateIntegration({config:v,dek:P}),l=k,k},...mi(d,g,s)}}function B(e){let{authType:n,integrationName:t,tenantId:r,kek:o,database:i,extraAccountFields:s=[],ensureProvisioned:a}=e,c=[...j[n].account,...s],l=null,u=async()=>{if(l)return l;let w=!1;for(;;){let R=await i.db.selectFrom("corsair_integrations").selectAll().where("name","=",t).executeTakeFirst();if(!R){if(!w&&a){w=!0,await a();continue}throw new Error(`Integration "${t}" not found. Make sure to create the integration first.`)}return l={id:R.id,config:br(R.config),dek:R.dek??null},l}},d={kek:o,integrationName:t,tenantId:r,getIntegration:u,getAccount:async()=>{let w=!1;for(;;){let R=await u(),A=await i.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",r).where("integration_id","=",R.id).executeTakeFirst();if(!A){if(!w&&a){w=!0,await a();continue}throw new Error(`Account not found for tenant "${r}" and integration "${t}". Make sure to create the account first.`)}return{id:A.id,config:br(A.config),dek:A.dek??null}}},updateAccount:async w=>{let R=await d.getAccount();await i.db.updateTable("corsair_accounts").set({...w.config!==void 0?{config:w.config}:{},...w.dek!==void 0?{dek:w.dek}:{},updated_at:new Date}).where("id","=",R.id).execute()}},p=null,g=null,f=null,h=async()=>{let w=await d.getAccount();if(!w.dek)throw new Error(`No DEK found for account (tenant: "${r}", integration: "${t}"). Initialize the account first.`);return p&&g===w.dek||(p=await ne(w.dek,o),g=w.dek),p},b=async()=>{if(f)return f;let w=await d.getIntegration();if(!w.dek)throw new Error(`No DEK found for integration "${t}". Initialize the integration first.`);return f=await ne(w.dek,o),f},k=async()=>{let w=await d.getAccount(),R=await h(),A=w.config;return!A||Object.keys(A).length===0?{}:de(A,R)},v=async()=>{let w=await d.getIntegration(),R=await b(),A=w.config;return!A||Object.keys(A).length===0?{}:de(A,R)},P=Promise.resolve(),O=w=>{let R=P.then(()=>D(w));return P=R.catch(()=>{}),R},D=async w=>{let R=await d.getAccount();if(!R.dek)throw new Error(`No DEK found for account (tenant: "${r}", integration: "${t}"). Initialize the account first.`);let A=await ne(R.dek,o),X;try{let L=R.config;X=!L||Object.keys(L).length===0?{}:de(L,A)}catch(L){console.error(`[corsair] Failed to decrypt config for account (tenant: "${r}", integration: "${t}"), starting fresh:`,L),X={}}let te={...X};for(let[L,Re]of Object.entries(w))Re===null?delete te[L]:te[L]=Re;let H=De(te,A);await d.updateAccount({config:H})},M={get_dek:h,issue_new_dek:async()=>{let w=await d.getAccount(),R=be(),A={};if(w.dek){let te=await ne(w.dek,o),H=w.config;H&&Object.keys(H).length>0&&(A=Mn(H,te,R))}let X=await ke(R,o);return await d.updateAccount({config:A,dek:X}),p=R,g=X,R},...mi(k,O,c)};return n==="oauth_2"&&(M.get_integration_credentials=async()=>{let w=await v();return{...w,client_id:w.client_id||null,client_secret:w.client_secret||null,redirect_url:w.redirect_url??null}}),M}async function hi(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=be(),i=await ke(o,t);return await e.db.updateTable("corsair_integrations").set({dek:i,updated_at:new Date}).where("id","=",r.id).execute(),o}async function bi(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=be(),a=await ke(s,r);return await e.db.updateTable("corsair_accounts").set({dek:a,updated_at:new Date}).where("id","=",i.id).execute(),s}var uc=new Set(["webhook_signature","expires_at","scope","redirect_url","refresh_token"]);function Oe(e){return uc.has(e)}function lc(e,n){return Oe(n)?!1:e==="oauth_2"?n==="client_id"||n==="client_secret":!0}function dc(e){return!Oe(e)}function pc(e){switch(e){case"oauth_2":case"managed":return["access_token"];case"api_key":return["api_key"];case"bot_token":return["bot_token"]}}function gc(e,n){return e!=="oauth_2"&&e!=="managed"?!1:n.some(t=>t.level==="account"&&t.name==="expires_at"&&t.configured)}function fc(e,n){let t=i=>n.find(s=>s.level==="account"&&s.name===i);if(!pc(e).every(i=>t(i)?.configured))return!1;let o=t("refresh_token");return o?.required?!!o.configured:!0}async function ki(e,n){if(!e)return!1;let t=ee(e,`get_${n}`);if(!t)return!1;try{let r=await t();return typeof r=="string"&&r.length>0}catch{return!1}}function yc(e,n){let r=e.authConfig?.[n]?.integration??[];return[...j[n].integration,...r]}function mc(e,n){let r=e.authConfig?.[n]?.account??[];return[...j[n].account,...r]}function hc(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:fc(n,t),fields:t,missingRequiredFields:r}}async function Ke(e,n,t){let r=S(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??[],c=F({authType:r,integrationName:n.id,kek:e.kek,database:e.database,extraIntegrationFields:s}),l=B({authType:r,integrationName:n.id,tenantId:o,kek:e.kek,database:e.database,extraAccountFields:a}),u=yc(n,r),d=mc(n,r),p=[];for(let g of u)p.push({name:g,level:"integration",required:lc(r,g),configured:await ki(c,g)});for(let g of d)p.push({name:g,level:"account",required:dc(g),configured:await ki(l,g)});if(gc(r,p)){let g=p.find(f=>f.level==="account"&&f.name==="refresh_token");g&&(g.required=!0)}return hc(n.id,r,p)}async function Hn(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 Ke(e,s,r);a&&i.push(a)}return i}function ct(e){return e.connected?"connected":e.status==="missing_integration"?"missing_credentials":"not_connected"}var wi=Symbol.for("corsair:internal"),Ci=new WeakMap,vi=new WeakMap;function bc(e,n){let t=n.map(r=>r.id).sort().join("\0");return`${e}\0${t}`}function kc(e){if(e.database){let t=Ci.get(e.database);return t||(t=new Map,Ci.set(e.database,t)),t}let n=vi.get(e);return n||(n=new Map,vi.set(e,n)),n}function wc(e){return e.multiTenancy?{withTenant:()=>({}),[wi]:e}:{[wi]:e}}async function an(e,n){if(!e.database)return;let t=n.trim()||"default",r=kc(e),o=bc(t,e.plugins),i=r.get(o);if(i){await i;return}let s=(async()=>{let{setupCorsair:a}=await import("./setup-I6RGZM2Y.js");await a(wc(e),{tenantId:e.multiTenancy?t:void 0,silent:!0})})().finally(()=>{r.delete(o)});r.set(o,s),await s}import*as Bn from"crypto";function Me(e,n){return Buffer.from(JSON.stringify({plugin:e,tenantId:n,iat:Date.now()})).toString("base64url")}function kr(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 cn(e,n){if(!n)throw new Error("OAuth state signing requires a configured kek. Pass kek to createCorsair().");let t=Bn.createHmac("sha256",n).update(e).digest("base64url");return`${e}.${t}`}var wr=600*1e3;function ut(e,n){if(!n)return null;let t=e.lastIndexOf(".");if(t===-1)return null;let r=e.slice(0,t),o=e.slice(t+1),i=Bn.createHmac("sha256",n).update(r).digest("base64url"),s=Buffer.from(o,"base64url"),a=Buffer.from(i,"base64url");return s.length!==a.length||!Bn.timingSafeEqual(s,a)?null:kr(r,{maxAgeMs:wr})}function Ti(e){return{tenantId:e.tenantId,plugin:e.plugin,authType:e.authType??"oauth_2",status:"ready",connected:!0,verified:!0,webhookLink:e.link}}function Pi(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 un(e,n){await I({hub:e,path:"/connections/report",body:Ti(n),parseResponse:()=>({ok:!0})}).catch(()=>{})}function Cc(e,n){try{let t=U(e);I({hub:t,path:"/connections/report",body:n,parseResponse:()=>({ok:!0})}).catch(()=>{})}catch(t){if(t instanceof he)return}}async function vc(e){if(!e.hub||!e.database||!e.kek)return;let n={database:e.database,kek:e.kek,plugins:e.plugins};if(!S(e.plugin))return;let r=e.tenantId?.trim()||"default",o=await Ke(n,e.plugin,r);o&&Ai(e.hub,Pi({tenantId:r,plugin:e.plugin.id,authType:o.authType,status:o.status,connected:o.connected,verified:e.verified??o.connected,missingFields:o.missingRequiredFields}))}function Ri(e,n){Cc(e,n)}function Ai(e,n){I({hub:e,path:"/connections/report",body:n,parseResponse:()=>({ok:!0})}).catch(()=>{})}function ln(e){vc(e).catch(()=>{})}async function we(e,n){let t=T(e);if(!S(n.plugin))return;let o=await Ke(t,n.plugin,n.tenantId);o&&Ri(e,Pi({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 lt(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 xi=e=>{if(!e)return{};if(typeof e=="string")try{return JSON.parse(e)}catch{return{}}return e};async function Tc(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 Pc(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 ne(n.dek,e.kek),r=xi(n.config),o={};Object.keys(r).length>0&&(o=de(r,t)),o[e.link.linkType]=e.link.externalId;let i=De(o,t);await e.database.db.updateTable("corsair_accounts").set({config:i,updated_at:new Date}).where("id","=",n.id).execute()}async function dn(e){let{database:n,kek:t,pluginId:r,tenantId:o,link:i,authType:s,extraAccountFields:a=[]}=e,{accountId:c}=await Tc({database:n,pluginId:r,tenantId:o}),l=!1;if(s){let u=B({authType:s,integrationName:r,tenantId:o,kek:t,database:n,extraAccountFields:a}),d=`set_${i.linkType}`,p=u[d];typeof p=="function"&&(await p(i.externalId),l=!0)}l||await Pc({database:n,kek:t,accountId:c,link:i})}async function Cr(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 c=await ne(a.dek,t),u=xi(a.config)[o];if(!u)continue;if(On(u,c)===i)return a}catch{continue}return null}async function dt(e){return(await Cr(e))?.tenant_id??null}async function Ii(e){return dt({database:e.database,kek:e.kek,pluginId:e.pluginId,linkType:e.match.linkType,externalId:e.match.externalId})}import*as Si from"querystring";function Ze(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}?${Si.stringify(i)}`}async function _i(e,n){try{return await q({hub:e,path:`/webhooks/endpoint?plugin=${encodeURIComponent(n)}`,parseResponse:t=>t?.url??null})}catch{return null}}async function pn(e,n,t,r){if(!n.subscribe)return;let o=U(e),i=await _i(o,n.id);if(!i)return;let s=await n.subscribe({keys:r},{webhookUrl:i});s&&await we(e,{plugin:n,tenantId:t,verified:!0,webhookLink:s.webhookLink,webhookSecret:s.webhookSecret})}var Z=class extends Error{code;constructor(n,t){super(t),this.name="OAuthCallbackError",this.code=n}};function Ei(e){let n=e.oauthConfig;if(!n)throw new Z("plugin_has_no_oauth_config",`Plugin '${e.id}' has no oauthConfig`);return n}async function Rc(e,n,t,r){await e.db.transaction().execute(async o=>{let i=o.selectFrom("corsair_integrations").select(["id"]).where("name","=",n);e.isPg===!0&&(i=i.forUpdate());let s=await i.executeTakeFirst();if(!s)throw new Error(`Integration '${n}' not found. Run setupCorsair first.`);if(await o.selectFrom("corsair_accounts").select("id").where("tenant_id","=",t).where("integration_id","=",s.id).executeTakeFirst())return;let c=be(),l=await ke(c,r),u=new Date;await o.insertInto("corsair_accounts").values({id:en(),created_at:u,updated_at:u,tenant_id:t,integration_id:s.id,config:{},dek:l}).execute()})}async function vr(e,n,t){let{tenantId:r,redirectUri:o,hubConnect:i=!1}=t,s=T(e,()=>new Z("invalid_corsair_instance","Invalid corsair instance"));if(!s.database)throw new Error("No database configured on corsair instance");let a=K(s,n,p=>new Z("plugin_not_found",p)),c=Ei(a),u=await F({authType:"oauth_2",integrationName:n,kek:s.kek,database:s.database}).get_client_id();if(!u)throw new Error(`client_id not configured for '${n}'`);if(i){let p=new URL(Ze({oauthConfig:c,clientId:u,redirectUri:o,state:""}));return p.searchParams.delete("state"),{url:p.toString(),state:""}}let d=cn(Me(n,r),s.kek);return{url:Ze({oauthConfig:c,clientId:u,redirectUri:o,state:d}),state:d}}function Ac(e,n){return{...n??{},...e}}async function Un(e,n){let{code:t,state:r,redirectUri:o}=n,i=T(e,()=>new Z("invalid_corsair_instance","Invalid corsair instance")),s,a;if(n.trusted){if(!n.plugin||!n.tenantId)throw new Z("invalid_state","trusted callback requires plugin and tenantId");s=n.plugin,a=n.tenantId}else{let h=ut(r,i.kek);if(!h)throw new Z("invalid_state","Invalid or tampered state parameter");s=h.plugin,a=h.tenantId}if(!i.database)throw new Z("no_database","No database configured on corsair instance");let c=K(i,s,h=>new Z("plugin_not_found",h)),l=Ei(c),u=F({authType:"oauth_2",integrationName:s,kek:i.kek,database:i.database}),d=await u.get_client_id(),p=await u.get_client_secret();if(!d||!p)throw new Z("credentials_not_configured",`Credentials not configured for '${s}'`);await Rc(i.database,s,a,i.kek);let g=await pt(t,d,p,l,o);if(!g.access_token)throw new Z("no_access_token",`No access_token returned from ${l.providerName}`);let f=B({authType:"oauth_2",integrationName:s,tenantId:a,kek:i.kek,database:i.database,extraAccountFields:[...c.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 we(e,{plugin:c,tenantId:a}).catch(()=>{});try{let h=Ac(g,n.callbackParams),b=await lt(i.plugins,s,h);if(b){try{let k=c.authConfig?.oauth_2?.account??[];await dn({database:i.database,kek:i.kek,pluginId:s,tenantId:a,link:b,authType:"oauth_2",extraAccountFields:k})}catch(k){console.warn(`[corsair:oauth] Failed to persist webhook tenant link for '${s}' tenant '${a}':`,k)}i.hub&&un(i.hub,{plugin:s,tenantId:a,link:b,authType:"oauth_2"})}}catch(h){console.warn(`[corsair:oauth] Failed to resolve webhook tenant link for '${s}' tenant '${a}':`,h)}if(c.subscribe)try{await pn(e,c,a,f)}catch(h){console.warn(`[corsair:oauth] BYO subscribe failed for '${s}' tenant '${a}':`,h)}return{plugin:s,tenantId:a}}async function xc(e){let{corsair:n,internal:t,rows:r}=e,o=e.subscribeAndReport??pn,i=[],s=[];if(!t.database)return{renewed:i,failed:s};for(let a of r){let c=t.plugins.find(u=>u.id===a.integrationName);if(!c?.subscribe)continue;let l=`${c.id}/${a.tenantId}`;try{let u=S(c)??"oauth_2",d=B({authType:u,integrationName:c.id,tenantId:a.tenantId,kek:t.kek,database:t.database,extraAccountFields:[...c.authConfig?.[u]?.account??[]]}),p=c.keyBuilder;if(p){let g=Object.create(d,{get_expires_at:{value:async()=>"0"}});await p({authType:u,keys:g,hub:t.hub},"endpoint")}await o(n,c,a.tenantId,d),i.push(l)}catch(u){console.warn(`[corsair:renewal] re-subscribe failed for '${l}':`,u),s.push(l)}}return{renewed:i,failed:s}}async function Di(e){let n=T(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 xc({corsair:e,internal:n,rows:t.filter(r=>!!r.tenantId)})}function Ic(e,n={}){let t=!1,r=()=>{t||(t=!0,Di(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 Oi(e){if(!T(e).database)throw new Error("A database must be configured to provision Corsair integrations");await gt(e,{silent:!0})}async function gn(e,n){let t=T(e);if(!t.database)throw new Error("A database must be configured to provision Corsair for connect");await an(t,n)}var Sc=Symbol.for("corsair:internal"),_c=new Set(["access_token","refresh_token","expires_at","scope"]);function Ec(e){return e==="oauth_2"||e==="managed"?"oauth":e==="bot_token"?"bot_token":"api_key"}function Dc(e,n){return e==="oauth_2"||e==="managed"?n.filter(t=>!Oe(t)&&!_c.has(t)):n.filter(t=>!Oe(t))}function Mi(e){return{plugins:e.plugins,database:e.database,kek:e.kek,multiTenancy:e.multiTenancy??!1}}function Oc(e){return{plugins:e.plugins,database:e.database,kek:e.kek,multiTenancy:e.multiTenancy??!1}}function Mc(e){return{[Sc]:Mi(e)}}async function ft(e,n,t={}){let r=ot(e.hub),o=[],i=t.pluginIds?new Set(t.pluginIds):null,s=Mi(e),a=Mc(e);for(let c of e.plugins){if(i&&!i.has(c.id))continue;let l=S(c);if(!l)continue;let u=Ec(l),d=t.providerNameOverrides?.[c.id]??Se(c.id),p=await Ke(s,c,n),g=Jn(c,l),f=Dc(l,g),h={plugin:c.id,providerName:d,authKind:u,alreadyConfigured:p?.connected??!1};if(f.length>0&&(h.credentialFields=f),u==="oauth"){let k=t.oauthModeOverrides?.[c.id]??(l==="managed"?"managed":"byo");if(h.oauthMode=k,!t.skipOAuthUrlGeneration&&k!=="managed")try{let v=await vr(a,c.id,{tenantId:n,redirectUri:r,hubConnect:!0});h.oauthUrl=v.url}catch(v){v instanceof Error&&/client_id not configured/i.test(v.message)||(h.setupError=v instanceof Error?v.message:`Could not prepare OAuth for ${c.id}`)}}o.push(h)}return o}async function Qg(e,n,t={}){let r=T(e),o=r.hub;if(!o)throw new Error("Hub is not configured");return ft({plugins:r.plugins,database:r.database,kek:r.kek,hub:o},n,t)}async function Hi(e,n){if(!e.database)throw new Error("A database must be configured to provision Corsair for connect");await an(e.internalConfig??Oc(e),n)}async function Bi(e,n){await gn(e,n)}async function Ui(e,n){let t=sn(e.projectApiKey),r={tenantId:n.tenantId,plugins:n.plugins};return e.redirectURL&&(r.redirectUri=e.redirectURL),t==="development"&&(r.deliveryUrl=xe({deliveryUrl:n.deliveryUrl})),I({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:Yn})}async function Fi(e,n){let t={plugins:n.plugins,database:n.database,kek:n.kek,hub:e,multiTenancy:n.multiTenancy};await Hi(t,n.tenantId);let r=await ft(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 Ui(e,{tenantId:n.tenantId,plugins:r,deliveryUrl:n.deliveryUrl})}async function yt(e,n){let t=T(e),r=U(e),o={plugins:t.plugins,database:t.database,kek:t.kek,hub:r,multiTenancy:t.multiTenancy,internalConfig:t};await Bi(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,c=await ft(o,n.tenantId,{pluginIds:i,oauthModeOverrides:s,providerNameOverrides:a});if(c.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 Ui(r,{tenantId:n.tenantId,plugins:c,deliveryUrl:n.deliveryUrl})}async function mt(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=T(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 Hc(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 Hc(e,n,t){let{buildConnectPluginManifestFromContext:r,ensureConnectAccountRowsFromContext:o}=await import("./setup-introspect-AMVPY6DX.js"),{postHubConnectSession:i}=await import("./connect-HIYSCOPY.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 c=a.find(l=>l.setupError);if(c)throw new Error(c.setupError??`Could not prepare connect link for ${c.plugin}`);return i(e,{tenantId:t.tenantId,plugins:a})}function fn(e){return!!(e?.baseUrl?.trim()&&e?.redirectUri?.trim())}var oe=class extends Error{code;constructor(n,t){super(t),this.name="ConnectError",this.code=n}};function Bc(e){let n=e.oauthConfig;if(!n)throw new oe("plugin_has_no_oauth_config",`Plugin '${e.id}' has no oauthConfig`);return n}async function Tr(e,n){let t=T(e,()=>new oe("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new oe("no_database","No database configured on corsair instance");let r=t.manual?.redirectUri;if(!r)throw new oe("no_redirect_uri","No redirectUri configured. Set manual.redirectUri in createCorsair().");let o=ut(n,t.kek);if(!o)throw new oe("invalid_state","Invalid or tampered state parameter");let{plugin:i,tenantId:s}=o,a=K(t,i,p=>new oe("plugin_not_found",p)),c=Bc(a),u=await F({authType:"oauth_2",integrationName:i,kek:t.kek,database:t.database}).get_client_id();if(!u)throw new oe("client_id_not_configured",`client_id not configured for '${i}'`);let d=Ze({oauthConfig:c,clientId:u,redirectUri:r,state:n});return{plugin:i,tenantId:s,providerName:c.providerName,oauthUrl:d,state:n}}import{AsyncLocalStorage as Fc}from"async_hooks";import{randomBytes as Lc}from"crypto";import{v4 as Nc}from"uuid";async function ht(e,n){let t=sn(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=xe({deliveryUrl:n.deliveryUrl})),I({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:Xn})}function bt(e){return`Approval required. Visit ${e} to approve or deny, then tell the agent to retry this action.`}var Pr="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 Ar(e){return e?e.approvalBaseUrl!==void 0||e.onApprovalRequired!==void 0:!1}function Li(e,n){return`${e.replace(/\/+$/,"")}/${n}`}function Rr(e){return bt(e)}async function xr(e,n){if(Ar(e.manual)){let r=e.manual?.approvalBaseUrl?.trim();return r?Li(r,n.token):null}let t=e.hub;if(!t)return null;try{return(await ht(t,{permissionId:n.id,permissionToken:n.token,plugin:n.plugin,endpoint:n.endpoint,args:Uc(n.args),tenantId:n.tenant_id,expiresAt:n.expires_at})).approvalUrl}catch{return null}}function Uc(e){try{return JSON.parse(e)}catch{return e}}async function kt(e,n){if(!(n.status==="pending"||n.status==="approved"))return{...n,approvalUrl:null};let r=await xr(e,n);return{...n,approvalUrl:r}}async function Ir(e){let{permissionsOptions:n,manual:t,hub:r,permissionId:o,permissionToken:i,plugin:s,endpoint:a,args:c,tenantId:l,expiresAt:u,operationPath:d}=e;if(n?.formatAsyncMessage)return n.formatAsyncMessage({token:i,id:o,plugin:s,endpoint:a,args:c});let g=await xr({manual:t,hub:r},{id:o,token:i,plugin:s,endpoint:a,args:JSON.stringify(c),tenant_id:l,expires_at:u});return Ar(t)?g?t?.onApprovalRequired?t.onApprovalRequired({approvalUrl:g}):Rr(g):Pr:r?g?Rr(g):`Action '${d}' requires user approval before it can run. Could not create approval link. Check hub configuration and server logs.`:Pr}var He=class extends Error{reason;constructor(n,t="pending"){super(n),Object.setPrototypeOf(this,new.target.prototype),this.name="PermissionRequiredError",this.reason=t}};var $i=new Fc,yn=class extends Error{endpointPath;riskLevel;constructor(n,t){super(`Action '${n}' is a '${t}' operation and is forbidden in readonly mode. Only read operations are permitted \u2014 rewrite the script to avoid write/destructive actions.`),this.name="ReadonlyForbiddenError",this.endpointPath=n,this.riskLevel=t}};function Sr(e){return $i.run(!0,e)}function Wi(){return $i.getStore()===!0}function _r(e,n){if(Wi()&&n!=="read")throw new yn(e,n)}var $c={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 Wc(e,n,t){return t!==void 0?t:$c[n][e]}function Er(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 ji(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 Ni(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 qi(e){let n=Wc(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,h=a.id;return{result:"allow",onComplete:async()=>{await f.db.updateTable("corsair_permissions").set({status:"completed",updated_at:new Date}).where("id","=",h).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"?Ni(e.db,a.id,e.timeoutMs??600*1e3):{result:"blocked",reason:"pending",id:a.id,token:a.token,expiresAt:a.expires_at})}let c=Nc(),l=Lc(32).toString("hex"),u=e.timeoutMs??600*1e3,d=new Date(Date.now()+u).toISOString();return await e.db.db.insertInto("corsair_permissions").values({id:c,created_at:new Date,updated_at:new Date,token:l,plugin:e.pluginId,endpoint:e.endpointPath,args:o,tenant_id:s,status:"pending",expires_at:d}).execute(),console.log(`[corsair/${e.pluginId}] '${e.endpointPath}' blocked \u2014 approval required.`,`
15
+ Action: ${r}`,`
16
+ Permission ID: ${c}`,`
17
+ Permission token: ${l}`,`
18
+ Expires at: ${d}`,`
19
+ Use the token to approve or deny this request.`),(typeof e.approvalMode=="function"?e.approvalMode():e.approvalMode)==="synchronous"?Ni(e.db,c,u):{result:"blocked",reason:"pending",id:c,token:l,expiresAt:d}}var C=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 x(e,n,t){return new Response(JSON.stringify(n),{status:e,headers:{"content-type":"application/json",...t}})}function pe(e){let n={error:e.code,message:e.message,...e.extra};return x(e.status,n)}function Be(e){return new C(404,"not_found",e)}function G(e,n={}){return new C(400,"bad_request",e,n)}function Dr(e,n){return K(e,n,t=>Be(t))}async function Ki(e,n){let t=e.options?.authType;if(!t||!n.database||!n.kek)return{configured:!1,missingFields:[]};let r=F({authType:t,integrationName:e.id,kek:n.kek,database:n.database}),o=j[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,u)=>s[u]==null),c;return t==="oauth_2"?c=!a.includes("client_id")&&!a.includes("client_secret"):c=a.length===0,{configured:c,missingFields:a}}async function Zi(e,n){let t=e.options?.authType??null,r=e.oauthConfig,{configured:o,missingFields:i}=await Ki(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 wt(){return{ok:!0}}async function mn(e){return Promise.all(e.plugins.map(n=>Zi(n,e)))}async function Ct(e,n){let t=Dr(e,n);return Zi(t,e)}async function jc(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 Gi(e,n){let t=await jc(e,n),r=t.filter(o=>o.hasCredentials).map(o=>o.integrationName);return{id:n,accounts:t,connectedPlugins:r}}async function hn(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 vt(e,n){if(!n)throw G("Tenant id must be a non-empty string");return Gi(e,n)}async function Tt(e,n){let t=n?.id?.trim();if(!t)throw G("Tenant id is required",{missingFields:["id"]});return Gi(e,t)}async function Pt(e,n){let t=n?.trim()||"default",r={},o=await Hn(e,t);for(let i of o)r[i.plugin]=ct(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 Rt(e,n){let t=n?.plugin;if(typeof t!="string"||!t.trim())throw G("plugin is required",{missingFields:["plugin"]});let r=t.trim();Dr(e,r);let o=n?.tenantId;if(o!=null&&typeof o!="string")throw G("tenantId must be a string");let i=o?.trim()||"default";if(!e.database)return{ok:!0,disconnected:!1};let s=e.database.db,a=await s.selectFrom("corsair_integrations").select(["id"]).where("name","=",r).executeTakeFirst();if(!a)return{ok:!0,disconnected:!1};let c=!1;return await s.transaction().execute(async l=>{e.database?.isPg===!0&&await l.selectFrom("corsair_integrations").select("id").where("name","=",r).forUpdate().execute();let u=l.selectFrom("corsair_accounts").select("id").where("tenant_id","=",i).where("integration_id","=",a.id);await l.deleteFrom("corsair_events").where("account_id","in",u).execute(),await l.deleteFrom("corsair_entities").where("account_id","in",u).execute(),c=((await l.deleteFrom("corsair_accounts").where("tenant_id","=",i).where("integration_id","=",a.id).executeTakeFirst()).numDeletedRows??0n)>0n}),{ok:!0,disconnected:c}}async function Or(e,n){if(!e.database)throw Be(`Permission '${n}' not found`);let t=await e.database.db.selectFrom("corsair_permissions").selectAll().where("id","=",n).executeTakeFirst();if(!t)throw Be(`Permission '${n}' not found`);return kt(e,t)}function qc(e){if(!e.oauthConfig)throw G(`Plugin '${e.id}' has no oauthConfig`)}function Kc(e){if(!e.manual)throw new C(500,"connect_not_configured","createCorsair was not given manual config. Set { manual: { baseUrl, redirectUri } } to enable manual connect routes.");return e.manual}function Mr(e){let n=Kc(e);if(!n.baseUrl?.trim()||!n.redirectUri?.trim())throw new C(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 Zc(e){let n=!!e.hub,t=fn(e.manual);if(!n&&!t)throw new C(500,"connect_not_configured","createCorsair was not given connect config. Set hub: { ... } for Hub mode, or manual: { baseUrl, redirectUri } for manual connect.")}function zi(e){if(!e.database||!e.kek)throw new C(500,"database_not_configured","A database and kek are required to issue connect links.")}async function Gc(e,n){let t=n?.plugin?.trim();if(!t)throw G("Plugin id is required",{missingFields:["plugin"]});let r=n.tenantId?.trim()||"default",o=Dr(e,t);qc(o);let i=Mr(e);zi(e);let s=await Ki(o,e);if(!s.configured)throw new C(400,"missing_credentials",`Plugin '${t}' is missing OAuth client credentials`,{missingFields:s.missingFields});let a=cn(Me(t,r),e.kek),c;try{c=new URL(i.baseUrl)}catch{throw new C(500,"connect_misconfigured","manual.baseUrl is not a valid URL. Set a full URL including protocol (e.g. https://app.example.com/connect).")}return c.searchParams.set("state",a),{connectUrl:c.toString(),expiresAt:new Date(Date.now()+wr).toISOString(),tenantId:r}}async function zc(e,n,t){zi(n);let r=t.tenantId?.trim()||"default",o={tenantId:r,oauthMode:t.oauthMode},i=t.plugin?.trim();i&&(o.plugin=i);let s=t.providerName?.trim();s&&(o.providerName=s);let a=await yt(e,o);return{connectUrl:a.connectUrl,expiresAt:a.expiresAt,tenantId:r}}async function At(e,n,t){return Zc(n),n.hub?zc(e,n,t):Gc(n,t)}async function xt(e,n,t){if(n.hub&&!fn(n.manual))throw new C(400,"hub_mode","resolve is not used with hub config. Redirect users to connectUrl from createLink.");let r=t?.trim();if(!r)throw G("state is required",{missingFields:["state"]});Mr(n);try{return await Tr(e,r)}catch(o){if(o instanceof oe)switch(o.code){case"invalid_state":throw G("Invalid or expired state");case"client_id_not_configured":throw new C(400,"missing_credentials","OAuth client_id is not configured for this plugin",{missingFields:["client_id"]});case"no_redirect_uri":break}throw new C(500,"resolve_failed","Could not resolve connect link. Check server logs for details.")}}async function It(e,n,t){if(n.hub&&!fn(n.manual))throw new C(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 G("Missing required fields",{missingFields:i});let s=Mr(n),{processOAuthCallback:a}=await import("./oauth.js");try{return await a(e,{code:r,state:o,redirectUri:s.redirectUri,callbackParams:t.callbackParams})}catch(c){if(c instanceof Error&&c.name==="OAuthCallbackError")switch(c.code){case"invalid_state":throw G("Invalid or expired state");case"credentials_not_configured":throw new C(400,"missing_credentials","OAuth client credentials are not configured for this plugin",{missingFields:["client_id","client_secret"]})}throw new C(502,"oauth_callback_failed","OAuth callback did not complete. Check server logs for details.")}}async function Hr(e,n){if(!e.database)throw Be("Permission not found");let t=await e.database.db.selectFrom("corsair_permissions").selectAll().where("token","=",n).executeTakeFirst();if(!t)throw Be("Permission not found");return kt(e,t)}async function Ji(e,n){return"id"in n?Or(e,n.id):Hr(e,n.token)}import{createCipheriv as tu,createDecipheriv as oy,randomBytes as Xi,scryptSync as ru}from"crypto";import{createHmac as Br,randomUUID as Jc,timingSafeEqual as Yi}from"crypto";function Ur(e){return e.run??null}function Fr(e){return e.probe??null}function Qi(e){if(e)return e.startsWith("sha256=")?e.slice(7):e}function St(e){let n=JSON.stringify({type:e.type,payload:e.payload}),t=Math.floor(Date.now()/1e3).toString(),r=Br("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":Jc()}}}function Lr(e){let n=e.signingSecret.trim();if(!n)return!1;let t=Qi(e.signatureHeader);if(!t)return!1;let r=Number(e.timestampHeader);if(!Number.isFinite(r)||Math.abs(Date.now()-r*1e3)>We)return!1;let i=Br("sha256",n).update(e.body).digest("hex");try{return Yi(Buffer.from(i,"utf8"),Buffer.from(t,"utf8"))}catch{return!1}}function bn(e){let n=e.signingSecret.trim();if(!n)return{ok:!1,error:"Tunnel signing secret is required"};let t=Qi(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)>We)return{ok:!1,error:"Tunnel request timestamp is outside the allowed window"};let i=Br("sha256",n).update(e.body).digest("hex");try{if(!Yi(Buffer.from(i,"utf8"),Buffer.from(t,"utf8")))return{ok:!1,error:"Invalid tunnel signature"}}catch{return{ok:!1,error:"Invalid tunnel signature"}}return{ok:!0}}function kn(e){if(!e)return{};try{return JSON.parse(e)}catch{return{}}}function _t(e){return e.httpOk&&(e.status===204||e.body.status==="ok"||e.body.ok===!0)}function Et(e){let n=e.sync?.encrypted;return typeof n!="string"||!n.trim()?null:{encrypted:n.trim()}}function Fn(e){let n=e.connectUrl?.trim();return n?{connectUrl:n,expiresAt:e.expiresAt}:null}function Nr(e){return Fn(kn(e))}async function $r(e){let n=await Mt({deliveryUrl:e.deliveryUrl,projectId:e.projectId,signingSecret:e.signingSecret,type:"connect.create_link",payload:{tenantId:e.tenantId,plugins:e.plugins}}),t=kn(n.body),r=_t({httpOk:n.ok,status:n.status,body:t}),o=Fn(t);if(!r||!o)throw new Error(Ot({deliveryUrl:e.deliveryUrl,status:n.status,body:n.body,ack:t}));return o}function Dt(e){return Et(kn(e))}function Vc(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 Vi(e,n=200){let t=e.trim();return t.length<=n?t:`${t.slice(0,n)}\u2026`}var Yc="Verify hub.signingSecret in your app matches the signing secret shown in Hub project settings.",Qc="Check the delivery URL configured for this environment.";function Xc(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})`}. ${Yc}`}function eu(e){return`${e.ack.error?`${e.ack.error} (HTTP 404 from ${e.deliveryUrl})`:`Delivery endpoint not found at ${e.deliveryUrl} (HTTP 404)`}. ${Qc}`}function Ln(e,n){let t=Vc(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 Ot(e){if(e.status===0)return e.ack.error?e.ack.error:e.body.startsWith("Could not reach")?e.body:Ln(e.deliveryUrl,new Error(e.body||"Delivery request failed"));if(e.status===401||e.status===403)return Xc(e);if(e.status===404)return eu(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}): ${Vi(t)}`:`App failed while processing the delivery (HTTP ${e.status} from ${e.deliveryUrl})`}let n=e.body.trim();return n?`${Vi(n)} (HTTP ${e.status} from ${e.deliveryUrl})`:`Delivery failed with HTTP ${e.status} from ${e.deliveryUrl}`}var nu=15e3;async function Mt(e){let{body:n,headers:t}=St(e);try{let r=await fetch(e.deliveryUrl,{method:"POST",headers:t,body:n,signal:AbortSignal.timeout(nu)}),o=await r.text();return{ok:r.ok,status:r.status,body:o}}catch(r){return{ok:!1,status:0,body:Ln(e.deliveryUrl,r)}}}var ou="aes-256-gcm",iu=12,su=16,au=16,cu=32;function uu(e,n){return ru(e.trim(),n,cu)}function Wr(e,n){let t=n.trim();if(!t)throw new Error("Signing secret is required to encrypt sync manifest");let r=Xi(au),o=uu(t,r),i=Xi(iu),s=tu(ou,o,i,{authTagLength:su}),a=JSON.stringify(e),c=Buffer.concat([s.update(a,"utf8"),s.final()]),l=s.getAuthTag();return[r.toString("base64"),i.toString("base64"),l.toString("base64"),c.toString("base64")].join(":")}var lu=["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 jr(e){if(e instanceof zo)return!1;if(!(e instanceof Error))return!0;let n=e.message.toLowerCase();return!lu.some(t=>n.includes(t))}function du(e){if(!e)return[];let n=S(e);return n?(e.authConfig?.[n]?.integration??[]).filter(r=>!Oe(r)):[]}async function Nn(e,n){let t=T(e);if(!t.database)throw new Error("A database must be configured to sync connections from the app");await gt(e,{silent:!0});let[r,o]=await Promise.all([hn(t),mn(t)]),i={tenants:r.map(s=>({id:s.id})),plugins:o.map(s=>{let a=du(t.plugins.find(c=>c.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 Wr(i,n)}var ge=class extends Error{code;constructor(n,t){super(t),this.name="AuthCredentialsDeliveryError",this.code=n}};async function Ht(e,n){let t=T(e,()=>new ge("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new ge("no_database","Database not configured");let r=K(t,n.plugin,u=>new ge("plugin_not_found",u)),o=S(r);if(!o)throw new ge("invalid_credentials",`Plugin '${r.id}' has no authType configured`);if(o==="oauth_2"||o==="managed")throw new ge("invalid_credentials","OAuth plugins must be connected via sign-in, not credentials delivery");await gn(e,n.tenantId);let i=new Set(Jn(r,o)),a=r.authConfig?.[o]?.account??[],c=B({authType:o,integrationName:n.plugin,tenantId:n.tenantId,kek:t.kek,database:t.database,extraAccountFields:a}),l=0;for(let[u,d]of Object.entries(n.credentials)){if(!d.trim())continue;if(!i.has(u))throw new ge("invalid_credentials",`Unknown credential field '${u}' for plugin '${n.plugin}'`);let p=ee(c,`set_${u}`);if(!p)throw new ge("invalid_credentials",`Cannot set credential field '${u}' for plugin '${n.plugin}'`);await p(d.trim()),l+=1}if(l===0)throw new ge("invalid_credentials","Provide at least one credential field to save");return await we(e,{plugin:r,tenantId:n.tenantId}).catch(()=>{}),{plugin:n.plugin,tenantId:n.tenantId}}var fe=class extends Error{code;constructor(n,t){super(t),this.name="IntegrationCredentialsDeliveryError",this.code=n}};async function qr(e,n){let t=T(e,()=>new fe("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new fe("no_database","Database not configured");let r=K(t,n.plugin,u=>new fe("plugin_not_found",u)),o=S(r);if(!o)throw new fe("invalid_credentials",`Plugin '${r.id}' has no authType configured`);await Oi(e);let i=new Set(Yo(r,o)),a=r.authConfig?.[o]?.integration??[],c=F({authType:o,integrationName:n.plugin,kek:t.kek,database:t.database,extraIntegrationFields:a}),l=0;for(let[u,d]of Object.entries(n.credentials)){if(!d.trim())continue;if(!i.has(u))throw new fe("invalid_credentials",`Unknown integration credential field '${u}' for plugin '${n.plugin}'`);let p=ee(c,`set_${u}`);if(!p)throw new fe("invalid_credentials",`Cannot set integration field '${u}' for plugin '${n.plugin}'`);await p(d.trim()),l+=1}if(l===0)throw new fe("invalid_credentials","Provide at least one integration credential field to save");return{plugin:n.plugin}}var Bt=new Map;function pu(e){for(let[n,t]of Bt)t<=e&&Bt.delete(n)}function Ut(e,n){let t=e.trim();if(!t)return{ok:!1,error:"Delivery replay key is required"};if(!Number.isFinite(n)||n<=0)return{ok:!1,error:"Delivery replay TTL must be a positive number"};let r=Date.now();pu(r);let o=Bt.get(t);return o!==void 0&&o>r?{ok:!1,error:"Delivery request already consumed"}:(Bt.set(t,r+n),{ok:!0})}var Ue=class extends Error{code;constructor(n,t){super(t),this.name="ManagedOAuthDeliveryError",this.code=n}};async function wn(e,n){let{plugin:t,tenantId:r,accessToken:o,refreshToken:i,expiresIn:s,scope:a,authType:c="managed",providerData:l}=n;if(!o.trim())throw new Ue("no_access_token","Managed OAuth delivery missing access_token");let u=T(e,()=>new Ue("invalid_corsair_instance","Invalid corsair instance"));if(!u.database)throw new Ue("no_database","No database configured on corsair instance");let d=K(u,t,g=>new Ue("plugin_not_found",g));await gn(e,r);let p=B({authType:c,integrationName:t,tenantId:r,kek:u.kek,database:u.database});await p.set_access_token(o),i&&await p.set_refresh_token(i),s&&await p.set_expires_at(String(Math.floor(Date.now()/1e3)+s)),a&&await p.set_scope(a),await we(e,{plugin:d,tenantId:r}).catch(()=>{});try{let g=await lt(u.plugins,t,{access_token:o,refresh_token:i,scope:a,...l});if(g){try{let f=d.authConfig?.[c]?.account??[];await dn({database:u.database,kek:u.kek,pluginId:t,tenantId:r,link:g,authType:c,extraAccountFields:f})}catch(f){console.warn(`[corsair:managed-oauth] Failed to persist webhook tenant link for '${t}' tenant '${r}':`,f)}u.hub&&un(u.hub,{plugin:t,tenantId:r,link:g,authType:c})}}catch(g){console.warn(`[corsair:managed-oauth] Failed to resolve webhook tenant link for '${t}' tenant '${r}':`,g)}return await pn(e,d,r,p).catch(g=>{console.warn(`[corsair:managed-oauth] subscribe failed for '${t}' tenant '${r}':`,g)}),{plugin:t,tenantId:r}}function gu(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function es(e,n,t=[]){for(let[r,o]of Object.entries(e))if(gu(o)){if(o.match(n))return{webhook:o,path:[...t,r]}}else if(o&&typeof o=="object"){let i=es(o,n,[...t,r]);if(i)return i}return null}function fu(e){let n={};for(let[t,r]of Object.entries(e))n[t.toLowerCase()]=Array.isArray(r)?r[0]:r;return n}function yu(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 ns(e,n,t,r,o){let i=fu(n),s=typeof t=="string"?JSON.parse(t):t;(!s||typeof s=="object"&&Object.keys(s).length===0)&&i["x-goog-resource-uri"]&&(s=yu(i)||s);let c={headers:i,body:s,...r?{query:r}:{}},l=r?.tenantId||"default",u=e.withTenant?e.withTenant(l):e,d=o?.plugin,p=d?[d]:Vn;for(let g of p){let f=u[g];if(!f||!f.webhooks||!d&&f.pluginWebhookMatcher&&!f.pluginWebhookMatcher(c))continue;let h=es(f.webhooks,c);if(!h)continue;let b=h.path.join("."),k={payload:s,headers:i,rawBody:typeof t=="string"?t:JSON.stringify(t),...r?{query:r}:{},...o?.hubVerified?{hubVerified:!0}:{}};try{let v=await h.webhook.handler(k),P=!!Object.keys(v.returnToSender||{})?.length;return{plugin:g,action:b,body:s,response:P?{...v?.returnToSender,success:!0}:{success:!0},...v.responseHeaders&&{responseHeaders:v.responseHeaders}}}catch(v){return console.error(`Error executing webhook handler for ${g}.${b}:`,v),{plugin:g,action:b,body:s,response:{success:!1,error:v instanceof Error?v.message:"Unknown error"}}}}return{plugin:null,action:null,body:null}}import{createHash as mu}from"crypto";import*as Ge from"vm";var ts="__corsairFailedStep",hu=3e4,Kr=class{constructor(n,t){this.wakeAt=n;this.stepName=t}__corsairSleep=!0};function rs(e){return typeof e=="object"&&e!==null&&e.__corsairSleep===!0}function os(e,n){return`st_${mu("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 is=new Set(["constructor","prototype","__proto__"]);function Ce(e,n){if(e===null)return null;let t=typeof e;return t==="function"?ku(e,n):t==="object"?bu(e):e}function bu(e){return new Proxy(e,{get(n,t){if(!is.has(t))return Ce(Reflect.get(n,t,n),n)},getPrototypeOf:()=>null,setPrototypeOf:()=>!1,defineProperty:()=>!1,set:()=>!1,deleteProperty:()=>!1})}function ku(e,n){return new Proxy(e,{apply:(t,r,o)=>wu(Reflect.apply(t,n,o)),construct(){throw new Error("Workflow code may not construct host objects")},get(t,r){if(!is.has(r))return Ce(Reflect.get(t,r,t),t)},getPrototypeOf:()=>null,setPrototypeOf:()=>!1,defineProperty:()=>!1,set:()=>!1,deleteProperty:()=>!1})}function wu(e){return e!==null&&typeof e=="object"&&typeof e.then=="function"?Promise.resolve(e).then(n=>Ce(n,void 0),n=>{throw Ce(n,void 0)}):Ce(e,void 0)}function Cu(e){let n=Object.create(null),t=Ge.createContext(n,{name:"corsair-workflow",codeGeneration:{strings:!1,wasm:!1}}),o=Ge.runInContext("(s) => JSON.parse(s)",t,{filename:"corsair:sandbox:json"})(JSON.stringify(e.payload??null)),s=Ge.runInContext(`(function (hostRun, hostSleep) {
20
+ const step = function step(name, fn) { return hostRun(name, fn); };
21
+ step.sleep = function sleep(name, ms) { return hostSleep(name, ms); };
22
+ return step;
23
+ })`,t,{filename:"corsair:sandbox:step"})((p,g)=>e.step(p,g),(p,g)=>e.step.sleep(p,g)),c=Ge.runInContext(`(function (sink) {
24
+ const fwd = (level) => function () {
25
+ try { sink(level, Array.prototype.slice.call(arguments)); } catch (_e) {}
26
+ };
27
+ return { log: fwd('log'), info: fwd('info'), warn: fwd('warn'), error: fwd('error'), debug: fwd('debug') };
28
+ })`,t,{filename:"corsair:sandbox:console"})((p,g)=>{let f=console[p]??console.log;try{f(...g)}catch{}});n.__corsair=Ce(e.corsair,void 0),n.__payload=o,n.__step=s,n.__console=c;let l=Ge.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 u,d=new Promise((p,g)=>{u=setTimeout(()=>g(new Error(`Workflow exceeded ${e.timeoutMs}ms time limit`)),e.timeoutMs)});return Promise.race([l,d]).finally(()=>clearTimeout(u))}async function Zr(e){let n=e.memoizedSteps??{},t=[],r=0,o=null,i=(async(s,a)=>{if(o)throw o;let c=r++,l=os(s,c);if(Object.hasOwn(n,l))return Ce(n[l].output,void 0);try{let u=await a();return t.push({stepId:l,name:s,seq:c,status:"completed",output:u}),u}catch(u){if(rs(u))throw u;let d=Ft(u);t.push({stepId:l,name:s,seq:c,status:"failed",error:d});let p=new Error(d);throw p[ts]=s,p}});i.sleep=async(s,a)=>{if(o)throw o;let c=r++,l=os(s,c);if(Object.hasOwn(n,l))return;t.push({stepId:l,name:s,seq:c,status:"completed",output:null});let u=Number.isFinite(a)?Math.max(0,a):0;throw o=new Kr(Date.now()+u,s),o};try{await Cu({code:e.code,corsair:e.corsair,payload:e.payload,step:i,timeoutMs:e.timeoutMs??hu});let s=o;return s?{status:"sleeping",steps:t,sleepUntil:new Date(s.wakeAt).toISOString()}:{status:"completed",steps:t}}catch(s){if(rs(s))return{status:"sleeping",steps:t,sleepUntil:new Date(s.wakeAt).toISOString()};let a=Ft(s),c=s!==null&&typeof s=="object"?s[ts]:void 0;return{status:"failed",steps:t,error:{message:a,...c?{failedStep:c}:{}}}}}import*as Lt from"vm";var ss=1e4;async function Gr(e){let n=Object.create(null),t=Lt.createContext(n,{name:"corsair-probe",codeGeneration:{strings:!1,wasm:!1}});n.corsair=Ce(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 Sr(()=>{let s=Lt.runInContext(o,t,{filename:"corsair:probe",timeout:r});s.catch(()=>{});let a,c=new Promise((l,u)=>{a=setTimeout(()=>u(new Error(`Probe exceeded ${r}ms time limit`)),r)});return Promise.race([s,c]).finally(()=>clearTimeout(a))});return{status:"ok",value:vu(i)}}catch(i){return{status:"error",error:Ft(i)}}}function vu(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?ss:Math.min(e,ss)}function ze(e){return e.deliveryMode==="auth.credentials"}function $n(e){return e.deliveryMode==="connections.sync"}function Nt(e){return e.deliveryMode==="connect.create_link"}function Wn(e){return e.deliveryMode==="permission.approve"||e.deliveryMode==="permission.deny"}function jn(e){return e.deliveryMode==="oauth.tokens"}function $t(e){return e.deliveryMode==="oauth.callback"||e.deliveryMode===void 0&&!ze(e)&&!$n(e)&&!Nt(e)&&!Wn(e)&&!jn(e)}function Pu(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 Ru(e,n){try{return{status:"ok",webhookResponse:{status:200,body:{status:"ok",sync:{encrypted:await Nn(e,n)}}}}}catch(t){return{status:"failed",retryable:jr(t),error:t instanceof Error?t.message:"Connections sync delivery failed"}}}async function Au(e,n){try{let t=await mt(e,n);return Pu(t)}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Connect link delivery failed"}}}function zr(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 xu(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 dt({database:n.database,kek:n.kek,pluginId:t.plugin,linkType:t.linkType,externalId:t.externalId})??void 0)}async function Iu(e,n,t,r){let o=await xu(e,n,t),i={...t.query??{},...o?{tenantId:o}:{}},s=await ns(e,t.headers,t.body,i,{plugin:t.plugin,hubVerified:r&&t.hubVerified===!0});if(!s.plugin)return{status:"failed",retryable:!1,error:"No matching webhook handler found"};if(s.response&&s.response.success===!1)return{status:"failed",retryable:!1,error:typeof s.response.error=="string"?s.response.error:"Webhook handler failed"};let a=s.response?.returnToSender,c=a&&typeof a=="object"&&typeof a.validationToken=="string"&&Object.keys(a).length===1?a.validationToken:a||(s.response?.data??s.response);return{status:"ok",webhookResponse:{status:s.response?.statusCode??200,body:c,headers:s.responseHeaders}}}async function Su(e,n){return await Un(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 _u(e,n){return await wn(e,{plugin:n.plugin,tenantId:n.tenantId,accessToken:n.accessToken,refreshToken:n.refreshToken,expiresIn:n.expiresIn,scope:n.scope,authType:n.authType,providerData:n.providerData}),{status:"ok"}}async function Vr(e,n,t){let r=await Jr(e,{token:n},t);if(r.status!=="ok")throw new Error(r.error??"Permission decision failed")}async function Jr(e,n,t){let r=T(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 Eu(e,n){try{return await Ht(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 qr(e,n),{status:"ok"}}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Integration credential delivery failed"}}}function as(e,n){let t=e;return n&&typeof t?.withTenant=="function"?t.withTenant(n):e}async function Ou(e,n){try{let t=as(e,n.tenantId);return{status:"ok",webhookResponse:{status:200,body:{status:"ok",run:await Zr({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 Mu(e,n){try{let t=as(e,n.tenantId);return{status:"ok",webhookResponse:{status:200,body:{status:"ok",probe:await Gr({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 qn(e,n,t={}){let r=T(e),o=zr(n.headers,"x-corsair-signature"),i=zr(n.headers,"x-corsair-timestamp"),s=zr(n.headers,"x-corsair-nonce"),a=!1;if(t.signingSecret?.trim()){let l=bn({body:n.body,signatureHeader:o,timestampHeader:i,signingSecret:t.signingSecret});if(!l.ok)return{status:"failed",retryable:!1,error:l.error};if(!s?.trim())return{status:"failed",retryable:!1,error:"Missing tunnel nonce"};let u=Ut(`nonce:${s.trim()}`,We);if(!u.ok)return{status:"failed",retryable:!1,error:u.error};a=!0}else if(!t.allowUnsignedTunnel)return{status:"failed",retryable:!1,error:"Tunnel signing secret is required"};let c;try{c=JSON.parse(n.body)}catch{return{status:"failed",retryable:!1,error:"Invalid tunnel envelope JSON"}}if(c.type==="connect.status")return{status:"failed",retryable:!1,error:"connect.status is deprecated; use connections.sync signed delivery instead"};switch(c.type){case"webhook":return Iu(e,r,c.payload,a);case"oauth.callback":return Su(e,c.payload);case"oauth.tokens":return _u(e,c.payload);case"permission.approve":return Jr(e,c.payload,"approved");case"permission.deny":return Jr(e,c.payload,"denied");case"auth.credentials":return Eu(e,c.payload);case"integration.credentials":return Du(e,c.payload);case"connect.create_link":return Au(e,c.payload);case"connections.sync":{let l=t.signingSecret?.trim();return l?Ru(e,l):{status:"failed",retryable:!1,error:"Tunnel signing secret is required for connections.sync"}}case"run":return t.allowWorkflowExecution?Ou(e,c.payload):{status:"failed",retryable:!1,error:"Workflow execution is not enabled (set allowWorkflowExecution: true)"};case"probe":return t.allowWorkflowExecution?Mu(e,c.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(c.type)}`}}}function Hu(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 Yr=3,Bu=250;function Uu(e){return e?.name==="AbortError"}async function Fu(e){try{return(await e.json())?.ok!==!1}catch{return!0}}async function Lu(e,n,t,r,o){for(let i=1;i<=Yr;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 Fu(s)||console.warn(`[corsair] hub did not record delivery ${r.deliveryId} (already timed out); the run may be retried`),!0}catch(s){if(Uu(s))throw s}i<Yr&&await us(Bu)}return console.warn(`[corsair] failed to acknowledge delivery ${r.deliveryId} after ${Yr} attempts; the run may be retried`),!1}async function Nu(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:c}=await i.json(),l=await t.process(e,{headers:c,body:a},{signingSecret:n.signingSecret,allowWorkflowExecution:n.allowWorkflowExecution}),{status:u,body:d}=Hu(l);return await Lu(n,t,o,{deliveryId:s,status:u,body:d},r)?"handled":"error"}var cs=1e3,$u=5e3,Wu=3e4;function us(e){return new Promise(n=>setTimeout(n,e))}var Wt=globalThis.__corsairConnectLoops??=new Map;function ju(e,n={fetch,process:qn}){let t;try{t=U(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(Wt.has(r))return{stop:()=>{}};let o=Symbol("corsair-connect-loop");Wt.set(r,o);let i=()=>{Wt.get(r)===o&&Wt.delete(r)},s=!1,a=null;return(async()=>{let l=cs,u=!1,d=async p=>{u||(console.warn("[corsair] connect loop error; retrying",p),u=!0),s||await us(l),l=Math.min(l*2,$u)};try{for(;!s;){a=new AbortController;let p=setTimeout(()=>a?.abort(),Wu);try{await Nu(e,t,n,a.signal)==="error"?await d("pull or ack failed"):(u=!1,l=cs)}catch(g){if(s)break;await d(g instanceof Error?g.message:g)}finally{clearTimeout(p)}}}finally{i()}})(),{stop:()=>{s=!0,a?.abort(),i()}}}function ls(e){return e==="oauth_2"||e==="managed"?"oauth":e==="bot_token"?"bot_token":"api_key"}function qu(e,n){return n&&!n.has(e.id)?!1:S(e)!==null}async function ds(e,n,t={}){let r=T(e),o=n.trim()||"default",i=t.pluginIds?.length?new Set(t.pluginIds):null,s=await Hn(r,o,{pluginIds:t.pluginIds}),a=new Map(s.map(l=>[l.plugin,l])),c=r.plugins.filter(l=>qu(l,i)).map(l=>{let u=S(l),d=a.get(l.id);return d?{plugin:l.id,providerName:Se(l.id),authKind:ls(u),status:d.status,connected:d.connected,fields:d.fields.map(p=>({name:p.name,level:p.level,required:p.required,configured:p.configured})),missingRequiredFields:d.missingRequiredFields}:{plugin:l.id,providerName:Se(l.id),authKind:ls(u),status:"not_started",connected:!1,fields:[],missingRequiredFields:[]}});return{tenantId:o,plugins:c}}async function ps(e,n){let t=U(e);return q({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:Qn})}var gs=1024*1024,fs=3e4;function Je(e){return e!==void 0&&Number.isFinite(e)&&e>0?e:gs}function Ve(e){return e!==void 0&&Number.isFinite(e)&&e>=0?e:fs}function Cn(e){return new C(413,"payload_too_large",`Request body exceeds the ${e}-byte limit`)}function Ku(e){return new C(408,"request_timeout",`Request body stalled: no bytes received for ${e}ms`)}async function jt(e,n){if(!(n>0))return e();let t;try{return await Promise.race([e(),new Promise((r,o)=>{t=setTimeout(()=>o(Ku(n)),n)})])}finally{clearTimeout(t)}}async function qt(e,n){if(e.body===null)return"";let t=e.body.getReader();try{let r=[],o=0;for(;;){let{done:a,value:c}=await jt(()=>t.read(),n.bodyStallTimeoutMs);if(a)break;if(o+=c.byteLength,o>n.maxBodyBytes)throw Cn(n.maxBodyBytes);r.push(c)}let i=new Uint8Array(o),s=0;for(let a of r)i.set(a,s),s+=a.byteLength;return new TextDecoder().decode(i)}catch(r){throw t.cancel().catch(()=>{}),r}}var Qr=new Map;function ys(e){let n;try{n=U(e)}catch{return}let t=ar(n);t&&Qr.get(n.projectApiKey)!==t&&(Qr.set(n.projectApiKey,t),I({hub:n,path:"/apps/announce",body:{deliveryUrl:t},parseResponse:()=>({ok:!0})}).catch(()=>{Qr.delete(n.projectApiKey)}))}var Zu=[".corsair.dev"];function Gu(e){return e==="localhost"||e==="127.0.0.1"||e==="[::1]"||e==="::1"}function zu(e){try{let{hostname:n,protocol:t}=new URL(e);return t!=="http:"&&t!=="https:"?!1:Gu(n)?!0:Zu.some(r=>n===r.slice(1)||n.endsWith(r))}catch{return!1}}function ms(e){return!e||!zu(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 hs(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 Xr(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 eo(e,n){let t=U(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=Ee(o,t.signingSecret);if(!i)return{type:"json",status:400,body:{error:"Invalid or expired delivery token"}};let s=Ut(`browser:${i.jti}`,_e);if(!s.ok)return{type:"json",status:400,body:{error:s.error}};try{if($n(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 Nn(e,t.signingSecret);return{type:"text",status:200,headers:{"Content-Type":"text/html; charset=utf-8"},body:tn({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!0,body:{status:"ok",sync:{encrypted:a}}})}}if(Nt(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 c=await mt(e,{tenantId:i.tenantId,plugins:a});return{type:"text",status:200,headers:{"Content-Type":"text/html; charset=utf-8"},body:tn({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!0,body:{status:"ok",connectUrl:c.connectUrl,expiresAt:c.expiresAt}})}}if(ze(i))return i.hubSuccessUrl?i.credentials?(await Ht(e,{plugin:i.plugin,tenantId:i.tenantId,credentials:i.credentials}),{type:"redirect",url:Xr(i.hubSuccessUrl,{connectedPlugin:i.plugin})}):{type:"redirect",url:Xr(i.hubSuccessUrl,{error:"Credential delivery missing credentials"})}:{type:"json",status:400,body:{error:"Credential delivery missing hubSuccessUrl"}};if(Wn(i)){if(!i.permissionToken)return{type:"json",status:400,body:{error:"Permission delivery missing permission token"}};await Vr(e,i.permissionToken,i.deliveryMode==="permission.approve"?"approved":"denied")}else if(jn(i)){if(!i.accessToken)return{type:"json",status:400,body:{error:"Managed OAuth delivery missing access_token"}};await wn(e,{plugin:i.plugin,tenantId:i.tenantId,accessToken:i.accessToken,refreshToken:i.refreshToken,expiresIn:i.expiresIn,scope:i.scope,authType:i.authType,providerData:i.providerData})}else{if(!$t(i)||!i.code||!i.state||!i.redirectUri)return{type:"json",status:400,body:{error:"Invalid BYO OAuth delivery token"}};await Un(e,{code:i.code,state:i.state,redirectUri:i.redirectUri,trusted:!0,plugin:i.plugin,tenantId:i.tenantId})}}catch(a){let c=a instanceof Error?a.message:"Hub delivery failed";return $n(i)&&i.hubOrigin&&i.requestId?{type:"text",status:400,headers:{"Content-Type":"text/html; charset=utf-8"},body:tn({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!1,error:c})}:Nt(i)&&i.hubOrigin&&i.requestId?{type:"text",status:400,headers:{"Content-Type":"text/html; charset=utf-8"},body:tn({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!1,error:c})}:ze(i)&&i.hubSuccessUrl?{type:"redirect",url:Xr(i.hubSuccessUrl,{error:c})}:ze(i)&&i.hubOrigin&&i.requestId?{type:"text",status:400,headers:{"Content-Type":"text/html; charset=utf-8"},body:tn({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!1,error:c})}:{type:"json",status:400,body:{error:c}}}return{type:"redirect",url:i.hubSuccessUrl}}async function no(e,n){let t=U(e),r=await qn(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 to(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 ro(e,n){return n.method==="GET"?eo(e,n.url):no(e,{headers:n.headers,body:n.body??""})}async function oo(e,n){try{let t=await ro(e,n);return to(t)}catch(t){if(t instanceof he)return Response.json({error:t.message},{status:503});throw t}}async function Ye(e,n,t){ys(e);let r=n.method.toUpperCase(),o=ms(n.headers.get("origin"));if(r==="OPTIONS")return o?new Response(null,{status:204,headers:o}):Response.json({error:"Method not allowed"},{status:405});if(r!=="GET"&&r!=="POST")return Response.json({error:"Method not allowed"},{status:405});let i=await oo(e,{method:r,url:n.url,headers:n.headers,body:r==="POST"?await qt(n,{maxBodyBytes:Je(t?.maxBodyBytes),bodyStallTimeoutMs:Ve(t?.bodyStallTimeoutMs)}):void 0});return hs(i,o)}var E=class extends Error{pluginId;authType;connectUrl;tenantId;constructor(n,t,r,o){super(r??`[auth-missing:${n}:${t}]`),Object.setPrototypeOf(this,new.target.prototype),this.name="AuthMissingError",this.pluginId=n,this.authType=t,this.connectUrl=o?.connectUrl??null,this.tenantId=o?.tenantId??null}};function vn(e){if(e.forceRefresh||!e.accessToken)return!1;if(!e.expiresAt)return!0;let n=e.now??Math.floor(Date.now()/1e3);return Number(e.expiresAt)>n+300}async function Tn(e,n,t){let r=Math.floor(Date.now()/1e3),o=t?Number(t):Number.NaN,i=typeof n.expires_in=="number"?r+n.expires_in:Number.isFinite(o)&&o>r?o:r+3600;return await e.set_access_token(n.access_token),await e.set_expires_at(String(i)),n.refresh_token&&await e.set_refresh_token(n.refresh_token),n.scope&&await e.set_scope(n.scope),i}var bs=new WeakMap;function Kn(e,n,t){let r=bs.get(e);r||(r=new Map,bs.set(e,r));let o=r.get(n);if(o!==void 0)return o;let i=t().finally(()=>{r.delete(n)});return r.set(n,i),i}var ks=300;async function io(e,n){let{keys:t,hub:r,plugin:o,tenantId:i}=e,s=n?.forceRefresh??!1,a=`managed:${o}:${i}`;return Kn(t,a,async()=>{let[c,l,u]=await Promise.all([t.get_access_token(),t.get_expires_at(),t.get_refresh_token()]);if(!c&&!u)throw new E(o,"managed");let d=Math.floor(Date.now()/1e3);if(!s&&c&&l&&Number(l)>d+ks)return{accessToken:c,expiresAt:Number(l),refreshed:!1};if(!u&&c&&!s){let f=l?Number(l):null;if(f===null||f>d+ks)return{accessToken:c,expiresAt:f??d+3600,refreshed:!1}}if(!u)throw new E(o,"managed");let p=await Vu(r,o,i,u),g=await Tn(t,p,l);return{accessToken:p.access_token,expiresAt:g,refreshed:!0}})}function Ju(e){return e.includes("Managed OAuth connection not found")||e.includes("Managed OAuth connection has no tokens")}async function Vu(e,n,t,r){try{return await I({hub:e,path:"/oauth/refresh",body:{plugin:n,tenantId:t,refresh_token:r},parseResponse:nn})}catch(o){let i=o instanceof Error?o.message:"";throw Ju(i)?new E(n,"managed"):o}}async function ws(e,n){e._refreshAuth=async()=>(await io(n,{forceRefresh:!0})).accessToken}function Cs(e){return{delivery:n=>Ye(e,n),deliveryOptions:n=>Ye(e,n)}}var vs=1200*1e3;function so(){return me()}function ao(){return vs}function co(e,n){return _n(e,n,vs)}function uo(e,n){return le(e,n)}function lo(e){return je(e)}var Ts=600*1e3;function po(){return me()}function go(){return Ts}function fo(e,n){return _n(e,n,Ts)}function yo(e,n){return le(e,n)}function mo(e){return fr(e)}function ho(e){return je(e)}function bo(){return me()}function ko(e,n,t){return tt(e,n,Math.floor(t.getTime()/1e3))}function wo(e,n){return le(e,n)}function Co(e){return je(e)}var Qe=class extends Error{constructor(){super(`Corsair KEK is missing. Pass \`kek\` to createCorsair() or set CORSAIR_KEK in your environment. Generate one with: openssl rand -base64 ${qe}`),this.name="CorsairKekMissingError"}};function Kt(e,n){let t=[];e||t.push("database"),n||t.push("kek");let r={};return new Proxy(r,{get(o,i){if(e&&!n)throw new Qe;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 ${qe}`)}})}async function Yu(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 Ps(e){let{integrationId:n,accountId:t}=await Yu(e);return{integrationId:n,accountId:t}}function Rs(e,n){let t=()=>{if(!e)throw new Error("corsair.chats requires Hub to be configured. Pass `hub` to createCorsair({ hub: { projectApiKey, ... } }).");return e};return{create:r=>cr(t(),{tenantId:n,message:r}),list:()=>lr(t(),{tenantId:n}),get:r=>({message:o=>ur(t(),{chatId:r,tenantId:n,message:o}),listMessages:()=>dr(t(),{chatId:r,tenantId:n})})}}function As(e,n){return`[auth-missing:${e}] Authentication required. Direct the user to connect their account: ${n}`}async function Qu(e){let n=e.hub;if(n&&e.database&&e.kek)try{let t=await Fi(n,{tenantId:e.tenantId,plugin:e.plugin,database:e.database,kek:e.kek,plugins:e.plugins,multiTenancy:e.multiTenancy});return{message:e.manual?.onAuthMissing?e.manual.onAuthMissing({plugin:e.pluginId,connectUrl:t.connectUrl,state:t.token}):As(e.pluginId,t.connectUrl),connectUrl:t.connectUrl}}catch{return{message:`[auth-missing:${e.pluginId}:${e.authType}] Authentication required. Could not create connect link. Check hub configuration and server logs.`,connectUrl:null}}return{message:`[auth-missing:${e.pluginId}:${e.authType}]`,connectUrl:null}}function Xu(e,n,t){let r=cn(Me(e,n.tenantId??t??"default"),n.kek),o=new URL(n.baseUrl);o.searchParams.set("state",r);let i=o.toString();return{message:n.onAuthMissing?n.onAuthMissing({plugin:e,connectUrl:i,state:r}):As(e,i),connectUrl:i}}async function el(e){let n=e.tenantId??"default",t=e.error.pluginId;return e.manual&&fn(e.manual)&&e.manual.oauthConfig&&e.manual.kek&&e.error.authType==="oauth_2"?Xu(t,{...e.manual,baseUrl:e.manual.baseUrl,kek:e.manual.kek},e.tenantId):e.hub&&e.plugin&&e.kek&&e.database&&e.plugins?Qu({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}):{message:e.error.message,connectUrl:null}}async function xs(e){let{message:n,connectUrl:t}=await el(e);throw new E(e.error.pluginId,e.error.authType,n,{connectUrl:t,tenantId:e.tenantId??"default"})}var Zt="connect.request",To="connect.cleared",nl=600*1e3;async function vo(e,n,t){let r=await e.db.selectFrom("corsair_integrations").select("id").where("name","=",t).executeTakeFirst();return r?(await e.db.selectFrom("corsair_accounts").select("id").where("tenant_id","=",n).where("integration_id","=",r.id).executeTakeFirst())?.id??null:null}async function tl(e,n){return(await e.db.selectFrom("corsair_accounts").select("id").where("tenant_id","=",n).execute()).map(r=>r.id)}async function rl(e,n,t){let r=await e.db.selectFrom("corsair_events").select("created_at").where("account_id","=",n).where("event_type","in",[Zt,To]).orderBy("created_at","desc").limit(1).executeTakeFirst();if(!r)return t;let o=r.created_at instanceof Date?r.created_at.getTime():Date.parse(String(r.created_at));return Math.max(t,o+1)}async function Is(e,n,t,r,o){let i=await rl(e,n,o),s=new Date(i);await e.db.insertInto("corsair_events").values({id:en(),created_at:s,updated_at:s,account_id:n,event_type:t,payload:r}).execute()}async function ol(e,n,t=Date.now()){let r=await vo(e,n.tenantId,n.plugin);r&&await Is(e,r,Zt,{plugin:n.plugin,connectUrl:n.connectUrl},t)}async function il(e,n,t,r,o){let i=await e.db.selectFrom("corsair_events").select(["event_type","payload","created_at"]).where("account_id","=",n).where("event_type","in",[Zt,To]).orderBy("created_at","desc").limit(1).executeTakeFirst();if(!i||i.event_type!==Zt)return null;let s=i.created_at instanceof Date?i.created_at.getTime():Date.parse(String(i.created_at));if(r-s>o)return null;let a=typeof i.payload=="string"?JSON.parse(i.payload):i.payload??{},c=a.plugin,l=a.connectUrl;return typeof c!="string"||typeof l!="string"?null:{plugin:c,connectUrl:l,requestedAt:new Date(s).toISOString(),tenantId:t,requestedAtMs:s,accountId:n}}async function Po(e,n,t=Date.now(),r=nl){let o=await tl(e,n);if(o.length===0)return null;let i=(await Promise.all(o.map(l=>il(e,l,n,t,r)))).filter(l=>l!==null);if(i.length===0)return null;i.sort((l,u)=>l.requestedAtMs-u.requestedAtMs||l.accountId.localeCompare(u.accountId));let{requestedAtMs:s,accountId:a,...c}=i[0];return c}async function Ss(e,n,t=Date.now(),r){let o;if(r)o=await vo(e,n,r);else{let i=await Po(e,n,t);o=i?await vo(e,n,i.plugin):null}o&&await Is(e,o,To,{},t)}async function Ro(e,n){if(!(!e||!n.plugin||!n.connectUrl))try{await ol(e,{tenantId:n.tenantId??"default",plugin:n.plugin,connectUrl:n.connectUrl})}catch{}}var sl=async(e,n)=>(console.error(`[corsair:${n.pluginId}:${n.operation}]`,{error:e.message,input:n.input}),{maxRetries:0});async function _s(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||sl)(e,i)}function al(e){return typeof e=="function"}function Ao({endpoints:e,hooks:n,ctx:t,tree:r,pluginId:o,errorHandlers:i,currentPath:s=[],keyBuilder:a,permissionsConfig:c,endpointMeta:l,database:u,permissionsOptions:d,tenantId:p,manualConfig:g,hubConfig:f,plugin:h,kek:b,allPlugins:k,multiTenancy:v}){for(let[P,O]of Object.entries(e)){let D=n?.[P];if(al(O)){let M=D,w=[...s,P].join("."),R=async(A={})=>{let X=l?.[w];_r(w,X?.riskLevel??"write");let te;if(c){let N=X,{result:ce,reason:W,onComplete:xn,token:Ae,id:$e,expiresAt:re}=await qi({pluginId:o,endpointPath:w,args:A,mode:c.mode,override:c.overrides?.[w],riskLevel:N?.riskLevel??"write",meta:N,db:u,timeoutMs:d?Er(d.timeout):void 0,tenantId:p,approvalMode:d?.mode});if(ce==="blocked"){let ue;W==="denied"?ue=`Action '${w}' was denied by the user. Await further instructions before proceeding.`:W==="policy"?ue=`Action '${w}' is blocked by the permission policy. Update the corsair config to allow it.`:W==="timeout"?ue=`Action '${w}' timed out waiting for approval.`:Ae&&$e?ue=await Ir({permissionsOptions:d,manual:g,hub:f,permissionId:$e,permissionToken:Ae,plugin:o,endpoint:w,args:A,tenantId:p??"default",expiresAt:re??new Date(Date.now()+(d?Er(d.timeout):600*1e3)).toISOString(),operationPath:w}):ue=`Action '${w}' requires user approval before it can run.`;let rr=W==="denied"||W==="policy"||W==="timeout"?W:"pending";throw new He(ue,rr)}te=xn}let H=async(N,ce,W)=>{try{return await O(ce,W)}catch(xn){if(xn instanceof Error){let Ae=await _s(xn,o,w,typeof W=="object"&&W!==null?W:{args:W},i);if(N<(Ae.maxRetries||0)){let $e=N+1;console.log(`Retrying (${$e} / ${Ae.maxRetries})...`);let re;if(Ae.headersRetryAfterMs)re=Ae.headersRetryAfterMs;else switch(Ae.retryStrategy){case"exponential_backoff":re=Math.pow(2,$e-1)*1e3;break;case"exponential_backoff_jitter":let ue=Math.pow(2,$e-1)*1e3,rr=(Math.random()-.5)*1e3;re=Math.max(0,ue+rr);break;case"linear_1s":re=1e3;break;case"linear_2s":re=2e3;break;case"linear_3s":re=3e3;break;case"linear_4s":re=4e3;break;default:re=1e3;break}return await new Promise(ue=>setTimeout(ue,re)),await H($e,ce,W)}}throw xn}},L;try{L=a?await a(t,"endpoint"):void 0}catch(N){if(N instanceof ye)throw h&&f&&ln({hub:f,database:u,kek:b,plugins:k??[],plugin:h,tenantId:p,verified:!1}),await Ro(u,{tenantId:N.tenantId??p,plugin:N.plugin,connectUrl:N.connectUrl}),N;if(N instanceof E){h&&f&&ln({hub:f,database:u,kek:b,plugins:k??[],plugin:h,tenantId:p,verified:!1});try{await xs({error:N,manual:g,hub:f,plugin:h,tenantId:p,database:u,kek:b,plugins:k,multiTenancy:v})}catch(ce){throw ce instanceof E&&await Ro(u,{tenantId:ce.tenantId??p,plugin:ce.pluginId,connectUrl:ce.connectUrl}),ce}}throw N}if(!M?.before&&!M?.after){let N=await H(0,{...t,key:L},A);return await te?.(),h&&f&&ln({hub:f,database:u,kek:b,plugins:k??[],plugin:h,tenantId:p,verified:!0}),N}let Re={...t,key:L},Ne=M.before?await M.before(Re,A):{ctx:Re,args:A,continue:!0,passToAfter:void 0};if(Ne.continue===!1)return;let Ko=await H(0,Ne.ctx,Ne.args);return await M.after?.(Ne.ctx,Ko,Ne.passToAfter),await te?.(),h&&f&&ln({hub:f,database:u,kek:b,plugins:k??[],plugin:h,tenantId:p,verified:!0}),Ko};r[P]=R}else if(O&&typeof O=="object"){let M={};Ao({endpoints:O,hooks:D,ctx:t,tree:M,pluginId:o,errorHandlers:i,currentPath:[...s,P],keyBuilder:a,permissionsConfig:c,endpointMeta:l,database:u,permissionsOptions:d,tenantId:p,manualConfig:g,hubConfig:f,plugin:h,kek:b,allPlugins:k,multiTenancy:v}),r[P]=M}}}function cl(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function xo({webhooks:e,hooks:n,ctx:t,webhooksTree:r,keyBuilder:o}){for(let[i,s]of Object.entries(e)){let a=n?.[i];if(cl(s)){let c=a,l=async u=>{let d=(g,f)=>s.handler(g,f),p=o&&u?.hubVerified!==!0?await o(t,"webhook"):void 0;return!c?.before&&!c?.after?d({...t,key:p},u):(async()=>{let g={...t,key:p},f=c.before?await c.before(g,u):{ctx:g,args:u,continue:!0,passToAfter:void 0};if(f.continue===!1)return;let h=await d(f.ctx,f.args);return h?.success===!0&&await c.after?.(f.ctx,h,f.passToAfter),h})()};r[i]={match:s.match,handler:l}}else if(s&&typeof s=="object"){let c={};xo({webhooks:s,hooks:a,ctx:t,webhooksTree:c,keyBuilder:o}),r[i]=c}}}function Es(e){return e&&typeof e=="object"?e:{}}async function Ds(e,n){return q({hub:e,path:`/workflows?tenantId=${encodeURIComponent(n.tenantId)}`,parseResponse:t=>{let r=Es(t).workflows;return Array.isArray(r)?r:[]}})}async function Os(e,n){return q({hub:e,path:`/workflows/${encodeURIComponent(n.workflowId)}?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Workflow "${n.workflowId}" not found`,parseResponse:t=>Es(t).workflow})}async function Ms(e,n){await I({hub:e,path:`/workflows/${encodeURIComponent(n.workflowId)}/status?tenantId=${encodeURIComponent(n.tenantId)}`,body:{status:n.status},notFoundMessage:`Workflow "${n.workflowId}" not found`,parseResponse:t=>t})}async function Hs(e,n){await I({hub:e,path:`/workflows/${encodeURIComponent(n.workflowId)}/rename?tenantId=${encodeURIComponent(n.tenantId)}`,body:{name:n.name},notFoundMessage:`Workflow "${n.workflowId}" not found`,parseResponse:t=>t})}async function Bs(e,n){return I({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 Io(e){return e&&typeof e=="object"?e:{}}async function Us(e,n){return q({hub:e,path:`/runs?tenantId=${encodeURIComponent(n.tenantId)}`,parseResponse:t=>{let r=Io(t).runs;return Array.isArray(r)?r:[]}})}async function Fs(e,n){return q({hub:e,path:`/workflows/${encodeURIComponent(n.workflowId)}/runs?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Workflow "${n.workflowId}" not found`,parseResponse:t=>{let r=Io(t).runs;return Array.isArray(r)?r:[]}})}async function Ls(e,n){return q({hub:e,path:`/runs/${encodeURIComponent(n.runId)}?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Run "${n.runId}" not found`,parseResponse:t=>Io(t).run})}async function So(e,n,t){await I({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 Ns=(e,n)=>So(e,"approve",n),$s=(e,n)=>So(e,"deny",n),Ws=(e,n)=>So(e,"cancel",n);function js(e,n){let t=()=>{if(!e)throw new Error("corsair.workflows.runs requires Hub to be configured. Pass `hub` to createCorsair({ hub: { projectApiKey, ... } }).");return e};return{list:r=>r?.workflowId?Fs(t(),{workflowId:r.workflowId,tenantId:n}):Us(t(),{tenantId:n}),get:r=>Ls(t(),{runId:r,tenantId:n}),approve:r=>Ns(t(),{runId:r,tenantId:n}),deny:r=>$s(t(),{runId:r,tenantId:n}),cancel:r=>Ws(t(),{runId:r,tenantId:n})}}function qs(e,n){let t=()=>{if(!e)throw new Error("corsair.workflows requires Hub to be configured. Pass `hub` to createCorsair({ hub: { projectApiKey, ... } }).");return e},r=(o,i)=>Ms(t(),{workflowId:o,tenantId:n,status:i});return{list:()=>Ds(t(),{tenantId:n}),get:o=>Os(t(),{workflowId:o,tenantId:n}),run:(o,i)=>Bs(t(),{workflowId:o,tenantId:n,payload:i?.payload,idempotencyKey:i?.idempotencyKey}),runs:js(e,n),disable:o=>r(o,"inactive"),enable:o=>r(o,"active"),archive:o=>r(o,"archived"),unarchive:o=>r(o,"inactive"),rename:(o,i)=>Hs(t(),{workflowId:o,tenantId:n,name:i})}}function ul(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 Ps({database:e,integrationName:n,tenantId:t,ensureProvisioned:r});return o=i,o}}function ll(e,n,t,r,o){return e?or(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 _o(e,n){let{database:t,tenantId:r,kek:o,rootErrorHandlers:i,permissionsOptions:s,manualConfig:a,hubConfig:c,internalConfig:l}=n,u=r??"default",d=l&&t?()=>an(l,u):void 0,p={},g={};for(let f of e)p[f.id]={},g[f.id]={};for(let f of e){let h=f.schema,b=ul(t,f.id,u,d);if(h?.entities){let H={};for(let[L,Re]of Object.entries(h.entities)){let Ne=t?or(t.db,b,L,h.version,Re):ll(void 0,b,L,h.version,Re);H[L]=Ne}g[f.id].db=H,p[f.id].db=H}let k=f.options,v=f.authConfig,P;if(t&&o&&k?.authType){let H=v?.[k.authType]?.account??[];P=B({authType:k.authType,integrationName:f.id,tenantId:u,kek:o,database:t,extraAccountFields:H,ensureProvisioned:d}),p[f.id].keys=P}let O={database:t,db:g[f.id]?.db??{},$getAccountId:b,...f.options?{options:f.options}:{},...P?{keys:P,authType:k?.authType}:{},tenantId:u,...c?{hub:c}:{}},D=f.endpoints??{},M=f.hooks,w={...i,...f.errorHandlers},R={},A=f.options?.permissions;Ao({endpoints:D,hooks:M,ctx:O,tree:R,pluginId:f.id,errorHandlers:w,currentPath:[],keyBuilder:f.keyBuilder,permissionsConfig:A,endpointMeta:f.endpointMeta,database:t,permissionsOptions:s,tenantId:r,manualConfig:a?{...a,oauthConfig:f.oauthConfig,kek:o,tenantId:u}:void 0,hubConfig:c,plugin:f,kek:o,allPlugins:e,multiTenancy:l?.multiTenancy}),Object.keys(R).length>0&&(p[f.id].api=R),O.endpoints=R;let X=f.webhooks??{},te=f.webhookHooks;if(Object.keys(X).length>0){let H={};xo({webhooks:X,hooks:te,ctx:O,webhooksTree:H,keyBuilder:f.keyBuilder}),p[f.id].webhooks=H,f.pluginWebhookMatcher&&(p[f.id].pluginWebhookMatcher=f.pluginWebhookMatcher),f.pluginTenantWebhookMatcher&&(p[f.id].pluginTenantWebhookMatcher=f.pluginTenantWebhookMatcher)}}return p.chats=Rs(c,u),p.workflows=qs(c,u),p}function Ks(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??[],c=F({authType:i.authType,integrationName:o.id,kek:t,database:n,extraIntegrationFields:a});r[o.id]=c}}return r}var dl=3e4;function Do(e){let n=e.length;for(;n>0&&e[n-1]==="/";)n--;return e.slice(0,n)}function pl(e){let n=0;for(;n<e.length&&e[n]==="/";)n++;return e.slice(n)}function gl(e,n){return`${Do(e)}/${pl(n)}`}function fl(e,n){let t=n??{},{error:r,message:o,...i}=t;return typeof r!="string"?new C(e,"internal_error","Internal error"):new C(e,r,o,i)}var Eo=Symbol("cloudRequestTimeout");async function z(e,n,t,r){let o=e.fetch??globalThis.fetch,i=e.timeoutMs??dl,s=new AbortController,a,c=new Promise(p=>{a=setTimeout(()=>{s.abort(),p(Eo)},i)}),l;try{let p=o(gl(e.baseUrl,t),{method:n,headers:{authorization:`Bearer ${e.apiKey}`,"content-type":"application/json"},body:r===void 0?void 0:JSON.stringify(r),signal:s.signal}).catch(f=>{if(s.signal.aborted)return Eo;throw f}),g=await Promise.race([p,c]);if(g===Eo)throw new C(0,"internal_error","Cloud request timed out");l=g}finally{clearTimeout(a)}let u=await l.text(),d;try{d=u?JSON.parse(u):void 0}catch{d=void 0}if(!l.ok)throw fl(l.status,d);if(d===void 0)throw new C(l.status,"internal_error","Invalid or empty response body from runtime");return d}var J={invoke:"/:tenant/:plugin/call/:op",instances:"/instances",connectLinks:"/connect/links",tenants:"/tenants",tenant:"/tenants/:id",connectionStatus:"/connection-status",disconnect:"/disconnect",permission:"/permissions/:id",permissionLookup:"/permissions/lookup-by-token"};var yl=new Set(["db","keys","webhooks"]),ml=new Set(["chats","workflows"]),Zs=new Set(["then","catch","finally"]);function ve(e){return typeof e=="function"?e():Promise.resolve(e)}function Gs(e,n,t,r){let o=async(...i)=>{let s=await ve(e);return(await z(s,"POST",J.invoke.replace(":tenant",encodeURIComponent(n)).replace(":plugin",encodeURIComponent(t)).replace(":op",r.map(encodeURIComponent).join(".")),{args:i[0]})).data};return new Proxy(o,{get(i,s){if(!(typeof s!="string"||Zs.has(s)))return Gs(e,n,t,[...r,s])}})}function Gt(e,n){let t=e?new Set(e.map(r=>r.id)):null;return new Proxy({},{get(r,o){if(!(typeof o!="string"||Zs.has(o))){if(ml.has(o))throw new Error(`"${o}" is not available in cloud mode (deferred)`);if(t&&!t.has(o))throw new Error(`Unknown plugin "${o}"`);return new Proxy({},{get(i,s){if(s==="api")return Gs(n.transport,n.tenantId,o,[]);if(typeof s=="string"&&yl.has(s))throw new Error(`"${s}" is not available in cloud mode (deferred)`)}})}}})}function zt(e){return{connect:{createLink:n=>{if(!n.plugin||!n.tenantId)throw new Error('connect.createLink requires both "plugin" and "tenantId" in cloud mode');return ve(e).then(t=>z(t,"POST",J.connectLinks,n))}},tenants:{create:n=>ve(e).then(t=>z(t,"POST",J.tenants,n)),list:()=>ve(e).then(n=>z(n,"GET",J.tenants)),get:n=>ve(e).then(t=>z(t,"GET",J.tenant.replace(":id",encodeURIComponent(n))))},connectionStatus:{get:n=>ve(e).then(t=>z(t,"GET",`${J.connectionStatus}?tenantId=${encodeURIComponent(n.tenantId)}`))},disconnect:n=>ve(e).then(t=>z(t,"POST",J.disconnect,n)),permissions:{get:n=>ve(e).then(t=>"id"in n?z(t,"GET",J.permission.replace(":id",encodeURIComponent(n.id))):z(t,"POST",J.permissionLookup,{token:n.token}))}}}var zs="default";function Te(e){throw new Error(`"${e}" is not available in cloud mode (deferred)`)}function hl(e){let n=e?.baseUrl?.trim()||process.env.CORSAIR_CLOUD_URL?.trim();if(!n)throw new Error("Cloud mode (ck_cloud_ key) requires a base URL \u2014 set hub.baseUrl or CORSAIR_CLOUD_URL.");return zn(n),n}function Js(e){return!!(e?.baseUrl?.trim()||process.env.CORSAIR_CLOUD_URL?.trim())}function bl(e,n){let t=zt(e);return{ok:()=>Te("manage.ok"),tenants:t.tenants,plugins:{list:()=>Te("manage.plugins.list"),get:()=>Te("manage.plugins.get")},connectionStatus:{get:r=>{let o=r?.tenantId||void 0;if(!o&&n)throw new Error("connectionStatus.get requires a tenantId in multi-tenant mode");return t.connectionStatus.get({tenantId:o??zs})}},permissions:t.permissions,connect:{createLink:t.connect.createLink,resolve:()=>Te("manage.connect.resolve"),oauthCallback:()=>Te("manage.connect.oauthCallback")},disconnect:t.disconnect}}function kl(e,n){let t=bl(e,n.multiTenancy);if(n.multiTenancy)return{withTenant:s=>{if(!s)throw new Error("corsair.withTenant(tenantId): tenantId must be a non-empty string");return Gt(n.plugins,{transport:e,tenantId:s})},get keys(){return Te("keys")},get permissions(){return Te("permissions")},manage:t};let r=Gt(n.plugins,{transport:e,tenantId:zs}),o={manage:t,get keys(){return Te("keys")},get permissions(){return Te("permissions")}};return new Proxy(r,{get(s,a,c){return typeof a=="string"&&a in o?Reflect.get(o,a,c):Reflect.get(s,a,c)}})}function Vs(e){return kl({baseUrl:hl(e.hub),apiKey:e.hub.projectApiKey},{multiTenancy:!!e.multiTenancy,plugins:e.plugins})}function wl(e){let n=Do(e),t="/api/corsair";return n.endsWith(t)?n.slice(0,-t.length):n}async function Cl(e){let n=await z({...e,baseUrl:wl(e.baseUrl)},"GET",J.instances),t=new Map;for(let r of n.instances)zn(r.url,`Instance "${r.instanceKey}" URL`),t.set(r.instanceKey,r.url);return t}function vl(e){let n=e.apiKey?.trim();if(!n)throw new Error("corsairCloud: apiKey is required");let t=e.url?.trim()||Zo(n);if(!t)throw new Error("corsairCloud: could not resolve a URL from apiKey \u2014 pass a ck_cloud_<slug>.<secret> key, or set `url` explicitly.");zn(t);let r={baseUrl:t,apiKey:n,fetch:e.fetch},o=null;function i(){return o||(o=Cl(r).catch(a=>{throw o=null,a})),o}let s=zt(r);return{manage:{tenants:s.tenants,permissions:s.permissions},withInstance:a=>{let c=async()=>{let u=await i(),d=u.get(a);if(!d){let p=[...u.keys()].join(", ")||"(none)";throw new Error(`corsairCloud.withInstance("${a}"): no such instance \u2014 available: ${p}`)}return{...r,baseUrl:d}},l=zt(c);return{withTenant(u){if(!u)throw new Error("corsair.withTenant(tenantId): tenantId must be a non-empty string");return Gt(void 0,{transport:c,tenantId:u})},connectionStatus:l.connectionStatus,connect:l.connect,disconnect:l.disconnect}}}}var Tl="createCorsair({ approval: ... }) is deprecated. Rename to permissions: { timeout, onTimeout, mode }.";function Ys(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] ${Tl}`),t):n}var Pl=e=>new C(404,"unknown_plugin",`Plugin '${e}' is not registered.`),Rl=(e,n)=>new C(404,"unknown_op",`Operation '${n}' not found on plugin '${e}'.`),Oo=()=>new C(403,"call_disabled","The /call route is disabled. Construct managementHandler with { unsafeAllowUnauthenticated: true } to enable it \u2014 only when your own backend fronts the handler."),Al=e=>new C(401,"not_connected",`Tenant is not connected for plugin '${e}'. Reconnect and retry.`),Qs=e=>new C(403,"permission_denied",`The call was blocked (${e}).`,{reason:e}),xl=()=>new C(403,"approval_required","This action needs human approval before it can run. Approval is not resumable over HTTP in this version.",{reason:"pending"}),Il=(e,n)=>new C(502,"provider_error","The provider returned an error.",{providerStatus:e,body:n});function Sl(e,n){if(e instanceof C)return e;if(e instanceof E)return Al(e.pluginId||n);if(e instanceof yn)return Qs("readonly");if(e instanceof He)return e.reason==="pending"?xl():Qs(e.reason);if(e instanceof Error&&e.name==="ApiError"){let t=e;return Il(typeof t.status=="number"?t.status:502,t.body)}return console.error("[corsair] unhandled error in call operation",e),new C(500,"internal_error","Internal error")}var _l=new WeakMap,Xs=new WeakMap,El=512;function ea(e,n){let t=e.get(n);return t||(t=new Map,e.set(n,t)),t}function Dl(e,n,t){if(n.size<=El)return;let r=Xs.get(e);for(let o of n.keys())if(o!==t&&(r?.get(o)??0)===0){n.delete(o);return}}function Ol(e,n,t){if(!n.multiTenancy)return{client:e};let r=typeof t=="string"?t.trim():"";if(!r)throw G("tenant is required for a multi-tenant runtime",{missingFields:["tenant"]});let o=ea(_l,e),i=o.get(r);if(i)return o.delete(r),o.set(r,i),{client:i,tenantId:r};let s=e.withTenant(r);return o.set(r,s),Dl(e,o,r),{client:s,tenantId:r}}function Ml(e,n){let t=e;for(let r of n.split(".")){if(t==null||typeof t!="object"||!Object.prototype.hasOwnProperty.call(t,r))return null;t=t[r]}return typeof t=="function"?t:null}function na(e,n=[]){let t=[];for(let[r,o]of Object.entries(e??{}))typeof o=="function"?t.push([...n,r].join(".")):o&&typeof o=="object"&&t.push(...na(o,[...n,r]));return t}function ta(e){let n={};for(let t of e.plugins)n[t.id]=na(t.endpoints??{});return n}async function ra(e,n,{plugin:t,op:r,tenant:o,args:i}){if(!n.plugins.some(d=>d.id===t))throw Pl(t);let{client:s,tenantId:a}=Ol(e,n,o),c=s[t],l=Ml(c?.api,r);if(!l)throw Rl(t,r);let u=a?ea(Xs,e):null;u&&a&&u.set(a,(u.get(a)??0)+1);try{return await l(i??{})}catch(d){throw Sl(d,t)}finally{if(u&&a){let d=(u.get(a)??1)-1;d<=0?u.delete(a):u.set(a,d)}}}function Pn(e,n){if(e===void 0)return n;if(e===null)throw new C(401,"unauthenticated","Could not determine the tenant for this request. Sign in and retry.");return e}function Jt(e){if(e!==void 0)throw new C(403,"forbidden","This route is disabled when resolveTenant is configured (end-user mode). Use a handler without resolveTenant, behind your own admin auth.")}var oa=[{method:"GET",pattern:"/ok",public:!0,handler:async()=>x(200,wt())},{method:"GET",pattern:"/tenants",handler:async({internal:e,scopedTenant:n})=>(Jt(n),x(200,await hn(e)))},{method:"POST",pattern:"/tenants",handler:async({internal:e,body:n,scopedTenant:t})=>(Jt(t),x(201,await Tt(e,n)))},{method:"GET",pattern:"/tenants/:id",handler:async({internal:e,params:n,scopedTenant:t})=>(Jt(t),x(200,await vt(e,n.id)))},{method:"GET",pattern:"/plugins",handler:async({internal:e})=>x(200,await mn(e))},{method:"GET",pattern:"/plugins/:id",handler:async({internal:e,params:n})=>x(200,await Ct(e,n.id))},{method:"GET",pattern:"/connection-status",handler:async({internal:e,query:n,scopedTenant:t})=>x(200,await Pt(e,Pn(t,n.tenantId)))},{method:"GET",pattern:"/permissions/:id",handler:async({internal:e,params:n,scopedTenant:t})=>(Jt(t),x(200,await Or(e,n.id)))},{method:"POST",pattern:"/permissions/lookup-by-token",public:!0,handler:async({internal:e,body:n})=>{let t=n?.token?.trim();return t?x(200,await Hr(e,t)):x(400,{error:"bad_request",message:"token is required",missingFields:["token"]})}},{method:"POST",pattern:"/connect/links",handler:async({corsair:e,internal:n,body:t,scopedTenant:r})=>{let o=t,i=Pn(r,o.tenantId);return x(200,await At(e,n,{...o,tenantId:i}))}},{method:"GET",pattern:"/connect/resolve",public:!0,handler:async({corsair:e,internal:n,query:t})=>x(200,await xt(e,n,t.state??""))},{method:"POST",pattern:"/connect/oauth/callback",public:!0,handler:async({corsair:e,internal:n,body:t})=>x(200,await It(e,n,t))},{method:"GET",pattern:"/connect/request",handler:async({internal:e,query:n,scopedTenant:t})=>{let r=Pn(t,n.tenantId)??"default",o=e.database?await Po(e.database,r):null;return x(200,{request:o},{"cache-control":"no-store"})}},{method:"POST",pattern:"/connect/request/clear",handler:async({internal:e,body:n,scopedTenant:t})=>{let r=n,o=Pn(t,r?.tenantId)??"default";return e.database&&await Ss(e.database,o,void 0,r?.plugin),x(200,{ok:!0})}},{method:"POST",pattern:"/disconnect",handler:async({internal:e,body:n,scopedTenant:t})=>{let r=n??{},o=Pn(t,r.tenantId);return x(200,await Rt(e,{...r,tenantId:o}))}},{method:"GET",pattern:"/call",handler:async({internal:e,allowCall:n})=>{if(!n)throw Oo();return x(200,{plugins:ta(e)})}},{method:"POST",pattern:"/:tenant/:plugin/call/:op",handler:async({corsair:e,internal:n,params:t,body:r,scopedTenant:o,allowCall:i})=>{if(!i)throw Oo();let s=r??{},a=Pn(o,t.tenant),c=await ra(e,n,{plugin:t.plugin,op:t.op,tenant:a,args:s.args});return x(200,{data:c})}}];(()=>{let e=new Set;for(let n of oa){let t=`${n.method} ${n.pattern}`;if(e.has(t))throw new Error(`Duplicate management route registered: ${t}`);e.add(t)}})();function Hl(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 Bl(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 Ul(e,n){if(e.method==="GET"||e.method==="HEAD"||!(e.headers.get("content-type")??"").includes("application/json"))return;let r=await qt(e,n).catch(o=>{throw o instanceof C?o:new C(400,"invalid_json","Request body is not valid JSON")});if(r)try{return JSON.parse(r)}catch{throw new C(400,"invalid_json","Request body is not valid JSON")}}var Fl="/api/corsair";function $(e,n={}){let t=n.basePath??Fl,r=Je(n.maxBodyBytes),o=Ve(n.bodyStallTimeoutMs),i={maxBodyBytes:r,bodyStallTimeoutMs:o},s=T(e,()=>new Error("managementHandler: invalid corsair instance (missing internal config)"));return async a=>{try{let c=a.headers.get("content-length");if(c!==null&&Number(c)>r)throw Cn(r);let l=new URL(a.url),u=Bl(l.pathname,t),d=a.method.toUpperCase();if(d==="OPTIONS"||u==="/"||u==="")return await Ye(e,a,{maxBodyBytes:r,bodyStallTimeoutMs:o});if(d!=="GET"&&d!=="POST")return x(405,{error:"method_not_allowed",message:`Method ${d} not allowed`});let p=Object.fromEntries(l.searchParams);for(let g of oa){if(g.method!==d)continue;let f=Hl(g.pattern,u);if(!f)continue;if(!g.public&&n.authenticate&&!await n.authenticate(a))return x(401,{error:"unauthorized",message:"invalid or missing credentials"});let h=await Ul(a,i),b=n.resolveTenant?await n.resolveTenant(a):void 0;return await g.handler({corsair:e,internal:s,req:a,params:f,query:p,body:h,scopedTenant:b,allowCall:(n.unsafeAllowUnauthenticated??!1)||!!n.authenticate})}throw Be(`No route for ${d} ${u}`)}catch(c){if(n.onError){let u=await n.onError(c,a);if(u)return u}if(c instanceof C)return pe(c);let l=c instanceof Error?c.message:"Internal server error";return x(500,{error:"internal_error",message:l})}}}function Ll(e,n){if(e.get)return e.get(n);let t=e.headers[n]??e.headers[n.toLowerCase()];return Array.isArray(t)?t[0]:t}function Nl(e){if(Buffer.isBuffer(e))return e;if(e instanceof Uint8Array)return Buffer.from(e);if(typeof e=="string")return Buffer.from(e,"utf8");throw new TypeError(`corsair adapter: unsupported stream chunk type ${typeof e}`)}async function $l(e,n,t){let r=[],o=0,i=e();try{let s=await jt(()=>i.next(),t);for(;s.done!==!0;){let a=Nl(s.value);if(o+=a.byteLength,o>n)throw Cn(n);r.push(a),s=await jt(()=>i.next(),t)}return Buffer.concat(r)}catch(s){try{Promise.resolve(i.return?.()).catch(()=>{})}catch{}throw s}}var ia=!1;function Wl(){ia||(ia=!0,console.warn("[corsair] A JSON body parser consumed this request before the corsair adapter.","Re-serializing the parsed object is lossy and will likely fail Hub signature",'verification ("Invalid tunnel signature"). Fix on the corsair route only:',"Express \u2192 mount express.raw({ type: 'application/json' }) before the handler,","or capture raw bytes via express.json({ verify: (req, _res, buf) => { req.rawBody = buf; } }).","Fastify \u2192 call registerCorsairRawBodyParser(app) before listen()."))}async function jl(e,n){let t=(e.method??"GET").toUpperCase();if(t==="GET"||t==="HEAD")return;let r=Je(n.maxBodyBytes),o=Ve(n.bodyStallTimeoutMs),i;if(typeof e.rawBody=="string")i=e.rawBody;else if(e.rawBody instanceof Uint8Array)i=e.rawBody;else if(e.body!==void 0&&e.body!==null)typeof e.body=="string"||e.body instanceof Uint8Array?i=e.body:(Wl(),i=JSON.stringify(e.body));else{let a=e[Symbol.asyncIterator];if(typeof a!="function")return;let c=await $l(a.bind(e),r,o);c.length>0&&(i=c)}if(i===void 0)return;if((typeof i=="string"?Buffer.byteLength(i,"utf8"):i.byteLength)>r)throw Cn(r);return typeof i=="string"?i:i}function V(e){e.resume?.()}async function Fe(e,n={}){let t=Ll(e,"host")??"localhost",r=e.protocol??"http",o=e.originalUrl??e.url??"/",i=`${r}://${t}${o}`,s=new Headers;for(let[l,u]of Object.entries(e.headers))if(u!=null&&!ql.has(l.toLowerCase()))if(Array.isArray(u))for(let d of u)s.append(l,d);else s.set(l,u);let a={method:(e.method??"GET").toUpperCase(),headers:s},c=await jl(e,n);return c!==void 0&&(a.body=c,s.has("content-type")||s.set("content-type","application/json")),new Request(i,a)}async function Y(e,n){typeof e.status=="function"?e.status(n.status):e.statusCode=n.status;let t=n.headers.getSetCookie();n.headers.forEach((o,i)=>{i!=="set-cookie"&&e.setHeader(i,o)}),t.length>0&&e.setHeader("set-cookie",t);let r=Buffer.from(await n.arrayBuffer());e.send?e.send(r):e.end?.(r)}var ql=new Set(["connection","keep-alive","proxy-authenticate","proxy-authorization","te","trailer","transfer-encoding","upgrade","content-length"]);function sa(e,n){let t=$(e,n);return async(r,o,i)=>{try{let s=await t(await Fe(r,{maxBodyBytes:n?.maxBodyBytes,bodyStallTimeoutMs:n?.bodyStallTimeoutMs}));await Y(o,s)}catch(s){if(s instanceof C&&o.headersSent!==!0){await Y(o,pe(s)),V(r);return}V(r),i(s)}}}function Kl(e,n){let t=e[n];return Array.isArray(t)?t[0]:t}function Zl(e){let n=(e.method??"GET").toUpperCase();if(n==="GET"||n==="HEAD"||e.body!==void 0||e.rawBody!==void 0)return;let t=Kl(e.headers,"content-type");if(!(!t||!t.includes("application/json"))&&!(e.raw.readableEnded!==!0&&e.raw.complete!==!0))throw new Error("corsair: Fastify consumed this JSON body before the corsair adapter could read it. Call registerCorsairRawBodyParser(app) before listen() so the original bytes reach the adapter verbatim (Hub signs deliveries over the exact bytes it sent).")}function aa(e){e.addContentTypeParser("application/json",{parseAs:"buffer"},(n,t,r)=>{n.rawBody=t;try{r(null,JSON.parse(t.toString("utf8")))}catch{r(Object.assign(new Error("Invalid JSON body"),{statusCode:400}))}})}function ca(e,n){let t=$(e,n);return async(r,o)=>{Zl(r);let i={method:r.method??r.raw.method,url:r.url??r.raw.url,headers:r.headers,protocol:r.protocol,body:r.body,rawBody:r.rawBody,resume:r.raw.resume?.bind(r.raw),[Symbol.asyncIterator]:r.raw[Symbol.asyncIterator]?.bind(r.raw)};try{let s=await t(await Fe(i,{maxBodyBytes:n?.maxBodyBytes,bodyStallTimeoutMs:n?.bodyStallTimeoutMs}));o.hijack?.(),await Y(o.raw,s)}catch(s){if(s instanceof C&&o.raw.headersSent!==!0&&o.hijack){o.hijack(),await Y(o.raw,pe(s)),V(i);return}throw V(i),s}}}function ua(e,n){let t=$(e,n);return r=>t(r.req.raw)}function la(e,n){let t=$(e,n);return{GET:t,POST:t,OPTIONS:t}}function da(e,n){let t=$(e,n);return async(r,o)=>{try{let i=await t(await Fe(r,{maxBodyBytes:n?.maxBodyBytes,bodyStallTimeoutMs:n?.bodyStallTimeoutMs}));await Y(o,i)}catch(i){if(o.headersSent===!0){console.error("[corsair] management response failed after headers were sent:",i),o.end?.(),V(r);return}if(i instanceof C){await Y(o,pe(i)),V(r);return}console.error("[corsair] management handler failed:",i),await Y(o,x(500,{error:"internal_error"})),V(r)}}}function Vt(e,n){let t=$(e,n);return r=>t(r.request)}function pa(e,n){let t=Vt(e,n);return{GET:t,POST:t,OPTIONS:t}}function ga(e,n){let t=Vt(e,n);return{loader:t,action:t}}function fa(e,n){let t=Vt(e,n);return{GET:t,POST:t,OPTIONS:t}}function ya(e,n){let t=Vt(e,n);return{GET:t,POST:t,OPTIONS:t}}function ma(e,n){let t=$(e,n);return async r=>{let o={method:r.node.req.method,url:r.node.req.url,headers:r.node.req.headers,protocol:r.node.req.protocol,body:r._body,rawBody:r.node.req.rawBody??r._rawBody,resume:r.node.req.resume?.bind(r.node.req),[Symbol.asyncIterator]:r.node.req[Symbol.asyncIterator]?.bind(r.node.req)};try{let i=await t(await Fe(o,{maxBodyBytes:n?.maxBodyBytes,bodyStallTimeoutMs:n?.bodyStallTimeoutMs}));await Y(r.node.res,i)}catch(i){if(i instanceof C&&r.node.res.headersSent!==!0){await Y(r.node.res,pe(i)),V(o);return}throw V(o),i}}}function ha(e,n){return $(e,n)}function ba(e){let n={[Zn]:e};return{ok:wt,tenants:{list:()=>hn(e),create:t=>Tt(e,t),get:t=>vt(e,t)},plugins:{list:()=>mn(e),get:t=>Ct(e,t)},connectionStatus:{get:t=>Pt(e,t?.tenantId)},permissions:{get:t=>Ji(e,t)},connect:{createLink:t=>At(n,e,t),resolve:t=>xt(n,e,t),oauthCallback:t=>It(n,e,t)},disconnect:t=>Rt(e,t)}}async function ka(e,n,t,r,o="pending"){if(!e)return null;try{let i=en(),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 Gl(e,n,t,r="pending"){try{let o=await e.$getAccountId();return ka(e.database,o,n,t,r)}catch(o){return console.warn("Failed to log event:",o),null}}import*as Ca from"https";import*as Yt from"querystring";var zl=["expires_in","refresh_token_expires_in"];function wa(e){let n={...e};for(let t of zl){let r=e[t];if(typeof r=="string"){let o=Number(r);n[t]=Number.isFinite(o)?o:void 0}}return n}function Jl(e){try{return wa(JSON.parse(e))}catch{}if(!e.includes("="))return null;let n=Yt.parse(e);return!n.access_token&&!n.error?null:wa({...n})}function pt(e,n,t,r,o){let i=new URL(r.tokenUrl),s=r.tokenAuthMethod==="basic";return new Promise((a,c)=>{let l={code:e.trim(),redirect_uri:o,grant_type:"authorization_code"};s||(l.client_id=n,l.client_secret=t);let u=Yt.stringify(l),d={"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json","Content-Length":Buffer.byteLength(u).toString()};s&&(d.Authorization=`Basic ${Buffer.from(`${n}:${t}`).toString("base64")}`);let p=Ca.request({hostname:i.hostname,...i.port?{port:Number(i.port)}:{},path:i.pathname+i.search,method:"POST",headers:d},g=>{let f="";g.on("data",h=>{f+=h}),g.on("end",()=>{if(g.statusCode!==200){c(new Error(`Token exchange failed (${g.statusCode}): ${f}`));return}let h=Jl(f);h?a(h):c(new Error(`Token endpoint returned non-JSON response: ${f}`))})});p.on("error",g=>c(new Error(`Request failed: ${g.message}`))),p.write(u),p.end()})}async function va(e,n){let{keys:t,hub:r,plugin:o,tenantId:i}=e,[s,a,c]=await Promise.all([t.get_access_token(),t.get_expires_at(),t.get_refresh_token()]);if(vn({accessToken:s,expiresAt:a,forceRefresh:n?.forceRefresh}))return{accessToken:s,expiresAt:Number(a),refreshed:!1};if(!c)throw new E(o,"oauth_2");let l=await I({hub:r,path:"/oauth/refresh",body:{plugin:o,tenantId:i,refresh_token:c},parseResponse:nn}),u=await Tn(t,l,a);return{accessToken:l.access_token,expiresAt:u,refreshed:!0}}async function Ta(e){let{tokenUrl:n,refreshToken:t,clientSecret:r,clientId:o,tokenAuthMethod:i="body",bodyFormat:s="form",extraParams:a}=e,c={grant_type:"refresh_token",refresh_token:t,...a},l={Accept:"application/json"};i==="basic"?l.Authorization=`Basic ${Buffer.from(`${o??""}:${r}`).toString("base64")}`:i==="basic_secret_only"?l.Authorization=`Basic ${Buffer.from(`${r}:`).toString("base64")}`:(o&&(c.client_id=o),c.client_secret=r),s==="json"?l["Content-Type"]="application/json":l["Content-Type"]="application/x-www-form-urlencoded";let u=await fetch(n,{method:"POST",headers:l,body:s==="json"?JSON.stringify(c):new URLSearchParams(c)});if(!u.ok)throw new Error(`OAuth token refresh failed (${u.status}): ${await u.text()}`);let d=JSON.parse(await u.text());if(typeof d.access_token!="string"||d.access_token.length===0)throw new Error("OAuth token refresh returned no access_token");return{access_token:d.access_token,...typeof d.refresh_token=="string"&&d.refresh_token.length>0?{refresh_token:d.refresh_token}:{},...typeof d.expires_in=="number"?{expires_in:d.expires_in}:{},...typeof d.scope=="string"&&d.scope.length>0?{scope:d.scope}:{}}}async function Pa(e,n){let t=await e.keys.get_integration_credentials(),r=`${n.plugin}:${e.tenantId}`;if(!t.client_secret){if(!e.hub)throw new E(n.plugin,"oauth_2");let l={keys:e.keys,hub:e.hub,plugin:n.plugin,tenantId:e.tenantId},u=g=>Kn(e.keys,r,async()=>(await va(l,{forceRefresh:g})).accessToken);e._refreshAuth=()=>u(!0);let[d,p]=await Promise.all([e.keys.get_access_token(),e.keys.get_expires_at()]);return vn({accessToken:d,expiresAt:p})?d:u(!1)}let o=t.client_secret,i=t.client_id,s=l=>Kn(e.keys,r,async()=>{let[u,d,p]=await Promise.all([e.keys.get_access_token(),e.keys.get_expires_at(),e.keys.get_refresh_token()]);if(!l&&vn({accessToken:u,expiresAt:d}))return u;if(!p)throw new E(n.plugin,"oauth_2");let g=await Ta({tokenUrl:n.tokenUrl,tokenAuthMethod:n.tokenAuthMethod,bodyFormat:n.bodyFormat,extraParams:n.extraParams,clientId:i,clientSecret:o,refreshToken:p});return await Tn(e.keys,g,d),g.access_token});e._refreshAuth=()=>s(!0);let[a,c]=await Promise.all([e.keys.get_access_token(),e.keys.get_expires_at()]);return vn({accessToken:a,expiresAt:c})?a:s(!1)}var Ra=" ";function se(e){let n=e;return n._def??n.def??{}}function ae(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 ie(e){return e.innerType??e.schema??e.out??e.in}function xa(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 ie(e)}}function Ia(e){let n=e.type;return e.element??(typeof n=="string"?void 0:n)}function Xt(e,n){let t=n.shape??e.shape;return typeof t=="function"?t():t}function Rn(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 Sa(e,n){return e.description??n.description}function Vl(e){let n=e;for(;n;){let t=se(n),r=Sa(n,t);if(r)return r;let o=ae(t);if(Fo(o)||o==="ZodPipe"||o==="ZodEffects"||o==="ZodTransform"){n=xa(t,o);continue}break}}function Fo(e){return e==="ZodOptional"||e==="ZodNullable"||e==="ZodDefault"||e==="ZodCatch"}function Q(e){let n=se(e),t=ae(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??Rn(n)[0]??"unknown");case"ZodEnum":return Rn(n).map(r=>String(r)).join(" | ");case"ZodOptional":{let r=ie(n);return r?Q(r):"unknown"}case"ZodNullable":{let r=ie(n);return`${r?Q(r):"unknown"} | null`}case"ZodDefault":case"ZodCatch":{let r=ie(n);return r?Q(r):"unknown"}case"ZodArray":{let r=Ia(n);if(!r)return"unknown[]";let o=se(r),i=ae(o)==="ZodUnion",s=Q(r);return`${i?`(${s})`:s}[]`}case"ZodRecord":return"{}";case"ZodObject":{let r=Xt(e,n),o=Object.entries(r);return o.length===0?"{}":`{ ${o.map(([s,a])=>{let c=ae(se(a));return`${c==="ZodOptional"||c==="ZodNullable"?s+"?":s}: ${Q(a)}`}).join(", ")} }`}case"ZodUnion":return Rn(n).map(r=>Q(r)).join(" | ");case"ZodIntersection":return`${Q(n.left)} & ${Q(n.right)}`;case"ZodPipe":case"ZodTransform":case"ZodEffects":{let r=xa(n,t);return r?Q(r):"unknown"}default:return(t??"unknown").replace("Zod","").toLowerCase()}}function Pe(e){let n=se(e),t=ae(n),r=Sa(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??Rn(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=Rn(n).map(i=>String(i));return{kind:"string",optional:!1,description:r,enum:o}}case"ZodOptional":{let o=ie(n),i=o?Pe(o):{kind:"unknown",optional:!1};return{...i,optional:!0,description:r??i.description}}case"ZodNullable":{let o=ie(n),i=o?Pe(o):{kind:"unknown",optional:!1};return{...i,optional:!0,description:r??i.description}}case"ZodDefault":case"ZodCatch":{let o=ie(n);return o?{...Pe(o),description:r}:{kind:"unknown",optional:!1,description:r}}case"ZodArray":{let o=Ia(n);return{kind:"array",optional:!1,description:r,items:o?Pe(o):{kind:"unknown",optional:!1}}}case"ZodObject":{let o=Xt(e,n),i={};for(let[s,a]of Object.entries(o))i[s]=Pe(a);return{kind:"object",optional:!1,description:r,fields:i}}case"ZodRecord":return{kind:"unknown",optional:!1,description:r};case"ZodUnion":{let o=Rn(n);for(let i of o){let s=se(i);if(ae(s)==="ZodObject")return{...Pe(i),description:r}}return{kind:"unknown",optional:!1,description:r}}case"ZodIntersection":case"ZodPipe":case"ZodTransform":case"ZodEffects":{let o=ie(n);return o?{...Pe(o),description:r}:{kind:"unknown",optional:!1,description:r}}default:return{kind:"unknown",optional:!1,description:r}}}function LC(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(u=>u.id===o);if(!s)return null;let a=i;a.startsWith("api.")&&(a=a.slice(4));let c=Le(s.endpointMeta,a),l=Le(s.endpointSchemas,a);return!c&&!l?null:{input:l?.input?Pe(l.input):null,output:l?.output?Pe(l.output):null,description:c?.description}}var Lo=["equals","contains","startsWith","endsWith","in"],Yl=["equals","gt","gte","lt","lte","in"],Ql=["equals"],Xl=["equals","before","after","between"];function _a(e){let n=se(e);switch(ae(n)){case"ZodOptional":case"ZodNullable":case"ZodDefault":case"ZodCatch":{let r=ie(n);return r?_a(r):null}case"ZodString":return"string";case"ZodNumber":return"number";case"ZodBoolean":return"boolean";case"ZodDate":return"date";default:return null}}function No(e){let n=se(e),t=ae(n);if(Fo(t)){let i=ie(n);return i?No(i):{}}if(t!=="ZodObject")return{};let r=Xt(e,n),o={};for(let[i,s]of Object.entries(r)){let a=_a(s);a==="string"?o[i]={type:"string",operators:Lo}:a==="number"?o[i]={type:"number",operators:Yl}:a==="boolean"?o[i]={type:"boolean",operators:Ql}:a==="date"&&(o[i]={type:"date",operators:Xl})}return o}function Ea(e,n){for(let[t,r]of Object.entries(e))if(t.toLowerCase()===n)return[t,r]}function Ho(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"&&Ho(o,i,t)}}function Bo(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function Uo(e,n,t){for(let[r,o]of Object.entries(e)){let i=[...n,r];Bo(o)?t.push(i.join(".")):o!==null&&typeof o=="object"&&Uo(o,i,t)}}function $o(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 Bo(s)?[i]:null;if(s!==null&&typeof s=="object"&&!Bo(s)){let a=$o(s,r);if(a!==null)return[i,...a]}return null}function Da(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 ed=new Set(Vn);function Xe(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 ed.has(r)?`This plugin (${r}) is not configured. Please add it to the Corsair instance to see its associated methods.`:Xe(e);if(t==="webhooks"){if(!i.webhooks)return[];let a=[];return Uo(i.webhooks,[],a),a.map(c=>`${i.id}.webhooks.${c}`)}if(t==="db"){let a=i.schema?.entities;return a?Object.keys(a).map(c=>`${i.id}.db.${c}.search`):[]}if(!i.endpoints)return[];let s=[];return Ho(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=[];Uo(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=[];Ho(i.endpoints,[],s),o[i.id]=s.map(a=>`${i.id}.api.${a}`)}return o}function Le(e,n){if(e){for(let[t,r]of Object.entries(e))if(t.toLowerCase()===n)return r}}function nd(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 Mo(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 NC(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 u=i.slice(3),d=u.lastIndexOf(".");if(d!==-1){let p=u.slice(0,d),g=u.slice(d+1),f=s.schema?.entities;if(g==="search"&&f){let h=Ea(f,p);if(h){let[b,k]=h,v=No(k),P=[`Search ${o} ${b} stored in the local database.`,"Pass limit and offset as numbers for pagination.","","filters {",` entity_id: string [${Lo.join(", ")}]`];for(let[O,D]of Object.entries(v))P.push(` ${O}?: ${D.type} [${D.operators.join(", ")}]`);return P.push("}"),P.join(`
54
+ `)}}}return Mo(Xe(e,{type:"db"}),"Path not found. Available db operations")}if(i.startsWith("webhooks.")){let u=i.slice(9);if(s.webhooks){let d=$o(s.webhooks,u.split("."));if(d!==null){let p=d.join("."),g=Le(s.webhookSchemas,p.toLowerCase()),f=g?.response?Q(g.response):null,h=[];return g?.description&&h.push(g.description),g?.payload&&h.push(`payload ${Qt(An(g.payload))}`),f&&h.push(`response: ${f}`),h.push(`usage:
55
+ ${Da(o,d)}`),h.join(`
56
+
57
+ `)}}return Mo(Xe(e,{type:"webhooks"}),"Path not found. Available webhooks")}let a=i;a.startsWith("api.")&&(a=a.slice(4));let c=Le(s.endpointMeta,a),l=Le(s.endpointSchemas,a);if(c||l){let u=[],d=[c?.riskLevel?`[${c.riskLevel}]`:"",c?.irreversible?"[irreversible]":""].filter(Boolean).join(" "),p=[c?.description,d].filter(Boolean).join(" ");return p&&u.push(p),l?.input&&u.push(`input ${Qt(An(l.input))}`),l?.output&&u.push(`output ${Qt(An(l.output))}`),u.join(`
58
+
59
+ `)}}}return Mo(Xe(e),"Path not found. Available operations")}function Aa(e){let n=e;for(;;){let t=se(n),r=ae(t);if(Fo(r)){let o=ie(t);if(!o)return n;n=o;continue}return n}}function An(e){if(e===void 0)return{kind:"inline",type:"unknown"};let n=Aa(e),t=se(n);if(ae(t)==="ZodObject"){let o=Xt(n,t),i=[];for(let[s,a]of Object.entries(o)){let c=se(a),l=ae(c),u=l==="ZodOptional"||l==="ZodNullable",d=Aa(a),p=Vl(a);i.push({key:s,optional:u,type:Q(d),...p!==void 0?{description:p}:{}})}return{kind:"object",fields:i}}return{kind:"inline",type:Q(n)}}function Qt(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=Ra.repeat(n+1),r=Ra.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 td(e,n){let t=Xe(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(u=>u.id===n);if(!r)return{ok:!1,error:`Plugin "${n}" is not configured on this instance.`};let o=[];for(let u of t){let{shortPath:d,lookupKey:p}=nd(u,n),g=Le(r.endpointMeta,p),f=Le(r.endpointSchemas,p);!g&&!f||o.push({path:u,shortPath:d,description:g?.description,riskLevel:g?.riskLevel,irreversible:g?.irreversible,input:An(f?.input),output:An(f?.output)})}o.sort((u,d)=>u.path.localeCompare(d.path));let i=[],s=Xe(e,{plugin:n,type:"webhooks"});if(Array.isArray(s)&&r.webhooks)for(let u of s){let p=u.toLowerCase().slice(n.length+1),g=p.startsWith(".")?p.slice(1):p;if(!g.startsWith("webhooks."))continue;let f=g.slice(9),h=$o(r.webhooks,f.split("."));if(h===null)continue;let b=h.join("."),k=Le(r.webhookSchemas,b.toLowerCase()),v=k?.response?Q(k.response):void 0;i.push({path:u,description:k?.description,payload:An(k?.payload),responseType:v,usageExample:Da(n,h)})}i.sort((u,d)=>u.path.localeCompare(d.path));let a=[],c=Xe(e,{plugin:n,type:"db"}),l=r.schema?.entities;if(Array.isArray(c)&&l)for(let u of c){let p=u.toLowerCase().slice(n.length+1),g=p.startsWith(".")?p.slice(1):p;if(!g.startsWith("db."))continue;let f=g.slice(3),h=f.lastIndexOf(".");if(h===-1)continue;let b=f.slice(0,h);if(f.slice(h+1)!=="search")continue;let v=Ea(l,b);if(!v)continue;let[P,O]=v,D=No(O),M=Object.entries(D).map(([w,R])=>({field:w,type:R.type,operators:R.operators}));a.push({path:u,entityName:P,filters:[{field:"entity_id",type:"string",operators:Lo},...M]})}return a.sort((u,d)=>u.path.localeCompare(d.path)),{ok:!0,data:{pluginId:n,api:o,webhooks:i,db:a}}}import{randomUUID as Oa}from"crypto";async function rd(e,n){let t=await e.keys.get_access_token();if(!t)return null;let r=Oa(),o=Oa(),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 od}from"crypto";var er="https://graph.microsoft.com/v1.0",Wo=2e4,id=60;async function sd(e,n){let t=await e.keys.get_access_token();if(!t)return null;let r={authorization:`Bearer ${t}`};try{let c=await fetch(`${er}/subscriptions`,{headers:r,signal:AbortSignal.timeout(Wo)});if(c.ok){let{value:l}=await c.json(),u=(l??[]).filter(d=>d.notificationUrl===n.webhookUrl);await Promise.all(u.map(d=>fetch(`${er}/subscriptions/${d.id}`,{method:"DELETE",headers:r,signal:AbortSignal.timeout(Wo)}).catch(()=>{})))}}catch{}let o=od(),i=new Date(Date.now()+id*6e4).toISOString(),s=await fetch(`${er}/subscriptions`,{method:"POST",headers:{...r,"content-type":"application/json"},signal:AbortSignal.timeout(Wo),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 Ma(e,n){for(let[t,r]of Object.entries(e))if(r?.pluginWebhookMatcher&&r.pluginWebhookMatcher(n))return t;return null}function ad(e,n){let t=Ma(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 cd(e){let n={};for(let t of e)!t.pluginWebhookMatcher&&!t.pluginTenantWebhookMatcher||(n[t.id]={pluginWebhookMatcher:t.pluginWebhookMatcher,pluginTenantWebhookMatcher:t.pluginTenantWebhookMatcher});return n}function Ha(e,n){let t=n.toLowerCase(),r=e[t]??e[n];return Array.isArray(r)?r[0]:typeof r=="string"?r:void 0}function Ba(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 Gn(e){return!e||typeof e!="object"||Array.isArray(e)?null:e}function ud(e){return Gn(e.body)}function Ua(e,n){let t=e.query;if(!t)return;let r=t[n]??t[n.toLowerCase()];return nr(Array.isArray(r)?r:[r])}function Fa(e){let n=e.headers??{},t=[n.validationtoken,n.validationToken,n["validation-token"],n["ms-validation-token"]];for(let c of t){let l=nr(Array.isArray(c)?c:[c]);if(l)return decodeURIComponent(l)}let r=Ua({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 c of o){let l=n[c],u=Array.isArray(l)?l[0]:l;if(!(!u||typeof u!="string"))try{let p=(u.startsWith("http")?new URL(u):new URL(`https://example.invalid${u.startsWith("/")?u:`/${u}`}`)).searchParams.get("validationToken");if(p?.trim())return p.trim()}catch{continue}}let i=e.payload!==void 0?e.payload:e.body!==void 0?e.body:void 0,s=Gn(typeof i=="string"?(()=>{try{return JSON.parse(i)}catch{return i}})():i);return nr([s?.validationToken])??null}function ld(e){if(Fa(e))return!0;let n=Gn(e.body??e.payload);return Ha(e.headers??{},"content-type")?.includes("text/plain")?!n||Object.keys(n).length===0:!1}function nr(e){for(let n of e){let t=Ba(n);if(t)return t}}function dd(e){let t=Gn(e.message)?.data;if(typeof t!="string")return null;try{return JSON.parse(Buffer.from(t,"base64").toString("utf8"))}catch{return null}}var Zn=Symbol.for("corsair:internal");function Wa(e){if(e.hub?.projectApiKey?.startsWith("ck_cloud_")&&Js(e.hub))return Vs(e);let n=e.database?Go(e.database):void 0,t=e.kek??"",r=n&&t?Ks(e.plugins,n,t):Kt(!!n,!!t),o=Ys(e),i={plugins:e.plugins,database:n,kek:t,multiTenancy:!!e.multiTenancy,permissions:o,manual:e.manual,hub:e.hub?rt(e.hub):void 0},s=ji(n),a=ba(i);if(e.multiTenancy){let u=Object.assign({withTenant:d=>{if(!d)throw new Error("corsair.withTenant(tenantId): tenantId must be a non-empty string");let p=_o(e.plugins,{database:n,tenantId:d,kek:t,rootErrorHandlers:e.errorHandlers,permissionsOptions:o,manualConfig:e.manual,hubConfig:i.hub,internalConfig:i});return Object.assign(p,{[Zn]:i})},keys:r,permissions:s,manage:a},{[Zn]:i});return La(u,i.hub),$a(u,i.hub),u}let c=_o(e.plugins,{database:n,tenantId:void 0,kek:t,rootErrorHandlers:e.errorHandlers,permissionsOptions:o,manualConfig:e.manual,hubConfig:i.hub,internalConfig:i}),l=Object.assign({},c,{keys:r,permissions:s,manage:a,[Zn]:i});return La(l,i.hub),$a(l,i.hub),l}function La(e,n){n?.projectApiKey?.startsWith("ck_dev_")&&import("./loop-QDWAVKCS.js").then(t=>t.startConnectLoop(e)).catch(()=>{})}function pd(e){return e?.projectApiKey?.startsWith("ck_dev_")?e.tunnel!==!1&&process.env.CORSAIR_TUNNEL!=="0":!1}var Na=globalThis.__corsairTunnels??=new Set,gd=1e3,fd=3e4;function yd(e){let n=e.schedule??((s,a)=>void setTimeout(s,a).unref?.()),t=e.minDelayMs??gd,r=e.maxDelayMs??fd,o=t,i=()=>{let s=!1,a=()=>{s||(s=!0,n(i,o),o=Math.min(o*2,r))};e.start(a).then(()=>{o=t}).catch(a)};i()}function $a(e,n){if(!pd(n))return;let t=n.projectApiKey;if(Na.has(t))return;let r=Number(process.env.PORT);if(!Number.isInteger(r)||r<1||r>65535){console.error("[corsair] PORT is not set \u2014 dev tunnel skipped. Set PORT to your app port, or run `corsair http <port>`.");return}Na.add(t);let o=typeof n.tunnel=="object"?n.tunnel:{},i=process.env.CORSAIR_FRP_HOST??o.shareHost??ir;yd({start:s=>import("./hub/tunnel/run-tunnel.js").then(a=>a.runTunnel({port:r,apiUrl:n.apiUrl,apiKey:t,shareHost:i,onClose:s})).then(({url:a})=>{console.log(`[corsair] tunnel active: ${a}${sr}`)}).catch(a=>{throw console.warn(`[corsair] tunnel down: ${a instanceof Error?a.message:String(a)}. Retrying \u2014 run \`corsair setup\` if it doesn't recover.`),a})})}var md={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:{}}}},jo=md;async function gt(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=Jo(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 c=Id(e,a.plugins,n),l={...a,database:a.database},u=l.database.db;await Ed(u,i);let d=await Dd(u,l,c.tenantId,c.provisionAccounts,o);n?.credentials&&Object.keys(n.credentials).length>0&&await Hd(e,c,n.credentials,l,o,i);let p=await Ud(d,c,o,s);if(n?.backfill){o("[corsair:setup] Starting backfill...");let g=Wa({plugins:a.plugins,database:u,kek:a.kek,multiTenancy:!0}).withTenant(c.tenantId);await Fd(g,a.plugins,p,o,i),o("[corsair:setup] Backfill complete.")}return t.join(`
63
+ `)}function qo(e,n,t){let r=t==="integration"?e.authConfig?.[n]?.integration??[]:e.authConfig?.[n]?.account??[];return new Set([...j[n][t],...r])}function xd(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=S(o);if(!i)continue;let s=qo(o,i,"account");for(let a of Object.keys(r))if(s.has(a))return!0}return!1}function Id(e,n,t){let r=Vo(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&&xd(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 qa(e,n){return Ie(e)?n===0?!0:Object.values(e).every(t=>qa(t,n-1)):!1}function Sd(e){return qa(e,4)}var _d=Qo;function tr(e){if(e instanceof vd){let n={};for(let[t,r]of Object.entries(e.shape))n[t]=r instanceof Ad?tr(r):"unknown";return n}return e instanceof wd?`${tr(e.unwrap())} | null`:e instanceof Td?`${tr(e.unwrap())} | undefined`:e instanceof kd?e.options.join(" | "):e instanceof Rd?"string":e instanceof Cd?"number":e instanceof hd?"boolean":e instanceof bd?"date":e instanceof Pd?"jsonb":"unknown"}async function Ed(e,n){let t=await e.introspection.getTables(),r=new Set(t.map(o=>o.name));for(let[o,i]of Object.entries(_d))r.has(o)||n(`[corsair:setup] Table "${o}" does not exist. Run your database migrations before calling setupCorsair.
64
+ Schema: ${JSON.stringify(tr(i),null,2)}`)}async function Dd(e,n,t,r,o){let i=new Date,s=new Map;for(let a of n.plugins){let c=a.id,l=S(a),u=await e.selectFrom("corsair_integrations").selectAll().where("name","=",c).executeTakeFirst();if(!u){let h=crypto.randomUUID();await e.insertInto("corsair_integrations").values({id:h,name:c,config:{},created_at:i,updated_at:i}).execute(),u=await e.selectFrom("corsair_integrations").selectAll().where("id","=",h).executeTakeFirst(),o(`[corsair:setup] Created integration: ${c}`)}let d=l?a.authConfig?.[l]?.integration??[]:[],p=l?a.authConfig?.[l]?.account??[]:[],g=l&&u?F({authType:l,integrationName:c,kek:n.kek,database:n.database,extraIntegrationFields:d}):void 0;if(u&&!u.dek&&g&&(await g.issue_new_dek(),o(`[corsair:setup] Issued integration DEK: ${c}`)),!u||!l||!g)continue;let f;if(r){let h=await e.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",t).where("integration_id","=",u.id).executeTakeFirst();if(!h){let b=crypto.randomUUID();await e.insertInto("corsair_accounts").values({id:b,tenant_id:t,integration_id:u.id,config:{},created_at:i,updated_at:i}).execute(),h=await e.selectFrom("corsair_accounts").selectAll().where("id","=",b).executeTakeFirst(),o(`[corsair:setup] Created account: ${c}`)}f=h&&B({authType:l,integrationName:c,tenantId:t,kek:n.kek,database:n.database,extraAccountFields:p}),h&&f&&!h.dek&&(await f.issue_new_dek(),o(`[corsair:setup] Issued account DEK: ${c}`))}s.set(c,{pluginId:c,authType:l,integration:g,account:f,integrationFields:[...j[l].integration,...d],accountFields:r?[...j[l].account,...p]:[]})}return s}function Od(e){if(!Ie(e))return;let n=e.keys;return Ie(n)?n:void 0}function Md(e,n){return"withTenant"in e&&typeof e.withTenant=="function"?e.withTenant(n):e}async function Hd(e,n,t,r,o,i){let s=Od(e),a=n.provisionAccounts?Md(e,n.tenantId):void 0;for(let[c,l]of Object.entries(t)){let u=r.plugins.find(k=>k.id===c);if(!u){i(`[corsair:setup] Unknown plugin '${c}' \u2014 skipping credentials.`);continue}let d=S(u);if(!d){i(`[corsair:setup] Plugin '${c}' has no auth type \u2014 skipping credentials.`);continue}let p=qo(u,d,"integration"),g=qo(u,d,"account"),f=s?.[c],h=a?.[c],b=Ie(h)?h.keys:void 0;for(let[k,v]of Object.entries(l))if(v){if(p.has(k)){if(n.multiTenant&&n.tenantIdProvided)throw new Error(`[corsair:setup] '${c}.${k}' 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 P=ee(f,`set_${k}`);if(!P){i(`[corsair:setup] Cannot set integration field '${k}' for '${c}'.`);continue}await P(v),o(`[corsair:setup] Set ${c} integration.${k}`);continue}if(g.has(k)){if(n.multiTenant&&!n.tenantIdProvided)throw new Error(`setupCorsair: tenantId is required to set account-level credential '${c}.${k}' on a multi-tenant instance`);let P=ee(b,`set_${k}`);if(!P){i(`[corsair:setup] Cannot set account field '${k}' for '${c}'.`);continue}await P(v),o(`[corsair:setup] Set ${c} account.${k} (tenant=${n.tenantId})`);continue}i(`[corsair:setup] Unknown credential field '${k}' for plugin '${c}'.`)}}}var ja=new Set(["webhook_signature","expires_at","scope","redirect_url"]);async function Bd(e,n,t,r,o,i,s,a,c){let l=[],u=[];for(let p of o){if(ja.has(p))continue;let g=ee(t,`get_${p}`);if(!g)continue;let f=null;try{let h=await g();f=typeof h=="string"?h:null}catch{}f||l.push(p)}if(r&&i.length>0)for(let p of i){if(ja.has(p))continue;let g=ee(r,`get_${p}`);if(!g)continue;let f=null;try{let h=await g();f=typeof h=="string"?h:null}catch{}f||u.push(p)}let d=l.length===0&&u.length===0;if(d)a(`[corsair:setup] '${e}' (${n}) is configured \u2713`);else if(n==="managed")a(`[corsair:setup] '${e}' (managed) is not connected yet. Use Connect in your app \u2014 Corsair Hub delivers OAuth tokens after authorization.`);else{let p=[...l,...u];if(c==="cli"){let g=p.map(f=>`${f}=VALUE`).join(" ");a(`[corsair:setup] '${e}' (${n}) needs credentials. Run:
65
+ corsair setup --${e} ${g}`)}else{let g=[`[corsair:setup] '${e}' (${n}) needs credentials. Call:`];for(let f of l)g.push(` await corsair.keys.${e}.set_${f}(value)`);for(let f of u){let h=s.provisionAccounts?s.tenantId==="default"?`corsair.${e}`:`corsair.withTenant(${JSON.stringify(s.tenantId)}).${e}`:`corsair.withTenant(<tenant>).${e}`;g.push(` await ${h}.keys.set_${f}(value)`)}a(g.join(`
66
+ `))}}return d}async function Ud(e,n,t,r){let o=new Set;for(let i of e.values())await Bd(i.pluginId,i.authType,i.integration,i.account,i.integrationFields,i.accountFields,n,t,r)&&o.add(i.pluginId);return o}async function Fd(e,n,t,r,o){if(!Sd(jo)){o("[corsair:setup] Backfill config is invalid - skipping backfill.");return}let i=jo,s=new Set(n.map(a=>a.id));for(let[a,c]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=Ie(e)?e[a]:void 0,u=Ie(l)?l.api:void 0;if(u)for(let[d,p]of Object.entries(c))for(let[g,f]of Object.entries(p)){r(`[corsair:setup] Backfilling ${a} \u203A ${d}.${g}...`);try{let h=Ie(u)?u[d]:void 0;await ee(h,g)?.(f)}catch(h){o(`[corsair:setup] ${a} \u203A ${d}.${g} failed: `+(h instanceof Error?h.message:String(h)))}}}}export{Xo as a,Se as b,ye as c,Yn as d,Qn as e,Xn as f,nn as g,ei as h,et as i,gr as j,In as k,ai as l,ci as m,_e as n,We as o,me as p,rn as q,on as r,Ee as s,yr as t,li as u,En as v,he as w,Dn as x,mr as y,rt as z,U as A,ot as B,sn as C,be as D,ke as E,ne as F,hr as G,On as H,De as I,de as J,Mn as K,F as L,B as M,hi as N,bi as O,gt as P,Hd as Q,Me as R,kr as S,un as T,dn as U,Cr as V,dt as W,Ii as X,Ze as Y,Z,vr as _,Un as $,Di as aa,Ic as ba,ft as ca,Qg as da,Hi as ea,Bi as fa,Ui as ga,Fi as ha,yt as ia,Tr as ja,ht as ka,bt as la,He as ma,yn as na,Sr as oa,Wi as pa,_r as qa,Ur as ra,Fr as sa,St as ta,Lr as ua,bn as va,kn as wa,_t as xa,Et as ya,Fn as za,Nr as Aa,$r as Ba,Dt as Ca,Ln as Da,Ot as Ea,Mt as Fa,Ue as Ga,wn as Ha,ns as Ia,Zr as Ja,Gr as Ka,ze as La,Wn as Ma,jn as Na,$t as Oa,Vr as Pa,qn as Qa,Hu as Ra,Nu as Sa,ju as Ta,ds as Ua,ps as Va,gs as Wa,fs as Xa,Je as Ya,Ve as Za,eo as _a,no as $a,to as ab,ro as bb,oo as cb,Ye as db,E as eb,io as fb,ws as gb,Cs as hb,so as ib,ao as jb,co as kb,uo as lb,lo as mb,po as nb,go as ob,fo as pb,yo as qb,mo as rb,ho as sb,bo as tb,ko as ub,wo as vb,Co as wb,Qe as xb,vl as yb,$ as zb,sa as Ab,aa as Bb,ca as Cb,ua as Db,la as Eb,da as Fb,pa as Gb,ga as Hb,fa as Ib,ya as Jb,ma as Kb,ha as Lb,ka as Mb,Gl as Nb,pt as Ob,Pa as Pb,LC as Qb,Xe as Rb,NC as Sb,Qt as Tb,td as Ub,rd as Vb,er as Wb,sd as Xb,Ma as Yb,ad as Zb,cd as _b,Ha as $b,Ba as ac,Gn as bc,ud as cc,Ua as dc,Fa as ec,ld as fc,nr as gc,dd as hc,Zn as ic,Wa as jc,pd as kc,yd as lc};
@@ -0,0 +1 @@
1
+ var s="api.corsair.cloud",n=new Set(["localhost","127.0.0.1","[::1]","::1"]);function a(r){if(!r.startsWith("ck_cloud_"))return null;let o=r.slice(9),t=o.indexOf(".");if(t<=0)return null;let e=o.slice(0,t);return/^[a-z0-9]+$/.test(e)?`https://${s}/${e}/api/corsair`:null}function l(r,o="Cloud base URL"){let t;try{t=new URL(r)}catch{throw new Error(`${o} is not a valid URL: "${r}"`)}if(t.search||t.hash)throw new Error(`${o} must not contain a query or fragment (got "${r}") \u2014 path segments are appended to it.`);if(t.protocol!=="https:"&&!(t.protocol==="http:"&&n.has(t.hostname)))throw new Error(`${o} must use https:// (got "${r}") \u2014 http:// is only allowed for localhost/127.0.0.1, since the project key is sent as a bearer token.`)}export{a,l as b};
@@ -154,6 +154,8 @@ type CorsairManagementClient = {
154
154
  ok: true;
155
155
  }>;
156
156
  };
157
+ /** Invoke a plugin op via `POST /:tenant/:plugin/call/:op`. Returns the op's result. */
158
+ call: <T = unknown>(plugin: string, op: string, tenantId: string, args?: unknown) => Promise<T>;
157
159
  };
158
160
 
159
161
  /** Props for {@link CorsairProvider}. */
@@ -332,4 +334,21 @@ declare function createCorsairReactClient(opts: CorsairReactClientOptions): {
332
334
  };
333
335
  };
334
336
 
335
- export { type AsyncState, type ConnectAppearance, type ConnectLink, type ConnectTheme, type ConnectionStatus, CorsairErrorBoundary, type CorsairErrorBoundaryProps, CorsairProvider, type CorsairProviderProps, type CorsairReactClientOptions, type CreateConnectLinkInput, type CreateTenantInput, type OAuthCallbackInput, type OAuthCallbackResult, type PermissionLookupInput, type PermissionRecord, type PluginConnectionState, type PluginInfo, type Tenant, type UseConnectionsResult, createCorsairReactClient, useConnections };
337
+ type ApiResult<T> = AsyncState<T> & {
338
+ refetch: () => void;
339
+ };
340
+ type UseCorsairResult = {
341
+ /**
342
+ * `pluginOp` splits on the first `.`: plugin is the segment before it, op is
343
+ * everything after (e.g. `"notion.pages.searchPage"` → plugin `notion`, op
344
+ * `pages.searchPage`). Tenant defaults to `'default'`.
345
+ */
346
+ useApi: <T = unknown>(pluginOp: string, args?: unknown, opts?: {
347
+ tenantId?: string;
348
+ }) => ApiResult<T>;
349
+ /** Reserved for a future typed query layer — no `/db` route exists yet. */
350
+ db: undefined;
351
+ };
352
+ declare function useCorsair(): UseCorsairResult;
353
+
354
+ export { type ApiResult, type AsyncState, type ConnectAppearance, type ConnectLink, type ConnectTheme, type ConnectionStatus, CorsairErrorBoundary, type CorsairErrorBoundaryProps, CorsairProvider, type CorsairProviderProps, type CorsairReactClientOptions, type CreateConnectLinkInput, type CreateTenantInput, type OAuthCallbackInput, type OAuthCallbackResult, type PermissionLookupInput, type PermissionRecord, type PluginConnectionState, type PluginInfo, type Tenant, type UseConnectionsResult, type UseCorsairResult, createCorsairReactClient, useConnections, useCorsair };