corsair 0.1.129 → 0.1.130

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{a as ve,b as Qt,c as Xt}from"./chunk-4OLKWKJG.js";import{a as Fo,b as Te,c as Uo,d as v,e as j,f as No,g as z,h as $,i as I,j as jn,k as Lo,l as ze,m as Yt,n as $o}from"./chunk-7AYINDN2.js";import{a as Bo}from"./chunk-N66TLOH2.js";import{ZodBoolean as vl,ZodDate as Tl,ZodEnum as Pl,ZodNullable as Al,ZodNumber as Rl,ZodObject as xl,ZodOptional as Il,ZodRecord as Sl,ZodString as _l,ZodType as El}from"zod";var qn=["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","asana","ascora","ashby","asindataapi","asticaai","asyncinterview","attio","autom","ayrshare","backendless","bannerbear","bart","basecamp","baselinker","basin","beaconstac","beeminder","benchmarkemail","bestbuy","bettercontact","betterproposals","betterstack","bigdatacloud","bigmailer","bigml","bitbucket","bitwarden","blazemeter","blocknative","bluesky","boldsign","boloforms","boltiot","bonsai","bookingmood","borneo","botbaba","botpress","botsonic","bouncer","box","boxhero","brandfetch","breathehr","brevo","brex","brightdata","browseai","browserless","browsertool","bubble","bugsnag","buildkite","bunnycdn","cal","calendly","campayn","canva","canvas","capsulecrm","castingwords","cdrplatform","certifier","chatbotkit","chatfai","chmeetings","circleci","clickhouse","clientary","clockify","cloudflare","cloudinary","collegefootballdata","confluence","connecteam","contentfulgraphql","contextsevenmcp","convoloai","countdownapi","crowterminal","cursor","customgpt","dadataru","databricks","datadog","datarobot","deepseek","devinmcp","diffbot","digitalocean","discord","dockerhub","dodopayments","doppler","dreamstudio","dripcel","dropbox","dropboxsign","dynapictures","epicgames","exa","exist","facebook","faraday","figma","filloutforms","firecrawl","fireflies","flexisign","formbricks","gemini","github","gitlab","gladia","gmail","googleaddressvalidation","googleanalytics","googlebigquery","googlecalendar","googlecloudvision","googledocs","googledrive","googlemaps","googlemeet","googlesheets","grafana","griptape","groqcloud","habitica","hackernews","harvest","hashnode","here","heygen","htmltoimage","hubspot","huggingface","imgbb","insightoai","instagram","intercom","jigsawstack","jira","kaggle","linear","linkedin","loyverse","mailboxlayer","mailchimp","mailtrap","marketstack","merriamwebsterdict","monday","neon","nextdns","notion","ocrspace","ocrwebservice","ollama","onedrive","onepassword","openai","openrouter","openweathermap","oura","outlook","pagerduty","parseur","pdfmonkey","perplexityai","pinecone","posthog","razorpay","reddit","removebg","resend","retailed","runpod","salesforce","sapsuccessfactors","scaleai","scrapegraphai","securitytrails","sendgrid","sentry","serpapi","sharepoint","slack","sourcegraph","spotify","strava","streamtime","stripe","studiobyai21labs","supabase","synthflowai","tally","tavily","tavilymcp","teams","telegram","textrazor","ticktick","timecamp","timelink","tinyurl","tisane","todoist","toggl","trello","twentyonerisk","twilio","twitter","twitterapiio","twochat","typeform","unione","uniswapapi","uploadcare","vapi","vercel","vestaboard","wakatime","webflow","webvizio","whatsapp","witai","wix","wiza","workday","workiom","worldnewsapi","xquik","youcom","youtube","zendesk","zohoinventory","zohomail","zoom","zoominfo"],Wo={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",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",beeminder:"Beeminder",benchmarkemail:"BenchmarkEmail",bestbuy:"Best Buy",bettercontact:"BetterContact",betterproposals:"Better Proposals",betterstack:"Better Stack",bigdatacloud:"BigDataCloud",bigmailer:"BigMailer",bigml:"BigML",bitbucket:"Bitbucket",bitwarden:"Bitwarden",blazemeter:"BlazeMeter",blocknative:"Blocknative",bluesky:"Bluesky",boldsign:"Boldsign",boloforms:"Boloforms",boltiot:"Bolt IoT",bonsai:"Bonsai",bookingmood:"Bookingmood",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",cal:"Cal",calendly:"Calendly",campayn:"Campayn",canva:"Canva",canvas:"Canvas LMS",capsulecrm:"Capsule CRM",castingwords:"CastingWords",cdrplatform:"CDR Platform",certifier:"Certifier",chatbotkit:"ChatBotKit",chatfai:"ChatFAI",chmeetings:"ChMeetings",circleci:"CircleCI",clickhouse:"Clickhouse",clientary:"Clientary",clockify:"Clockify",cloudflare:"Cloudflare",cloudinary:"Cloudinary",collegefootballdata:"College Football Data",confluence:"Confluence",connecteam:"Connecteam",contentfulgraphql:"Contentful GraphQL",contextsevenmcp:"Context7",convoloai:"ConvoloAi",countdownapi:"Countdown API",crowterminal:"CrowTerminal",cursor:"Cursor",customgpt:"CustomGPT",dadataru:"Dadataru",databricks:"Databricks",datadog:"Datadog",datarobot:"DataRobot",deepseek:"DeepSeek",devinmcp:"Devin MCP",diffbot:"Diffbot",digitalocean:"DigitalOcean",discord:"Discord",dockerhub:"Docker Hub",dodopayments:"Dodo Payments",doppler:"Doppler",dreamstudio:"DreamStudio",dripcel:"Dripcel",dropbox:"Dropbox",dropboxsign:"Dropbox Sign",dynapictures:"Dynapictures",epicgames:"Epic Games",exa:"Exa",exist:"Exist",facebook:"Facebook",faraday:"Faraday",figma:"Figma",filloutforms:"FilloutForms",firecrawl:"Firecrawl",fireflies:"Fireflies",flexisign:"Flexisign",formbricks:"Formbricks",gemini:"Gemini",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",htmltoimage:"HtmlToImage",hubspot:"HubSpot",huggingface:"Hugging Face",imgbb:"ImgBB",insightoai:"Insighto.ai",instagram:"Instagram",intercom:"Intercom",jigsawstack:"JigsawStack",jira:"Jira",kaggle:"Kaggle",linear:"Linear",linkedin:"LinkedIn",loyverse:"Loyverse",mailboxlayer:"MailboxLayer",mailchimp:"Mailchimp",mailtrap:"Mailtrap",marketstack:"Marketstack",merriamwebsterdict:"Merriam-Webster Dictionary",monday:"Monday",neon:"Neon",nextdns:"NextDNS",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",pdfmonkey:"PDFMonkey",perplexityai:"Perplexity AI",pinecone:"Pinecone",posthog:"PostHog",razorpay:"Razorpay",reddit:"Reddit",removebg:"remove.bg",resend:"Resend",retailed:"Retailed",runpod:"RunPod",salesforce:"Salesforce",sapsuccessfactors:"SAP SuccessFactors",scaleai:"Scale AI",scrapegraphai:"ScrapeGraphAI",securitytrails:"SecurityTrails",sendgrid:"SendGrid",sentry:"Sentry",serpapi:"Serpapi",sharepoint:"SharePoint",slack:"Slack",sourcegraph:"Sourcegraph",spotify:"Spotify",strava:"Strava",streamtime:"Streamtime",stripe:"Stripe",studiobyai21labs:"StudioByAI21Labs",supabase:"Supabase",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",trello:"Trello",twentyonerisk:"TwentyOneRisk",twilio:"Twilio",twitter:"Twitter",twitterapiio:"Twitter API IO",twochat:"TwoChat",typeform:"Typeform",unione:"Unione",uniswapapi:"Uniswap",uploadcare:"Uploadcare",vapi:"Vapi",vercel:"Vercel",vestaboard:"Vestaboard",wakatime:"WakaTime",webflow:"Webflow",webvizio:"Webvizio",whatsapp:"WhatsApp",witai:"WitAi",wix:"Wix",wiza:"Wiza",workday:"Workday",workiom:"Workiom",worldnewsapi:"World News API",xquik:"XQuik",youcom:"You.com",youtube:"YouTube",zendesk:"Zendesk",zohoinventory:"Zoho Inventory",zohomail:"Zoho Mail",zoom:"Zoom",zoominfo:"ZoomInfo"};function Pe(e){let n=Wo[e];return n||e.charAt(0).toUpperCase()+e.slice(1)}var pe=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(e){return typeof e=="string"&&e.length>0}function Ta(e){return e==="ready"||e==="partial"||e==="not_started"||e==="missing_integration"}function Pa(e){return e==="oauth_2"||e==="api_key"||e==="bot_token"||e==="managed"}function Kn(e){if(!e||typeof e!="object")throw new Error("Hub API returned an empty connect session");let n=e;if(!E(n.connectUrl)||!E(n.token)||!E(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:E(n.environmentId)?n.environmentId:n.projectId};return E(n.expiresAt)&&(t.expiresAt=n.expiresAt),t}function Zn(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(!E(r.tenantId)||!E(r.plugin)||!Ta(r.status)||!Pa(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:E(r.reportedAt)?r.reportedAt:new Date().toISOString()})}return n}function Gn(e){if(!e||typeof e!="object")throw new Error("Hub API returned an empty permission session");let n=e;if(!E(n.approvalUrl)||!E(n.token)||!E(n.projectId)||!E(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 Je(e){if(!e||typeof e!="object")throw new Error("Hub token refresh returned an empty response");let n=e;if(E(n.access_token))return{access_token:n.access_token,refresh_token:E(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:E(n.scope)?n.scope:void 0};throw new Error(E(n.error)?E(n.error_description)?n.error_description:n.error:"Hub token refresh returned no access_token")}function Aa(e){return Array.isArray(e)?e.filter(n=>typeof n=="string"):[]}function Ra(e){if(!Array.isArray(e))return[];let n=[];for(let t of e){if(!t||typeof t!="object")continue;let r=t;E(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 xa(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 jo(e){if(!e||typeof e!="object")throw new Error("Connect status response was empty");let n=e;if(!E(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(!E(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=Ra(o.fields),a=Aa(o.missingRequiredFields),c=xa(o.status,o.connected,s,a);t.push({plugin:o.plugin,providerName:E(o.providerName)?o.providerName:o.plugin,authKind:i,status:c,connected:o.connected,fields:s,missingRequiredFields:a})}return{tenantId:n.tenantId,plugins:t}}function zn(e){if(!e||typeof e!="object")return null;let n=e;return n.error??n.message??null}function qo(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 Ko(e){return e.replace(/\/$/,"")}function er(e){if(!e.projectApiKey.startsWith("ck_dev_"))return null;try{return ve()}catch{return null}}function Zo(e){let n=er(e);return n?{"x-corsair-delivery-url":n}:{}}async function Go(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 Ia(e,n,t){if(n===404&&t)return t;let r=zn(e);return r||`Hub API returned HTTP ${n}`}function zo(e,n,t){let r=qo(e);throw r?new pe({message:r.message??void 0,connectUrl:r.connectUrl,plugin:r.plugin,tenantId:r.tenantId,reason:r.reason??void 0}):new Error(Ia(e,n,t))}async function x(e){let n=Ko(e.hub.apiUrl),t=await fetch(`${n}${e.path}`,{method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${e.hub.projectApiKey}`,...Zo(e.hub)},body:JSON.stringify(e.body)}),r=await Go(t);return t.ok||zo(r,t.status,e.notFoundMessage),e.parseResponse(r)}async function W(e){let n=Ko(e.hub.apiUrl),t=await fetch(`${n}${e.path}`,{method:"GET",headers:{authorization:`Bearer ${e.hub.projectApiKey}`,...Zo(e.hub)}}),r=await Go(t);return t.ok||zo(r,t.status,e.notFoundMessage),e.parseResponse(r)}function Jn(e){return e&&typeof e=="object"?e:{}}function Jo(e){let n=Jn(e);return{chatId:n.threadId,message:n.message,workflowId:n.workflowId??null,action:n.action}}async function nr(e,n){return x({hub:e,path:"/threads",body:{tenantId:n.tenantId,message:n.message},parseResponse:t=>{let r=Jn(t);return{chat:r.thread,reply:Jo(r.reply)}}})}async function tr(e,n){return x({hub:e,path:`/threads/${encodeURIComponent(n.chatId)}/messages`,body:{tenantId:n.tenantId,message:n.message},notFoundMessage:`Chat "${n.chatId}" not found`,parseResponse:Jo})}async function rr(e,n){return W({hub:e,path:`/threads?tenantId=${encodeURIComponent(n.tenantId)}`,parseResponse:t=>{let r=Jn(t).threads;return Array.isArray(r)?r:[]}})}async function or(e,n){return W({hub:e,path:`/threads/${encodeURIComponent(n.chatId)}/messages?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Chat "${n.chatId}" not found`,parseResponse:t=>{let r=Jn(t).messages;return Array.isArray(r)?r:[]}})}import{randomUUID as Ha}from"crypto";var Sa="corsair:client-bridge";function ir(e){return new URL(e).origin}function Ve(e){let n=JSON.stringify({type:Sa,requestId:e.requestId,ok:e.ok,body:e.body??null,error:e.error??null}),t=JSON.stringify(ir(e.hubOrigin));return`<!DOCTYPE html><html><head><meta charset="utf-8"></head><body><script>
1
+ import{a as ve,b as Yt,c as Qt}from"./chunk-4OLKWKJG.js";import{a as Bo,b as Te,c as Fo,d as v,e as j,f as Uo,g as z,h as $,i as I,j as jn,k as No,l as ze,m as Vt,n as Lo}from"./chunk-7AYINDN2.js";import{a as Ho}from"./chunk-N66TLOH2.js";import{ZodBoolean as Rl,ZodDate as xl,ZodEnum as Il,ZodNullable as Sl,ZodNumber as _l,ZodObject as El,ZodOptional as Dl,ZodRecord as Ol,ZodString as Ml,ZodType as Hl}from"zod";var qn=["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","asana","ascora","ashby","asindataapi","asticaai","asyncinterview","attio","autom","ayrshare","backendless","bannerbear","bart","basecamp","baselinker","basin","beaconstac","beeminder","benchmarkemail","bestbuy","bettercontact","betterproposals","betterstack","bigdatacloud","bigmailer","bigml","bitbucket","bitwarden","blazemeter","blocknative","bluesky","boldsign","boloforms","boltiot","bonsai","bookingmood","borneo","botbaba","botpress","botsonic","bouncer","box","boxhero","brandfetch","breathehr","brevo","brex","brightdata","browseai","browserless","browsertool","bubble","bugsnag","buildkite","bunnycdn","cal","calendly","campayn","canva","canvas","capsulecrm","castingwords","cdrplatform","certifier","chatbotkit","chatfai","chmeetings","circleci","clickhouse","clientary","clockify","cloudflare","cloudinary","collegefootballdata","confluence","connecteam","contentfulgraphql","contextsevenmcp","convoloai","countdownapi","crowterminal","cursor","customgpt","dadataru","databricks","datadog","datarobot","deepseek","devinmcp","diffbot","digitalocean","discord","dockerhub","dodopayments","doppler","dreamstudio","dripcel","dropbox","dropboxsign","dynapictures","epicgames","exa","exist","facebook","faraday","figma","filloutforms","firecrawl","fireflies","flexisign","formbricks","gemini","github","gitlab","gladia","gmail","googleaddressvalidation","googleanalytics","googlebigquery","googlecalendar","googlecloudvision","googledocs","googledrive","googlemaps","googlemeet","googlesheets","grafana","griptape","groqcloud","habitica","hackernews","harvest","hashnode","here","heygen","htmltoimage","hubspot","huggingface","imgbb","insightoai","instagram","intercom","jigsawstack","jira","kaggle","linear","linkedin","loyverse","mailboxlayer","mailchimp","mailtrap","marketstack","merriamwebsterdict","monday","neon","nextdns","notion","ocrspace","ocrwebservice","ollama","onedrive","onepassword","openai","openrouter","openweathermap","oura","outlook","pagerduty","parseur","pdfmonkey","perplexityai","pinecone","posthog","razorpay","reddit","removebg","resend","retailed","runpod","salesforce","sapsuccessfactors","scaleai","scrapegraphai","securitytrails","sendgrid","sentry","serpapi","sharepoint","slack","sourcegraph","spotify","strava","streamtime","stripe","studiobyai21labs","supabase","synthflowai","tally","tavily","tavilymcp","teams","telegram","textrazor","ticktick","timecamp","timelink","tinyurl","tisane","todoist","toggl","trello","twentyonerisk","twilio","twitter","twitterapiio","twochat","typeform","unione","uniswapapi","uploadcare","vapi","vercel","vestaboard","wakatime","webflow","webvizio","whatsapp","witai","wix","wiza","workday","workiom","worldnewsapi","xquik","youcom","youtube","zendesk","zohoinventory","zohomail","zoom","zoominfo"],$o={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",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",beeminder:"Beeminder",benchmarkemail:"BenchmarkEmail",bestbuy:"Best Buy",bettercontact:"BetterContact",betterproposals:"Better Proposals",betterstack:"Better Stack",bigdatacloud:"BigDataCloud",bigmailer:"BigMailer",bigml:"BigML",bitbucket:"Bitbucket",bitwarden:"Bitwarden",blazemeter:"BlazeMeter",blocknative:"Blocknative",bluesky:"Bluesky",boldsign:"Boldsign",boloforms:"Boloforms",boltiot:"Bolt IoT",bonsai:"Bonsai",bookingmood:"Bookingmood",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",cal:"Cal",calendly:"Calendly",campayn:"Campayn",canva:"Canva",canvas:"Canvas LMS",capsulecrm:"Capsule CRM",castingwords:"CastingWords",cdrplatform:"CDR Platform",certifier:"Certifier",chatbotkit:"ChatBotKit",chatfai:"ChatFAI",chmeetings:"ChMeetings",circleci:"CircleCI",clickhouse:"Clickhouse",clientary:"Clientary",clockify:"Clockify",cloudflare:"Cloudflare",cloudinary:"Cloudinary",collegefootballdata:"College Football Data",confluence:"Confluence",connecteam:"Connecteam",contentfulgraphql:"Contentful GraphQL",contextsevenmcp:"Context7",convoloai:"ConvoloAi",countdownapi:"Countdown API",crowterminal:"CrowTerminal",cursor:"Cursor",customgpt:"CustomGPT",dadataru:"Dadataru",databricks:"Databricks",datadog:"Datadog",datarobot:"DataRobot",deepseek:"DeepSeek",devinmcp:"Devin MCP",diffbot:"Diffbot",digitalocean:"DigitalOcean",discord:"Discord",dockerhub:"Docker Hub",dodopayments:"Dodo Payments",doppler:"Doppler",dreamstudio:"DreamStudio",dripcel:"Dripcel",dropbox:"Dropbox",dropboxsign:"Dropbox Sign",dynapictures:"Dynapictures",epicgames:"Epic Games",exa:"Exa",exist:"Exist",facebook:"Facebook",faraday:"Faraday",figma:"Figma",filloutforms:"FilloutForms",firecrawl:"Firecrawl",fireflies:"Fireflies",flexisign:"Flexisign",formbricks:"Formbricks",gemini:"Gemini",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",htmltoimage:"HtmlToImage",hubspot:"HubSpot",huggingface:"Hugging Face",imgbb:"ImgBB",insightoai:"Insighto.ai",instagram:"Instagram",intercom:"Intercom",jigsawstack:"JigsawStack",jira:"Jira",kaggle:"Kaggle",linear:"Linear",linkedin:"LinkedIn",loyverse:"Loyverse",mailboxlayer:"MailboxLayer",mailchimp:"Mailchimp",mailtrap:"Mailtrap",marketstack:"Marketstack",merriamwebsterdict:"Merriam-Webster Dictionary",monday:"Monday",neon:"Neon",nextdns:"NextDNS",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",pdfmonkey:"PDFMonkey",perplexityai:"Perplexity AI",pinecone:"Pinecone",posthog:"PostHog",razorpay:"Razorpay",reddit:"Reddit",removebg:"remove.bg",resend:"Resend",retailed:"Retailed",runpod:"RunPod",salesforce:"Salesforce",sapsuccessfactors:"SAP SuccessFactors",scaleai:"Scale AI",scrapegraphai:"ScrapeGraphAI",securitytrails:"SecurityTrails",sendgrid:"SendGrid",sentry:"Sentry",serpapi:"Serpapi",sharepoint:"SharePoint",slack:"Slack",sourcegraph:"Sourcegraph",spotify:"Spotify",strava:"Strava",streamtime:"Streamtime",stripe:"Stripe",studiobyai21labs:"StudioByAI21Labs",supabase:"Supabase",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",trello:"Trello",twentyonerisk:"TwentyOneRisk",twilio:"Twilio",twitter:"Twitter",twitterapiio:"Twitter API IO",twochat:"TwoChat",typeform:"Typeform",unione:"Unione",uniswapapi:"Uniswap",uploadcare:"Uploadcare",vapi:"Vapi",vercel:"Vercel",vestaboard:"Vestaboard",wakatime:"WakaTime",webflow:"Webflow",webvizio:"Webvizio",whatsapp:"WhatsApp",witai:"WitAi",wix:"Wix",wiza:"Wiza",workday:"Workday",workiom:"Workiom",worldnewsapi:"World News API",xquik:"XQuik",youcom:"You.com",youtube:"YouTube",zendesk:"Zendesk",zohoinventory:"Zoho Inventory",zohomail:"Zoho Mail",zoom:"Zoom",zoominfo:"ZoomInfo"};function Pe(e){let n=$o[e];return n||e.charAt(0).toUpperCase()+e.slice(1)}var pe=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(e){return typeof e=="string"&&e.length>0}function Ta(e){return e==="ready"||e==="partial"||e==="not_started"||e==="missing_integration"}function Pa(e){return e==="oauth_2"||e==="api_key"||e==="bot_token"||e==="managed"}function Kn(e){if(!e||typeof e!="object")throw new Error("Hub API returned an empty connect session");let n=e;if(!E(n.connectUrl)||!E(n.token)||!E(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:E(n.environmentId)?n.environmentId:n.projectId};return E(n.expiresAt)&&(t.expiresAt=n.expiresAt),t}function Zn(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(!E(r.tenantId)||!E(r.plugin)||!Ta(r.status)||!Pa(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:E(r.reportedAt)?r.reportedAt:new Date().toISOString()})}return n}function Gn(e){if(!e||typeof e!="object")throw new Error("Hub API returned an empty permission session");let n=e;if(!E(n.approvalUrl)||!E(n.token)||!E(n.projectId)||!E(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 Je(e){if(!e||typeof e!="object")throw new Error("Hub token refresh returned an empty response");let n=e;if(E(n.access_token))return{access_token:n.access_token,refresh_token:E(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:E(n.scope)?n.scope:void 0};throw new Error(E(n.error)?E(n.error_description)?n.error_description:n.error:"Hub token refresh returned no access_token")}function Aa(e){return Array.isArray(e)?e.filter(n=>typeof n=="string"):[]}function Ra(e){if(!Array.isArray(e))return[];let n=[];for(let t of e){if(!t||typeof t!="object")continue;let r=t;E(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 xa(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 Wo(e){if(!e||typeof e!="object")throw new Error("Connect status response was empty");let n=e;if(!E(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(!E(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=Ra(o.fields),a=Aa(o.missingRequiredFields),c=xa(o.status,o.connected,s,a);t.push({plugin:o.plugin,providerName:E(o.providerName)?o.providerName:o.plugin,authKind:i,status:c,connected:o.connected,fields:s,missingRequiredFields:a})}return{tenantId:n.tenantId,plugins:t}}function zn(e){if(!e||typeof e!="object")return null;let n=e;return n.error??n.message??null}function jo(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 qo(e){return e.replace(/\/$/,"")}function Xt(e){if(!e.projectApiKey.startsWith("ck_dev_"))return null;try{return ve()}catch{return null}}function Ko(e){let n=Xt(e);return n?{"x-corsair-delivery-url":n}:{}}async function Zo(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 Ia(e,n,t){if(n===404&&t)return t;let r=zn(e);return r||`Hub API returned HTTP ${n}`}function Go(e,n,t){let r=jo(e);throw r?new pe({message:r.message??void 0,connectUrl:r.connectUrl,plugin:r.plugin,tenantId:r.tenantId,reason:r.reason??void 0}):new Error(Ia(e,n,t))}async function x(e){let n=qo(e.hub.apiUrl),t=await fetch(`${n}${e.path}`,{method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${e.hub.projectApiKey}`,...Ko(e.hub)},body:JSON.stringify(e.body)}),r=await Zo(t);return t.ok||Go(r,t.status,e.notFoundMessage),e.parseResponse(r)}async function W(e){let n=qo(e.hub.apiUrl),t=await fetch(`${n}${e.path}`,{method:"GET",headers:{authorization:`Bearer ${e.hub.projectApiKey}`,...Ko(e.hub)}}),r=await Zo(t);return t.ok||Go(r,t.status,e.notFoundMessage),e.parseResponse(r)}function Jn(e){return e&&typeof e=="object"?e:{}}function zo(e){let n=Jn(e);return{chatId:n.threadId,message:n.message,workflowId:n.workflowId??null,action:n.action}}async function er(e,n){return x({hub:e,path:"/threads",body:{tenantId:n.tenantId,message:n.message},parseResponse:t=>{let r=Jn(t);return{chat:r.thread,reply:zo(r.reply)}}})}async function nr(e,n){return x({hub:e,path:`/threads/${encodeURIComponent(n.chatId)}/messages`,body:{tenantId:n.tenantId,message:n.message},notFoundMessage:`Chat "${n.chatId}" not found`,parseResponse:zo})}async function tr(e,n){return W({hub:e,path:`/threads?tenantId=${encodeURIComponent(n.tenantId)}`,parseResponse:t=>{let r=Jn(t).threads;return Array.isArray(r)?r:[]}})}async function rr(e,n){return W({hub:e,path:`/threads/${encodeURIComponent(n.chatId)}/messages?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Chat "${n.chatId}" not found`,parseResponse:t=>{let r=Jn(t).messages;return Array.isArray(r)?r:[]}})}import{randomUUID as Ha}from"crypto";var Sa="corsair:client-bridge";function or(e){return new URL(e).origin}function Ve(e){let n=JSON.stringify({type:Sa,requestId:e.requestId,ok:e.ok,body:e.body??null,error:e.error??null}),t=JSON.stringify(or(e.hubOrigin));return`<!DOCTYPE html><html><head><meta charset="utf-8"></head><body><script>
2
2
  (function () {
3
3
  var message = ${n};
4
4
  var targetOrigin = ${t};
@@ -6,17 +6,17 @@ import{a as ve,b as Qt,c as Xt}from"./chunk-4OLKWKJG.js";import{a as Fo,b as Te,
6
6
  window.parent.postMessage(message, targetOrigin);
7
7
  }
8
8
  })();
9
- </script></body></html>`}var _a=new Set(["localhost","127.0.0.1","[::1]","::1"]);function sr(e){try{let{hostname:n,protocol:t}=new URL(e);return t!=="http:"&&t!=="https:"?!1:_a.has(n)}catch{return!1}}function vn(e){return e==="development"?"browser":"server"}function Vo(e){return vn(e)==="browser"}function Yo(e){return sr(e)?"Production delivery URL must be a public URL, not localhost":null}import{randomBytes as Ma}from"crypto";var Ae=60*1e3,Be=300*1e3;import{createHmac as Ea,randomBytes as Da,timingSafeEqual as Oa}from"crypto";function ge(){return Da(16).toString("base64url")}function Tn(e,n){let t=n.trim();if(!t)throw new Error("Signing secret is required");return Ea("sha256",t).update(e).digest("base64url")}function ae(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=Tn(o,t);try{if(!Oa(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 Vn(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=Tn(i,n);return`${i}.${s}`}function Pn(e,n,t){let r=Math.floor(Date.now()/1e3);return Vn(e,n,r+Math.floor(t/1e3))}function Fe(e){return decodeURIComponent(e)}function ar(e){return encodeURIComponent(e).replace(/\./g,"%2E")}function Qo(e){let n=e.trim();return n.length>0?n:null}function Ye(e,n){let t=new URL(e);return t.searchParams.set("d",n),t.toString()}function Qe(e,n){if(!Qo(n))throw new Error("Signing secret is required for browser delivery tokens");let t=Math.floor(Date.now()/1e3),r={...e,jti:e.jti??Ma(16).toString("base64url"),iat:t,exp:t+Math.floor(Ae/1e3)},o=Buffer.from(JSON.stringify(r)).toString("base64url"),i=Tn(o,n);return`${o}.${i}`}function Re(e,n){return Qo(n)?ae(e,n):null}function Ba(e){let n=ir(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 cr(e){let n=Qe(Ba(e),e.signingSecret);return Ye(e.deliveryUrl,n)}function Xo(e){if(vn(e.environmentSlug)==="server")return{transport:"server"};if(!e.hubOrigin)throw new Error(`hubOrigin is required for development ${e.deliveryMode} delivery`);let t=Ha(),r={...e,hubOrigin:e.hubOrigin,requestId:t};return{transport:"browser",requestId:t,deliveryUrl:cr(r)}}var An="https://auth.corsair.dev";var fe=class extends Error{constructor(){super("Hub is not configured. Pass hub: { projectApiKey, signingSecret } to createCorsair()."),this.name="HubNotConfiguredError"}},Rn=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 ur(e){let n=(e.apiUrl?.trim()||An).replace(/\/$/,""),t=e.projectApiKey?.trim()??"",r=e.signingSecret?.trim()??"";if(!t||!r)throw new Rn;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 Yn(e){return ur(e)}function Fa(e){return e.apiUrl.trim().length>0&&e.projectApiKey.trim().length>0&&e.signingSecret.trim().length>0}function F(e){let n=v(e).hub;if(!n||!Fa(n))throw new fe;return n}function ei(e){return e.replace(/\/$/,"")}function Qn(e){return e.oauthCallbackUrl?ei(e.oauthCallbackUrl.trim()):`${ei(e.apiUrl)}/oauth/callback`}function Xe(e){if(e.startsWith("ck_dev_"))return"development";if(e.startsWith("ck_prod_"))return"production";throw new Error("Hub API key must start with ck_dev_ (development) or ck_prod_ (production)")}import{createCipheriv as ni,createDecipheriv as ti,randomBytes as Xn,scrypt as Ua}from"crypto";import{promisify as Na}from"util";var ri=Na(Ua),et="aes-256-gcm",oi=12,nt=16,La=16,Ue=32;function ye(){return Xn(Ue).toString("base64")}async function me(e,n){let t=Xn(La),r=await ri(n,t,Ue),o=Xn(oi),i=ni(et,r,o,{authTagLength:nt}),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 Y(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 ri(n,s,Ue),d=ti(et,u,a,{authTagLength:nt});return d.setAuthTag(c),Buffer.concat([d.update(l),d.final()]).toString("utf8")}function lr(e,n){let t=Buffer.from(n,"base64"),r=Xn(oi),o=ni(et,t,r,{authTagLength:nt}),i=Buffer.concat([o.update(e,"utf8"),o.final()]),s=o.getAuthTag();return[r.toString("base64"),s.toString("base64"),i.toString("base64")].join(":")}function xn(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=ti(et,i,s,{authTagLength:nt});return l.setAuthTag(a),Buffer.concat([l.update(c),l.final()]).toString("utf8")}function xe(e,n){let t={};for(let[r,o]of Object.entries(e))t[r]=lr(o,n);return t}function he(e,n){let t={};for(let[r,o]of Object.entries(e))t[r]=xn(o,n);return t}function In(e,n,t){let r=he(e,n);return xe(r,t)}function ii(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 dr=e=>{if(!e)return{};if(typeof e=="string")try{return JSON.parse(e)}catch{return{}}return e};function U(e){let{authType:n,integrationName:t,kek:r,database:o,extraIntegrationFields:i=[]}=e,s=[...$[n].integration,...i],a=null,c={kek:r,integrationName:t,getIntegration:async()=>{if(a)return a;let k=await o.db.selectFrom("corsair_integrations").selectAll().where("name","=",t).executeTakeFirst();if(!k)throw new Error(`Integration "${t}" not found. Make sure to create the integration first.`);return a={id:k.id,config:dr(k.config),dek:k.dek??null},a},updateIntegration:async k=>{let b=await c.getIntegration();await o.db.updateTable("corsair_integrations").set({...k.config!==void 0?{config:k.config}:{},...k.dek!==void 0?{dek:k.dek}:{},updated_at:new Date}).where("id","=",b.id).execute(),a=null}},l=null,u=async()=>{if(l)return l;let k=await c.getIntegration();if(!k.dek)throw new Error(`No DEK found for integration "${t}". Initialize the integration first.`);return l=await Y(k.dek,r),l},d=async()=>{let k=await c.getIntegration(),b=await u(),C=k.config;return!C||Object.keys(C).length===0?{}:he(C,b)},p=Promise.resolve(),g=k=>{let b=p.then(()=>f(k));return p=b.catch(()=>{}),b},f=async k=>{let b=await u(),C;try{C=await d()}catch(D){console.error(`[corsair] Failed to decrypt config for integration "${t}", starting fresh:`,D),C={}}let P={...C};for(let[D,H]of Object.entries(k))H===null?delete P[D]:P[D]=H;let O=xe(P,b);await c.updateIntegration({config:O})};return{get_dek:u,issue_new_dek:async()=>{let k=await c.getIntegration(),b=ye(),C={};if(k.dek){let O=await Y(k.dek,r),D=k.config;D&&Object.keys(D).length>0&&(C=In(D,O,b))}let P=await me(b,r);return await c.updateIntegration({config:C,dek:P}),l=b,b},...ii(d,g,s)}}function B(e){let{authType:n,integrationName:t,tenantId:r,kek:o,database:i,extraAccountFields:s=[],ensureProvisioned:a}=e,c=[...$[n].account,...s],l=null,u=null,d=async()=>{if(u)return u;let w=!1;for(;;){let A=await i.db.selectFrom("corsair_integrations").selectAll().where("name","=",t).executeTakeFirst();if(!A){if(!w&&a){w=!0,await a();continue}throw new Error(`Integration "${t}" not found. Make sure to create the integration first.`)}return u={id:A.id,config:dr(A.config),dek:A.dek??null},u}},p={kek:o,integrationName:t,tenantId:r,getIntegration:d,getAccount:async()=>{if(l)return l;let w=!1;for(;;){let A=await d(),R=await i.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",r).where("integration_id","=",A.id).executeTakeFirst();if(!R){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 l={id:R.id,config:dr(R.config),dek:R.dek??null},l}},updateAccount:async w=>{let A=await p.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","=",A.id).execute(),l=null}},g=null,f=null,h=async()=>{if(g)return g;let w=await p.getAccount();if(!w.dek)throw new Error(`No DEK found for account (tenant: "${r}", integration: "${t}"). Initialize the account first.`);return g=await Y(w.dek,o),g},k=async()=>{if(f)return f;let w=await p.getIntegration();if(!w.dek)throw new Error(`No DEK found for integration "${t}". Initialize the integration first.`);return f=await Y(w.dek,o),f},b=async()=>{let w=await p.getAccount(),A=await h(),R=w.config;return!R||Object.keys(R).length===0?{}:he(R,A)},C=async()=>{let w=await p.getIntegration(),A=await k(),R=w.config;return!R||Object.keys(R).length===0?{}:he(R,A)},P=Promise.resolve(),O=w=>{let A=P.then(()=>D(w));return P=A.catch(()=>{}),A},D=async w=>{let A=await h(),R;try{R=await b()}catch(_){console.error(`[corsair] Failed to decrypt config for account (tenant: "${r}", integration: "${t}"), starting fresh:`,_),R={}}let J={...R};for(let[_,re]of Object.entries(w))re===null?delete J[_]:J[_]=re;let de=xe(J,A);await p.updateAccount({config:de})},H={get_dek:h,issue_new_dek:async()=>{let w=await p.getAccount(),A=ye(),R={};if(w.dek){let de=await Y(w.dek,o),_=w.config;_&&Object.keys(_).length>0&&(R=In(_,de,A))}let J=await me(A,o);return await p.updateAccount({config:R,dek:J}),g=A,A},...ii(b,O,c)};return n==="oauth_2"&&(H.get_integration_credentials=async()=>{let w=await C();return{...w,client_id:w.client_id||null,client_secret:w.client_secret||null,redirect_url:w.redirect_url??null}}),H}async function si(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=ye(),i=await me(o,t);return await e.db.updateTable("corsair_integrations").set({dek:i,updated_at:new Date}).where("id","=",r.id).execute(),o}async function ai(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=ye(),a=await me(s,r);return await e.db.updateTable("corsair_accounts").set({dek:a,updated_at:new Date}).where("id","=",i.id).execute(),s}var $a=new Set(["webhook_signature","expires_at","scope","redirect_url","refresh_token"]);function Ie(e){return $a.has(e)}function Wa(e,n){return Ie(n)?!1:e==="oauth_2"?n==="client_id"||n==="client_secret":!0}function ja(e){return!Ie(e)}function qa(e){switch(e){case"oauth_2":case"managed":return["access_token"];case"api_key":return["api_key"];case"bot_token":return["bot_token"]}}function Ka(e,n){return e!=="oauth_2"&&e!=="managed"?!1:n.some(t=>t.level==="account"&&t.name==="expires_at"&&t.configured)}function Za(e,n){let t=i=>n.find(s=>s.level==="account"&&s.name===i);if(!qa(e).every(i=>t(i)?.configured))return!1;let o=t("refresh_token");return o?.required?!!o.configured:!0}async function ci(e,n){if(!e)return!1;let t=z(e,`get_${n}`);if(!t)return!1;try{let r=await t();return typeof r=="string"&&r.length>0}catch{return!1}}function Ga(e,n){let r=e.authConfig?.[n]?.integration??[];return[...$[n].integration,...r]}function za(e,n){let r=e.authConfig?.[n]?.account??[];return[...$[n].account,...r]}function Ja(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:Za(n,t),fields:t,missingRequiredFields:r}}async function Ne(e,n,t){let r=I(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=U({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=Ga(n,r),d=za(n,r),p=[];for(let g of u)p.push({name:g,level:"integration",required:Wa(r,g),configured:await ci(c,g)});for(let g of d)p.push({name:g,level:"account",required:ja(g),configured:await ci(l,g)});if(Ka(r,p)){let g=p.find(f=>f.level==="account"&&f.name==="refresh_token");g&&(g.required=!0)}return Ja(n.id,r,p)}async function Sn(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 Ne(e,s,r);a&&i.push(a)}return i}function tt(e){return e.connected?"connected":e.status==="missing_integration"?"missing_credentials":"not_connected"}var ui=Symbol.for("corsair:internal"),li=new WeakMap,di=new WeakMap;function Va(e,n){let t=n.map(r=>r.id).sort().join("\0");return`${e}\0${t}`}function Ya(e){if(e.database){let t=li.get(e.database);return t||(t=new Map,li.set(e.database,t)),t}let n=di.get(e);return n||(n=new Map,di.set(e,n)),n}function Qa(e){return e.multiTenancy?{withTenant:()=>({}),[ui]:e}:{[ui]:e}}async function en(e,n){if(!e.database)return;let t=n.trim()||"default",r=Ya(e),o=Va(t,e.plugins),i=r.get(o);if(i){await i;return}let s=(async()=>{let{setupCorsair:a}=await import("./setup-UE6ZXEGK.js");await a(Qa(e),{tenantId:e.multiTenancy?t:void 0,silent:!0})})().finally(()=>{r.delete(o)});r.set(o,s),await s}import*as _n from"crypto";function Se(e,n){return Buffer.from(JSON.stringify({plugin:e,tenantId:n,iat:Date.now()})).toString("base64url")}function pr(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 nn(e,n){let t=_n.createHmac("sha256",n).update(e).digest("base64url");return`${e}.${t}`}var gr=600*1e3;function rt(e,n){let t=e.lastIndexOf(".");if(t===-1)return null;let r=e.slice(0,t),o=e.slice(t+1),i=_n.createHmac("sha256",n).update(r).digest("base64url"),s=Buffer.from(o,"base64url"),a=Buffer.from(i,"base64url");return s.length!==a.length||!_n.timingSafeEqual(s,a)?null:pr(r,{maxAgeMs:gr})}function pi(e){return{tenantId:e.tenantId,plugin:e.plugin,authType:e.authType??"oauth_2",status:"ready",connected:!0,verified:!0,webhookLink:e.link}}function gi(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 tn(e,n){await x({hub:e,path:"/connections/report",body:pi(n),parseResponse:()=>({ok:!0})}).catch(()=>{})}function Xa(e,n){try{let t=F(e);x({hub:t,path:"/connections/report",body:n,parseResponse:()=>({ok:!0})}).catch(()=>{})}catch(t){if(t instanceof fe)return}}async function ec(e){if(!e.hub||!e.database||!e.kek)return;let n={database:e.database,kek:e.kek,plugins:e.plugins};if(!I(e.plugin))return;let r=e.tenantId?.trim()||"default",o=await Ne(n,e.plugin,r);o&&yi(e.hub,gi({tenantId:r,plugin:e.plugin.id,authType:o.authType,status:o.status,connected:o.connected,verified:e.verified??o.connected,missingFields:o.missingRequiredFields}))}function fi(e,n){Xa(e,n)}function yi(e,n){x({hub:e,path:"/connections/report",body:n,parseResponse:()=>({ok:!0})}).catch(()=>{})}function rn(e){ec(e).catch(()=>{})}async function be(e,n){let t=v(e);if(!I(n.plugin))return;let o=await Ne(t,n.plugin,n.tenantId);o&&fi(e,gi({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 ot(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 mi=e=>{if(!e)return{};if(typeof e=="string")try{return JSON.parse(e)}catch{return{}}return e};async function nc(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 tc(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 Y(n.dek,e.kek),r=mi(n.config),o={};Object.keys(r).length>0&&(o=he(r,t)),o[e.link.linkType]=e.link.externalId;let i=xe(o,t);await e.database.db.updateTable("corsair_accounts").set({config:i,updated_at:new Date}).where("id","=",n.id).execute()}async function on(e){let{database:n,kek:t,pluginId:r,tenantId:o,link:i,authType:s,extraAccountFields:a=[]}=e,{accountId:c}=await nc({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 tc({database:n,kek:t,accountId:c,link:i})}async function fr(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 Y(a.dek,t),u=mi(a.config)[o];if(!u)continue;if(xn(u,c)===i)return a}catch{continue}return null}async function it(e){return(await fr(e))?.tenant_id??null}async function hi(e){return it({database:e.database,kek:e.kek,pluginId:e.pluginId,linkType:e.match.linkType,externalId:e.match.externalId})}import*as bi from"querystring";function Le(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}?${bi.stringify(i)}`}async function ki(e,n){try{return await W({hub:e,path:`/webhooks/endpoint?plugin=${encodeURIComponent(n)}`,parseResponse:t=>t?.url??null})}catch{return null}}async function sn(e,n,t,r){if(!n.subscribe)return;let o=F(e),i=await ki(o,n.id);if(!i)return;let s=await n.subscribe({keys:r},{webhookUrl:i});s&&await be(e,{plugin:n,tenantId:t,verified:!0,webhookLink:s.webhookLink,webhookSecret:s.webhookSecret})}var q=class extends Error{code;constructor(n,t){super(t),this.name="OAuthCallbackError",this.code=n}};function wi(e){let n=e.oauthConfig;if(!n)throw new q("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=ye(),l=await me(c,r),u=new Date;await o.insertInto("corsair_accounts").values({id:ze(),created_at:u,updated_at:u,tenant_id:t,integration_id:s.id,config:{},dek:l}).execute()})}async function yr(e,n,t){let{tenantId:r,redirectUri:o,hubConnect:i=!1}=t,s=v(e,()=>new q("invalid_corsair_instance","Invalid corsair instance"));if(!s.database)throw new Error("No database configured on corsair instance");let a=j(s,n,p=>new q("plugin_not_found",p)),c=wi(a),u=await U({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(Le({oauthConfig:c,clientId:u,redirectUri:o,state:""}));return p.searchParams.delete("state"),{url:p.toString(),state:""}}let d=nn(Se(n,r),s.kek);return{url:Le({oauthConfig:c,clientId:u,redirectUri:o,state:d}),state:d}}function oc(e,n){return{...n??{},...e}}async function En(e,n){let{code:t,state:r,redirectUri:o}=n,i=v(e,()=>new q("invalid_corsair_instance","Invalid corsair instance")),s,a;if(n.trusted){if(!n.plugin||!n.tenantId)throw new q("invalid_state","trusted callback requires plugin and tenantId");s=n.plugin,a=n.tenantId}else{let h=rt(r,i.kek);if(!h)throw new q("invalid_state","Invalid or tampered state parameter");s=h.plugin,a=h.tenantId}if(!i.database)throw new q("no_database","No database configured on corsair instance");let c=j(i,s,h=>new q("plugin_not_found",h)),l=wi(c),u=U({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 q("credentials_not_configured",`Credentials not configured for '${s}'`);await rc(i.database,s,a,i.kek);let g=await st(t,d,p,l,o);if(!g.access_token)throw new q("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 be(e,{plugin:c,tenantId:a}).catch(()=>{});try{let h=oc(g,n.callbackParams),k=await ot(i.plugins,s,h);if(k){try{let b=c.authConfig?.oauth_2?.account??[];await on({database:i.database,kek:i.kek,pluginId:s,tenantId:a,link:k,authType:"oauth_2",extraAccountFields:b})}catch(b){console.warn(`[corsair:oauth] Failed to persist webhook tenant link for '${s}' tenant '${a}':`,b)}i.hub&&tn(i.hub,{plugin:s,tenantId:a,link:k,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 sn(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 ic(e){let{corsair:n,internal:t,rows:r}=e,o=e.subscribeAndReport??sn,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=I(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 Ci(e){let n=v(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 ic({corsair:e,internal:n,rows:t.filter(r=>!!r.tenantId)})}function sc(e,n={}){let t=!1,r=()=>{t||(t=!0,Ci(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 vi(e){if(!v(e).database)throw new Error("A database must be configured to provision Corsair integrations");await at(e,{silent:!0})}async function an(e,n){let t=v(e);if(!t.database)throw new Error("A database must be configured to provision Corsair for connect");await en(t,n)}var ac=Symbol.for("corsair:internal"),cc=new Set(["access_token","refresh_token","expires_at","scope"]);function uc(e){return e==="oauth_2"||e==="managed"?"oauth":e==="bot_token"?"bot_token":"api_key"}function lc(e,n){return e==="oauth_2"||e==="managed"?n.filter(t=>!Ie(t)&&!cc.has(t)):n.filter(t=>!Ie(t))}function Ti(e){return{plugins:e.plugins,database:e.database,kek:e.kek,multiTenancy:e.multiTenancy??!1}}function dc(e){return{plugins:e.plugins,database:e.database,kek:e.kek,multiTenancy:e.multiTenancy??!1}}function pc(e){return{[ac]:Ti(e)}}async function ct(e,n,t={}){let r=Qn(e.hub),o=[],i=t.pluginIds?new Set(t.pluginIds):null,s=Ti(e),a=pc(e);for(let c of e.plugins){if(i&&!i.has(c.id))continue;let l=I(c);if(!l)continue;let u=uc(l),d=t.providerNameOverrides?.[c.id]??Pe(c.id),p=await Ne(s,c,n),g=jn(c,l),f=lc(l,g),h={plugin:c.id,providerName:d,authKind:u,alreadyConfigured:p?.connected??!1};if(f.length>0&&(h.credentialFields=f),u==="oauth"){let b=t.oauthModeOverrides?.[c.id]??(l==="managed"?"managed":"byo");if(h.oauthMode=b,!t.skipOAuthUrlGeneration&&b!=="managed")try{let C=await yr(a,c.id,{tenantId:n,redirectUri:r,hubConnect:!0});h.oauthUrl=C.url}catch(C){C instanceof Error&&/client_id not configured/i.test(C.message)||(h.setupError=C instanceof Error?C.message:`Could not prepare OAuth for ${c.id}`)}}o.push(h)}return o}async function rg(e,n,t={}){let r=v(e),o=r.hub;if(!o)throw new Error("Hub is not configured");return ct({plugins:r.plugins,database:r.database,kek:r.kek,hub:o},n,t)}async function Pi(e,n){if(!e.database)throw new Error("A database must be configured to provision Corsair for connect");await en(e.internalConfig??dc(e),n)}async function Ai(e,n){await an(e,n)}async function Ri(e,n){let t=Xe(e.projectApiKey),r={tenantId:n.tenantId,plugins:n.plugins};return e.redirectURL&&(r.redirectUri=e.redirectURL),t==="development"&&(r.deliveryUrl=ve({deliveryUrl:n.deliveryUrl})),x({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:Kn})}async function xi(e,n){let t={plugins:n.plugins,database:n.database,kek:n.kek,hub:e,multiTenancy:n.multiTenancy};await Pi(t,n.tenantId);let r=await ct(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 Ri(e,{tenantId:n.tenantId,plugins:r,deliveryUrl:n.deliveryUrl})}async function ut(e,n){let t=v(e),r=F(e),o={plugins:t.plugins,database:t.database,kek:t.kek,hub:r,multiTenancy:t.multiTenancy,internalConfig:t};await Ai(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 ct(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 Ri(r,{tenantId:n.tenantId,plugins:c,deliveryUrl:n.deliveryUrl})}async function lt(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=v(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 gc(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 gc(e,n,t){let{buildConnectPluginManifestFromContext:r,ensureConnectAccountRowsFromContext:o}=await import("./setup-introspect-QE6ZJWOF.js"),{postHubConnectSession:i}=await import("./connect-2YTVRI7C.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 cn(e){return!!(e?.baseUrl?.trim()&&e?.redirectUri?.trim())}var Q=class extends Error{code;constructor(n,t){super(t),this.name="ConnectError",this.code=n}};function fc(e){let n=e.oauthConfig;if(!n)throw new Q("plugin_has_no_oauth_config",`Plugin '${e.id}' has no oauthConfig`);return n}async function mr(e,n){let t=v(e,()=>new Q("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new Q("no_database","No database configured on corsair instance");let r=t.manual?.redirectUri;if(!r)throw new Q("no_redirect_uri","No redirectUri configured. Set manual.redirectUri in createCorsair().");let o=rt(n,t.kek);if(!o)throw new Q("invalid_state","Invalid or tampered state parameter");let{plugin:i,tenantId:s}=o,a=j(t,i,p=>new Q("plugin_not_found",p)),c=fc(a),u=await U({authType:"oauth_2",integrationName:i,kek:t.kek,database:t.database}).get_client_id();if(!u)throw new Q("client_id_not_configured",`client_id not configured for '${i}'`);let d=Le({oauthConfig:c,clientId:u,redirectUri:r,state:n});return{plugin:i,tenantId:s,providerName:c.providerName,oauthUrl:d,state:n}}import{AsyncLocalStorage as mc}from"async_hooks";import{randomBytes as hc}from"crypto";import{v4 as bc}from"uuid";async function dt(e,n){let t=Xe(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=ve({deliveryUrl:n.deliveryUrl})),x({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:Gn})}function pt(e){return`Approval required. Visit ${e} to approve or deny, then tell the agent to retry this action.`}var hr="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 kr(e){return e?e.approvalBaseUrl!==void 0||e.onApprovalRequired!==void 0:!1}function Ii(e,n){return`${e.replace(/\/+$/,"")}/${n}`}function br(e){return pt(e)}async function wr(e,n){if(kr(e.manual)){let r=e.manual?.approvalBaseUrl?.trim();return r?Ii(r,n.token):null}let t=e.hub;if(!t)return null;try{return(await dt(t,{permissionId:n.id,permissionToken:n.token,plugin:n.plugin,endpoint:n.endpoint,args:yc(n.args),tenantId:n.tenant_id,expiresAt:n.expires_at})).approvalUrl}catch{return null}}function yc(e){try{return JSON.parse(e)}catch{return e}}async function gt(e,n){if(!(n.status==="pending"||n.status==="approved"))return{...n,approvalUrl:null};let r=await wr(e,n);return{...n,approvalUrl:r}}async function Cr(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 wr({manual:t,hub:r},{id:o,token:i,plugin:s,endpoint:a,args:JSON.stringify(c),tenant_id:l,expires_at:u});return kr(t)?g?t?.onApprovalRequired?t.onApprovalRequired({approvalUrl:g}):br(g):hr:r?g?br(g):`Action '${d}' requires user approval before it can run. Could not create approval link. Check hub configuration and server logs.`:hr}var un=class extends Error{constructor(n){super(n),Object.setPrototypeOf(this,new.target.prototype),this.name="PermissionRequiredError"}};var _i=new mc,ft=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 vr(e){return _i.run(!0,e)}function Ei(){return _i.getStore()===!0}function Tr(e,n){if(Ei()&&n!=="read")throw new ft(e,n)}var kc={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:kc[n][e]}function Pr(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 Di(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 Si(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 Oi(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}'.`,`
9
+ </script></body></html>`}var _a=new Set(["localhost","127.0.0.1","[::1]","::1"]);function ir(e){try{let{hostname:n,protocol:t}=new URL(e);return t!=="http:"&&t!=="https:"?!1:_a.has(n)}catch{return!1}}function vn(e){return e==="development"?"browser":"server"}function Jo(e){return vn(e)==="browser"}function Vo(e){return ir(e)?"Production delivery URL must be a public URL, not localhost":null}import{randomBytes as Ma}from"crypto";var Ae=60*1e3,Be=300*1e3;import{createHmac as Ea,randomBytes as Da,timingSafeEqual as Oa}from"crypto";function ge(){return Da(16).toString("base64url")}function Tn(e,n){let t=n.trim();if(!t)throw new Error("Signing secret is required");return Ea("sha256",t).update(e).digest("base64url")}function ae(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=Tn(o,t);try{if(!Oa(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 Vn(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=Tn(i,n);return`${i}.${s}`}function Pn(e,n,t){let r=Math.floor(Date.now()/1e3);return Vn(e,n,r+Math.floor(t/1e3))}function Fe(e){return decodeURIComponent(e)}function sr(e){return encodeURIComponent(e).replace(/\./g,"%2E")}function Yo(e){let n=e.trim();return n.length>0?n:null}function Ye(e,n){let t=new URL(e);return t.searchParams.set("d",n),t.toString()}function Qe(e,n){if(!Yo(n))throw new Error("Signing secret is required for browser delivery tokens");let t=Math.floor(Date.now()/1e3),r={...e,jti:e.jti??Ma(16).toString("base64url"),iat:t,exp:t+Math.floor(Ae/1e3)},o=Buffer.from(JSON.stringify(r)).toString("base64url"),i=Tn(o,n);return`${o}.${i}`}function Re(e,n){return Yo(n)?ae(e,n):null}function Ba(e){let n=or(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 ar(e){let n=Qe(Ba(e),e.signingSecret);return Ye(e.deliveryUrl,n)}function Qo(e){if(vn(e.environmentSlug)==="server")return{transport:"server"};if(!e.hubOrigin)throw new Error(`hubOrigin is required for development ${e.deliveryMode} delivery`);let t=Ha(),r={...e,hubOrigin:e.hubOrigin,requestId:t};return{transport:"browser",requestId:t,deliveryUrl:ar(r)}}var An="https://auth.corsair.dev";var fe=class extends Error{constructor(){super("Hub is not configured. Pass hub: { projectApiKey, signingSecret } to createCorsair()."),this.name="HubNotConfiguredError"}},Rn=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 cr(e){let n=(e.apiUrl?.trim()||An).replace(/\/$/,""),t=e.projectApiKey?.trim()??"",r=e.signingSecret?.trim()??"";if(!t||!r)throw new Rn;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 Yn(e){return cr(e)}function Fa(e){return e.apiUrl.trim().length>0&&e.projectApiKey.trim().length>0&&e.signingSecret.trim().length>0}function F(e){let n=v(e).hub;if(!n||!Fa(n))throw new fe;return n}function Xo(e){return e.replace(/\/$/,"")}function Qn(e){return e.oauthCallbackUrl?Xo(e.oauthCallbackUrl.trim()):`${Xo(e.apiUrl)}/oauth/callback`}function Xe(e){if(e.startsWith("ck_dev_"))return"development";if(e.startsWith("ck_prod_"))return"production";throw new Error("Hub API key must start with ck_dev_ (development) or ck_prod_ (production)")}import{createCipheriv as ei,createDecipheriv as ni,randomBytes as Xn,scrypt as Ua}from"crypto";import{promisify as Na}from"util";var ti=Na(Ua),et="aes-256-gcm",ri=12,nt=16,La=16,Ue=32;function ye(){return Xn(Ue).toString("base64")}async function me(e,n){let t=Xn(La),r=await ti(n,t,Ue),o=Xn(ri),i=ei(et,r,o,{authTagLength:nt}),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 Y(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 ti(n,s,Ue),d=ni(et,u,a,{authTagLength:nt});return d.setAuthTag(c),Buffer.concat([d.update(l),d.final()]).toString("utf8")}function ur(e,n){let t=Buffer.from(n,"base64"),r=Xn(ri),o=ei(et,t,r,{authTagLength:nt}),i=Buffer.concat([o.update(e,"utf8"),o.final()]),s=o.getAuthTag();return[r.toString("base64"),s.toString("base64"),i.toString("base64")].join(":")}function xn(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=ni(et,i,s,{authTagLength:nt});return l.setAuthTag(a),Buffer.concat([l.update(c),l.final()]).toString("utf8")}function xe(e,n){let t={};for(let[r,o]of Object.entries(e))t[r]=ur(o,n);return t}function he(e,n){let t={};for(let[r,o]of Object.entries(e))t[r]=xn(o,n);return t}function In(e,n,t){let r=he(e,n);return xe(r,t)}function oi(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 lr=e=>{if(!e)return{};if(typeof e=="string")try{return JSON.parse(e)}catch{return{}}return e};function U(e){let{authType:n,integrationName:t,kek:r,database:o,extraIntegrationFields:i=[]}=e,s=[...$[n].integration,...i],a=null,c={kek:r,integrationName:t,getIntegration:async()=>{if(a)return a;let k=await o.db.selectFrom("corsair_integrations").selectAll().where("name","=",t).executeTakeFirst();if(!k)throw new Error(`Integration "${t}" not found. Make sure to create the integration first.`);return a={id:k.id,config:lr(k.config),dek:k.dek??null},a},updateIntegration:async k=>{let b=await c.getIntegration();await o.db.updateTable("corsair_integrations").set({...k.config!==void 0?{config:k.config}:{},...k.dek!==void 0?{dek:k.dek}:{},updated_at:new Date}).where("id","=",b.id).execute(),a=null}},l=null,u=async()=>{if(l)return l;let k=await c.getIntegration();if(!k.dek)throw new Error(`No DEK found for integration "${t}". Initialize the integration first.`);return l=await Y(k.dek,r),l},d=async()=>{let k=await c.getIntegration(),b=await u(),C=k.config;return!C||Object.keys(C).length===0?{}:he(C,b)},p=Promise.resolve(),g=k=>{let b=p.then(()=>f(k));return p=b.catch(()=>{}),b},f=async k=>{let b=await u(),C;try{C=await d()}catch(D){console.error(`[corsair] Failed to decrypt config for integration "${t}", starting fresh:`,D),C={}}let P={...C};for(let[D,H]of Object.entries(k))H===null?delete P[D]:P[D]=H;let O=xe(P,b);await c.updateIntegration({config:O})};return{get_dek:u,issue_new_dek:async()=>{let k=await c.getIntegration(),b=ye(),C={};if(k.dek){let O=await Y(k.dek,r),D=k.config;D&&Object.keys(D).length>0&&(C=In(D,O,b))}let P=await me(b,r);return await c.updateIntegration({config:C,dek:P}),l=b,b},...oi(d,g,s)}}function B(e){let{authType:n,integrationName:t,tenantId:r,kek:o,database:i,extraAccountFields:s=[],ensureProvisioned:a}=e,c=[...$[n].account,...s],l=null,u=null,d=async()=>{if(u)return u;let w=!1;for(;;){let A=await i.db.selectFrom("corsair_integrations").selectAll().where("name","=",t).executeTakeFirst();if(!A){if(!w&&a){w=!0,await a();continue}throw new Error(`Integration "${t}" not found. Make sure to create the integration first.`)}return u={id:A.id,config:lr(A.config),dek:A.dek??null},u}},p={kek:o,integrationName:t,tenantId:r,getIntegration:d,getAccount:async()=>{if(l)return l;let w=!1;for(;;){let A=await d(),R=await i.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",r).where("integration_id","=",A.id).executeTakeFirst();if(!R){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 l={id:R.id,config:lr(R.config),dek:R.dek??null},l}},updateAccount:async w=>{let A=await p.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","=",A.id).execute(),l=null}},g=null,f=null,h=async()=>{if(g)return g;let w=await p.getAccount();if(!w.dek)throw new Error(`No DEK found for account (tenant: "${r}", integration: "${t}"). Initialize the account first.`);return g=await Y(w.dek,o),g},k=async()=>{if(f)return f;let w=await p.getIntegration();if(!w.dek)throw new Error(`No DEK found for integration "${t}". Initialize the integration first.`);return f=await Y(w.dek,o),f},b=async()=>{let w=await p.getAccount(),A=await h(),R=w.config;return!R||Object.keys(R).length===0?{}:he(R,A)},C=async()=>{let w=await p.getIntegration(),A=await k(),R=w.config;return!R||Object.keys(R).length===0?{}:he(R,A)},P=Promise.resolve(),O=w=>{let A=P.then(()=>D(w));return P=A.catch(()=>{}),A},D=async w=>{let A=await h(),R;try{R=await b()}catch(_){console.error(`[corsair] Failed to decrypt config for account (tenant: "${r}", integration: "${t}"), starting fresh:`,_),R={}}let J={...R};for(let[_,re]of Object.entries(w))re===null?delete J[_]:J[_]=re;let de=xe(J,A);await p.updateAccount({config:de})},H={get_dek:h,issue_new_dek:async()=>{let w=await p.getAccount(),A=ye(),R={};if(w.dek){let de=await Y(w.dek,o),_=w.config;_&&Object.keys(_).length>0&&(R=In(_,de,A))}let J=await me(A,o);return await p.updateAccount({config:R,dek:J}),g=A,A},...oi(b,O,c)};return n==="oauth_2"&&(H.get_integration_credentials=async()=>{let w=await C();return{...w,client_id:w.client_id||null,client_secret:w.client_secret||null,redirect_url:w.redirect_url??null}}),H}async function ii(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=ye(),i=await me(o,t);return await e.db.updateTable("corsair_integrations").set({dek:i,updated_at:new Date}).where("id","=",r.id).execute(),o}async function si(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=ye(),a=await me(s,r);return await e.db.updateTable("corsair_accounts").set({dek:a,updated_at:new Date}).where("id","=",i.id).execute(),s}var $a=new Set(["webhook_signature","expires_at","scope","redirect_url","refresh_token"]);function Ie(e){return $a.has(e)}function Wa(e,n){return Ie(n)?!1:e==="oauth_2"?n==="client_id"||n==="client_secret":!0}function ja(e){return!Ie(e)}function qa(e){switch(e){case"oauth_2":case"managed":return["access_token"];case"api_key":return["api_key"];case"bot_token":return["bot_token"]}}function Ka(e,n){return e!=="oauth_2"&&e!=="managed"?!1:n.some(t=>t.level==="account"&&t.name==="expires_at"&&t.configured)}function Za(e,n){let t=i=>n.find(s=>s.level==="account"&&s.name===i);if(!qa(e).every(i=>t(i)?.configured))return!1;let o=t("refresh_token");return o?.required?!!o.configured:!0}async function ai(e,n){if(!e)return!1;let t=z(e,`get_${n}`);if(!t)return!1;try{let r=await t();return typeof r=="string"&&r.length>0}catch{return!1}}function Ga(e,n){let r=e.authConfig?.[n]?.integration??[];return[...$[n].integration,...r]}function za(e,n){let r=e.authConfig?.[n]?.account??[];return[...$[n].account,...r]}function Ja(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:Za(n,t),fields:t,missingRequiredFields:r}}async function Ne(e,n,t){let r=I(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=U({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=Ga(n,r),d=za(n,r),p=[];for(let g of u)p.push({name:g,level:"integration",required:Wa(r,g),configured:await ai(c,g)});for(let g of d)p.push({name:g,level:"account",required:ja(g),configured:await ai(l,g)});if(Ka(r,p)){let g=p.find(f=>f.level==="account"&&f.name==="refresh_token");g&&(g.required=!0)}return Ja(n.id,r,p)}async function Sn(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 Ne(e,s,r);a&&i.push(a)}return i}function tt(e){return e.connected?"connected":e.status==="missing_integration"?"missing_credentials":"not_connected"}var ci=Symbol.for("corsair:internal"),ui=new WeakMap,li=new WeakMap;function Va(e,n){let t=n.map(r=>r.id).sort().join("\0");return`${e}\0${t}`}function Ya(e){if(e.database){let t=ui.get(e.database);return t||(t=new Map,ui.set(e.database,t)),t}let n=li.get(e);return n||(n=new Map,li.set(e,n)),n}function Qa(e){return e.multiTenancy?{withTenant:()=>({}),[ci]:e}:{[ci]:e}}async function en(e,n){if(!e.database)return;let t=n.trim()||"default",r=Ya(e),o=Va(t,e.plugins),i=r.get(o);if(i){await i;return}let s=(async()=>{let{setupCorsair:a}=await import("./setup-PXJ3S3RO.js");await a(Qa(e),{tenantId:e.multiTenancy?t:void 0,silent:!0})})().finally(()=>{r.delete(o)});r.set(o,s),await s}import*as _n from"crypto";function Se(e,n){return Buffer.from(JSON.stringify({plugin:e,tenantId:n,iat:Date.now()})).toString("base64url")}function dr(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 nn(e,n){let t=_n.createHmac("sha256",n).update(e).digest("base64url");return`${e}.${t}`}var pr=600*1e3;function rt(e,n){let t=e.lastIndexOf(".");if(t===-1)return null;let r=e.slice(0,t),o=e.slice(t+1),i=_n.createHmac("sha256",n).update(r).digest("base64url"),s=Buffer.from(o,"base64url"),a=Buffer.from(i,"base64url");return s.length!==a.length||!_n.timingSafeEqual(s,a)?null:dr(r,{maxAgeMs:pr})}function di(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 tn(e,n){await x({hub:e,path:"/connections/report",body:di(n),parseResponse:()=>({ok:!0})}).catch(()=>{})}function Xa(e,n){try{let t=F(e);x({hub:t,path:"/connections/report",body:n,parseResponse:()=>({ok:!0})}).catch(()=>{})}catch(t){if(t instanceof fe)return}}async function ec(e){if(!e.hub||!e.database||!e.kek)return;let n={database:e.database,kek:e.kek,plugins:e.plugins};if(!I(e.plugin))return;let r=e.tenantId?.trim()||"default",o=await Ne(n,e.plugin,r);o&&fi(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 gi(e,n){Xa(e,n)}function fi(e,n){x({hub:e,path:"/connections/report",body:n,parseResponse:()=>({ok:!0})}).catch(()=>{})}function rn(e){ec(e).catch(()=>{})}async function be(e,n){let t=v(e);if(!I(n.plugin))return;let o=await Ne(t,n.plugin,n.tenantId);o&&gi(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 ot(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 yi=e=>{if(!e)return{};if(typeof e=="string")try{return JSON.parse(e)}catch{return{}}return e};async function nc(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 tc(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 Y(n.dek,e.kek),r=yi(n.config),o={};Object.keys(r).length>0&&(o=he(r,t)),o[e.link.linkType]=e.link.externalId;let i=xe(o,t);await e.database.db.updateTable("corsair_accounts").set({config:i,updated_at:new Date}).where("id","=",n.id).execute()}async function on(e){let{database:n,kek:t,pluginId:r,tenantId:o,link:i,authType:s,extraAccountFields:a=[]}=e,{accountId:c}=await nc({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 tc({database:n,kek:t,accountId:c,link:i})}async function gr(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 Y(a.dek,t),u=yi(a.config)[o];if(!u)continue;if(xn(u,c)===i)return a}catch{continue}return null}async function it(e){return(await gr(e))?.tenant_id??null}async function mi(e){return it({database:e.database,kek:e.kek,pluginId:e.pluginId,linkType:e.match.linkType,externalId:e.match.externalId})}import*as hi from"querystring";function Le(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}?${hi.stringify(i)}`}async function bi(e,n){try{return await W({hub:e,path:`/webhooks/endpoint?plugin=${encodeURIComponent(n)}`,parseResponse:t=>t?.url??null})}catch{return null}}async function sn(e,n,t,r){if(!n.subscribe)return;let o=F(e),i=await bi(o,n.id);if(!i)return;let s=await n.subscribe({keys:r},{webhookUrl:i});s&&await be(e,{plugin:n,tenantId:t,verified:!0,webhookLink:s.webhookLink,webhookSecret:s.webhookSecret})}var q=class extends Error{code;constructor(n,t){super(t),this.name="OAuthCallbackError",this.code=n}};function ki(e){let n=e.oauthConfig;if(!n)throw new q("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=ye(),l=await me(c,r),u=new Date;await o.insertInto("corsair_accounts").values({id:ze(),created_at:u,updated_at:u,tenant_id:t,integration_id:s.id,config:{},dek:l}).execute()})}async function fr(e,n,t){let{tenantId:r,redirectUri:o,hubConnect:i=!1}=t,s=v(e,()=>new q("invalid_corsair_instance","Invalid corsair instance"));if(!s.database)throw new Error("No database configured on corsair instance");let a=j(s,n,p=>new q("plugin_not_found",p)),c=ki(a),u=await U({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(Le({oauthConfig:c,clientId:u,redirectUri:o,state:""}));return p.searchParams.delete("state"),{url:p.toString(),state:""}}let d=nn(Se(n,r),s.kek);return{url:Le({oauthConfig:c,clientId:u,redirectUri:o,state:d}),state:d}}function oc(e,n){return{...n??{},...e}}async function En(e,n){let{code:t,state:r,redirectUri:o}=n,i=v(e,()=>new q("invalid_corsair_instance","Invalid corsair instance")),s,a;if(n.trusted){if(!n.plugin||!n.tenantId)throw new q("invalid_state","trusted callback requires plugin and tenantId");s=n.plugin,a=n.tenantId}else{let h=rt(r,i.kek);if(!h)throw new q("invalid_state","Invalid or tampered state parameter");s=h.plugin,a=h.tenantId}if(!i.database)throw new q("no_database","No database configured on corsair instance");let c=j(i,s,h=>new q("plugin_not_found",h)),l=ki(c),u=U({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 q("credentials_not_configured",`Credentials not configured for '${s}'`);await rc(i.database,s,a,i.kek);let g=await st(t,d,p,l,o);if(!g.access_token)throw new q("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 be(e,{plugin:c,tenantId:a}).catch(()=>{});try{let h=oc(g,n.callbackParams),k=await ot(i.plugins,s,h);if(k){try{let b=c.authConfig?.oauth_2?.account??[];await on({database:i.database,kek:i.kek,pluginId:s,tenantId:a,link:k,authType:"oauth_2",extraAccountFields:b})}catch(b){console.warn(`[corsair:oauth] Failed to persist webhook tenant link for '${s}' tenant '${a}':`,b)}i.hub&&tn(i.hub,{plugin:s,tenantId:a,link:k,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 sn(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 ic(e){let{corsair:n,internal:t,rows:r}=e,o=e.subscribeAndReport??sn,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=I(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 wi(e){let n=v(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 ic({corsair:e,internal:n,rows:t.filter(r=>!!r.tenantId)})}function sc(e,n={}){let t=!1,r=()=>{t||(t=!0,wi(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 Ci(e){if(!v(e).database)throw new Error("A database must be configured to provision Corsair integrations");await at(e,{silent:!0})}async function an(e,n){let t=v(e);if(!t.database)throw new Error("A database must be configured to provision Corsair for connect");await en(t,n)}var ac=Symbol.for("corsair:internal"),cc=new Set(["access_token","refresh_token","expires_at","scope"]);function uc(e){return e==="oauth_2"||e==="managed"?"oauth":e==="bot_token"?"bot_token":"api_key"}function lc(e,n){return e==="oauth_2"||e==="managed"?n.filter(t=>!Ie(t)&&!cc.has(t)):n.filter(t=>!Ie(t))}function vi(e){return{plugins:e.plugins,database:e.database,kek:e.kek,multiTenancy:e.multiTenancy??!1}}function dc(e){return{plugins:e.plugins,database:e.database,kek:e.kek,multiTenancy:e.multiTenancy??!1}}function pc(e){return{[ac]:vi(e)}}async function ct(e,n,t={}){let r=Qn(e.hub),o=[],i=t.pluginIds?new Set(t.pluginIds):null,s=vi(e),a=pc(e);for(let c of e.plugins){if(i&&!i.has(c.id))continue;let l=I(c);if(!l)continue;let u=uc(l),d=t.providerNameOverrides?.[c.id]??Pe(c.id),p=await Ne(s,c,n),g=jn(c,l),f=lc(l,g),h={plugin:c.id,providerName:d,authKind:u,alreadyConfigured:p?.connected??!1};if(f.length>0&&(h.credentialFields=f),u==="oauth"){let b=t.oauthModeOverrides?.[c.id]??(l==="managed"?"managed":"byo");if(h.oauthMode=b,!t.skipOAuthUrlGeneration&&b!=="managed")try{let C=await fr(a,c.id,{tenantId:n,redirectUri:r,hubConnect:!0});h.oauthUrl=C.url}catch(C){C instanceof Error&&/client_id not configured/i.test(C.message)||(h.setupError=C instanceof Error?C.message:`Could not prepare OAuth for ${c.id}`)}}o.push(h)}return o}async function ag(e,n,t={}){let r=v(e),o=r.hub;if(!o)throw new Error("Hub is not configured");return ct({plugins:r.plugins,database:r.database,kek:r.kek,hub:o},n,t)}async function Ti(e,n){if(!e.database)throw new Error("A database must be configured to provision Corsair for connect");await en(e.internalConfig??dc(e),n)}async function Pi(e,n){await an(e,n)}async function Ai(e,n){let t=Xe(e.projectApiKey),r={tenantId:n.tenantId,plugins:n.plugins};return e.redirectURL&&(r.redirectUri=e.redirectURL),t==="development"&&(r.deliveryUrl=ve({deliveryUrl:n.deliveryUrl})),x({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:Kn})}async function Ri(e,n){let t={plugins:n.plugins,database:n.database,kek:n.kek,hub:e,multiTenancy:n.multiTenancy};await Ti(t,n.tenantId);let r=await ct(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 Ai(e,{tenantId:n.tenantId,plugins:r,deliveryUrl:n.deliveryUrl})}async function ut(e,n){let t=v(e),r=F(e),o={plugins:t.plugins,database:t.database,kek:t.kek,hub:r,multiTenancy:t.multiTenancy,internalConfig:t};await Pi(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 ct(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 Ai(r,{tenantId:n.tenantId,plugins:c,deliveryUrl:n.deliveryUrl})}async function lt(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=v(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 gc(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 gc(e,n,t){let{buildConnectPluginManifestFromContext:r,ensureConnectAccountRowsFromContext:o}=await import("./setup-introspect-J77AZVKF.js"),{postHubConnectSession:i}=await import("./connect-BM3VAVNP.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 cn(e){return!!(e?.baseUrl?.trim()&&e?.redirectUri?.trim())}var Q=class extends Error{code;constructor(n,t){super(t),this.name="ConnectError",this.code=n}};function fc(e){let n=e.oauthConfig;if(!n)throw new Q("plugin_has_no_oauth_config",`Plugin '${e.id}' has no oauthConfig`);return n}async function yr(e,n){let t=v(e,()=>new Q("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new Q("no_database","No database configured on corsair instance");let r=t.manual?.redirectUri;if(!r)throw new Q("no_redirect_uri","No redirectUri configured. Set manual.redirectUri in createCorsair().");let o=rt(n,t.kek);if(!o)throw new Q("invalid_state","Invalid or tampered state parameter");let{plugin:i,tenantId:s}=o,a=j(t,i,p=>new Q("plugin_not_found",p)),c=fc(a),u=await U({authType:"oauth_2",integrationName:i,kek:t.kek,database:t.database}).get_client_id();if(!u)throw new Q("client_id_not_configured",`client_id not configured for '${i}'`);let d=Le({oauthConfig:c,clientId:u,redirectUri:r,state:n});return{plugin:i,tenantId:s,providerName:c.providerName,oauthUrl:d,state:n}}import{AsyncLocalStorage as mc}from"async_hooks";import{randomBytes as hc}from"crypto";import{v4 as bc}from"uuid";async function dt(e,n){let t=Xe(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=ve({deliveryUrl:n.deliveryUrl})),x({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:Gn})}function pt(e){return`Approval required. Visit ${e} to approve or deny, then tell the agent to retry this action.`}var mr="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 br(e){return e?e.approvalBaseUrl!==void 0||e.onApprovalRequired!==void 0:!1}function xi(e,n){return`${e.replace(/\/+$/,"")}/${n}`}function hr(e){return pt(e)}async function kr(e,n){if(br(e.manual)){let r=e.manual?.approvalBaseUrl?.trim();return r?xi(r,n.token):null}let t=e.hub;if(!t)return null;try{return(await dt(t,{permissionId:n.id,permissionToken:n.token,plugin:n.plugin,endpoint:n.endpoint,args:yc(n.args),tenantId:n.tenant_id,expiresAt:n.expires_at})).approvalUrl}catch{return null}}function yc(e){try{return JSON.parse(e)}catch{return e}}async function gt(e,n){if(!(n.status==="pending"||n.status==="approved"))return{...n,approvalUrl:null};let r=await kr(e,n);return{...n,approvalUrl:r}}async function wr(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 kr({manual:t,hub:r},{id:o,token:i,plugin:s,endpoint:a,args:JSON.stringify(c),tenant_id:l,expires_at:u});return br(t)?g?t?.onApprovalRequired?t.onApprovalRequired({approvalUrl:g}):hr(g):mr:r?g?hr(g):`Action '${d}' requires user approval before it can run. Could not create approval link. Check hub configuration and server logs.`:mr}var un=class extends Error{constructor(n){super(n),Object.setPrototypeOf(this,new.target.prototype),this.name="PermissionRequiredError"}};var Si=new mc,ft=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 Cr(e){return Si.run(!0,e)}function _i(){return Si.getStore()===!0}function vr(e,n){if(_i()&&n!=="read")throw new ft(e,n)}var kc={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:kc[n][e]}function Tr(e){let n=/(\d+)(d|h|m|s)/g,t=0,r;for(;(r=n.exec(e))!==null;){let o=parseInt(r[1],10);switch(r[2]){case"d":t+=o*864e5;break;case"h":t+=o*36e5;break;case"m":t+=o*6e4;break;case"s":t+=o*1e3;break}}return t>0?t:600*1e3}function Ei(e){return{async find_by_permission_id(n){if(e)return e.db.selectFrom("corsair_permissions").selectAll().where("id","=",n).executeTakeFirst()},async find_by_token(n){if(e)return e.db.selectFrom("corsair_permissions").selectAll().where("token","=",n).executeTakeFirst()},async set_executing(n){e&&await e.db.updateTable("corsair_permissions").set({status:"executing",updated_at:new Date}).where("id","=",n).execute()},async set_completed(n){e&&await e.db.updateTable("corsair_permissions").set({status:"completed",updated_at:new Date}).where("id","=",n).execute()}}}async function Ii(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 Di(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
10
  Action: ${r}`,`
11
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
12
  Action: ${r}`,`
13
13
  Permission ID: ${a.id}`,`
14
- Use the token to approve or deny this request.`),(typeof e.approvalMode=="function"?e.approvalMode():e.approvalMode)==="synchronous"?Si(e.db,a.id,e.timeoutMs??600*1e3):{result:"blocked",reason:"pending",id:a.id,token:a.token,expiresAt:a.expires_at})}let c=bc(),l=hc(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.`,`
14
+ Use the token to approve or deny this request.`),(typeof e.approvalMode=="function"?e.approvalMode():e.approvalMode)==="synchronous"?Ii(e.db,a.id,e.timeoutMs??600*1e3):{result:"blocked",reason:"pending",id:a.id,token:a.token,expiresAt:a.expires_at})}let c=bc(),l=hc(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
15
  Action: ${r}`,`
16
16
  Permission ID: ${c}`,`
17
17
  Permission token: ${l}`,`
18
18
  Expires at: ${d}`,`
19
- Use the token to approve or deny this request.`),(typeof e.approvalMode=="function"?e.approvalMode():e.approvalMode)==="synchronous"?Si(e.db,c,u):{result:"blocked",reason:"pending",id:c,token:l,expiresAt:d}}var T=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 S(e,n,t){return new Response(JSON.stringify(n),{status:e,headers:{"content-type":"application/json",...t}})}function ce(e){let n={error:e.code,message:e.message,...e.extra};return S(e.status,n)}function _e(e){return new T(404,"not_found",e)}function X(e,n={}){return new T(400,"bad_request",e,n)}function Ar(e,n){return j(e,n,t=>_e(t))}async function Mi(e,n){let t=e.options?.authType;if(!t||!n.database||!n.kek)return{configured:!1,missingFields:[]};let r=U({authType:t,integrationName:e.id,kek:n.kek,database:n.database}),o=$[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 Hi(e,n){let t=e.options?.authType??null,r=e.oauthConfig,{configured:o,missingFields:i}=await Mi(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 yt(){return{ok:!0}}async function ln(e){return Promise.all(e.plugins.map(n=>Hi(n,e)))}async function mt(e,n){let t=Ar(e,n);return Hi(t,e)}async function Cc(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 Bi(e,n){let t=await Cc(e,n),r=t.filter(o=>o.hasCredentials).map(o=>o.integrationName);return{id:n,accounts:t,connectedPlugins:r}}async function dn(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 ht(e,n){if(!n)throw X("Tenant id must be a non-empty string");return Bi(e,n)}async function bt(e,n){let t=n?.id?.trim();if(!t)throw X("Tenant id is required",{missingFields:["id"]});return Bi(e,t)}async function kt(e,n){let t=n?.trim()||"default",r={},o=await Sn(e,t);for(let i of o)r[i.plugin]=tt(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 wt(e,n){let t=n?.plugin;if(typeof t!="string"||!t.trim())throw X("plugin is required",{missingFields:["plugin"]});let r=t.trim();Ar(e,r);let o=n?.tenantId;if(o!=null&&typeof o!="string")throw X("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 Rr(e,n){if(!e.database)throw _e(`Permission '${n}' not found`);let t=await e.database.db.selectFrom("corsair_permissions").selectAll().where("id","=",n).executeTakeFirst();if(!t)throw _e(`Permission '${n}' not found`);return gt(e,t)}function vc(e){if(!e.oauthConfig)throw X(`Plugin '${e.id}' has no oauthConfig`)}function Tc(e){if(!e.manual)throw new T(500,"connect_not_configured","createCorsair was not given manual config. Set { manual: { baseUrl, redirectUri } } to enable manual connect routes.");return e.manual}function xr(e){let n=Tc(e);if(!n.baseUrl?.trim()||!n.redirectUri?.trim())throw new T(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 Pc(e){let n=!!e.hub,t=cn(e.manual);if(!n&&!t)throw new T(500,"connect_not_configured","createCorsair was not given connect config. Set hub: { ... } for Hub mode, or manual: { baseUrl, redirectUri } for manual connect.")}function Fi(e){if(!e.database||!e.kek)throw new T(500,"database_not_configured","A database and kek are required to issue connect links.")}async function Ac(e,n){let t=n?.plugin?.trim();if(!t)throw X("Plugin id is required",{missingFields:["plugin"]});let r=n.tenantId?.trim()||"default",o=Ar(e,t);vc(o);let i=xr(e);Fi(e);let s=await Mi(o,e);if(!s.configured)throw new T(400,"missing_credentials",`Plugin '${t}' is missing OAuth client credentials`,{missingFields:s.missingFields});let a=nn(Se(t,r),e.kek),c;try{c=new URL(i.baseUrl)}catch{throw new T(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()+gr).toISOString(),tenantId:r}}async function Rc(e,n,t){Fi(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 ut(e,o);return{connectUrl:a.connectUrl,expiresAt:a.expiresAt,tenantId:r}}async function Ct(e,n,t){return Pc(n),n.hub?Rc(e,n,t):Ac(n,t)}async function vt(e,n,t){if(n.hub&&!cn(n.manual))throw new T(400,"hub_mode","resolve is not used with hub config. Redirect users to connectUrl from createLink.");let r=t?.trim();if(!r)throw X("state is required",{missingFields:["state"]});xr(n);try{return await mr(e,r)}catch(o){if(o instanceof Q)switch(o.code){case"invalid_state":throw X("Invalid or expired state");case"client_id_not_configured":throw new T(400,"missing_credentials","OAuth client_id is not configured for this plugin",{missingFields:["client_id"]});case"no_redirect_uri":break}throw new T(500,"resolve_failed","Could not resolve connect link. Check server logs for details.")}}async function Tt(e,n,t){if(n.hub&&!cn(n.manual))throw new T(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 X("Missing required fields",{missingFields:i});let s=xr(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 X("Invalid or expired state");case"credentials_not_configured":throw new T(400,"missing_credentials","OAuth client credentials are not configured for this plugin",{missingFields:["client_id","client_secret"]})}throw new T(502,"oauth_callback_failed","OAuth callback did not complete. Check server logs for details.")}}async function Ir(e,n){if(!e.database)throw _e("Permission not found");let t=await e.database.db.selectFrom("corsair_permissions").selectAll().where("token","=",n).executeTakeFirst();if(!t)throw _e("Permission not found");return gt(e,t)}async function Ui(e,n){return"id"in n?Rr(e,n.id):Ir(e,n.token)}import{createCipheriv as Oc,createDecipheriv as uf,randomBytes as Wi,scryptSync as Mc}from"crypto";import{createHmac as Sr,randomUUID as xc,timingSafeEqual as Li}from"crypto";function _r(e){return e.run??null}function Er(e){return e.probe??null}function $i(e){if(e)return e.startsWith("sha256=")?e.slice(7):e}function Pt(e){let n=JSON.stringify({type:e.type,payload:e.payload}),t=Math.floor(Date.now()/1e3).toString(),r=Sr("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":xc()}}}function Dr(e){let n=e.signingSecret.trim();if(!n)return!1;let t=$i(e.signatureHeader);if(!t)return!1;let r=Number(e.timestampHeader);if(!Number.isFinite(r)||Math.abs(Date.now()-r*1e3)>Be)return!1;let i=Sr("sha256",n).update(e.body).digest("hex");try{return Li(Buffer.from(i,"utf8"),Buffer.from(t,"utf8"))}catch{return!1}}function pn(e){let n=e.signingSecret.trim();if(!n)return{ok:!1,error:"Tunnel signing secret is required"};let t=$i(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)>Be)return{ok:!1,error:"Tunnel request timestamp is outside the allowed window"};let i=Sr("sha256",n).update(e.body).digest("hex");try{if(!Li(Buffer.from(i,"utf8"),Buffer.from(t,"utf8")))return{ok:!1,error:"Invalid tunnel signature"}}catch{return{ok:!1,error:"Invalid tunnel signature"}}return{ok:!0}}function gn(e){if(!e)return{};try{return JSON.parse(e)}catch{return{}}}function At(e){return e.httpOk&&(e.status===204||e.body.status==="ok"||e.body.ok===!0)}function Rt(e){let n=e.sync?.encrypted;return typeof n!="string"||!n.trim()?null:{encrypted:n.trim()}}function Dn(e){let n=e.connectUrl?.trim();return n?{connectUrl:n,expiresAt:e.expiresAt}:null}function Or(e){return Dn(gn(e))}async function Mr(e){let n=await St({deliveryUrl:e.deliveryUrl,projectId:e.projectId,signingSecret:e.signingSecret,type:"connect.create_link",payload:{tenantId:e.tenantId,plugins:e.plugins}}),t=gn(n.body),r=At({httpOk:n.ok,status:n.status,body:t}),o=Dn(t);if(!r||!o)throw new Error(It({deliveryUrl:e.deliveryUrl,status:n.status,body:n.body,ack:t}));return o}function xt(e){return Rt(gn(e))}function Ic(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 Ni(e,n=200){let t=e.trim();return t.length<=n?t:`${t.slice(0,n)}\u2026`}var Sc="Verify hub.signingSecret in your app matches the signing secret shown in Hub project settings.",_c="Check the delivery URL configured for this environment.";function Ec(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})`}. ${Sc}`}function Dc(e){return`${e.ack.error?`${e.ack.error} (HTTP 404 from ${e.deliveryUrl})`:`Delivery endpoint not found at ${e.deliveryUrl} (HTTP 404)`}. ${_c}`}function On(e,n){let t=Ic(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 It(e){if(e.status===0)return e.ack.error?e.ack.error:e.body.startsWith("Could not reach")?e.body:On(e.deliveryUrl,new Error(e.body||"Delivery request failed"));if(e.status===401||e.status===403)return Ec(e);if(e.status===404)return Dc(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}): ${Ni(t)}`:`App failed while processing the delivery (HTTP ${e.status} from ${e.deliveryUrl})`}let n=e.body.trim();return n?`${Ni(n)} (HTTP ${e.status} from ${e.deliveryUrl})`:`Delivery failed with HTTP ${e.status} from ${e.deliveryUrl}`}async function St(e){let{body:n,headers:t}=Pt(e);try{let r=await fetch(e.deliveryUrl,{method:"POST",headers:t,body:n}),o=await r.text();return{ok:r.ok,status:r.status,body:o}}catch(r){return{ok:!1,status:0,body:On(e.deliveryUrl,r)}}}var Hc="aes-256-gcm",Bc=12,Fc=16,Uc=16,Nc=32;function Lc(e,n){return Mc(e.trim(),n,Nc)}function Hr(e,n){let t=n.trim();if(!t)throw new Error("Signing secret is required to encrypt sync manifest");let r=Wi(Uc),o=Lc(t,r),i=Wi(Bc),s=Oc(Hc,o,i,{authTagLength:Fc}),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 $c=["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 Br(e){if(e instanceof Fo)return!1;if(!(e instanceof Error))return!0;let n=e.message.toLowerCase();return!$c.some(t=>n.includes(t))}function Wc(e){if(!e)return[];let n=I(e);return n?(e.authConfig?.[n]?.integration??[]).filter(r=>!Ie(r)):[]}async function Mn(e,n){let t=v(e);if(!t.database)throw new Error("A database must be configured to sync connections from the app");await at(e,{silent:!0});let[r,o]=await Promise.all([dn(t),ln(t)]),i={tenants:r.map(s=>({id:s.id})),plugins:o.map(s=>{let a=Wc(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 Hr(i,n)}var ue=class extends Error{code;constructor(n,t){super(t),this.name="AuthCredentialsDeliveryError",this.code=n}};async function _t(e,n){let t=v(e,()=>new ue("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new ue("no_database","Database not configured");let r=j(t,n.plugin,u=>new ue("plugin_not_found",u)),o=I(r);if(!o)throw new ue("invalid_credentials",`Plugin '${r.id}' has no authType configured`);if(o==="oauth_2"||o==="managed")throw new ue("invalid_credentials","OAuth plugins must be connected via sign-in, not credentials delivery");await an(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 ue("invalid_credentials",`Unknown credential field '${u}' for plugin '${n.plugin}'`);let p=z(c,`set_${u}`);if(!p)throw new ue("invalid_credentials",`Cannot set credential field '${u}' for plugin '${n.plugin}'`);await p(d.trim()),l+=1}if(l===0)throw new ue("invalid_credentials","Provide at least one credential field to save");return await be(e,{plugin:r,tenantId:n.tenantId}).catch(()=>{}),{plugin:n.plugin,tenantId:n.tenantId}}var le=class extends Error{code;constructor(n,t){super(t),this.name="IntegrationCredentialsDeliveryError",this.code=n}};async function Fr(e,n){let t=v(e,()=>new le("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new le("no_database","Database not configured");let r=j(t,n.plugin,u=>new le("plugin_not_found",u)),o=I(r);if(!o)throw new le("invalid_credentials",`Plugin '${r.id}' has no authType configured`);await vi(e);let i=new Set(Lo(r,o)),a=r.authConfig?.[o]?.integration??[],c=U({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 le("invalid_credentials",`Unknown integration credential field '${u}' for plugin '${n.plugin}'`);let p=z(c,`set_${u}`);if(!p)throw new le("invalid_credentials",`Cannot set integration field '${u}' for plugin '${n.plugin}'`);await p(d.trim()),l+=1}if(l===0)throw new le("invalid_credentials","Provide at least one integration credential field to save");return{plugin:n.plugin}}var Et=new Map;function jc(e){for(let[n,t]of Et)t<=e&&Et.delete(n)}function Dt(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();jc(r);let o=Et.get(t);return o!==void 0&&o>r?{ok:!1,error:"Delivery request already consumed"}:(Et.set(t,r+n),{ok:!0})}var Ee=class extends Error{code;constructor(n,t){super(t),this.name="ManagedOAuthDeliveryError",this.code=n}};async function fn(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 Ee("no_access_token","Managed OAuth delivery missing access_token");let u=v(e,()=>new Ee("invalid_corsair_instance","Invalid corsair instance"));if(!u.database)throw new Ee("no_database","No database configured on corsair instance");let d=j(u,t,g=>new Ee("plugin_not_found",g));await an(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 be(e,{plugin:d,tenantId:r}).catch(()=>{});try{let g=await ot(u.plugins,t,{access_token:o,refresh_token:i,scope:a,...l});if(g){try{let f=d.authConfig?.[c]?.account??[];await on({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&&tn(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 sn(e,d,r,p).catch(g=>{console.warn(`[corsair:managed-oauth] subscribe failed for '${t}' tenant '${r}':`,g)}),{plugin:t,tenantId:r}}function qc(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function ji(e,n,t=[]){for(let[r,o]of Object.entries(e))if(qc(o)){if(o.match(n))return{webhook:o,path:[...t,r]}}else if(o&&typeof o=="object"){let i=ji(o,n,[...t,r]);if(i)return i}return null}function Kc(e){let n={};for(let[t,r]of Object.entries(e))n[t.toLowerCase()]=Array.isArray(r)?r[0]:r;return n}function Zc(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 qi(e,n,t,r,o){let i=Kc(n),s=typeof t=="string"?JSON.parse(t):t;(!s||typeof s=="object"&&Object.keys(s).length===0)&&i["x-goog-resource-uri"]&&(s=Zc(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]:qn;for(let g of p){let f=u[g];if(!f||!f.webhooks||!d&&f.pluginWebhookMatcher&&!f.pluginWebhookMatcher(c))continue;let h=ji(f.webhooks,c);if(!h)continue;let k=h.path.join("."),b={payload:s,headers:i,rawBody:typeof t=="string"?t:JSON.stringify(t),...r?{query:r}:{},...o?.hubVerified?{hubVerified:!0}:{}};try{let C=await h.webhook.handler(b),P=!!Object.keys(C.returnToSender||{})?.length;return{plugin:g,action:k,body:s,response:P?{...C?.returnToSender,success:!0}:{success:!0},...C.responseHeaders&&{responseHeaders:C.responseHeaders}}}catch(C){return console.error(`Error executing webhook handler for ${g}.${k}:`,C),{plugin:g,action:k,body:s,response:{success:!1,error:C instanceof Error?C.message:"Unknown error"}}}}return{plugin:null,action:null,body:null}}import{createHash as Gc}from"crypto";import*as $e from"vm";var Ki="__corsairFailedStep",zc=3e4,Ur=class{constructor(n,t){this.wakeAt=n;this.stepName=t}__corsairSleep=!0};function Zi(e){return typeof e=="object"&&e!==null&&e.__corsairSleep===!0}function Gi(e,n){return`st_${Gc("sha256").update(`${n} ${e}`).digest("hex").slice(0,16)}`}function Ot(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 zi=new Set(["constructor","prototype","__proto__"]);function ke(e,n){if(e===null)return null;let t=typeof e;return t==="function"?Vc(e,n):t==="object"?Jc(e):e}function Jc(e){return new Proxy(e,{get(n,t){if(!zi.has(t))return ke(Reflect.get(n,t,n),n)},getPrototypeOf:()=>null,setPrototypeOf:()=>!1,defineProperty:()=>!1,set:()=>!1,deleteProperty:()=>!1})}function Vc(e,n){return new Proxy(e,{apply:(t,r,o)=>Yc(Reflect.apply(t,n,o)),construct(){throw new Error("Workflow code may not construct host objects")},get(t,r){if(!zi.has(r))return ke(Reflect.get(t,r,t),t)},getPrototypeOf:()=>null,setPrototypeOf:()=>!1,defineProperty:()=>!1,set:()=>!1,deleteProperty:()=>!1})}function Yc(e){return e!==null&&typeof e=="object"&&typeof e.then=="function"?Promise.resolve(e).then(n=>ke(n,void 0),n=>{throw ke(n,void 0)}):ke(e,void 0)}function Qc(e){let n=Object.create(null),t=$e.createContext(n,{name:"corsair-workflow",codeGeneration:{strings:!1,wasm:!1}}),o=$e.runInContext("(s) => JSON.parse(s)",t,{filename:"corsair:sandbox:json"})(JSON.stringify(e.payload??null)),s=$e.runInContext(`(function (hostRun, hostSleep) {
19
+ Use the token to approve or deny this request.`),(typeof e.approvalMode=="function"?e.approvalMode():e.approvalMode)==="synchronous"?Ii(e.db,c,u):{result:"blocked",reason:"pending",id:c,token:l,expiresAt:d}}var T=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 S(e,n,t){return new Response(JSON.stringify(n),{status:e,headers:{"content-type":"application/json",...t}})}function ce(e){let n={error:e.code,message:e.message,...e.extra};return S(e.status,n)}function _e(e){return new T(404,"not_found",e)}function X(e,n={}){return new T(400,"bad_request",e,n)}function Pr(e,n){return j(e,n,t=>_e(t))}async function Oi(e,n){let t=e.options?.authType;if(!t||!n.database||!n.kek)return{configured:!1,missingFields:[]};let r=U({authType:t,integrationName:e.id,kek:n.kek,database:n.database}),o=$[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 Mi(e,n){let t=e.options?.authType??null,r=e.oauthConfig,{configured:o,missingFields:i}=await Oi(e,n);return{id:e.id,authType:t,configured:o,missingFields:i,oauth:r?{providerName:r.providerName,scopes:r.scopes,requiresRegisteredRedirect:!!r.requiresRegisteredRedirect}:null}}function yt(){return{ok:!0}}async function ln(e){return Promise.all(e.plugins.map(n=>Mi(n,e)))}async function mt(e,n){let t=Pr(e,n);return Mi(t,e)}async function Cc(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 Hi(e,n){let t=await Cc(e,n),r=t.filter(o=>o.hasCredentials).map(o=>o.integrationName);return{id:n,accounts:t,connectedPlugins:r}}async function dn(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 ht(e,n){if(!n)throw X("Tenant id must be a non-empty string");return Hi(e,n)}async function bt(e,n){let t=n?.id?.trim();if(!t)throw X("Tenant id is required",{missingFields:["id"]});return Hi(e,t)}async function kt(e,n){let t=n?.trim()||"default",r={},o=await Sn(e,t);for(let i of o)r[i.plugin]=tt(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 wt(e,n){let t=n?.plugin;if(typeof t!="string"||!t.trim())throw X("plugin is required",{missingFields:["plugin"]});let r=t.trim();Pr(e,r);let o=n?.tenantId;if(o!=null&&typeof o!="string")throw X("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 Ar(e,n){if(!e.database)throw _e(`Permission '${n}' not found`);let t=await e.database.db.selectFrom("corsair_permissions").selectAll().where("id","=",n).executeTakeFirst();if(!t)throw _e(`Permission '${n}' not found`);return gt(e,t)}function vc(e){if(!e.oauthConfig)throw X(`Plugin '${e.id}' has no oauthConfig`)}function Tc(e){if(!e.manual)throw new T(500,"connect_not_configured","createCorsair was not given manual config. Set { manual: { baseUrl, redirectUri } } to enable manual connect routes.");return e.manual}function Rr(e){let n=Tc(e);if(!n.baseUrl?.trim()||!n.redirectUri?.trim())throw new T(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 Pc(e){let n=!!e.hub,t=cn(e.manual);if(!n&&!t)throw new T(500,"connect_not_configured","createCorsair was not given connect config. Set hub: { ... } for Hub mode, or manual: { baseUrl, redirectUri } for manual connect.")}function Bi(e){if(!e.database||!e.kek)throw new T(500,"database_not_configured","A database and kek are required to issue connect links.")}async function Ac(e,n){let t=n?.plugin?.trim();if(!t)throw X("Plugin id is required",{missingFields:["plugin"]});let r=n.tenantId?.trim()||"default",o=Pr(e,t);vc(o);let i=Rr(e);Bi(e);let s=await Oi(o,e);if(!s.configured)throw new T(400,"missing_credentials",`Plugin '${t}' is missing OAuth client credentials`,{missingFields:s.missingFields});let a=nn(Se(t,r),e.kek),c;try{c=new URL(i.baseUrl)}catch{throw new T(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()+pr).toISOString(),tenantId:r}}async function Rc(e,n,t){Bi(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 ut(e,o);return{connectUrl:a.connectUrl,expiresAt:a.expiresAt,tenantId:r}}async function Ct(e,n,t){return Pc(n),n.hub?Rc(e,n,t):Ac(n,t)}async function vt(e,n,t){if(n.hub&&!cn(n.manual))throw new T(400,"hub_mode","resolve is not used with hub config. Redirect users to connectUrl from createLink.");let r=t?.trim();if(!r)throw X("state is required",{missingFields:["state"]});Rr(n);try{return await yr(e,r)}catch(o){if(o instanceof Q)switch(o.code){case"invalid_state":throw X("Invalid or expired state");case"client_id_not_configured":throw new T(400,"missing_credentials","OAuth client_id is not configured for this plugin",{missingFields:["client_id"]});case"no_redirect_uri":break}throw new T(500,"resolve_failed","Could not resolve connect link. Check server logs for details.")}}async function Tt(e,n,t){if(n.hub&&!cn(n.manual))throw new T(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 X("Missing required fields",{missingFields:i});let s=Rr(n),{processOAuthCallback:a}=await import("./oauth.js");try{return await a(e,{code:r,state:o,redirectUri:s.redirectUri,callbackParams:t.callbackParams})}catch(c){if(c instanceof Error&&c.name==="OAuthCallbackError")switch(c.code){case"invalid_state":throw X("Invalid or expired state");case"credentials_not_configured":throw new T(400,"missing_credentials","OAuth client credentials are not configured for this plugin",{missingFields:["client_id","client_secret"]})}throw new T(502,"oauth_callback_failed","OAuth callback did not complete. Check server logs for details.")}}async function xr(e,n){if(!e.database)throw _e("Permission not found");let t=await e.database.db.selectFrom("corsair_permissions").selectAll().where("token","=",n).executeTakeFirst();if(!t)throw _e("Permission not found");return gt(e,t)}async function Fi(e,n){return"id"in n?Ar(e,n.id):xr(e,n.token)}import{createCipheriv as Mc,createDecipheriv as gf,randomBytes as $i,scryptSync as Hc}from"crypto";import{createHmac as Ir,randomUUID as xc,timingSafeEqual as Ni}from"crypto";function Sr(e){return e.run??null}function _r(e){return e.probe??null}function Li(e){if(e)return e.startsWith("sha256=")?e.slice(7):e}function Pt(e){let n=JSON.stringify({type:e.type,payload:e.payload}),t=Math.floor(Date.now()/1e3).toString(),r=Ir("sha256",e.signingSecret.trim()).update(n).digest("hex");return{body:n,headers:{"content-type":"application/json","x-corsair-signature":`sha256=${r}`,"x-corsair-timestamp":t,"x-corsair-project":e.projectId,"x-corsair-nonce":xc()}}}function Er(e){let n=e.signingSecret.trim();if(!n)return!1;let t=Li(e.signatureHeader);if(!t)return!1;let r=Number(e.timestampHeader);if(!Number.isFinite(r)||Math.abs(Date.now()-r*1e3)>Be)return!1;let i=Ir("sha256",n).update(e.body).digest("hex");try{return Ni(Buffer.from(i,"utf8"),Buffer.from(t,"utf8"))}catch{return!1}}function pn(e){let n=e.signingSecret.trim();if(!n)return{ok:!1,error:"Tunnel signing secret is required"};let t=Li(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)>Be)return{ok:!1,error:"Tunnel request timestamp is outside the allowed window"};let i=Ir("sha256",n).update(e.body).digest("hex");try{if(!Ni(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 gn(e){if(!e)return{};try{return JSON.parse(e)}catch{return{}}}function At(e){return e.httpOk&&(e.status===204||e.body.status==="ok"||e.body.ok===!0)}function Rt(e){let n=e.sync?.encrypted;return typeof n!="string"||!n.trim()?null:{encrypted:n.trim()}}function Dn(e){let n=e.connectUrl?.trim();return n?{connectUrl:n,expiresAt:e.expiresAt}:null}function Dr(e){return Dn(gn(e))}async function Or(e){let n=await St({deliveryUrl:e.deliveryUrl,projectId:e.projectId,signingSecret:e.signingSecret,type:"connect.create_link",payload:{tenantId:e.tenantId,plugins:e.plugins}}),t=gn(n.body),r=At({httpOk:n.ok,status:n.status,body:t}),o=Dn(t);if(!r||!o)throw new Error(It({deliveryUrl:e.deliveryUrl,status:n.status,body:n.body,ack:t}));return o}function xt(e){return Rt(gn(e))}function Ic(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 Ui(e,n=200){let t=e.trim();return t.length<=n?t:`${t.slice(0,n)}\u2026`}var Sc="Verify hub.signingSecret in your app matches the signing secret shown in Hub project settings.",_c="Check the delivery URL configured for this environment.";function Ec(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})`}. ${Sc}`}function Dc(e){return`${e.ack.error?`${e.ack.error} (HTTP 404 from ${e.deliveryUrl})`:`Delivery endpoint not found at ${e.deliveryUrl} (HTTP 404)`}. ${_c}`}function On(e,n){let t=Ic(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 It(e){if(e.status===0)return e.ack.error?e.ack.error:e.body.startsWith("Could not reach")?e.body:On(e.deliveryUrl,new Error(e.body||"Delivery request failed"));if(e.status===401||e.status===403)return Ec(e);if(e.status===404)return Dc(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}): ${Ui(t)}`:`App failed while processing the delivery (HTTP ${e.status} from ${e.deliveryUrl})`}let n=e.body.trim();return n?`${Ui(n)} (HTTP ${e.status} from ${e.deliveryUrl})`:`Delivery failed with HTTP ${e.status} from ${e.deliveryUrl}`}var Oc=15e3;async function St(e){let{body:n,headers:t}=Pt(e);try{let r=await fetch(e.deliveryUrl,{method:"POST",headers:t,body:n,signal:AbortSignal.timeout(Oc)}),o=await r.text();return{ok:r.ok,status:r.status,body:o}}catch(r){return{ok:!1,status:0,body:On(e.deliveryUrl,r)}}}var Bc="aes-256-gcm",Fc=12,Uc=16,Nc=16,Lc=32;function $c(e,n){return Hc(e.trim(),n,Lc)}function Mr(e,n){let t=n.trim();if(!t)throw new Error("Signing secret is required to encrypt sync manifest");let r=$i(Nc),o=$c(t,r),i=$i(Fc),s=Mc(Bc,o,i,{authTagLength:Uc}),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 Wc=["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 Hr(e){if(e instanceof Bo)return!1;if(!(e instanceof Error))return!0;let n=e.message.toLowerCase();return!Wc.some(t=>n.includes(t))}function jc(e){if(!e)return[];let n=I(e);return n?(e.authConfig?.[n]?.integration??[]).filter(r=>!Ie(r)):[]}async function Mn(e,n){let t=v(e);if(!t.database)throw new Error("A database must be configured to sync connections from the app");await at(e,{silent:!0});let[r,o]=await Promise.all([dn(t),ln(t)]),i={tenants:r.map(s=>({id:s.id})),plugins:o.map(s=>{let a=jc(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 Mr(i,n)}var ue=class extends Error{code;constructor(n,t){super(t),this.name="AuthCredentialsDeliveryError",this.code=n}};async function _t(e,n){let t=v(e,()=>new ue("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new ue("no_database","Database not configured");let r=j(t,n.plugin,u=>new ue("plugin_not_found",u)),o=I(r);if(!o)throw new ue("invalid_credentials",`Plugin '${r.id}' has no authType configured`);if(o==="oauth_2"||o==="managed")throw new ue("invalid_credentials","OAuth plugins must be connected via sign-in, not credentials delivery");await an(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 ue("invalid_credentials",`Unknown credential field '${u}' for plugin '${n.plugin}'`);let p=z(c,`set_${u}`);if(!p)throw new ue("invalid_credentials",`Cannot set credential field '${u}' for plugin '${n.plugin}'`);await p(d.trim()),l+=1}if(l===0)throw new ue("invalid_credentials","Provide at least one credential field to save");return await be(e,{plugin:r,tenantId:n.tenantId}).catch(()=>{}),{plugin:n.plugin,tenantId:n.tenantId}}var le=class extends Error{code;constructor(n,t){super(t),this.name="IntegrationCredentialsDeliveryError",this.code=n}};async function Br(e,n){let t=v(e,()=>new le("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new le("no_database","Database not configured");let r=j(t,n.plugin,u=>new le("plugin_not_found",u)),o=I(r);if(!o)throw new le("invalid_credentials",`Plugin '${r.id}' has no authType configured`);await Ci(e);let i=new Set(No(r,o)),a=r.authConfig?.[o]?.integration??[],c=U({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 le("invalid_credentials",`Unknown integration credential field '${u}' for plugin '${n.plugin}'`);let p=z(c,`set_${u}`);if(!p)throw new le("invalid_credentials",`Cannot set integration field '${u}' for plugin '${n.plugin}'`);await p(d.trim()),l+=1}if(l===0)throw new le("invalid_credentials","Provide at least one integration credential field to save");return{plugin:n.plugin}}var Et=new Map;function qc(e){for(let[n,t]of Et)t<=e&&Et.delete(n)}function Dt(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();qc(r);let o=Et.get(t);return o!==void 0&&o>r?{ok:!1,error:"Delivery request already consumed"}:(Et.set(t,r+n),{ok:!0})}var Ee=class extends Error{code;constructor(n,t){super(t),this.name="ManagedOAuthDeliveryError",this.code=n}};async function fn(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 Ee("no_access_token","Managed OAuth delivery missing access_token");let u=v(e,()=>new Ee("invalid_corsair_instance","Invalid corsair instance"));if(!u.database)throw new Ee("no_database","No database configured on corsair instance");let d=j(u,t,g=>new Ee("plugin_not_found",g));await an(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 be(e,{plugin:d,tenantId:r}).catch(()=>{});try{let g=await ot(u.plugins,t,{access_token:o,refresh_token:i,scope:a,...l});if(g){try{let f=d.authConfig?.[c]?.account??[];await on({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&&tn(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 sn(e,d,r,p).catch(g=>{console.warn(`[corsair:managed-oauth] subscribe failed for '${t}' tenant '${r}':`,g)}),{plugin:t,tenantId:r}}function Kc(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function Wi(e,n,t=[]){for(let[r,o]of Object.entries(e))if(Kc(o)){if(o.match(n))return{webhook:o,path:[...t,r]}}else if(o&&typeof o=="object"){let i=Wi(o,n,[...t,r]);if(i)return i}return null}function Zc(e){let n={};for(let[t,r]of Object.entries(e))n[t.toLowerCase()]=Array.isArray(r)?r[0]:r;return n}function Gc(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 ji(e,n,t,r,o){let i=Zc(n),s=typeof t=="string"?JSON.parse(t):t;(!s||typeof s=="object"&&Object.keys(s).length===0)&&i["x-goog-resource-uri"]&&(s=Gc(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]:qn;for(let g of p){let f=u[g];if(!f||!f.webhooks||!d&&f.pluginWebhookMatcher&&!f.pluginWebhookMatcher(c))continue;let h=Wi(f.webhooks,c);if(!h)continue;let k=h.path.join("."),b={payload:s,headers:i,rawBody:typeof t=="string"?t:JSON.stringify(t),...r?{query:r}:{},...o?.hubVerified?{hubVerified:!0}:{}};try{let C=await h.webhook.handler(b),P=!!Object.keys(C.returnToSender||{})?.length;return{plugin:g,action:k,body:s,response:P?{...C?.returnToSender,success:!0}:{success:!0},...C.responseHeaders&&{responseHeaders:C.responseHeaders}}}catch(C){return console.error(`Error executing webhook handler for ${g}.${k}:`,C),{plugin:g,action:k,body:s,response:{success:!1,error:C instanceof Error?C.message:"Unknown error"}}}}return{plugin:null,action:null,body:null}}import{createHash as zc}from"crypto";import*as $e from"vm";var qi="__corsairFailedStep",Jc=3e4,Fr=class{constructor(n,t){this.wakeAt=n;this.stepName=t}__corsairSleep=!0};function Ki(e){return typeof e=="object"&&e!==null&&e.__corsairSleep===!0}function Zi(e,n){return`st_${zc("sha256").update(`${n} ${e}`).digest("hex").slice(0,16)}`}function Ot(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 Gi=new Set(["constructor","prototype","__proto__"]);function ke(e,n){if(e===null)return null;let t=typeof e;return t==="function"?Yc(e,n):t==="object"?Vc(e):e}function Vc(e){return new Proxy(e,{get(n,t){if(!Gi.has(t))return ke(Reflect.get(n,t,n),n)},getPrototypeOf:()=>null,setPrototypeOf:()=>!1,defineProperty:()=>!1,set:()=>!1,deleteProperty:()=>!1})}function Yc(e,n){return new Proxy(e,{apply:(t,r,o)=>Qc(Reflect.apply(t,n,o)),construct(){throw new Error("Workflow code may not construct host objects")},get(t,r){if(!Gi.has(r))return ke(Reflect.get(t,r,t),t)},getPrototypeOf:()=>null,setPrototypeOf:()=>!1,defineProperty:()=>!1,set:()=>!1,deleteProperty:()=>!1})}function Qc(e){return e!==null&&typeof e=="object"&&typeof e.then=="function"?Promise.resolve(e).then(n=>ke(n,void 0),n=>{throw ke(n,void 0)}):ke(e,void 0)}function Xc(e){let n=Object.create(null),t=$e.createContext(n,{name:"corsair-workflow",codeGeneration:{strings:!1,wasm:!1}}),o=$e.runInContext("(s) => JSON.parse(s)",t,{filename:"corsair:sandbox:json"})(JSON.stringify(e.payload??null)),s=$e.runInContext(`(function (hostRun, hostSleep) {
20
20
  const step = function step(name, fn) { return hostRun(name, fn); };
21
21
  step.sleep = function sleep(name, ms) { return hostSleep(name, ms); };
22
22
  return step;
@@ -39,28 +39,28 @@ ${e.code}
39
39
  throw new Error('Workflow code must export a \`main\` function');
40
40
  }
41
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 Nr(e){let n=e.memoizedSteps??{},t=[],r=0,o=null,i=(async(s,a)=>{if(o)throw o;let c=r++,l=Gi(s,c);if(Object.hasOwn(n,l))return ke(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(Zi(u))throw u;let d=Ot(u);t.push({stepId:l,name:s,seq:c,status:"failed",error:d});let p=new Error(d);throw p[Ki]=s,p}});i.sleep=async(s,a)=>{if(o)throw o;let c=r++,l=Gi(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 Ur(Date.now()+u,s),o};try{await Qc({code:e.code,corsair:e.corsair,payload:e.payload,step:i,timeoutMs:e.timeoutMs??zc});let s=o;return s?{status:"sleeping",steps:t,sleepUntil:new Date(s.wakeAt).toISOString()}:{status:"completed",steps:t}}catch(s){if(Zi(s))return{status:"sleeping",steps:t,sleepUntil:new Date(s.wakeAt).toISOString()};let a=Ot(s),c=s!==null&&typeof s=="object"?s[Ki]:void 0;return{status:"failed",steps:t,error:{message:a,...c?{failedStep:c}:{}}}}}import*as Mt from"vm";var Ji=1e4;async function Lr(e){let n=Object.create(null),t=Mt.createContext(n,{name:"corsair-probe",codeGeneration:{strings:!1,wasm:!1}});n.corsair=ke(e.corsair,void 0);let r=eu(e.timeoutMs),o=`(async () => {
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 Ur(e){let n=e.memoizedSteps??{},t=[],r=0,o=null,i=(async(s,a)=>{if(o)throw o;let c=r++,l=Zi(s,c);if(Object.hasOwn(n,l))return ke(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(Ki(u))throw u;let d=Ot(u);t.push({stepId:l,name:s,seq:c,status:"failed",error:d});let p=new Error(d);throw p[qi]=s,p}});i.sleep=async(s,a)=>{if(o)throw o;let c=r++,l=Zi(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 Fr(Date.now()+u,s),o};try{await Xc({code:e.code,corsair:e.corsair,payload:e.payload,step:i,timeoutMs:e.timeoutMs??Jc});let s=o;return s?{status:"sleeping",steps:t,sleepUntil:new Date(s.wakeAt).toISOString()}:{status:"completed",steps:t}}catch(s){if(Ki(s))return{status:"sleeping",steps:t,sleepUntil:new Date(s.wakeAt).toISOString()};let a=Ot(s),c=s!==null&&typeof s=="object"?s[qi]:void 0;return{status:"failed",steps:t,error:{message:a,...c?{failedStep:c}:{}}}}}import*as Mt from"vm";var zi=1e4;async function Nr(e){let n=Object.create(null),t=Mt.createContext(n,{name:"corsair-probe",codeGeneration:{strings:!1,wasm:!1}});n.corsair=ke(e.corsair,void 0);let r=nu(e.timeoutMs),o=`(async () => {
43
43
  const __result = await (async () => {
44
44
  ${e.code}
45
45
  })();
46
46
  return JSON.stringify(__result) ?? 'null';
47
- })()`;try{let i=await vr(()=>{let s=Mt.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:Xc(i)}}catch(i){return{status:"error",error:Ot(i)}}}function Xc(e){if(typeof e!="string")throw new Error(`Probe returned a non-string result (${typeof e})`);return JSON.parse(e)}function eu(e){return typeof e!="number"||!Number.isFinite(e)||e<=0?Ji:Math.min(e,Ji)}function We(e){return e.deliveryMode==="auth.credentials"}function Hn(e){return e.deliveryMode==="connections.sync"}function Ht(e){return e.deliveryMode==="connect.create_link"}function Bn(e){return e.deliveryMode==="permission.approve"||e.deliveryMode==="permission.deny"}function Fn(e){return e.deliveryMode==="oauth.tokens"}function Bt(e){return e.deliveryMode==="oauth.callback"||e.deliveryMode===void 0&&!We(e)&&!Hn(e)&&!Ht(e)&&!Bn(e)&&!Fn(e)}function nu(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 tu(e,n){try{return{status:"ok",webhookResponse:{status:200,body:{status:"ok",sync:{encrypted:await Mn(e,n)}}}}}catch(t){return{status:"failed",retryable:Br(t),error:t instanceof Error?t.message:"Connections sync delivery failed"}}}async function ru(e,n){try{let t=await lt(e,n);return nu(t)}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Connect link delivery failed"}}}function $r(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 ou(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 it({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 ou(e,n,t),i={...t.query??{},...o?{tenantId:o}:{}},s=await qi(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 En(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 au(e,n){return await fn(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 jr(e,n,t){let r=await Wr(e,{token:n},t);if(r.status!=="ok")throw new Error(r.error??"Permission decision failed")}async function Wr(e,n,t){let r=v(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 cu(e,n){try{return await _t(e,n),{status:"ok"}}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Credential delivery failed"}}}async function uu(e,n){try{return await Fr(e,n),{status:"ok"}}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Integration credential delivery failed"}}}function Vi(e,n){let t=e;return n&&typeof t?.withTenant=="function"?t.withTenant(n):e}async function lu(e,n){try{let t=Vi(e,n.tenantId);return{status:"ok",webhookResponse:{status:200,body:{status:"ok",run:await Nr({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 du(e,n){try{let t=Vi(e,n.tenantId);return{status:"ok",webhookResponse:{status:200,body:{status:"ok",probe:await Lr({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 Un(e,n,t={}){let r=v(e),o=$r(n.headers,"x-corsair-signature"),i=$r(n.headers,"x-corsair-timestamp"),s=$r(n.headers,"x-corsair-nonce"),a=!1;if(t.signingSecret?.trim()){let l=pn({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=Dt(`nonce:${s.trim()}`,Be);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 au(e,c.payload);case"permission.approve":return Wr(e,c.payload,"approved");case"permission.deny":return Wr(e,c.payload,"denied");case"auth.credentials":return cu(e,c.payload);case"integration.credentials":return uu(e,c.payload);case"connect.create_link":return ru(e,c.payload);case"connections.sync":{let l=t.signingSecret?.trim();return l?tu(e,l):{status:"failed",retryable:!1,error:"Tunnel signing secret is required for connections.sync"}}case"run":return t.allowWorkflowExecution?lu(e,c.payload):{status:"failed",retryable:!1,error:"Workflow execution is not enabled (set allowWorkflowExecution: true)"};case"probe":return t.allowWorkflowExecution?du(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 pu(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 qr=3,gu=250;function fu(e){return e?.name==="AbortError"}async function yu(e){try{return(await e.json())?.ok!==!1}catch{return!0}}async function mu(e,n,t,r,o){for(let i=1;i<=qr;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 yu(s)||console.warn(`[corsair] hub did not record delivery ${r.deliveryId} (already timed out); the run may be retried`),!0}catch(s){if(fu(s))throw s}i<qr&&await Qi(gu)}return console.warn(`[corsair] failed to acknowledge delivery ${r.deliveryId} after ${qr} attempts; the run may be retried`),!1}async function hu(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}=pu(l);return await mu(n,t,o,{deliveryId:s,status:u,body:d},r)?"handled":"error"}var Yi=1e3,bu=5e3,ku=3e4;function Qi(e){return new Promise(n=>setTimeout(n,e))}var Ft=globalThis.__corsairConnectLoops??=new Map;function wu(e,n={fetch,process:Un}){let t;try{t=F(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(Ft.has(r))return{stop:()=>{}};let o=Symbol("corsair-connect-loop");Ft.set(r,o);let i=()=>{Ft.get(r)===o&&Ft.delete(r)},s=!1,a=null;return(async()=>{let l=Yi,u=!1,d=async p=>{u||(console.warn("[corsair] connect loop error; retrying",p),u=!0),s||await Qi(l),l=Math.min(l*2,bu)};try{for(;!s;){a=new AbortController;let p=setTimeout(()=>a?.abort(),ku);try{await hu(e,t,n,a.signal)==="error"?await d("pull or ack failed"):(u=!1,l=Yi)}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 Xi(e){return e==="oauth_2"||e==="managed"?"oauth":e==="bot_token"?"bot_token":"api_key"}function Cu(e,n){return n&&!n.has(e.id)?!1:I(e)!==null}async function es(e,n,t={}){let r=v(e),o=n.trim()||"default",i=t.pluginIds?.length?new Set(t.pluginIds):null,s=await Sn(r,o,{pluginIds:t.pluginIds}),a=new Map(s.map(l=>[l.plugin,l])),c=r.plugins.filter(l=>Cu(l,i)).map(l=>{let u=I(l),d=a.get(l.id);return d?{plugin:l.id,providerName:Pe(l.id),authKind:Xi(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:Pe(l.id),authKind:Xi(u),status:"not_started",connected:!1,fields:[],missingRequiredFields:[]}});return{tenantId:o,plugins:c}}async function ns(e,n){let t=F(e);return W({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:Zn})}var ts=1024*1024,rs=3e4;function je(e){return e!==void 0&&Number.isFinite(e)&&e>0?e:ts}function qe(e){return e!==void 0&&Number.isFinite(e)&&e>=0?e:rs}function yn(e){return new T(413,"payload_too_large",`Request body exceeds the ${e}-byte limit`)}function vu(e){return new T(408,"request_timeout",`Request body stalled: no bytes received for ${e}ms`)}async function Ut(e,n){if(!(n>0))return e();let t;try{return await Promise.race([e(),new Promise((r,o)=>{t=setTimeout(()=>o(vu(n)),n)})])}finally{clearTimeout(t)}}async function Nt(e,n){if(e.body===null)return"";let t=e.body.getReader();try{let r=[],o=0;for(;;){let{done:a,value:c}=await Ut(()=>t.read(),n.bodyStallTimeoutMs);if(a)break;if(o+=c.byteLength,o>n.maxBodyBytes)throw yn(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 Kr=new Map;function os(e){let n;try{n=F(e)}catch{return}let t=er(n);t&&Kr.get(n.projectApiKey)!==t&&(Kr.set(n.projectApiKey,t),x({hub:n,path:"/apps/announce",body:{deliveryUrl:t},parseResponse:()=>({ok:!0})}).catch(()=>{Kr.delete(n.projectApiKey)}))}var Tu=[".corsair.dev"];function Pu(e){return e==="localhost"||e==="127.0.0.1"||e==="[::1]"||e==="::1"}function Au(e){try{let{hostname:n,protocol:t}=new URL(e);return t!=="http:"&&t!=="https:"?!1:Pu(n)?!0:Tu.some(r=>n===r.slice(1)||n.endsWith(r))}catch{return!1}}function is(e){return!e||!Au(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 ss(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 Zr(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 Gr(e,n){let t=F(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=Re(o,t.signingSecret);if(!i)return{type:"json",status:400,body:{error:"Invalid or expired delivery token"}};let s=Dt(`browser:${i.jti}`,Ae);if(!s.ok)return{type:"json",status:400,body:{error:s.error}};try{if(Hn(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 Mn(e,t.signingSecret);return{type:"text",status:200,headers:{"Content-Type":"text/html; charset=utf-8"},body:Ve({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!0,body:{status:"ok",sync:{encrypted:a}}})}}if(Ht(i)){if(!i.hubOrigin||!i.requestId)return{type:"json",status:400,body:{error:"Connect link delivery requires hubOrigin and requestId for client bridge"}};let a=i.connectLinkPlugins?.filter(Boolean)??[];if(a.length===0)return{type:"json",status:400,body:{error:"Connect link delivery requires at least one plugin in connectLinkPlugins"}};let c=await lt(e,{tenantId:i.tenantId,plugins:a});return{type:"text",status:200,headers:{"Content-Type":"text/html; charset=utf-8"},body:Ve({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!0,body:{status:"ok",connectUrl:c.connectUrl,expiresAt:c.expiresAt}})}}if(We(i))return i.hubSuccessUrl?i.credentials?(await _t(e,{plugin:i.plugin,tenantId:i.tenantId,credentials:i.credentials}),{type:"redirect",url:Zr(i.hubSuccessUrl,{connectedPlugin:i.plugin})}):{type:"redirect",url:Zr(i.hubSuccessUrl,{error:"Credential delivery missing credentials"})}:{type:"json",status:400,body:{error:"Credential delivery missing hubSuccessUrl"}};if(Bn(i)){if(!i.permissionToken)return{type:"json",status:400,body:{error:"Permission delivery missing permission token"}};await jr(e,i.permissionToken,i.deliveryMode==="permission.approve"?"approved":"denied")}else if(Fn(i)){if(!i.accessToken)return{type:"json",status:400,body:{error:"Managed OAuth delivery missing access_token"}};await fn(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(!Bt(i)||!i.code||!i.state||!i.redirectUri)return{type:"json",status:400,body:{error:"Invalid BYO OAuth delivery token"}};await En(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 Hn(i)&&i.hubOrigin&&i.requestId?{type:"text",status:400,headers:{"Content-Type":"text/html; charset=utf-8"},body:Ve({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!1,error:c})}:Ht(i)&&i.hubOrigin&&i.requestId?{type:"text",status:400,headers:{"Content-Type":"text/html; charset=utf-8"},body:Ve({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!1,error:c})}:We(i)&&i.hubSuccessUrl?{type:"redirect",url:Zr(i.hubSuccessUrl,{error:c})}:We(i)&&i.hubOrigin&&i.requestId?{type:"text",status:400,headers:{"Content-Type":"text/html; charset=utf-8"},body:Ve({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 zr(e,n){let t=F(e),r=await Un(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 Jr(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 Vr(e,n){return n.method==="GET"?Gr(e,n.url):zr(e,{headers:n.headers,body:n.body??""})}async function Yr(e,n){try{let t=await Vr(e,n);return Jr(t)}catch(t){if(t instanceof fe)return Response.json({error:t.message},{status:503});throw t}}async function Ke(e,n,t){os(e);let r=n.method.toUpperCase(),o=is(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 Yr(e,{method:r,url:n.url,headers:n.headers,body:r==="POST"?await Nt(n,{maxBodyBytes:je(t?.maxBodyBytes),bodyStallTimeoutMs:qe(t?.bodyStallTimeoutMs)}):void 0});return ss(i,o)}var M=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 mn(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 hn(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 as=new WeakMap;function Nn(e,n,t){let r=as.get(e);r||(r=new Map,as.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 cs=300;async function Qr(e,n){let{keys:t,hub:r,plugin:o,tenantId:i}=e,s=n?.forceRefresh??!1,a=`managed:${o}:${i}`;return Nn(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 M(o,"managed");let d=Math.floor(Date.now()/1e3);if(!s&&c&&l&&Number(l)>d+cs)return{accessToken:c,expiresAt:Number(l),refreshed:!1};if(!u&&c&&!s){let f=l?Number(l):null;if(f===null||f>d+cs)return{accessToken:c,expiresAt:f??d+3600,refreshed:!1}}if(!u)throw new M(o,"managed");let p=await xu(r,o,i,u),g=await hn(t,p,l);return{accessToken:p.access_token,expiresAt:g,refreshed:!0}})}function Ru(e){return e.includes("Managed OAuth connection not found")||e.includes("Managed OAuth connection has no tokens")}async function xu(e,n,t,r){try{return await x({hub:e,path:"/oauth/refresh",body:{plugin:n,tenantId:t,refresh_token:r},parseResponse:Je})}catch(o){let i=o instanceof Error?o.message:"";throw Ru(i)?new M(n,"managed"):o}}async function us(e,n){e._refreshAuth=async()=>(await Qr(n,{forceRefresh:!0})).accessToken}function ls(e){return{delivery:n=>Ke(e,n),deliveryOptions:n=>Ke(e,n)}}var ds=1200*1e3;function Xr(){return ge()}function eo(){return ds}function no(e,n){return Pn(e,n,ds)}function to(e,n){return ae(e,n)}function ro(e){return Fe(e)}var ps=600*1e3;function oo(){return ge()}function io(){return ps}function so(e,n){return Pn(e,n,ps)}function ao(e,n){return ae(e,n)}function co(e){return ar(e)}function uo(e){return Fe(e)}function lo(){return ge()}function po(e,n,t){return Vn(e,n,Math.floor(t.getTime()/1e3))}function go(e,n){return ae(e,n)}function fo(e){return Fe(e)}var Ze=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 ${Ue}`),this.name="CorsairKekMissingError"}};function Lt(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 Ze;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.
47
+ })()`;try{let i=await Cr(()=>{let s=Mt.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:eu(i)}}catch(i){return{status:"error",error:Ot(i)}}}function eu(e){if(typeof e!="string")throw new Error(`Probe returned a non-string result (${typeof e})`);return JSON.parse(e)}function nu(e){return typeof e!="number"||!Number.isFinite(e)||e<=0?zi:Math.min(e,zi)}function We(e){return e.deliveryMode==="auth.credentials"}function Hn(e){return e.deliveryMode==="connections.sync"}function Ht(e){return e.deliveryMode==="connect.create_link"}function Bn(e){return e.deliveryMode==="permission.approve"||e.deliveryMode==="permission.deny"}function Fn(e){return e.deliveryMode==="oauth.tokens"}function Bt(e){return e.deliveryMode==="oauth.callback"||e.deliveryMode===void 0&&!We(e)&&!Hn(e)&&!Ht(e)&&!Bn(e)&&!Fn(e)}function tu(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 Mn(e,n)}}}}}catch(t){return{status:"failed",retryable:Hr(t),error:t instanceof Error?t.message:"Connections sync delivery failed"}}}async function ou(e,n){try{let t=await lt(e,n);return tu(t)}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Connect link delivery failed"}}}function Lr(e,n){if(e instanceof Headers)return e.get(n)??void 0;let t=e[n]??e[n.toLowerCase()];return Array.isArray(t)?t[0]:typeof t=="string"?t:void 0}async function iu(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 it({database:n.database,kek:n.kek,pluginId:t.plugin,linkType:t.linkType,externalId:t.externalId})??void 0)}async function su(e,n,t,r){let o=await iu(e,n,t),i={...t.query??{},...o?{tenantId:o}:{}},s=await ji(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 au(e,n){return await En(e,{code:n.code,state:n.state,redirectUri:n.redirectUri,callbackParams:n.callbackParams,...n.plugin&&n.tenantId?{trusted:!0,plugin:n.plugin,tenantId:n.tenantId}:{}}),{status:"ok"}}async function cu(e,n){return await fn(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 Wr(e,n,t){let r=await $r(e,{token:n},t);if(r.status!=="ok")throw new Error(r.error??"Permission decision failed")}async function $r(e,n,t){let r=v(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 uu(e,n){try{return await _t(e,n),{status:"ok"}}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Credential delivery failed"}}}async function lu(e,n){try{return await Br(e,n),{status:"ok"}}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Integration credential delivery failed"}}}function Ji(e,n){let t=e;return n&&typeof t?.withTenant=="function"?t.withTenant(n):e}async function du(e,n){try{let t=Ji(e,n.tenantId);return{status:"ok",webhookResponse:{status:200,body:{status:"ok",run:await Ur({corsair:t,code:n.code,payload:n.trigger?.payload??null,memoizedSteps:n.memoizedSteps})}}}}catch(t){return{status:"failed",retryable:!0,error:t instanceof Error?t.message:"Workflow run failed"}}}async function pu(e,n){try{let t=Ji(e,n.tenantId);return{status:"ok",webhookResponse:{status:200,body:{status:"ok",probe:await Nr({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 Un(e,n,t={}){let r=v(e),o=Lr(n.headers,"x-corsair-signature"),i=Lr(n.headers,"x-corsair-timestamp"),s=Lr(n.headers,"x-corsair-nonce"),a=!1;if(t.signingSecret?.trim()){let l=pn({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=Dt(`nonce:${s.trim()}`,Be);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 su(e,r,c.payload,a);case"oauth.callback":return au(e,c.payload);case"oauth.tokens":return cu(e,c.payload);case"permission.approve":return $r(e,c.payload,"approved");case"permission.deny":return $r(e,c.payload,"denied");case"auth.credentials":return uu(e,c.payload);case"integration.credentials":return lu(e,c.payload);case"connect.create_link":return ou(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?du(e,c.payload):{status:"failed",retryable:!1,error:"Workflow execution is not enabled (set allowWorkflowExecution: true)"};case"probe":return t.allowWorkflowExecution?pu(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 gu(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 jr=3,fu=250;function yu(e){return e?.name==="AbortError"}async function mu(e){try{return(await e.json())?.ok!==!1}catch{return!0}}async function hu(e,n,t,r,o){for(let i=1;i<=jr;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 mu(s)||console.warn(`[corsair] hub did not record delivery ${r.deliveryId} (already timed out); the run may be retried`),!0}catch(s){if(yu(s))throw s}i<jr&&await Yi(fu)}return console.warn(`[corsair] failed to acknowledge delivery ${r.deliveryId} after ${jr} attempts; the run may be retried`),!1}async function bu(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}=gu(l);return await hu(n,t,o,{deliveryId:s,status:u,body:d},r)?"handled":"error"}var Vi=1e3,ku=5e3,wu=3e4;function Yi(e){return new Promise(n=>setTimeout(n,e))}var Ft=globalThis.__corsairConnectLoops??=new Map;function Cu(e,n={fetch,process:Un}){let t;try{t=F(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(Ft.has(r))return{stop:()=>{}};let o=Symbol("corsair-connect-loop");Ft.set(r,o);let i=()=>{Ft.get(r)===o&&Ft.delete(r)},s=!1,a=null;return(async()=>{let l=Vi,u=!1,d=async p=>{u||(console.warn("[corsair] connect loop error; retrying",p),u=!0),s||await Yi(l),l=Math.min(l*2,ku)};try{for(;!s;){a=new AbortController;let p=setTimeout(()=>a?.abort(),wu);try{await bu(e,t,n,a.signal)==="error"?await d("pull or ack failed"):(u=!1,l=Vi)}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 Qi(e){return e==="oauth_2"||e==="managed"?"oauth":e==="bot_token"?"bot_token":"api_key"}function vu(e,n){return n&&!n.has(e.id)?!1:I(e)!==null}async function Xi(e,n,t={}){let r=v(e),o=n.trim()||"default",i=t.pluginIds?.length?new Set(t.pluginIds):null,s=await Sn(r,o,{pluginIds:t.pluginIds}),a=new Map(s.map(l=>[l.plugin,l])),c=r.plugins.filter(l=>vu(l,i)).map(l=>{let u=I(l),d=a.get(l.id);return d?{plugin:l.id,providerName:Pe(l.id),authKind:Qi(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:Pe(l.id),authKind:Qi(u),status:"not_started",connected:!1,fields:[],missingRequiredFields:[]}});return{tenantId:o,plugins:c}}async function es(e,n){let t=F(e);return W({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:Zn})}var ns=1024*1024,ts=3e4;function je(e){return e!==void 0&&Number.isFinite(e)&&e>0?e:ns}function qe(e){return e!==void 0&&Number.isFinite(e)&&e>=0?e:ts}function yn(e){return new T(413,"payload_too_large",`Request body exceeds the ${e}-byte limit`)}function Tu(e){return new T(408,"request_timeout",`Request body stalled: no bytes received for ${e}ms`)}async function Ut(e,n){if(!(n>0))return e();let t;try{return await Promise.race([e(),new Promise((r,o)=>{t=setTimeout(()=>o(Tu(n)),n)})])}finally{clearTimeout(t)}}async function Nt(e,n){if(e.body===null)return"";let t=e.body.getReader();try{let r=[],o=0;for(;;){let{done:a,value:c}=await Ut(()=>t.read(),n.bodyStallTimeoutMs);if(a)break;if(o+=c.byteLength,o>n.maxBodyBytes)throw yn(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 rs(e){let n;try{n=F(e)}catch{return}let t=Xt(n);t&&qr.get(n.projectApiKey)!==t&&(qr.set(n.projectApiKey,t),x({hub:n,path:"/apps/announce",body:{deliveryUrl:t},parseResponse:()=>({ok:!0})}).catch(()=>{qr.delete(n.projectApiKey)}))}var Pu=[".corsair.dev"];function Au(e){return e==="localhost"||e==="127.0.0.1"||e==="[::1]"||e==="::1"}function Ru(e){try{let{hostname:n,protocol:t}=new URL(e);return t!=="http:"&&t!=="https:"?!1:Au(n)?!0:Pu.some(r=>n===r.slice(1)||n.endsWith(r))}catch{return!1}}function os(e){return!e||!Ru(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 is(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 Kr(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 Zr(e,n){let t=F(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=Re(o,t.signingSecret);if(!i)return{type:"json",status:400,body:{error:"Invalid or expired delivery token"}};let s=Dt(`browser:${i.jti}`,Ae);if(!s.ok)return{type:"json",status:400,body:{error:s.error}};try{if(Hn(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 Mn(e,t.signingSecret);return{type:"text",status:200,headers:{"Content-Type":"text/html; charset=utf-8"},body:Ve({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!0,body:{status:"ok",sync:{encrypted:a}}})}}if(Ht(i)){if(!i.hubOrigin||!i.requestId)return{type:"json",status:400,body:{error:"Connect link delivery requires hubOrigin and requestId for client bridge"}};let a=i.connectLinkPlugins?.filter(Boolean)??[];if(a.length===0)return{type:"json",status:400,body:{error:"Connect link delivery requires at least one plugin in connectLinkPlugins"}};let c=await lt(e,{tenantId:i.tenantId,plugins:a});return{type:"text",status:200,headers:{"Content-Type":"text/html; charset=utf-8"},body:Ve({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!0,body:{status:"ok",connectUrl:c.connectUrl,expiresAt:c.expiresAt}})}}if(We(i))return i.hubSuccessUrl?i.credentials?(await _t(e,{plugin:i.plugin,tenantId:i.tenantId,credentials:i.credentials}),{type:"redirect",url:Kr(i.hubSuccessUrl,{connectedPlugin:i.plugin})}):{type:"redirect",url:Kr(i.hubSuccessUrl,{error:"Credential delivery missing credentials"})}:{type:"json",status:400,body:{error:"Credential delivery missing hubSuccessUrl"}};if(Bn(i)){if(!i.permissionToken)return{type:"json",status:400,body:{error:"Permission delivery missing permission token"}};await Wr(e,i.permissionToken,i.deliveryMode==="permission.approve"?"approved":"denied")}else if(Fn(i)){if(!i.accessToken)return{type:"json",status:400,body:{error:"Managed OAuth delivery missing access_token"}};await fn(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(!Bt(i)||!i.code||!i.state||!i.redirectUri)return{type:"json",status:400,body:{error:"Invalid BYO OAuth delivery token"}};await En(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 Hn(i)&&i.hubOrigin&&i.requestId?{type:"text",status:400,headers:{"Content-Type":"text/html; charset=utf-8"},body:Ve({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!1,error:c})}:Ht(i)&&i.hubOrigin&&i.requestId?{type:"text",status:400,headers:{"Content-Type":"text/html; charset=utf-8"},body:Ve({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!1,error:c})}:We(i)&&i.hubSuccessUrl?{type:"redirect",url:Kr(i.hubSuccessUrl,{error:c})}:We(i)&&i.hubOrigin&&i.requestId?{type:"text",status:400,headers:{"Content-Type":"text/html; charset=utf-8"},body:Ve({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 Gr(e,n){let t=F(e),r=await Un(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 zr(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 Jr(e,n){return n.method==="GET"?Zr(e,n.url):Gr(e,{headers:n.headers,body:n.body??""})}async function Vr(e,n){try{let t=await Jr(e,n);return zr(t)}catch(t){if(t instanceof fe)return Response.json({error:t.message},{status:503});throw t}}async function Ke(e,n,t){rs(e);let r=n.method.toUpperCase(),o=os(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 Vr(e,{method:r,url:n.url,headers:n.headers,body:r==="POST"?await Nt(n,{maxBodyBytes:je(t?.maxBodyBytes),bodyStallTimeoutMs:qe(t?.bodyStallTimeoutMs)}):void 0});return is(i,o)}var M=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 mn(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 hn(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 ss=new WeakMap;function Nn(e,n,t){let r=ss.get(e);r||(r=new Map,ss.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 as=300;async function Yr(e,n){let{keys:t,hub:r,plugin:o,tenantId:i}=e,s=n?.forceRefresh??!1,a=`managed:${o}:${i}`;return Nn(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 M(o,"managed");let d=Math.floor(Date.now()/1e3);if(!s&&c&&l&&Number(l)>d+as)return{accessToken:c,expiresAt:Number(l),refreshed:!1};if(!u&&c&&!s){let f=l?Number(l):null;if(f===null||f>d+as)return{accessToken:c,expiresAt:f??d+3600,refreshed:!1}}if(!u)throw new M(o,"managed");let p=await Iu(r,o,i,u),g=await hn(t,p,l);return{accessToken:p.access_token,expiresAt:g,refreshed:!0}})}function xu(e){return e.includes("Managed OAuth connection not found")||e.includes("Managed OAuth connection has no tokens")}async function Iu(e,n,t,r){try{return await x({hub:e,path:"/oauth/refresh",body:{plugin:n,tenantId:t,refresh_token:r},parseResponse:Je})}catch(o){let i=o instanceof Error?o.message:"";throw xu(i)?new M(n,"managed"):o}}async function cs(e,n){e._refreshAuth=async()=>(await Yr(n,{forceRefresh:!0})).accessToken}function us(e){return{delivery:n=>Ke(e,n),deliveryOptions:n=>Ke(e,n)}}var ls=1200*1e3;function Qr(){return ge()}function Xr(){return ls}function eo(e,n){return Pn(e,n,ls)}function no(e,n){return ae(e,n)}function to(e){return Fe(e)}var ds=600*1e3;function ro(){return ge()}function oo(){return ds}function io(e,n){return Pn(e,n,ds)}function so(e,n){return ae(e,n)}function ao(e){return sr(e)}function co(e){return Fe(e)}function uo(){return ge()}function lo(e,n,t){return Vn(e,n,Math.floor(t.getTime()/1e3))}function po(e,n){return ae(e,n)}function go(e){return Fe(e)}var Ze=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 ${Ue}`),this.name="CorsairKekMissingError"}};function Lt(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 Ze;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
48
 
49
- To generate a KEK, run: openssl rand -base64 ${Ue}`)}})}async function Iu(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 gs(e){let{integrationId:n,accountId:t}=await Iu(e);return{integrationId:n,accountId:t}}function fs(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=>nr(t(),{tenantId:n,message:r}),list:()=>rr(t(),{tenantId:n}),get:r=>({message:o=>tr(t(),{chatId:r,tenantId:n,message:o}),listMessages:()=>or(t(),{chatId:r,tenantId:n})})}}function ys(e,n){return`[auth-missing:${e}] Authentication required. Direct the user to connect their account: ${n}`}async function Su(e){let n=e.hub;if(n&&e.database&&e.kek)try{let t=await xi(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}):ys(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 _u(e,n,t){let r=nn(Se(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}):ys(e,i),connectUrl:i}}async function Eu(e){let n=e.tenantId??"default",t=e.error.pluginId;return e.manual&&cn(e.manual)&&e.manual.oauthConfig&&e.manual.kek&&e.error.authType==="oauth_2"?_u(t,{...e.manual,baseUrl:e.manual.baseUrl,kek:e.manual.kek},e.tenantId):e.hub&&e.plugin&&e.kek&&e.database&&e.plugins?Su({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 ms(e){let{message:n,connectUrl:t}=await Eu(e);throw new M(e.error.pluginId,e.error.authType,n,{connectUrl:t,tenantId:e.tenantId??"default"})}var $t="connect.request",mo="connect.cleared",Du=600*1e3;async function yo(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 Ou(e,n){return(await e.db.selectFrom("corsair_accounts").select("id").where("tenant_id","=",n).execute()).map(r=>r.id)}async function Mu(e,n,t){let r=await e.db.selectFrom("corsair_events").select("created_at").where("account_id","=",n).where("event_type","in",[$t,mo]).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 hs(e,n,t,r,o){let i=await Mu(e,n,o),s=new Date(i);await e.db.insertInto("corsair_events").values({id:ze(),created_at:s,updated_at:s,account_id:n,event_type:t,payload:r}).execute()}async function Hu(e,n,t=Date.now()){let r=await yo(e,n.tenantId,n.plugin);r&&await hs(e,r,$t,{plugin:n.plugin,connectUrl:n.connectUrl},t)}async function Bu(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",[$t,mo]).orderBy("created_at","desc").limit(1).executeTakeFirst();if(!i||i.event_type!==$t)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 ho(e,n,t=Date.now(),r=Du){let o=await Ou(e,n);if(o.length===0)return null;let i=(await Promise.all(o.map(l=>Bu(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 bs(e,n,t=Date.now(),r){let o;if(r)o=await yo(e,n,r);else{let i=await ho(e,n,t);o=i?await yo(e,n,i.plugin):null}o&&await hs(e,o,mo,{},t)}async function bo(e,n){if(!(!e||!n.plugin||!n.connectUrl))try{await Hu(e,{tenantId:n.tenantId??"default",plugin:n.plugin,connectUrl:n.connectUrl})}catch{}}var Fu=async(e,n)=>(console.error(`[corsair:${n.pluginId}:${n.operation}]`,{error:e.message,input:n.input}),{maxRetries:0});async function ks(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||Fu)(e,i)}function Uu(e){return typeof e=="function"}function ko({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:k,allPlugins:b,multiTenancy:C}){for(let[P,O]of Object.entries(e)){let D=n?.[P];if(Uu(O)){let H=D,w=[...s,P].join("."),A=async(R={})=>{let J=l?.[w];Tr(w,J?.riskLevel??"write");let de;if(c){let N=J,{result:oe,reason:ie,onComplete:Cn,token:Ce,id:He,expiresAt:V}=await Oi({pluginId:o,endpointPath:w,args:R,mode:c.mode,override:c.overrides?.[w],riskLevel:N?.riskLevel??"write",meta:N,db:u,timeoutMs:d?Pr(d.timeout):void 0,tenantId:p,approvalMode:d?.mode});if(oe==="blocked"){let se;throw ie==="denied"?se=`Action '${w}' was denied by the user. Await further instructions before proceeding.`:ie==="policy"?se=`Action '${w}' is blocked by the permission policy. Update the corsair config to allow it.`:ie==="timeout"?se=`Action '${w}' timed out waiting for approval.`:Ce&&He?se=await Cr({permissionsOptions:d,manual:g,hub:f,permissionId:He,permissionToken:Ce,plugin:o,endpoint:w,args:R,tenantId:p??"default",expiresAt:V??new Date(Date.now()+(d?Pr(d.timeout):600*1e3)).toISOString(),operationPath:w}):se=`Action '${w}' requires user approval before it can run.`,new un(se)}de=Cn}let _=async(N,oe,ie)=>{try{return await O(oe,ie)}catch(Cn){if(Cn instanceof Error){let Ce=await ks(Cn,o,w,typeof ie=="object"&&ie!==null?ie:{args:ie},i);if(N<(Ce.maxRetries||0)){let He=N+1;console.log(`Retrying (${He} / ${Ce.maxRetries})...`);let V;if(Ce.headersRetryAfterMs)V=Ce.headersRetryAfterMs;else switch(Ce.retryStrategy){case"exponential_backoff":V=Math.pow(2,He-1)*1e3;break;case"exponential_backoff_jitter":let se=Math.pow(2,He-1)*1e3,va=(Math.random()-.5)*1e3;V=Math.max(0,se+va);break;case"linear_1s":V=1e3;break;case"linear_2s":V=2e3;break;case"linear_3s":V=3e3;break;case"linear_4s":V=4e3;break;default:V=1e3;break}return await new Promise(se=>setTimeout(se,V)),await _(He,oe,ie)}}throw Cn}},re;try{re=a?await a(t,"endpoint"):void 0}catch(N){if(N instanceof pe)throw h&&f&&rn({hub:f,database:u,kek:k,plugins:b??[],plugin:h,tenantId:p,verified:!1}),await bo(u,{tenantId:N.tenantId??p,plugin:N.plugin,connectUrl:N.connectUrl}),N;if(N instanceof M){h&&f&&rn({hub:f,database:u,kek:k,plugins:b??[],plugin:h,tenantId:p,verified:!1});try{await ms({error:N,manual:g,hub:f,plugin:h,tenantId:p,database:u,kek:k,plugins:b,multiTenancy:C})}catch(oe){throw oe instanceof M&&await bo(u,{tenantId:oe.tenantId??p,plugin:oe.pluginId,connectUrl:oe.connectUrl}),oe}}throw N}if(!H?.before&&!H?.after){let N=await _(0,{...t,key:re},R);return await de?.(),h&&f&&rn({hub:f,database:u,kek:k,plugins:b??[],plugin:h,tenantId:p,verified:!0}),N}let wn={...t,key:re},Me=H.before?await H.before(wn,R):{ctx:wn,args:R,continue:!0,passToAfter:void 0};if(Me.continue===!1)return;let Ho=await _(0,Me.ctx,Me.args);return await H.after?.(Me.ctx,Ho,Me.passToAfter),await de?.(),h&&f&&rn({hub:f,database:u,kek:k,plugins:b??[],plugin:h,tenantId:p,verified:!0}),Ho};r[P]=A}else if(O&&typeof O=="object"){let H={};ko({endpoints:O,hooks:D,ctx:t,tree:H,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:k,allPlugins:b,multiTenancy:C}),r[P]=H}}}function Nu(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function wo({webhooks:e,hooks:n,ctx:t,webhooksTree:r,keyBuilder:o}){for(let[i,s]of Object.entries(e)){let a=n?.[i];if(Nu(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={};wo({webhooks:s,hooks:a,ctx:t,webhooksTree:c,keyBuilder:o}),r[i]=c}}}function ws(e){return e&&typeof e=="object"?e:{}}async function Cs(e,n){return W({hub:e,path:`/workflows?tenantId=${encodeURIComponent(n.tenantId)}`,parseResponse:t=>{let r=ws(t).workflows;return Array.isArray(r)?r:[]}})}async function vs(e,n){return W({hub:e,path:`/workflows/${encodeURIComponent(n.workflowId)}?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Workflow "${n.workflowId}" not found`,parseResponse:t=>ws(t).workflow})}async function Ts(e,n){await x({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 Ps(e,n){await x({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 As(e,n){return x({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 Co(e){return e&&typeof e=="object"?e:{}}async function Rs(e,n){return W({hub:e,path:`/runs?tenantId=${encodeURIComponent(n.tenantId)}`,parseResponse:t=>{let r=Co(t).runs;return Array.isArray(r)?r:[]}})}async function xs(e,n){return W({hub:e,path:`/workflows/${encodeURIComponent(n.workflowId)}/runs?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Workflow "${n.workflowId}" not found`,parseResponse:t=>{let r=Co(t).runs;return Array.isArray(r)?r:[]}})}async function Is(e,n){return W({hub:e,path:`/runs/${encodeURIComponent(n.runId)}?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Run "${n.runId}" not found`,parseResponse:t=>Co(t).run})}async function vo(e,n,t){await x({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 Ss=(e,n)=>vo(e,"approve",n),_s=(e,n)=>vo(e,"deny",n),Es=(e,n)=>vo(e,"cancel",n);function Ds(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?xs(t(),{workflowId:r.workflowId,tenantId:n}):Rs(t(),{tenantId:n}),get:r=>Is(t(),{runId:r,tenantId:n}),approve:r=>Ss(t(),{runId:r,tenantId:n}),deny:r=>_s(t(),{runId:r,tenantId:n}),cancel:r=>Es(t(),{runId:r,tenantId:n})}}function Os(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)=>Ts(t(),{workflowId:o,tenantId:n,status:i});return{list:()=>Cs(t(),{tenantId:n}),get:o=>vs(t(),{workflowId:o,tenantId:n}),run:(o,i)=>As(t(),{workflowId:o,tenantId:n,payload:i?.payload,idempotencyKey:i?.idempotencyKey}),runs:Ds(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)=>Ps(t(),{workflowId:o,tenantId:n,name:i})}}function Lu(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 gs({database:e,integrationName:n,tenantId:t,ensureProvisioned:r});return o=i,o}}function $u(e,n,t,r,o){return e?Yt(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 To(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?()=>en(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,k=Lu(t,f.id,u,d);if(h?.entities){let _={};for(let[re,wn]of Object.entries(h.entities)){let Me=t?Yt(t.db,k,re,h.version,wn):$u(void 0,k,re,h.version,wn);_[re]=Me}g[f.id].db=_,p[f.id].db=_}let b=f.options,C=f.authConfig,P;if(t&&o&&b?.authType){let _=C?.[b.authType]?.account??[];P=B({authType:b.authType,integrationName:f.id,tenantId:u,kek:o,database:t,extraAccountFields:_,ensureProvisioned:d}),p[f.id].keys=P}let O={database:t,db:g[f.id]?.db??{},$getAccountId:k,...f.options?{options:f.options}:{},...P?{keys:P,authType:b?.authType}:{},tenantId:u,...c?{hub:c}:{}},D=f.endpoints??{},H=f.hooks,w={...i,...f.errorHandlers},A={},R=f.options?.permissions;ko({endpoints:D,hooks:H,ctx:O,tree:A,pluginId:f.id,errorHandlers:w,currentPath:[],keyBuilder:f.keyBuilder,permissionsConfig:R,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(A).length>0&&(p[f.id].api=A),O.endpoints=A;let J=f.webhooks??{},de=f.webhookHooks;if(Object.keys(J).length>0){let _={};wo({webhooks:J,hooks:de,ctx:O,webhooksTree:_,keyBuilder:f.keyBuilder}),p[f.id].webhooks=_,f.pluginWebhookMatcher&&(p[f.id].pluginWebhookMatcher=f.pluginWebhookMatcher),f.pluginTenantWebhookMatcher&&(p[f.id].pluginTenantWebhookMatcher=f.pluginTenantWebhookMatcher)}}return p.chats=fs(c,u),p.workflows=Os(c,u),p}function Ms(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=U({authType:i.authType,integrationName:o.id,kek:t,database:n,extraIntegrationFields:a});r[o.id]=c}}return r}var Wu="createCorsair({ approval: ... }) is deprecated. Rename to permissions: { timeout, onTimeout, mode }.";function Hs(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] ${Wu}`),t):n}function Ln(e,n){if(e===void 0)return n;if(e===null)throw new T(401,"unauthenticated","Could not determine the tenant for this request. Sign in and retry.");return e}function Wt(e){if(e!==void 0)throw new T(403,"forbidden","This route is disabled when resolveTenant is configured (end-user mode). Use a handler without resolveTenant, behind your own admin auth.")}var Bs=[{method:"GET",pattern:"/ok",handler:async()=>S(200,yt())},{method:"GET",pattern:"/tenants",handler:async({internal:e,scopedTenant:n})=>(Wt(n),S(200,await dn(e)))},{method:"POST",pattern:"/tenants",handler:async({internal:e,body:n,scopedTenant:t})=>(Wt(t),S(201,await bt(e,n)))},{method:"GET",pattern:"/tenants/:id",handler:async({internal:e,params:n,scopedTenant:t})=>(Wt(t),S(200,await ht(e,n.id)))},{method:"GET",pattern:"/plugins",handler:async({internal:e})=>S(200,await ln(e))},{method:"GET",pattern:"/plugins/:id",handler:async({internal:e,params:n})=>S(200,await mt(e,n.id))},{method:"GET",pattern:"/connection-status",handler:async({internal:e,query:n,scopedTenant:t})=>S(200,await kt(e,Ln(t,n.tenantId)))},{method:"GET",pattern:"/permissions/:id",handler:async({internal:e,params:n,scopedTenant:t})=>(Wt(t),S(200,await Rr(e,n.id)))},{method:"POST",pattern:"/permissions/lookup-by-token",handler:async({internal:e,body:n})=>{let t=n?.token?.trim();return t?S(200,await Ir(e,t)):S(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=Ln(r,o.tenantId);return S(200,await Ct(e,n,{...o,tenantId:i}))}},{method:"GET",pattern:"/connect/resolve",handler:async({corsair:e,internal:n,query:t})=>S(200,await vt(e,n,t.state??""))},{method:"POST",pattern:"/connect/oauth/callback",handler:async({corsair:e,internal:n,body:t})=>S(200,await Tt(e,n,t))},{method:"GET",pattern:"/connect/request",handler:async({internal:e,query:n,scopedTenant:t})=>{let r=Ln(t,n.tenantId)??"default",o=e.database?await ho(e.database,r):null;return S(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=Ln(t,r?.tenantId)??"default";return e.database&&await bs(e.database,o,void 0,r?.plugin),S(200,{ok:!0})}},{method:"POST",pattern:"/disconnect",handler:async({internal:e,body:n,scopedTenant:t})=>{let r=n??{},o=Ln(t,r.tenantId);return S(200,await wt(e,{...r,tenantId:o}))}}];(()=>{let e=new Set;for(let n of Bs){let t=`${n.method} ${n.pattern}`;if(e.has(t))throw new Error(`Duplicate management route registered: ${t}`);e.add(t)}})();function ju(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 qu(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 Ku(e,n){if(e.method==="GET"||e.method==="HEAD"||!(e.headers.get("content-type")??"").includes("application/json"))return;let r=await Nt(e,n).catch(o=>{throw o instanceof T?o:new T(400,"invalid_json","Request body is not valid JSON")});if(r)try{return JSON.parse(r)}catch{throw new T(400,"invalid_json","Request body is not valid JSON")}}var Zu="/api/corsair";function L(e,n={}){let t=n.basePath??Zu,r=je(n.maxBodyBytes),o=qe(n.bodyStallTimeoutMs),i={maxBodyBytes:r,bodyStallTimeoutMs:o},s=v(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 yn(r);let l=new URL(a.url),u=qu(l.pathname,t),d=a.method.toUpperCase();if(d==="OPTIONS"||u==="/"||u==="")return await Ke(e,a,{maxBodyBytes:r,bodyStallTimeoutMs:o});if(d!=="GET"&&d!=="POST")return S(405,{error:"method_not_allowed",message:`Method ${d} not allowed`});let p=Object.fromEntries(l.searchParams);for(let g of Bs){if(g.method!==d)continue;let f=ju(g.pattern,u);if(!f)continue;let h=await Ku(a,i),k=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:k})}throw _e(`No route for ${d} ${u}`)}catch(c){if(n.onError){let u=await n.onError(c,a);if(u)return u}if(c instanceof T)return ce(c);let l=c instanceof Error?c.message:"Internal server error";return S(500,{error:"internal_error",message:l})}}}function Gu(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 zu(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 Ju(e,n,t){let r=[],o=0,i=e();try{let s=await Ut(()=>i.next(),t);for(;s.done!==!0;){let a=zu(s.value);if(o+=a.byteLength,o>n)throw yn(n);r.push(a),s=await Ut(()=>i.next(),t)}return Buffer.concat(r)}catch(s){try{Promise.resolve(i.return?.()).catch(()=>{})}catch{}throw s}}var Fs=!1;function Vu(){Fs||(Fs=!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 Yu(e,n){let t=(e.method??"GET").toUpperCase();if(t==="GET"||t==="HEAD")return;let r=je(n.maxBodyBytes),o=qe(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:(Vu(),i=JSON.stringify(e.body));else{let a=e[Symbol.asyncIterator];if(typeof a!="function")return;let c=await Ju(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 yn(r);return typeof i=="string"?i:i}function K(e){e.resume?.()}async function De(e,n={}){let t=Gu(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&&!Qu.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 Yu(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 Z(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 Qu=new Set(["connection","keep-alive","proxy-authenticate","proxy-authorization","te","trailer","transfer-encoding","upgrade","content-length"]);function Us(e,n){let t=L(e,n);return async(r,o,i)=>{try{let s=await t(await De(r,{maxBodyBytes:n?.maxBodyBytes,bodyStallTimeoutMs:n?.bodyStallTimeoutMs}));await Z(o,s)}catch(s){if(s instanceof T&&o.headersSent!==!0){await Z(o,ce(s)),K(r);return}K(r),i(s)}}}function Xu(e,n){let t=e[n];return Array.isArray(t)?t[0]:t}function el(e){let n=(e.method??"GET").toUpperCase();if(n==="GET"||n==="HEAD"||e.body!==void 0||e.rawBody!==void 0)return;let t=Xu(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 Ns(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 Ls(e,n){let t=L(e,n);return async(r,o)=>{el(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 De(i,{maxBodyBytes:n?.maxBodyBytes,bodyStallTimeoutMs:n?.bodyStallTimeoutMs}));o.hijack?.(),await Z(o.raw,s)}catch(s){if(s instanceof T&&o.raw.headersSent!==!0&&o.hijack){o.hijack(),await Z(o.raw,ce(s)),K(i);return}throw K(i),s}}}function $s(e,n){let t=L(e,n);return r=>t(r.req.raw)}function Ws(e,n){let t=L(e,n);return{GET:t,POST:t,OPTIONS:t}}function js(e,n){let t=L(e,n);return async(r,o)=>{try{let i=await t(await De(r,{maxBodyBytes:n?.maxBodyBytes,bodyStallTimeoutMs:n?.bodyStallTimeoutMs}));await Z(o,i)}catch(i){if(o.headersSent===!0){console.error("[corsair] management response failed after headers were sent:",i),o.end?.(),K(r);return}if(i instanceof T){await Z(o,ce(i)),K(r);return}console.error("[corsair] management handler failed:",i),await Z(o,S(500,{error:"internal_error"})),K(r)}}}function jt(e,n){let t=L(e,n);return r=>t(r.request)}function qs(e,n){let t=jt(e,n);return{GET:t,POST:t,OPTIONS:t}}function Ks(e,n){let t=jt(e,n);return{loader:t,action:t}}function Zs(e,n){let t=jt(e,n);return{GET:t,POST:t,OPTIONS:t}}function Gs(e,n){let t=jt(e,n);return{GET:t,POST:t,OPTIONS:t}}function zs(e,n){let t=L(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 De(o,{maxBodyBytes:n?.maxBodyBytes,bodyStallTimeoutMs:n?.bodyStallTimeoutMs}));await Z(r.node.res,i)}catch(i){if(i instanceof T&&r.node.res.headersSent!==!0){await Z(r.node.res,ce(i)),K(o);return}throw K(o),i}}}function Js(e,n){return L(e,n)}function Vs(e){let n={[$n]:e};return{ok:yt,tenants:{list:()=>dn(e),create:t=>bt(e,t),get:t=>ht(e,t)},plugins:{list:()=>ln(e),get:t=>mt(e,t)},connectionStatus:{get:t=>kt(e,t?.tenantId)},permissions:{get:t=>Ui(e,t)},connect:{createLink:t=>Ct(n,e,t),resolve:t=>vt(n,e,t),oauthCallback:t=>Tt(n,e,t)},disconnect:t=>wt(e,t)}}async function Ys(e,n,t,r,o="pending"){if(!e)return null;try{let i=ze(),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 nl(e,n,t,r="pending"){try{let o=await e.$getAccountId();return Ys(e.database,o,n,t,r)}catch(o){return console.warn("Failed to log event:",o),null}}import*as Xs from"https";import*as qt from"querystring";var tl=["expires_in","refresh_token_expires_in"];function Qs(e){let n={...e};for(let t of tl){let r=e[t];if(typeof r=="string"){let o=Number(r);n[t]=Number.isFinite(o)?o:void 0}}return n}function rl(e){try{return Qs(JSON.parse(e))}catch{}if(!e.includes("="))return null;let n=qt.parse(e);return!n.access_token&&!n.error?null:Qs({...n})}function st(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=qt.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=Xs.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=rl(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 ea(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(mn({accessToken:s,expiresAt:a,forceRefresh:n?.forceRefresh}))return{accessToken:s,expiresAt:Number(a),refreshed:!1};if(!c)throw new M(o,"oauth_2");let l=await x({hub:r,path:"/oauth/refresh",body:{plugin:o,tenantId:i,refresh_token:c},parseResponse:Je}),u=await hn(t,l,a);return{accessToken:l.access_token,expiresAt:u,refreshed:!0}}async function na(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 ta(e,n){let t=await e.keys.get_integration_credentials(),r=`${n.plugin}:${e.tenantId}`;if(!t.client_secret){if(!e.hub)throw new M(n.plugin,"oauth_2");let l={keys:e.keys,hub:e.hub,plugin:n.plugin,tenantId:e.tenantId},u=g=>Nn(e.keys,r,async()=>(await ea(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 mn({accessToken:d,expiresAt:p})?d:u(!1)}let o=t.client_secret,i=t.client_id,s=l=>Nn(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&&mn({accessToken:u,expiresAt:d}))return u;if(!p)throw new M(n.plugin,"oauth_2");let g=await na({tokenUrl:n.tokenUrl,tokenAuthMethod:n.tokenAuthMethod,bodyFormat:n.bodyFormat,extraParams:n.extraParams,clientId:i,clientSecret:o,refreshToken:p});return await hn(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 mn({accessToken:a,expiresAt:c})?a:s(!1)}var ra=" ";function ne(e){let n=e;return n._def??n.def??{}}function te(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 ee(e){return e.innerType??e.schema??e.out??e.in}function ia(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 ee(e)}}function sa(e){let n=e.type;return e.element??(typeof n=="string"?void 0:n)}function Zt(e,n){let t=n.shape??e.shape;return typeof t=="function"?t():t}function bn(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 aa(e,n){return e.description??n.description}function ol(e){let n=e;for(;n;){let t=ne(n),r=aa(n,t);if(r)return r;let o=te(t);if(Io(o)||o==="ZodPipe"||o==="ZodEffects"||o==="ZodTransform"){n=ia(t,o);continue}break}}function Io(e){return e==="ZodOptional"||e==="ZodNullable"||e==="ZodDefault"||e==="ZodCatch"}function G(e){let n=ne(e),t=te(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??bn(n)[0]??"unknown");case"ZodEnum":return bn(n).map(r=>String(r)).join(" | ");case"ZodOptional":{let r=ee(n);return r?G(r):"unknown"}case"ZodNullable":{let r=ee(n);return`${r?G(r):"unknown"} | null`}case"ZodDefault":case"ZodCatch":{let r=ee(n);return r?G(r):"unknown"}case"ZodArray":{let r=sa(n);if(!r)return"unknown[]";let o=ne(r),i=te(o)==="ZodUnion",s=G(r);return`${i?`(${s})`:s}[]`}case"ZodRecord":return"{}";case"ZodObject":{let r=Zt(e,n),o=Object.entries(r);return o.length===0?"{}":`{ ${o.map(([s,a])=>{let c=te(ne(a));return`${c==="ZodOptional"||c==="ZodNullable"?s+"?":s}: ${G(a)}`}).join(", ")} }`}case"ZodUnion":return bn(n).map(r=>G(r)).join(" | ");case"ZodIntersection":return`${G(n.left)} & ${G(n.right)}`;case"ZodPipe":case"ZodTransform":case"ZodEffects":{let r=ia(n,t);return r?G(r):"unknown"}default:return(t??"unknown").replace("Zod","").toLowerCase()}}function we(e){let n=ne(e),t=te(n),r=aa(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??bn(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=bn(n).map(i=>String(i));return{kind:"string",optional:!1,description:r,enum:o}}case"ZodOptional":{let o=ee(n),i=o?we(o):{kind:"unknown",optional:!1};return{...i,optional:!0,description:r??i.description}}case"ZodNullable":{let o=ee(n),i=o?we(o):{kind:"unknown",optional:!1};return{...i,optional:!0,description:r??i.description}}case"ZodDefault":case"ZodCatch":{let o=ee(n);return o?{...we(o),description:r}:{kind:"unknown",optional:!1,description:r}}case"ZodArray":{let o=sa(n);return{kind:"array",optional:!1,description:r,items:o?we(o):{kind:"unknown",optional:!1}}}case"ZodObject":{let o=Zt(e,n),i={};for(let[s,a]of Object.entries(o))i[s]=we(a);return{kind:"object",optional:!1,description:r,fields:i}}case"ZodRecord":return{kind:"unknown",optional:!1,description:r};case"ZodUnion":{let o=bn(n);for(let i of o){let s=ne(i);if(te(s)==="ZodObject")return{...we(i),description:r}}return{kind:"unknown",optional:!1,description:r}}case"ZodIntersection":case"ZodPipe":case"ZodTransform":case"ZodEffects":{let o=ee(n);return o?{...we(o),description:r}:{kind:"unknown",optional:!1,description:r}}default:return{kind:"unknown",optional:!1,description:r}}}function hw(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=Oe(s.endpointMeta,a),l=Oe(s.endpointSchemas,a);return!c&&!l?null:{input:l?.input?we(l.input):null,output:l?.output?we(l.output):null,description:c?.description}}var So=["equals","contains","startsWith","endsWith","in"],il=["equals","gt","gte","lt","lte","in"],sl=["equals"],al=["equals","before","after","between"];function ca(e){let n=ne(e);switch(te(n)){case"ZodOptional":case"ZodNullable":case"ZodDefault":case"ZodCatch":{let r=ee(n);return r?ca(r):null}case"ZodString":return"string";case"ZodNumber":return"number";case"ZodBoolean":return"boolean";case"ZodDate":return"date";default:return null}}function _o(e){let n=ne(e),t=te(n);if(Io(t)){let i=ee(n);return i?_o(i):{}}if(t!=="ZodObject")return{};let r=Zt(e,n),o={};for(let[i,s]of Object.entries(r)){let a=ca(s);a==="string"?o[i]={type:"string",operators:So}:a==="number"?o[i]={type:"number",operators:il}:a==="boolean"?o[i]={type:"boolean",operators:sl}:a==="date"&&(o[i]={type:"date",operators:al})}return o}function ua(e,n){for(let[t,r]of Object.entries(e))if(t.toLowerCase()===n)return[t,r]}function Ao(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"&&Ao(o,i,t)}}function Ro(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function xo(e,n,t){for(let[r,o]of Object.entries(e)){let i=[...n,r];Ro(o)?t.push(i.join(".")):o!==null&&typeof o=="object"&&xo(o,i,t)}}function Eo(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 Ro(s)?[i]:null;if(s!==null&&typeof s=="object"&&!Ro(s)){let a=Eo(s,r);if(a!==null)return[i,...a]}return null}function la(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 cl=new Set(qn);function Ge(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 cl.has(r)?`This plugin (${r}) is not configured. Please add it to the Corsair instance to see its associated methods.`:Ge(e);if(t==="webhooks"){if(!i.webhooks)return[];let a=[];return xo(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 Ao(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=[];xo(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=[];Ao(i.endpoints,[],s),o[i.id]=s.map(a=>`${i.id}.api.${a}`)}return o}function Oe(e,n){if(e){for(let[t,r]of Object.entries(e))if(t.toLowerCase()===n)return r}}function ul(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 Po(e,n){return typeof e=="string"?e:Array.isArray(e)?`${n}:
49
+ To generate a KEK, run: openssl rand -base64 ${Ue}`)}})}async function Su(e){let n=!1;for(;;){let t=await e.database.db.selectFrom("corsair_integrations").selectAll().where("name","=",e.integrationName).executeTakeFirst();if(!t){if(!n&&e.ensureProvisioned){n=!0,await e.ensureProvisioned();continue}throw new Error(`Integration "${e.integrationName}" not found. Make sure to create the integration first.`)}let r=await e.database.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",e.tenantId).where("integration_id","=",t.id).executeTakeFirst();if(!r){if(!n&&e.ensureProvisioned){n=!0,await e.ensureProvisioned();continue}throw new Error(`Account not found for tenant "${e.tenantId}" and integration "${e.integrationName}". Make sure to create the account first.`)}return{integrationId:t.id,accountId:r.id,integration:{id:t.id,config:t.config,dek:t.dek??null},account:{id:r.id,config:r.config,dek:r.dek??null}}}}async function ps(e){let{integrationId:n,accountId:t}=await Su(e);return{integrationId:n,accountId:t}}function gs(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=>er(t(),{tenantId:n,message:r}),list:()=>tr(t(),{tenantId:n}),get:r=>({message:o=>nr(t(),{chatId:r,tenantId:n,message:o}),listMessages:()=>rr(t(),{chatId:r,tenantId:n})})}}function fs(e,n){return`[auth-missing:${e}] Authentication required. Direct the user to connect their account: ${n}`}async function _u(e){let n=e.hub;if(n&&e.database&&e.kek)try{let t=await Ri(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}):fs(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 Eu(e,n,t){let r=nn(Se(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}):fs(e,i),connectUrl:i}}async function Du(e){let n=e.tenantId??"default",t=e.error.pluginId;return e.manual&&cn(e.manual)&&e.manual.oauthConfig&&e.manual.kek&&e.error.authType==="oauth_2"?Eu(t,{...e.manual,baseUrl:e.manual.baseUrl,kek:e.manual.kek},e.tenantId):e.hub&&e.plugin&&e.kek&&e.database&&e.plugins?_u({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 ys(e){let{message:n,connectUrl:t}=await Du(e);throw new M(e.error.pluginId,e.error.authType,n,{connectUrl:t,tenantId:e.tenantId??"default"})}var $t="connect.request",yo="connect.cleared",Ou=600*1e3;async function fo(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 Mu(e,n){return(await e.db.selectFrom("corsair_accounts").select("id").where("tenant_id","=",n).execute()).map(r=>r.id)}async function Hu(e,n,t){let r=await e.db.selectFrom("corsair_events").select("created_at").where("account_id","=",n).where("event_type","in",[$t,yo]).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 ms(e,n,t,r,o){let i=await Hu(e,n,o),s=new Date(i);await e.db.insertInto("corsair_events").values({id:ze(),created_at:s,updated_at:s,account_id:n,event_type:t,payload:r}).execute()}async function Bu(e,n,t=Date.now()){let r=await fo(e,n.tenantId,n.plugin);r&&await ms(e,r,$t,{plugin:n.plugin,connectUrl:n.connectUrl},t)}async function Fu(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",[$t,yo]).orderBy("created_at","desc").limit(1).executeTakeFirst();if(!i||i.event_type!==$t)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 mo(e,n,t=Date.now(),r=Ou){let o=await Mu(e,n);if(o.length===0)return null;let i=(await Promise.all(o.map(l=>Fu(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 hs(e,n,t=Date.now(),r){let o;if(r)o=await fo(e,n,r);else{let i=await mo(e,n,t);o=i?await fo(e,n,i.plugin):null}o&&await ms(e,o,yo,{},t)}async function ho(e,n){if(!(!e||!n.plugin||!n.connectUrl))try{await Bu(e,{tenantId:n.tenantId??"default",plugin:n.plugin,connectUrl:n.connectUrl})}catch{}}var Uu=async(e,n)=>(console.error(`[corsair:${n.pluginId}:${n.operation}]`,{error:e.message,input:n.input}),{maxRetries:0});async function bs(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||Uu)(e,i)}function Nu(e){return typeof e=="function"}function bo({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:k,allPlugins:b,multiTenancy:C}){for(let[P,O]of Object.entries(e)){let D=n?.[P];if(Nu(O)){let H=D,w=[...s,P].join("."),A=async(R={})=>{let J=l?.[w];vr(w,J?.riskLevel??"write");let de;if(c){let N=J,{result:oe,reason:ie,onComplete:Cn,token:Ce,id:He,expiresAt:V}=await Di({pluginId:o,endpointPath:w,args:R,mode:c.mode,override:c.overrides?.[w],riskLevel:N?.riskLevel??"write",meta:N,db:u,timeoutMs:d?Tr(d.timeout):void 0,tenantId:p,approvalMode:d?.mode});if(oe==="blocked"){let se;throw ie==="denied"?se=`Action '${w}' was denied by the user. Await further instructions before proceeding.`:ie==="policy"?se=`Action '${w}' is blocked by the permission policy. Update the corsair config to allow it.`:ie==="timeout"?se=`Action '${w}' timed out waiting for approval.`:Ce&&He?se=await wr({permissionsOptions:d,manual:g,hub:f,permissionId:He,permissionToken:Ce,plugin:o,endpoint:w,args:R,tenantId:p??"default",expiresAt:V??new Date(Date.now()+(d?Tr(d.timeout):600*1e3)).toISOString(),operationPath:w}):se=`Action '${w}' requires user approval before it can run.`,new un(se)}de=Cn}let _=async(N,oe,ie)=>{try{return await O(oe,ie)}catch(Cn){if(Cn instanceof Error){let Ce=await bs(Cn,o,w,typeof ie=="object"&&ie!==null?ie:{args:ie},i);if(N<(Ce.maxRetries||0)){let He=N+1;console.log(`Retrying (${He} / ${Ce.maxRetries})...`);let V;if(Ce.headersRetryAfterMs)V=Ce.headersRetryAfterMs;else switch(Ce.retryStrategy){case"exponential_backoff":V=Math.pow(2,He-1)*1e3;break;case"exponential_backoff_jitter":let se=Math.pow(2,He-1)*1e3,va=(Math.random()-.5)*1e3;V=Math.max(0,se+va);break;case"linear_1s":V=1e3;break;case"linear_2s":V=2e3;break;case"linear_3s":V=3e3;break;case"linear_4s":V=4e3;break;default:V=1e3;break}return await new Promise(se=>setTimeout(se,V)),await _(He,oe,ie)}}throw Cn}},re;try{re=a?await a(t,"endpoint"):void 0}catch(N){if(N instanceof pe)throw h&&f&&rn({hub:f,database:u,kek:k,plugins:b??[],plugin:h,tenantId:p,verified:!1}),await ho(u,{tenantId:N.tenantId??p,plugin:N.plugin,connectUrl:N.connectUrl}),N;if(N instanceof M){h&&f&&rn({hub:f,database:u,kek:k,plugins:b??[],plugin:h,tenantId:p,verified:!1});try{await ys({error:N,manual:g,hub:f,plugin:h,tenantId:p,database:u,kek:k,plugins:b,multiTenancy:C})}catch(oe){throw oe instanceof M&&await ho(u,{tenantId:oe.tenantId??p,plugin:oe.pluginId,connectUrl:oe.connectUrl}),oe}}throw N}if(!H?.before&&!H?.after){let N=await _(0,{...t,key:re},R);return await de?.(),h&&f&&rn({hub:f,database:u,kek:k,plugins:b??[],plugin:h,tenantId:p,verified:!0}),N}let wn={...t,key:re},Me=H.before?await H.before(wn,R):{ctx:wn,args:R,continue:!0,passToAfter:void 0};if(Me.continue===!1)return;let Mo=await _(0,Me.ctx,Me.args);return await H.after?.(Me.ctx,Mo,Me.passToAfter),await de?.(),h&&f&&rn({hub:f,database:u,kek:k,plugins:b??[],plugin:h,tenantId:p,verified:!0}),Mo};r[P]=A}else if(O&&typeof O=="object"){let H={};bo({endpoints:O,hooks:D,ctx:t,tree:H,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:k,allPlugins:b,multiTenancy:C}),r[P]=H}}}function Lu(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function ko({webhooks:e,hooks:n,ctx:t,webhooksTree:r,keyBuilder:o}){for(let[i,s]of Object.entries(e)){let a=n?.[i];if(Lu(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={};ko({webhooks:s,hooks:a,ctx:t,webhooksTree:c,keyBuilder:o}),r[i]=c}}}function ks(e){return e&&typeof e=="object"?e:{}}async function ws(e,n){return W({hub:e,path:`/workflows?tenantId=${encodeURIComponent(n.tenantId)}`,parseResponse:t=>{let r=ks(t).workflows;return Array.isArray(r)?r:[]}})}async function Cs(e,n){return W({hub:e,path:`/workflows/${encodeURIComponent(n.workflowId)}?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Workflow "${n.workflowId}" not found`,parseResponse:t=>ks(t).workflow})}async function vs(e,n){await x({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 Ts(e,n){await x({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 Ps(e,n){return x({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 wo(e){return e&&typeof e=="object"?e:{}}async function As(e,n){return W({hub:e,path:`/runs?tenantId=${encodeURIComponent(n.tenantId)}`,parseResponse:t=>{let r=wo(t).runs;return Array.isArray(r)?r:[]}})}async function Rs(e,n){return W({hub:e,path:`/workflows/${encodeURIComponent(n.workflowId)}/runs?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Workflow "${n.workflowId}" not found`,parseResponse:t=>{let r=wo(t).runs;return Array.isArray(r)?r:[]}})}async function xs(e,n){return W({hub:e,path:`/runs/${encodeURIComponent(n.runId)}?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Run "${n.runId}" not found`,parseResponse:t=>wo(t).run})}async function Co(e,n,t){await x({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 Is=(e,n)=>Co(e,"approve",n),Ss=(e,n)=>Co(e,"deny",n),_s=(e,n)=>Co(e,"cancel",n);function Es(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?Rs(t(),{workflowId:r.workflowId,tenantId:n}):As(t(),{tenantId:n}),get:r=>xs(t(),{runId:r,tenantId:n}),approve:r=>Is(t(),{runId:r,tenantId:n}),deny:r=>Ss(t(),{runId:r,tenantId:n}),cancel:r=>_s(t(),{runId:r,tenantId:n})}}function Ds(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)=>vs(t(),{workflowId:o,tenantId:n,status:i});return{list:()=>ws(t(),{tenantId:n}),get:o=>Cs(t(),{workflowId:o,tenantId:n}),run:(o,i)=>Ps(t(),{workflowId:o,tenantId:n,payload:i?.payload,idempotencyKey:i?.idempotencyKey}),runs:Es(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)=>Ts(t(),{workflowId:o,tenantId:n,name:i})}}function $u(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 Wu(e,n,t,r,o){return e?Vt(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 vo(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?()=>en(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,k=$u(t,f.id,u,d);if(h?.entities){let _={};for(let[re,wn]of Object.entries(h.entities)){let Me=t?Vt(t.db,k,re,h.version,wn):Wu(void 0,k,re,h.version,wn);_[re]=Me}g[f.id].db=_,p[f.id].db=_}let b=f.options,C=f.authConfig,P;if(t&&o&&b?.authType){let _=C?.[b.authType]?.account??[];P=B({authType:b.authType,integrationName:f.id,tenantId:u,kek:o,database:t,extraAccountFields:_,ensureProvisioned:d}),p[f.id].keys=P}let O={database:t,db:g[f.id]?.db??{},$getAccountId:k,...f.options?{options:f.options}:{},...P?{keys:P,authType:b?.authType}:{},tenantId:u,...c?{hub:c}:{}},D=f.endpoints??{},H=f.hooks,w={...i,...f.errorHandlers},A={},R=f.options?.permissions;bo({endpoints:D,hooks:H,ctx:O,tree:A,pluginId:f.id,errorHandlers:w,currentPath:[],keyBuilder:f.keyBuilder,permissionsConfig:R,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(A).length>0&&(p[f.id].api=A),O.endpoints=A;let J=f.webhooks??{},de=f.webhookHooks;if(Object.keys(J).length>0){let _={};ko({webhooks:J,hooks:de,ctx:O,webhooksTree:_,keyBuilder:f.keyBuilder}),p[f.id].webhooks=_,f.pluginWebhookMatcher&&(p[f.id].pluginWebhookMatcher=f.pluginWebhookMatcher),f.pluginTenantWebhookMatcher&&(p[f.id].pluginTenantWebhookMatcher=f.pluginTenantWebhookMatcher)}}return p.chats=gs(c,u),p.workflows=Ds(c,u),p}function Os(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=U({authType:i.authType,integrationName:o.id,kek:t,database:n,extraIntegrationFields:a});r[o.id]=c}}return r}var ju="createCorsair({ approval: ... }) is deprecated. Rename to permissions: { timeout, onTimeout, mode }.";function Ms(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] ${ju}`),t):n}function Ln(e,n){if(e===void 0)return n;if(e===null)throw new T(401,"unauthenticated","Could not determine the tenant for this request. Sign in and retry.");return e}function Wt(e){if(e!==void 0)throw new T(403,"forbidden","This route is disabled when resolveTenant is configured (end-user mode). Use a handler without resolveTenant, behind your own admin auth.")}var Hs=[{method:"GET",pattern:"/ok",handler:async()=>S(200,yt())},{method:"GET",pattern:"/tenants",handler:async({internal:e,scopedTenant:n})=>(Wt(n),S(200,await dn(e)))},{method:"POST",pattern:"/tenants",handler:async({internal:e,body:n,scopedTenant:t})=>(Wt(t),S(201,await bt(e,n)))},{method:"GET",pattern:"/tenants/:id",handler:async({internal:e,params:n,scopedTenant:t})=>(Wt(t),S(200,await ht(e,n.id)))},{method:"GET",pattern:"/plugins",handler:async({internal:e})=>S(200,await ln(e))},{method:"GET",pattern:"/plugins/:id",handler:async({internal:e,params:n})=>S(200,await mt(e,n.id))},{method:"GET",pattern:"/connection-status",handler:async({internal:e,query:n,scopedTenant:t})=>S(200,await kt(e,Ln(t,n.tenantId)))},{method:"GET",pattern:"/permissions/:id",handler:async({internal:e,params:n,scopedTenant:t})=>(Wt(t),S(200,await Ar(e,n.id)))},{method:"POST",pattern:"/permissions/lookup-by-token",handler:async({internal:e,body:n})=>{let t=n?.token?.trim();return t?S(200,await xr(e,t)):S(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=Ln(r,o.tenantId);return S(200,await Ct(e,n,{...o,tenantId:i}))}},{method:"GET",pattern:"/connect/resolve",handler:async({corsair:e,internal:n,query:t})=>S(200,await vt(e,n,t.state??""))},{method:"POST",pattern:"/connect/oauth/callback",handler:async({corsair:e,internal:n,body:t})=>S(200,await Tt(e,n,t))},{method:"GET",pattern:"/connect/request",handler:async({internal:e,query:n,scopedTenant:t})=>{let r=Ln(t,n.tenantId)??"default",o=e.database?await mo(e.database,r):null;return S(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=Ln(t,r?.tenantId)??"default";return e.database&&await hs(e.database,o,void 0,r?.plugin),S(200,{ok:!0})}},{method:"POST",pattern:"/disconnect",handler:async({internal:e,body:n,scopedTenant:t})=>{let r=n??{},o=Ln(t,r.tenantId);return S(200,await wt(e,{...r,tenantId:o}))}}];(()=>{let e=new Set;for(let n of Hs){let t=`${n.method} ${n.pattern}`;if(e.has(t))throw new Error(`Duplicate management route registered: ${t}`);e.add(t)}})();function qu(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 Ku(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 Zu(e,n){if(e.method==="GET"||e.method==="HEAD"||!(e.headers.get("content-type")??"").includes("application/json"))return;let r=await Nt(e,n).catch(o=>{throw o instanceof T?o:new T(400,"invalid_json","Request body is not valid JSON")});if(r)try{return JSON.parse(r)}catch{throw new T(400,"invalid_json","Request body is not valid JSON")}}var Gu="/api/corsair";function L(e,n={}){let t=n.basePath??Gu,r=je(n.maxBodyBytes),o=qe(n.bodyStallTimeoutMs),i={maxBodyBytes:r,bodyStallTimeoutMs:o},s=v(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 yn(r);let l=new URL(a.url),u=Ku(l.pathname,t),d=a.method.toUpperCase();if(d==="OPTIONS"||u==="/"||u==="")return await Ke(e,a,{maxBodyBytes:r,bodyStallTimeoutMs:o});if(d!=="GET"&&d!=="POST")return S(405,{error:"method_not_allowed",message:`Method ${d} not allowed`});let p=Object.fromEntries(l.searchParams);for(let g of Hs){if(g.method!==d)continue;let f=qu(g.pattern,u);if(!f)continue;let h=await Zu(a,i),k=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:k})}throw _e(`No route for ${d} ${u}`)}catch(c){if(n.onError){let u=await n.onError(c,a);if(u)return u}if(c instanceof T)return ce(c);let l=c instanceof Error?c.message:"Internal server error";return S(500,{error:"internal_error",message:l})}}}function zu(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 Ju(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 Vu(e,n,t){let r=[],o=0,i=e();try{let s=await Ut(()=>i.next(),t);for(;s.done!==!0;){let a=Ju(s.value);if(o+=a.byteLength,o>n)throw yn(n);r.push(a),s=await Ut(()=>i.next(),t)}return Buffer.concat(r)}catch(s){try{Promise.resolve(i.return?.()).catch(()=>{})}catch{}throw s}}var Bs=!1;function Yu(){Bs||(Bs=!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 Qu(e,n){let t=(e.method??"GET").toUpperCase();if(t==="GET"||t==="HEAD")return;let r=je(n.maxBodyBytes),o=qe(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:(Yu(),i=JSON.stringify(e.body));else{let a=e[Symbol.asyncIterator];if(typeof a!="function")return;let c=await Vu(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 yn(r);return typeof i=="string"?i:i}function K(e){e.resume?.()}async function De(e,n={}){let t=zu(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&&!Xu.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 Qu(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 Z(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 Xu=new Set(["connection","keep-alive","proxy-authenticate","proxy-authorization","te","trailer","transfer-encoding","upgrade","content-length"]);function Fs(e,n){let t=L(e,n);return async(r,o,i)=>{try{let s=await t(await De(r,{maxBodyBytes:n?.maxBodyBytes,bodyStallTimeoutMs:n?.bodyStallTimeoutMs}));await Z(o,s)}catch(s){if(s instanceof T&&o.headersSent!==!0){await Z(o,ce(s)),K(r);return}K(r),i(s)}}}function el(e,n){let t=e[n];return Array.isArray(t)?t[0]:t}function nl(e){let n=(e.method??"GET").toUpperCase();if(n==="GET"||n==="HEAD"||e.body!==void 0||e.rawBody!==void 0)return;let t=el(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 Us(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 Ns(e,n){let t=L(e,n);return async(r,o)=>{nl(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 De(i,{maxBodyBytes:n?.maxBodyBytes,bodyStallTimeoutMs:n?.bodyStallTimeoutMs}));o.hijack?.(),await Z(o.raw,s)}catch(s){if(s instanceof T&&o.raw.headersSent!==!0&&o.hijack){o.hijack(),await Z(o.raw,ce(s)),K(i);return}throw K(i),s}}}function Ls(e,n){let t=L(e,n);return r=>t(r.req.raw)}function $s(e,n){let t=L(e,n);return{GET:t,POST:t,OPTIONS:t}}function Ws(e,n){let t=L(e,n);return async(r,o)=>{try{let i=await t(await De(r,{maxBodyBytes:n?.maxBodyBytes,bodyStallTimeoutMs:n?.bodyStallTimeoutMs}));await Z(o,i)}catch(i){if(o.headersSent===!0){console.error("[corsair] management response failed after headers were sent:",i),o.end?.(),K(r);return}if(i instanceof T){await Z(o,ce(i)),K(r);return}console.error("[corsair] management handler failed:",i),await Z(o,S(500,{error:"internal_error"})),K(r)}}}function jt(e,n){let t=L(e,n);return r=>t(r.request)}function js(e,n){let t=jt(e,n);return{GET:t,POST:t,OPTIONS:t}}function qs(e,n){let t=jt(e,n);return{loader:t,action:t}}function Ks(e,n){let t=jt(e,n);return{GET:t,POST:t,OPTIONS:t}}function Zs(e,n){let t=jt(e,n);return{GET:t,POST:t,OPTIONS:t}}function Gs(e,n){let t=L(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 De(o,{maxBodyBytes:n?.maxBodyBytes,bodyStallTimeoutMs:n?.bodyStallTimeoutMs}));await Z(r.node.res,i)}catch(i){if(i instanceof T&&r.node.res.headersSent!==!0){await Z(r.node.res,ce(i)),K(o);return}throw K(o),i}}}function zs(e,n){return L(e,n)}function Js(e){let n={[$n]:e};return{ok:yt,tenants:{list:()=>dn(e),create:t=>bt(e,t),get:t=>ht(e,t)},plugins:{list:()=>ln(e),get:t=>mt(e,t)},connectionStatus:{get:t=>kt(e,t?.tenantId)},permissions:{get:t=>Fi(e,t)},connect:{createLink:t=>Ct(n,e,t),resolve:t=>vt(n,e,t),oauthCallback:t=>Tt(n,e,t)},disconnect:t=>wt(e,t)}}async function Vs(e,n,t,r,o="pending"){if(!e)return null;try{let i=ze(),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 tl(e,n,t,r="pending"){try{let o=await e.$getAccountId();return Vs(e.database,o,n,t,r)}catch(o){return console.warn("Failed to log event:",o),null}}import*as Qs from"https";import*as qt from"querystring";var rl=["expires_in","refresh_token_expires_in"];function Ys(e){let n={...e};for(let t of rl){let r=e[t];if(typeof r=="string"){let o=Number(r);n[t]=Number.isFinite(o)?o:void 0}}return n}function ol(e){try{return Ys(JSON.parse(e))}catch{}if(!e.includes("="))return null;let n=qt.parse(e);return!n.access_token&&!n.error?null:Ys({...n})}function st(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=qt.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=Qs.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=ol(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 Xs(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(mn({accessToken:s,expiresAt:a,forceRefresh:n?.forceRefresh}))return{accessToken:s,expiresAt:Number(a),refreshed:!1};if(!c)throw new M(o,"oauth_2");let l=await x({hub:r,path:"/oauth/refresh",body:{plugin:o,tenantId:i,refresh_token:c},parseResponse:Je}),u=await hn(t,l,a);return{accessToken:l.access_token,expiresAt:u,refreshed:!0}}async function ea(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 na(e,n){let t=await e.keys.get_integration_credentials(),r=`${n.plugin}:${e.tenantId}`;if(!t.client_secret){if(!e.hub)throw new M(n.plugin,"oauth_2");let l={keys:e.keys,hub:e.hub,plugin:n.plugin,tenantId:e.tenantId},u=g=>Nn(e.keys,r,async()=>(await Xs(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 mn({accessToken:d,expiresAt:p})?d:u(!1)}let o=t.client_secret,i=t.client_id,s=l=>Nn(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&&mn({accessToken:u,expiresAt:d}))return u;if(!p)throw new M(n.plugin,"oauth_2");let g=await ea({tokenUrl:n.tokenUrl,tokenAuthMethod:n.tokenAuthMethod,bodyFormat:n.bodyFormat,extraParams:n.extraParams,clientId:i,clientSecret:o,refreshToken:p});return await hn(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 mn({accessToken:a,expiresAt:c})?a:s(!1)}var ta=" ";function ne(e){let n=e;return n._def??n.def??{}}function te(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 ee(e){return e.innerType??e.schema??e.out??e.in}function oa(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 ee(e)}}function ia(e){let n=e.type;return e.element??(typeof n=="string"?void 0:n)}function Zt(e,n){let t=n.shape??e.shape;return typeof t=="function"?t():t}function bn(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 il(e){let n=e;for(;n;){let t=ne(n),r=sa(n,t);if(r)return r;let o=te(t);if(xo(o)||o==="ZodPipe"||o==="ZodEffects"||o==="ZodTransform"){n=oa(t,o);continue}break}}function xo(e){return e==="ZodOptional"||e==="ZodNullable"||e==="ZodDefault"||e==="ZodCatch"}function G(e){let n=ne(e),t=te(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??bn(n)[0]??"unknown");case"ZodEnum":return bn(n).map(r=>String(r)).join(" | ");case"ZodOptional":{let r=ee(n);return r?G(r):"unknown"}case"ZodNullable":{let r=ee(n);return`${r?G(r):"unknown"} | null`}case"ZodDefault":case"ZodCatch":{let r=ee(n);return r?G(r):"unknown"}case"ZodArray":{let r=ia(n);if(!r)return"unknown[]";let o=ne(r),i=te(o)==="ZodUnion",s=G(r);return`${i?`(${s})`:s}[]`}case"ZodRecord":return"{}";case"ZodObject":{let r=Zt(e,n),o=Object.entries(r);return o.length===0?"{}":`{ ${o.map(([s,a])=>{let c=te(ne(a));return`${c==="ZodOptional"||c==="ZodNullable"?s+"?":s}: ${G(a)}`}).join(", ")} }`}case"ZodUnion":return bn(n).map(r=>G(r)).join(" | ");case"ZodIntersection":return`${G(n.left)} & ${G(n.right)}`;case"ZodPipe":case"ZodTransform":case"ZodEffects":{let r=oa(n,t);return r?G(r):"unknown"}default:return(t??"unknown").replace("Zod","").toLowerCase()}}function we(e){let n=ne(e),t=te(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??bn(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=bn(n).map(i=>String(i));return{kind:"string",optional:!1,description:r,enum:o}}case"ZodOptional":{let o=ee(n),i=o?we(o):{kind:"unknown",optional:!1};return{...i,optional:!0,description:r??i.description}}case"ZodNullable":{let o=ee(n),i=o?we(o):{kind:"unknown",optional:!1};return{...i,optional:!0,description:r??i.description}}case"ZodDefault":case"ZodCatch":{let o=ee(n);return o?{...we(o),description:r}:{kind:"unknown",optional:!1,description:r}}case"ZodArray":{let o=ia(n);return{kind:"array",optional:!1,description:r,items:o?we(o):{kind:"unknown",optional:!1}}}case"ZodObject":{let o=Zt(e,n),i={};for(let[s,a]of Object.entries(o))i[s]=we(a);return{kind:"object",optional:!1,description:r,fields:i}}case"ZodRecord":return{kind:"unknown",optional:!1,description:r};case"ZodUnion":{let o=bn(n);for(let i of o){let s=ne(i);if(te(s)==="ZodObject")return{...we(i),description:r}}return{kind:"unknown",optional:!1,description:r}}case"ZodIntersection":case"ZodPipe":case"ZodTransform":case"ZodEffects":{let o=ee(n);return o?{...we(o),description:r}:{kind:"unknown",optional:!1,description:r}}default:return{kind:"unknown",optional:!1,description:r}}}function Cw(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=Oe(s.endpointMeta,a),l=Oe(s.endpointSchemas,a);return!c&&!l?null:{input:l?.input?we(l.input):null,output:l?.output?we(l.output):null,description:c?.description}}var Io=["equals","contains","startsWith","endsWith","in"],sl=["equals","gt","gte","lt","lte","in"],al=["equals"],cl=["equals","before","after","between"];function aa(e){let n=ne(e);switch(te(n)){case"ZodOptional":case"ZodNullable":case"ZodDefault":case"ZodCatch":{let r=ee(n);return r?aa(r):null}case"ZodString":return"string";case"ZodNumber":return"number";case"ZodBoolean":return"boolean";case"ZodDate":return"date";default:return null}}function So(e){let n=ne(e),t=te(n);if(xo(t)){let i=ee(n);return i?So(i):{}}if(t!=="ZodObject")return{};let r=Zt(e,n),o={};for(let[i,s]of Object.entries(r)){let a=aa(s);a==="string"?o[i]={type:"string",operators:Io}:a==="number"?o[i]={type:"number",operators:sl}:a==="boolean"?o[i]={type:"boolean",operators:al}:a==="date"&&(o[i]={type:"date",operators:cl})}return o}function ca(e,n){for(let[t,r]of Object.entries(e))if(t.toLowerCase()===n)return[t,r]}function Po(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"&&Po(o,i,t)}}function Ao(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function Ro(e,n,t){for(let[r,o]of Object.entries(e)){let i=[...n,r];Ao(o)?t.push(i.join(".")):o!==null&&typeof o=="object"&&Ro(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 Ao(s)?[i]:null;if(s!==null&&typeof s=="object"&&!Ao(s)){let a=_o(s,r);if(a!==null)return[i,...a]}return null}function ua(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 ul=new Set(qn);function Ge(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 ul.has(r)?`This plugin (${r}) is not configured. Please add it to the Corsair instance to see its associated methods.`:Ge(e);if(t==="webhooks"){if(!i.webhooks)return[];let a=[];return Ro(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 Po(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=[];Ro(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=[];Po(i.endpoints,[],s),o[i.id]=s.map(a=>`${i.id}.api.${a}`)}return o}function Oe(e,n){if(e){for(let[t,r]of Object.entries(e))if(t.toLowerCase()===n)return r}}function ll(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 To(e,n){return typeof e=="string"?e:Array.isArray(e)?`${n}:
51
51
  ${e.join(", ")}`:`${n}:
52
52
  `+Object.entries(e).map(([t,r])=>` ${t}: ${r.join(", ")}`).join(`
53
- `)}function bw(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=ua(f,p);if(h){let[k,b]=h,C=_o(b),P=[`Search ${o} ${k} stored in the local database.`,"Pass limit and offset as numbers for pagination.","","filters {",` entity_id: string [${So.join(", ")}]`];for(let[O,D]of Object.entries(C))P.push(` ${O}?: ${D.type} [${D.operators.join(", ")}]`);return P.push("}"),P.join(`
54
- `)}}}return Po(Ge(e,{type:"db"}),"Path not found. Available db operations")}if(i.startsWith("webhooks.")){let u=i.slice(9);if(s.webhooks){let d=Eo(s.webhooks,u.split("."));if(d!==null){let p=d.join("."),g=Oe(s.webhookSchemas,p.toLowerCase()),f=g?.response?G(g.response):null,h=[];return g?.description&&h.push(g.description),g?.payload&&h.push(`payload ${Kt(kn(g.payload))}`),f&&h.push(`response: ${f}`),h.push(`usage:
55
- ${la(o,d)}`),h.join(`
53
+ `)}function vw(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=ca(f,p);if(h){let[k,b]=h,C=So(b),P=[`Search ${o} ${k} stored in the local database.`,"Pass limit and offset as numbers for pagination.","","filters {",` entity_id: string [${Io.join(", ")}]`];for(let[O,D]of Object.entries(C))P.push(` ${O}?: ${D.type} [${D.operators.join(", ")}]`);return P.push("}"),P.join(`
54
+ `)}}}return To(Ge(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=Oe(s.webhookSchemas,p.toLowerCase()),f=g?.response?G(g.response):null,h=[];return g?.description&&h.push(g.description),g?.payload&&h.push(`payload ${Kt(kn(g.payload))}`),f&&h.push(`response: ${f}`),h.push(`usage:
55
+ ${ua(o,d)}`),h.join(`
56
56
 
57
- `)}}return Po(Ge(e,{type:"webhooks"}),"Path not found. Available webhooks")}let a=i;a.startsWith("api.")&&(a=a.slice(4));let c=Oe(s.endpointMeta,a),l=Oe(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 ${Kt(kn(l.input))}`),l?.output&&u.push(`output ${Kt(kn(l.output))}`),u.join(`
57
+ `)}}return To(Ge(e,{type:"webhooks"}),"Path not found. Available webhooks")}let a=i;a.startsWith("api.")&&(a=a.slice(4));let c=Oe(s.endpointMeta,a),l=Oe(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 ${Kt(kn(l.input))}`),l?.output&&u.push(`output ${Kt(kn(l.output))}`),u.join(`
58
58
 
59
- `)}}}return Po(Ge(e),"Path not found. Available operations")}function oa(e){let n=e;for(;;){let t=ne(n),r=te(t);if(Io(r)){let o=ee(t);if(!o)return n;n=o;continue}return n}}function kn(e){if(e===void 0)return{kind:"inline",type:"unknown"};let n=oa(e),t=ne(n);if(te(t)==="ZodObject"){let o=Zt(n,t),i=[];for(let[s,a]of Object.entries(o)){let c=ne(a),l=te(c),u=l==="ZodOptional"||l==="ZodNullable",d=oa(a),p=ol(a);i.push({key:s,optional:u,type:G(d),...p!==void 0?{description:p}:{}})}return{kind:"object",fields:i}}return{kind:"inline",type:G(n)}}function Kt(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`{
59
+ `)}}}return To(Ge(e),"Path not found. Available operations")}function ra(e){let n=e;for(;;){let t=ne(n),r=te(t);if(xo(r)){let o=ee(t);if(!o)return n;n=o;continue}return n}}function kn(e){if(e===void 0)return{kind:"inline",type:"unknown"};let n=ra(e),t=ne(n);if(te(t)==="ZodObject"){let o=Zt(n,t),i=[];for(let[s,a]of Object.entries(o)){let c=ne(a),l=te(c),u=l==="ZodOptional"||l==="ZodNullable",d=ra(a),p=il(a);i.push({key:s,optional:u,type:G(d),...p!==void 0?{description:p}:{}})}return{kind:"object",fields:i}}return{kind:"inline",type:G(n)}}function Kt(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=ta.repeat(n+1),r=ta.repeat(n);return`{
60
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
61
  `)}
62
- ${r}}`}return"unknown"}function ll(e,n){let t=Ge(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}=ul(u,n),g=Oe(r.endpointMeta,p),f=Oe(r.endpointSchemas,p);!g&&!f||o.push({path:u,shortPath:d,description:g?.description,riskLevel:g?.riskLevel,irreversible:g?.irreversible,input:kn(f?.input),output:kn(f?.output)})}o.sort((u,d)=>u.path.localeCompare(d.path));let i=[],s=Ge(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=Eo(r.webhooks,f.split("."));if(h===null)continue;let k=h.join("."),b=Oe(r.webhookSchemas,k.toLowerCase()),C=b?.response?G(b.response):void 0;i.push({path:u,description:b?.description,payload:kn(b?.payload),responseType:C,usageExample:la(n,h)})}i.sort((u,d)=>u.path.localeCompare(d.path));let a=[],c=Ge(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 k=f.slice(0,h);if(f.slice(h+1)!=="search")continue;let C=ua(l,k);if(!C)continue;let[P,O]=C,D=_o(O),H=Object.entries(D).map(([w,A])=>({field:w,type:A.type,operators:A.operators}));a.push({path:u,entityName:P,filters:[{field:"entity_id",type:"string",operators:So},...H]})}return a.sort((u,d)=>u.path.localeCompare(d.path)),{ok:!0,data:{pluginId:n,api:o,webhooks:i,db:a}}}import{randomUUID as da}from"crypto";async function dl(e,n){let t=await e.keys.get_access_token();if(!t)return null;let r=da(),o=da(),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 pl}from"crypto";var Gt="https://graph.microsoft.com/v1.0",Do=2e4,gl=60;async function fl(e,n){let t=await e.keys.get_access_token();if(!t)return null;let r={authorization:`Bearer ${t}`};try{let c=await fetch(`${Gt}/subscriptions`,{headers:r,signal:AbortSignal.timeout(Do)});if(c.ok){let{value:l}=await c.json(),u=(l??[]).filter(d=>d.notificationUrl===n.webhookUrl);await Promise.all(u.map(d=>fetch(`${Gt}/subscriptions/${d.id}`,{method:"DELETE",headers:r,signal:AbortSignal.timeout(Do)}).catch(()=>{})))}}catch{}let o=pl(),i=new Date(Date.now()+gl*6e4).toISOString(),s=await fetch(`${Gt}/subscriptions`,{method:"POST",headers:{...r,"content-type":"application/json"},signal:AbortSignal.timeout(Do),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 pa(e,n){for(let[t,r]of Object.entries(e))if(r?.pluginWebhookMatcher&&r.pluginWebhookMatcher(n))return t;return null}function yl(e,n){let t=pa(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 ml(e){let n={};for(let t of e)!t.pluginWebhookMatcher&&!t.pluginTenantWebhookMatcher||(n[t.id]={pluginWebhookMatcher:t.pluginWebhookMatcher,pluginTenantWebhookMatcher:t.pluginTenantWebhookMatcher});return n}function ga(e,n){let t=n.toLowerCase(),r=e[t]??e[n];return Array.isArray(r)?r[0]:typeof r=="string"?r:void 0}function fa(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 Wn(e){return!e||typeof e!="object"||Array.isArray(e)?null:e}function hl(e){return Wn(e.body)}function ya(e,n){let t=e.query;if(!t)return;let r=t[n]??t[n.toLowerCase()];return zt(Array.isArray(r)?r:[r])}function ma(e){let n=e.headers??{},t=[n.validationtoken,n.validationToken,n["validation-token"],n["ms-validation-token"]];for(let c of t){let l=zt(Array.isArray(c)?c:[c]);if(l)return decodeURIComponent(l)}let r=ya({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=Wn(typeof i=="string"?(()=>{try{return JSON.parse(i)}catch{return i}})():i);return zt([s?.validationToken])??null}function bl(e){if(ma(e))return!0;let n=Wn(e.body??e.payload);return ga(e.headers??{},"content-type")?.includes("text/plain")?!n||Object.keys(n).length===0:!1}function zt(e){for(let n of e){let t=fa(n);if(t)return t}}function kl(e){let t=Wn(e.message)?.data;if(typeof t!="string")return null;try{return JSON.parse(Buffer.from(t,"base64").toString("utf8"))}catch{return null}}var $n=Symbol.for("corsair:internal");function ka(e){let n=e.database?Bo(e.database):void 0,t=e.kek,r=n&&t?Ms(e.plugins,n,t):Lt(!!n,!!t),o=Hs(e),i={plugins:e.plugins,database:n,kek:t,multiTenancy:!!e.multiTenancy,permissions:o,manual:e.manual,hub:e.hub?Yn(e.hub):void 0},s=Di(n),a=Vs(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=To(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,{[$n]:i})},keys:r,permissions:s,manage:a},{[$n]:i});return ha(u,i.hub),ba(u,i.hub),u}let c=To(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,[$n]:i});return ha(l,i.hub),ba(l,i.hub),l}function ha(e,n){n?.projectApiKey?.startsWith("ck_dev_")&&import("./loop-W4VG4EZ2.js").then(t=>t.startConnectLoop(e)).catch(()=>{})}function wl(e){return e?.projectApiKey?.startsWith("ck_dev_")?e.tunnel!==!1&&process.env.CORSAIR_TUNNEL!=="0":!1}var Jt=globalThis.__corsairTunnels??=new Set;function ba(e,n){if(!wl(n))return;let t=n.projectApiKey;if(Jt.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}Jt.add(t);let o=typeof n.tunnel=="object"?n.tunnel:{},i=process.env.CORSAIR_FRP_HOST??o.shareHost??Qt;import("./hub/tunnel/run-tunnel.js").then(s=>s.runTunnel({port:r,apiUrl:n.apiUrl,apiKey:t,shareHost:i,onClose:()=>Jt.delete(t)})).then(({url:s})=>{console.log(`[corsair] tunnel active: ${s}${Xt}`)}).catch(s=>{Jt.delete(t),console.warn(`[corsair] tunnel failed to start: ${s instanceof Error?s.message:String(s)}. Run \`corsair setup\` to enable your dev tunnel.`)})}var Cl={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:{}}}},Oo=Cl;async function at(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=Uo(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=Ol(e,a.plugins,n),l={...a,database:a.database},u=l.database.db;await Bl(u,i);let d=await Fl(u,l,c.tenantId,c.provisionAccounts,o);n?.credentials&&Object.keys(n.credentials).length>0&&await Ll(e,c,n.credentials,l,o,i);let p=await Wl(d,c,o,s);if(n?.backfill){o("[corsair:setup] Starting backfill...");let g=ka({plugins:a.plugins,database:u,kek:a.kek,multiTenancy:!0}).withTenant(c.tenantId);await jl(g,a.plugins,p,o,i),o("[corsair:setup] Backfill complete.")}return t.join(`
63
- `)}function Mo(e,n,t){let r=t==="integration"?e.authConfig?.[n]?.integration??[]:e.authConfig?.[n]?.account??[];return new Set([...$[n][t],...r])}function Dl(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=I(o);if(!i)continue;let s=Mo(o,i,"account");for(let a of Object.keys(r))if(s.has(a))return!0}return!1}function Ol(e,n,t){let r=No(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&&Dl(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 Ca(e,n){return Te(e)?n===0?!0:Object.values(e).every(t=>Ca(t,n-1)):!1}function Ml(e){return Ca(e,4)}var Hl=$o;function Vt(e){if(e instanceof xl){let n={};for(let[t,r]of Object.entries(e.shape))n[t]=r instanceof El?Vt(r):"unknown";return n}return e instanceof Al?`${Vt(e.unwrap())} | null`:e instanceof Il?`${Vt(e.unwrap())} | undefined`:e instanceof Pl?e.options.join(" | "):e instanceof _l?"string":e instanceof Rl?"number":e instanceof vl?"boolean":e instanceof Tl?"date":e instanceof Sl?"jsonb":"unknown"}async function Bl(e,n){let t=await e.introspection.getTables(),r=new Set(t.map(o=>o.name));for(let[o,i]of Object.entries(Hl))r.has(o)||n(`[corsair:setup] Table "${o}" does not exist. Run your database migrations before calling setupCorsair.
64
- Schema: ${JSON.stringify(Vt(i),null,2)}`)}async function Fl(e,n,t,r,o){let i=new Date,s=new Map;for(let a of n.plugins){let c=a.id,l=I(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?U({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 k=crypto.randomUUID();await e.insertInto("corsair_accounts").values({id:k,tenant_id:t,integration_id:u.id,config:{},created_at:i,updated_at:i}).execute(),h=await e.selectFrom("corsair_accounts").selectAll().where("id","=",k).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:[...$[l].integration,...d],accountFields:r?[...$[l].account,...p]:[]})}return s}function Ul(e){if(!Te(e))return;let n=e.keys;return Te(n)?n:void 0}function Nl(e,n){return"withTenant"in e&&typeof e.withTenant=="function"?e.withTenant(n):e}async function Ll(e,n,t,r,o,i){let s=Ul(e),a=n.provisionAccounts?Nl(e,n.tenantId):void 0;for(let[c,l]of Object.entries(t)){let u=r.plugins.find(b=>b.id===c);if(!u){i(`[corsair:setup] Unknown plugin '${c}' \u2014 skipping credentials.`);continue}let d=I(u);if(!d){i(`[corsair:setup] Plugin '${c}' has no auth type \u2014 skipping credentials.`);continue}let p=Mo(u,d,"integration"),g=Mo(u,d,"account"),f=s?.[c],h=a?.[c],k=Te(h)?h.keys:void 0;for(let[b,C]of Object.entries(l))if(C){if(p.has(b)){if(n.multiTenant&&n.tenantIdProvided)throw new Error(`[corsair:setup] '${c}.${b}' 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=z(f,`set_${b}`);if(!P){i(`[corsair:setup] Cannot set integration field '${b}' for '${c}'.`);continue}await P(C),o(`[corsair:setup] Set ${c} integration.${b}`);continue}if(g.has(b)){if(n.multiTenant&&!n.tenantIdProvided)throw new Error(`setupCorsair: tenantId is required to set account-level credential '${c}.${b}' on a multi-tenant instance`);let P=z(k,`set_${b}`);if(!P){i(`[corsair:setup] Cannot set account field '${b}' for '${c}'.`);continue}await P(C),o(`[corsair:setup] Set ${c} account.${b} (tenant=${n.tenantId})`);continue}i(`[corsair:setup] Unknown credential field '${b}' for plugin '${c}'.`)}}}var wa=new Set(["webhook_signature","expires_at","scope","redirect_url"]);async function $l(e,n,t,r,o,i,s,a,c){let l=[],u=[];for(let p of o){if(wa.has(p))continue;let g=z(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(wa.has(p))continue;let g=z(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:
62
+ ${r}}`}return"unknown"}function dl(e,n){let t=Ge(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}=ll(u,n),g=Oe(r.endpointMeta,p),f=Oe(r.endpointSchemas,p);!g&&!f||o.push({path:u,shortPath:d,description:g?.description,riskLevel:g?.riskLevel,irreversible:g?.irreversible,input:kn(f?.input),output:kn(f?.output)})}o.sort((u,d)=>u.path.localeCompare(d.path));let i=[],s=Ge(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 k=h.join("."),b=Oe(r.webhookSchemas,k.toLowerCase()),C=b?.response?G(b.response):void 0;i.push({path:u,description:b?.description,payload:kn(b?.payload),responseType:C,usageExample:ua(n,h)})}i.sort((u,d)=>u.path.localeCompare(d.path));let a=[],c=Ge(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 k=f.slice(0,h);if(f.slice(h+1)!=="search")continue;let C=ca(l,k);if(!C)continue;let[P,O]=C,D=So(O),H=Object.entries(D).map(([w,A])=>({field:w,type:A.type,operators:A.operators}));a.push({path:u,entityName:P,filters:[{field:"entity_id",type:"string",operators:Io},...H]})}return a.sort((u,d)=>u.path.localeCompare(d.path)),{ok:!0,data:{pluginId:n,api:o,webhooks:i,db:a}}}import{randomUUID as la}from"crypto";async function pl(e,n){let t=await e.keys.get_access_token();if(!t)return null;let r=la(),o=la(),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 gl}from"crypto";var Gt="https://graph.microsoft.com/v1.0",Eo=2e4,fl=60;async function yl(e,n){let t=await e.keys.get_access_token();if(!t)return null;let r={authorization:`Bearer ${t}`};try{let c=await fetch(`${Gt}/subscriptions`,{headers:r,signal:AbortSignal.timeout(Eo)});if(c.ok){let{value:l}=await c.json(),u=(l??[]).filter(d=>d.notificationUrl===n.webhookUrl);await Promise.all(u.map(d=>fetch(`${Gt}/subscriptions/${d.id}`,{method:"DELETE",headers:r,signal:AbortSignal.timeout(Eo)}).catch(()=>{})))}}catch{}let o=gl(),i=new Date(Date.now()+fl*6e4).toISOString(),s=await fetch(`${Gt}/subscriptions`,{method:"POST",headers:{...r,"content-type":"application/json"},signal:AbortSignal.timeout(Eo),body:JSON.stringify({changeType:n.changeType,notificationUrl:n.webhookUrl,resource:n.resource,expirationDateTime:i,clientState:o})});if(!s.ok)throw new Error(`MS Graph subscribe failed (${s.status}): ${await s.text()}`);let a=await s.json();return a.id?(await e.keys.set_webhook_signature(o),{webhookLink:{linkType:"subscription_id",externalId:a.id},webhookSecret:o}):null}function da(e,n){for(let[t,r]of Object.entries(e))if(r?.pluginWebhookMatcher&&r.pluginWebhookMatcher(n))return t;return null}function ml(e,n){let t=da(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 hl(e){let n={};for(let t of e)!t.pluginWebhookMatcher&&!t.pluginTenantWebhookMatcher||(n[t.id]={pluginWebhookMatcher:t.pluginWebhookMatcher,pluginTenantWebhookMatcher:t.pluginTenantWebhookMatcher});return n}function pa(e,n){let t=n.toLowerCase(),r=e[t]??e[n];return Array.isArray(r)?r[0]:typeof r=="string"?r:void 0}function ga(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 Wn(e){return!e||typeof e!="object"||Array.isArray(e)?null:e}function bl(e){return Wn(e.body)}function fa(e,n){let t=e.query;if(!t)return;let r=t[n]??t[n.toLowerCase()];return zt(Array.isArray(r)?r:[r])}function ya(e){let n=e.headers??{},t=[n.validationtoken,n.validationToken,n["validation-token"],n["ms-validation-token"]];for(let c of t){let l=zt(Array.isArray(c)?c:[c]);if(l)return decodeURIComponent(l)}let r=fa({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=Wn(typeof i=="string"?(()=>{try{return JSON.parse(i)}catch{return i}})():i);return zt([s?.validationToken])??null}function kl(e){if(ya(e))return!0;let n=Wn(e.body??e.payload);return pa(e.headers??{},"content-type")?.includes("text/plain")?!n||Object.keys(n).length===0:!1}function zt(e){for(let n of e){let t=ga(n);if(t)return t}}function wl(e){let t=Wn(e.message)?.data;if(typeof t!="string")return null;try{return JSON.parse(Buffer.from(t,"base64").toString("utf8"))}catch{return null}}var $n=Symbol.for("corsair:internal");function ka(e){let n=e.database?Ho(e.database):void 0,t=e.kek,r=n&&t?Os(e.plugins,n,t):Lt(!!n,!!t),o=Ms(e),i={plugins:e.plugins,database:n,kek:t,multiTenancy:!!e.multiTenancy,permissions:o,manual:e.manual,hub:e.hub?Yn(e.hub):void 0},s=Ei(n),a=Js(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=vo(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,{[$n]:i})},keys:r,permissions:s,manage:a},{[$n]:i});return ma(u,i.hub),ba(u,i.hub),u}let c=vo(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,[$n]:i});return ma(l,i.hub),ba(l,i.hub),l}function ma(e,n){n?.projectApiKey?.startsWith("ck_dev_")&&import("./loop-335YKNR2.js").then(t=>t.startConnectLoop(e)).catch(()=>{})}function Cl(e){return e?.projectApiKey?.startsWith("ck_dev_")?e.tunnel!==!1&&process.env.CORSAIR_TUNNEL!=="0":!1}var ha=globalThis.__corsairTunnels??=new Set,vl=1e3,Tl=3e4;function Pl(e){let n=e.schedule??((s,a)=>void setTimeout(s,a).unref?.()),t=e.minDelayMs??vl,r=e.maxDelayMs??Tl,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 ba(e,n){if(!Cl(n))return;let t=n.projectApiKey;if(ha.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}ha.add(t);let o=typeof n.tunnel=="object"?n.tunnel:{},i=process.env.CORSAIR_FRP_HOST??o.shareHost??Yt;Pl({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}${Qt}`)}).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 Al={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:{}}}},Do=Al;async function at(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=Fo(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=Fl(e,a.plugins,n),l={...a,database:a.database},u=l.database.db;await Ll(u,i);let d=await $l(u,l,c.tenantId,c.provisionAccounts,o);n?.credentials&&Object.keys(n.credentials).length>0&&await ql(e,c,n.credentials,l,o,i);let p=await Zl(d,c,o,s);if(n?.backfill){o("[corsair:setup] Starting backfill...");let g=ka({plugins:a.plugins,database:u,kek:a.kek,multiTenancy:!0}).withTenant(c.tenantId);await Gl(g,a.plugins,p,o,i),o("[corsair:setup] Backfill complete.")}return t.join(`
63
+ `)}function Oo(e,n,t){let r=t==="integration"?e.authConfig?.[n]?.integration??[]:e.authConfig?.[n]?.account??[];return new Set([...$[n][t],...r])}function Bl(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=I(o);if(!i)continue;let s=Oo(o,i,"account");for(let a of Object.keys(r))if(s.has(a))return!0}return!1}function Fl(e,n,t){let r=Uo(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&&Bl(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 Ca(e,n){return Te(e)?n===0?!0:Object.values(e).every(t=>Ca(t,n-1)):!1}function Ul(e){return Ca(e,4)}var Nl=Lo;function Jt(e){if(e instanceof El){let n={};for(let[t,r]of Object.entries(e.shape))n[t]=r instanceof Hl?Jt(r):"unknown";return n}return e instanceof Sl?`${Jt(e.unwrap())} | null`:e instanceof Dl?`${Jt(e.unwrap())} | undefined`:e instanceof Il?e.options.join(" | "):e instanceof Ml?"string":e instanceof _l?"number":e instanceof Rl?"boolean":e instanceof xl?"date":e instanceof Ol?"jsonb":"unknown"}async function Ll(e,n){let t=await e.introspection.getTables(),r=new Set(t.map(o=>o.name));for(let[o,i]of Object.entries(Nl))r.has(o)||n(`[corsair:setup] Table "${o}" does not exist. Run your database migrations before calling setupCorsair.
64
+ Schema: ${JSON.stringify(Jt(i),null,2)}`)}async function $l(e,n,t,r,o){let i=new Date,s=new Map;for(let a of n.plugins){let c=a.id,l=I(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?U({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 k=crypto.randomUUID();await e.insertInto("corsair_accounts").values({id:k,tenant_id:t,integration_id:u.id,config:{},created_at:i,updated_at:i}).execute(),h=await e.selectFrom("corsair_accounts").selectAll().where("id","=",k).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:[...$[l].integration,...d],accountFields:r?[...$[l].account,...p]:[]})}return s}function Wl(e){if(!Te(e))return;let n=e.keys;return Te(n)?n:void 0}function jl(e,n){return"withTenant"in e&&typeof e.withTenant=="function"?e.withTenant(n):e}async function ql(e,n,t,r,o,i){let s=Wl(e),a=n.provisionAccounts?jl(e,n.tenantId):void 0;for(let[c,l]of Object.entries(t)){let u=r.plugins.find(b=>b.id===c);if(!u){i(`[corsair:setup] Unknown plugin '${c}' \u2014 skipping credentials.`);continue}let d=I(u);if(!d){i(`[corsair:setup] Plugin '${c}' has no auth type \u2014 skipping credentials.`);continue}let p=Oo(u,d,"integration"),g=Oo(u,d,"account"),f=s?.[c],h=a?.[c],k=Te(h)?h.keys:void 0;for(let[b,C]of Object.entries(l))if(C){if(p.has(b)){if(n.multiTenant&&n.tenantIdProvided)throw new Error(`[corsair:setup] '${c}.${b}' 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=z(f,`set_${b}`);if(!P){i(`[corsair:setup] Cannot set integration field '${b}' for '${c}'.`);continue}await P(C),o(`[corsair:setup] Set ${c} integration.${b}`);continue}if(g.has(b)){if(n.multiTenant&&!n.tenantIdProvided)throw new Error(`setupCorsair: tenantId is required to set account-level credential '${c}.${b}' on a multi-tenant instance`);let P=z(k,`set_${b}`);if(!P){i(`[corsair:setup] Cannot set account field '${b}' for '${c}'.`);continue}await P(C),o(`[corsair:setup] Set ${c} account.${b} (tenant=${n.tenantId})`);continue}i(`[corsair:setup] Unknown credential field '${b}' for plugin '${c}'.`)}}}var wa=new Set(["webhook_signature","expires_at","scope","redirect_url"]);async function Kl(e,n,t,r,o,i,s,a,c){let l=[],u=[];for(let p of o){if(wa.has(p))continue;let g=z(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(wa.has(p))continue;let g=z(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
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 Wl(e,n,t,r){let o=new Set;for(let i of e.values())await $l(i.pluginId,i.authType,i.integration,i.account,i.integrationFields,i.accountFields,n,t,r)&&o.add(i.pluginId);return o}async function jl(e,n,t,r,o){if(!Ml(Oo)){o("[corsair:setup] Backfill config is invalid - skipping backfill.");return}let i=Oo,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=Te(e)?e[a]:void 0,u=Te(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=Te(u)?u[d]:void 0;await z(h,g)?.(f)}catch(h){o(`[corsair:setup] ${a} \u203A ${d}.${g} failed: `+(h instanceof Error?h.message:String(h)))}}}}export{Wo as a,Pe as b,pe as c,Kn as d,Zn as e,Gn as f,Je as g,jo as h,zn as i,sr as j,vn as k,Vo as l,Yo as m,Ae as n,Be as o,ge as p,Ye as q,Qe as r,Re as s,cr as t,Xo as u,An as v,fe as w,Rn as x,ur as y,Yn as z,F as A,Qn as B,Xe as C,ye as D,me as E,Y as F,lr as G,xn as H,xe as I,he as J,In as K,U as L,B as M,si as N,ai as O,at as P,Ll as Q,Se as R,pr as S,tn as T,on as U,fr as V,it as W,hi as X,Le as Y,q as Z,yr as _,En as $,Ci as aa,sc as ba,ct as ca,rg as da,Pi as ea,Ai as fa,Ri as ga,xi as ha,ut as ia,mr as ja,dt as ka,pt as la,un as ma,ft as na,vr as oa,Ei as pa,Tr as qa,_r as ra,Er as sa,Pt as ta,Dr as ua,pn as va,gn as wa,At as xa,Rt as ya,Dn as za,Or as Aa,Mr as Ba,xt as Ca,On as Da,It as Ea,St as Fa,Ee as Ga,fn as Ha,qi as Ia,Nr as Ja,Lr as Ka,We as La,Bn as Ma,Fn as Na,Bt as Oa,jr as Pa,Un as Qa,pu as Ra,hu as Sa,wu as Ta,es as Ua,ns as Va,ts as Wa,rs as Xa,je as Ya,qe as Za,Gr as _a,zr as $a,Jr as ab,Vr as bb,Yr as cb,Ke as db,M as eb,Qr as fb,us as gb,ls as hb,Xr as ib,eo as jb,no as kb,to as lb,ro as mb,oo as nb,io as ob,so as pb,ao as qb,co as rb,uo as sb,lo as tb,po as ub,go as vb,fo as wb,Ze as xb,L as yb,Us as zb,Ns as Ab,Ls as Bb,$s as Cb,Ws as Db,js as Eb,qs as Fb,Ks as Gb,Zs as Hb,Gs as Ib,zs as Jb,Js as Kb,Ys as Lb,nl as Mb,st as Nb,ta as Ob,hw as Pb,Ge as Qb,bw as Rb,Kt as Sb,ll as Tb,dl as Ub,Gt as Vb,fl as Wb,pa as Xb,yl as Yb,ml as Zb,ga as _b,fa as $b,Wn as ac,hl as bc,ya as cc,ma as dc,bl as ec,zt as fc,kl as gc,$n as hc,ka as ic,wl as jc};
66
+ `))}}return d}async function Zl(e,n,t,r){let o=new Set;for(let i of e.values())await Kl(i.pluginId,i.authType,i.integration,i.account,i.integrationFields,i.accountFields,n,t,r)&&o.add(i.pluginId);return o}async function Gl(e,n,t,r,o){if(!Ul(Do)){o("[corsair:setup] Backfill config is invalid - skipping backfill.");return}let i=Do,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=Te(e)?e[a]:void 0,u=Te(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=Te(u)?u[d]:void 0;await z(h,g)?.(f)}catch(h){o(`[corsair:setup] ${a} \u203A ${d}.${g} failed: `+(h instanceof Error?h.message:String(h)))}}}}export{$o as a,Pe as b,pe as c,Kn as d,Zn as e,Gn as f,Je as g,Wo as h,zn as i,ir as j,vn as k,Jo as l,Vo as m,Ae as n,Be as o,ge as p,Ye as q,Qe as r,Re as s,ar as t,Qo as u,An as v,fe as w,Rn as x,cr as y,Yn as z,F as A,Qn as B,Xe as C,ye as D,me as E,Y as F,ur as G,xn as H,xe as I,he as J,In as K,U as L,B as M,ii as N,si as O,at as P,ql as Q,Se as R,dr as S,tn as T,on as U,gr as V,it as W,mi as X,Le as Y,q as Z,fr as _,En as $,wi as aa,sc as ba,ct as ca,ag as da,Ti as ea,Pi as fa,Ai as ga,Ri as ha,ut as ia,yr as ja,dt as ka,pt as la,un as ma,ft as na,Cr as oa,_i as pa,vr as qa,Sr as ra,_r as sa,Pt as ta,Er as ua,pn as va,gn as wa,At as xa,Rt as ya,Dn as za,Dr as Aa,Or as Ba,xt as Ca,On as Da,It as Ea,St as Fa,Ee as Ga,fn as Ha,ji as Ia,Ur as Ja,Nr as Ka,We as La,Bn as Ma,Fn as Na,Bt as Oa,Wr as Pa,Un as Qa,gu as Ra,bu as Sa,Cu as Ta,Xi as Ua,es as Va,ns as Wa,ts as Xa,je as Ya,qe as Za,Zr as _a,Gr as $a,zr as ab,Jr as bb,Vr as cb,Ke as db,M as eb,Yr as fb,cs as gb,us as hb,Qr as ib,Xr as jb,eo as kb,no as lb,to as mb,ro as nb,oo as ob,io as pb,so as qb,ao as rb,co as sb,uo as tb,lo as ub,po as vb,go as wb,Ze as xb,L as yb,Fs as zb,Us as Ab,Ns as Bb,Ls as Cb,$s as Db,Ws as Eb,js as Fb,qs as Gb,Ks as Hb,Zs as Ib,Gs as Jb,zs as Kb,Vs as Lb,tl as Mb,st as Nb,na as Ob,Cw as Pb,Ge as Qb,vw as Rb,Kt as Sb,dl as Tb,pl as Ub,Gt as Vb,yl as Wb,da as Xb,ml as Yb,hl as Zb,pa as _b,ga as $b,Wn as ac,bl as bc,fa as cc,ya as dc,kl as ec,zt as fc,wl as gc,$n as hc,ka as ic,Cl as jc,Pl as kc};
@@ -1 +1 @@
1
- import{ga as a,ha as b,ia as c}from"./chunk-HDOJLIMA.js";import"./chunk-4OLKWKJG.js";import"./chunk-7AYINDN2.js";import"./chunk-N66TLOH2.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{c as createHubConnectSession,b as createHubConnectSessionForPlugin,a as postHubConnectSession};
1
+ import{ga as a,ha as b,ia as c}from"./chunk-QFOUQIUB.js";import"./chunk-4OLKWKJG.js";import"./chunk-7AYINDN2.js";import"./chunk-N66TLOH2.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{c as createHubConnectSession,b as createHubConnectSessionForPlugin,a as postHubConnectSession};
package/dist/core.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { C as CORSAIR_INTERNAL, a as CorsairInternalConfig, c as createCorsair, s as shouldStartTunnel } from './index-CM92kJI-.js';
1
+ export { C as CORSAIR_INTERNAL, a as CorsairInternalConfig, c as createCorsair, s as shouldStartTunnel, b as superviseTunnel } from './index-Dy0NLzS3.js';
2
2
  import { CorsairDatabase } from './db.js';
3
3
  import { A as AuthTypes, f as AccountKeyManagerFor, I as IntegrationKeyManagerFor, H as HubConfig, g as CorsairPluginSubscribeResult } from './index-BzjK9SZA.js';
4
4
  export { h as AccountFieldNames, n as AgentMessageRole, o as AgentReply, v as AllProviders, l as BASE_AUTH_FIELDS, B as BaseAuthFieldConfig, i as BaseKeyManager, w as BaseProviders, a2 as BeforeHookResult, D as BindEndpoints, ap as BindWebhooks, an as Bivariant, E as BoundEndpointFn, F as BoundEndpointTree, aq as BoundWebhook, ar as BoundWebhookTree, p as ChatHandle, q as ChatMessage, r as ChatSummary, s as CorsairChatsNamespace, u as CorsairClient, G as CorsairContext, J as CorsairEndpoint, M as CorsairErrorHandler, c as CorsairIntegration, a3 as CorsairKeyBuilder, a4 as CorsairKeyBuilderBase, as as CorsairOAuthWebhookTenantLinkResolver, X as CorsairPermissionsNamespace, C as CorsairPlugin, a5 as CorsairPluginContext, a6 as CorsairPluginSubscribe, aj as CorsairRunsNamespace, e as CorsairSingleTenantClient, d as CorsairTenantWrapper, at as CorsairWebhook, au as CorsairWebhookHandler, av as CorsairWebhookMatcher, aw as CorsairWebhookTenantMatcher, aC as CorsairWorkflowsNamespace, t as CreateChatResult, a7 as EndpointHooks, a8 as EndpointMetaEntry, K as EndpointPathsOf, a9 as EndpointRiskLevel, L as EndpointTree, Y as EnforcePermissionOptions, Z as EnforcePermissionResult, N as ErrorContext, Q as ErrorHandler, R as ErrorHandlerAndMatchFunction, S as ErrorMatcher, j as IntegrationFieldNames, aa as KeyBuilderContext, k as OAuth2IntegrationCredentials, O as OAuthConfig, ab as PermissionMode, ac as PermissionPolicy, x as PickAuth, P as PluginAuthConfig, ad as PluginEndpointMeta, ae as PluginPermissionsConfig, z as ProviderDisplayNames, ax as RawWebhookRequest, a0 as ReadonlyForbiddenError, af as RequiredPluginEndpointMeta, ag as RequiredPluginEndpointSchemas, ah as RequiredPluginWebhookSchemas, U as RetryStrategies, V as RetryStrategy, T as TokenResponse, aD as TriggerRunResult, ao as UnionToIntersection, ai as WebhookHooks, ay as WebhookPathsOf, az as WebhookRequest, aA as WebhookResponse, W as WebhookTenantMatch, aB as WebhookTree, ak as WorkflowRun, al as WorkflowRunStatus, am as WorkflowRunStep, aE as WorkflowStatus, aF as WorkflowSummary, _ as assertReadonlyAllowed, m as exchangeCodeForTokens, y as formatProviderDisplayName, $ as isReadonlyScopeActive, a1 as runReadonly } from './index-BzjK9SZA.js';
package/dist/core.js CHANGED
@@ -1 +1 @@
1
- import{$b as L,D as e,E as f,F as g,G as h,H as i,I as j,J as k,K as l,L as m,Lb as y,M as n,Mb as z,N as o,Nb as A,O as p,Ob as B,Sb as C,Tb as D,Ub as E,Vb as F,Wb as G,Xb as H,Yb as I,Zb as J,_b as K,a,ac as M,b,bc as N,c,cc as O,dc as P,eb as w,ec as Q,fc as R,gc as S,hc as T,ic as U,ja as q,jc as V,ma as r,na as s,oa as t,pa as u,qa as v,xb as x}from"./chunk-HDOJLIMA.js";import"./chunk-4OLKWKJG.js";import{h as d}from"./chunk-7AYINDN2.js";import"./chunk-N66TLOH2.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{w as AuthMissingError,d as BASE_AUTH_FIELDS,T as CORSAIR_INTERNAL,x as CorsairKekMissingError,F as MS_GRAPH_API_BASE,r as PermissionRequiredError,a as ProviderDisplayNames,s as ReadonlyForbiddenError,c as ReconnectRequiredError,M as asRecord,v as assertReadonlyAllowed,J as collectPluginWebhookMatchers,n as createAccountKeyManager,U as createCorsair,m as createIntegrationKeyManager,S as decodePubSubData,k as decryptConfig,g as decryptDEK,i as decryptWithDEK,j as encryptConfig,f as encryptDEK,h as encryptWithDEK,A as exchangeCodeForTokens,P as extractMicrosoftGraphValidationToken,R as firstString,C as formatDocSchemaShape,b as formatProviderDisplayName,e as generateDEK,K as getHeader,B as getOAuthAccessToken,E as googleChannelSubscribe,p as initializeAccountDEK,o as initializeIntegrationDEK,D as introspectPluginForDocs,Q as isMicrosoftGraphValidationHandshake,u as isReadonlyScopeActive,y as logEvent,z as logEventFromContext,H as matchWebhookPlugin,I as matchWebhookPluginAndTenant,G as msGraphSubscribe,l as reEncryptConfig,N as readBodyRecord,O as readQueryParam,q as resolveConnectLink,t as runReadonly,V as shouldStartTunnel,L as toExternalId};
1
+ import{$b as L,D as e,E as f,F as g,G as h,H as i,I as j,J as k,K as l,L as m,Lb as y,M as n,Mb as z,N as o,Nb as A,O as p,Ob as B,Sb as C,Tb as D,Ub as E,Vb as F,Wb as G,Xb as H,Yb as I,Zb as J,_b as K,a,ac as M,b,bc as N,c,cc as O,dc as P,eb as w,ec as Q,fc as R,gc as S,hc as T,ic as U,ja as q,jc as V,kc as W,ma as r,na as s,oa as t,pa as u,qa as v,xb as x}from"./chunk-QFOUQIUB.js";import"./chunk-4OLKWKJG.js";import{h as d}from"./chunk-7AYINDN2.js";import"./chunk-N66TLOH2.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{w as AuthMissingError,d as BASE_AUTH_FIELDS,T as CORSAIR_INTERNAL,x as CorsairKekMissingError,F as MS_GRAPH_API_BASE,r as PermissionRequiredError,a as ProviderDisplayNames,s as ReadonlyForbiddenError,c as ReconnectRequiredError,M as asRecord,v as assertReadonlyAllowed,J as collectPluginWebhookMatchers,n as createAccountKeyManager,U as createCorsair,m as createIntegrationKeyManager,S as decodePubSubData,k as decryptConfig,g as decryptDEK,i as decryptWithDEK,j as encryptConfig,f as encryptDEK,h as encryptWithDEK,A as exchangeCodeForTokens,P as extractMicrosoftGraphValidationToken,R as firstString,C as formatDocSchemaShape,b as formatProviderDisplayName,e as generateDEK,K as getHeader,B as getOAuthAccessToken,E as googleChannelSubscribe,p as initializeAccountDEK,o as initializeIntegrationDEK,D as introspectPluginForDocs,Q as isMicrosoftGraphValidationHandshake,u as isReadonlyScopeActive,y as logEvent,z as logEventFromContext,H as matchWebhookPlugin,I as matchWebhookPluginAndTenant,G as msGraphSubscribe,l as reEncryptConfig,N as readBodyRecord,O as readQueryParam,q as resolveConnectLink,t as runReadonly,V as shouldStartTunnel,W as superviseTunnel,L as toExternalId};
package/dist/hub.d.ts CHANGED
@@ -334,12 +334,6 @@ type FormatServerDeliveryErrorInput = {
334
334
  * Formats a user-facing error when server delivery fails (network, HTTP error, or app rejection).
335
335
  */
336
336
  declare function formatServerDeliveryError(input: FormatServerDeliveryErrorInput): string;
337
- /**
338
- * Signs and POSTs a tunnel envelope to the app's delivery URL (hub-side server delivery).
339
- *
340
- * Used by the hub for production credential transfer, OAuth callbacks, permission decisions,
341
- * and connect status introspection.
342
- */
343
337
  declare function deliverSignedEnvelope(input: {
344
338
  deliveryUrl: string;
345
339
  projectId: string;
package/dist/hub.js CHANGED
@@ -1 +1 @@
1
- import{$a as _,A as z,Aa as P,B as A,Ba as Q,C as B,Ca as R,Da as S,Ea as T,Fa as U,Ga as V,Ha as W,T as C,Ua as X,Va as Y,_a as Z,ab as $,b as a,bb as aa,cb as ba,d as b,db as ca,e as c,f as d,fb as da,g as e,gb as ea,h as f,hb as fa,i as g,ia as D,ib as ga,j as i,jb as ha,k as j,ka as E,kb as ia,l as k,la as F,lb as ja,m as l,mb as ka,n as m,nb as la,o as n,ob as ma,p as o,pb as na,q as p,qb as oa,r as q,ra as G,rb as pa,s as r,sa as H,sb as qa,t as s,ta as I,tb as ra,u as t,ua as J,ub as sa,v as u,va as K,vb as ta,w as v,wa as L,wb as ua,x as w,xa as M,y as x,ya as N,z as y,za as O}from"./chunk-HDOJLIMA.js";import{a as h,b as va,c as wa,d as xa,e as ya,f as za}from"./chunk-4OLKWKJG.js";import"./chunk-7AYINDN2.js";import"./chunk-N66TLOH2.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{m as BROWSER_DELIVERY_TTL_MS,wa as CORSAIR_TUNNEL_PATH,va as CORSAIR_TUNNEL_ZONE,u as DEFAULT_HUB_API_URL,xa as FRPC_VERSION,w as HubCredentialsMissingError,v as HubNotConfiguredError,V as ManagedOAuthDeliveryError,n as SIGNED_TUNNEL_REPLAY_WINDOW_MS,ea as attachManagedRefreshAuth,p as buildBrowserDeliveryRedirectUrl,s as buildClientBridgeBrowserDeliveryUrl,ga as createConnectSessionJti,la as createConnectTokenJti,D as createHubConnectSession,E as createHubPermissionSession,fa as createHubRouteHandlers,ra as createPermissionSessionJti,o as createSignedTokenJti,ka as decodeConnectSessionTokenFromPath,qa as decodeConnectTokenFromPath,ua as decodePermissionTokenFromPath,Q as deliverConnectCreateLink,U as deliverSignedEnvelope,S as describeDeliveryNetworkError,pa as encodeConnectTokenForPath,O as extractConnectLinkFromDeliveryAck,H as extractProbeFromDeliveryAck,G as extractRunFromDeliveryAck,N as extractSyncFromDeliveryAck,F as formatHubApprovalMessage,a as formatProviderDisplayName,T as formatServerDeliveryError,ya as frpcPlatformKey,ha as getConnectSessionExpiryMs,X as getConnectStatusForTenant,ma as getConnectTokenExpiryMs,z as getHubConfig,da as getManagedAccessToken,Z as handleHubDeliveryGet,_ as handleHubDeliveryPost,aa as handleHubDeliveryRequest,$ as hubDeliveryToResponse,B as inferHubEnvironmentSlug,i as isLoopbackUrl,M as isServerDeliveryAckSuccessful,Y as listHubProjectConnections,x as normalizeHubConfig,P as parseConnectLinkFromDeliveryBody,b as parseConnectSessionResponse,f as parseConnectStatusResponse,g as parseHubApiErrorBody,e as parseOAuthRefreshResponse,d as parsePermissionSessionResponse,c as parseProjectConnectionsResponse,L as parseServerDeliveryAckBody,R as parseSyncFromDeliveryBody,t as prepareClientBridgeDeliveryTransport,W as processManagedOAuthDelivery,C as registerHubWebhookTenantLink,j as resolveDeliveryTransport,za as resolveFrpcBinary,y as resolveHubConfigInput,h as resolveHubDeliveryUrl,A as resolveHubOAuthCallbackUrl,ba as respondToHubDelivery,ca as respondToHubDeliveryFromRequest,q as signBrowserDeliveryToken,ia as signConnectSessionToken,na as signConnectToken,I as signDeliveryEnvelope,sa as signPermissionToken,k as usesBrowserDelivery,l as validateProductionDeliveryUrl,r as verifyBrowserDeliveryToken,ja as verifyConnectSessionToken,oa as verifyConnectToken,J as verifyDeliveryEnvelope,ta as verifyPermissionToken,K as verifySignedTunnelDelivery};
1
+ import{$a as _,A as z,Aa as P,B as A,Ba as Q,C as B,Ca as R,Da as S,Ea as T,Fa as U,Ga as V,Ha as W,T as C,Ua as X,Va as Y,_a as Z,ab as $,b as a,bb as aa,cb as ba,d as b,db as ca,e as c,f as d,fb as da,g as e,gb as ea,h as f,hb as fa,i as g,ia as D,ib as ga,j as i,jb as ha,k as j,ka as E,kb as ia,l as k,la as F,lb as ja,m as l,mb as ka,n as m,nb as la,o as n,ob as ma,p as o,pb as na,q as p,qb as oa,r as q,ra as G,rb as pa,s as r,sa as H,sb as qa,t as s,ta as I,tb as ra,u as t,ua as J,ub as sa,v as u,va as K,vb as ta,w as v,wa as L,wb as ua,x as w,xa as M,y as x,ya as N,z as y,za as O}from"./chunk-QFOUQIUB.js";import{a as h,b as va,c as wa,d as xa,e as ya,f as za}from"./chunk-4OLKWKJG.js";import"./chunk-7AYINDN2.js";import"./chunk-N66TLOH2.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{m as BROWSER_DELIVERY_TTL_MS,wa as CORSAIR_TUNNEL_PATH,va as CORSAIR_TUNNEL_ZONE,u as DEFAULT_HUB_API_URL,xa as FRPC_VERSION,w as HubCredentialsMissingError,v as HubNotConfiguredError,V as ManagedOAuthDeliveryError,n as SIGNED_TUNNEL_REPLAY_WINDOW_MS,ea as attachManagedRefreshAuth,p as buildBrowserDeliveryRedirectUrl,s as buildClientBridgeBrowserDeliveryUrl,ga as createConnectSessionJti,la as createConnectTokenJti,D as createHubConnectSession,E as createHubPermissionSession,fa as createHubRouteHandlers,ra as createPermissionSessionJti,o as createSignedTokenJti,ka as decodeConnectSessionTokenFromPath,qa as decodeConnectTokenFromPath,ua as decodePermissionTokenFromPath,Q as deliverConnectCreateLink,U as deliverSignedEnvelope,S as describeDeliveryNetworkError,pa as encodeConnectTokenForPath,O as extractConnectLinkFromDeliveryAck,H as extractProbeFromDeliveryAck,G as extractRunFromDeliveryAck,N as extractSyncFromDeliveryAck,F as formatHubApprovalMessage,a as formatProviderDisplayName,T as formatServerDeliveryError,ya as frpcPlatformKey,ha as getConnectSessionExpiryMs,X as getConnectStatusForTenant,ma as getConnectTokenExpiryMs,z as getHubConfig,da as getManagedAccessToken,Z as handleHubDeliveryGet,_ as handleHubDeliveryPost,aa as handleHubDeliveryRequest,$ as hubDeliveryToResponse,B as inferHubEnvironmentSlug,i as isLoopbackUrl,M as isServerDeliveryAckSuccessful,Y as listHubProjectConnections,x as normalizeHubConfig,P as parseConnectLinkFromDeliveryBody,b as parseConnectSessionResponse,f as parseConnectStatusResponse,g as parseHubApiErrorBody,e as parseOAuthRefreshResponse,d as parsePermissionSessionResponse,c as parseProjectConnectionsResponse,L as parseServerDeliveryAckBody,R as parseSyncFromDeliveryBody,t as prepareClientBridgeDeliveryTransport,W as processManagedOAuthDelivery,C as registerHubWebhookTenantLink,j as resolveDeliveryTransport,za as resolveFrpcBinary,y as resolveHubConfigInput,h as resolveHubDeliveryUrl,A as resolveHubOAuthCallbackUrl,ba as respondToHubDelivery,ca as respondToHubDeliveryFromRequest,q as signBrowserDeliveryToken,ia as signConnectSessionToken,na as signConnectToken,I as signDeliveryEnvelope,sa as signPermissionToken,k as usesBrowserDelivery,l as validateProductionDeliveryUrl,r as verifyBrowserDeliveryToken,ja as verifyConnectSessionToken,oa as verifyConnectToken,J as verifyDeliveryEnvelope,ta as verifyPermissionToken,K as verifySignedTunnelDelivery};
@@ -31,5 +31,19 @@ declare function createCorsair<const Plugins extends readonly CorsairPlugin[]>(c
31
31
  multiTenancy?: false | undefined;
32
32
  }): CorsairSingleTenantClient<Plugins>;
33
33
  declare function shouldStartTunnel(hub: HubConfig | undefined): boolean;
34
+ /**
35
+ * Keep a dev tunnel alive. frpc has no supervisor — a death (laptop sleep,
36
+ * network blip, frps restart) leaves the tunnel down until the app process
37
+ * restarts, and the Hub keeps delivering to the dead URL. Restart on death with
38
+ * capped exponential backoff; a healthy start resets the backoff. The
39
+ * Hub-owned slug is sticky, so a restart re-registers the same public URL.
40
+ * Extracted from the spawn so the restart wiring is unit-testable.
41
+ */
42
+ declare function superviseTunnel(opts: {
43
+ start: (onClose: () => void) => Promise<unknown>;
44
+ schedule?: (fn: () => void, ms: number) => void;
45
+ minDelayMs?: number;
46
+ maxDelayMs?: number;
47
+ }): void;
34
48
 
35
- export { CORSAIR_INTERNAL as C, type CorsairInternalConfig as a, createCorsair as c, shouldStartTunnel as s };
49
+ export { CORSAIR_INTERNAL as C, type CorsairInternalConfig as a, superviseTunnel as b, createCorsair as c, shouldStartTunnel as s };
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ import { e as CorsairSingleTenantClient, d as CorsairTenantWrapper, C as Corsair
3
3
  export { aT as CorsairManageNamespace, b as CorsairManualConfig, a as CorsairPermissionsOptions, aU as PluginConnectionState, a0 as ReadonlyForbiddenError, a1 as runReadonly } from './index-BzjK9SZA.js';
4
4
  import { F as FormFieldSchema, L as ListOperationsOptions } from './tenant-match-utils-CQ0UAjUs.js';
5
5
  export { A as AuthMissingError, C as CorsairKekMissingError, h as PermissionRequiredError, l as PluginWebhookMatchers, R as ReconnectRequiredError, a as ResolveConnectLinkResult, W as WebhookPluginTenantMatch, n as asRecord, j as collectPluginWebhookMatchers, o as decodePubSubData, q as firstString, g as formatDocSchemaShape, s as getHeader, m as matchWebhookPlugin, k as matchWebhookPluginAndTenant, u as readBodyRecord, r as resolveConnectLink, w as toExternalId } from './tenant-match-utils-CQ0UAjUs.js';
6
- export { c as createCorsair } from './index-CM92kJI-.js';
6
+ export { c as createCorsair } from './index-Dy0NLzS3.js';
7
7
  export { SetupCorsairOptions, setupCorsair } from './setup.js';
8
8
  export { O as OAuthCallbackTunnelPayload, f as ProcessCorsairOptions, g as ProcessCorsairRequest, l as ResolveAccountFromWebhookLinkInput, T as TunnelAck, j as TunnelEnvelope, k as TunnelType, m as WebhookTenantLink, W as WebhookTunnelPayload, p as processCorsair, r as resolveAccountFromWebhookLink, h as resolveTenantFromWebhookLink, i as resolveTenantIdFromWebhookLink, s as setWebhookTenantLink } from './index-4oKvjBws.js';
9
9
  import './db.js';
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import{$b as cn,Ab as J,Bb as Y,Cb as K,Db as G,Eb as X,Fb as Q,Gb as V,Hb as nn,Ia as H,Ib as en,Jb as tn,Kb as rn,P as O,Pb as P,Qa as W,Qb as w,Rb as x,Sb as R,U as A,V as L,W as E,Wa as q,X as v,Xa as N,Xb as on,Ya as j,Yb as sn,Za as B,Zb as an,_b as un,ac as pn,bc as ln,c as S,eb as D,fc as dn,gc as mn,hc as T,ic as gn,ja as F,ma as M,na as _,oa as $,xb as U,yb as Z,zb as z}from"./chunk-HDOJLIMA.js";import"./chunk-4OLKWKJG.js";import"./chunk-7AYINDN2.js";import"./chunk-N66TLOH2.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";import{z as p}from"zod";function f(e){let t=e[T];if(!t)throw new Error("listOperations / getSchema: invalid corsair instance. Pass the value returned by createCorsair() or corsair.withTenant().");return t.plugins}function y(e,t){let o=w(f(e),t);return typeof o=="string"?o:Array.isArray(o)?o.join(`
1
+ import{$b as cn,Ab as J,Bb as Y,Cb as K,Db as G,Eb as X,Fb as Q,Gb as V,Hb as nn,Ia as H,Ib as en,Jb as tn,Kb as rn,P as O,Pb as P,Qa as W,Qb as w,Rb as x,Sb as R,U as A,V as L,W as E,Wa as q,X as v,Xa as N,Xb as on,Ya as j,Yb as sn,Za as B,Zb as an,_b as un,ac as pn,bc as ln,c as S,eb as D,fc as dn,gc as mn,hc as T,ic as gn,ja as F,ma as M,na as _,oa as $,xb as U,yb as Z,zb as z}from"./chunk-QFOUQIUB.js";import"./chunk-4OLKWKJG.js";import"./chunk-7AYINDN2.js";import"./chunk-N66TLOH2.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";import{z as p}from"zod";function f(e){let t=e[T];if(!t)throw new Error("listOperations / getSchema: invalid corsair instance. Pass the value returned by createCorsair() or corsair.withTenant().");return t.plugins}function y(e,t){let o=w(f(e),t);return typeof o=="string"?o:Array.isArray(o)?o.join(`
2
2
  `):Object.values(o).flat().join(`
3
3
  `)}function fn(e,t){return x(f(e),t)}function k(e,t){return P(f(e),t)}function h(e,t){let o=f(e),n=t.toLowerCase(),i=n.indexOf(".");if(i===-1)return null;let u=n.slice(0,i),r=n.slice(i+1),s=o.find(c=>c.id===u);if(!s?.endpointSchemas)return null;let a=r;a.startsWith("api.")&&(a=a.slice(4));for(let[c,g]of Object.entries(s.endpointSchemas))if(c.toLowerCase()===a)return g.input??null;return null}function C(e){let t=Cn(e);return e.description&&(t=t.describe(e.description)),e.optional&&(t=t.optional()),t}function Cn(e){switch(e.kind){case"string":return e.enum&&e.enum.length>0?p.enum(e.enum):p.string();case"number":return p.number();case"boolean":return p.boolean();case"literal":return p.literal(e.value);case"object":{let t={};for(let[o,n]of Object.entries(e.fields))t[o]=C(n);return p.object(t)}case"array":return p.array(C(e.items));case"unknown":return p.unknown()}}function yn(e,t){let o=t?.tenantId?Pn(e,t.tenantId):e;return(t?.operations??kn(y(o,{plugin:t?.plugin,type:"api"}))).map(i=>{let u=k(o,i),s=h(o,i)??(u?.input?C(u.input):p.object({}));return{name:hn(i),operation:i,description:u?.description??i,schema:s,execute:a=>wn(o,i,a??{})}})}function kn(e){return e.split(`
4
4
  `).map(t=>t.trim()).filter(Boolean)}function hn(e){return e.replace(/[^a-zA-Z0-9_-]/g,"_")}function Pn(e,t){let o=e.withTenant;return typeof o=="function"?o.call(e,t):e}async function wn(e,t,o){let n=t.split("."),i=n.pop();if(!i)throw new Error(`Invalid operation path: ${t}`);let u=e;for(let s of n)if(u=u?.[s],u==null)throw new Error(`Unknown operation path: ${t}`);let r=u[i];if(typeof r!="function")throw new Error(`Operation is not callable: ${t}`);return r.call(u,o)}var l=class extends Error{status;code;extra;constructor(t,o,n,i={}){super(n),this.name="CorsairClientError",this.status=t,this.code=o,this.extra=i}};function xn(e){return e.endsWith("/")?e.slice(0,-1):e}async function I(e){let t={};try{t=await e.json()}catch{}let o=typeof t.error=="string"?t.error:"request_failed",n=typeof t.message=="string"?t.message:`Request failed (${e.status})`,{error:i,message:u,...r}=t;return new l(e.status,o,n,r)}function Rn(e){let t=xn(e.baseURL),o=e.fetch??((...r)=>globalThis.fetch(...r));async function n(r,s){let a=s&&Object.keys(s).length?`?${new URLSearchParams(s).toString()}`:"",c=await o(`${t}${r}${a}`,{method:"GET"});if(!c.ok)throw await I(c);return await c.json()}async function i(r,s){let a=await o(`${t}${r}`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(s)});if(!a.ok)throw await I(a);return await a.json()}let u=encodeURIComponent;return{ok:()=>n("/ok"),tenants:{list:()=>n("/tenants"),create:r=>i("/tenants",r),get:r=>n(`/tenants/${u(r)}`)},plugins:{list:()=>n("/plugins"),get:r=>n(`/plugins/${u(r)}`)},connectionStatus:{get:r=>{let s={};return r?.tenantId&&(s.tenantId=r.tenantId),n("/connection-status",s)}},permissions:{get:r=>"id"in r?n(`/permissions/${u(r.id)}`):i("/permissions/lookup-by-token",{token:r.token})},connect:{createLink:r=>i("/connect/links",r),resolve:r=>n("/connect/resolve",{state:r}),oauthCallback:r=>i("/connect/oauth/callback",r)},connectRequest:{get:r=>{let s={};return r?.tenantId&&(s.tenantId=r.tenantId),n("/connect/request",s)},clear:r=>i("/connect/request/clear",r??{})}}}var Tn=Symbol.for("corsair:internal");function In(e,t){let o=e;for(let n of t){if(!o||typeof o!="object")return null;o=o[n]}return typeof o=="function"?o:null}function b(e){return e[Tn]?.database}async function bn(e,t){let o=new Date().toISOString(),n=await e.permissions.find_by_token(t);if(!n)return console.error("executePermission: no permission found for token."),{error:"executePermission: no permission found for token."};if(n.status!=="approved")return console.error(`executePermission: permission '${n.id}' is '${n.status}', expected 'approved'.`),{endpoint:n.endpoint,plugin:n.plugin,result:null,error:`executePermission: permission '${n.id}' is '${n.status}', expected 'approved'.`};if(n.expires_at<o){let a=b(e);return a&&await a.db.updateTable("corsair_permissions").set({status:"expired",updated_at:new Date}).where("id","=",n.id).execute(),console.error(`executePermission: permission '${n.id}' has expired.`),{error:`executePermission: permission '${n.id}' has expired.`,endpoint:n.endpoint,plugin:n.plugin,result:null}}let i=n.tenant_id??"default",r=(e.withTenant?e.withTenant(i):e)[n.plugin];if(!r?.api)return console.error(`executePermission: plugin '${n.plugin}' not found or has no API on this corsair instance.`),{error:`executePermission: plugin '${n.plugin}' not found or has no API on this corsair instance.`,plugin:n.plugin,endpoint:n.endpoint,result:null};let s=In(r.api,n.endpoint.split("."));if(!s)return console.error(`executePermission: endpoint '${n.endpoint}' not found in plugin '${n.plugin}'.`),{endpoint:n.endpoint,plugin:n.plugin,result:null,error:`executePermission: endpoint '${n.endpoint}' not found in plugin '${n.plugin}'.`};await e.permissions.set_executing(n.id);try{let a=typeof n.args=="string"?JSON.parse(n.args):n.args,c=await s(a);return await e.permissions.set_completed(n.id),{plugin:n.plugin,endpoint:n.endpoint,result:c}}catch(a){let c=a instanceof Error?a.message:String(a),g=b(e);return g&&await g.db.updateTable("corsair_permissions").set({status:"failed",error:c,updated_at:new Date}).where("id","=",n.id).execute(),{plugin:n.plugin,endpoint:n.endpoint,result:null,error:c}}}export{D as AuthMissingError,l as CorsairClientError,U as CorsairKekMissingError,N as DEFAULT_BODY_STALL_TIMEOUT_MS,q as DEFAULT_MAX_BODY_BYTES,M as PermissionRequiredError,_ as ReadonlyForbiddenError,S as ReconnectRequiredError,pn as asRecord,yn as buildCorsairTools,an as collectPluginWebhookMatchers,gn as createCorsair,Rn as createCorsairClient,mn as decodePubSubData,bn as executePermission,dn as firstString,C as formFieldToZod,R as formatDocSchemaShape,un as getHeader,h as getInputSchema,fn as getSchema,k as getStructuredSchema,y as listOperations,Z as managementHandler,on as matchWebhookPlugin,sn as matchWebhookPluginAndTenant,W as processCorsair,H as processWebhook,ln as readBodyRecord,J as registerCorsairRawBodyParser,L as resolveAccountFromWebhookLink,B as resolveBodyStallTimeoutMs,F as resolveConnectLink,j as resolveMaxBodyBytes,v as resolveTenantFromWebhookLink,E as resolveTenantIdFromWebhookLink,$ as runReadonly,A as setWebhookTenantLink,O as setupCorsair,nn as toAstroHandler,z as toExpressHandler,cn as toExternalId,Y as toFastifyHandler,K as toHonoHandler,G as toNextJsHandler,X as toNodeHandler,tn as toNuxtHandler,V as toRemixHandler,Q as toSvelteKitHandler,en as toTanStackHandler,rn as toWebHandler};
@@ -1 +1 @@
1
- import{Ra as a,Sa as b,Ta as c}from"./chunk-HDOJLIMA.js";import"./chunk-4OLKWKJG.js";import"./chunk-7AYINDN2.js";import"./chunk-N66TLOH2.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{a as deriveAck,b as pollOnce,c as startConnectLoop};
1
+ import{Ra as a,Sa as b,Ta as c}from"./chunk-QFOUQIUB.js";import"./chunk-4OLKWKJG.js";import"./chunk-7AYINDN2.js";import"./chunk-N66TLOH2.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{a as deriveAck,b as pollOnce,c as startConnectLoop};
package/dist/oauth.js CHANGED
@@ -1 +1 @@
1
- import{$ as f,R as a,S as b,Y as c,Z as d,_ as e,aa as g,ba as h}from"./chunk-HDOJLIMA.js";import"./chunk-4OLKWKJG.js";import"./chunk-7AYINDN2.js";import"./chunk-N66TLOH2.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{d as OAuthCallbackError,c as buildOAuthAuthorizeUrl,b as decodeOAuthState,a as encodeOAuthState,e as generateOAuthUrl,f as processOAuthCallback,g as renewSubscriptions,h as startSubscriptionRenewal};
1
+ import{$ as f,R as a,S as b,Y as c,Z as d,_ as e,aa as g,ba as h}from"./chunk-QFOUQIUB.js";import"./chunk-4OLKWKJG.js";import"./chunk-7AYINDN2.js";import"./chunk-N66TLOH2.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{d as OAuthCallbackError,c as buildOAuthAuthorizeUrl,b as decodeOAuthState,a as encodeOAuthState,e as generateOAuthUrl,f as processOAuthCallback,g as renewSubscriptions,h as startSubscriptionRenewal};
@@ -1 +1 @@
1
- import{P as a,Q as b}from"./chunk-HDOJLIMA.js";import"./chunk-4OLKWKJG.js";import"./chunk-7AYINDN2.js";import"./chunk-N66TLOH2.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{b as applySetupCredentials,a as setupCorsair};
1
+ import{P as a,Q as b}from"./chunk-QFOUQIUB.js";import"./chunk-4OLKWKJG.js";import"./chunk-7AYINDN2.js";import"./chunk-N66TLOH2.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{b as applySetupCredentials,a as setupCorsair};
@@ -1 +1 @@
1
- import{ca as a,da as b,ea as c,fa as d}from"./chunk-HDOJLIMA.js";import"./chunk-4OLKWKJG.js";import"./chunk-7AYINDN2.js";import"./chunk-N66TLOH2.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{b as buildConnectPluginManifest,a as buildConnectPluginManifestFromContext,d as ensureConnectAccountRows,c as ensureConnectAccountRowsFromContext};
1
+ import{ca as a,da as b,ea as c,fa as d}from"./chunk-QFOUQIUB.js";import"./chunk-4OLKWKJG.js";import"./chunk-7AYINDN2.js";import"./chunk-N66TLOH2.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{b as buildConnectPluginManifest,a as buildConnectPluginManifestFromContext,d as ensureConnectAccountRows,c as ensureConnectAccountRowsFromContext};
package/dist/setup.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as CorsairInternalConfig } from './index-CM92kJI-.js';
1
+ import { a as CorsairInternalConfig } from './index-Dy0NLzS3.js';
2
2
  import { C as CorsairPlugin, e as CorsairSingleTenantClient, d as CorsairTenantWrapper } from './index-BzjK9SZA.js';
3
3
  import { CorsairDatabase } from './db.js';
4
4
  import 'zod';
package/dist/setup.js CHANGED
@@ -1 +1 @@
1
- import{P as a,Q as b}from"./chunk-HDOJLIMA.js";import"./chunk-4OLKWKJG.js";import"./chunk-7AYINDN2.js";import"./chunk-N66TLOH2.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{b as applySetupCredentials,a as setupCorsair};
1
+ import{P as a,Q as b}from"./chunk-QFOUQIUB.js";import"./chunk-4OLKWKJG.js";import"./chunk-7AYINDN2.js";import"./chunk-N66TLOH2.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{b as applySetupCredentials,a as setupCorsair};
package/dist/tunnel.js CHANGED
@@ -1 +1 @@
1
- import{Ja as f,Ka as g,La as h,Ma as i,Na as j,Oa as k,Pa as l,Qa as m,U as b,V as c,W as d,X as e,s as a}from"./chunk-HDOJLIMA.js";import"./chunk-4OLKWKJG.js";import"./chunk-7AYINDN2.js";import"./chunk-N66TLOH2.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{l as applyPermissionDecision,f as executeWorkflowRun,h as isAuthCredentialsBrowserDelivery,k as isByoOAuthBrowserDelivery,j as isManagedBrowserDelivery,i as isPermissionBrowserDelivery,m as processCorsair,c as resolveAccountFromWebhookLink,e as resolveTenantFromWebhookLink,d as resolveTenantIdFromWebhookLink,g as runReadonlyProbe,b as setWebhookTenantLink,a as verifyBrowserDeliveryToken};
1
+ import{Ja as f,Ka as g,La as h,Ma as i,Na as j,Oa as k,Pa as l,Qa as m,U as b,V as c,W as d,X as e,s as a}from"./chunk-QFOUQIUB.js";import"./chunk-4OLKWKJG.js";import"./chunk-7AYINDN2.js";import"./chunk-N66TLOH2.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{l as applyPermissionDecision,f as executeWorkflowRun,h as isAuthCredentialsBrowserDelivery,k as isByoOAuthBrowserDelivery,j as isManagedBrowserDelivery,i as isPermissionBrowserDelivery,m as processCorsair,c as resolveAccountFromWebhookLink,e as resolveTenantFromWebhookLink,d as resolveTenantIdFromWebhookLink,g as runReadonlyProbe,b as setWebhookTenantLink,a as verifyBrowserDeliveryToken};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "corsair",
3
- "version": "0.1.129",
3
+ "version": "0.1.130",
4
4
  "description": "Open-source integration layer for AI agents and apps. Managed OAuth, webhooks, and one API for 200+ integrations, with credentials that stay in your own database.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -83,10 +83,10 @@
83
83
  "zod": "^4.1.13"
84
84
  },
85
85
  "optionalDependencies": {
86
- "@corsair-dev/frpc-darwin-x64": "0.1.117",
87
86
  "@corsair-dev/frpc-darwin-arm64": "0.1.117",
88
87
  "@corsair-dev/frpc-linux-arm64": "0.1.117",
89
88
  "@corsair-dev/frpc-linux-x64": "0.1.117",
89
+ "@corsair-dev/frpc-darwin-x64": "0.1.117",
90
90
  "@corsair-dev/frpc-win32-arm64": "0.1.117",
91
91
  "@corsair-dev/frpc-win32-x64": "0.1.117"
92
92
  },