corsair 0.1.130 → 0.1.131
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-BIweOz_D.d.ts → browser-delivery-B-wwTCU1.d.ts} +1 -1
- package/dist/chunk-6IURNA4L.js +1 -0
- package/dist/{chunk-QFOUQIUB.js → chunk-OP2RVRNB.js} +3 -3
- package/dist/{connect-BM3VAVNP.js → connect-ZWRSHTZ6.js} +1 -1
- package/dist/core.d.ts +4 -4
- package/dist/core.js +1 -1
- package/dist/hub/tunnel/run-tunnel.js +1 -1
- package/dist/hub.d.ts +7 -7
- package/dist/hub.js +1 -1
- package/dist/{index-4oKvjBws.d.ts → index-C1LLhMI1.d.ts} +1 -1
- package/dist/{index-BzjK9SZA.d.ts → index-C6OPrZ-q.d.ts} +1 -1
- package/dist/{index-Dy0NLzS3.d.ts → index-CDIwDm35.d.ts} +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.js +1 -1
- package/dist/{loop-335YKNR2.js → loop-XAOZRMBN.js} +1 -1
- package/dist/oauth.d.ts +1 -1
- package/dist/oauth.js +1 -1
- package/dist/setup-LFPX6UVE.js +1 -0
- package/dist/{setup-introspect-J77AZVKF.js → setup-introspect-POYZQMHO.js} +1 -1
- package/dist/setup.d.ts +2 -2
- package/dist/setup.js +1 -1
- package/dist/{tenant-match-utils-CQ0UAjUs.d.ts → tenant-match-utils-CHag-lmL.d.ts} +1 -1
- package/dist/tunnel.d.ts +4 -4
- package/dist/tunnel.js +1 -1
- package/package.json +4 -4
- package/dist/chunk-4OLKWKJG.js +0 -1
- package/dist/setup-PXJ3S3RO.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as o}from"./chunk-SOY77BN4.js";var l="3000",m="/api/corsair";function R(r){return r.replace(/\/$/,"")}function I(r){let e=r?.deliveryUrl?.trim()||process.env.CORSAIR_DELIVERY_URL?.trim();if(e){let f=/^https?:\/\//i.test(e)?e:`https://${e}`;return R(f)}return`http://localhost:${process.env.PORT?.trim()||l}${m}`}var P="corsair.run",$="/api/corsair";import{chmodSync as d,existsSync as c,statSync as h}from"fs";import{createRequire as g}from"module";import{homedir as y}from"os";import{dirname as _,join as p}from"path";var v="0.71.0",i;function x(){return i??=g(o),i}function S(){let r=`@corsair-dev/frpc-${process.platform}-${process.arch}`;try{let e=p(_(x().resolve(`${r}/package.json`)),u());return c(e)?e:null}catch{return null}}function a(){return`${process.platform}-${process.arch}`}function u(){return process.platform==="win32"?"frpc.exe":"frpc"}function E(){return p(y(),".cache","corsair","frpc",v,a(),u())}function n(r){if(process.platform==="win32")return r;try{let e=h(r).mode&511,t=e|73;t!==e&&d(r,t)}catch{}return r}function B(){let r=process.env.CORSAIR_FRP_BIN;if(r&&c(r))return n(r);let e=S();if(e)return n(e);let t=E();if(c(t))return n(t);throw new Error(`frpc binary not found for ${a()}. If you use pnpm, run \`pnpm approve-builds corsair\` (or add corsair to onlyBuiltDependencies) and reinstall; otherwise reinstall corsair, or set CORSAIR_FRP_BIN to an frpc path (https://github.com/fatedier/frp/releases).`)}export{I as a,P as b,$ as c,v as d,a as e,B as f};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as ve,b as Yt,c as Qt}from"./chunk-4OLKWKJG.js";import{a as Bo,b as Te,c as Fo,d as v,e as j,f as Uo,g as z,h as $,i as I,j as jn,k as No,l as ze,m as Vt,n as Lo}from"./chunk-7AYINDN2.js";import{a as Ho}from"./chunk-N66TLOH2.js";import{ZodBoolean as Rl,ZodDate as xl,ZodEnum as Il,ZodNullable as Sl,ZodNumber as _l,ZodObject as El,ZodOptional as Dl,ZodRecord as Ol,ZodString as Ml,ZodType as Hl}from"zod";var qn=["ably","abstract","abuseipdb","abyssale","accrediblecertificates","activecampaign","activetrail","addresszen","aeroleads","affinda","agencyzoom","agentmail","agentql","agenty","agiled","agilitycms","ahrefs","aimlapi","airtable","aivoov","alchemy","algolia","allimagesai","alphavantage","altoviz","alttextai","amara","ambee","ambientweather","amcards","amplitude","anchorbrowser","anonyflow","anthropicadministrator","apaleo","api2pdf","apibible","apify","apilabz","apininjas","apipie","apisports","appointo","asana","ascora","ashby","asindataapi","asticaai","asyncinterview","attio","autom","ayrshare","backendless","bannerbear","bart","basecamp","baselinker","basin","beaconstac","beeminder","benchmarkemail","bestbuy","bettercontact","betterproposals","betterstack","bigdatacloud","bigmailer","bigml","bitbucket","bitwarden","blazemeter","blocknative","bluesky","boldsign","boloforms","boltiot","bonsai","bookingmood","borneo","botbaba","botpress","botsonic","bouncer","box","boxhero","brandfetch","breathehr","brevo","brex","brightdata","browseai","browserless","browsertool","bubble","bugsnag","buildkite","bunnycdn","cal","calendly","campayn","canva","canvas","capsulecrm","castingwords","cdrplatform","certifier","chatbotkit","chatfai","chmeetings","circleci","clickhouse","clientary","clockify","cloudflare","cloudinary","collegefootballdata","confluence","connecteam","contentfulgraphql","contextsevenmcp","convoloai","countdownapi","crowterminal","cursor","customgpt","dadataru","databricks","datadog","datarobot","deepseek","devinmcp","diffbot","digitalocean","discord","dockerhub","dodopayments","doppler","dreamstudio","dripcel","dropbox","dropboxsign","dynapictures","epicgames","exa","exist","facebook","faraday","figma","filloutforms","firecrawl","fireflies","flexisign","formbricks","gemini","github","gitlab","gladia","gmail","googleaddressvalidation","googleanalytics","googlebigquery","googlecalendar","googlecloudvision","googledocs","googledrive","googlemaps","googlemeet","googlesheets","grafana","griptape","groqcloud","habitica","hackernews","harvest","hashnode","here","heygen","htmltoimage","hubspot","huggingface","imgbb","insightoai","instagram","intercom","jigsawstack","jira","kaggle","linear","linkedin","loyverse","mailboxlayer","mailchimp","mailtrap","marketstack","merriamwebsterdict","monday","neon","nextdns","notion","ocrspace","ocrwebservice","ollama","onedrive","onepassword","openai","openrouter","openweathermap","oura","outlook","pagerduty","parseur","pdfmonkey","perplexityai","pinecone","posthog","razorpay","reddit","removebg","resend","retailed","runpod","salesforce","sapsuccessfactors","scaleai","scrapegraphai","securitytrails","sendgrid","sentry","serpapi","sharepoint","slack","sourcegraph","spotify","strava","streamtime","stripe","studiobyai21labs","supabase","synthflowai","tally","tavily","tavilymcp","teams","telegram","textrazor","ticktick","timecamp","timelink","tinyurl","tisane","todoist","toggl","trello","twentyonerisk","twilio","twitter","twitterapiio","twochat","typeform","unione","uniswapapi","uploadcare","vapi","vercel","vestaboard","wakatime","webflow","webvizio","whatsapp","witai","wix","wiza","workday","workiom","worldnewsapi","xquik","youcom","youtube","zendesk","zohoinventory","zohomail","zoom","zoominfo"],$o={ably:"Ably",abstract:"Abstract",abuseipdb:"AbuseIPDB",abyssale:"Abyssale",accrediblecertificates:"Accredible Certificates",activecampaign:"ActiveCampaign",activetrail:"Active Trail",addresszen:"Addresszen",aeroleads:"Aeroleads",affinda:"Affinda",agencyzoom:"AgencyZoom",agentmail:"AgentMail",agentql:"AgentQL",agenty:"Agenty",agiled:"Agiled",agilitycms:"Agility CMS",ahrefs:"Ahrefs",aimlapi:"AI/ML API",airtable:"Airtable",aivoov:"AiVOOV",alchemy:"Alchemy",algolia:"Algolia",allimagesai:"All Images AI",alphavantage:"Alpha Vantage",altoviz:"Altoviz",alttextai:"AltText.ai",amara:"Amara",ambee:"Ambee",ambientweather:"Ambient Weather",amcards:"AMcards",amplitude:"Amplitude",anchorbrowser:"Anchor Browser",anonyflow:"Anonyflow",anthropicadministrator:"Anthropic Administrator",apaleo:"Apaleo",api2pdf:"API2PDF",apibible:"API.Bible",apify:"Apify",apilabz:"API Labz",apininjas:"API Ninjas",apipie:"APIpie AI",apisports:"API-Sports",appointo:"Appointo",asana:"Asana",ascora:"Ascora",ashby:"Ashby",asindataapi:"ASIN Data API",asticaai:"Astica AI",asyncinterview:"Async Interview",attio:"Attio",autom:"Autom",ayrshare:"Ayrshare",backendless:"Backendless",bannerbear:"Bannerbear",bart:"BART",basecamp:"Basecamp",baselinker:"BaseLinker",basin:"Basin",beaconstac:"Beaconstac",beeminder:"Beeminder",benchmarkemail:"BenchmarkEmail",bestbuy:"Best Buy",bettercontact:"BetterContact",betterproposals:"Better Proposals",betterstack:"Better Stack",bigdatacloud:"BigDataCloud",bigmailer:"BigMailer",bigml:"BigML",bitbucket:"Bitbucket",bitwarden:"Bitwarden",blazemeter:"BlazeMeter",blocknative:"Blocknative",bluesky:"Bluesky",boldsign:"Boldsign",boloforms:"Boloforms",boltiot:"Bolt IoT",bonsai:"Bonsai",bookingmood:"Bookingmood",borneo:"Borneo",botbaba:"Botbaba",botpress:"Botpress",botsonic:"Botsonic",bouncer:"Bouncer",box:"Box",boxhero:"BoxHero",brandfetch:"Brandfetch",breathehr:"Breathe HR",brevo:"Brevo",brex:"Brex",brightdata:"Bright Data",browseai:"Browse AI",browserless:"Browserless",browsertool:"Browser Tool",bubble:"Bubble",bugsnag:"BugSnag",buildkite:"Buildkite",bunnycdn:"Bunnycdn",cal:"Cal",calendly:"Calendly",campayn:"Campayn",canva:"Canva",canvas:"Canvas LMS",capsulecrm:"Capsule CRM",castingwords:"CastingWords",cdrplatform:"CDR Platform",certifier:"Certifier",chatbotkit:"ChatBotKit",chatfai:"ChatFAI",chmeetings:"ChMeetings",circleci:"CircleCI",clickhouse:"Clickhouse",clientary:"Clientary",clockify:"Clockify",cloudflare:"Cloudflare",cloudinary:"Cloudinary",collegefootballdata:"College Football Data",confluence:"Confluence",connecteam:"Connecteam",contentfulgraphql:"Contentful GraphQL",contextsevenmcp:"Context7",convoloai:"ConvoloAi",countdownapi:"Countdown API",crowterminal:"CrowTerminal",cursor:"Cursor",customgpt:"CustomGPT",dadataru:"Dadataru",databricks:"Databricks",datadog:"Datadog",datarobot:"DataRobot",deepseek:"DeepSeek",devinmcp:"Devin MCP",diffbot:"Diffbot",digitalocean:"DigitalOcean",discord:"Discord",dockerhub:"Docker Hub",dodopayments:"Dodo Payments",doppler:"Doppler",dreamstudio:"DreamStudio",dripcel:"Dripcel",dropbox:"Dropbox",dropboxsign:"Dropbox Sign",dynapictures:"Dynapictures",epicgames:"Epic Games",exa:"Exa",exist:"Exist",facebook:"Facebook",faraday:"Faraday",figma:"Figma",filloutforms:"FilloutForms",firecrawl:"Firecrawl",fireflies:"Fireflies",flexisign:"Flexisign",formbricks:"Formbricks",gemini:"Gemini",github:"GitHub",gitlab:"GitLab",gladia:"Gladia",gmail:"Gmail",googleaddressvalidation:"Google Address Validation",googleanalytics:"Google Analytics",googlebigquery:"Google BigQuery",googlecalendar:"Google Calendar",googlecloudvision:"Google Cloud Vision",googledocs:"Google Docs",googledrive:"Google Drive",googlemaps:"Google Maps",googlemeet:"Google Meet",googlesheets:"Google Sheets",grafana:"Grafana",griptape:"Griptape",groqcloud:"GroqCloud",habitica:"Habitica",hackernews:"Hacker News",harvest:"Harvest",hashnode:"Hashnode",here:"HERE",heygen:"HeyGen",htmltoimage:"HtmlToImage",hubspot:"HubSpot",huggingface:"Hugging Face",imgbb:"ImgBB",insightoai:"Insighto.ai",instagram:"Instagram",intercom:"Intercom",jigsawstack:"JigsawStack",jira:"Jira",kaggle:"Kaggle",linear:"Linear",linkedin:"LinkedIn",loyverse:"Loyverse",mailboxlayer:"MailboxLayer",mailchimp:"Mailchimp",mailtrap:"Mailtrap",marketstack:"Marketstack",merriamwebsterdict:"Merriam-Webster Dictionary",monday:"Monday",neon:"Neon",nextdns:"NextDNS",notion:"Notion",ocrspace:"OCR.space",ocrwebservice:"OcrWebService",ollama:"Ollama",onedrive:"OneDrive",onepassword:"1Password",openai:"OpenAI",openrouter:"OpenRouter",openweathermap:"OpenWeatherMap",oura:"Oura",outlook:"Outlook",pagerduty:"PagerDuty",parseur:"Parseur",pdfmonkey:"PDFMonkey",perplexityai:"Perplexity AI",pinecone:"Pinecone",posthog:"PostHog",razorpay:"Razorpay",reddit:"Reddit",removebg:"remove.bg",resend:"Resend",retailed:"Retailed",runpod:"RunPod",salesforce:"Salesforce",sapsuccessfactors:"SAP SuccessFactors",scaleai:"Scale AI",scrapegraphai:"ScrapeGraphAI",securitytrails:"SecurityTrails",sendgrid:"SendGrid",sentry:"Sentry",serpapi:"Serpapi",sharepoint:"SharePoint",slack:"Slack",sourcegraph:"Sourcegraph",spotify:"Spotify",strava:"Strava",streamtime:"Streamtime",stripe:"Stripe",studiobyai21labs:"StudioByAI21Labs",supabase:"Supabase",synthflowai:"Synthflow AI",tally:"Tally",tavily:"Tavily",tavilymcp:"Tavily MCP",teams:"Teams",telegram:"Telegram",textrazor:"TextRazor",ticktick:"TickTick",timecamp:"TimeCamp",timelink:"Timelink",tinyurl:"TinyURL",tisane:"Tisane",todoist:"Todoist",toggl:"Toggl",trello:"Trello",twentyonerisk:"TwentyOneRisk",twilio:"Twilio",twitter:"Twitter",twitterapiio:"Twitter API IO",twochat:"TwoChat",typeform:"Typeform",unione:"Unione",uniswapapi:"Uniswap",uploadcare:"Uploadcare",vapi:"Vapi",vercel:"Vercel",vestaboard:"Vestaboard",wakatime:"WakaTime",webflow:"Webflow",webvizio:"Webvizio",whatsapp:"WhatsApp",witai:"WitAi",wix:"Wix",wiza:"Wiza",workday:"Workday",workiom:"Workiom",worldnewsapi:"World News API",xquik:"XQuik",youcom:"You.com",youtube:"YouTube",zendesk:"Zendesk",zohoinventory:"Zoho Inventory",zohomail:"Zoho Mail",zoom:"Zoom",zoominfo:"ZoomInfo"};function Pe(e){let n=$o[e];return n||e.charAt(0).toUpperCase()+e.slice(1)}var pe=class extends Error{connectUrl;plugin;tenantId;reason;constructor(n){super(n.message??"Reconnect required"),Object.setPrototypeOf(this,new.target.prototype),this.name="ReconnectRequiredError",this.connectUrl=n.connectUrl,this.plugin=n.plugin,this.tenantId=n.tenantId,this.reason=n.reason}};function E(e){return typeof e=="string"&&e.length>0}function Ta(e){return e==="ready"||e==="partial"||e==="not_started"||e==="missing_integration"}function Pa(e){return e==="oauth_2"||e==="api_key"||e==="bot_token"||e==="managed"}function Kn(e){if(!e||typeof e!="object")throw new Error("Hub API returned an empty connect session");let n=e;if(!E(n.connectUrl)||!E(n.token)||!E(n.projectId))throw new Error("Hub API returned an incomplete connect session (expected connectUrl, token, and projectId)");let t={connectUrl:n.connectUrl,token:n.token,projectId:n.projectId,environmentId:E(n.environmentId)?n.environmentId:n.projectId};return E(n.expiresAt)&&(t.expiresAt=n.expiresAt),t}function Zn(e){if(!Array.isArray(e))throw new Error("Hub API returned an invalid connections response (expected array)");let n=[];for(let t of e){if(!t||typeof t!="object")continue;let r=t;if(!E(r.tenantId)||!E(r.plugin)||!Ta(r.status)||!Pa(r.authType)||typeof r.connected!="boolean"||typeof r.verified!="boolean")continue;let o=Array.isArray(r.missingFields)?r.missingFields.filter(i=>typeof i=="string"):[];n.push({tenantId:r.tenantId,plugin:r.plugin,status:r.status,authType:r.authType,connected:r.connected,verified:r.verified,missingFields:o,reportedAt:E(r.reportedAt)?r.reportedAt:new Date().toISOString()})}return n}function Gn(e){if(!e||typeof e!="object")throw new Error("Hub API returned an empty permission session");let n=e;if(!E(n.approvalUrl)||!E(n.token)||!E(n.projectId)||!E(n.expiresAt))throw new Error("Hub API returned an incomplete permission session (expected approvalUrl, token, projectId, and expiresAt)");return{approvalUrl:n.approvalUrl,token:n.token,projectId:n.projectId,expiresAt:n.expiresAt}}function Je(e){if(!e||typeof e!="object")throw new Error("Hub token refresh returned an empty response");let n=e;if(E(n.access_token))return{access_token:n.access_token,refresh_token:E(n.refresh_token)?n.refresh_token:void 0,expires_in:(()=>{if(typeof n.expires_in=="number")return n.expires_in;if(typeof n.expires_in=="string"&&n.expires_in.trim().length>0){let t=Number(n.expires_in);return Number.isFinite(t)?t:void 0}})(),scope:E(n.scope)?n.scope:void 0};throw new Error(E(n.error)?E(n.error_description)?n.error_description:n.error:"Hub token refresh returned no access_token")}function Aa(e){return Array.isArray(e)?e.filter(n=>typeof n=="string"):[]}function Ra(e){if(!Array.isArray(e))return[];let n=[];for(let t of e){if(!t||typeof t!="object")continue;let r=t;E(r.name)&&n.push({name:r.name,level:r.level==="integration"||r.level==="account"?r.level:"account",required:r.required===!0,configured:r.configured===!0})}return n}function xa(e,n,t,r){return e==="ready"||e==="partial"||e==="not_started"||e==="missing_integration"?e:n?"ready":t.some(i=>i.level==="integration"&&i.required&&!i.configured)?"missing_integration":t.some(i=>i.level==="account"&&i.required&&i.configured)?"partial":(r.length>0,"not_started")}function Wo(e){if(!e||typeof e!="object")throw new Error("Connect status response was empty");let n=e;if(!E(n.tenantId)||!Array.isArray(n.plugins))throw new Error("Connect status response was incomplete (expected tenantId and plugins)");let t=[];for(let r of n.plugins){if(!r||typeof r!="object")continue;let o=r;if(!E(o.plugin)||typeof o.connected!="boolean")continue;let i=o.authKind==="oauth"||o.authKind==="api_key"||o.authKind==="bot_token"?o.authKind:"api_key",s=Ra(o.fields),a=Aa(o.missingRequiredFields),c=xa(o.status,o.connected,s,a);t.push({plugin:o.plugin,providerName:E(o.providerName)?o.providerName:o.plugin,authKind:i,status:c,connected:o.connected,fields:s,missingRequiredFields:a})}return{tenantId:n.tenantId,plugins:t}}function zn(e){if(!e||typeof e!="object")return null;let n=e;return n.error??n.message??null}function jo(e){if(!e||typeof e!="object")return null;let n=e;if(n.errorType!=="reconnect_required")return null;let t=r=>typeof r=="string"&&r.length>0?r:null;return{message:t(n.error),connectUrl:t(n.connectUrl),plugin:t(n.plugin),tenantId:t(n.tenantId),reason:t(n.reason)}}function qo(e){return e.replace(/\/$/,"")}function Xt(e){if(!e.projectApiKey.startsWith("ck_dev_"))return null;try{return ve()}catch{return null}}function Ko(e){let n=Xt(e);return n?{"x-corsair-delivery-url":n}:{}}async function Zo(e){let n=e.headers.get("content-type")??"",t=await e.text();if(!t)return null;if(!n.includes("application/json")&&t.trimStart().startsWith("<"))throw new Error(`Hub API returned HTML instead of JSON (HTTP ${e.status}). Check HUB_API_URL and deploy the latest hub API.`);try{return JSON.parse(t)}catch{throw new Error(`Hub API returned invalid JSON (HTTP ${e.status})`)}}function Ia(e,n,t){if(n===404&&t)return t;let r=zn(e);return r||`Hub API returned HTTP ${n}`}function Go(e,n,t){let r=jo(e);throw r?new pe({message:r.message??void 0,connectUrl:r.connectUrl,plugin:r.plugin,tenantId:r.tenantId,reason:r.reason??void 0}):new Error(Ia(e,n,t))}async function x(e){let n=qo(e.hub.apiUrl),t=await fetch(`${n}${e.path}`,{method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${e.hub.projectApiKey}`,...Ko(e.hub)},body:JSON.stringify(e.body)}),r=await Zo(t);return t.ok||Go(r,t.status,e.notFoundMessage),e.parseResponse(r)}async function W(e){let n=qo(e.hub.apiUrl),t=await fetch(`${n}${e.path}`,{method:"GET",headers:{authorization:`Bearer ${e.hub.projectApiKey}`,...Ko(e.hub)}}),r=await Zo(t);return t.ok||Go(r,t.status,e.notFoundMessage),e.parseResponse(r)}function Jn(e){return e&&typeof e=="object"?e:{}}function zo(e){let n=Jn(e);return{chatId:n.threadId,message:n.message,workflowId:n.workflowId??null,action:n.action}}async function er(e,n){return x({hub:e,path:"/threads",body:{tenantId:n.tenantId,message:n.message},parseResponse:t=>{let r=Jn(t);return{chat:r.thread,reply:zo(r.reply)}}})}async function nr(e,n){return x({hub:e,path:`/threads/${encodeURIComponent(n.chatId)}/messages`,body:{tenantId:n.tenantId,message:n.message},notFoundMessage:`Chat "${n.chatId}" not found`,parseResponse:zo})}async function tr(e,n){return W({hub:e,path:`/threads?tenantId=${encodeURIComponent(n.tenantId)}`,parseResponse:t=>{let r=Jn(t).threads;return Array.isArray(r)?r:[]}})}async function rr(e,n){return W({hub:e,path:`/threads/${encodeURIComponent(n.chatId)}/messages?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Chat "${n.chatId}" not found`,parseResponse:t=>{let r=Jn(t).messages;return Array.isArray(r)?r:[]}})}import{randomUUID as Ha}from"crypto";var Sa="corsair:client-bridge";function or(e){return new URL(e).origin}function Ve(e){let n=JSON.stringify({type:Sa,requestId:e.requestId,ok:e.ok,body:e.body??null,error:e.error??null}),t=JSON.stringify(or(e.hubOrigin));return`<!DOCTYPE html><html><head><meta charset="utf-8"></head><body><script>
|
|
1
|
+
import{a as ve,b as Yt,c as Qt}from"./chunk-6IURNA4L.js";import{a as Bo,b as Te,c as Fo,d as v,e as j,f as Uo,g as z,h as $,i as I,j as jn,k as No,l as ze,m as Vt,n as Lo}from"./chunk-7AYINDN2.js";import{a as Ho}from"./chunk-N66TLOH2.js";import{ZodBoolean as Rl,ZodDate as xl,ZodEnum as Il,ZodNullable as Sl,ZodNumber as _l,ZodObject as El,ZodOptional as Dl,ZodRecord as Ol,ZodString as Ml,ZodType as Hl}from"zod";var qn=["ably","abstract","abuseipdb","abyssale","accrediblecertificates","activecampaign","activetrail","addresszen","aeroleads","affinda","agencyzoom","agentmail","agentql","agenty","agiled","agilitycms","ahrefs","aimlapi","airtable","aivoov","alchemy","algolia","allimagesai","alphavantage","altoviz","alttextai","amara","ambee","ambientweather","amcards","amplitude","anchorbrowser","anonyflow","anthropicadministrator","apaleo","api2pdf","apibible","apify","apilabz","apininjas","apipie","apisports","appointo","asana","ascora","ashby","asindataapi","asticaai","asyncinterview","attio","autom","ayrshare","backendless","bannerbear","bart","basecamp","baselinker","basin","beaconstac","beeminder","benchmarkemail","bestbuy","bettercontact","betterproposals","betterstack","bigdatacloud","bigmailer","bigml","bitbucket","bitwarden","blazemeter","blocknative","bluesky","boldsign","boloforms","boltiot","bonsai","bookingmood","borneo","botbaba","botpress","botsonic","bouncer","box","boxhero","brandfetch","breathehr","brevo","brex","brightdata","browseai","browserless","browsertool","bubble","bugsnag","buildkite","bunnycdn","cal","calendly","campayn","canva","canvas","capsulecrm","castingwords","cdrplatform","certifier","chatbotkit","chatfai","chmeetings","circleci","clickhouse","clientary","clockify","cloudflare","cloudinary","collegefootballdata","confluence","connecteam","contentfulgraphql","contextsevenmcp","convoloai","countdownapi","crowterminal","cursor","customgpt","dadataru","databricks","datadog","datarobot","deepseek","devinmcp","diffbot","digitalocean","discord","dockerhub","dodopayments","doppler","dreamstudio","dripcel","dropbox","dropboxsign","dynapictures","epicgames","exa","exist","facebook","faraday","figma","filloutforms","firecrawl","fireflies","flexisign","formbricks","gemini","github","gitlab","gladia","gmail","googleaddressvalidation","googleanalytics","googlebigquery","googlecalendar","googlecloudvision","googledocs","googledrive","googlemaps","googlemeet","googlesheets","grafana","griptape","groqcloud","habitica","hackernews","harvest","hashnode","here","heygen","htmltoimage","hubspot","huggingface","imgbb","insightoai","instagram","intercom","jigsawstack","jira","kaggle","linear","linkedin","loyverse","mailboxlayer","mailchimp","mailtrap","marketstack","merriamwebsterdict","monday","neon","nextdns","notion","ocrspace","ocrwebservice","ollama","onedrive","onepassword","openai","openrouter","openweathermap","oura","outlook","pagerduty","parseur","pdfmonkey","perplexityai","pinecone","posthog","razorpay","reddit","removebg","resend","retailed","runpod","salesforce","sapsuccessfactors","scaleai","scrapegraphai","securitytrails","sendgrid","sentry","serpapi","sharepoint","slack","sourcegraph","spotify","strava","streamtime","stripe","studiobyai21labs","supabase","synthflowai","tally","tavily","tavilymcp","teams","telegram","textrazor","ticktick","timecamp","timelink","tinyurl","tisane","todoist","toggl","trello","twentyonerisk","twilio","twitter","twitterapiio","twochat","typeform","unione","uniswapapi","uploadcare","vapi","vercel","vestaboard","wakatime","webflow","webvizio","whatsapp","witai","wix","wiza","workday","workiom","worldnewsapi","xquik","youcom","youtube","zendesk","zohoinventory","zohomail","zoom","zoominfo"],$o={ably:"Ably",abstract:"Abstract",abuseipdb:"AbuseIPDB",abyssale:"Abyssale",accrediblecertificates:"Accredible Certificates",activecampaign:"ActiveCampaign",activetrail:"Active Trail",addresszen:"Addresszen",aeroleads:"Aeroleads",affinda:"Affinda",agencyzoom:"AgencyZoom",agentmail:"AgentMail",agentql:"AgentQL",agenty:"Agenty",agiled:"Agiled",agilitycms:"Agility CMS",ahrefs:"Ahrefs",aimlapi:"AI/ML API",airtable:"Airtable",aivoov:"AiVOOV",alchemy:"Alchemy",algolia:"Algolia",allimagesai:"All Images AI",alphavantage:"Alpha Vantage",altoviz:"Altoviz",alttextai:"AltText.ai",amara:"Amara",ambee:"Ambee",ambientweather:"Ambient Weather",amcards:"AMcards",amplitude:"Amplitude",anchorbrowser:"Anchor Browser",anonyflow:"Anonyflow",anthropicadministrator:"Anthropic Administrator",apaleo:"Apaleo",api2pdf:"API2PDF",apibible:"API.Bible",apify:"Apify",apilabz:"API Labz",apininjas:"API Ninjas",apipie:"APIpie AI",apisports:"API-Sports",appointo:"Appointo",asana:"Asana",ascora:"Ascora",ashby:"Ashby",asindataapi:"ASIN Data API",asticaai:"Astica AI",asyncinterview:"Async Interview",attio:"Attio",autom:"Autom",ayrshare:"Ayrshare",backendless:"Backendless",bannerbear:"Bannerbear",bart:"BART",basecamp:"Basecamp",baselinker:"BaseLinker",basin:"Basin",beaconstac:"Beaconstac",beeminder:"Beeminder",benchmarkemail:"BenchmarkEmail",bestbuy:"Best Buy",bettercontact:"BetterContact",betterproposals:"Better Proposals",betterstack:"Better Stack",bigdatacloud:"BigDataCloud",bigmailer:"BigMailer",bigml:"BigML",bitbucket:"Bitbucket",bitwarden:"Bitwarden",blazemeter:"BlazeMeter",blocknative:"Blocknative",bluesky:"Bluesky",boldsign:"Boldsign",boloforms:"Boloforms",boltiot:"Bolt IoT",bonsai:"Bonsai",bookingmood:"Bookingmood",borneo:"Borneo",botbaba:"Botbaba",botpress:"Botpress",botsonic:"Botsonic",bouncer:"Bouncer",box:"Box",boxhero:"BoxHero",brandfetch:"Brandfetch",breathehr:"Breathe HR",brevo:"Brevo",brex:"Brex",brightdata:"Bright Data",browseai:"Browse AI",browserless:"Browserless",browsertool:"Browser Tool",bubble:"Bubble",bugsnag:"BugSnag",buildkite:"Buildkite",bunnycdn:"Bunnycdn",cal:"Cal",calendly:"Calendly",campayn:"Campayn",canva:"Canva",canvas:"Canvas LMS",capsulecrm:"Capsule CRM",castingwords:"CastingWords",cdrplatform:"CDR Platform",certifier:"Certifier",chatbotkit:"ChatBotKit",chatfai:"ChatFAI",chmeetings:"ChMeetings",circleci:"CircleCI",clickhouse:"Clickhouse",clientary:"Clientary",clockify:"Clockify",cloudflare:"Cloudflare",cloudinary:"Cloudinary",collegefootballdata:"College Football Data",confluence:"Confluence",connecteam:"Connecteam",contentfulgraphql:"Contentful GraphQL",contextsevenmcp:"Context7",convoloai:"ConvoloAi",countdownapi:"Countdown API",crowterminal:"CrowTerminal",cursor:"Cursor",customgpt:"CustomGPT",dadataru:"Dadataru",databricks:"Databricks",datadog:"Datadog",datarobot:"DataRobot",deepseek:"DeepSeek",devinmcp:"Devin MCP",diffbot:"Diffbot",digitalocean:"DigitalOcean",discord:"Discord",dockerhub:"Docker Hub",dodopayments:"Dodo Payments",doppler:"Doppler",dreamstudio:"DreamStudio",dripcel:"Dripcel",dropbox:"Dropbox",dropboxsign:"Dropbox Sign",dynapictures:"Dynapictures",epicgames:"Epic Games",exa:"Exa",exist:"Exist",facebook:"Facebook",faraday:"Faraday",figma:"Figma",filloutforms:"FilloutForms",firecrawl:"Firecrawl",fireflies:"Fireflies",flexisign:"Flexisign",formbricks:"Formbricks",gemini:"Gemini",github:"GitHub",gitlab:"GitLab",gladia:"Gladia",gmail:"Gmail",googleaddressvalidation:"Google Address Validation",googleanalytics:"Google Analytics",googlebigquery:"Google BigQuery",googlecalendar:"Google Calendar",googlecloudvision:"Google Cloud Vision",googledocs:"Google Docs",googledrive:"Google Drive",googlemaps:"Google Maps",googlemeet:"Google Meet",googlesheets:"Google Sheets",grafana:"Grafana",griptape:"Griptape",groqcloud:"GroqCloud",habitica:"Habitica",hackernews:"Hacker News",harvest:"Harvest",hashnode:"Hashnode",here:"HERE",heygen:"HeyGen",htmltoimage:"HtmlToImage",hubspot:"HubSpot",huggingface:"Hugging Face",imgbb:"ImgBB",insightoai:"Insighto.ai",instagram:"Instagram",intercom:"Intercom",jigsawstack:"JigsawStack",jira:"Jira",kaggle:"Kaggle",linear:"Linear",linkedin:"LinkedIn",loyverse:"Loyverse",mailboxlayer:"MailboxLayer",mailchimp:"Mailchimp",mailtrap:"Mailtrap",marketstack:"Marketstack",merriamwebsterdict:"Merriam-Webster Dictionary",monday:"Monday",neon:"Neon",nextdns:"NextDNS",notion:"Notion",ocrspace:"OCR.space",ocrwebservice:"OcrWebService",ollama:"Ollama",onedrive:"OneDrive",onepassword:"1Password",openai:"OpenAI",openrouter:"OpenRouter",openweathermap:"OpenWeatherMap",oura:"Oura",outlook:"Outlook",pagerduty:"PagerDuty",parseur:"Parseur",pdfmonkey:"PDFMonkey",perplexityai:"Perplexity AI",pinecone:"Pinecone",posthog:"PostHog",razorpay:"Razorpay",reddit:"Reddit",removebg:"remove.bg",resend:"Resend",retailed:"Retailed",runpod:"RunPod",salesforce:"Salesforce",sapsuccessfactors:"SAP SuccessFactors",scaleai:"Scale AI",scrapegraphai:"ScrapeGraphAI",securitytrails:"SecurityTrails",sendgrid:"SendGrid",sentry:"Sentry",serpapi:"Serpapi",sharepoint:"SharePoint",slack:"Slack",sourcegraph:"Sourcegraph",spotify:"Spotify",strava:"Strava",streamtime:"Streamtime",stripe:"Stripe",studiobyai21labs:"StudioByAI21Labs",supabase:"Supabase",synthflowai:"Synthflow AI",tally:"Tally",tavily:"Tavily",tavilymcp:"Tavily MCP",teams:"Teams",telegram:"Telegram",textrazor:"TextRazor",ticktick:"TickTick",timecamp:"TimeCamp",timelink:"Timelink",tinyurl:"TinyURL",tisane:"Tisane",todoist:"Todoist",toggl:"Toggl",trello:"Trello",twentyonerisk:"TwentyOneRisk",twilio:"Twilio",twitter:"Twitter",twitterapiio:"Twitter API IO",twochat:"TwoChat",typeform:"Typeform",unione:"Unione",uniswapapi:"Uniswap",uploadcare:"Uploadcare",vapi:"Vapi",vercel:"Vercel",vestaboard:"Vestaboard",wakatime:"WakaTime",webflow:"Webflow",webvizio:"Webvizio",whatsapp:"WhatsApp",witai:"WitAi",wix:"Wix",wiza:"Wiza",workday:"Workday",workiom:"Workiom",worldnewsapi:"World News API",xquik:"XQuik",youcom:"You.com",youtube:"YouTube",zendesk:"Zendesk",zohoinventory:"Zoho Inventory",zohomail:"Zoho Mail",zoom:"Zoom",zoominfo:"ZoomInfo"};function Pe(e){let n=$o[e];return n||e.charAt(0).toUpperCase()+e.slice(1)}var pe=class extends Error{connectUrl;plugin;tenantId;reason;constructor(n){super(n.message??"Reconnect required"),Object.setPrototypeOf(this,new.target.prototype),this.name="ReconnectRequiredError",this.connectUrl=n.connectUrl,this.plugin=n.plugin,this.tenantId=n.tenantId,this.reason=n.reason}};function E(e){return typeof e=="string"&&e.length>0}function Ta(e){return e==="ready"||e==="partial"||e==="not_started"||e==="missing_integration"}function Pa(e){return e==="oauth_2"||e==="api_key"||e==="bot_token"||e==="managed"}function Kn(e){if(!e||typeof e!="object")throw new Error("Hub API returned an empty connect session");let n=e;if(!E(n.connectUrl)||!E(n.token)||!E(n.projectId))throw new Error("Hub API returned an incomplete connect session (expected connectUrl, token, and projectId)");let t={connectUrl:n.connectUrl,token:n.token,projectId:n.projectId,environmentId:E(n.environmentId)?n.environmentId:n.projectId};return E(n.expiresAt)&&(t.expiresAt=n.expiresAt),t}function Zn(e){if(!Array.isArray(e))throw new Error("Hub API returned an invalid connections response (expected array)");let n=[];for(let t of e){if(!t||typeof t!="object")continue;let r=t;if(!E(r.tenantId)||!E(r.plugin)||!Ta(r.status)||!Pa(r.authType)||typeof r.connected!="boolean"||typeof r.verified!="boolean")continue;let o=Array.isArray(r.missingFields)?r.missingFields.filter(i=>typeof i=="string"):[];n.push({tenantId:r.tenantId,plugin:r.plugin,status:r.status,authType:r.authType,connected:r.connected,verified:r.verified,missingFields:o,reportedAt:E(r.reportedAt)?r.reportedAt:new Date().toISOString()})}return n}function Gn(e){if(!e||typeof e!="object")throw new Error("Hub API returned an empty permission session");let n=e;if(!E(n.approvalUrl)||!E(n.token)||!E(n.projectId)||!E(n.expiresAt))throw new Error("Hub API returned an incomplete permission session (expected approvalUrl, token, projectId, and expiresAt)");return{approvalUrl:n.approvalUrl,token:n.token,projectId:n.projectId,expiresAt:n.expiresAt}}function Je(e){if(!e||typeof e!="object")throw new Error("Hub token refresh returned an empty response");let n=e;if(E(n.access_token))return{access_token:n.access_token,refresh_token:E(n.refresh_token)?n.refresh_token:void 0,expires_in:(()=>{if(typeof n.expires_in=="number")return n.expires_in;if(typeof n.expires_in=="string"&&n.expires_in.trim().length>0){let t=Number(n.expires_in);return Number.isFinite(t)?t:void 0}})(),scope:E(n.scope)?n.scope:void 0};throw new Error(E(n.error)?E(n.error_description)?n.error_description:n.error:"Hub token refresh returned no access_token")}function Aa(e){return Array.isArray(e)?e.filter(n=>typeof n=="string"):[]}function Ra(e){if(!Array.isArray(e))return[];let n=[];for(let t of e){if(!t||typeof t!="object")continue;let r=t;E(r.name)&&n.push({name:r.name,level:r.level==="integration"||r.level==="account"?r.level:"account",required:r.required===!0,configured:r.configured===!0})}return n}function xa(e,n,t,r){return e==="ready"||e==="partial"||e==="not_started"||e==="missing_integration"?e:n?"ready":t.some(i=>i.level==="integration"&&i.required&&!i.configured)?"missing_integration":t.some(i=>i.level==="account"&&i.required&&i.configured)?"partial":(r.length>0,"not_started")}function Wo(e){if(!e||typeof e!="object")throw new Error("Connect status response was empty");let n=e;if(!E(n.tenantId)||!Array.isArray(n.plugins))throw new Error("Connect status response was incomplete (expected tenantId and plugins)");let t=[];for(let r of n.plugins){if(!r||typeof r!="object")continue;let o=r;if(!E(o.plugin)||typeof o.connected!="boolean")continue;let i=o.authKind==="oauth"||o.authKind==="api_key"||o.authKind==="bot_token"?o.authKind:"api_key",s=Ra(o.fields),a=Aa(o.missingRequiredFields),c=xa(o.status,o.connected,s,a);t.push({plugin:o.plugin,providerName:E(o.providerName)?o.providerName:o.plugin,authKind:i,status:c,connected:o.connected,fields:s,missingRequiredFields:a})}return{tenantId:n.tenantId,plugins:t}}function zn(e){if(!e||typeof e!="object")return null;let n=e;return n.error??n.message??null}function jo(e){if(!e||typeof e!="object")return null;let n=e;if(n.errorType!=="reconnect_required")return null;let t=r=>typeof r=="string"&&r.length>0?r:null;return{message:t(n.error),connectUrl:t(n.connectUrl),plugin:t(n.plugin),tenantId:t(n.tenantId),reason:t(n.reason)}}function qo(e){return e.replace(/\/$/,"")}function Xt(e){if(!e.projectApiKey.startsWith("ck_dev_"))return null;try{return ve()}catch{return null}}function Ko(e){let n=Xt(e);return n?{"x-corsair-delivery-url":n}:{}}async function Zo(e){let n=e.headers.get("content-type")??"",t=await e.text();if(!t)return null;if(!n.includes("application/json")&&t.trimStart().startsWith("<"))throw new Error(`Hub API returned HTML instead of JSON (HTTP ${e.status}). Check HUB_API_URL and deploy the latest hub API.`);try{return JSON.parse(t)}catch{throw new Error(`Hub API returned invalid JSON (HTTP ${e.status})`)}}function Ia(e,n,t){if(n===404&&t)return t;let r=zn(e);return r||`Hub API returned HTTP ${n}`}function Go(e,n,t){let r=jo(e);throw r?new pe({message:r.message??void 0,connectUrl:r.connectUrl,plugin:r.plugin,tenantId:r.tenantId,reason:r.reason??void 0}):new Error(Ia(e,n,t))}async function x(e){let n=qo(e.hub.apiUrl),t=await fetch(`${n}${e.path}`,{method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${e.hub.projectApiKey}`,...Ko(e.hub)},body:JSON.stringify(e.body)}),r=await Zo(t);return t.ok||Go(r,t.status,e.notFoundMessage),e.parseResponse(r)}async function W(e){let n=qo(e.hub.apiUrl),t=await fetch(`${n}${e.path}`,{method:"GET",headers:{authorization:`Bearer ${e.hub.projectApiKey}`,...Ko(e.hub)}}),r=await Zo(t);return t.ok||Go(r,t.status,e.notFoundMessage),e.parseResponse(r)}function Jn(e){return e&&typeof e=="object"?e:{}}function zo(e){let n=Jn(e);return{chatId:n.threadId,message:n.message,workflowId:n.workflowId??null,action:n.action}}async function er(e,n){return x({hub:e,path:"/threads",body:{tenantId:n.tenantId,message:n.message},parseResponse:t=>{let r=Jn(t);return{chat:r.thread,reply:zo(r.reply)}}})}async function nr(e,n){return x({hub:e,path:`/threads/${encodeURIComponent(n.chatId)}/messages`,body:{tenantId:n.tenantId,message:n.message},notFoundMessage:`Chat "${n.chatId}" not found`,parseResponse:zo})}async function tr(e,n){return W({hub:e,path:`/threads?tenantId=${encodeURIComponent(n.tenantId)}`,parseResponse:t=>{let r=Jn(t).threads;return Array.isArray(r)?r:[]}})}async function rr(e,n){return W({hub:e,path:`/threads/${encodeURIComponent(n.chatId)}/messages?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Chat "${n.chatId}" not found`,parseResponse:t=>{let r=Jn(t).messages;return Array.isArray(r)?r:[]}})}import{randomUUID as Ha}from"crypto";var Sa="corsair:client-bridge";function or(e){return new URL(e).origin}function Ve(e){let n=JSON.stringify({type:Sa,requestId:e.requestId,ok:e.ok,body:e.body??null,error:e.error??null}),t=JSON.stringify(or(e.hubOrigin));return`<!DOCTYPE html><html><head><meta charset="utf-8"></head><body><script>
|
|
2
2
|
(function () {
|
|
3
3
|
var message = ${n};
|
|
4
4
|
var targetOrigin = ${t};
|
|
@@ -6,7 +6,7 @@ import{a as ve,b as Yt,c as Qt}from"./chunk-4OLKWKJG.js";import{a as Bo,b as Te,
|
|
|
6
6
|
window.parent.postMessage(message, targetOrigin);
|
|
7
7
|
}
|
|
8
8
|
})();
|
|
9
|
-
</script></body></html>`}var _a=new Set(["localhost","127.0.0.1","[::1]","::1"]);function ir(e){try{let{hostname:n,protocol:t}=new URL(e);return t!=="http:"&&t!=="https:"?!1:_a.has(n)}catch{return!1}}function vn(e){return e==="development"?"browser":"server"}function Jo(e){return vn(e)==="browser"}function Vo(e){return ir(e)?"Production delivery URL must be a public URL, not localhost":null}import{randomBytes as Ma}from"crypto";var Ae=60*1e3,Be=300*1e3;import{createHmac as Ea,randomBytes as Da,timingSafeEqual as Oa}from"crypto";function ge(){return Da(16).toString("base64url")}function Tn(e,n){let t=n.trim();if(!t)throw new Error("Signing secret is required");return Ea("sha256",t).update(e).digest("base64url")}function ae(e,n){let t=n.trim();if(!t)return null;let r=e.split(".");if(r.length!==2)return null;let[o,i]=r;if(!o||!i)return null;let s=Tn(o,t);try{if(!Oa(Buffer.from(i,"utf8"),Buffer.from(s,"utf8")))return null}catch{return null}let a;try{a=JSON.parse(Buffer.from(o,"base64url").toString("utf8"))}catch{return null}return a.exp*1e3<Date.now()?null:a}function Vn(e,n,t){let r=Math.floor(Date.now()/1e3),o={...e,iat:r,exp:t},i=Buffer.from(JSON.stringify(o)).toString("base64url"),s=Tn(i,n);return`${i}.${s}`}function Pn(e,n,t){let r=Math.floor(Date.now()/1e3);return Vn(e,n,r+Math.floor(t/1e3))}function Fe(e){return decodeURIComponent(e)}function sr(e){return encodeURIComponent(e).replace(/\./g,"%2E")}function Yo(e){let n=e.trim();return n.length>0?n:null}function Ye(e,n){let t=new URL(e);return t.searchParams.set("d",n),t.toString()}function Qe(e,n){if(!Yo(n))throw new Error("Signing secret is required for browser delivery tokens");let t=Math.floor(Date.now()/1e3),r={...e,jti:e.jti??Ma(16).toString("base64url"),iat:t,exp:t+Math.floor(Ae/1e3)},o=Buffer.from(JSON.stringify(r)).toString("base64url"),i=Tn(o,n);return`${o}.${i}`}function Re(e,n){return Yo(n)?ae(e,n):null}function Ba(e){let n=or(e.hubOrigin),t={connectJti:e.requestId,projectId:e.projectId,hubSuccessUrl:e.hubOrigin,deliveryMode:e.deliveryMode,hubOrigin:n,requestId:e.requestId};switch(e.deliveryMode){case"connections.sync":return{...t,plugin:"connections.sync",tenantId:"*"};case"connect.create_link":return{...t,plugin:"connect.create_link",tenantId:e.tenantId,connectLinkPlugins:e.plugins}}}function ar(e){let n=Qe(Ba(e),e.signingSecret);return Ye(e.deliveryUrl,n)}function Qo(e){if(vn(e.environmentSlug)==="server")return{transport:"server"};if(!e.hubOrigin)throw new Error(`hubOrigin is required for development ${e.deliveryMode} delivery`);let t=Ha(),r={...e,hubOrigin:e.hubOrigin,requestId:t};return{transport:"browser",requestId:t,deliveryUrl:ar(r)}}var An="https://auth.corsair.dev";var fe=class extends Error{constructor(){super("Hub is not configured. Pass hub: { projectApiKey, signingSecret } to createCorsair()."),this.name="HubNotConfiguredError"}},Rn=class extends Error{constructor(){super("Hub credentials are missing. Pass hub: { projectApiKey, signingSecret } to createCorsair() with non-empty values, or omit `hub` entirely if you are not using Corsair Hub."),this.name="HubCredentialsMissingError"}};function cr(e){let n=(e.apiUrl?.trim()||An).replace(/\/$/,""),t=e.projectApiKey?.trim()??"",r=e.signingSecret?.trim()??"";if(!t||!r)throw new Rn;return{apiUrl:n,projectApiKey:t,signingSecret:r,oauthCallbackUrl:e.oauthCallbackUrl?.trim().replace(/\/$/,""),redirectURL:e.redirectURL?.trim()||void 0,allowWorkflowExecution:e.allowWorkflowExecution??!1,tunnel:e.tunnel}}function Yn(e){return cr(e)}function Fa(e){return e.apiUrl.trim().length>0&&e.projectApiKey.trim().length>0&&e.signingSecret.trim().length>0}function F(e){let n=v(e).hub;if(!n||!Fa(n))throw new fe;return n}function Xo(e){return e.replace(/\/$/,"")}function Qn(e){return e.oauthCallbackUrl?Xo(e.oauthCallbackUrl.trim()):`${Xo(e.apiUrl)}/oauth/callback`}function Xe(e){if(e.startsWith("ck_dev_"))return"development";if(e.startsWith("ck_prod_"))return"production";throw new Error("Hub API key must start with ck_dev_ (development) or ck_prod_ (production)")}import{createCipheriv as ei,createDecipheriv as ni,randomBytes as Xn,scrypt as Ua}from"crypto";import{promisify as Na}from"util";var ti=Na(Ua),et="aes-256-gcm",ri=12,nt=16,La=16,Ue=32;function ye(){return Xn(Ue).toString("base64")}async function me(e,n){let t=Xn(La),r=await ti(n,t,Ue),o=Xn(ri),i=ei(et,r,o,{authTagLength:nt}),s=Buffer.concat([i.update(e,"utf8"),i.final()]),a=i.getAuthTag();return[t.toString("base64"),o.toString("base64"),a.toString("base64"),s.toString("base64")].join(":")}async function Y(e,n){let[t,r,o,i]=e.split(":");if(!t||!r||!o||!i)throw new Error("Invalid encrypted DEK format");let s=Buffer.from(t,"base64"),a=Buffer.from(r,"base64"),c=Buffer.from(o,"base64"),l=Buffer.from(i,"base64"),u=await ti(n,s,Ue),d=ni(et,u,a,{authTagLength:nt});return d.setAuthTag(c),Buffer.concat([d.update(l),d.final()]).toString("utf8")}function ur(e,n){let t=Buffer.from(n,"base64"),r=Xn(ri),o=ei(et,t,r,{authTagLength:nt}),i=Buffer.concat([o.update(e,"utf8"),o.final()]),s=o.getAuthTag();return[r.toString("base64"),s.toString("base64"),i.toString("base64")].join(":")}function xn(e,n){let[t,r,o]=e.split(":");if(!t||!r||!o)throw new Error("Invalid encrypted data format");let i=Buffer.from(n,"base64"),s=Buffer.from(t,"base64"),a=Buffer.from(r,"base64"),c=Buffer.from(o,"base64"),l=ni(et,i,s,{authTagLength:nt});return l.setAuthTag(a),Buffer.concat([l.update(c),l.final()]).toString("utf8")}function xe(e,n){let t={};for(let[r,o]of Object.entries(e))t[r]=ur(o,n);return t}function he(e,n){let t={};for(let[r,o]of Object.entries(e))t[r]=xn(o,n);return t}function In(e,n,t){let r=he(e,n);return xe(r,t)}function oi(e,n,t){let r={};for(let o of t)r[`get_${o}`]=async()=>(await e())[o]??null,r[`set_${o}`]=async i=>{let s=[null,void 0,""].includes(i)?null:i;await n({[o]:s})};return r}var lr=e=>{if(!e)return{};if(typeof e=="string")try{return JSON.parse(e)}catch{return{}}return e};function U(e){let{authType:n,integrationName:t,kek:r,database:o,extraIntegrationFields:i=[]}=e,s=[...$[n].integration,...i],a=null,c={kek:r,integrationName:t,getIntegration:async()=>{if(a)return a;let k=await o.db.selectFrom("corsair_integrations").selectAll().where("name","=",t).executeTakeFirst();if(!k)throw new Error(`Integration "${t}" not found. Make sure to create the integration first.`);return a={id:k.id,config:lr(k.config),dek:k.dek??null},a},updateIntegration:async k=>{let b=await c.getIntegration();await o.db.updateTable("corsair_integrations").set({...k.config!==void 0?{config:k.config}:{},...k.dek!==void 0?{dek:k.dek}:{},updated_at:new Date}).where("id","=",b.id).execute(),a=null}},l=null,u=async()=>{if(l)return l;let k=await c.getIntegration();if(!k.dek)throw new Error(`No DEK found for integration "${t}". Initialize the integration first.`);return l=await Y(k.dek,r),l},d=async()=>{let k=await c.getIntegration(),b=await u(),C=k.config;return!C||Object.keys(C).length===0?{}:he(C,b)},p=Promise.resolve(),g=k=>{let b=p.then(()=>f(k));return p=b.catch(()=>{}),b},f=async k=>{let b=await u(),C;try{C=await d()}catch(D){console.error(`[corsair] Failed to decrypt config for integration "${t}", starting fresh:`,D),C={}}let P={...C};for(let[D,H]of Object.entries(k))H===null?delete P[D]:P[D]=H;let O=xe(P,b);await c.updateIntegration({config:O})};return{get_dek:u,issue_new_dek:async()=>{let k=await c.getIntegration(),b=ye(),C={};if(k.dek){let O=await Y(k.dek,r),D=k.config;D&&Object.keys(D).length>0&&(C=In(D,O,b))}let P=await me(b,r);return await c.updateIntegration({config:C,dek:P}),l=b,b},...oi(d,g,s)}}function B(e){let{authType:n,integrationName:t,tenantId:r,kek:o,database:i,extraAccountFields:s=[],ensureProvisioned:a}=e,c=[...$[n].account,...s],l=null,u=null,d=async()=>{if(u)return u;let w=!1;for(;;){let A=await i.db.selectFrom("corsair_integrations").selectAll().where("name","=",t).executeTakeFirst();if(!A){if(!w&&a){w=!0,await a();continue}throw new Error(`Integration "${t}" not found. Make sure to create the integration first.`)}return u={id:A.id,config:lr(A.config),dek:A.dek??null},u}},p={kek:o,integrationName:t,tenantId:r,getIntegration:d,getAccount:async()=>{if(l)return l;let w=!1;for(;;){let A=await d(),R=await i.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",r).where("integration_id","=",A.id).executeTakeFirst();if(!R){if(!w&&a){w=!0,await a();continue}throw new Error(`Account not found for tenant "${r}" and integration "${t}". Make sure to create the account first.`)}return l={id:R.id,config:lr(R.config),dek:R.dek??null},l}},updateAccount:async w=>{let A=await p.getAccount();await i.db.updateTable("corsair_accounts").set({...w.config!==void 0?{config:w.config}:{},...w.dek!==void 0?{dek:w.dek}:{},updated_at:new Date}).where("id","=",A.id).execute(),l=null}},g=null,f=null,h=async()=>{if(g)return g;let w=await p.getAccount();if(!w.dek)throw new Error(`No DEK found for account (tenant: "${r}", integration: "${t}"). Initialize the account first.`);return g=await Y(w.dek,o),g},k=async()=>{if(f)return f;let w=await p.getIntegration();if(!w.dek)throw new Error(`No DEK found for integration "${t}". Initialize the integration first.`);return f=await Y(w.dek,o),f},b=async()=>{let w=await p.getAccount(),A=await h(),R=w.config;return!R||Object.keys(R).length===0?{}:he(R,A)},C=async()=>{let w=await p.getIntegration(),A=await k(),R=w.config;return!R||Object.keys(R).length===0?{}:he(R,A)},P=Promise.resolve(),O=w=>{let A=P.then(()=>D(w));return P=A.catch(()=>{}),A},D=async w=>{let A=await h(),R;try{R=await b()}catch(_){console.error(`[corsair] Failed to decrypt config for account (tenant: "${r}", integration: "${t}"), starting fresh:`,_),R={}}let J={...R};for(let[_,re]of Object.entries(w))re===null?delete J[_]:J[_]=re;let de=xe(J,A);await p.updateAccount({config:de})},H={get_dek:h,issue_new_dek:async()=>{let w=await p.getAccount(),A=ye(),R={};if(w.dek){let de=await Y(w.dek,o),_=w.config;_&&Object.keys(_).length>0&&(R=In(_,de,A))}let J=await me(A,o);return await p.updateAccount({config:R,dek:J}),g=A,A},...oi(b,O,c)};return n==="oauth_2"&&(H.get_integration_credentials=async()=>{let w=await C();return{...w,client_id:w.client_id||null,client_secret:w.client_secret||null,redirect_url:w.redirect_url??null}}),H}async function ii(e,n,t){let r=await e.db.selectFrom("corsair_integrations").selectAll().where("name","=",n).executeTakeFirst();if(!r)throw new Error(`Integration "${n}" not found.`);let o=ye(),i=await me(o,t);return await e.db.updateTable("corsair_integrations").set({dek:i,updated_at:new Date}).where("id","=",r.id).execute(),o}async function si(e,n,t,r){let o=await e.db.selectFrom("corsair_integrations").selectAll().where("name","=",n).executeTakeFirst();if(!o)throw new Error(`Integration "${n}" not found.`);let i=await e.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",t).where("integration_id","=",o.id).executeTakeFirst();if(!i)throw new Error(`Account not found for tenant "${t}" and integration "${n}".`);let s=ye(),a=await me(s,r);return await e.db.updateTable("corsair_accounts").set({dek:a,updated_at:new Date}).where("id","=",i.id).execute(),s}var $a=new Set(["webhook_signature","expires_at","scope","redirect_url","refresh_token"]);function Ie(e){return $a.has(e)}function Wa(e,n){return Ie(n)?!1:e==="oauth_2"?n==="client_id"||n==="client_secret":!0}function ja(e){return!Ie(e)}function qa(e){switch(e){case"oauth_2":case"managed":return["access_token"];case"api_key":return["api_key"];case"bot_token":return["bot_token"]}}function Ka(e,n){return e!=="oauth_2"&&e!=="managed"?!1:n.some(t=>t.level==="account"&&t.name==="expires_at"&&t.configured)}function Za(e,n){let t=i=>n.find(s=>s.level==="account"&&s.name===i);if(!qa(e).every(i=>t(i)?.configured))return!1;let o=t("refresh_token");return o?.required?!!o.configured:!0}async function ai(e,n){if(!e)return!1;let t=z(e,`get_${n}`);if(!t)return!1;try{let r=await t();return typeof r=="string"&&r.length>0}catch{return!1}}function Ga(e,n){let r=e.authConfig?.[n]?.integration??[];return[...$[n].integration,...r]}function za(e,n){let r=e.authConfig?.[n]?.account??[];return[...$[n].account,...r]}function Ja(e,n,t){let r=t.filter(a=>a.required&&!a.configured).map(a=>a.name),o=t.filter(a=>a.level==="integration"&&a.required&&!a.configured).map(a=>a.name),i=t.filter(a=>a.level==="account"&&a.required&&a.configured),s;return o.length>0?s="missing_integration":r.length===0?s="ready":i.length>0?s="partial":s="not_started",{plugin:e,authType:n,status:s,connected:Za(n,t),fields:t,missingRequiredFields:r}}async function Ne(e,n,t){let r=I(n);if(!r||!e.database||!e.kek)return null;let o=t.trim()||"default",i=n.authConfig,s=i?.[r]?.integration??[],a=i?.[r]?.account??[],c=U({authType:r,integrationName:n.id,kek:e.kek,database:e.database,extraIntegrationFields:s}),l=B({authType:r,integrationName:n.id,tenantId:o,kek:e.kek,database:e.database,extraAccountFields:a}),u=Ga(n,r),d=za(n,r),p=[];for(let g of u)p.push({name:g,level:"integration",required:Wa(r,g),configured:await ai(c,g)});for(let g of d)p.push({name:g,level:"account",required:ja(g),configured:await ai(l,g)});if(Ka(r,p)){let g=p.find(f=>f.level==="account"&&f.name==="refresh_token");g&&(g.required=!0)}return Ja(n.id,r,p)}async function Sn(e,n,t={}){let r=n.trim()||"default",o=t.pluginIds?.length?new Set(t.pluginIds):null,i=[];for(let s of e.plugins){if(o&&!o.has(s.id))continue;let a=await Ne(e,s,r);a&&i.push(a)}return i}function tt(e){return e.connected?"connected":e.status==="missing_integration"?"missing_credentials":"not_connected"}var ci=Symbol.for("corsair:internal"),ui=new WeakMap,li=new WeakMap;function Va(e,n){let t=n.map(r=>r.id).sort().join("\0");return`${e}\0${t}`}function Ya(e){if(e.database){let t=ui.get(e.database);return t||(t=new Map,ui.set(e.database,t)),t}let n=li.get(e);return n||(n=new Map,li.set(e,n)),n}function Qa(e){return e.multiTenancy?{withTenant:()=>({}),[ci]:e}:{[ci]:e}}async function en(e,n){if(!e.database)return;let t=n.trim()||"default",r=Ya(e),o=Va(t,e.plugins),i=r.get(o);if(i){await i;return}let s=(async()=>{let{setupCorsair:a}=await import("./setup-PXJ3S3RO.js");await a(Qa(e),{tenantId:e.multiTenancy?t:void 0,silent:!0})})().finally(()=>{r.delete(o)});r.set(o,s),await s}import*as _n from"crypto";function Se(e,n){return Buffer.from(JSON.stringify({plugin:e,tenantId:n,iat:Date.now()})).toString("base64url")}function dr(e,{maxAgeMs:n}={}){try{let t=e.includes(".")?e.split(".")[0]:e,r=JSON.parse(Buffer.from(t,"base64url").toString("utf-8"));if(r!==null&&typeof r=="object"&&"plugin"in r&&"tenantId"in r&&typeof r.plugin=="string"&&typeof r.tenantId=="string"){let o=r;return n!==void 0&&typeof o.iat=="number"&&Date.now()-o.iat>n?null:o}return null}catch{return null}}function nn(e,n){let t=_n.createHmac("sha256",n).update(e).digest("base64url");return`${e}.${t}`}var pr=600*1e3;function rt(e,n){let t=e.lastIndexOf(".");if(t===-1)return null;let r=e.slice(0,t),o=e.slice(t+1),i=_n.createHmac("sha256",n).update(r).digest("base64url"),s=Buffer.from(o,"base64url"),a=Buffer.from(i,"base64url");return s.length!==a.length||!_n.timingSafeEqual(s,a)?null:dr(r,{maxAgeMs:pr})}function di(e){return{tenantId:e.tenantId,plugin:e.plugin,authType:e.authType??"oauth_2",status:"ready",connected:!0,verified:!0,webhookLink:e.link}}function pi(e){return{tenantId:e.tenantId,plugin:e.plugin,authType:e.authType,status:e.status,connected:e.connected,verified:e.verified,missingFields:e.missingFields,webhookLink:e.webhookLink,webhookSecret:e.webhookSecret}}async function tn(e,n){await x({hub:e,path:"/connections/report",body:di(n),parseResponse:()=>({ok:!0})}).catch(()=>{})}function Xa(e,n){try{let t=F(e);x({hub:t,path:"/connections/report",body:n,parseResponse:()=>({ok:!0})}).catch(()=>{})}catch(t){if(t instanceof fe)return}}async function ec(e){if(!e.hub||!e.database||!e.kek)return;let n={database:e.database,kek:e.kek,plugins:e.plugins};if(!I(e.plugin))return;let r=e.tenantId?.trim()||"default",o=await Ne(n,e.plugin,r);o&&fi(e.hub,pi({tenantId:r,plugin:e.plugin.id,authType:o.authType,status:o.status,connected:o.connected,verified:e.verified??o.connected,missingFields:o.missingRequiredFields}))}function gi(e,n){Xa(e,n)}function fi(e,n){x({hub:e,path:"/connections/report",body:n,parseResponse:()=>({ok:!0})}).catch(()=>{})}function rn(e){ec(e).catch(()=>{})}async function be(e,n){let t=v(e);if(!I(n.plugin))return;let o=await Ne(t,n.plugin,n.tenantId);o&&gi(e,pi({tenantId:n.tenantId.trim()||"default",plugin:n.plugin.id,authType:o.authType,status:o.status,connected:o.connected,verified:n.verified??o.connected,missingFields:o.missingRequiredFields,webhookLink:n.webhookLink,webhookSecret:n.webhookSecret}))}async function ot(e,n,t){for(let r of e){if(r.id!==n)continue;let o=r.oauthWebhookTenantLinkResolver;return o?o(t):null}return null}var yi=e=>{if(!e)return{};if(typeof e=="string")try{return JSON.parse(e)}catch{return{}}return e};async function nc(e){let n=await e.database.db.selectFrom("corsair_integrations").selectAll().where("name","=",e.pluginId).executeTakeFirst();if(!n)throw new Error(`Integration '${e.pluginId}' not found. Run setupCorsair before registering webhook tenant links.`);let t=await e.database.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",e.tenantId).where("integration_id","=",n.id).executeTakeFirst();if(!t)throw new Error(`Account not found for tenant '${e.tenantId}' and integration '${e.pluginId}'.`);return{integrationId:n.id,accountId:t.id}}async function tc(e){let n=await e.database.db.selectFrom("corsair_accounts").selectAll().where("id","=",e.accountId).executeTakeFirst();if(!n?.dek)throw new Error(`Account '${e.accountId}' has no DEK.`);let t=await Y(n.dek,e.kek),r=yi(n.config),o={};Object.keys(r).length>0&&(o=he(r,t)),o[e.link.linkType]=e.link.externalId;let i=xe(o,t);await e.database.db.updateTable("corsair_accounts").set({config:i,updated_at:new Date}).where("id","=",n.id).execute()}async function on(e){let{database:n,kek:t,pluginId:r,tenantId:o,link:i,authType:s,extraAccountFields:a=[]}=e,{accountId:c}=await nc({database:n,pluginId:r,tenantId:o}),l=!1;if(s){let u=B({authType:s,integrationName:r,tenantId:o,kek:t,database:n,extraAccountFields:a}),d=`set_${i.linkType}`,p=u[d];typeof p=="function"&&(await p(i.externalId),l=!0)}l||await tc({database:n,kek:t,accountId:c,link:i})}async function gr(e){let{database:n,kek:t,pluginId:r,linkType:o,externalId:i}=e,s=await n.db.selectFrom("corsair_accounts as accounts").innerJoin("corsair_integrations as integrations","integrations.id","accounts.integration_id").selectAll("accounts").where("integrations.name","=",r).execute();for(let a of s)if(a.dek)try{let c=await Y(a.dek,t),u=yi(a.config)[o];if(!u)continue;if(xn(u,c)===i)return a}catch{continue}return null}async function it(e){return(await gr(e))?.tenant_id??null}async function mi(e){return it({database:e.database,kek:e.kek,pluginId:e.pluginId,linkType:e.match.linkType,externalId:e.match.externalId})}import*as hi from"querystring";function Le(e){let{oauthConfig:n,clientId:t,redirectUri:r,state:o}=e,i={...n.authParams,client_id:t,redirect_uri:r,response_type:"code",scope:n.scopes.join(" "),state:o};return`${n.authUrl}?${hi.stringify(i)}`}async function bi(e,n){try{return await W({hub:e,path:`/webhooks/endpoint?plugin=${encodeURIComponent(n)}`,parseResponse:t=>t?.url??null})}catch{return null}}async function sn(e,n,t,r){if(!n.subscribe)return;let o=F(e),i=await bi(o,n.id);if(!i)return;let s=await n.subscribe({keys:r},{webhookUrl:i});s&&await be(e,{plugin:n,tenantId:t,verified:!0,webhookLink:s.webhookLink,webhookSecret:s.webhookSecret})}var q=class extends Error{code;constructor(n,t){super(t),this.name="OAuthCallbackError",this.code=n}};function ki(e){let n=e.oauthConfig;if(!n)throw new q("plugin_has_no_oauth_config",`Plugin '${e.id}' has no oauthConfig`);return n}async function rc(e,n,t,r){await e.db.transaction().execute(async o=>{let i=o.selectFrom("corsair_integrations").select(["id"]).where("name","=",n);e.isPg===!0&&(i=i.forUpdate());let s=await i.executeTakeFirst();if(!s)throw new Error(`Integration '${n}' not found. Run setupCorsair first.`);if(await o.selectFrom("corsair_accounts").select("id").where("tenant_id","=",t).where("integration_id","=",s.id).executeTakeFirst())return;let c=ye(),l=await me(c,r),u=new Date;await o.insertInto("corsair_accounts").values({id:ze(),created_at:u,updated_at:u,tenant_id:t,integration_id:s.id,config:{},dek:l}).execute()})}async function fr(e,n,t){let{tenantId:r,redirectUri:o,hubConnect:i=!1}=t,s=v(e,()=>new q("invalid_corsair_instance","Invalid corsair instance"));if(!s.database)throw new Error("No database configured on corsair instance");let a=j(s,n,p=>new q("plugin_not_found",p)),c=ki(a),u=await U({authType:"oauth_2",integrationName:n,kek:s.kek,database:s.database}).get_client_id();if(!u)throw new Error(`client_id not configured for '${n}'`);if(i){let p=new URL(Le({oauthConfig:c,clientId:u,redirectUri:o,state:""}));return p.searchParams.delete("state"),{url:p.toString(),state:""}}let d=nn(Se(n,r),s.kek);return{url:Le({oauthConfig:c,clientId:u,redirectUri:o,state:d}),state:d}}function oc(e,n){return{...n??{},...e}}async function En(e,n){let{code:t,state:r,redirectUri:o}=n,i=v(e,()=>new q("invalid_corsair_instance","Invalid corsair instance")),s,a;if(n.trusted){if(!n.plugin||!n.tenantId)throw new q("invalid_state","trusted callback requires plugin and tenantId");s=n.plugin,a=n.tenantId}else{let h=rt(r,i.kek);if(!h)throw new q("invalid_state","Invalid or tampered state parameter");s=h.plugin,a=h.tenantId}if(!i.database)throw new q("no_database","No database configured on corsair instance");let c=j(i,s,h=>new q("plugin_not_found",h)),l=ki(c),u=U({authType:"oauth_2",integrationName:s,kek:i.kek,database:i.database}),d=await u.get_client_id(),p=await u.get_client_secret();if(!d||!p)throw new q("credentials_not_configured",`Credentials not configured for '${s}'`);await rc(i.database,s,a,i.kek);let g=await st(t,d,p,l,o);if(!g.access_token)throw new q("no_access_token",`No access_token returned from ${l.providerName}`);let f=B({authType:"oauth_2",integrationName:s,tenantId:a,kek:i.kek,database:i.database,extraAccountFields:[...c.authConfig?.oauth_2?.account??[]]});await f.set_access_token(g.access_token),g.refresh_token&&await f.set_refresh_token(g.refresh_token),g.expires_in&&await f.set_expires_at(String(Math.floor(Date.now()/1e3)+g.expires_in)),await be(e,{plugin:c,tenantId:a}).catch(()=>{});try{let h=oc(g,n.callbackParams),k=await ot(i.plugins,s,h);if(k){try{let b=c.authConfig?.oauth_2?.account??[];await on({database:i.database,kek:i.kek,pluginId:s,tenantId:a,link:k,authType:"oauth_2",extraAccountFields:b})}catch(b){console.warn(`[corsair:oauth] Failed to persist webhook tenant link for '${s}' tenant '${a}':`,b)}i.hub&&tn(i.hub,{plugin:s,tenantId:a,link:k,authType:"oauth_2"})}}catch(h){console.warn(`[corsair:oauth] Failed to resolve webhook tenant link for '${s}' tenant '${a}':`,h)}if(c.subscribe)try{await sn(e,c,a,f)}catch(h){console.warn(`[corsair:oauth] BYO subscribe failed for '${s}' tenant '${a}':`,h)}return{plugin:s,tenantId:a}}async function ic(e){let{corsair:n,internal:t,rows:r}=e,o=e.subscribeAndReport??sn,i=[],s=[];if(!t.database)return{renewed:i,failed:s};for(let a of r){let c=t.plugins.find(u=>u.id===a.integrationName);if(!c?.subscribe)continue;let l=`${c.id}/${a.tenantId}`;try{let u=I(c)??"oauth_2",d=B({authType:u,integrationName:c.id,tenantId:a.tenantId,kek:t.kek,database:t.database,extraAccountFields:[...c.authConfig?.[u]?.account??[]]}),p=c.keyBuilder;if(p){let g=Object.create(d,{get_expires_at:{value:async()=>"0"}});await p({authType:u,keys:g,hub:t.hub},"endpoint")}await o(n,c,a.tenantId,d),i.push(l)}catch(u){console.warn(`[corsair:renewal] re-subscribe failed for '${l}':`,u),s.push(l)}}return{renewed:i,failed:s}}async function wi(e){let n=v(e);if(!n.database)return{renewed:[],failed:[]};let t=await n.database.db.selectFrom("corsair_accounts as a").innerJoin("corsair_integrations as i","i.id","a.integration_id").select(["a.tenant_id as tenantId","i.name as integrationName"]).where("a.dek","is not",null).execute();return ic({corsair:e,internal:n,rows:t.filter(r=>!!r.tenantId)})}function sc(e,n={}){let t=!1,r=()=>{t||(t=!0,wi(e).catch(i=>console.warn("[corsair:renewal] renewal pass failed:",i)).finally(()=>{t=!1}))};r();let o=setInterval(r,(n.intervalMinutes??45)*6e4);return o.unref?.(),()=>clearInterval(o)}async function Ci(e){if(!v(e).database)throw new Error("A database must be configured to provision Corsair integrations");await at(e,{silent:!0})}async function an(e,n){let t=v(e);if(!t.database)throw new Error("A database must be configured to provision Corsair for connect");await en(t,n)}var ac=Symbol.for("corsair:internal"),cc=new Set(["access_token","refresh_token","expires_at","scope"]);function uc(e){return e==="oauth_2"||e==="managed"?"oauth":e==="bot_token"?"bot_token":"api_key"}function lc(e,n){return e==="oauth_2"||e==="managed"?n.filter(t=>!Ie(t)&&!cc.has(t)):n.filter(t=>!Ie(t))}function vi(e){return{plugins:e.plugins,database:e.database,kek:e.kek,multiTenancy:e.multiTenancy??!1}}function dc(e){return{plugins:e.plugins,database:e.database,kek:e.kek,multiTenancy:e.multiTenancy??!1}}function pc(e){return{[ac]:vi(e)}}async function ct(e,n,t={}){let r=Qn(e.hub),o=[],i=t.pluginIds?new Set(t.pluginIds):null,s=vi(e),a=pc(e);for(let c of e.plugins){if(i&&!i.has(c.id))continue;let l=I(c);if(!l)continue;let u=uc(l),d=t.providerNameOverrides?.[c.id]??Pe(c.id),p=await Ne(s,c,n),g=jn(c,l),f=lc(l,g),h={plugin:c.id,providerName:d,authKind:u,alreadyConfigured:p?.connected??!1};if(f.length>0&&(h.credentialFields=f),u==="oauth"){let b=t.oauthModeOverrides?.[c.id]??(l==="managed"?"managed":"byo");if(h.oauthMode=b,!t.skipOAuthUrlGeneration&&b!=="managed")try{let C=await fr(a,c.id,{tenantId:n,redirectUri:r,hubConnect:!0});h.oauthUrl=C.url}catch(C){C instanceof Error&&/client_id not configured/i.test(C.message)||(h.setupError=C instanceof Error?C.message:`Could not prepare OAuth for ${c.id}`)}}o.push(h)}return o}async function ag(e,n,t={}){let r=v(e),o=r.hub;if(!o)throw new Error("Hub is not configured");return ct({plugins:r.plugins,database:r.database,kek:r.kek,hub:o},n,t)}async function Ti(e,n){if(!e.database)throw new Error("A database must be configured to provision Corsair for connect");await en(e.internalConfig??dc(e),n)}async function Pi(e,n){await an(e,n)}async function Ai(e,n){let t=Xe(e.projectApiKey),r={tenantId:n.tenantId,plugins:n.plugins};return e.redirectURL&&(r.redirectUri=e.redirectURL),t==="development"&&(r.deliveryUrl=ve({deliveryUrl:n.deliveryUrl})),x({hub:e,path:"/connect/sessions",notFoundMessage:"Hub REST API not found at /connect/sessions. Check HUB_API_URL and ensure the Hub API is deployed.",body:r,parseResponse:Kn})}async function Ri(e,n){let t={plugins:n.plugins,database:n.database,kek:n.kek,hub:e,multiTenancy:n.multiTenancy};await Ti(t,n.tenantId);let r=await ct(t,n.tenantId,{pluginIds:[n.plugin.id]});if(r.length===0)throw new Error(`Plugin '${n.plugin.id}' is not configured on this Corsair instance`);return Ai(e,{tenantId:n.tenantId,plugins:r,deliveryUrl:n.deliveryUrl})}async function ut(e,n){let t=v(e),r=F(e),o={plugins:t.plugins,database:t.database,kek:t.kek,hub:r,multiTenancy:t.multiTenancy,internalConfig:t};await Pi(e,n.tenantId);let i=n.plugin?[n.plugin]:void 0,s=n.plugin&&n.oauthMode?{[n.plugin]:n.oauthMode}:void 0,a=n.plugin&&n.providerName?{[n.plugin]:n.providerName}:void 0,c=await ct(o,n.tenantId,{pluginIds:i,oauthModeOverrides:s,providerNameOverrides:a});if(c.length===0)throw new Error(n.plugin?`Plugin '${n.plugin}' is not configured on this Corsair instance`:"No plugins are configured on this Corsair instance");return Ai(r,{tenantId:n.tenantId,plugins:c,deliveryUrl:n.deliveryUrl})}async function lt(e,n){let t=n.tenantId.trim();if(!t)throw new Error("tenantId is required");let r=n.plugins.map(s=>s.trim()).filter(Boolean);if(r.length===0)throw new Error("At least one plugin is required");let o=v(e);if(!o.hub)throw new Error("Hub is not configured on this Corsair instance");if(!o.database)throw new Error("Database not configured");let i=await gc(o.hub,{plugins:o.plugins,database:o.database,kek:o.kek,multiTenancy:o.multiTenancy},{tenantId:t,pluginIds:r});return{connectUrl:i.connectUrl,expiresAt:i.expiresAt}}async function gc(e,n,t){let{buildConnectPluginManifestFromContext:r,ensureConnectAccountRowsFromContext:o}=await import("./setup-introspect-J77AZVKF.js"),{postHubConnectSession:i}=await import("./connect-BM3VAVNP.js"),s={plugins:n.plugins,database:n.database,kek:n.kek,hub:e,multiTenancy:n.multiTenancy};await o(s,t.tenantId);let a=await r(s,t.tenantId,{pluginIds:t.pluginIds});if(a.length===0)throw new Error("No connectable plugins found for this tenant");let c=a.find(l=>l.setupError);if(c)throw new Error(c.setupError??`Could not prepare connect link for ${c.plugin}`);return i(e,{tenantId:t.tenantId,plugins:a})}function cn(e){return!!(e?.baseUrl?.trim()&&e?.redirectUri?.trim())}var Q=class extends Error{code;constructor(n,t){super(t),this.name="ConnectError",this.code=n}};function fc(e){let n=e.oauthConfig;if(!n)throw new Q("plugin_has_no_oauth_config",`Plugin '${e.id}' has no oauthConfig`);return n}async function yr(e,n){let t=v(e,()=>new Q("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new Q("no_database","No database configured on corsair instance");let r=t.manual?.redirectUri;if(!r)throw new Q("no_redirect_uri","No redirectUri configured. Set manual.redirectUri in createCorsair().");let o=rt(n,t.kek);if(!o)throw new Q("invalid_state","Invalid or tampered state parameter");let{plugin:i,tenantId:s}=o,a=j(t,i,p=>new Q("plugin_not_found",p)),c=fc(a),u=await U({authType:"oauth_2",integrationName:i,kek:t.kek,database:t.database}).get_client_id();if(!u)throw new Q("client_id_not_configured",`client_id not configured for '${i}'`);let d=Le({oauthConfig:c,clientId:u,redirectUri:r,state:n});return{plugin:i,tenantId:s,providerName:c.providerName,oauthUrl:d,state:n}}import{AsyncLocalStorage as mc}from"async_hooks";import{randomBytes as hc}from"crypto";import{v4 as bc}from"uuid";async function dt(e,n){let t=Xe(e.projectApiKey),r={permissionId:n.permissionId,permissionToken:n.permissionToken,plugin:n.plugin,endpoint:n.endpoint,args:n.args,tenantId:n.tenantId,expiresAt:n.expiresAt};return e.redirectURL&&(r.redirectUri=e.redirectURL),t==="development"&&(r.deliveryUrl=ve({deliveryUrl:n.deliveryUrl})),x({hub:e,path:"/permission/sessions",notFoundMessage:"Hub REST API not found at /permission/sessions. Check HUB_API_URL and ensure the Hub API is deployed.",body:r,parseResponse:Gn})}function pt(e){return`Approval required. Visit ${e} to approve or deny, then tell the agent to retry this action.`}var mr="Permission approval required. Set manual.approvalBaseUrl (or use hub for hosted approval) so an approval URL can be generated. Optionally set manual.onApprovalRequired to customize the agent message.";function br(e){return e?e.approvalBaseUrl!==void 0||e.onApprovalRequired!==void 0:!1}function xi(e,n){return`${e.replace(/\/+$/,"")}/${n}`}function hr(e){return pt(e)}async function kr(e,n){if(br(e.manual)){let r=e.manual?.approvalBaseUrl?.trim();return r?xi(r,n.token):null}let t=e.hub;if(!t)return null;try{return(await dt(t,{permissionId:n.id,permissionToken:n.token,plugin:n.plugin,endpoint:n.endpoint,args:yc(n.args),tenantId:n.tenant_id,expiresAt:n.expires_at})).approvalUrl}catch{return null}}function yc(e){try{return JSON.parse(e)}catch{return e}}async function gt(e,n){if(!(n.status==="pending"||n.status==="approved"))return{...n,approvalUrl:null};let r=await kr(e,n);return{...n,approvalUrl:r}}async function wr(e){let{permissionsOptions:n,manual:t,hub:r,permissionId:o,permissionToken:i,plugin:s,endpoint:a,args:c,tenantId:l,expiresAt:u,operationPath:d}=e;if(n?.formatAsyncMessage)return n.formatAsyncMessage({token:i,id:o,plugin:s,endpoint:a,args:c});let g=await kr({manual:t,hub:r},{id:o,token:i,plugin:s,endpoint:a,args:JSON.stringify(c),tenant_id:l,expires_at:u});return br(t)?g?t?.onApprovalRequired?t.onApprovalRequired({approvalUrl:g}):hr(g):mr:r?g?hr(g):`Action '${d}' requires user approval before it can run. Could not create approval link. Check hub configuration and server logs.`:mr}var un=class extends Error{constructor(n){super(n),Object.setPrototypeOf(this,new.target.prototype),this.name="PermissionRequiredError"}};var Si=new mc,ft=class extends Error{endpointPath;riskLevel;constructor(n,t){super(`Action '${n}' is a '${t}' operation and is forbidden in readonly mode. Only read operations are permitted \u2014 rewrite the script to avoid write/destructive actions.`),this.name="ReadonlyForbiddenError",this.endpointPath=n,this.riskLevel=t}};function Cr(e){return Si.run(!0,e)}function _i(){return Si.getStore()===!0}function vr(e,n){if(_i()&&n!=="read")throw new ft(e,n)}var kc={open:{read:"allow",write:"allow",destructive:"allow"},cautious:{read:"allow",write:"allow",destructive:"require_approval"},strict:{read:"allow",write:"require_approval",destructive:"deny"},readonly:{read:"allow",write:"deny",destructive:"deny"}};function wc(e,n,t){return t!==void 0?t:kc[n][e]}function Tr(e){let n=/(\d+)(d|h|m|s)/g,t=0,r;for(;(r=n.exec(e))!==null;){let o=parseInt(r[1],10);switch(r[2]){case"d":t+=o*864e5;break;case"h":t+=o*36e5;break;case"m":t+=o*6e4;break;case"s":t+=o*1e3;break}}return t>0?t:600*1e3}function Ei(e){return{async find_by_permission_id(n){if(e)return e.db.selectFrom("corsair_permissions").selectAll().where("id","=",n).executeTakeFirst()},async find_by_token(n){if(e)return e.db.selectFrom("corsair_permissions").selectAll().where("token","=",n).executeTakeFirst()},async set_executing(n){e&&await e.db.updateTable("corsair_permissions").set({status:"executing",updated_at:new Date}).where("id","=",n).execute()},async set_completed(n){e&&await e.db.updateTable("corsair_permissions").set({status:"completed",updated_at:new Date}).where("id","=",n).execute()}}}async function Ii(e,n,t){let r=Date.now()+t;for(;Date.now()<r;){let o=await e.db.selectFrom("corsair_permissions").select(["id","status"]).where("id","=",n).executeTakeFirst();if(!o)return{result:"blocked",reason:"pending"};if(o.status==="approved")return{result:"allow",onComplete:async()=>{await e.db.updateTable("corsair_permissions").set({status:"completed",updated_at:new Date}).where("id","=",n).execute()}};if(o.status==="denied")return{result:"blocked",reason:"denied"};if(o.status==="expired"||o.status==="failed")return{result:"blocked",reason:"timeout"};await new Promise(i=>setTimeout(i,500))}return{result:"blocked",reason:"timeout"}}async function Di(e){let n=wc(e.riskLevel,e.mode,e.override);if(n==="allow")return{result:"allow"};let t=e.meta?.irreversible?" (irreversible)":"",r=e.meta?.description?`${e.meta.description}${t}`:`${e.pluginId}.${e.endpointPath}${t}`;if(n==="deny"||!e.db)return console.log(`[corsair/${e.pluginId}] '${e.endpointPath}' blocked \u2014 denied by permission mode '${e.mode}'.`,`
|
|
9
|
+
</script></body></html>`}var _a=new Set(["localhost","127.0.0.1","[::1]","::1"]);function ir(e){try{let{hostname:n,protocol:t}=new URL(e);return t!=="http:"&&t!=="https:"?!1:_a.has(n)}catch{return!1}}function vn(e){return e==="development"?"browser":"server"}function Jo(e){return vn(e)==="browser"}function Vo(e){return ir(e)?"Production delivery URL must be a public URL, not localhost":null}import{randomBytes as Ma}from"crypto";var Ae=60*1e3,Be=300*1e3;import{createHmac as Ea,randomBytes as Da,timingSafeEqual as Oa}from"crypto";function ge(){return Da(16).toString("base64url")}function Tn(e,n){let t=n.trim();if(!t)throw new Error("Signing secret is required");return Ea("sha256",t).update(e).digest("base64url")}function ae(e,n){let t=n.trim();if(!t)return null;let r=e.split(".");if(r.length!==2)return null;let[o,i]=r;if(!o||!i)return null;let s=Tn(o,t);try{if(!Oa(Buffer.from(i,"utf8"),Buffer.from(s,"utf8")))return null}catch{return null}let a;try{a=JSON.parse(Buffer.from(o,"base64url").toString("utf8"))}catch{return null}return a.exp*1e3<Date.now()?null:a}function Vn(e,n,t){let r=Math.floor(Date.now()/1e3),o={...e,iat:r,exp:t},i=Buffer.from(JSON.stringify(o)).toString("base64url"),s=Tn(i,n);return`${i}.${s}`}function Pn(e,n,t){let r=Math.floor(Date.now()/1e3);return Vn(e,n,r+Math.floor(t/1e3))}function Fe(e){return decodeURIComponent(e)}function sr(e){return encodeURIComponent(e).replace(/\./g,"%2E")}function Yo(e){let n=e.trim();return n.length>0?n:null}function Ye(e,n){let t=new URL(e);return t.searchParams.set("d",n),t.toString()}function Qe(e,n){if(!Yo(n))throw new Error("Signing secret is required for browser delivery tokens");let t=Math.floor(Date.now()/1e3),r={...e,jti:e.jti??Ma(16).toString("base64url"),iat:t,exp:t+Math.floor(Ae/1e3)},o=Buffer.from(JSON.stringify(r)).toString("base64url"),i=Tn(o,n);return`${o}.${i}`}function Re(e,n){return Yo(n)?ae(e,n):null}function Ba(e){let n=or(e.hubOrigin),t={connectJti:e.requestId,projectId:e.projectId,hubSuccessUrl:e.hubOrigin,deliveryMode:e.deliveryMode,hubOrigin:n,requestId:e.requestId};switch(e.deliveryMode){case"connections.sync":return{...t,plugin:"connections.sync",tenantId:"*"};case"connect.create_link":return{...t,plugin:"connect.create_link",tenantId:e.tenantId,connectLinkPlugins:e.plugins}}}function ar(e){let n=Qe(Ba(e),e.signingSecret);return Ye(e.deliveryUrl,n)}function Qo(e){if(vn(e.environmentSlug)==="server")return{transport:"server"};if(!e.hubOrigin)throw new Error(`hubOrigin is required for development ${e.deliveryMode} delivery`);let t=Ha(),r={...e,hubOrigin:e.hubOrigin,requestId:t};return{transport:"browser",requestId:t,deliveryUrl:ar(r)}}var An="https://auth.corsair.dev";var fe=class extends Error{constructor(){super("Hub is not configured. Pass hub: { projectApiKey, signingSecret } to createCorsair()."),this.name="HubNotConfiguredError"}},Rn=class extends Error{constructor(){super("Hub credentials are missing. Pass hub: { projectApiKey, signingSecret } to createCorsair() with non-empty values, or omit `hub` entirely if you are not using Corsair Hub."),this.name="HubCredentialsMissingError"}};function cr(e){let n=(e.apiUrl?.trim()||An).replace(/\/$/,""),t=e.projectApiKey?.trim()??"",r=e.signingSecret?.trim()??"";if(!t||!r)throw new Rn;return{apiUrl:n,projectApiKey:t,signingSecret:r,oauthCallbackUrl:e.oauthCallbackUrl?.trim().replace(/\/$/,""),redirectURL:e.redirectURL?.trim()||void 0,allowWorkflowExecution:e.allowWorkflowExecution??!1,tunnel:e.tunnel}}function Yn(e){return cr(e)}function Fa(e){return e.apiUrl.trim().length>0&&e.projectApiKey.trim().length>0&&e.signingSecret.trim().length>0}function F(e){let n=v(e).hub;if(!n||!Fa(n))throw new fe;return n}function Xo(e){return e.replace(/\/$/,"")}function Qn(e){return e.oauthCallbackUrl?Xo(e.oauthCallbackUrl.trim()):`${Xo(e.apiUrl)}/oauth/callback`}function Xe(e){if(e.startsWith("ck_dev_"))return"development";if(e.startsWith("ck_prod_"))return"production";throw new Error("Hub API key must start with ck_dev_ (development) or ck_prod_ (production)")}import{createCipheriv as ei,createDecipheriv as ni,randomBytes as Xn,scrypt as Ua}from"crypto";import{promisify as Na}from"util";var ti=Na(Ua),et="aes-256-gcm",ri=12,nt=16,La=16,Ue=32;function ye(){return Xn(Ue).toString("base64")}async function me(e,n){let t=Xn(La),r=await ti(n,t,Ue),o=Xn(ri),i=ei(et,r,o,{authTagLength:nt}),s=Buffer.concat([i.update(e,"utf8"),i.final()]),a=i.getAuthTag();return[t.toString("base64"),o.toString("base64"),a.toString("base64"),s.toString("base64")].join(":")}async function Y(e,n){let[t,r,o,i]=e.split(":");if(!t||!r||!o||!i)throw new Error("Invalid encrypted DEK format");let s=Buffer.from(t,"base64"),a=Buffer.from(r,"base64"),c=Buffer.from(o,"base64"),l=Buffer.from(i,"base64"),u=await ti(n,s,Ue),d=ni(et,u,a,{authTagLength:nt});return d.setAuthTag(c),Buffer.concat([d.update(l),d.final()]).toString("utf8")}function ur(e,n){let t=Buffer.from(n,"base64"),r=Xn(ri),o=ei(et,t,r,{authTagLength:nt}),i=Buffer.concat([o.update(e,"utf8"),o.final()]),s=o.getAuthTag();return[r.toString("base64"),s.toString("base64"),i.toString("base64")].join(":")}function xn(e,n){let[t,r,o]=e.split(":");if(!t||!r||!o)throw new Error("Invalid encrypted data format");let i=Buffer.from(n,"base64"),s=Buffer.from(t,"base64"),a=Buffer.from(r,"base64"),c=Buffer.from(o,"base64"),l=ni(et,i,s,{authTagLength:nt});return l.setAuthTag(a),Buffer.concat([l.update(c),l.final()]).toString("utf8")}function xe(e,n){let t={};for(let[r,o]of Object.entries(e))t[r]=ur(o,n);return t}function he(e,n){let t={};for(let[r,o]of Object.entries(e))t[r]=xn(o,n);return t}function In(e,n,t){let r=he(e,n);return xe(r,t)}function oi(e,n,t){let r={};for(let o of t)r[`get_${o}`]=async()=>(await e())[o]??null,r[`set_${o}`]=async i=>{let s=[null,void 0,""].includes(i)?null:i;await n({[o]:s})};return r}var lr=e=>{if(!e)return{};if(typeof e=="string")try{return JSON.parse(e)}catch{return{}}return e};function U(e){let{authType:n,integrationName:t,kek:r,database:o,extraIntegrationFields:i=[]}=e,s=[...$[n].integration,...i],a=null,c={kek:r,integrationName:t,getIntegration:async()=>{if(a)return a;let k=await o.db.selectFrom("corsair_integrations").selectAll().where("name","=",t).executeTakeFirst();if(!k)throw new Error(`Integration "${t}" not found. Make sure to create the integration first.`);return a={id:k.id,config:lr(k.config),dek:k.dek??null},a},updateIntegration:async k=>{let b=await c.getIntegration();await o.db.updateTable("corsair_integrations").set({...k.config!==void 0?{config:k.config}:{},...k.dek!==void 0?{dek:k.dek}:{},updated_at:new Date}).where("id","=",b.id).execute(),a=null}},l=null,u=async()=>{if(l)return l;let k=await c.getIntegration();if(!k.dek)throw new Error(`No DEK found for integration "${t}". Initialize the integration first.`);return l=await Y(k.dek,r),l},d=async()=>{let k=await c.getIntegration(),b=await u(),C=k.config;return!C||Object.keys(C).length===0?{}:he(C,b)},p=Promise.resolve(),g=k=>{let b=p.then(()=>f(k));return p=b.catch(()=>{}),b},f=async k=>{let b=await u(),C;try{C=await d()}catch(D){console.error(`[corsair] Failed to decrypt config for integration "${t}", starting fresh:`,D),C={}}let P={...C};for(let[D,H]of Object.entries(k))H===null?delete P[D]:P[D]=H;let O=xe(P,b);await c.updateIntegration({config:O})};return{get_dek:u,issue_new_dek:async()=>{let k=await c.getIntegration(),b=ye(),C={};if(k.dek){let O=await Y(k.dek,r),D=k.config;D&&Object.keys(D).length>0&&(C=In(D,O,b))}let P=await me(b,r);return await c.updateIntegration({config:C,dek:P}),l=b,b},...oi(d,g,s)}}function B(e){let{authType:n,integrationName:t,tenantId:r,kek:o,database:i,extraAccountFields:s=[],ensureProvisioned:a}=e,c=[...$[n].account,...s],l=null,u=null,d=async()=>{if(u)return u;let w=!1;for(;;){let A=await i.db.selectFrom("corsair_integrations").selectAll().where("name","=",t).executeTakeFirst();if(!A){if(!w&&a){w=!0,await a();continue}throw new Error(`Integration "${t}" not found. Make sure to create the integration first.`)}return u={id:A.id,config:lr(A.config),dek:A.dek??null},u}},p={kek:o,integrationName:t,tenantId:r,getIntegration:d,getAccount:async()=>{if(l)return l;let w=!1;for(;;){let A=await d(),R=await i.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",r).where("integration_id","=",A.id).executeTakeFirst();if(!R){if(!w&&a){w=!0,await a();continue}throw new Error(`Account not found for tenant "${r}" and integration "${t}". Make sure to create the account first.`)}return l={id:R.id,config:lr(R.config),dek:R.dek??null},l}},updateAccount:async w=>{let A=await p.getAccount();await i.db.updateTable("corsair_accounts").set({...w.config!==void 0?{config:w.config}:{},...w.dek!==void 0?{dek:w.dek}:{},updated_at:new Date}).where("id","=",A.id).execute(),l=null}},g=null,f=null,h=async()=>{if(g)return g;let w=await p.getAccount();if(!w.dek)throw new Error(`No DEK found for account (tenant: "${r}", integration: "${t}"). Initialize the account first.`);return g=await Y(w.dek,o),g},k=async()=>{if(f)return f;let w=await p.getIntegration();if(!w.dek)throw new Error(`No DEK found for integration "${t}". Initialize the integration first.`);return f=await Y(w.dek,o),f},b=async()=>{let w=await p.getAccount(),A=await h(),R=w.config;return!R||Object.keys(R).length===0?{}:he(R,A)},C=async()=>{let w=await p.getIntegration(),A=await k(),R=w.config;return!R||Object.keys(R).length===0?{}:he(R,A)},P=Promise.resolve(),O=w=>{let A=P.then(()=>D(w));return P=A.catch(()=>{}),A},D=async w=>{let A=await h(),R;try{R=await b()}catch(_){console.error(`[corsair] Failed to decrypt config for account (tenant: "${r}", integration: "${t}"), starting fresh:`,_),R={}}let J={...R};for(let[_,re]of Object.entries(w))re===null?delete J[_]:J[_]=re;let de=xe(J,A);await p.updateAccount({config:de})},H={get_dek:h,issue_new_dek:async()=>{let w=await p.getAccount(),A=ye(),R={};if(w.dek){let de=await Y(w.dek,o),_=w.config;_&&Object.keys(_).length>0&&(R=In(_,de,A))}let J=await me(A,o);return await p.updateAccount({config:R,dek:J}),g=A,A},...oi(b,O,c)};return n==="oauth_2"&&(H.get_integration_credentials=async()=>{let w=await C();return{...w,client_id:w.client_id||null,client_secret:w.client_secret||null,redirect_url:w.redirect_url??null}}),H}async function ii(e,n,t){let r=await e.db.selectFrom("corsair_integrations").selectAll().where("name","=",n).executeTakeFirst();if(!r)throw new Error(`Integration "${n}" not found.`);let o=ye(),i=await me(o,t);return await e.db.updateTable("corsair_integrations").set({dek:i,updated_at:new Date}).where("id","=",r.id).execute(),o}async function si(e,n,t,r){let o=await e.db.selectFrom("corsair_integrations").selectAll().where("name","=",n).executeTakeFirst();if(!o)throw new Error(`Integration "${n}" not found.`);let i=await e.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",t).where("integration_id","=",o.id).executeTakeFirst();if(!i)throw new Error(`Account not found for tenant "${t}" and integration "${n}".`);let s=ye(),a=await me(s,r);return await e.db.updateTable("corsair_accounts").set({dek:a,updated_at:new Date}).where("id","=",i.id).execute(),s}var $a=new Set(["webhook_signature","expires_at","scope","redirect_url","refresh_token"]);function Ie(e){return $a.has(e)}function Wa(e,n){return Ie(n)?!1:e==="oauth_2"?n==="client_id"||n==="client_secret":!0}function ja(e){return!Ie(e)}function qa(e){switch(e){case"oauth_2":case"managed":return["access_token"];case"api_key":return["api_key"];case"bot_token":return["bot_token"]}}function Ka(e,n){return e!=="oauth_2"&&e!=="managed"?!1:n.some(t=>t.level==="account"&&t.name==="expires_at"&&t.configured)}function Za(e,n){let t=i=>n.find(s=>s.level==="account"&&s.name===i);if(!qa(e).every(i=>t(i)?.configured))return!1;let o=t("refresh_token");return o?.required?!!o.configured:!0}async function ai(e,n){if(!e)return!1;let t=z(e,`get_${n}`);if(!t)return!1;try{let r=await t();return typeof r=="string"&&r.length>0}catch{return!1}}function Ga(e,n){let r=e.authConfig?.[n]?.integration??[];return[...$[n].integration,...r]}function za(e,n){let r=e.authConfig?.[n]?.account??[];return[...$[n].account,...r]}function Ja(e,n,t){let r=t.filter(a=>a.required&&!a.configured).map(a=>a.name),o=t.filter(a=>a.level==="integration"&&a.required&&!a.configured).map(a=>a.name),i=t.filter(a=>a.level==="account"&&a.required&&a.configured),s;return o.length>0?s="missing_integration":r.length===0?s="ready":i.length>0?s="partial":s="not_started",{plugin:e,authType:n,status:s,connected:Za(n,t),fields:t,missingRequiredFields:r}}async function Ne(e,n,t){let r=I(n);if(!r||!e.database||!e.kek)return null;let o=t.trim()||"default",i=n.authConfig,s=i?.[r]?.integration??[],a=i?.[r]?.account??[],c=U({authType:r,integrationName:n.id,kek:e.kek,database:e.database,extraIntegrationFields:s}),l=B({authType:r,integrationName:n.id,tenantId:o,kek:e.kek,database:e.database,extraAccountFields:a}),u=Ga(n,r),d=za(n,r),p=[];for(let g of u)p.push({name:g,level:"integration",required:Wa(r,g),configured:await ai(c,g)});for(let g of d)p.push({name:g,level:"account",required:ja(g),configured:await ai(l,g)});if(Ka(r,p)){let g=p.find(f=>f.level==="account"&&f.name==="refresh_token");g&&(g.required=!0)}return Ja(n.id,r,p)}async function Sn(e,n,t={}){let r=n.trim()||"default",o=t.pluginIds?.length?new Set(t.pluginIds):null,i=[];for(let s of e.plugins){if(o&&!o.has(s.id))continue;let a=await Ne(e,s,r);a&&i.push(a)}return i}function tt(e){return e.connected?"connected":e.status==="missing_integration"?"missing_credentials":"not_connected"}var ci=Symbol.for("corsair:internal"),ui=new WeakMap,li=new WeakMap;function Va(e,n){let t=n.map(r=>r.id).sort().join("\0");return`${e}\0${t}`}function Ya(e){if(e.database){let t=ui.get(e.database);return t||(t=new Map,ui.set(e.database,t)),t}let n=li.get(e);return n||(n=new Map,li.set(e,n)),n}function Qa(e){return e.multiTenancy?{withTenant:()=>({}),[ci]:e}:{[ci]:e}}async function en(e,n){if(!e.database)return;let t=n.trim()||"default",r=Ya(e),o=Va(t,e.plugins),i=r.get(o);if(i){await i;return}let s=(async()=>{let{setupCorsair:a}=await import("./setup-LFPX6UVE.js");await a(Qa(e),{tenantId:e.multiTenancy?t:void 0,silent:!0})})().finally(()=>{r.delete(o)});r.set(o,s),await s}import*as _n from"crypto";function Se(e,n){return Buffer.from(JSON.stringify({plugin:e,tenantId:n,iat:Date.now()})).toString("base64url")}function dr(e,{maxAgeMs:n}={}){try{let t=e.includes(".")?e.split(".")[0]:e,r=JSON.parse(Buffer.from(t,"base64url").toString("utf-8"));if(r!==null&&typeof r=="object"&&"plugin"in r&&"tenantId"in r&&typeof r.plugin=="string"&&typeof r.tenantId=="string"){let o=r;return n!==void 0&&typeof o.iat=="number"&&Date.now()-o.iat>n?null:o}return null}catch{return null}}function nn(e,n){let t=_n.createHmac("sha256",n).update(e).digest("base64url");return`${e}.${t}`}var pr=600*1e3;function rt(e,n){let t=e.lastIndexOf(".");if(t===-1)return null;let r=e.slice(0,t),o=e.slice(t+1),i=_n.createHmac("sha256",n).update(r).digest("base64url"),s=Buffer.from(o,"base64url"),a=Buffer.from(i,"base64url");return s.length!==a.length||!_n.timingSafeEqual(s,a)?null:dr(r,{maxAgeMs:pr})}function di(e){return{tenantId:e.tenantId,plugin:e.plugin,authType:e.authType??"oauth_2",status:"ready",connected:!0,verified:!0,webhookLink:e.link}}function pi(e){return{tenantId:e.tenantId,plugin:e.plugin,authType:e.authType,status:e.status,connected:e.connected,verified:e.verified,missingFields:e.missingFields,webhookLink:e.webhookLink,webhookSecret:e.webhookSecret}}async function tn(e,n){await x({hub:e,path:"/connections/report",body:di(n),parseResponse:()=>({ok:!0})}).catch(()=>{})}function Xa(e,n){try{let t=F(e);x({hub:t,path:"/connections/report",body:n,parseResponse:()=>({ok:!0})}).catch(()=>{})}catch(t){if(t instanceof fe)return}}async function ec(e){if(!e.hub||!e.database||!e.kek)return;let n={database:e.database,kek:e.kek,plugins:e.plugins};if(!I(e.plugin))return;let r=e.tenantId?.trim()||"default",o=await Ne(n,e.plugin,r);o&&fi(e.hub,pi({tenantId:r,plugin:e.plugin.id,authType:o.authType,status:o.status,connected:o.connected,verified:e.verified??o.connected,missingFields:o.missingRequiredFields}))}function gi(e,n){Xa(e,n)}function fi(e,n){x({hub:e,path:"/connections/report",body:n,parseResponse:()=>({ok:!0})}).catch(()=>{})}function rn(e){ec(e).catch(()=>{})}async function be(e,n){let t=v(e);if(!I(n.plugin))return;let o=await Ne(t,n.plugin,n.tenantId);o&&gi(e,pi({tenantId:n.tenantId.trim()||"default",plugin:n.plugin.id,authType:o.authType,status:o.status,connected:o.connected,verified:n.verified??o.connected,missingFields:o.missingRequiredFields,webhookLink:n.webhookLink,webhookSecret:n.webhookSecret}))}async function ot(e,n,t){for(let r of e){if(r.id!==n)continue;let o=r.oauthWebhookTenantLinkResolver;return o?o(t):null}return null}var yi=e=>{if(!e)return{};if(typeof e=="string")try{return JSON.parse(e)}catch{return{}}return e};async function nc(e){let n=await e.database.db.selectFrom("corsair_integrations").selectAll().where("name","=",e.pluginId).executeTakeFirst();if(!n)throw new Error(`Integration '${e.pluginId}' not found. Run setupCorsair before registering webhook tenant links.`);let t=await e.database.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",e.tenantId).where("integration_id","=",n.id).executeTakeFirst();if(!t)throw new Error(`Account not found for tenant '${e.tenantId}' and integration '${e.pluginId}'.`);return{integrationId:n.id,accountId:t.id}}async function tc(e){let n=await e.database.db.selectFrom("corsair_accounts").selectAll().where("id","=",e.accountId).executeTakeFirst();if(!n?.dek)throw new Error(`Account '${e.accountId}' has no DEK.`);let t=await Y(n.dek,e.kek),r=yi(n.config),o={};Object.keys(r).length>0&&(o=he(r,t)),o[e.link.linkType]=e.link.externalId;let i=xe(o,t);await e.database.db.updateTable("corsair_accounts").set({config:i,updated_at:new Date}).where("id","=",n.id).execute()}async function on(e){let{database:n,kek:t,pluginId:r,tenantId:o,link:i,authType:s,extraAccountFields:a=[]}=e,{accountId:c}=await nc({database:n,pluginId:r,tenantId:o}),l=!1;if(s){let u=B({authType:s,integrationName:r,tenantId:o,kek:t,database:n,extraAccountFields:a}),d=`set_${i.linkType}`,p=u[d];typeof p=="function"&&(await p(i.externalId),l=!0)}l||await tc({database:n,kek:t,accountId:c,link:i})}async function gr(e){let{database:n,kek:t,pluginId:r,linkType:o,externalId:i}=e,s=await n.db.selectFrom("corsair_accounts as accounts").innerJoin("corsair_integrations as integrations","integrations.id","accounts.integration_id").selectAll("accounts").where("integrations.name","=",r).execute();for(let a of s)if(a.dek)try{let c=await Y(a.dek,t),u=yi(a.config)[o];if(!u)continue;if(xn(u,c)===i)return a}catch{continue}return null}async function it(e){return(await gr(e))?.tenant_id??null}async function mi(e){return it({database:e.database,kek:e.kek,pluginId:e.pluginId,linkType:e.match.linkType,externalId:e.match.externalId})}import*as hi from"querystring";function Le(e){let{oauthConfig:n,clientId:t,redirectUri:r,state:o}=e,i={...n.authParams,client_id:t,redirect_uri:r,response_type:"code",scope:n.scopes.join(" "),state:o};return`${n.authUrl}?${hi.stringify(i)}`}async function bi(e,n){try{return await W({hub:e,path:`/webhooks/endpoint?plugin=${encodeURIComponent(n)}`,parseResponse:t=>t?.url??null})}catch{return null}}async function sn(e,n,t,r){if(!n.subscribe)return;let o=F(e),i=await bi(o,n.id);if(!i)return;let s=await n.subscribe({keys:r},{webhookUrl:i});s&&await be(e,{plugin:n,tenantId:t,verified:!0,webhookLink:s.webhookLink,webhookSecret:s.webhookSecret})}var q=class extends Error{code;constructor(n,t){super(t),this.name="OAuthCallbackError",this.code=n}};function ki(e){let n=e.oauthConfig;if(!n)throw new q("plugin_has_no_oauth_config",`Plugin '${e.id}' has no oauthConfig`);return n}async function rc(e,n,t,r){await e.db.transaction().execute(async o=>{let i=o.selectFrom("corsair_integrations").select(["id"]).where("name","=",n);e.isPg===!0&&(i=i.forUpdate());let s=await i.executeTakeFirst();if(!s)throw new Error(`Integration '${n}' not found. Run setupCorsair first.`);if(await o.selectFrom("corsair_accounts").select("id").where("tenant_id","=",t).where("integration_id","=",s.id).executeTakeFirst())return;let c=ye(),l=await me(c,r),u=new Date;await o.insertInto("corsair_accounts").values({id:ze(),created_at:u,updated_at:u,tenant_id:t,integration_id:s.id,config:{},dek:l}).execute()})}async function fr(e,n,t){let{tenantId:r,redirectUri:o,hubConnect:i=!1}=t,s=v(e,()=>new q("invalid_corsair_instance","Invalid corsair instance"));if(!s.database)throw new Error("No database configured on corsair instance");let a=j(s,n,p=>new q("plugin_not_found",p)),c=ki(a),u=await U({authType:"oauth_2",integrationName:n,kek:s.kek,database:s.database}).get_client_id();if(!u)throw new Error(`client_id not configured for '${n}'`);if(i){let p=new URL(Le({oauthConfig:c,clientId:u,redirectUri:o,state:""}));return p.searchParams.delete("state"),{url:p.toString(),state:""}}let d=nn(Se(n,r),s.kek);return{url:Le({oauthConfig:c,clientId:u,redirectUri:o,state:d}),state:d}}function oc(e,n){return{...n??{},...e}}async function En(e,n){let{code:t,state:r,redirectUri:o}=n,i=v(e,()=>new q("invalid_corsair_instance","Invalid corsair instance")),s,a;if(n.trusted){if(!n.plugin||!n.tenantId)throw new q("invalid_state","trusted callback requires plugin and tenantId");s=n.plugin,a=n.tenantId}else{let h=rt(r,i.kek);if(!h)throw new q("invalid_state","Invalid or tampered state parameter");s=h.plugin,a=h.tenantId}if(!i.database)throw new q("no_database","No database configured on corsair instance");let c=j(i,s,h=>new q("plugin_not_found",h)),l=ki(c),u=U({authType:"oauth_2",integrationName:s,kek:i.kek,database:i.database}),d=await u.get_client_id(),p=await u.get_client_secret();if(!d||!p)throw new q("credentials_not_configured",`Credentials not configured for '${s}'`);await rc(i.database,s,a,i.kek);let g=await st(t,d,p,l,o);if(!g.access_token)throw new q("no_access_token",`No access_token returned from ${l.providerName}`);let f=B({authType:"oauth_2",integrationName:s,tenantId:a,kek:i.kek,database:i.database,extraAccountFields:[...c.authConfig?.oauth_2?.account??[]]});await f.set_access_token(g.access_token),g.refresh_token&&await f.set_refresh_token(g.refresh_token),g.expires_in&&await f.set_expires_at(String(Math.floor(Date.now()/1e3)+g.expires_in)),await be(e,{plugin:c,tenantId:a}).catch(()=>{});try{let h=oc(g,n.callbackParams),k=await ot(i.plugins,s,h);if(k){try{let b=c.authConfig?.oauth_2?.account??[];await on({database:i.database,kek:i.kek,pluginId:s,tenantId:a,link:k,authType:"oauth_2",extraAccountFields:b})}catch(b){console.warn(`[corsair:oauth] Failed to persist webhook tenant link for '${s}' tenant '${a}':`,b)}i.hub&&tn(i.hub,{plugin:s,tenantId:a,link:k,authType:"oauth_2"})}}catch(h){console.warn(`[corsair:oauth] Failed to resolve webhook tenant link for '${s}' tenant '${a}':`,h)}if(c.subscribe)try{await sn(e,c,a,f)}catch(h){console.warn(`[corsair:oauth] BYO subscribe failed for '${s}' tenant '${a}':`,h)}return{plugin:s,tenantId:a}}async function ic(e){let{corsair:n,internal:t,rows:r}=e,o=e.subscribeAndReport??sn,i=[],s=[];if(!t.database)return{renewed:i,failed:s};for(let a of r){let c=t.plugins.find(u=>u.id===a.integrationName);if(!c?.subscribe)continue;let l=`${c.id}/${a.tenantId}`;try{let u=I(c)??"oauth_2",d=B({authType:u,integrationName:c.id,tenantId:a.tenantId,kek:t.kek,database:t.database,extraAccountFields:[...c.authConfig?.[u]?.account??[]]}),p=c.keyBuilder;if(p){let g=Object.create(d,{get_expires_at:{value:async()=>"0"}});await p({authType:u,keys:g,hub:t.hub},"endpoint")}await o(n,c,a.tenantId,d),i.push(l)}catch(u){console.warn(`[corsair:renewal] re-subscribe failed for '${l}':`,u),s.push(l)}}return{renewed:i,failed:s}}async function wi(e){let n=v(e);if(!n.database)return{renewed:[],failed:[]};let t=await n.database.db.selectFrom("corsair_accounts as a").innerJoin("corsair_integrations as i","i.id","a.integration_id").select(["a.tenant_id as tenantId","i.name as integrationName"]).where("a.dek","is not",null).execute();return ic({corsair:e,internal:n,rows:t.filter(r=>!!r.tenantId)})}function sc(e,n={}){let t=!1,r=()=>{t||(t=!0,wi(e).catch(i=>console.warn("[corsair:renewal] renewal pass failed:",i)).finally(()=>{t=!1}))};r();let o=setInterval(r,(n.intervalMinutes??45)*6e4);return o.unref?.(),()=>clearInterval(o)}async function Ci(e){if(!v(e).database)throw new Error("A database must be configured to provision Corsair integrations");await at(e,{silent:!0})}async function an(e,n){let t=v(e);if(!t.database)throw new Error("A database must be configured to provision Corsair for connect");await en(t,n)}var ac=Symbol.for("corsair:internal"),cc=new Set(["access_token","refresh_token","expires_at","scope"]);function uc(e){return e==="oauth_2"||e==="managed"?"oauth":e==="bot_token"?"bot_token":"api_key"}function lc(e,n){return e==="oauth_2"||e==="managed"?n.filter(t=>!Ie(t)&&!cc.has(t)):n.filter(t=>!Ie(t))}function vi(e){return{plugins:e.plugins,database:e.database,kek:e.kek,multiTenancy:e.multiTenancy??!1}}function dc(e){return{plugins:e.plugins,database:e.database,kek:e.kek,multiTenancy:e.multiTenancy??!1}}function pc(e){return{[ac]:vi(e)}}async function ct(e,n,t={}){let r=Qn(e.hub),o=[],i=t.pluginIds?new Set(t.pluginIds):null,s=vi(e),a=pc(e);for(let c of e.plugins){if(i&&!i.has(c.id))continue;let l=I(c);if(!l)continue;let u=uc(l),d=t.providerNameOverrides?.[c.id]??Pe(c.id),p=await Ne(s,c,n),g=jn(c,l),f=lc(l,g),h={plugin:c.id,providerName:d,authKind:u,alreadyConfigured:p?.connected??!1};if(f.length>0&&(h.credentialFields=f),u==="oauth"){let b=t.oauthModeOverrides?.[c.id]??(l==="managed"?"managed":"byo");if(h.oauthMode=b,!t.skipOAuthUrlGeneration&&b!=="managed")try{let C=await fr(a,c.id,{tenantId:n,redirectUri:r,hubConnect:!0});h.oauthUrl=C.url}catch(C){C instanceof Error&&/client_id not configured/i.test(C.message)||(h.setupError=C instanceof Error?C.message:`Could not prepare OAuth for ${c.id}`)}}o.push(h)}return o}async function ag(e,n,t={}){let r=v(e),o=r.hub;if(!o)throw new Error("Hub is not configured");return ct({plugins:r.plugins,database:r.database,kek:r.kek,hub:o},n,t)}async function Ti(e,n){if(!e.database)throw new Error("A database must be configured to provision Corsair for connect");await en(e.internalConfig??dc(e),n)}async function Pi(e,n){await an(e,n)}async function Ai(e,n){let t=Xe(e.projectApiKey),r={tenantId:n.tenantId,plugins:n.plugins};return e.redirectURL&&(r.redirectUri=e.redirectURL),t==="development"&&(r.deliveryUrl=ve({deliveryUrl:n.deliveryUrl})),x({hub:e,path:"/connect/sessions",notFoundMessage:"Hub REST API not found at /connect/sessions. Check HUB_API_URL and ensure the Hub API is deployed.",body:r,parseResponse:Kn})}async function Ri(e,n){let t={plugins:n.plugins,database:n.database,kek:n.kek,hub:e,multiTenancy:n.multiTenancy};await Ti(t,n.tenantId);let r=await ct(t,n.tenantId,{pluginIds:[n.plugin.id]});if(r.length===0)throw new Error(`Plugin '${n.plugin.id}' is not configured on this Corsair instance`);return Ai(e,{tenantId:n.tenantId,plugins:r,deliveryUrl:n.deliveryUrl})}async function ut(e,n){let t=v(e),r=F(e),o={plugins:t.plugins,database:t.database,kek:t.kek,hub:r,multiTenancy:t.multiTenancy,internalConfig:t};await Pi(e,n.tenantId);let i=n.plugin?[n.plugin]:void 0,s=n.plugin&&n.oauthMode?{[n.plugin]:n.oauthMode}:void 0,a=n.plugin&&n.providerName?{[n.plugin]:n.providerName}:void 0,c=await ct(o,n.tenantId,{pluginIds:i,oauthModeOverrides:s,providerNameOverrides:a});if(c.length===0)throw new Error(n.plugin?`Plugin '${n.plugin}' is not configured on this Corsair instance`:"No plugins are configured on this Corsair instance");return Ai(r,{tenantId:n.tenantId,plugins:c,deliveryUrl:n.deliveryUrl})}async function lt(e,n){let t=n.tenantId.trim();if(!t)throw new Error("tenantId is required");let r=n.plugins.map(s=>s.trim()).filter(Boolean);if(r.length===0)throw new Error("At least one plugin is required");let o=v(e);if(!o.hub)throw new Error("Hub is not configured on this Corsair instance");if(!o.database)throw new Error("Database not configured");let i=await gc(o.hub,{plugins:o.plugins,database:o.database,kek:o.kek,multiTenancy:o.multiTenancy},{tenantId:t,pluginIds:r});return{connectUrl:i.connectUrl,expiresAt:i.expiresAt}}async function gc(e,n,t){let{buildConnectPluginManifestFromContext:r,ensureConnectAccountRowsFromContext:o}=await import("./setup-introspect-POYZQMHO.js"),{postHubConnectSession:i}=await import("./connect-ZWRSHTZ6.js"),s={plugins:n.plugins,database:n.database,kek:n.kek,hub:e,multiTenancy:n.multiTenancy};await o(s,t.tenantId);let a=await r(s,t.tenantId,{pluginIds:t.pluginIds});if(a.length===0)throw new Error("No connectable plugins found for this tenant");let c=a.find(l=>l.setupError);if(c)throw new Error(c.setupError??`Could not prepare connect link for ${c.plugin}`);return i(e,{tenantId:t.tenantId,plugins:a})}function cn(e){return!!(e?.baseUrl?.trim()&&e?.redirectUri?.trim())}var Q=class extends Error{code;constructor(n,t){super(t),this.name="ConnectError",this.code=n}};function fc(e){let n=e.oauthConfig;if(!n)throw new Q("plugin_has_no_oauth_config",`Plugin '${e.id}' has no oauthConfig`);return n}async function yr(e,n){let t=v(e,()=>new Q("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new Q("no_database","No database configured on corsair instance");let r=t.manual?.redirectUri;if(!r)throw new Q("no_redirect_uri","No redirectUri configured. Set manual.redirectUri in createCorsair().");let o=rt(n,t.kek);if(!o)throw new Q("invalid_state","Invalid or tampered state parameter");let{plugin:i,tenantId:s}=o,a=j(t,i,p=>new Q("plugin_not_found",p)),c=fc(a),u=await U({authType:"oauth_2",integrationName:i,kek:t.kek,database:t.database}).get_client_id();if(!u)throw new Q("client_id_not_configured",`client_id not configured for '${i}'`);let d=Le({oauthConfig:c,clientId:u,redirectUri:r,state:n});return{plugin:i,tenantId:s,providerName:c.providerName,oauthUrl:d,state:n}}import{AsyncLocalStorage as mc}from"async_hooks";import{randomBytes as hc}from"crypto";import{v4 as bc}from"uuid";async function dt(e,n){let t=Xe(e.projectApiKey),r={permissionId:n.permissionId,permissionToken:n.permissionToken,plugin:n.plugin,endpoint:n.endpoint,args:n.args,tenantId:n.tenantId,expiresAt:n.expiresAt};return e.redirectURL&&(r.redirectUri=e.redirectURL),t==="development"&&(r.deliveryUrl=ve({deliveryUrl:n.deliveryUrl})),x({hub:e,path:"/permission/sessions",notFoundMessage:"Hub REST API not found at /permission/sessions. Check HUB_API_URL and ensure the Hub API is deployed.",body:r,parseResponse:Gn})}function pt(e){return`Approval required. Visit ${e} to approve or deny, then tell the agent to retry this action.`}var mr="Permission approval required. Set manual.approvalBaseUrl (or use hub for hosted approval) so an approval URL can be generated. Optionally set manual.onApprovalRequired to customize the agent message.";function br(e){return e?e.approvalBaseUrl!==void 0||e.onApprovalRequired!==void 0:!1}function xi(e,n){return`${e.replace(/\/+$/,"")}/${n}`}function hr(e){return pt(e)}async function kr(e,n){if(br(e.manual)){let r=e.manual?.approvalBaseUrl?.trim();return r?xi(r,n.token):null}let t=e.hub;if(!t)return null;try{return(await dt(t,{permissionId:n.id,permissionToken:n.token,plugin:n.plugin,endpoint:n.endpoint,args:yc(n.args),tenantId:n.tenant_id,expiresAt:n.expires_at})).approvalUrl}catch{return null}}function yc(e){try{return JSON.parse(e)}catch{return e}}async function gt(e,n){if(!(n.status==="pending"||n.status==="approved"))return{...n,approvalUrl:null};let r=await kr(e,n);return{...n,approvalUrl:r}}async function wr(e){let{permissionsOptions:n,manual:t,hub:r,permissionId:o,permissionToken:i,plugin:s,endpoint:a,args:c,tenantId:l,expiresAt:u,operationPath:d}=e;if(n?.formatAsyncMessage)return n.formatAsyncMessage({token:i,id:o,plugin:s,endpoint:a,args:c});let g=await kr({manual:t,hub:r},{id:o,token:i,plugin:s,endpoint:a,args:JSON.stringify(c),tenant_id:l,expires_at:u});return br(t)?g?t?.onApprovalRequired?t.onApprovalRequired({approvalUrl:g}):hr(g):mr:r?g?hr(g):`Action '${d}' requires user approval before it can run. Could not create approval link. Check hub configuration and server logs.`:mr}var un=class extends Error{constructor(n){super(n),Object.setPrototypeOf(this,new.target.prototype),this.name="PermissionRequiredError"}};var Si=new mc,ft=class extends Error{endpointPath;riskLevel;constructor(n,t){super(`Action '${n}' is a '${t}' operation and is forbidden in readonly mode. Only read operations are permitted \u2014 rewrite the script to avoid write/destructive actions.`),this.name="ReadonlyForbiddenError",this.endpointPath=n,this.riskLevel=t}};function Cr(e){return Si.run(!0,e)}function _i(){return Si.getStore()===!0}function vr(e,n){if(_i()&&n!=="read")throw new ft(e,n)}var kc={open:{read:"allow",write:"allow",destructive:"allow"},cautious:{read:"allow",write:"allow",destructive:"require_approval"},strict:{read:"allow",write:"require_approval",destructive:"deny"},readonly:{read:"allow",write:"deny",destructive:"deny"}};function wc(e,n,t){return t!==void 0?t:kc[n][e]}function Tr(e){let n=/(\d+)(d|h|m|s)/g,t=0,r;for(;(r=n.exec(e))!==null;){let o=parseInt(r[1],10);switch(r[2]){case"d":t+=o*864e5;break;case"h":t+=o*36e5;break;case"m":t+=o*6e4;break;case"s":t+=o*1e3;break}}return t>0?t:600*1e3}function Ei(e){return{async find_by_permission_id(n){if(e)return e.db.selectFrom("corsair_permissions").selectAll().where("id","=",n).executeTakeFirst()},async find_by_token(n){if(e)return e.db.selectFrom("corsair_permissions").selectAll().where("token","=",n).executeTakeFirst()},async set_executing(n){e&&await e.db.updateTable("corsair_permissions").set({status:"executing",updated_at:new Date}).where("id","=",n).execute()},async set_completed(n){e&&await e.db.updateTable("corsair_permissions").set({status:"completed",updated_at:new Date}).where("id","=",n).execute()}}}async function Ii(e,n,t){let r=Date.now()+t;for(;Date.now()<r;){let o=await e.db.selectFrom("corsair_permissions").select(["id","status"]).where("id","=",n).executeTakeFirst();if(!o)return{result:"blocked",reason:"pending"};if(o.status==="approved")return{result:"allow",onComplete:async()=>{await e.db.updateTable("corsair_permissions").set({status:"completed",updated_at:new Date}).where("id","=",n).execute()}};if(o.status==="denied")return{result:"blocked",reason:"denied"};if(o.status==="expired"||o.status==="failed")return{result:"blocked",reason:"timeout"};await new Promise(i=>setTimeout(i,500))}return{result:"blocked",reason:"timeout"}}async function Di(e){let n=wc(e.riskLevel,e.mode,e.override);if(n==="allow")return{result:"allow"};let t=e.meta?.irreversible?" (irreversible)":"",r=e.meta?.description?`${e.meta.description}${t}`:`${e.pluginId}.${e.endpointPath}${t}`;if(n==="deny"||!e.db)return console.log(`[corsair/${e.pluginId}] '${e.endpointPath}' blocked \u2014 denied by permission mode '${e.mode}'.`,`
|
|
10
10
|
Action: ${r}`,`
|
|
11
11
|
To allow this, update the permission mode or add an override in your corsair config.`),{result:"blocked",reason:"policy"};let o=JSON.stringify(e.args),i=new Date().toISOString(),s=e.tenantId??"default",a=await e.db.db.selectFrom("corsair_permissions").selectAll().where("plugin","=",e.pluginId).where("endpoint","=",e.endpointPath).where("args","=",o).where("tenant_id","=",s).where("expires_at",">",i).where("status","in",["pending","approved","executing"]).orderBy("created_at","desc").limit(1).executeTakeFirst();if(a){if(a.status==="approved"){let f=e.db,h=a.id;return{result:"allow",onComplete:async()=>{await f.db.updateTable("corsair_permissions").set({status:"completed",updated_at:new Date}).where("id","=",h).execute()}}}return a.status==="executing"?{result:"allow"}:(console.log(`[corsair/${e.pluginId}] '${e.endpointPath}' blocked \u2014 approval already pending.`,`
|
|
12
12
|
Action: ${r}`,`
|
|
@@ -59,7 +59,7 @@ ${ua(o,d)}`),h.join(`
|
|
|
59
59
|
`)}}}return To(Ge(e),"Path not found. Available operations")}function ra(e){let n=e;for(;;){let t=ne(n),r=te(t);if(xo(r)){let o=ee(t);if(!o)return n;n=o;continue}return n}}function kn(e){if(e===void 0)return{kind:"inline",type:"unknown"};let n=ra(e),t=ne(n);if(te(t)==="ZodObject"){let o=Zt(n,t),i=[];for(let[s,a]of Object.entries(o)){let c=ne(a),l=te(c),u=l==="ZodOptional"||l==="ZodNullable",d=ra(a),p=il(a);i.push({key:s,optional:u,type:G(d),...p!==void 0?{description:p}:{}})}return{kind:"object",fields:i}}return{kind:"inline",type:G(n)}}function Kt(e,n=0){if(e===void 0)return"{}";if(e.kind==="inline")return e.type;if(e.kind==="object"){if(e.fields.length===0)return"{}";let t=ta.repeat(n+1),r=ta.repeat(n);return`{
|
|
60
60
|
${e.fields.map(i=>{let s=i.optional?`${i.key}?`:i.key,a=i.description?` // ${i.description}`:"";return`${t}${s}: ${i.type}${a}`}).join(`
|
|
61
61
|
`)}
|
|
62
|
-
${r}}`}return"unknown"}function dl(e,n){let t=Ge(e,{plugin:n,type:"api"});if(typeof t=="string")return{ok:!1,error:t};if(!Array.isArray(t))return{ok:!1,error:"list_operations did not return a path array \u2014 pass a configured plugin id."};let r=e.find(u=>u.id===n);if(!r)return{ok:!1,error:`Plugin "${n}" is not configured on this instance.`};let o=[];for(let u of t){let{shortPath:d,lookupKey:p}=ll(u,n),g=Oe(r.endpointMeta,p),f=Oe(r.endpointSchemas,p);!g&&!f||o.push({path:u,shortPath:d,description:g?.description,riskLevel:g?.riskLevel,irreversible:g?.irreversible,input:kn(f?.input),output:kn(f?.output)})}o.sort((u,d)=>u.path.localeCompare(d.path));let i=[],s=Ge(e,{plugin:n,type:"webhooks"});if(Array.isArray(s)&&r.webhooks)for(let u of s){let p=u.toLowerCase().slice(n.length+1),g=p.startsWith(".")?p.slice(1):p;if(!g.startsWith("webhooks."))continue;let f=g.slice(9),h=_o(r.webhooks,f.split("."));if(h===null)continue;let k=h.join("."),b=Oe(r.webhookSchemas,k.toLowerCase()),C=b?.response?G(b.response):void 0;i.push({path:u,description:b?.description,payload:kn(b?.payload),responseType:C,usageExample:ua(n,h)})}i.sort((u,d)=>u.path.localeCompare(d.path));let a=[],c=Ge(e,{plugin:n,type:"db"}),l=r.schema?.entities;if(Array.isArray(c)&&l)for(let u of c){let p=u.toLowerCase().slice(n.length+1),g=p.startsWith(".")?p.slice(1):p;if(!g.startsWith("db."))continue;let f=g.slice(3),h=f.lastIndexOf(".");if(h===-1)continue;let k=f.slice(0,h);if(f.slice(h+1)!=="search")continue;let C=ca(l,k);if(!C)continue;let[P,O]=C,D=So(O),H=Object.entries(D).map(([w,A])=>({field:w,type:A.type,operators:A.operators}));a.push({path:u,entityName:P,filters:[{field:"entity_id",type:"string",operators:Io},...H]})}return a.sort((u,d)=>u.path.localeCompare(d.path)),{ok:!0,data:{pluginId:n,api:o,webhooks:i,db:a}}}import{randomUUID as la}from"crypto";async function pl(e,n){let t=await e.keys.get_access_token();if(!t)return null;let r=la(),o=la(),i=await fetch(n.watchUrl,{method:"POST",signal:AbortSignal.timeout(2e4),headers:{authorization:`Bearer ${t}`,"content-type":"application/json"},body:JSON.stringify({id:r,type:"web_hook",address:n.webhookUrl,token:o,...n.body})});if(!i.ok)throw new Error(`Google channel watch failed (${i.status}): ${await i.text()}`);return{webhookLink:{linkType:"channel_id",externalId:r},webhookSecret:o}}import{randomUUID as gl}from"crypto";var Gt="https://graph.microsoft.com/v1.0",Eo=2e4,fl=60;async function yl(e,n){let t=await e.keys.get_access_token();if(!t)return null;let r={authorization:`Bearer ${t}`};try{let c=await fetch(`${Gt}/subscriptions`,{headers:r,signal:AbortSignal.timeout(Eo)});if(c.ok){let{value:l}=await c.json(),u=(l??[]).filter(d=>d.notificationUrl===n.webhookUrl);await Promise.all(u.map(d=>fetch(`${Gt}/subscriptions/${d.id}`,{method:"DELETE",headers:r,signal:AbortSignal.timeout(Eo)}).catch(()=>{})))}}catch{}let o=gl(),i=new Date(Date.now()+fl*6e4).toISOString(),s=await fetch(`${Gt}/subscriptions`,{method:"POST",headers:{...r,"content-type":"application/json"},signal:AbortSignal.timeout(Eo),body:JSON.stringify({changeType:n.changeType,notificationUrl:n.webhookUrl,resource:n.resource,expirationDateTime:i,clientState:o})});if(!s.ok)throw new Error(`MS Graph subscribe failed (${s.status}): ${await s.text()}`);let a=await s.json();return a.id?(await e.keys.set_webhook_signature(o),{webhookLink:{linkType:"subscription_id",externalId:a.id},webhookSecret:o}):null}function da(e,n){for(let[t,r]of Object.entries(e))if(r?.pluginWebhookMatcher&&r.pluginWebhookMatcher(n))return t;return null}function ml(e,n){let t=da(e,n);if(!t)return null;let r=e[t];if(!r?.pluginTenantWebhookMatcher)return null;let o=r.pluginTenantWebhookMatcher(n);return o?{plugin:t,tenantMatch:o}:null}function hl(e){let n={};for(let t of e)!t.pluginWebhookMatcher&&!t.pluginTenantWebhookMatcher||(n[t.id]={pluginWebhookMatcher:t.pluginWebhookMatcher,pluginTenantWebhookMatcher:t.pluginTenantWebhookMatcher});return n}function pa(e,n){let t=n.toLowerCase(),r=e[t]??e[n];return Array.isArray(r)?r[0]:typeof r=="string"?r:void 0}function ga(e){if(typeof e=="string"){let n=e.trim();return n.length>0?n:void 0}if(typeof e=="number"&&Number.isFinite(e))return String(e)}function Wn(e){return!e||typeof e!="object"||Array.isArray(e)?null:e}function bl(e){return Wn(e.body)}function fa(e,n){let t=e.query;if(!t)return;let r=t[n]??t[n.toLowerCase()];return zt(Array.isArray(r)?r:[r])}function ya(e){let n=e.headers??{},t=[n.validationtoken,n.validationToken,n["validation-token"],n["ms-validation-token"]];for(let c of t){let l=zt(Array.isArray(c)?c:[c]);if(l)return decodeURIComponent(l)}let r=fa({query:e.query},"validationToken");if(r)return r;let o=["x-forwarded-uri","x-original-uri","x-rewrite-url","x-envoy-original-path","referer"];for(let c of o){let l=n[c],u=Array.isArray(l)?l[0]:l;if(!(!u||typeof u!="string"))try{let p=(u.startsWith("http")?new URL(u):new URL(`https://example.invalid${u.startsWith("/")?u:`/${u}`}`)).searchParams.get("validationToken");if(p?.trim())return p.trim()}catch{continue}}let i=e.payload!==void 0?e.payload:e.body!==void 0?e.body:void 0,s=Wn(typeof i=="string"?(()=>{try{return JSON.parse(i)}catch{return i}})():i);return zt([s?.validationToken])??null}function kl(e){if(ya(e))return!0;let n=Wn(e.body??e.payload);return pa(e.headers??{},"content-type")?.includes("text/plain")?!n||Object.keys(n).length===0:!1}function zt(e){for(let n of e){let t=ga(n);if(t)return t}}function wl(e){let t=Wn(e.message)?.data;if(typeof t!="string")return null;try{return JSON.parse(Buffer.from(t,"base64").toString("utf8"))}catch{return null}}var $n=Symbol.for("corsair:internal");function ka(e){let n=e.database?Ho(e.database):void 0,t=e.kek,r=n&&t?Os(e.plugins,n,t):Lt(!!n,!!t),o=Ms(e),i={plugins:e.plugins,database:n,kek:t,multiTenancy:!!e.multiTenancy,permissions:o,manual:e.manual,hub:e.hub?Yn(e.hub):void 0},s=Ei(n),a=Js(i);if(e.multiTenancy){let u=Object.assign({withTenant:d=>{if(!d)throw new Error("corsair.withTenant(tenantId): tenantId must be a non-empty string");let p=vo(e.plugins,{database:n,tenantId:d,kek:t,rootErrorHandlers:e.errorHandlers,permissionsOptions:o,manualConfig:e.manual,hubConfig:i.hub,internalConfig:i});return Object.assign(p,{[$n]:i})},keys:r,permissions:s,manage:a},{[$n]:i});return ma(u,i.hub),ba(u,i.hub),u}let c=vo(e.plugins,{database:n,tenantId:void 0,kek:t,rootErrorHandlers:e.errorHandlers,permissionsOptions:o,manualConfig:e.manual,hubConfig:i.hub,internalConfig:i}),l=Object.assign({},c,{keys:r,permissions:s,manage:a,[$n]:i});return ma(l,i.hub),ba(l,i.hub),l}function ma(e,n){n?.projectApiKey?.startsWith("ck_dev_")&&import("./loop-
|
|
62
|
+
${r}}`}return"unknown"}function dl(e,n){let t=Ge(e,{plugin:n,type:"api"});if(typeof t=="string")return{ok:!1,error:t};if(!Array.isArray(t))return{ok:!1,error:"list_operations did not return a path array \u2014 pass a configured plugin id."};let r=e.find(u=>u.id===n);if(!r)return{ok:!1,error:`Plugin "${n}" is not configured on this instance.`};let o=[];for(let u of t){let{shortPath:d,lookupKey:p}=ll(u,n),g=Oe(r.endpointMeta,p),f=Oe(r.endpointSchemas,p);!g&&!f||o.push({path:u,shortPath:d,description:g?.description,riskLevel:g?.riskLevel,irreversible:g?.irreversible,input:kn(f?.input),output:kn(f?.output)})}o.sort((u,d)=>u.path.localeCompare(d.path));let i=[],s=Ge(e,{plugin:n,type:"webhooks"});if(Array.isArray(s)&&r.webhooks)for(let u of s){let p=u.toLowerCase().slice(n.length+1),g=p.startsWith(".")?p.slice(1):p;if(!g.startsWith("webhooks."))continue;let f=g.slice(9),h=_o(r.webhooks,f.split("."));if(h===null)continue;let k=h.join("."),b=Oe(r.webhookSchemas,k.toLowerCase()),C=b?.response?G(b.response):void 0;i.push({path:u,description:b?.description,payload:kn(b?.payload),responseType:C,usageExample:ua(n,h)})}i.sort((u,d)=>u.path.localeCompare(d.path));let a=[],c=Ge(e,{plugin:n,type:"db"}),l=r.schema?.entities;if(Array.isArray(c)&&l)for(let u of c){let p=u.toLowerCase().slice(n.length+1),g=p.startsWith(".")?p.slice(1):p;if(!g.startsWith("db."))continue;let f=g.slice(3),h=f.lastIndexOf(".");if(h===-1)continue;let k=f.slice(0,h);if(f.slice(h+1)!=="search")continue;let C=ca(l,k);if(!C)continue;let[P,O]=C,D=So(O),H=Object.entries(D).map(([w,A])=>({field:w,type:A.type,operators:A.operators}));a.push({path:u,entityName:P,filters:[{field:"entity_id",type:"string",operators:Io},...H]})}return a.sort((u,d)=>u.path.localeCompare(d.path)),{ok:!0,data:{pluginId:n,api:o,webhooks:i,db:a}}}import{randomUUID as la}from"crypto";async function pl(e,n){let t=await e.keys.get_access_token();if(!t)return null;let r=la(),o=la(),i=await fetch(n.watchUrl,{method:"POST",signal:AbortSignal.timeout(2e4),headers:{authorization:`Bearer ${t}`,"content-type":"application/json"},body:JSON.stringify({id:r,type:"web_hook",address:n.webhookUrl,token:o,...n.body})});if(!i.ok)throw new Error(`Google channel watch failed (${i.status}): ${await i.text()}`);return{webhookLink:{linkType:"channel_id",externalId:r},webhookSecret:o}}import{randomUUID as gl}from"crypto";var Gt="https://graph.microsoft.com/v1.0",Eo=2e4,fl=60;async function yl(e,n){let t=await e.keys.get_access_token();if(!t)return null;let r={authorization:`Bearer ${t}`};try{let c=await fetch(`${Gt}/subscriptions`,{headers:r,signal:AbortSignal.timeout(Eo)});if(c.ok){let{value:l}=await c.json(),u=(l??[]).filter(d=>d.notificationUrl===n.webhookUrl);await Promise.all(u.map(d=>fetch(`${Gt}/subscriptions/${d.id}`,{method:"DELETE",headers:r,signal:AbortSignal.timeout(Eo)}).catch(()=>{})))}}catch{}let o=gl(),i=new Date(Date.now()+fl*6e4).toISOString(),s=await fetch(`${Gt}/subscriptions`,{method:"POST",headers:{...r,"content-type":"application/json"},signal:AbortSignal.timeout(Eo),body:JSON.stringify({changeType:n.changeType,notificationUrl:n.webhookUrl,resource:n.resource,expirationDateTime:i,clientState:o})});if(!s.ok)throw new Error(`MS Graph subscribe failed (${s.status}): ${await s.text()}`);let a=await s.json();return a.id?(await e.keys.set_webhook_signature(o),{webhookLink:{linkType:"subscription_id",externalId:a.id},webhookSecret:o}):null}function da(e,n){for(let[t,r]of Object.entries(e))if(r?.pluginWebhookMatcher&&r.pluginWebhookMatcher(n))return t;return null}function ml(e,n){let t=da(e,n);if(!t)return null;let r=e[t];if(!r?.pluginTenantWebhookMatcher)return null;let o=r.pluginTenantWebhookMatcher(n);return o?{plugin:t,tenantMatch:o}:null}function hl(e){let n={};for(let t of e)!t.pluginWebhookMatcher&&!t.pluginTenantWebhookMatcher||(n[t.id]={pluginWebhookMatcher:t.pluginWebhookMatcher,pluginTenantWebhookMatcher:t.pluginTenantWebhookMatcher});return n}function pa(e,n){let t=n.toLowerCase(),r=e[t]??e[n];return Array.isArray(r)?r[0]:typeof r=="string"?r:void 0}function ga(e){if(typeof e=="string"){let n=e.trim();return n.length>0?n:void 0}if(typeof e=="number"&&Number.isFinite(e))return String(e)}function Wn(e){return!e||typeof e!="object"||Array.isArray(e)?null:e}function bl(e){return Wn(e.body)}function fa(e,n){let t=e.query;if(!t)return;let r=t[n]??t[n.toLowerCase()];return zt(Array.isArray(r)?r:[r])}function ya(e){let n=e.headers??{},t=[n.validationtoken,n.validationToken,n["validation-token"],n["ms-validation-token"]];for(let c of t){let l=zt(Array.isArray(c)?c:[c]);if(l)return decodeURIComponent(l)}let r=fa({query:e.query},"validationToken");if(r)return r;let o=["x-forwarded-uri","x-original-uri","x-rewrite-url","x-envoy-original-path","referer"];for(let c of o){let l=n[c],u=Array.isArray(l)?l[0]:l;if(!(!u||typeof u!="string"))try{let p=(u.startsWith("http")?new URL(u):new URL(`https://example.invalid${u.startsWith("/")?u:`/${u}`}`)).searchParams.get("validationToken");if(p?.trim())return p.trim()}catch{continue}}let i=e.payload!==void 0?e.payload:e.body!==void 0?e.body:void 0,s=Wn(typeof i=="string"?(()=>{try{return JSON.parse(i)}catch{return i}})():i);return zt([s?.validationToken])??null}function kl(e){if(ya(e))return!0;let n=Wn(e.body??e.payload);return pa(e.headers??{},"content-type")?.includes("text/plain")?!n||Object.keys(n).length===0:!1}function zt(e){for(let n of e){let t=ga(n);if(t)return t}}function wl(e){let t=Wn(e.message)?.data;if(typeof t!="string")return null;try{return JSON.parse(Buffer.from(t,"base64").toString("utf8"))}catch{return null}}var $n=Symbol.for("corsair:internal");function ka(e){let n=e.database?Ho(e.database):void 0,t=e.kek,r=n&&t?Os(e.plugins,n,t):Lt(!!n,!!t),o=Ms(e),i={plugins:e.plugins,database:n,kek:t,multiTenancy:!!e.multiTenancy,permissions:o,manual:e.manual,hub:e.hub?Yn(e.hub):void 0},s=Ei(n),a=Js(i);if(e.multiTenancy){let u=Object.assign({withTenant:d=>{if(!d)throw new Error("corsair.withTenant(tenantId): tenantId must be a non-empty string");let p=vo(e.plugins,{database:n,tenantId:d,kek:t,rootErrorHandlers:e.errorHandlers,permissionsOptions:o,manualConfig:e.manual,hubConfig:i.hub,internalConfig:i});return Object.assign(p,{[$n]:i})},keys:r,permissions:s,manage:a},{[$n]:i});return ma(u,i.hub),ba(u,i.hub),u}let c=vo(e.plugins,{database:n,tenantId:void 0,kek:t,rootErrorHandlers:e.errorHandlers,permissionsOptions:o,manualConfig:e.manual,hubConfig:i.hub,internalConfig:i}),l=Object.assign({},c,{keys:r,permissions:s,manage:a,[$n]:i});return ma(l,i.hub),ba(l,i.hub),l}function ma(e,n){n?.projectApiKey?.startsWith("ck_dev_")&&import("./loop-XAOZRMBN.js").then(t=>t.startConnectLoop(e)).catch(()=>{})}function Cl(e){return e?.projectApiKey?.startsWith("ck_dev_")?e.tunnel!==!1&&process.env.CORSAIR_TUNNEL!=="0":!1}var ha=globalThis.__corsairTunnels??=new Set,vl=1e3,Tl=3e4;function Pl(e){let n=e.schedule??((s,a)=>void setTimeout(s,a).unref?.()),t=e.minDelayMs??vl,r=e.maxDelayMs??Tl,o=t,i=()=>{let s=!1,a=()=>{s||(s=!0,n(i,o),o=Math.min(o*2,r))};e.start(a).then(()=>{o=t}).catch(a)};i()}function ba(e,n){if(!Cl(n))return;let t=n.projectApiKey;if(ha.has(t))return;let r=Number(process.env.PORT);if(!Number.isInteger(r)||r<1||r>65535){console.error("[corsair] PORT is not set \u2014 dev tunnel skipped. Set PORT to your app port, or run `corsair http <port>`.");return}ha.add(t);let o=typeof n.tunnel=="object"?n.tunnel:{},i=process.env.CORSAIR_FRP_HOST??o.shareHost??Yt;Pl({start:s=>import("./hub/tunnel/run-tunnel.js").then(a=>a.runTunnel({port:r,apiUrl:n.apiUrl,apiKey:t,shareHost:i,onClose:s})).then(({url:a})=>{console.log(`[corsair] tunnel active: ${a}${Qt}`)}).catch(a=>{throw console.warn(`[corsair] tunnel down: ${a instanceof Error?a.message:String(a)}. Retrying \u2014 run \`corsair setup\` if it doesn't recover.`),a})})}var Al={slack:{channels:{list:{}},users:{list:{}}},linear:{projects:{list:{}},issues:{list:{}},users:{list:{}}},github:{issues:{list:{}},repositories:{list:{}}},discord:{guilds:{list:{}},channels:{list:{}}},hubspot:{contacts:{getMany:{}},companies:{getMany:{}},deals:{getMany:{}}},gmail:{messages:{list:{}},labels:{list:{}},drafts:{list:{}},threads:{list:{}}},googlecalendar:{events:{getMany:{}}},googlemeet:{conferenceRecords:{list:{}}},googledrive:{files:{list:{}},folders:{list:{}},sharedDrives:{list:{}}},notion:{databases:{getManyDatabases:{}},databasePages:{getManyDatabasePages:{}},users:{getManyUsers:{}}},airtable:{bases:{getMany:{}}},todoist:{projects:{getMany:{}},tasks:{getMany:{}}},cal:{bookings:{list:{}}},zohomail:{folders:{list:{}},messages:{list:{}}}},Do=Al;async function at(e,n){let t=[],r=n?.silent??!1,o=g=>{t.push(g),r||console.log(g)},i=g=>{t.push(g),r||console.warn(g)},s=n?.caller??"script",a=Fo(e);if(!a)throw new Error("setupCorsair: invalid corsair instance");if(!a.database)throw new Error("setupCorsair: a database must be configured on the corsair instance");let c=Fl(e,a.plugins,n),l={...a,database:a.database},u=l.database.db;await Ll(u,i);let d=await $l(u,l,c.tenantId,c.provisionAccounts,o);n?.credentials&&Object.keys(n.credentials).length>0&&await ql(e,c,n.credentials,l,o,i);let p=await Zl(d,c,o,s);if(n?.backfill){o("[corsair:setup] Starting backfill...");let g=ka({plugins:a.plugins,database:u,kek:a.kek,multiTenancy:!0}).withTenant(c.tenantId);await Gl(g,a.plugins,p,o,i),o("[corsair:setup] Backfill complete.")}return t.join(`
|
|
63
63
|
`)}function Oo(e,n,t){let r=t==="integration"?e.authConfig?.[n]?.integration??[]:e.authConfig?.[n]?.account??[];return new Set([...$[n][t],...r])}function Bl(e,n){if(!e)return!1;for(let[t,r]of Object.entries(e)){let o=n.find(a=>a.id===t);if(!o)continue;let i=I(o);if(!i)continue;let s=Oo(o,i,"account");for(let a of Object.keys(r))if(s.has(a))return!0}return!1}function Fl(e,n,t){let r=Uo(e),o=t?.tenantId?.trim(),i=o!==void 0&&o.length>0;if(r&&t?.backfill&&!i)throw new Error("setupCorsair: tenantId is required for backfill on a multi-tenant instance");if(r&&Bl(t?.credentials,n)&&!i)throw new Error("setupCorsair: tenantId is required when setting account-level credentials on a multi-tenant instance");if(i&&!o)throw new Error("setupCorsair: tenantId must be a non-empty string");return{multiTenant:r,tenantIdProvided:i,tenantId:i?o:"default",provisionAccounts:!r||i}}function Ca(e,n){return Te(e)?n===0?!0:Object.values(e).every(t=>Ca(t,n-1)):!1}function Ul(e){return Ca(e,4)}var Nl=Lo;function Jt(e){if(e instanceof El){let n={};for(let[t,r]of Object.entries(e.shape))n[t]=r instanceof Hl?Jt(r):"unknown";return n}return e instanceof Sl?`${Jt(e.unwrap())} | null`:e instanceof Dl?`${Jt(e.unwrap())} | undefined`:e instanceof Il?e.options.join(" | "):e instanceof Ml?"string":e instanceof _l?"number":e instanceof Rl?"boolean":e instanceof xl?"date":e instanceof Ol?"jsonb":"unknown"}async function Ll(e,n){let t=await e.introspection.getTables(),r=new Set(t.map(o=>o.name));for(let[o,i]of Object.entries(Nl))r.has(o)||n(`[corsair:setup] Table "${o}" does not exist. Run your database migrations before calling setupCorsair.
|
|
64
64
|
Schema: ${JSON.stringify(Jt(i),null,2)}`)}async function $l(e,n,t,r,o){let i=new Date,s=new Map;for(let a of n.plugins){let c=a.id,l=I(a),u=await e.selectFrom("corsair_integrations").selectAll().where("name","=",c).executeTakeFirst();if(!u){let h=crypto.randomUUID();await e.insertInto("corsair_integrations").values({id:h,name:c,config:{},created_at:i,updated_at:i}).execute(),u=await e.selectFrom("corsair_integrations").selectAll().where("id","=",h).executeTakeFirst(),o(`[corsair:setup] Created integration: ${c}`)}let d=l?a.authConfig?.[l]?.integration??[]:[],p=l?a.authConfig?.[l]?.account??[]:[],g=l&&u?U({authType:l,integrationName:c,kek:n.kek,database:n.database,extraIntegrationFields:d}):void 0;if(u&&!u.dek&&g&&(await g.issue_new_dek(),o(`[corsair:setup] Issued integration DEK: ${c}`)),!u||!l||!g)continue;let f;if(r){let h=await e.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",t).where("integration_id","=",u.id).executeTakeFirst();if(!h){let k=crypto.randomUUID();await e.insertInto("corsair_accounts").values({id:k,tenant_id:t,integration_id:u.id,config:{},created_at:i,updated_at:i}).execute(),h=await e.selectFrom("corsair_accounts").selectAll().where("id","=",k).executeTakeFirst(),o(`[corsair:setup] Created account: ${c}`)}f=h&&B({authType:l,integrationName:c,tenantId:t,kek:n.kek,database:n.database,extraAccountFields:p}),h&&f&&!h.dek&&(await f.issue_new_dek(),o(`[corsair:setup] Issued account DEK: ${c}`))}s.set(c,{pluginId:c,authType:l,integration:g,account:f,integrationFields:[...$[l].integration,...d],accountFields:r?[...$[l].account,...p]:[]})}return s}function Wl(e){if(!Te(e))return;let n=e.keys;return Te(n)?n:void 0}function jl(e,n){return"withTenant"in e&&typeof e.withTenant=="function"?e.withTenant(n):e}async function ql(e,n,t,r,o,i){let s=Wl(e),a=n.provisionAccounts?jl(e,n.tenantId):void 0;for(let[c,l]of Object.entries(t)){let u=r.plugins.find(b=>b.id===c);if(!u){i(`[corsair:setup] Unknown plugin '${c}' \u2014 skipping credentials.`);continue}let d=I(u);if(!d){i(`[corsair:setup] Plugin '${c}' has no auth type \u2014 skipping credentials.`);continue}let p=Oo(u,d,"integration"),g=Oo(u,d,"account"),f=s?.[c],h=a?.[c],k=Te(h)?h.keys:void 0;for(let[b,C]of Object.entries(l))if(C){if(p.has(b)){if(n.multiTenant&&n.tenantIdProvided)throw new Error(`[corsair:setup] '${c}.${b}' is an integration-level credential shared across all tenants. You passed tenantId="${n.tenantId}", which only scopes account-level credentials. Run setup without --tenant if you intend to change this credential globally.`);let P=z(f,`set_${b}`);if(!P){i(`[corsair:setup] Cannot set integration field '${b}' for '${c}'.`);continue}await P(C),o(`[corsair:setup] Set ${c} integration.${b}`);continue}if(g.has(b)){if(n.multiTenant&&!n.tenantIdProvided)throw new Error(`setupCorsair: tenantId is required to set account-level credential '${c}.${b}' on a multi-tenant instance`);let P=z(k,`set_${b}`);if(!P){i(`[corsair:setup] Cannot set account field '${b}' for '${c}'.`);continue}await P(C),o(`[corsair:setup] Set ${c} account.${b} (tenant=${n.tenantId})`);continue}i(`[corsair:setup] Unknown credential field '${b}' for plugin '${c}'.`)}}}var wa=new Set(["webhook_signature","expires_at","scope","redirect_url"]);async function Kl(e,n,t,r,o,i,s,a,c){let l=[],u=[];for(let p of o){if(wa.has(p))continue;let g=z(t,`get_${p}`);if(!g)continue;let f=null;try{let h=await g();f=typeof h=="string"?h:null}catch{}f||l.push(p)}if(r&&i.length>0)for(let p of i){if(wa.has(p))continue;let g=z(r,`get_${p}`);if(!g)continue;let f=null;try{let h=await g();f=typeof h=="string"?h:null}catch{}f||u.push(p)}let d=l.length===0&&u.length===0;if(d)a(`[corsair:setup] '${e}' (${n}) is configured \u2713`);else if(n==="managed")a(`[corsair:setup] '${e}' (managed) is not connected yet. Use Connect in your app \u2014 Corsair Hub delivers OAuth tokens after authorization.`);else{let p=[...l,...u];if(c==="cli"){let g=p.map(f=>`${f}=VALUE`).join(" ");a(`[corsair:setup] '${e}' (${n}) needs credentials. Run:
|
|
65
65
|
corsair setup --${e} ${g}`)}else{let g=[`[corsair:setup] '${e}' (${n}) needs credentials. Call:`];for(let f of l)g.push(` await corsair.keys.${e}.set_${f}(value)`);for(let f of u){let h=s.provisionAccounts?s.tenantId==="default"?`corsair.${e}`:`corsair.withTenant(${JSON.stringify(s.tenantId)}).${e}`:`corsair.withTenant(<tenant>).${e}`;g.push(` await ${h}.keys.set_${f}(value)`)}a(g.join(`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ga as a,ha as b,ia as c}from"./chunk-
|
|
1
|
+
import{ga as a,ha as b,ia as c}from"./chunk-OP2RVRNB.js";import"./chunk-6IURNA4L.js";import"./chunk-7AYINDN2.js";import"./chunk-N66TLOH2.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{c as createHubConnectSession,b as createHubConnectSessionForPlugin,a as postHubConnectSession};
|
package/dist/core.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export { C as CORSAIR_INTERNAL, a as CorsairInternalConfig, c as createCorsair, s as shouldStartTunnel, b as superviseTunnel } from './index-
|
|
1
|
+
export { C as CORSAIR_INTERNAL, a as CorsairInternalConfig, c as createCorsair, s as shouldStartTunnel, b as superviseTunnel } from './index-CDIwDm35.js';
|
|
2
2
|
import { CorsairDatabase } from './db.js';
|
|
3
|
-
import { A as AuthTypes, f as AccountKeyManagerFor, I as IntegrationKeyManagerFor, H as HubConfig, g as CorsairPluginSubscribeResult } from './index-
|
|
4
|
-
export { h as AccountFieldNames, n as AgentMessageRole, o as AgentReply, v as AllProviders, l as BASE_AUTH_FIELDS, B as BaseAuthFieldConfig, i as BaseKeyManager, w as BaseProviders, a2 as BeforeHookResult, D as BindEndpoints, ap as BindWebhooks, an as Bivariant, E as BoundEndpointFn, F as BoundEndpointTree, aq as BoundWebhook, ar as BoundWebhookTree, p as ChatHandle, q as ChatMessage, r as ChatSummary, s as CorsairChatsNamespace, u as CorsairClient, G as CorsairContext, J as CorsairEndpoint, M as CorsairErrorHandler, c as CorsairIntegration, a3 as CorsairKeyBuilder, a4 as CorsairKeyBuilderBase, as as CorsairOAuthWebhookTenantLinkResolver, X as CorsairPermissionsNamespace, C as CorsairPlugin, a5 as CorsairPluginContext, a6 as CorsairPluginSubscribe, aj as CorsairRunsNamespace, e as CorsairSingleTenantClient, d as CorsairTenantWrapper, at as CorsairWebhook, au as CorsairWebhookHandler, av as CorsairWebhookMatcher, aw as CorsairWebhookTenantMatcher, aC as CorsairWorkflowsNamespace, t as CreateChatResult, a7 as EndpointHooks, a8 as EndpointMetaEntry, K as EndpointPathsOf, a9 as EndpointRiskLevel, L as EndpointTree, Y as EnforcePermissionOptions, Z as EnforcePermissionResult, N as ErrorContext, Q as ErrorHandler, R as ErrorHandlerAndMatchFunction, S as ErrorMatcher, j as IntegrationFieldNames, aa as KeyBuilderContext, k as OAuth2IntegrationCredentials, O as OAuthConfig, ab as PermissionMode, ac as PermissionPolicy, x as PickAuth, P as PluginAuthConfig, ad as PluginEndpointMeta, ae as PluginPermissionsConfig, z as ProviderDisplayNames, ax as RawWebhookRequest, a0 as ReadonlyForbiddenError, af as RequiredPluginEndpointMeta, ag as RequiredPluginEndpointSchemas, ah as RequiredPluginWebhookSchemas, U as RetryStrategies, V as RetryStrategy, T as TokenResponse, aD as TriggerRunResult, ao as UnionToIntersection, ai as WebhookHooks, ay as WebhookPathsOf, az as WebhookRequest, aA as WebhookResponse, W as WebhookTenantMatch, aB as WebhookTree, ak as WorkflowRun, al as WorkflowRunStatus, am as WorkflowRunStep, aE as WorkflowStatus, aF as WorkflowSummary, _ as assertReadonlyAllowed, m as exchangeCodeForTokens, y as formatProviderDisplayName, $ as isReadonlyScopeActive, a1 as runReadonly } from './index-
|
|
5
|
-
export { A as AuthMissingError, C as CorsairKekMissingError, D as DocSchemaFieldRow, b as DocSchemaShape, c as DocsApiEndpoint, d as DocsDbEntity, e as DocsDbFilterField, f as DocsWebhook, E as EndpointSchemaResult, I as IntrospectPluginForDocsResult, L as ListOperationsOptions, h as PermissionRequiredError, P as PluginDocsIntrospection, l as PluginWebhookMatchers, R as ReconnectRequiredError, a as ResolveConnectLinkResult, W as WebhookPluginTenantMatch, n as asRecord, j as collectPluginWebhookMatchers, o as decodePubSubData, p as extractMicrosoftGraphValidationToken, q as firstString, g as formatDocSchemaShape, s as getHeader, i as introspectPluginForDocs, t as isMicrosoftGraphValidationHandshake, m as matchWebhookPlugin, k as matchWebhookPluginAndTenant, u as readBodyRecord, v as readQueryParam, r as resolveConnectLink, w as toExternalId } from './tenant-match-utils-
|
|
3
|
+
import { A as AuthTypes, f as AccountKeyManagerFor, I as IntegrationKeyManagerFor, H as HubConfig, g as CorsairPluginSubscribeResult } from './index-C6OPrZ-q.js';
|
|
4
|
+
export { h as AccountFieldNames, n as AgentMessageRole, o as AgentReply, v as AllProviders, l as BASE_AUTH_FIELDS, B as BaseAuthFieldConfig, i as BaseKeyManager, w as BaseProviders, a2 as BeforeHookResult, D as BindEndpoints, ap as BindWebhooks, an as Bivariant, E as BoundEndpointFn, F as BoundEndpointTree, aq as BoundWebhook, ar as BoundWebhookTree, p as ChatHandle, q as ChatMessage, r as ChatSummary, s as CorsairChatsNamespace, u as CorsairClient, G as CorsairContext, J as CorsairEndpoint, M as CorsairErrorHandler, c as CorsairIntegration, a3 as CorsairKeyBuilder, a4 as CorsairKeyBuilderBase, as as CorsairOAuthWebhookTenantLinkResolver, X as CorsairPermissionsNamespace, C as CorsairPlugin, a5 as CorsairPluginContext, a6 as CorsairPluginSubscribe, aj as CorsairRunsNamespace, e as CorsairSingleTenantClient, d as CorsairTenantWrapper, at as CorsairWebhook, au as CorsairWebhookHandler, av as CorsairWebhookMatcher, aw as CorsairWebhookTenantMatcher, aC as CorsairWorkflowsNamespace, t as CreateChatResult, a7 as EndpointHooks, a8 as EndpointMetaEntry, K as EndpointPathsOf, a9 as EndpointRiskLevel, L as EndpointTree, Y as EnforcePermissionOptions, Z as EnforcePermissionResult, N as ErrorContext, Q as ErrorHandler, R as ErrorHandlerAndMatchFunction, S as ErrorMatcher, j as IntegrationFieldNames, aa as KeyBuilderContext, k as OAuth2IntegrationCredentials, O as OAuthConfig, ab as PermissionMode, ac as PermissionPolicy, x as PickAuth, P as PluginAuthConfig, ad as PluginEndpointMeta, ae as PluginPermissionsConfig, z as ProviderDisplayNames, ax as RawWebhookRequest, a0 as ReadonlyForbiddenError, af as RequiredPluginEndpointMeta, ag as RequiredPluginEndpointSchemas, ah as RequiredPluginWebhookSchemas, U as RetryStrategies, V as RetryStrategy, T as TokenResponse, aD as TriggerRunResult, ao as UnionToIntersection, ai as WebhookHooks, ay as WebhookPathsOf, az as WebhookRequest, aA as WebhookResponse, W as WebhookTenantMatch, aB as WebhookTree, ak as WorkflowRun, al as WorkflowRunStatus, am as WorkflowRunStep, aE as WorkflowStatus, aF as WorkflowSummary, _ as assertReadonlyAllowed, m as exchangeCodeForTokens, y as formatProviderDisplayName, $ as isReadonlyScopeActive, a1 as runReadonly } from './index-C6OPrZ-q.js';
|
|
5
|
+
export { A as AuthMissingError, C as CorsairKekMissingError, D as DocSchemaFieldRow, b as DocSchemaShape, c as DocsApiEndpoint, d as DocsDbEntity, e as DocsDbFilterField, f as DocsWebhook, E as EndpointSchemaResult, I as IntrospectPluginForDocsResult, L as ListOperationsOptions, h as PermissionRequiredError, P as PluginDocsIntrospection, l as PluginWebhookMatchers, R as ReconnectRequiredError, a as ResolveConnectLinkResult, W as WebhookPluginTenantMatch, n as asRecord, j as collectPluginWebhookMatchers, o as decodePubSubData, p as extractMicrosoftGraphValidationToken, q as firstString, g as formatDocSchemaShape, s as getHeader, i as introspectPluginForDocs, t as isMicrosoftGraphValidationHandshake, m as matchWebhookPlugin, k as matchWebhookPluginAndTenant, u as readBodyRecord, v as readQueryParam, r as resolveConnectLink, w as toExternalId } from './tenant-match-utils-CHag-lmL.js';
|
|
6
6
|
import 'kysely';
|
|
7
7
|
import 'zod';
|
|
8
8
|
import 'pg';
|
package/dist/core.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{$b as L,D as e,E as f,F as g,G as h,H as i,I as j,J as k,K as l,L as m,Lb as y,M as n,Mb as z,N as o,Nb as A,O as p,Ob as B,Sb as C,Tb as D,Ub as E,Vb as F,Wb as G,Xb as H,Yb as I,Zb as J,_b as K,a,ac as M,b,bc as N,c,cc as O,dc as P,eb as w,ec as Q,fc as R,gc as S,hc as T,ic as U,ja as q,jc as V,kc as W,ma as r,na as s,oa as t,pa as u,qa as v,xb as x}from"./chunk-
|
|
1
|
+
import{$b as L,D as e,E as f,F as g,G as h,H as i,I as j,J as k,K as l,L as m,Lb as y,M as n,Mb as z,N as o,Nb as A,O as p,Ob as B,Sb as C,Tb as D,Ub as E,Vb as F,Wb as G,Xb as H,Yb as I,Zb as J,_b as K,a,ac as M,b,bc as N,c,cc as O,dc as P,eb as w,ec as Q,fc as R,gc as S,hc as T,ic as U,ja as q,jc as V,kc as W,ma as r,na as s,oa as t,pa as u,qa as v,xb as x}from"./chunk-OP2RVRNB.js";import"./chunk-6IURNA4L.js";import{h as d}from"./chunk-7AYINDN2.js";import"./chunk-N66TLOH2.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{w as AuthMissingError,d as BASE_AUTH_FIELDS,T as CORSAIR_INTERNAL,x as CorsairKekMissingError,F as MS_GRAPH_API_BASE,r as PermissionRequiredError,a as ProviderDisplayNames,s as ReadonlyForbiddenError,c as ReconnectRequiredError,M as asRecord,v as assertReadonlyAllowed,J as collectPluginWebhookMatchers,n as createAccountKeyManager,U as createCorsair,m as createIntegrationKeyManager,S as decodePubSubData,k as decryptConfig,g as decryptDEK,i as decryptWithDEK,j as encryptConfig,f as encryptDEK,h as encryptWithDEK,A as exchangeCodeForTokens,P as extractMicrosoftGraphValidationToken,R as firstString,C as formatDocSchemaShape,b as formatProviderDisplayName,e as generateDEK,K as getHeader,B as getOAuthAccessToken,E as googleChannelSubscribe,p as initializeAccountDEK,o as initializeIntegrationDEK,D as introspectPluginForDocs,Q as isMicrosoftGraphValidationHandshake,u as isReadonlyScopeActive,y as logEvent,z as logEventFromContext,H as matchWebhookPlugin,I as matchWebhookPluginAndTenant,G as msGraphSubscribe,l as reEncryptConfig,N as readBodyRecord,O as readQueryParam,q as resolveConnectLink,t as runReadonly,V as shouldStartTunnel,W as superviseTunnel,L as toExternalId};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as I,b as L,c as w,f as O}from"../../chunk-
|
|
1
|
+
import{a as I,b as L,c as w,f as O}from"../../chunk-6IURNA4L.js";import"../../chunk-SOY77BN4.js";import{spawn as X}from"child_process";import{mkdtempSync as rr,rmSync as er,writeFileSync as G}from"fs";import{tmpdir as tr}from"os";import{join as S}from"path";var Z=/^(?:\/[A-Za-z0-9._~-]+)+$/;function F(r){if(!/^[\x20-\x21\x23-\x7E]+$/.test(r.apiKey))throw new Error("apiKey contains invalid characters (quotes, newlines, or control chars)");if(r.deliveryPath&&!Z.test(r.deliveryPath))throw new Error("deliveryPath must be an absolute URL path (e.g. /api/corsair)");if(r.caCertPath&&/["\x00-\x1F\x7F]/.test(r.caCertPath))throw new Error("caCertPath contains invalid characters (quotes or control chars)");let o=[`serverAddr = "${r.serverAddr}"`,`serverPort = ${r.serverPort}`,"loginFailExit = true",`metadatas.token = "${r.apiKey}"`];if(r.deliveryPath&&o.push(`metadatas.path = "${r.deliveryPath}"`),r.caCertPath){let e=/^[A-Za-z]:[\\/]|^\\\\/.test(r.caCertPath)?r.caCertPath.replace(/\\/g,"/"):r.caCertPath.replace(/\\/g,"\\\\");o.push("transport.tls.enable = true",`transport.tls.serverName = "${r.serverName??r.serverAddr}"`,`transport.tls.trustedCaFile = "${e}"`)}return o.push("","[[proxies]]",`name = "corsair-${r.slug}"`,'type = "http"','localIP = "127.0.0.1"',`localPort = ${r.localPort}`,`subdomain = "${r.slug}"`,""),o.join(`
|
|
2
2
|
`)}import K from"http";var Q=3e4,J=new Set(["host","forwarded","x-real-ip"]);function V(r){return J.has(r)||r.startsWith("x-forwarded-")}function M(r,o=w){let n=K.createServer((e,t)=>{let d=e.url??"/",i;try{i=new URL(d,"http://127.0.0.1")}catch{t.statusCode=400,t.end("Bad request");return}if(/%2f|%5c/i.test(i.pathname)){t.statusCode=400,t.end("Bad request");return}if(!(i.pathname===o||i.pathname.startsWith(`${o}/`))){t.statusCode=404,t.end("Not found");return}let E={host:`127.0.0.1:${r}`};for(let[c,u]of Object.entries(e.headers))u!==void 0&&!V(c)&&(E[c]=u);let a=K.request({host:"127.0.0.1",port:r,method:e.method,path:i.pathname+i.search,headers:E,timeout:Q},c=>{let u={};for(let[y,p]of Object.entries(c.headers))p!==void 0&&y!=="set-cookie"&&(u[y]=p);t.writeHead(c.statusCode??502,u),c.pipe(t)});a.on("timeout",()=>a.destroy()),a.on("error",()=>{if(!t.writableEnded){if(t.headersSent){t.destroy();return}t.statusCode=502,t.end("Bad gateway")}}),e.on("error",()=>a.destroy()),t.on("close",()=>{a.destroyed||a.destroy()}),e.pipe(a)});return new Promise((e,t)=>{n.once("error",t),n.listen(0,"127.0.0.1",()=>{let d=n.address(),i=typeof d=="object"&&d?d.port:0;e({port:i,close:()=>new Promise(P=>{n.close(()=>P())})})})})}var z=15e3,nr=/start proxy success/i,D=/start error/i,j=/^[a-z0-9.-]+$/i;async function or(r){let o=r.apiUrl.replace(/\/$/,""),n=await fetch(`${o}/api/dev/tunnel-config`,{headers:{authorization:`Bearer ${r.apiKey}`},signal:AbortSignal.timeout(z)});if(!n.ok)throw new Error(`Hub tunnel-config failed (HTTP ${n.status})`);let e=await n.json();if(!e.slug||!/^[a-z0-9-]+$/.test(e.slug))throw new Error("Hub tunnel-config returned an invalid slug");if(!e.serverAddr||!j.test(e.serverAddr))throw new Error("Hub tunnel-config returned an invalid server address");if(!Number.isInteger(e.serverPort)||e.serverPort<1||e.serverPort>65535)throw new Error("Hub tunnel-config returned an invalid server port");if(e.serverName!==void 0&&!j.test(e.serverName))throw new Error("Hub tunnel-config returned an invalid serverName");let t=e.caCert??null;if(t&&!t.startsWith("-----BEGIN CERTIFICATE-----"))throw new Error('Hub tunnel-config returned a caCert that does not begin with "-----BEGIN CERTIFICATE-----"');return{serverAddr:e.serverAddr,serverPort:e.serverPort,slug:e.slug,caCert:t,serverName:e.serverName}}async function Tr(r){let{port:o,apiUrl:n,apiKey:e,shareHost:t=L,timeoutMs:d=2e4,onClose:i}=r,{serverAddr:P,serverPort:E,slug:a,caCert:c,serverName:u}=await or({apiUrl:n,apiKey:e}),y=O(),p=sr(),T=await M(o,p),b,$;try{b=rr(S(tr(),"corsair-frpc-")),$=S(b,"frpc.toml");let f=c?S(b,"ca.crt"):void 0;f&&c&&G(f,c,{mode:384}),G($,F({serverAddr:P,serverPort:E,apiKey:e,slug:a,localPort:T.port,caCertPath:f,serverName:u,deliveryPath:p}),{mode:384})}catch(f){throw await T.close(),f}let W=`https://${a}.${t}`;return new Promise((f,q)=>{let h=!1,N=!1,g="",l=X(y,["-c",$],{stdio:["ignore","pipe","pipe"]}),A=()=>{T.close(),er(b,{recursive:!0,force:!0})},_=!1,H=()=>{l.killed||l.kill(),A()};process.once("exit",H);let R=()=>{_||(_=!0,process.removeListener("exit",H),process.removeListener("SIGINT",C),process.removeListener("SIGTERM",C),l.stdout.removeAllListeners("data"),l.stderr.removeAllListeners("data"),l.killed||l.kill(),A())},C=s=>{R(),process.kill(process.pid,s)};process.once("SIGINT",C),process.once("SIGTERM",C);let v=s=>{h||(h=!0,clearTimeout(U),R(),q(s))},x=async s=>{if(!N){if(g+=s.toString(),D.test(g)){v(new Error(`frpc rejected the tunnel: ${ir(g)}`));return}if(nr.test(g)){N=!0,clearTimeout(U);try{await cr({apiUrl:n,apiKey:e})}catch(m){v(m instanceof Error?m:new Error(String(m)));return}h||(h=!0,f({url:W,stop:R}))}}};l.stdout.on("data",s=>{x(s)}),l.stderr.on("data",s=>{x(s)}),l.on("error",s=>{v(new Error(`Failed to spawn frpc: ${s.message}`))}),l.on("exit",s=>{if(!h){let m=ar(g),Y=m?` \u2014 ${m}`:"";v(new Error(`frpc exited early (code ${s??"null"}) before the tunnel came up${Y}`));return}process.removeListener("exit",H),A(),i?.()});let U=setTimeout(()=>{v(new Error(`Timed out after ${d}ms waiting for frpc to establish the tunnel`))},d)})}function sr(){try{let r=new URL(I()).pathname.replace(/\/$/,"");return r&&r!=="/"?r:w}catch{return w}}function ir(r){return(r.split(`
|
|
3
3
|
`).find(n=>D.test(n))??"start error").trim()}function ar(r){return r.split(`
|
|
4
4
|
`).filter(n=>n.trim()!=="").at(-1)?.trim()??""}async function cr(r){let o=r.apiUrl.replace(/\/$/,""),n=await fetch(`${o}/api/dev/register`,{method:"POST",headers:{authorization:`Bearer ${r.apiKey}`},signal:AbortSignal.timeout(z)});if(!n.ok)throw new Error(`Hub tunnel-live ping failed (HTTP ${n.status})`)}export{or as fetchTunnelConfig,cr as pingTunnelLive,Tr as runTunnel};
|
package/dist/hub.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { aV as HubOAuthMode, A as AuthTypes, aW as HubConnectSessionResult, aX as HubPermissionSessionResult, H as HubConfig, aY as HubConfigInput, aZ as HubConnectSessionInput, a_ as HubListProjectConnectionsInput, f as AccountKeyManagerFor, a$ as HubPermissionSessionInput } from './index-
|
|
2
|
-
export { b0 as DEFAULT_HUB_API_URL, b1 as HubEnvironmentSlug, y as formatProviderDisplayName } from './index-
|
|
3
|
-
import { k as TunnelType, R as RunResultPayload, P as ProbeResultPayload, g as ProcessCorsairRequest, m as WebhookTenantLink } from './index-
|
|
4
|
-
export { n as BROWSER_DELIVERY_TTL_MS, o as BrowserDeliveryMode, B as BrowserDeliveryPayload, S as SIGNED_TUNNEL_REPLAY_WINDOW_MS, j as TunnelEnvelope } from './index-
|
|
5
|
-
export { b as buildBrowserDeliveryRedirectUrl, s as signBrowserDeliveryToken, v as verifyBrowserDeliveryToken } from './browser-delivery-
|
|
1
|
+
import { aV as HubOAuthMode, A as AuthTypes, aW as HubConnectSessionResult, aX as HubPermissionSessionResult, H as HubConfig, aY as HubConfigInput, aZ as HubConnectSessionInput, a_ as HubListProjectConnectionsInput, f as AccountKeyManagerFor, a$ as HubPermissionSessionInput } from './index-C6OPrZ-q.js';
|
|
2
|
+
export { b0 as DEFAULT_HUB_API_URL, b1 as HubEnvironmentSlug, y as formatProviderDisplayName } from './index-C6OPrZ-q.js';
|
|
3
|
+
import { k as TunnelType, R as RunResultPayload, P as ProbeResultPayload, g as ProcessCorsairRequest, m as WebhookTenantLink } from './index-C1LLhMI1.js';
|
|
4
|
+
export { n as BROWSER_DELIVERY_TTL_MS, o as BrowserDeliveryMode, B as BrowserDeliveryPayload, S as SIGNED_TUNNEL_REPLAY_WINDOW_MS, j as TunnelEnvelope } from './index-C1LLhMI1.js';
|
|
5
|
+
export { b as buildBrowserDeliveryRedirectUrl, s as signBrowserDeliveryToken, v as verifyBrowserDeliveryToken } from './browser-delivery-B-wwTCU1.js';
|
|
6
6
|
import 'zod';
|
|
7
7
|
import './db.js';
|
|
8
8
|
import 'kysely';
|
|
@@ -593,8 +593,8 @@ declare function decodePermissionTokenFromPath(encoded: string): string;
|
|
|
593
593
|
*/
|
|
594
594
|
declare function createSignedTokenJti(): string;
|
|
595
595
|
|
|
596
|
-
/** Corsair's tunnel DNS zone; dev shares are served at `<slug>.corsair.
|
|
597
|
-
declare const CORSAIR_TUNNEL_ZONE = "corsair.
|
|
596
|
+
/** Corsair's tunnel DNS zone; dev shares are served at `<slug>.corsair.run`. */
|
|
597
|
+
declare const CORSAIR_TUNNEL_ZONE = "corsair.run";
|
|
598
598
|
/** The only path the dev tunnel forwards to the app; everything else 404s. */
|
|
599
599
|
declare const CORSAIR_TUNNEL_PATH = "/api/corsair";
|
|
600
600
|
|
package/dist/hub.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{$a as _,A as z,Aa as P,B as A,Ba as Q,C as B,Ca as R,Da as S,Ea as T,Fa as U,Ga as V,Ha as W,T as C,Ua as X,Va as Y,_a as Z,ab as $,b as a,bb as aa,cb as ba,d as b,db as ca,e as c,f as d,fb as da,g as e,gb as ea,h as f,hb as fa,i as g,ia as D,ib as ga,j as i,jb as ha,k as j,ka as E,kb as ia,l as k,la as F,lb as ja,m as l,mb as ka,n as m,nb as la,o as n,ob as ma,p as o,pb as na,q as p,qb as oa,r as q,ra as G,rb as pa,s as r,sa as H,sb as qa,t as s,ta as I,tb as ra,u as t,ua as J,ub as sa,v as u,va as K,vb as ta,w as v,wa as L,wb as ua,x as w,xa as M,y as x,ya as N,z as y,za as O}from"./chunk-
|
|
1
|
+
import{$a as _,A as z,Aa as P,B as A,Ba as Q,C as B,Ca as R,Da as S,Ea as T,Fa as U,Ga as V,Ha as W,T as C,Ua as X,Va as Y,_a as Z,ab as $,b as a,bb as aa,cb as ba,d as b,db as ca,e as c,f as d,fb as da,g as e,gb as ea,h as f,hb as fa,i as g,ia as D,ib as ga,j as i,jb as ha,k as j,ka as E,kb as ia,l as k,la as F,lb as ja,m as l,mb as ka,n as m,nb as la,o as n,ob as ma,p as o,pb as na,q as p,qb as oa,r as q,ra as G,rb as pa,s as r,sa as H,sb as qa,t as s,ta as I,tb as ra,u as t,ua as J,ub as sa,v as u,va as K,vb as ta,w as v,wa as L,wb as ua,x as w,xa as M,y as x,ya as N,z as y,za as O}from"./chunk-OP2RVRNB.js";import{a as h,b as va,c as wa,d as xa,e as ya,f as za}from"./chunk-6IURNA4L.js";import"./chunk-7AYINDN2.js";import"./chunk-N66TLOH2.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{m as BROWSER_DELIVERY_TTL_MS,wa as CORSAIR_TUNNEL_PATH,va as CORSAIR_TUNNEL_ZONE,u as DEFAULT_HUB_API_URL,xa as FRPC_VERSION,w as HubCredentialsMissingError,v as HubNotConfiguredError,V as ManagedOAuthDeliveryError,n as SIGNED_TUNNEL_REPLAY_WINDOW_MS,ea as attachManagedRefreshAuth,p as buildBrowserDeliveryRedirectUrl,s as buildClientBridgeBrowserDeliveryUrl,ga as createConnectSessionJti,la as createConnectTokenJti,D as createHubConnectSession,E as createHubPermissionSession,fa as createHubRouteHandlers,ra as createPermissionSessionJti,o as createSignedTokenJti,ka as decodeConnectSessionTokenFromPath,qa as decodeConnectTokenFromPath,ua as decodePermissionTokenFromPath,Q as deliverConnectCreateLink,U as deliverSignedEnvelope,S as describeDeliveryNetworkError,pa as encodeConnectTokenForPath,O as extractConnectLinkFromDeliveryAck,H as extractProbeFromDeliveryAck,G as extractRunFromDeliveryAck,N as extractSyncFromDeliveryAck,F as formatHubApprovalMessage,a as formatProviderDisplayName,T as formatServerDeliveryError,ya as frpcPlatformKey,ha as getConnectSessionExpiryMs,X as getConnectStatusForTenant,ma as getConnectTokenExpiryMs,z as getHubConfig,da as getManagedAccessToken,Z as handleHubDeliveryGet,_ as handleHubDeliveryPost,aa as handleHubDeliveryRequest,$ as hubDeliveryToResponse,B as inferHubEnvironmentSlug,i as isLoopbackUrl,M as isServerDeliveryAckSuccessful,Y as listHubProjectConnections,x as normalizeHubConfig,P as parseConnectLinkFromDeliveryBody,b as parseConnectSessionResponse,f as parseConnectStatusResponse,g as parseHubApiErrorBody,e as parseOAuthRefreshResponse,d as parsePermissionSessionResponse,c as parseProjectConnectionsResponse,L as parseServerDeliveryAckBody,R as parseSyncFromDeliveryBody,t as prepareClientBridgeDeliveryTransport,W as processManagedOAuthDelivery,C as registerHubWebhookTenantLink,j as resolveDeliveryTransport,za as resolveFrpcBinary,y as resolveHubConfigInput,h as resolveHubDeliveryUrl,A as resolveHubOAuthCallbackUrl,ba as respondToHubDelivery,ca as respondToHubDeliveryFromRequest,q as signBrowserDeliveryToken,ia as signConnectSessionToken,na as signConnectToken,I as signDeliveryEnvelope,sa as signPermissionToken,k as usesBrowserDelivery,l as validateProductionDeliveryUrl,r as verifyBrowserDeliveryToken,ja as verifyConnectSessionToken,oa as verifyConnectToken,J as verifyDeliveryEnvelope,ta as verifyPermissionToken,K as verifySignedTunnelDelivery};
|
|
@@ -323,7 +323,7 @@ type HubConfigInput = {
|
|
|
323
323
|
* with the SDK (override with `CORSAIR_FRP_BIN`); this only tunes the URL zone.
|
|
324
324
|
*/
|
|
325
325
|
type TunnelConfig = {
|
|
326
|
-
/** DNS zone of the tunnel URL, e.g. `'corsair.
|
|
326
|
+
/** DNS zone of the tunnel URL, e.g. `'corsair.run'` (the default). */
|
|
327
327
|
shareHost?: string;
|
|
328
328
|
};
|
|
329
329
|
type HubConfig = {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CorsairDatabase } from './db.js';
|
|
2
|
-
import { C as CorsairPlugin, a as CorsairPermissionsOptions, b as CorsairManualConfig, H as HubConfig, c as CorsairIntegration, d as CorsairTenantWrapper, e as CorsairSingleTenantClient } from './index-
|
|
2
|
+
import { C as CorsairPlugin, a as CorsairPermissionsOptions, b as CorsairManualConfig, H as HubConfig, c as CorsairIntegration, d as CorsairTenantWrapper, e as CorsairSingleTenantClient } from './index-C6OPrZ-q.js';
|
|
3
3
|
|
|
4
4
|
declare const CORSAIR_INTERNAL: unique symbol;
|
|
5
5
|
type CorsairInternalConfig = {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { ZodTypeAny, z } from 'zod';
|
|
2
|
-
import { e as CorsairSingleTenantClient, d as CorsairTenantWrapper, C as CorsairPlugin, u as CorsairClient, aG as ManagementOk, aH as Tenant, aI as CreateTenantInput, aJ as PluginInfo, aK as ConnectionStatus, aL as PermissionLookupInput, aM as PermissionRecord, aN as CreateConnectLinkInput, aO as ConnectLink, aP as ResolvedConnectLink, aQ as OAuthCallbackInput, aR as OAuthCallbackResult, aS as ConnectRequest, X as CorsairPermissionsNamespace, ar as BoundWebhookTree, ax as RawWebhookRequest, aw as CorsairWebhookTenantMatcher, w as BaseProviders, aA as WebhookResponse } from './index-
|
|
3
|
-
export { aT as CorsairManageNamespace, b as CorsairManualConfig, a as CorsairPermissionsOptions, aU as PluginConnectionState, a0 as ReadonlyForbiddenError, a1 as runReadonly } from './index-
|
|
4
|
-
import { F as FormFieldSchema, L as ListOperationsOptions } from './tenant-match-utils-
|
|
5
|
-
export { A as AuthMissingError, C as CorsairKekMissingError, h as PermissionRequiredError, l as PluginWebhookMatchers, R as ReconnectRequiredError, a as ResolveConnectLinkResult, W as WebhookPluginTenantMatch, n as asRecord, j as collectPluginWebhookMatchers, o as decodePubSubData, q as firstString, g as formatDocSchemaShape, s as getHeader, m as matchWebhookPlugin, k as matchWebhookPluginAndTenant, u as readBodyRecord, r as resolveConnectLink, w as toExternalId } from './tenant-match-utils-
|
|
6
|
-
export { c as createCorsair } from './index-
|
|
2
|
+
import { e as CorsairSingleTenantClient, d as CorsairTenantWrapper, C as CorsairPlugin, u as CorsairClient, aG as ManagementOk, aH as Tenant, aI as CreateTenantInput, aJ as PluginInfo, aK as ConnectionStatus, aL as PermissionLookupInput, aM as PermissionRecord, aN as CreateConnectLinkInput, aO as ConnectLink, aP as ResolvedConnectLink, aQ as OAuthCallbackInput, aR as OAuthCallbackResult, aS as ConnectRequest, X as CorsairPermissionsNamespace, ar as BoundWebhookTree, ax as RawWebhookRequest, aw as CorsairWebhookTenantMatcher, w as BaseProviders, aA as WebhookResponse } from './index-C6OPrZ-q.js';
|
|
3
|
+
export { aT as CorsairManageNamespace, b as CorsairManualConfig, a as CorsairPermissionsOptions, aU as PluginConnectionState, a0 as ReadonlyForbiddenError, a1 as runReadonly } from './index-C6OPrZ-q.js';
|
|
4
|
+
import { F as FormFieldSchema, L as ListOperationsOptions } from './tenant-match-utils-CHag-lmL.js';
|
|
5
|
+
export { A as AuthMissingError, C as CorsairKekMissingError, h as PermissionRequiredError, l as PluginWebhookMatchers, R as ReconnectRequiredError, a as ResolveConnectLinkResult, W as WebhookPluginTenantMatch, n as asRecord, j as collectPluginWebhookMatchers, o as decodePubSubData, q as firstString, g as formatDocSchemaShape, s as getHeader, m as matchWebhookPlugin, k as matchWebhookPluginAndTenant, u as readBodyRecord, r as resolveConnectLink, w as toExternalId } from './tenant-match-utils-CHag-lmL.js';
|
|
6
|
+
export { c as createCorsair } from './index-CDIwDm35.js';
|
|
7
7
|
export { SetupCorsairOptions, setupCorsair } from './setup.js';
|
|
8
|
-
export { O as OAuthCallbackTunnelPayload, f as ProcessCorsairOptions, g as ProcessCorsairRequest, l as ResolveAccountFromWebhookLinkInput, T as TunnelAck, j as TunnelEnvelope, k as TunnelType, m as WebhookTenantLink, W as WebhookTunnelPayload, p as processCorsair, r as resolveAccountFromWebhookLink, h as resolveTenantFromWebhookLink, i as resolveTenantIdFromWebhookLink, s as setWebhookTenantLink } from './index-
|
|
8
|
+
export { O as OAuthCallbackTunnelPayload, f as ProcessCorsairOptions, g as ProcessCorsairRequest, l as ResolveAccountFromWebhookLinkInput, T as TunnelAck, j as TunnelEnvelope, k as TunnelType, m as WebhookTenantLink, W as WebhookTunnelPayload, p as processCorsair, r as resolveAccountFromWebhookLink, h as resolveTenantFromWebhookLink, i as resolveTenantIdFromWebhookLink, s as setWebhookTenantLink } from './index-C1LLhMI1.js';
|
|
9
9
|
import './db.js';
|
|
10
10
|
import 'kysely';
|
|
11
11
|
import 'pg';
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{$b as cn,Ab as J,Bb as Y,Cb as K,Db as G,Eb as X,Fb as Q,Gb as V,Hb as nn,Ia as H,Ib as en,Jb as tn,Kb as rn,P as O,Pb as P,Qa as W,Qb as w,Rb as x,Sb as R,U as A,V as L,W as E,Wa as q,X as v,Xa as N,Xb as on,Ya as j,Yb as sn,Za as B,Zb as an,_b as un,ac as pn,bc as ln,c as S,eb as D,fc as dn,gc as mn,hc as T,ic as gn,ja as F,ma as M,na as _,oa as $,xb as U,yb as Z,zb as z}from"./chunk-
|
|
1
|
+
import{$b as cn,Ab as J,Bb as Y,Cb as K,Db as G,Eb as X,Fb as Q,Gb as V,Hb as nn,Ia as H,Ib as en,Jb as tn,Kb as rn,P as O,Pb as P,Qa as W,Qb as w,Rb as x,Sb as R,U as A,V as L,W as E,Wa as q,X as v,Xa as N,Xb as on,Ya as j,Yb as sn,Za as B,Zb as an,_b as un,ac as pn,bc as ln,c as S,eb as D,fc as dn,gc as mn,hc as T,ic as gn,ja as F,ma as M,na as _,oa as $,xb as U,yb as Z,zb as z}from"./chunk-OP2RVRNB.js";import"./chunk-6IURNA4L.js";import"./chunk-7AYINDN2.js";import"./chunk-N66TLOH2.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";import{z as p}from"zod";function f(e){let t=e[T];if(!t)throw new Error("listOperations / getSchema: invalid corsair instance. Pass the value returned by createCorsair() or corsair.withTenant().");return t.plugins}function y(e,t){let o=w(f(e),t);return typeof o=="string"?o:Array.isArray(o)?o.join(`
|
|
2
2
|
`):Object.values(o).flat().join(`
|
|
3
3
|
`)}function fn(e,t){return x(f(e),t)}function k(e,t){return P(f(e),t)}function h(e,t){let o=f(e),n=t.toLowerCase(),i=n.indexOf(".");if(i===-1)return null;let u=n.slice(0,i),r=n.slice(i+1),s=o.find(c=>c.id===u);if(!s?.endpointSchemas)return null;let a=r;a.startsWith("api.")&&(a=a.slice(4));for(let[c,g]of Object.entries(s.endpointSchemas))if(c.toLowerCase()===a)return g.input??null;return null}function C(e){let t=Cn(e);return e.description&&(t=t.describe(e.description)),e.optional&&(t=t.optional()),t}function Cn(e){switch(e.kind){case"string":return e.enum&&e.enum.length>0?p.enum(e.enum):p.string();case"number":return p.number();case"boolean":return p.boolean();case"literal":return p.literal(e.value);case"object":{let t={};for(let[o,n]of Object.entries(e.fields))t[o]=C(n);return p.object(t)}case"array":return p.array(C(e.items));case"unknown":return p.unknown()}}function yn(e,t){let o=t?.tenantId?Pn(e,t.tenantId):e;return(t?.operations??kn(y(o,{plugin:t?.plugin,type:"api"}))).map(i=>{let u=k(o,i),s=h(o,i)??(u?.input?C(u.input):p.object({}));return{name:hn(i),operation:i,description:u?.description??i,schema:s,execute:a=>wn(o,i,a??{})}})}function kn(e){return e.split(`
|
|
4
4
|
`).map(t=>t.trim()).filter(Boolean)}function hn(e){return e.replace(/[^a-zA-Z0-9_-]/g,"_")}function Pn(e,t){let o=e.withTenant;return typeof o=="function"?o.call(e,t):e}async function wn(e,t,o){let n=t.split("."),i=n.pop();if(!i)throw new Error(`Invalid operation path: ${t}`);let u=e;for(let s of n)if(u=u?.[s],u==null)throw new Error(`Unknown operation path: ${t}`);let r=u[i];if(typeof r!="function")throw new Error(`Operation is not callable: ${t}`);return r.call(u,o)}var l=class extends Error{status;code;extra;constructor(t,o,n,i={}){super(n),this.name="CorsairClientError",this.status=t,this.code=o,this.extra=i}};function xn(e){return e.endsWith("/")?e.slice(0,-1):e}async function I(e){let t={};try{t=await e.json()}catch{}let o=typeof t.error=="string"?t.error:"request_failed",n=typeof t.message=="string"?t.message:`Request failed (${e.status})`,{error:i,message:u,...r}=t;return new l(e.status,o,n,r)}function Rn(e){let t=xn(e.baseURL),o=e.fetch??((...r)=>globalThis.fetch(...r));async function n(r,s){let a=s&&Object.keys(s).length?`?${new URLSearchParams(s).toString()}`:"",c=await o(`${t}${r}${a}`,{method:"GET"});if(!c.ok)throw await I(c);return await c.json()}async function i(r,s){let a=await o(`${t}${r}`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(s)});if(!a.ok)throw await I(a);return await a.json()}let u=encodeURIComponent;return{ok:()=>n("/ok"),tenants:{list:()=>n("/tenants"),create:r=>i("/tenants",r),get:r=>n(`/tenants/${u(r)}`)},plugins:{list:()=>n("/plugins"),get:r=>n(`/plugins/${u(r)}`)},connectionStatus:{get:r=>{let s={};return r?.tenantId&&(s.tenantId=r.tenantId),n("/connection-status",s)}},permissions:{get:r=>"id"in r?n(`/permissions/${u(r.id)}`):i("/permissions/lookup-by-token",{token:r.token})},connect:{createLink:r=>i("/connect/links",r),resolve:r=>n("/connect/resolve",{state:r}),oauthCallback:r=>i("/connect/oauth/callback",r)},connectRequest:{get:r=>{let s={};return r?.tenantId&&(s.tenantId=r.tenantId),n("/connect/request",s)},clear:r=>i("/connect/request/clear",r??{})}}}var Tn=Symbol.for("corsair:internal");function In(e,t){let o=e;for(let n of t){if(!o||typeof o!="object")return null;o=o[n]}return typeof o=="function"?o:null}function b(e){return e[Tn]?.database}async function bn(e,t){let o=new Date().toISOString(),n=await e.permissions.find_by_token(t);if(!n)return console.error("executePermission: no permission found for token."),{error:"executePermission: no permission found for token."};if(n.status!=="approved")return console.error(`executePermission: permission '${n.id}' is '${n.status}', expected 'approved'.`),{endpoint:n.endpoint,plugin:n.plugin,result:null,error:`executePermission: permission '${n.id}' is '${n.status}', expected 'approved'.`};if(n.expires_at<o){let a=b(e);return a&&await a.db.updateTable("corsair_permissions").set({status:"expired",updated_at:new Date}).where("id","=",n.id).execute(),console.error(`executePermission: permission '${n.id}' has expired.`),{error:`executePermission: permission '${n.id}' has expired.`,endpoint:n.endpoint,plugin:n.plugin,result:null}}let i=n.tenant_id??"default",r=(e.withTenant?e.withTenant(i):e)[n.plugin];if(!r?.api)return console.error(`executePermission: plugin '${n.plugin}' not found or has no API on this corsair instance.`),{error:`executePermission: plugin '${n.plugin}' not found or has no API on this corsair instance.`,plugin:n.plugin,endpoint:n.endpoint,result:null};let s=In(r.api,n.endpoint.split("."));if(!s)return console.error(`executePermission: endpoint '${n.endpoint}' not found in plugin '${n.plugin}'.`),{endpoint:n.endpoint,plugin:n.plugin,result:null,error:`executePermission: endpoint '${n.endpoint}' not found in plugin '${n.plugin}'.`};await e.permissions.set_executing(n.id);try{let a=typeof n.args=="string"?JSON.parse(n.args):n.args,c=await s(a);return await e.permissions.set_completed(n.id),{plugin:n.plugin,endpoint:n.endpoint,result:c}}catch(a){let c=a instanceof Error?a.message:String(a),g=b(e);return g&&await g.db.updateTable("corsair_permissions").set({status:"failed",error:c,updated_at:new Date}).where("id","=",n.id).execute(),{plugin:n.plugin,endpoint:n.endpoint,result:null,error:c}}}export{D as AuthMissingError,l as CorsairClientError,U as CorsairKekMissingError,N as DEFAULT_BODY_STALL_TIMEOUT_MS,q as DEFAULT_MAX_BODY_BYTES,M as PermissionRequiredError,_ as ReadonlyForbiddenError,S as ReconnectRequiredError,pn as asRecord,yn as buildCorsairTools,an as collectPluginWebhookMatchers,gn as createCorsair,Rn as createCorsairClient,mn as decodePubSubData,bn as executePermission,dn as firstString,C as formFieldToZod,R as formatDocSchemaShape,un as getHeader,h as getInputSchema,fn as getSchema,k as getStructuredSchema,y as listOperations,Z as managementHandler,on as matchWebhookPlugin,sn as matchWebhookPluginAndTenant,W as processCorsair,H as processWebhook,ln as readBodyRecord,J as registerCorsairRawBodyParser,L as resolveAccountFromWebhookLink,B as resolveBodyStallTimeoutMs,F as resolveConnectLink,j as resolveMaxBodyBytes,v as resolveTenantFromWebhookLink,E as resolveTenantIdFromWebhookLink,$ as runReadonly,A as setWebhookTenantLink,O as setupCorsair,nn as toAstroHandler,z as toExpressHandler,cn as toExternalId,Y as toFastifyHandler,K as toHonoHandler,G as toNextJsHandler,X as toNodeHandler,tn as toNuxtHandler,V as toRemixHandler,Q as toSvelteKitHandler,en as toTanStackHandler,rn as toWebHandler};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Ra as a,Sa as b,Ta as c}from"./chunk-
|
|
1
|
+
import{Ra as a,Sa as b,Ta as c}from"./chunk-OP2RVRNB.js";import"./chunk-6IURNA4L.js";import"./chunk-7AYINDN2.js";import"./chunk-N66TLOH2.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{a as deriveAck,b as pollOnce,c as startConnectLoop};
|
package/dist/oauth.d.ts
CHANGED
package/dist/oauth.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{$ as f,R as a,S as b,Y as c,Z as d,_ as e,aa as g,ba as h}from"./chunk-
|
|
1
|
+
import{$ as f,R as a,S as b,Y as c,Z as d,_ as e,aa as g,ba as h}from"./chunk-OP2RVRNB.js";import"./chunk-6IURNA4L.js";import"./chunk-7AYINDN2.js";import"./chunk-N66TLOH2.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{d as OAuthCallbackError,c as buildOAuthAuthorizeUrl,b as decodeOAuthState,a as encodeOAuthState,e as generateOAuthUrl,f as processOAuthCallback,g as renewSubscriptions,h as startSubscriptionRenewal};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{P as a,Q as b}from"./chunk-OP2RVRNB.js";import"./chunk-6IURNA4L.js";import"./chunk-7AYINDN2.js";import"./chunk-N66TLOH2.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{b as applySetupCredentials,a as setupCorsair};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ca as a,da as b,ea as c,fa as d}from"./chunk-
|
|
1
|
+
import{ca as a,da as b,ea as c,fa as d}from"./chunk-OP2RVRNB.js";import"./chunk-6IURNA4L.js";import"./chunk-7AYINDN2.js";import"./chunk-N66TLOH2.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{b as buildConnectPluginManifest,a as buildConnectPluginManifestFromContext,d as ensureConnectAccountRows,c as ensureConnectAccountRowsFromContext};
|
package/dist/setup.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as CorsairInternalConfig } from './index-
|
|
2
|
-
import { C as CorsairPlugin, e as CorsairSingleTenantClient, d as CorsairTenantWrapper } from './index-
|
|
1
|
+
import { a as CorsairInternalConfig } from './index-CDIwDm35.js';
|
|
2
|
+
import { C as CorsairPlugin, e as CorsairSingleTenantClient, d as CorsairTenantWrapper } from './index-C6OPrZ-q.js';
|
|
3
3
|
import { CorsairDatabase } from './db.js';
|
|
4
4
|
import 'zod';
|
|
5
5
|
import './orm.js';
|
package/dist/setup.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{P as a,Q as b}from"./chunk-
|
|
1
|
+
import{P as a,Q as b}from"./chunk-OP2RVRNB.js";import"./chunk-6IURNA4L.js";import"./chunk-7AYINDN2.js";import"./chunk-N66TLOH2.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{b as applySetupCredentials,a as setupCorsair};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a9 as EndpointRiskLevel, C as CorsairPlugin, av as CorsairWebhookMatcher, aw as CorsairWebhookTenantMatcher, ax as RawWebhookRequest, v as AllProviders, W as WebhookTenantMatch } from './index-
|
|
1
|
+
import { a9 as EndpointRiskLevel, C as CorsairPlugin, av as CorsairWebhookMatcher, aw as CorsairWebhookTenantMatcher, ax as RawWebhookRequest, v as AllProviders, W as WebhookTenantMatch } from './index-C6OPrZ-q.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Error thrown when an endpoint call is blocked pending user approval or by
|
package/dist/tunnel.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { B as BrowserDeliveryPayload, R as RunResultPayload, P as ProbeResultPayload } from './index-
|
|
2
|
-
export { O as OAuthCallbackTunnelPayload, e as OAuthTokensTunnelPayload, f as ProcessCorsairOptions, g as ProcessCorsairRequest, a as RunStepResult, b as RunTriggerType, c as RunTunnelPayload, T as TunnelAck, j as TunnelEnvelope, k as TunnelType, W as WebhookTunnelPayload, d as applyPermissionDecision, p as processCorsair, r as resolveAccountFromWebhookLink, h as resolveTenantFromWebhookLink, i as resolveTenantIdFromWebhookLink, s as setWebhookTenantLink } from './index-
|
|
3
|
-
export { v as verifyBrowserDeliveryToken } from './browser-delivery-
|
|
4
|
-
import './index-
|
|
1
|
+
import { B as BrowserDeliveryPayload, R as RunResultPayload, P as ProbeResultPayload } from './index-C1LLhMI1.js';
|
|
2
|
+
export { O as OAuthCallbackTunnelPayload, e as OAuthTokensTunnelPayload, f as ProcessCorsairOptions, g as ProcessCorsairRequest, a as RunStepResult, b as RunTriggerType, c as RunTunnelPayload, T as TunnelAck, j as TunnelEnvelope, k as TunnelType, W as WebhookTunnelPayload, d as applyPermissionDecision, p as processCorsair, r as resolveAccountFromWebhookLink, h as resolveTenantFromWebhookLink, i as resolveTenantIdFromWebhookLink, s as setWebhookTenantLink } from './index-C1LLhMI1.js';
|
|
3
|
+
export { v as verifyBrowserDeliveryToken } from './browser-delivery-B-wwTCU1.js';
|
|
4
|
+
import './index-C6OPrZ-q.js';
|
|
5
5
|
import 'zod';
|
|
6
6
|
import './db.js';
|
|
7
7
|
import 'kysely';
|
package/dist/tunnel.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Ja as f,Ka as g,La as h,Ma as i,Na as j,Oa as k,Pa as l,Qa as m,U as b,V as c,W as d,X as e,s as a}from"./chunk-
|
|
1
|
+
import{Ja as f,Ka as g,La as h,Ma as i,Na as j,Oa as k,Pa as l,Qa as m,U as b,V as c,W as d,X as e,s as a}from"./chunk-OP2RVRNB.js";import"./chunk-6IURNA4L.js";import"./chunk-7AYINDN2.js";import"./chunk-N66TLOH2.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{l as applyPermissionDecision,f as executeWorkflowRun,h as isAuthCredentialsBrowserDelivery,k as isByoOAuthBrowserDelivery,j as isManagedBrowserDelivery,i as isPermissionBrowserDelivery,m as processCorsair,c as resolveAccountFromWebhookLink,e as resolveTenantFromWebhookLink,d as resolveTenantIdFromWebhookLink,g as runReadonlyProbe,b as setWebhookTenantLink,a as verifyBrowserDeliveryToken};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "corsair",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.131",
|
|
4
4
|
"description": "Open-source integration layer for AI agents and apps. Managed OAuth, webhooks, and one API for 200+ integrations, with credentials that stay in your own database.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -83,12 +83,12 @@
|
|
|
83
83
|
"zod": "^4.1.13"
|
|
84
84
|
},
|
|
85
85
|
"optionalDependencies": {
|
|
86
|
-
"@corsair-dev/frpc-darwin-arm64": "0.1.117",
|
|
87
|
-
"@corsair-dev/frpc-linux-arm64": "0.1.117",
|
|
88
86
|
"@corsair-dev/frpc-linux-x64": "0.1.117",
|
|
89
87
|
"@corsair-dev/frpc-darwin-x64": "0.1.117",
|
|
90
88
|
"@corsair-dev/frpc-win32-arm64": "0.1.117",
|
|
91
|
-
"@corsair-dev/frpc-win32-x64": "0.1.117"
|
|
89
|
+
"@corsair-dev/frpc-win32-x64": "0.1.117",
|
|
90
|
+
"@corsair-dev/frpc-linux-arm64": "0.1.117",
|
|
91
|
+
"@corsair-dev/frpc-darwin-arm64": "0.1.117"
|
|
92
92
|
},
|
|
93
93
|
"devDependencies": {
|
|
94
94
|
"@testing-library/react": "^16.3.2",
|
package/dist/chunk-4OLKWKJG.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{a as o}from"./chunk-SOY77BN4.js";var l="3000",m="/api/corsair";function R(r){return r.replace(/\/$/,"")}function I(r){let e=r?.deliveryUrl?.trim()||process.env.CORSAIR_DELIVERY_URL?.trim();if(e){let f=/^https?:\/\//i.test(e)?e:`https://${e}`;return R(f)}return`http://localhost:${process.env.PORT?.trim()||l}${m}`}var P="corsair.cloud",$="/api/corsair";import{chmodSync as d,existsSync as c,statSync as h}from"fs";import{createRequire as g}from"module";import{homedir as y}from"os";import{dirname as _,join as p}from"path";var v="0.71.0",i;function x(){return i??=g(o),i}function S(){let r=`@corsair-dev/frpc-${process.platform}-${process.arch}`;try{let e=p(_(x().resolve(`${r}/package.json`)),u());return c(e)?e:null}catch{return null}}function a(){return`${process.platform}-${process.arch}`}function u(){return process.platform==="win32"?"frpc.exe":"frpc"}function E(){return p(y(),".cache","corsair","frpc",v,a(),u())}function n(r){if(process.platform==="win32")return r;try{let e=h(r).mode&511,t=e|73;t!==e&&d(r,t)}catch{}return r}function B(){let r=process.env.CORSAIR_FRP_BIN;if(r&&c(r))return n(r);let e=S();if(e)return n(e);let t=E();if(c(t))return n(t);throw new Error(`frpc binary not found for ${a()}. If you use pnpm, run \`pnpm approve-builds corsair\` (or add corsair to onlyBuiltDependencies) and reinstall; otherwise reinstall corsair, or set CORSAIR_FRP_BIN to an frpc path (https://github.com/fatedier/frp/releases).`)}export{I as a,P as b,$ as c,v as d,a as e,B as f};
|
package/dist/setup-PXJ3S3RO.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{P as a,Q as b}from"./chunk-QFOUQIUB.js";import"./chunk-4OLKWKJG.js";import"./chunk-7AYINDN2.js";import"./chunk-N66TLOH2.js";import"./chunk-Z2KT4F2U.js";import"./chunk-SOY77BN4.js";export{b as applySetupCredentials,a as setupCorsair};
|