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