corsair 0.1.121 → 0.1.123
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/README.md +25 -66
- package/dist/{browser-delivery-6Nn8dhmS.d.ts → browser-delivery-Uug_WCaP.d.ts} +1 -1
- package/dist/chunk-4OLKWKJG.js +1 -0
- package/dist/chunk-CWMYDY33.js +66 -0
- package/dist/client/react/index.d.ts +3 -3
- package/dist/{connect-L3R6F7WA.js → connect-JBFEIF2J.js} +1 -1
- package/dist/core.d.ts +6 -6
- package/dist/core.js +1 -1
- package/dist/hub/tunnel/run-tunnel.js +4 -4
- package/dist/hub.d.ts +16 -8
- package/dist/hub.js +1 -1
- package/dist/{index-Xni8GcDz.d.ts → index-BEu0WC4i.d.ts} +7 -3
- package/dist/{index-EWCtg4Qv.d.ts → index-BNQZfKP_.d.ts} +2 -2
- package/dist/{index-A9wj7Cc0.d.ts → index-CbaPR2Ry.d.ts} +1 -1
- package/dist/index.d.ts +10 -10
- package/dist/index.js +2 -2
- package/dist/{loop-FAJAJSPN.js → loop-UGODWXLA.js} +1 -1
- package/dist/oauth.d.ts +2 -2
- package/dist/oauth.js +1 -1
- package/dist/setup-KEZWK5UF.js +1 -0
- package/dist/setup-introspect-UOQO3JTV.js +1 -0
- package/dist/setup.d.ts +3 -3
- package/dist/setup.js +1 -1
- package/dist/{tenant-match-utils-CErR8w3K.d.ts → tenant-match-utils-Ca97pm5I.d.ts} +7 -3
- package/dist/tunnel.d.ts +5 -5
- package/dist/tunnel.js +1 -1
- package/dist/{types-BhDHL7BI.d.ts → types-OmoMr-B2.d.ts} +1 -1
- package/dist/{types-BtkZNK5I.d.ts → types-TZLkC0wi.d.ts} +42 -2
- package/package.json +3 -3
- package/dist/chunk-3TC2WIUS.js +0 -1
- package/dist/chunk-56G5KUMM.js +0 -66
- package/dist/setup-EMCKALPS.js +0 -1
- package/dist/setup-introspect-NCOKP62I.js +0 -1
package/README.md
CHANGED
|
@@ -1,92 +1,51 @@
|
|
|
1
|
-
# Corsair:
|
|
1
|
+
# Corsair: Connect your users to their apps
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<div align="center">
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[Website](https://corsair.dev) · [Discord](https://discord.gg/uNgCP3mSzU) · [X](https://x.com/corsairdotdev)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
</div>
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Corsair is a fully-featured product integration platform with a seamless DX. Build anything, from an agent working across all your integrations to a multi-tenant dashboard for your users to connect to anything.
|
|
10
10
|
|
|
11
|
-
## Get started
|
|
12
11
|
|
|
13
|
-
Install Corsair:
|
|
14
|
-
```bash
|
|
15
|
-
npm install corsair @corsair-dev/mcp @corsair-dev/slack @corsair-dev/github @corsair-dev/gmail @corsair-dev/linear @corsair-dev/googlecalendar
|
|
16
12
|
```
|
|
17
|
-
|
|
18
|
-
Declare your integrations in a file you can track and commit to git:
|
|
19
|
-
```typescript
|
|
20
|
-
// corsair.ts
|
|
21
13
|
import { createCorsair } from 'corsair';
|
|
22
|
-
import { slack } from '@corsair-dev/slack';
|
|
23
14
|
import { github } from '@corsair-dev/github';
|
|
24
|
-
import {
|
|
25
|
-
import { linear } from '@corsair-dev/linear';
|
|
26
|
-
import { googlecalendar } from '@corsair-dev/googlecalendar';
|
|
15
|
+
import { slack } from '@corsair-dev/slack';
|
|
27
16
|
|
|
28
17
|
export const corsair = createCorsair({
|
|
29
|
-
plugins: [
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
import { runStdioMcpServer } from '@corsair-dev/mcp';
|
|
36
|
-
|
|
37
|
-
const corsairMcpServer = runStdioMcpServer({ corsair })
|
|
38
|
-
|
|
39
|
-
query({
|
|
40
|
-
prompt: "invite jim to next thursday's sales call. tell him over slack too so he can accept it. lmk when he does",
|
|
41
|
-
options: {
|
|
42
|
-
mcpServers: { corsair: corsairMcpServer },
|
|
18
|
+
plugins: [github(), slack()],
|
|
19
|
+
database: db,
|
|
20
|
+
kek: process.env.CORSAIR_KEK!,
|
|
21
|
+
hub: {
|
|
22
|
+
projectApiKey: process.env.CORSAIR_DEV_API_KEY!,
|
|
23
|
+
signingSecret: process.env.CORSAIR_DEV_SIGNING_SECRET!,
|
|
43
24
|
},
|
|
44
|
-
})
|
|
25
|
+
});
|
|
45
26
|
```
|
|
46
27
|
|
|
47
|
-
|
|
48
|
-
> - Setup: `corsair_setup`
|
|
49
|
-
> - Introspection: `list_operations` and `get_schema`
|
|
50
|
-
> - Execution: `corsair_run`
|
|
51
|
-
|
|
52
|
-
---
|
|
53
|
-
|
|
54
|
-
## What you can do
|
|
55
|
-
|
|
56
|
-
Once connected, your agent can reason across all your integrations at once. Some things that become one-liners:
|
|
28
|
+
## Why does this exist?
|
|
57
29
|
|
|
58
|
-
|
|
30
|
+
### More than MCP
|
|
59
31
|
|
|
60
|
-
|
|
32
|
+
Most agent integration tools are MCP-only. Corsair is built on a REST API, so the same integration layer works for agents, backend services, and the dashboards your customers use.
|
|
61
33
|
|
|
62
|
-
|
|
34
|
+
### One syntax for every integration
|
|
63
35
|
|
|
64
|
-
|
|
36
|
+
The more third-party APIs your agent touches, the more glue code you write. Corsair gives every integration the same syntax, and we maintain the adapters behind it. Connect once instead of rewriting plumbing for each new tool.
|
|
65
37
|
|
|
66
|
-
|
|
38
|
+
### Open source, your data
|
|
67
39
|
|
|
68
|
-
|
|
40
|
+
Closed integration platforms keep your users' tokens and data on infrastructure you can't inspect or leave. Corsair is open source. Self-host it, or use Hub if you want us to handle OAuth refresh and webhooks. Your data remains yours either way.
|
|
69
41
|
|
|
70
|
-
|
|
42
|
+
## Contributing
|
|
71
43
|
|
|
72
|
-
|
|
44
|
+
We welcome PRs for the core library, docs, tooling, and new integration plugins. Read [CONTRIBUTING.md](CONTRIBUTING.md) for the full workflow.
|
|
73
45
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
## Alternatives
|
|
77
|
-
|
|
78
|
-
You should choose the best integration solution for your use case. Here's a quick comparison, in an effort to demonstrate why we think Corsair is the best integration solution for any use case:
|
|
79
|
-
|
|
80
|
-
| | Corsair | cURL / CLI | SDK | Vibe code it yourself | Pay for a no-code platform |
|
|
81
|
-
|--------------------------------------------------|---------|------------|-----|-----------------------|----------------------------|
|
|
82
|
-
| Compatible with coding agents | 🟢 | 🟢 | 🔴 | inconsistent | via plugins |
|
|
83
|
-
| Strongly typed | 🟢 | 🔴 | dependent on SDK | 🔴 | 🔴 |
|
|
84
|
-
| Automatically refreshes data (minimal staleness) | 🟢 | 🔴 | 🔴 | 🔴 | inconsistent |
|
|
85
|
-
| Webhook support | 🟢 | 🔴 | manual | 🔴 | 🟢 |
|
|
86
|
-
| Data is seen only by you | 🟢 | 🟢 | 🟢 | 🟢 | 🔴 |
|
|
87
|
-
| Updates with breaking API changes | 🟢 | 🔴 | manual | 🔴 | 🟢 |
|
|
88
|
-
| Multi-tenant to use with customers | 🟢 | 🔴 | manual | 🔴 | 🔴 |
|
|
46
|
+
For a new integration, claim it on the [OSS Integrations page](https://corsair.dev/oss) before you start, then open an issue with the API you want to add. Questions? Ask in [Discord](https://discord.gg/uNgCP3mSzU).
|
|
89
47
|
|
|
48
|
+
---
|
|
90
49
|
## License
|
|
91
50
|
|
|
92
|
-
Licensed under the Apache License, Version 2.0. See [LICENSE](LICENSE) for details.
|
|
51
|
+
Licensed under the Apache License, Version 2.0. See [LICENSE](https://github.com/corsairdev/corsair/blob/main/LICENSE) for details.
|
|
@@ -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.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};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import{a as we,b as Gt,c as zt}from"./chunk-4OLKWKJG.js";import{a as So,b as Ce,c as _o,d as v,e as W,f as Eo,g as G,h as L,i as I,j as Ln,k as Do,l as Oo,m as Zt,n as Mo,o as Ho}from"./chunk-VOH7OVWP.js";import{a as Io}from"./chunk-F2EV3CHK.js";import{ZodBoolean as al,ZodDate as ul,ZodEnum as cl,ZodNullable as ll,ZodNumber as dl,ZodObject as pl,ZodOptional as gl,ZodRecord as fl,ZodString as yl,ZodType as ml}from"zod";var $n=["dropboxsign","ably","abstract","abuseipdb","abyssale","accrediblecertificates","activecampaign","activetrail","addresszen","aeroleads","affinda","agencyzoom","agentmail","agentql","agenty","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","asana","asindataapi","asticaai","asyncinterview","attio","autom","ayrshare","backendless","bannerbear","bart","basecamp","baselinker","basin","beaconstac","beeminder","bettercontact","betterproposals","betterstack","bigdatacloud","bigmailer","bigml","bitbucket","bitwarden","blazemeter","blocknative","bluesky","boloforms","boltiot","bonsai","bookingmood","botpress","botsonic","bouncer","box","boxhero","brandfetch","brex","browseai","browserless","bugsnag","cal","calendly","canva","canvas","chatbotkit","circleci","clickhouse","clientary","clockify","cloudflare","cloudinary","collegefootballdata","confluence","contentfulgraphql","contextsevenmcp","crowterminal","cursor","customgpt","databricks","datadog","deepseek","devinmcp","diffbot","digitalocean","discord","dockerhub","dodopayments","doppler","dreamstudio","dropbox","epicgames","exa","facebook","faraday","figma","firecrawl","fireflies","formbricks","gemini","github","gitlab","gmail","googleaddressvalidation","googlebigquery","googlecalendar","googlecloudvision","googledocs","googledrive","googlemaps","googlemeet","googlesheets","grafana","groqcloud","habitica","hackernews","harvest","hashnode","here","heygen","htmltoimage","hubspot","huggingface","imgbb","insightoai","instagram","intercom","jigsawstack","jira","kaggle","linear","linkedin","loyverse","mailboxlayer","mailchimp","mailtrap","merriamwebsterdict","monday","neon","nextdns","notion","ocrspace","ocrwebservice","ollama","onedrive","onepassword","openai","openrouter","openweathermap","oura","outlook","pagerduty","pdfmonkey","perplexityai","pinecone","posthog","razorpay","reddit","resend","retailed","salesforce","securitytrails","sentry","serpapi","sharepoint","slack","sourcegraph","spotify","strava","streamtime","stripe","studiobyai21labs","supabase","synthflowai","tally","tavily","tavilymcp","teams","telegram","textrazor","ticktick","tisane","timecamp","todoist","toggl","trello","twentyonerisk","twilio","twitter","twitterapiio","twochat","typeform","unione","uniswapapi","vapi","vercel","vestaboard","wakatime","webflow","webvizio","whatsapp","witai","wiza","workday","xquik","youcom","youtube","zendesk","zohomail","zoom","zoominfo"],Bo={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",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",asana:"Asana",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",bettercontact:"BetterContact",betterproposals:"Better Proposals",betterstack:"Better Stack",bigdatacloud:"BigDataCloud",bigmailer:"BigMailer",bigml:"BigML",bitbucket:"Bitbucket",bitwarden:"Bitwarden",blazemeter:"BlazeMeter",blocknative:"Blocknative",bluesky:"Bluesky",boloforms:"Boloforms",boltiot:"Bolt IoT",bonsai:"Bonsai",bookingmood:"Bookingmood",botpress:"Botpress",botsonic:"Botsonic",bouncer:"Bouncer",box:"Box",boxhero:"BoxHero",brandfetch:"Brandfetch",brex:"Brex",browseai:"Browse AI",browserless:"Browserless",bugsnag:"BugSnag",cal:"Cal",calendly:"Calendly",canva:"Canva",canvas:"Canvas LMS",chatbotkit:"ChatBotKit",circleci:"CircleCI",clickhouse:"Clickhouse",clientary:"Clientary",clockify:"Clockify",cloudflare:"Cloudflare",cloudinary:"Cloudinary",collegefootballdata:"College Football Data",confluence:"Confluence",contentfulgraphql:"Contentful GraphQL",contextsevenmcp:"Context7",crowterminal:"CrowTerminal",cursor:"Cursor",customgpt:"CustomGPT",databricks:"Databricks",datadog:"Datadog",deepseek:"DeepSeek",devinmcp:"Devin MCP",diffbot:"Diffbot",digitalocean:"DigitalOcean",discord:"Discord",dockerhub:"Docker Hub",dodopayments:"Dodo Payments",doppler:"Doppler",dreamstudio:"DreamStudio",dropbox:"Dropbox",dropboxsign:"Dropbox Sign",epicgames:"Epic Games",exa:"Exa",facebook:"Facebook",faraday:"Faraday",figma:"Figma",firecrawl:"Firecrawl",fireflies:"Fireflies",formbricks:"Formbricks",gemini:"Gemini",github:"GitHub",gitlab:"GitLab",gmail:"Gmail",googleaddressvalidation:"Google Address Validation",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",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",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",pdfmonkey:"PDFMonkey",perplexityai:"Perplexity AI",pinecone:"Pinecone",posthog:"PostHog",razorpay:"Razorpay",reddit:"Reddit",resend:"Resend",retailed:"Retailed",salesforce:"Salesforce",securitytrails:"SecurityTrails",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",tisane:"Tisane",timecamp:"TimeCamp",todoist:"Todoist",toggl:"Toggl",trello:"Trello",twentyonerisk:"TwentyOneRisk",twilio:"Twilio",twitter:"Twitter",twitterapiio:"Twitter API IO",twochat:"TwoChat",typeform:"Typeform",unione:"Unione",uniswapapi:"Uniswap",vapi:"Vapi",vercel:"Vercel",vestaboard:"Vestaboard",wakatime:"WakaTime",webflow:"Webflow",webvizio:"Webvizio",whatsapp:"WhatsApp",witai:"WitAi",wiza:"Wiza",workday:"Workday",xquik:"XQuik",youcom:"You.com",youtube:"YouTube",zendesk:"Zendesk",zohomail:"Zoho Mail",zoom:"Zoom",zoominfo:"ZoomInfo"};function ve(e){let n=Bo[e];return n||e.charAt(0).toUpperCase()+e.slice(1)}function _(e){return typeof e=="string"&&e.length>0}function ga(e){return e==="ready"||e==="partial"||e==="not_started"||e==="missing_integration"}function fa(e){return e==="oauth_2"||e==="api_key"||e==="bot_token"||e==="managed"}function Wn(e){if(!e||typeof e!="object")throw new Error("Hub API returned an empty connect session");let n=e;if(!_(n.connectUrl)||!_(n.token)||!_(n.projectId))throw new Error("Hub API returned an incomplete connect session (expected connectUrl, token, and projectId)");let t={connectUrl:n.connectUrl,token:n.token,projectId:n.projectId,environmentId:_(n.environmentId)?n.environmentId:n.projectId};return _(n.expiresAt)&&(t.expiresAt=n.expiresAt),t}function jn(e){if(!Array.isArray(e))throw new Error("Hub API returned an invalid connections response (expected array)");let n=[];for(let t of e){if(!t||typeof t!="object")continue;let r=t;if(!_(r.tenantId)||!_(r.plugin)||!ga(r.status)||!fa(r.authType)||typeof r.connected!="boolean"||typeof r.verified!="boolean")continue;let o=Array.isArray(r.missingFields)?r.missingFields.filter(i=>typeof i=="string"):[];n.push({tenantId:r.tenantId,plugin:r.plugin,status:r.status,authType:r.authType,connected:r.connected,verified:r.verified,missingFields:o,reportedAt:_(r.reportedAt)?r.reportedAt:new Date().toISOString()})}return n}function Kn(e){if(!e||typeof e!="object")throw new Error("Hub API returned an empty permission session");let n=e;if(!_(n.approvalUrl)||!_(n.token)||!_(n.projectId)||!_(n.expiresAt))throw new Error("Hub API returned an incomplete permission session (expected approvalUrl, token, projectId, and expiresAt)");return{approvalUrl:n.approvalUrl,token:n.token,projectId:n.projectId,expiresAt:n.expiresAt}}function qe(e){if(!e||typeof e!="object")throw new Error("Hub token refresh returned an empty response");let n=e;if(_(n.access_token))return{access_token:n.access_token,refresh_token:_(n.refresh_token)?n.refresh_token:void 0,expires_in:(()=>{if(typeof n.expires_in=="number")return n.expires_in;if(typeof n.expires_in=="string"&&n.expires_in.trim().length>0){let t=Number(n.expires_in);return Number.isFinite(t)?t:void 0}})(),scope:_(n.scope)?n.scope:void 0};throw new Error(_(n.error)?_(n.error_description)?n.error_description:n.error:"Hub token refresh returned no access_token")}function ya(e){return Array.isArray(e)?e.filter(n=>typeof n=="string"):[]}function ma(e){if(!Array.isArray(e))return[];let n=[];for(let t of e){if(!t||typeof t!="object")continue;let r=t;_(r.name)&&n.push({name:r.name,level:r.level==="integration"||r.level==="account"?r.level:"account",required:r.required===!0,configured:r.configured===!0})}return n}function ha(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 Fo(e){if(!e||typeof e!="object")throw new Error("Connect status response was empty");let n=e;if(!_(n.tenantId)||!Array.isArray(n.plugins))throw new Error("Connect status response was incomplete (expected tenantId and plugins)");let t=[];for(let r of n.plugins){if(!r||typeof r!="object")continue;let o=r;if(!_(o.plugin)||typeof o.connected!="boolean")continue;let i=o.authKind==="oauth"||o.authKind==="api_key"||o.authKind==="bot_token"?o.authKind:"api_key",s=ma(o.fields),a=ya(o.missingRequiredFields),u=ha(o.status,o.connected,s,a);t.push({plugin:o.plugin,providerName:_(o.providerName)?o.providerName:o.plugin,authKind:i,status:u,connected:o.connected,fields:s,missingRequiredFields:a})}return{tenantId:n.tenantId,plugins:t}}function qn(e){if(!e||typeof e!="object")return null;let n=e;return n.error??n.message??null}function No(e){return e.replace(/\/$/,"")}function Jt(e){if(!e.projectApiKey.startsWith("ck_dev_"))return null;try{return we()}catch{return null}}function Uo(e){let n=Jt(e);return n?{"x-corsair-delivery-url":n}:{}}async function Lo(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 $o(e,n,t){if(n===404&&t)return t;let r=qn(e);return r||`Hub API returned HTTP ${n}`}async function x(e){let n=No(e.hub.apiUrl),t=await fetch(`${n}${e.path}`,{method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${e.hub.projectApiKey}`,...Uo(e.hub)},body:JSON.stringify(e.body)}),r=await Lo(t);if(!t.ok)throw new Error($o(r,t.status,e.notFoundMessage));return e.parseResponse(r)}async function $(e){let n=No(e.hub.apiUrl),t=await fetch(`${n}${e.path}`,{method:"GET",headers:{authorization:`Bearer ${e.hub.projectApiKey}`,...Uo(e.hub)}}),r=await Lo(t);if(!t.ok)throw new Error($o(r,t.status,e.notFoundMessage));return e.parseResponse(r)}function Zn(e){return e&&typeof e=="object"?e:{}}function Wo(e){let n=Zn(e);return{chatId:n.threadId,message:n.message,workflowId:n.workflowId??null,action:n.action}}async function Vt(e,n){return x({hub:e,path:"/threads",body:{tenantId:n.tenantId,message:n.message},parseResponse:t=>{let r=Zn(t);return{chat:r.thread,reply:Wo(r.reply)}}})}async function Yt(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:Wo})}async function Xt(e,n){return $({hub:e,path:`/threads?tenantId=${encodeURIComponent(n.tenantId)}`,parseResponse:t=>{let r=Zn(t).threads;return Array.isArray(r)?r:[]}})}async function Qt(e,n){return $({hub:e,path:`/threads/${encodeURIComponent(n.chatId)}/messages?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Chat "${n.chatId}" not found`,parseResponse:t=>{let r=Zn(t).messages;return Array.isArray(r)?r:[]}})}import{randomUUID as Pa}from"crypto";var ba="corsair:client-bridge";function er(e){return new URL(e).origin}function Ze(e){let n=JSON.stringify({type:ba,requestId:e.requestId,ok:e.ok,body:e.body??null,error:e.error??null}),t=JSON.stringify(er(e.hubOrigin));return`<!DOCTYPE html><html><head><meta charset="utf-8"></head><body><script>
|
|
2
|
+
(function () {
|
|
3
|
+
var message = ${n};
|
|
4
|
+
var targetOrigin = ${t};
|
|
5
|
+
if (window.parent && window.parent !== window) {
|
|
6
|
+
window.parent.postMessage(message, targetOrigin);
|
|
7
|
+
}
|
|
8
|
+
})();
|
|
9
|
+
</script></body></html>`}var ka=new Set(["localhost","127.0.0.1","[::1]","::1"]);function nr(e){try{let{hostname:n,protocol:t}=new URL(e);return t!=="http:"&&t!=="https:"?!1:ka.has(n)}catch{return!1}}function bn(e){return e==="development"?"browser":"server"}function jo(e){return bn(e)==="browser"}function Ko(e){return nr(e)?"Production delivery URL must be a public URL, not localhost":null}import{randomBytes as Ta}from"crypto";var Te=60*1e3,Me=300*1e3;import{createHmac as wa,randomBytes as Ca,timingSafeEqual as va}from"crypto";function le(){return Ca(16).toString("base64url")}function kn(e,n){let t=n.trim();if(!t)throw new Error("Signing secret is required");return wa("sha256",t).update(e).digest("base64url")}function ie(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=kn(o,t);try{if(!va(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 Gn(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=kn(i,n);return`${i}.${s}`}function wn(e,n,t){let r=Math.floor(Date.now()/1e3);return Gn(e,n,r+Math.floor(t/1e3))}function He(e){return decodeURIComponent(e)}function tr(e){return encodeURIComponent(e).replace(/\./g,"%2E")}function qo(e){let n=e.trim();return n.length>0?n:null}function Ge(e,n){let t=new URL(e);return t.searchParams.set("d",n),t.toString()}function ze(e,n){if(!qo(n))throw new Error("Signing secret is required for browser delivery tokens");let t=Math.floor(Date.now()/1e3),r={...e,jti:e.jti??Ta(16).toString("base64url"),iat:t,exp:t+Math.floor(Te/1e3)},o=Buffer.from(JSON.stringify(r)).toString("base64url"),i=kn(o,n);return`${o}.${i}`}function Pe(e,n){return qo(n)?ie(e,n):null}function Aa(e){let n=er(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 rr(e){let n=ze(Aa(e),e.signingSecret);return Ge(e.deliveryUrl,n)}function Zo(e){if(bn(e.environmentSlug)==="server")return{transport:"server"};if(!e.hubOrigin)throw new Error(`hubOrigin is required for development ${e.deliveryMode} delivery`);let t=Pa(),r={...e,hubOrigin:e.hubOrigin,requestId:t};return{transport:"browser",requestId:t,deliveryUrl:rr(r)}}var Cn="https://auth.corsair.dev";var de=class extends Error{constructor(){super("Hub is not configured. Pass hub: { projectApiKey, signingSecret } to createCorsair()."),this.name="HubNotConfiguredError"}},vn=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 or(e){let n=(e.apiUrl?.trim()||Cn).replace(/\/$/,""),t=e.projectApiKey?.trim()??"",r=e.signingSecret?.trim()??"";if(!t||!r)throw new vn;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 zn(e){return or(e)}function Ra(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||!Ra(n))throw new de;return n}function Go(e){return e.replace(/\/$/,"")}function Jn(e){return e.oauthCallbackUrl?Go(e.oauthCallbackUrl.trim()):`${Go(e.apiUrl)}/oauth/callback`}function Je(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 zo,createDecipheriv as Jo,randomBytes as Vn,scrypt as xa}from"crypto";import{promisify as Ia}from"util";var Vo=Ia(xa),Yn="aes-256-gcm",Yo=12,Xn=16,Sa=16,Be=32;function pe(){return Vn(Be).toString("base64")}async function ge(e,n){let t=Vn(Sa),r=await Vo(n,t,Be),o=Vn(Yo),i=zo(Yn,r,o,{authTagLength:Xn}),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"),u=Buffer.from(o,"base64"),l=Buffer.from(i,"base64"),c=await Vo(n,s,Be),d=Jo(Yn,c,a,{authTagLength:Xn});return d.setAuthTag(u),Buffer.concat([d.update(l),d.final()]).toString("utf8")}function ir(e,n){let t=Buffer.from(n,"base64"),r=Vn(Yo),o=zo(Yn,t,r,{authTagLength:Xn}),i=Buffer.concat([o.update(e,"utf8"),o.final()]),s=o.getAuthTag();return[r.toString("base64"),s.toString("base64"),i.toString("base64")].join(":")}function Tn(e,n){let[t,r,o]=e.split(":");if(!t||!r||!o)throw new Error("Invalid encrypted data format");let i=Buffer.from(n,"base64"),s=Buffer.from(t,"base64"),a=Buffer.from(r,"base64"),u=Buffer.from(o,"base64"),l=Jo(Yn,i,s,{authTagLength:Xn});return l.setAuthTag(a),Buffer.concat([l.update(u),l.final()]).toString("utf8")}function Ae(e,n){let t={};for(let[r,o]of Object.entries(e))t[r]=ir(o,n);return t}function fe(e,n){let t={};for(let[r,o]of Object.entries(e))t[r]=Tn(o,n);return t}function Pn(e,n,t){let r=fe(e,n);return Ae(r,t)}function Xo(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 sr=e=>{if(!e)return{};if(typeof e=="string")try{return JSON.parse(e)}catch{return{}}return e};function N(e){let{authType:n,integrationName:t,kek:r,database:o,extraIntegrationFields:i=[]}=e,s=[...L[n].integration,...i],a=null,u={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:sr(k.config),dek:k.dek??null},a},updateIntegration:async k=>{let b=await u.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,c=async()=>{if(l)return l;let k=await u.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 u.getIntegration(),b=await c(),C=k.config;return!C||Object.keys(C).length===0?{}:fe(C,b)},p=Promise.resolve(),g=k=>{let b=p.then(()=>f(k));return p=b.catch(()=>{}),b},f=async k=>{let b=await c(),C;try{C=await d()}catch(E){console.error(`[corsair] Failed to decrypt config for integration "${t}", starting fresh:`,E),C={}}let T={...C};for(let[E,M]of Object.entries(k))M===null?delete T[E]:T[E]=M;let D=Ae(T,b);await u.updateIntegration({config:D})};return{get_dek:c,issue_new_dek:async()=>{let k=await u.getIntegration(),b=pe(),C={};if(k.dek){let D=await Y(k.dek,r),E=k.config;E&&Object.keys(E).length>0&&(C=Pn(E,D,b))}let T=await ge(b,r);return await u.updateIntegration({config:C,dek:T}),l=b,b},...Xo(d,g,s)}}function H(e){let{authType:n,integrationName:t,tenantId:r,kek:o,database:i,extraAccountFields:s=[],ensureProvisioned:a}=e,u=[...L[n].account,...s],l=null,c=null,d=async()=>{if(c)return c;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 c={id:A.id,config:sr(A.config),dek:A.dek??null},c}},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:sr(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?{}:fe(R,A)},C=async()=>{let w=await p.getIntegration(),A=await k(),R=w.config;return!R||Object.keys(R).length===0?{}:fe(R,A)},T=Promise.resolve(),D=w=>{let A=T.then(()=>E(w));return T=A.catch(()=>{}),A},E=async w=>{let A=await h(),R;try{R=await b()}catch(S){console.error(`[corsair] Failed to decrypt config for account (tenant: "${r}", integration: "${t}"), starting fresh:`,S),R={}}let z={...R};for(let[S,te]of Object.entries(w))te===null?delete z[S]:z[S]=te;let ce=Ae(z,A);await p.updateAccount({config:ce})},M={get_dek:h,issue_new_dek:async()=>{let w=await p.getAccount(),A=pe(),R={};if(w.dek){let ce=await Y(w.dek,o),S=w.config;S&&Object.keys(S).length>0&&(R=Pn(S,ce,A))}let z=await ge(A,o);return await p.updateAccount({config:R,dek:z}),g=A,A},...Xo(b,D,u)};return n==="oauth_2"&&(M.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}}),M}async function Qo(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=pe(),i=await ge(o,t);return await e.db.updateTable("corsair_integrations").set({dek:i,updated_at:new Date}).where("id","=",r.id).execute(),o}async function ei(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=pe(),a=await ge(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 Re(e){return _a.has(e)}function Ea(e,n){return Re(n)?!1:e==="oauth_2"?n==="client_id"||n==="client_secret":!0}function Da(e){return!Re(e)}function Oa(e){switch(e){case"oauth_2":case"managed":return["access_token"];case"api_key":return["api_key"];case"bot_token":return["bot_token"]}}function Ma(e,n){return e!=="oauth_2"&&e!=="managed"?!1:n.some(t=>t.level==="account"&&t.name==="expires_at"&&t.configured)}function Ha(e,n){let t=i=>n.find(s=>s.level==="account"&&s.name===i);if(!Oa(e).every(i=>t(i)?.configured))return!1;let o=t("refresh_token");return o?.required?!!o.configured:!0}async function ni(e,n){if(!e)return!1;let t=G(e,`get_${n}`);if(!t)return!1;try{let r=await t();return typeof r=="string"&&r.length>0}catch{return!1}}function Ba(e,n){let r=e.authConfig?.[n]?.integration??[];return[...L[n].integration,...r]}function Fa(e,n){let r=e.authConfig?.[n]?.account??[];return[...L[n].account,...r]}function Na(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:Ha(n,t),fields:t,missingRequiredFields:r}}async function Fe(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??[],u=N({authType:r,integrationName:n.id,kek:e.kek,database:e.database,extraIntegrationFields:s}),l=H({authType:r,integrationName:n.id,tenantId:o,kek:e.kek,database:e.database,extraAccountFields:a}),c=Ba(n,r),d=Fa(n,r),p=[];for(let g of c)p.push({name:g,level:"integration",required:Ea(r,g),configured:await ni(u,g)});for(let g of d)p.push({name:g,level:"account",required:Da(g),configured:await ni(l,g)});if(Ma(r,p)){let g=p.find(f=>f.level==="account"&&f.name==="refresh_token");g&&(g.required=!0)}return Na(n.id,r,p)}async function An(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 Fe(e,s,r);a&&i.push(a)}return i}function Qn(e){return e.connected?"connected":e.status==="missing_integration"?"missing_credentials":"not_connected"}var ti=Symbol.for("corsair:internal"),ri=new WeakMap,oi=new WeakMap;function Ua(e,n){let t=n.map(r=>r.id).sort().join("\0");return`${e}\0${t}`}function La(e){if(e.database){let t=ri.get(e.database);return t||(t=new Map,ri.set(e.database,t)),t}let n=oi.get(e);return n||(n=new Map,oi.set(e,n)),n}function $a(e){return e.multiTenancy?{withTenant:()=>({}),[ti]:e}:{[ti]:e}}async function Ve(e,n){if(!e.database)return;let t=n.trim()||"default",r=La(e),o=Ua(t,e.plugins),i=r.get(o);if(i){await i;return}let s=(async()=>{let{setupCorsair:a}=await import("./setup-KEZWK5UF.js");await a($a(e),{tenantId:e.multiTenancy?t:void 0,silent:!0})})().finally(()=>{r.delete(o)});r.set(o,s),await s}import*as Rn from"crypto";function xe(e,n){return Buffer.from(JSON.stringify({plugin:e,tenantId:n,iat:Date.now()})).toString("base64url")}function ar(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 Ye(e,n){let t=Rn.createHmac("sha256",n).update(e).digest("base64url");return`${e}.${t}`}var ur=600*1e3;function et(e,n){let t=e.lastIndexOf(".");if(t===-1)return null;let r=e.slice(0,t),o=e.slice(t+1),i=Rn.createHmac("sha256",n).update(r).digest("base64url"),s=Buffer.from(o,"base64url"),a=Buffer.from(i,"base64url");return s.length!==a.length||!Rn.timingSafeEqual(s,a)?null:ar(r,{maxAgeMs:ur})}function ii(e){return{tenantId:e.tenantId,plugin:e.plugin,authType:e.authType??"oauth_2",status:"ready",connected:!0,verified:!0,webhookLink:e.link}}function si(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 Xe(e,n){await x({hub:e,path:"/connections/report",body:ii(n),parseResponse:()=>({ok:!0})}).catch(()=>{})}function Wa(e,n){try{let t=F(e);x({hub:t,path:"/connections/report",body:n,parseResponse:()=>({ok:!0})}).catch(()=>{})}catch(t){if(t instanceof de)return}}async function ja(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 Fe(n,e.plugin,r);o&&ui(e.hub,si({tenantId:r,plugin:e.plugin.id,authType:o.authType,status:o.status,connected:o.connected,verified:e.verified??o.connected,missingFields:o.missingRequiredFields}))}function ai(e,n){Wa(e,n)}function ui(e,n){x({hub:e,path:"/connections/report",body:n,parseResponse:()=>({ok:!0})}).catch(()=>{})}function xn(e){ja(e).catch(()=>{})}async function ye(e,n){let t=v(e);if(!I(n.plugin))return;let o=await Fe(t,n.plugin,n.tenantId);o&&ai(e,si({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 nt(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 ci=e=>{if(!e)return{};if(typeof e=="string")try{return JSON.parse(e)}catch{return{}}return e};async function Ka(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 qa(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=ci(n.config),o={};Object.keys(r).length>0&&(o=fe(r,t)),o[e.link.linkType]=e.link.externalId;let i=Ae(o,t);await e.database.db.updateTable("corsair_accounts").set({config:i,updated_at:new Date}).where("id","=",n.id).execute()}async function Qe(e){let{database:n,kek:t,pluginId:r,tenantId:o,link:i,authType:s,extraAccountFields:a=[]}=e,{accountId:u}=await Ka({database:n,pluginId:r,tenantId:o}),l=!1;if(s){let c=H({authType:s,integrationName:r,tenantId:o,kek:t,database:n,extraAccountFields:a}),d=`set_${i.linkType}`,p=c[d];typeof p=="function"&&(await p(i.externalId),l=!0)}l||await qa({database:n,kek:t,accountId:u,link:i})}async function cr(e){let{database:n,kek:t,pluginId:r,linkType:o,externalId:i}=e,s=await n.db.selectFrom("corsair_accounts as accounts").innerJoin("corsair_integrations as integrations","integrations.id","accounts.integration_id").selectAll("accounts").where("integrations.name","=",r).execute();for(let a of s)if(a.dek)try{let u=await Y(a.dek,t),c=ci(a.config)[o];if(!c)continue;if(Tn(c,u)===i)return a}catch{continue}return null}async function tt(e){return(await cr(e))?.tenant_id??null}async function li(e){return tt({database:e.database,kek:e.kek,pluginId:e.pluginId,linkType:e.match.linkType,externalId:e.match.externalId})}import*as di from"querystring";function Ne(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}?${di.stringify(i)}`}async function pi(e,n){try{return await $({hub:e,path:`/webhooks/endpoint?plugin=${encodeURIComponent(n)}`,parseResponse:t=>t?.url??null})}catch{return null}}async function en(e,n,t,r){if(!n.subscribe)return;let o=F(e),i=await pi(o,n.id);if(!i)return;let s=await n.subscribe({keys:r},{webhookUrl:i});s&&await ye(e,{plugin:n,tenantId:t,verified:!0,webhookLink:s.webhookLink,webhookSecret:s.webhookSecret})}var j=class extends Error{code;constructor(n,t){super(t),this.name="OAuthCallbackError",this.code=n}};function gi(e){let n=e.oauthConfig;if(!n)throw new j("plugin_has_no_oauth_config",`Plugin '${e.id}' has no oauthConfig`);return n}async function Za(e,n,t,r){let o=Ho(e),i=await o.integrations.findByName(n);if(!i)throw new Error(`Integration '${n}' not found. Run setupCorsair first.`);if(await o.accounts.findOne({tenant_id:t,integration_id:i.id}))return;let a=pe(),u=await ge(a,r);await o.accounts.create({tenant_id:t,integration_id:i.id,config:{},dek:u})}async function lr(e,n,t){let{tenantId:r,redirectUri:o,hubConnect:i=!1}=t,s=v(e,()=>new j("invalid_corsair_instance","Invalid corsair instance"));if(!s.database)throw new Error("No database configured on corsair instance");let a=W(s,n,p=>new j("plugin_not_found",p)),u=gi(a),c=await N({authType:"oauth_2",integrationName:n,kek:s.kek,database:s.database}).get_client_id();if(!c)throw new Error(`client_id not configured for '${n}'`);if(i){let p=new URL(Ne({oauthConfig:u,clientId:c,redirectUri:o,state:""}));return p.searchParams.delete("state"),{url:p.toString(),state:""}}let d=Ye(xe(n,r),s.kek);return{url:Ne({oauthConfig:u,clientId:c,redirectUri:o,state:d}),state:d}}function Ga(e,n){return{...n??{},...e}}async function In(e,n){let{code:t,state:r,redirectUri:o}=n,i=v(e,()=>new j("invalid_corsair_instance","Invalid corsair instance")),s,a;if(n.trusted){if(!n.plugin||!n.tenantId)throw new j("invalid_state","trusted callback requires plugin and tenantId");s=n.plugin,a=n.tenantId}else{let h=et(r,i.kek);if(!h)throw new j("invalid_state","Invalid or tampered state parameter");s=h.plugin,a=h.tenantId}if(!i.database)throw new j("no_database","No database configured on corsair instance");let u=W(i,s,h=>new j("plugin_not_found",h)),l=gi(u),c=N({authType:"oauth_2",integrationName:s,kek:i.kek,database:i.database}),d=await c.get_client_id(),p=await c.get_client_secret();if(!d||!p)throw new j("credentials_not_configured",`Credentials not configured for '${s}'`);await Za(i.database,s,a,i.kek);let g=await rt(t,d,p,l,o);if(!g.access_token)throw new j("no_access_token",`No access_token returned from ${l.providerName}`);let f=H({authType:"oauth_2",integrationName:s,tenantId:a,kek:i.kek,database:i.database,extraAccountFields:[...u.authConfig?.oauth_2?.account??[]]});await f.set_access_token(g.access_token),g.refresh_token&&await f.set_refresh_token(g.refresh_token),g.expires_in&&await f.set_expires_at(String(Math.floor(Date.now()/1e3)+g.expires_in)),await ye(e,{plugin:u,tenantId:a}).catch(()=>{});try{let h=Ga(g,n.callbackParams),k=await nt(i.plugins,s,h);if(k){try{let b=u.authConfig?.oauth_2?.account??[];await Qe({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&&Xe(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(u.subscribe)try{await en(e,u,a,f)}catch(h){console.warn(`[corsair:oauth] BYO subscribe failed for '${s}' tenant '${a}':`,h)}return{plugin:s,tenantId:a}}async function za(e){let{corsair:n,internal:t,rows:r}=e,o=e.subscribeAndReport??en,i=[],s=[];if(!t.database)return{renewed:i,failed:s};for(let a of r){let u=t.plugins.find(c=>c.id===a.integrationName);if(!u?.subscribe)continue;let l=`${u.id}/${a.tenantId}`;try{let c=I(u)??"oauth_2",d=H({authType:c,integrationName:u.id,tenantId:a.tenantId,kek:t.kek,database:t.database,extraAccountFields:[...u.authConfig?.[c]?.account??[]]}),p=u.keyBuilder;if(p){let g=Object.create(d,{get_expires_at:{value:async()=>"0"}});await p({authType:c,keys:g,hub:t.hub},"endpoint")}await o(n,u,a.tenantId,d),i.push(l)}catch(c){console.warn(`[corsair:renewal] re-subscribe failed for '${l}':`,c),s.push(l)}}return{renewed:i,failed:s}}async function fi(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 za({corsair:e,internal:n,rows:t.filter(r=>!!r.tenantId)})}function Ja(e,n={}){let t=!1,r=()=>{t||(t=!0,fi(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 yi(e){if(!v(e).database)throw new Error("A database must be configured to provision Corsair integrations");await ot(e,{silent:!0})}async function nn(e,n){let t=v(e);if(!t.database)throw new Error("A database must be configured to provision Corsair for connect");await Ve(t,n)}var Va=Symbol.for("corsair:internal"),Ya=new Set(["access_token","refresh_token","expires_at","scope"]);function Xa(e){return e==="oauth_2"||e==="managed"?"oauth":e==="bot_token"?"bot_token":"api_key"}function Qa(e,n){return e==="oauth_2"||e==="managed"?n.filter(t=>!Re(t)&&!Ya.has(t)):n.filter(t=>!Re(t))}function mi(e){return{plugins:e.plugins,database:e.database,kek:e.kek,multiTenancy:e.multiTenancy??!1}}function eu(e){return{plugins:e.plugins,database:e.database,kek:e.kek,multiTenancy:e.multiTenancy??!1}}function nu(e){return{[Va]:mi(e)}}async function it(e,n,t={}){let r=Jn(e.hub),o=[],i=t.pluginIds?new Set(t.pluginIds):null,s=mi(e),a=nu(e);for(let u of e.plugins){if(i&&!i.has(u.id))continue;let l=I(u);if(!l)continue;let c=Xa(l),d=t.providerNameOverrides?.[u.id]??ve(u.id),p=await Fe(s,u,n),g=Ln(u,l),f=Qa(l,g),h={plugin:u.id,providerName:d,authKind:c,alreadyConfigured:p?.connected??!1};if(f.length>0&&(h.credentialFields=f),c==="oauth"){let b=t.oauthModeOverrides?.[u.id]??(l==="managed"?"managed":"byo");if(h.oauthMode=b,!t.skipOAuthUrlGeneration&&b!=="managed")try{let C=await lr(a,u.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 ${u.id}`)}}o.push(h)}return o}async function Up(e,n,t={}){let r=v(e),o=r.hub;if(!o)throw new Error("Hub is not configured");return it({plugins:r.plugins,database:r.database,kek:r.kek,hub:o},n,t)}async function hi(e,n){if(!e.database)throw new Error("A database must be configured to provision Corsair for connect");await Ve(e.internalConfig??eu(e),n)}async function bi(e,n){await nn(e,n)}async function ki(e,n){let t=Je(e.projectApiKey),r={tenantId:n.tenantId,plugins:n.plugins};return e.redirectURL&&(r.redirectUri=e.redirectURL),t==="development"&&(r.deliveryUrl=we({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:Wn})}async function dr(e,n){let t={plugins:n.plugins,database:n.database,kek:n.kek,hub:e,multiTenancy:n.multiTenancy};await hi(t,n.tenantId);let r=await it(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 ki(e,{tenantId:n.tenantId,plugins:r,deliveryUrl:n.deliveryUrl})}async function st(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 bi(e,n.tenantId);let i=n.plugin?[n.plugin]:void 0,s=n.plugin&&n.oauthMode?{[n.plugin]:n.oauthMode}:void 0,a=n.plugin&&n.providerName?{[n.plugin]:n.providerName}:void 0,u=await it(o,n.tenantId,{pluginIds:i,oauthModeOverrides:s,providerNameOverrides:a});if(u.length===0)throw new Error(n.plugin?`Plugin '${n.plugin}' is not configured on this Corsair instance`:"No plugins are configured on this Corsair instance");return ki(r,{tenantId:n.tenantId,plugins:u,deliveryUrl:n.deliveryUrl})}async function at(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 tu(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 tu(e,n,t){let{buildConnectPluginManifestFromContext:r,ensureConnectAccountRowsFromContext:o}=await import("./setup-introspect-UOQO3JTV.js"),{postHubConnectSession:i}=await import("./connect-JBFEIF2J.js"),s={plugins:n.plugins,database:n.database,kek:n.kek,hub:e,multiTenancy:n.multiTenancy};await o(s,t.tenantId);let a=await r(s,t.tenantId,{pluginIds:t.pluginIds});if(a.length===0)throw new Error("No connectable plugins found for this tenant");let u=a.find(l=>l.setupError);if(u)throw new Error(u.setupError??`Could not prepare connect link for ${u.plugin}`);return i(e,{tenantId:t.tenantId,plugins:a})}function tn(e){return!!(e?.baseUrl?.trim()&&e?.redirectUri?.trim())}var X=class extends Error{code;constructor(n,t){super(t),this.name="ConnectError",this.code=n}};function ru(e){let n=e.oauthConfig;if(!n)throw new X("plugin_has_no_oauth_config",`Plugin '${e.id}' has no oauthConfig`);return n}async function pr(e,n){let t=v(e,()=>new X("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new X("no_database","No database configured on corsair instance");let r=t.manual?.redirectUri;if(!r)throw new X("no_redirect_uri","No redirectUri configured. Set manual.redirectUri in createCorsair().");let o=et(n,t.kek);if(!o)throw new X("invalid_state","Invalid or tampered state parameter");let{plugin:i,tenantId:s}=o,a=W(t,i,p=>new X("plugin_not_found",p)),u=ru(a),c=await N({authType:"oauth_2",integrationName:i,kek:t.kek,database:t.database}).get_client_id();if(!c)throw new X("client_id_not_configured",`client_id not configured for '${i}'`);let d=Ne({oauthConfig:u,clientId:c,redirectUri:r,state:n});return{plugin:i,tenantId:s,providerName:u.providerName,oauthUrl:d,state:n}}import{AsyncLocalStorage as iu}from"async_hooks";import{randomBytes as su}from"crypto";import{v4 as au}from"uuid";async function ut(e,n){let t=Je(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=we({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:Kn})}function ct(e){return`Approval required. Visit ${e} to approve or deny, then tell the agent to retry this action.`}var gr="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 yr(e){return e?e.approvalBaseUrl!==void 0||e.onApprovalRequired!==void 0:!1}function wi(e,n){return`${e.replace(/\/+$/,"")}/${n}`}function fr(e){return ct(e)}async function mr(e,n){if(yr(e.manual)){let r=e.manual?.approvalBaseUrl?.trim();return r?wi(r,n.token):null}let t=e.hub;if(!t)return null;try{return(await ut(t,{permissionId:n.id,permissionToken:n.token,plugin:n.plugin,endpoint:n.endpoint,args:ou(n.args),tenantId:n.tenant_id,expiresAt:n.expires_at})).approvalUrl}catch{return null}}function ou(e){try{return JSON.parse(e)}catch{return e}}async function lt(e,n){if(!(n.status==="pending"||n.status==="approved"))return{...n,approvalUrl:null};let r=await mr(e,n);return{...n,approvalUrl:r}}async function hr(e){let{permissionsOptions:n,manual:t,hub:r,permissionId:o,permissionToken:i,plugin:s,endpoint:a,args:u,tenantId:l,expiresAt:c,operationPath:d}=e;if(n?.formatAsyncMessage)return n.formatAsyncMessage({token:i,id:o,plugin:s,endpoint:a,args:u});let g=await mr({manual:t,hub:r},{id:o,token:i,plugin:s,endpoint:a,args:JSON.stringify(u),tenant_id:l,expires_at:c});return yr(t)?g?t?.onApprovalRequired?t.onApprovalRequired({approvalUrl:g}):fr(g):gr:r?g?fr(g):`Action '${d}' requires user approval before it can run. Could not create approval link. Check hub configuration and server logs.`:gr}var rn=class extends Error{constructor(n){super(n),Object.setPrototypeOf(this,new.target.prototype),this.name="PermissionRequiredError"}};var vi=new iu,dt=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 br(e){return vi.run(!0,e)}function Ti(){return vi.getStore()===!0}function kr(e,n){if(Ti()&&n!=="read")throw new dt(e,n)}var uu={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 cu(e,n,t){return t!==void 0?t:uu[n][e]}function wr(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 Pi(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 Ci(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 Ai(e){let n=cu(e.riskLevel,e.mode,e.override);if(n==="allow")return{result:"allow"};let t=e.meta?.irreversible?" (irreversible)":"",r=e.meta?.description?`${e.meta.description}${t}`:`${e.pluginId}.${e.endpointPath}${t}`;if(n==="deny"||!e.db)return console.log(`[corsair/${e.pluginId}] '${e.endpointPath}' blocked \u2014 denied by permission mode '${e.mode}'.`,`
|
|
10
|
+
Action: ${r}`,`
|
|
11
|
+
To allow this, update the permission mode or add an override in your corsair config.`),{result:"blocked",reason:"policy"};let o=JSON.stringify(e.args),i=new Date().toISOString(),s=e.tenantId??"default",a=await e.db.db.selectFrom("corsair_permissions").selectAll().where("plugin","=",e.pluginId).where("endpoint","=",e.endpointPath).where("args","=",o).where("tenant_id","=",s).where("expires_at",">",i).where("status","in",["pending","approved","executing"]).orderBy("created_at","desc").limit(1).executeTakeFirst();if(a){if(a.status==="approved"){let f=e.db,h=a.id;return{result:"allow",onComplete:async()=>{await f.db.updateTable("corsair_permissions").set({status:"completed",updated_at:new Date}).where("id","=",h).execute()}}}return a.status==="executing"?{result:"allow"}:(console.log(`[corsair/${e.pluginId}] '${e.endpointPath}' blocked \u2014 approval already pending.`,`
|
|
12
|
+
Action: ${r}`,`
|
|
13
|
+
Permission ID: ${a.id}`,`
|
|
14
|
+
Use the token to approve or deny this request.`),(typeof e.approvalMode=="function"?e.approvalMode():e.approvalMode)==="synchronous"?Ci(e.db,a.id,e.timeoutMs??600*1e3):{result:"blocked",reason:"pending",id:a.id,token:a.token,expiresAt:a.expires_at})}let u=au(),l=su(32).toString("hex"),c=e.timeoutMs??600*1e3,d=new Date(Date.now()+c).toISOString();return await e.db.db.insertInto("corsair_permissions").values({id:u,created_at:new Date,updated_at:new Date,token:l,plugin:e.pluginId,endpoint:e.endpointPath,args:o,tenant_id:s,status:"pending",expires_at:d}).execute(),console.log(`[corsair/${e.pluginId}] '${e.endpointPath}' blocked \u2014 approval required.`,`
|
|
15
|
+
Action: ${r}`,`
|
|
16
|
+
Permission ID: ${u}`,`
|
|
17
|
+
Permission token: ${l}`,`
|
|
18
|
+
Expires at: ${d}`,`
|
|
19
|
+
Use the token to approve or deny this request.`),(typeof e.approvalMode=="function"?e.approvalMode():e.approvalMode)==="synchronous"?Ci(e.db,u,c):{result:"blocked",reason:"pending",id:u,token:l,expiresAt:d}}var P=class extends Error{status;code;extra;constructor(n,t,r,o={}){super(r??t),this.name="ManagementApiError",this.status=n,this.code=t,this.extra=o}};function O(e,n){return new Response(JSON.stringify(n),{status:e,headers:{"content-type":"application/json"}})}function se(e){let n={error:e.code,message:e.message,...e.extra};return O(e.status,n)}function Ie(e){return new P(404,"not_found",e)}function me(e,n={}){return new P(400,"bad_request",e,n)}function Ri(e,n){return W(e,n,t=>Ie(t))}async function xi(e,n){let t=e.options?.authType;if(!t||!n.database||!n.kek)return{configured:!1,missingFields:[]};let r=N({authType:t,integrationName:e.id,kek:n.kek,database:n.database}),o=L[t].integration,i=r,s;try{s=await Promise.all(o.map(l=>i[`get_${l}`]()))}catch{s=o.map(()=>null)}let a=o.filter((l,c)=>s[c]==null),u;return t==="oauth_2"?u=!a.includes("client_id")&&!a.includes("client_secret"):u=a.length===0,{configured:u,missingFields:a}}async function Ii(e,n){let t=e.options?.authType??null,r=e.oauthConfig,{configured:o,missingFields:i}=await xi(e,n);return{id:e.id,authType:t,configured:o,missingFields:i,oauth:r?{providerName:r.providerName,scopes:r.scopes,requiresRegisteredRedirect:!!r.requiresRegisteredRedirect}:null}}function pt(){return{ok:!0}}async function on(e){return Promise.all(e.plugins.map(n=>Ii(n,e)))}async function gt(e,n){let t=Ri(e,n);return Ii(t,e)}async function lu(e,n){return e.database?(await e.database.db.selectFrom("corsair_accounts as a").innerJoin("corsair_integrations as i","i.id","a.integration_id").select(["a.id as accountId","a.dek as dek","i.name as integrationName"]).where("a.tenant_id","=",n).execute()).map(r=>({integrationName:r.integrationName,hasCredentials:!!r.dek})):[]}async function Si(e,n){let t=await lu(e,n),r=t.filter(o=>o.hasCredentials).map(o=>o.integrationName);return{id:n,accounts:t,connectedPlugins:r}}async function sn(e){let n=new Map;if(n.set("default",{id:"default",accounts:[],connectedPlugins:[]}),e.database){let t=await e.database.db.selectFrom("corsair_accounts as a").innerJoin("corsair_integrations as i","i.id","a.integration_id").select(["a.tenant_id","a.dek as dek","i.name as integrationName"]).execute();for(let r of t){let o=r.tenant_id;if(!o)continue;let i=n.get(o);i||(i={id:o,accounts:[],connectedPlugins:[]},n.set(o,i));let s=!!r.dek;i.accounts.push({integrationName:r.integrationName,hasCredentials:s}),s&&i.connectedPlugins.push(r.integrationName)}}return[...n.values()]}async function ft(e,n){if(!n)throw me("Tenant id must be a non-empty string");return Si(e,n)}async function yt(e,n){let t=n?.id?.trim();if(!t)throw me("Tenant id is required",{missingFields:["id"]});return Si(e,t)}async function mt(e,n){let t=n?.trim()||"default",r={},o=await An(e,t);for(let i of o)r[i.plugin]=Qn(i);for(let i of e.plugins)i.id in r||(!i.options?.authType||!e.database||!e.kek?r[i.id]="missing_credentials":r[i.id]="not_connected");return r}async function Cr(e,n){if(!e.database)throw Ie(`Permission '${n}' not found`);let t=await e.database.db.selectFrom("corsair_permissions").selectAll().where("id","=",n).executeTakeFirst();if(!t)throw Ie(`Permission '${n}' not found`);return lt(e,t)}function du(e){if(!e.oauthConfig)throw me(`Plugin '${e.id}' has no oauthConfig`)}function pu(e){if(!e.manual)throw new P(500,"connect_not_configured","createCorsair was not given manual config. Set { manual: { baseUrl, redirectUri } } to enable manual connect routes.");return e.manual}function vr(e){let n=pu(e);if(!n.baseUrl?.trim()||!n.redirectUri?.trim())throw new P(500,"connect_not_configured","Manual connect requires manual.baseUrl and manual.redirectUri. Use hub for hosted connect, or set both URLs for manual OAuth.");return n}function gu(e){let n=!!e.hub,t=tn(e.manual);if(!n&&!t)throw new P(500,"connect_not_configured","createCorsair was not given connect config. Set hub: { ... } for Hub mode, or manual: { baseUrl, redirectUri } for manual connect.")}function _i(e){if(!e.database||!e.kek)throw new P(500,"database_not_configured","A database and kek are required to issue connect links.")}async function fu(e,n){let t=n?.plugin?.trim();if(!t)throw me("Plugin id is required",{missingFields:["plugin"]});let r=n.tenantId?.trim()||"default",o=Ri(e,t);du(o);let i=vr(e);_i(e);let s=await xi(o,e);if(!s.configured)throw new P(400,"missing_credentials",`Plugin '${t}' is missing OAuth client credentials`,{missingFields:s.missingFields});let a=Ye(xe(t,r),e.kek),u;try{u=new URL(i.baseUrl)}catch{throw new P(500,"connect_misconfigured","manual.baseUrl is not a valid URL. Set a full URL including protocol (e.g. https://app.example.com/connect).")}return u.searchParams.set("state",a),{connectUrl:u.toString(),expiresAt:new Date(Date.now()+ur).toISOString()}}async function yu(e,n,t){_i(n);let o={tenantId:t.tenantId?.trim()||"default",oauthMode:t.oauthMode},i=t.plugin?.trim();i&&(o.plugin=i);let s=t.providerName?.trim();s&&(o.providerName=s);let a=await st(e,o);return{connectUrl:a.connectUrl,expiresAt:a.expiresAt}}async function ht(e,n,t){return gu(n),n.hub?yu(e,n,t):fu(n,t)}async function bt(e,n,t){if(n.hub&&!tn(n.manual))throw new P(400,"hub_mode","resolve is not used with hub config. Redirect users to connectUrl from createLink.");let r=t?.trim();if(!r)throw me("state is required",{missingFields:["state"]});vr(n);try{return await pr(e,r)}catch(o){if(o instanceof X)switch(o.code){case"invalid_state":throw me("Invalid or expired state");case"client_id_not_configured":throw new P(400,"missing_credentials","OAuth client_id is not configured for this plugin",{missingFields:["client_id"]});case"no_redirect_uri":break}throw new P(500,"resolve_failed","Could not resolve connect link. Check server logs for details.")}}async function kt(e,n,t){if(n.hub&&!tn(n.manual))throw new P(400,"hub_mode","oauthCallback is not used with hub config. Hub delivers tokens to your deliveryUrl.");let r=t?.code?.trim(),o=t?.state?.trim(),i=[];if(r||i.push("code"),o||i.push("state"),i.length)throw me("Missing required fields",{missingFields:i});let s=vr(n),{processOAuthCallback:a}=await import("./oauth.js");try{return await a(e,{code:r,state:o,redirectUri:s.redirectUri,callbackParams:t.callbackParams})}catch(u){if(u instanceof Error&&u.name==="OAuthCallbackError")switch(u.code){case"invalid_state":throw me("Invalid or expired state");case"credentials_not_configured":throw new P(400,"missing_credentials","OAuth client credentials are not configured for this plugin",{missingFields:["client_id","client_secret"]})}throw new P(502,"oauth_callback_failed","OAuth callback did not complete. Check server logs for details.")}}async function Tr(e,n){if(!e.database)throw Ie("Permission not found");let t=await e.database.db.selectFrom("corsair_permissions").selectAll().where("token","=",n).executeTakeFirst();if(!t)throw Ie("Permission not found");return lt(e,t)}async function Ei(e,n){return"id"in n?Cr(e,n.id):Tr(e,n.token)}import{createCipheriv as vu,createDecipheriv as Kg,randomBytes as Hi,scryptSync as Tu}from"crypto";import{createHmac as Pr,randomUUID as mu,timingSafeEqual as Oi}from"crypto";function Ar(e){return e.run??null}function Rr(e){return e.probe??null}function Mi(e){if(e)return e.startsWith("sha256=")?e.slice(7):e}function wt(e){let n=JSON.stringify({type:e.type,payload:e.payload}),t=Math.floor(Date.now()/1e3).toString(),r=Pr("sha256",e.signingSecret.trim()).update(n).digest("hex");return{body:n,headers:{"content-type":"application/json","x-corsair-signature":`sha256=${r}`,"x-corsair-timestamp":t,"x-corsair-project":e.projectId,"x-corsair-nonce":mu()}}}function xr(e){let n=e.signingSecret.trim();if(!n)return!1;let t=Mi(e.signatureHeader);if(!t)return!1;let r=Number(e.timestampHeader);if(!Number.isFinite(r)||Math.abs(Date.now()-r*1e3)>Me)return!1;let i=Pr("sha256",n).update(e.body).digest("hex");try{return Oi(Buffer.from(i,"utf8"),Buffer.from(t,"utf8"))}catch{return!1}}function an(e){let n=e.signingSecret.trim();if(!n)return{ok:!1,error:"Tunnel signing secret is required"};let t=Mi(e.signatureHeader);if(!t)return{ok:!1,error:"Invalid tunnel signature"};let r=Number(e.timestampHeader);if(!Number.isFinite(r))return{ok:!1,error:"Invalid or missing tunnel timestamp"};if(Math.abs(Date.now()-r*1e3)>Me)return{ok:!1,error:"Tunnel request timestamp is outside the allowed window"};let i=Pr("sha256",n).update(e.body).digest("hex");try{if(!Oi(Buffer.from(i,"utf8"),Buffer.from(t,"utf8")))return{ok:!1,error:"Invalid tunnel signature"}}catch{return{ok:!1,error:"Invalid tunnel signature"}}return{ok:!0}}function un(e){if(!e)return{};try{return JSON.parse(e)}catch{return{}}}function Ct(e){return e.httpOk&&(e.status===204||e.body.status==="ok"||e.body.ok===!0)}function vt(e){let n=e.sync?.encrypted;return typeof n!="string"||!n.trim()?null:{encrypted:n.trim()}}function Sn(e){let n=e.connectUrl?.trim();return n?{connectUrl:n,expiresAt:e.expiresAt}:null}function Ir(e){return Sn(un(e))}async function Sr(e){let n=await At({deliveryUrl:e.deliveryUrl,projectId:e.projectId,signingSecret:e.signingSecret,type:"connect.create_link",payload:{tenantId:e.tenantId,plugins:e.plugins}}),t=un(n.body),r=Ct({httpOk:n.ok,status:n.status,body:t}),o=Sn(t);if(!r||!o)throw new Error(Pt({deliveryUrl:e.deliveryUrl,status:n.status,body:n.body,ack:t}));return o}function Tt(e){return vt(un(e))}function hu(e){let n=e;for(;n;){if(n instanceof Error){let t=n.code;if(typeof t=="string")return t;n=n.cause;continue}if(typeof n=="object"&&n!==null&&"code"in n){let t=n.code;if(typeof t=="string")return t}break}}function Di(e,n=200){let t=e.trim();return t.length<=n?t:`${t.slice(0,n)}\u2026`}var bu="Verify hub.signingSecret in your app matches the signing secret shown in Hub project settings.",ku="Check the delivery URL configured for this environment.";function wu(e){return`${e.ack.error?`${e.ack.error} (HTTP ${e.status} from ${e.deliveryUrl})`:`App rejected the signed delivery (HTTP ${e.status} from ${e.deliveryUrl})`}. ${bu}`}function Cu(e){return`${e.ack.error?`${e.ack.error} (HTTP 404 from ${e.deliveryUrl})`:`Delivery endpoint not found at ${e.deliveryUrl} (HTTP 404)`}. ${ku}`}function _n(e,n){let t=hu(n),r=n instanceof Error?n.message:"Delivery request failed",o;switch(t){case"ECONNREFUSED":o="connection refused \u2014 nothing accepted a TCP connection on that host and port";break;case"ENOTFOUND":o="host not found \u2014 DNS could not resolve the hostname";break;case"ETIMEDOUT":case"UND_ERR_CONNECT_TIMEOUT":o="connection timed out before the app responded";break;case"ECONNRESET":o="connection reset while talking to the app";break;case"CERT_HAS_EXPIRED":case"UNABLE_TO_VERIFY_LEAF_SIGNATURE":case"DEPTH_ZERO_SELF_SIGNED_CERT":o=`TLS certificate error (${t})`;break;default:o=r==="fetch failed"&&t?`${r} (${t})`:r}return[`Could not reach ${e}`,o].join(". ")}function Pt(e){if(e.status===0)return e.ack.error?e.ack.error:e.body.startsWith("Could not reach")?e.body:_n(e.deliveryUrl,new Error(e.body||"Delivery request failed"));if(e.status===401||e.status===403)return wu(e);if(e.status===404)return Cu(e);if(e.ack.error)return`${e.ack.error} (HTTP ${e.status} from ${e.deliveryUrl})`;if(e.status>=500){let t=e.body.trim();return t?`App failed while processing the delivery (HTTP ${e.status} from ${e.deliveryUrl}): ${Di(t)}`:`App failed while processing the delivery (HTTP ${e.status} from ${e.deliveryUrl})`}let n=e.body.trim();return n?`${Di(n)} (HTTP ${e.status} from ${e.deliveryUrl})`:`Delivery failed with HTTP ${e.status} from ${e.deliveryUrl}`}async function At(e){let{body:n,headers:t}=wt(e);try{let r=await fetch(e.deliveryUrl,{method:"POST",headers:t,body:n}),o=await r.text();return{ok:r.ok,status:r.status,body:o}}catch(r){return{ok:!1,status:0,body:_n(e.deliveryUrl,r)}}}var Pu="aes-256-gcm",Au=12,Ru=16,xu=16,Iu=32;function Su(e,n){return Tu(e.trim(),n,Iu)}function _r(e,n){let t=n.trim();if(!t)throw new Error("Signing secret is required to encrypt sync manifest");let r=Hi(xu),o=Su(t,r),i=Hi(Au),s=vu(Pu,o,i,{authTagLength:Ru}),a=JSON.stringify(e),u=Buffer.concat([s.update(a,"utf8"),s.final()]),l=s.getAuthTag();return[r.toString("base64"),i.toString("base64"),l.toString("base64"),u.toString("base64")].join(":")}var _u=["invalid corsair instance","a database must be configured to sync connections from the app","a database must be configured on the corsair instance","signing secret is required to encrypt sync manifest"];function Er(e){if(e instanceof So)return!1;if(!(e instanceof Error))return!0;let n=e.message.toLowerCase();return!_u.some(t=>n.includes(t))}function Eu(e){if(!e)return[];let n=I(e);return n?(e.authConfig?.[n]?.integration??[]).filter(r=>!Re(r)):[]}async function En(e,n){let t=v(e);if(!t.database)throw new Error("A database must be configured to sync connections from the app");await ot(e,{silent:!0});let[r,o]=await Promise.all([sn(t),on(t)]),i={tenants:r.map(s=>({id:s.id})),plugins:o.map(s=>{let a=Eu(t.plugins.find(u=>u.id===s.id));return{id:s.id,authType:s.authType,configured:s.configured,missingFields:s.missingFields,...a.length>0?{integrationCredentialFields:a}:{}}}),syncedAt:new Date().toISOString()};return _r(i,n)}var ae=class extends Error{code;constructor(n,t){super(t),this.name="AuthCredentialsDeliveryError",this.code=n}};async function Rt(e,n){let t=v(e,()=>new ae("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new ae("no_database","Database not configured");let r=W(t,n.plugin,c=>new ae("plugin_not_found",c)),o=I(r);if(!o)throw new ae("invalid_credentials",`Plugin '${r.id}' has no authType configured`);if(o==="oauth_2"||o==="managed")throw new ae("invalid_credentials","OAuth plugins must be connected via sign-in, not credentials delivery");await nn(e,n.tenantId);let i=new Set(Ln(r,o)),a=r.authConfig?.[o]?.account??[],u=H({authType:o,integrationName:n.plugin,tenantId:n.tenantId,kek:t.kek,database:t.database,extraAccountFields:a}),l=0;for(let[c,d]of Object.entries(n.credentials)){if(!d.trim())continue;if(!i.has(c))throw new ae("invalid_credentials",`Unknown credential field '${c}' for plugin '${n.plugin}'`);let p=G(u,`set_${c}`);if(!p)throw new ae("invalid_credentials",`Cannot set credential field '${c}' for plugin '${n.plugin}'`);await p(d.trim()),l+=1}if(l===0)throw new ae("invalid_credentials","Provide at least one credential field to save");return await ye(e,{plugin:r,tenantId:n.tenantId}).catch(()=>{}),{plugin:n.plugin,tenantId:n.tenantId}}var ue=class extends Error{code;constructor(n,t){super(t),this.name="IntegrationCredentialsDeliveryError",this.code=n}};async function Dr(e,n){let t=v(e,()=>new ue("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new ue("no_database","Database not configured");let r=W(t,n.plugin,c=>new ue("plugin_not_found",c)),o=I(r);if(!o)throw new ue("invalid_credentials",`Plugin '${r.id}' has no authType configured`);await yi(e);let i=new Set(Do(r,o)),a=r.authConfig?.[o]?.integration??[],u=N({authType:o,integrationName:n.plugin,kek:t.kek,database:t.database,extraIntegrationFields:a}),l=0;for(let[c,d]of Object.entries(n.credentials)){if(!d.trim())continue;if(!i.has(c))throw new ue("invalid_credentials",`Unknown integration credential field '${c}' for plugin '${n.plugin}'`);let p=G(u,`set_${c}`);if(!p)throw new ue("invalid_credentials",`Cannot set integration field '${c}' for plugin '${n.plugin}'`);await p(d.trim()),l+=1}if(l===0)throw new ue("invalid_credentials","Provide at least one integration credential field to save");return{plugin:n.plugin}}var xt=new Map;function Du(e){for(let[n,t]of xt)t<=e&&xt.delete(n)}function It(e,n){let t=e.trim();if(!t)return{ok:!1,error:"Delivery replay key is required"};if(!Number.isFinite(n)||n<=0)return{ok:!1,error:"Delivery replay TTL must be a positive number"};let r=Date.now();Du(r);let o=xt.get(t);return o!==void 0&&o>r?{ok:!1,error:"Delivery request already consumed"}:(xt.set(t,r+n),{ok:!0})}var Se=class extends Error{code;constructor(n,t){super(t),this.name="ManagedOAuthDeliveryError",this.code=n}};async function cn(e,n){let{plugin:t,tenantId:r,accessToken:o,refreshToken:i,expiresIn:s,scope:a,authType:u="managed",providerData:l}=n;if(!o.trim())throw new Se("no_access_token","Managed OAuth delivery missing access_token");let c=v(e,()=>new Se("invalid_corsair_instance","Invalid corsair instance"));if(!c.database)throw new Se("no_database","No database configured on corsair instance");let d=W(c,t,g=>new Se("plugin_not_found",g));await nn(e,r);let p=H({authType:u,integrationName:t,tenantId:r,kek:c.kek,database:c.database});await p.set_access_token(o),i&&await p.set_refresh_token(i),s&&await p.set_expires_at(String(Math.floor(Date.now()/1e3)+s)),a&&await p.set_scope(a),await ye(e,{plugin:d,tenantId:r}).catch(()=>{});try{let g=await nt(c.plugins,t,{access_token:o,refresh_token:i,scope:a,...l});if(g){try{let f=d.authConfig?.[u]?.account??[];await Qe({database:c.database,kek:c.kek,pluginId:t,tenantId:r,link:g,authType:u,extraAccountFields:f})}catch(f){console.warn(`[corsair:managed-oauth] Failed to persist webhook tenant link for '${t}' tenant '${r}':`,f)}c.hub&&Xe(c.hub,{plugin:t,tenantId:r,link:g,authType:u})}}catch(g){console.warn(`[corsair:managed-oauth] Failed to resolve webhook tenant link for '${t}' tenant '${r}':`,g)}return await en(e,d,r,p).catch(g=>{console.warn(`[corsair:managed-oauth] subscribe failed for '${t}' tenant '${r}':`,g)}),{plugin:t,tenantId:r}}function Ou(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function Bi(e,n,t=[]){for(let[r,o]of Object.entries(e))if(Ou(o)){if(o.match(n))return{webhook:o,path:[...t,r]}}else if(o&&typeof o=="object"){let i=Bi(o,n,[...t,r]);if(i)return i}return null}function Mu(e){let n={};for(let[t,r]of Object.entries(e))n[t.toLowerCase()]=Array.isArray(r)?r[0]:r;return n}function Hu(e){let n=e["x-goog-resource-uri"],t=e["x-goog-channel-id"];if(!n||!t)return null;let r={resourceId:e["x-goog-resource-id"]||"",resourceState:e["x-goog-resource-state"]||"",resourceUri:n,channelId:t,channelExpiration:e["x-goog-channel-expiration"]||""};return n.includes("/drive/")&&(r.kind="drive#change"),{message:{data:Buffer.from(JSON.stringify(r)).toString("base64"),messageId:e["x-goog-message-number"]||""}}}async function Fi(e,n,t,r,o){let i=Mu(n),s=typeof t=="string"?JSON.parse(t):t;(!s||typeof s=="object"&&Object.keys(s).length===0)&&i["x-goog-resource-uri"]&&(s=Hu(i)||s);let u={headers:i,body:s,...r?{query:r}:{}},l=r?.tenantId||"default",c=e.withTenant?e.withTenant(l):e,d=o?.plugin,p=d?[d]:$n;for(let g of p){let f=c[g];if(!f||!f.webhooks||!d&&f.pluginWebhookMatcher&&!f.pluginWebhookMatcher(u))continue;let h=Bi(f.webhooks,u);if(!h)continue;let k=h.path.join("."),b={payload:s,headers:i,rawBody:typeof t=="string"?t:JSON.stringify(t),...r?{query:r}:{},...o?.hubVerified?{hubVerified:!0}:{}};try{let C=await h.webhook.handler(b),T=!!Object.keys(C.returnToSender||{})?.length;return{plugin:g,action:k,body:s,response:T?{...C?.returnToSender,success:!0}:{success:!0},...C.responseHeaders&&{responseHeaders:C.responseHeaders}}}catch(C){return console.error(`Error executing webhook handler for ${g}.${k}:`,C),{plugin:g,action:k,body:s,response:{success:!1,error:C instanceof Error?C.message:"Unknown error"}}}}return{plugin:null,action:null,body:null}}import{createHash as Bu}from"crypto";import*as Ue from"vm";var Ni="__corsairFailedStep",Fu=3e4,Or=class{constructor(n,t){this.wakeAt=n;this.stepName=t}__corsairSleep=!0};function Ui(e){return typeof e=="object"&&e!==null&&e.__corsairSleep===!0}function Li(e,n){return`st_${Bu("sha256").update(`${n} ${e}`).digest("hex").slice(0,16)}`}function St(e){if(e instanceof Error)return e.message;if(e!==null&&typeof e=="object"&&"message"in e){let n=e.message;if(typeof n=="string")return n}return String(e)}var $i=new Set(["constructor","prototype","__proto__"]);function he(e,n){if(e===null)return null;let t=typeof e;return t==="function"?Uu(e,n):t==="object"?Nu(e):e}function Nu(e){return new Proxy(e,{get(n,t){if(!$i.has(t))return he(Reflect.get(n,t,n),n)},getPrototypeOf:()=>null,setPrototypeOf:()=>!1,defineProperty:()=>!1,set:()=>!1,deleteProperty:()=>!1})}function Uu(e,n){return new Proxy(e,{apply:(t,r,o)=>Lu(Reflect.apply(t,n,o)),construct(){throw new Error("Workflow code may not construct host objects")},get(t,r){if(!$i.has(r))return he(Reflect.get(t,r,t),t)},getPrototypeOf:()=>null,setPrototypeOf:()=>!1,defineProperty:()=>!1,set:()=>!1,deleteProperty:()=>!1})}function Lu(e){return e!==null&&typeof e=="object"&&typeof e.then=="function"?Promise.resolve(e).then(n=>he(n,void 0),n=>{throw he(n,void 0)}):he(e,void 0)}function $u(e){let n=Object.create(null),t=Ue.createContext(n,{name:"corsair-workflow",codeGeneration:{strings:!1,wasm:!1}}),o=Ue.runInContext("(s) => JSON.parse(s)",t,{filename:"corsair:sandbox:json"})(JSON.stringify(e.payload??null)),s=Ue.runInContext(`(function (hostRun, hostSleep) {
|
|
20
|
+
const step = function step(name, fn) { return hostRun(name, fn); };
|
|
21
|
+
step.sleep = function sleep(name, ms) { return hostSleep(name, ms); };
|
|
22
|
+
return step;
|
|
23
|
+
})`,t,{filename:"corsair:sandbox:step"})((p,g)=>e.step(p,g),(p,g)=>e.step.sleep(p,g)),u=Ue.runInContext(`(function (sink) {
|
|
24
|
+
const fwd = (level) => function () {
|
|
25
|
+
try { sink(level, Array.prototype.slice.call(arguments)); } catch (_e) {}
|
|
26
|
+
};
|
|
27
|
+
return { log: fwd('log'), info: fwd('info'), warn: fwd('warn'), error: fwd('error'), debug: fwd('debug') };
|
|
28
|
+
})`,t,{filename:"corsair:sandbox:console"})((p,g)=>{let f=console[p]??console.log;try{f(...g)}catch{}});n.__corsair=he(e.corsair,void 0),n.__payload=o,n.__step=s,n.__console=u;let l=Ue.runInContext(`(function () {
|
|
29
|
+
'use strict';
|
|
30
|
+
const module = { exports: {} };
|
|
31
|
+
const require = function (id) {
|
|
32
|
+
throw new Error('Workflow code may not import modules (attempted to require "' + id + '")');
|
|
33
|
+
};
|
|
34
|
+
(function (exports, module, require, console) {
|
|
35
|
+
${e.code}
|
|
36
|
+
})(module.exports, module, require, __console);
|
|
37
|
+
const main = module.exports.main;
|
|
38
|
+
if (typeof main !== 'function') {
|
|
39
|
+
throw new Error('Workflow code must export a \`main\` function');
|
|
40
|
+
}
|
|
41
|
+
return main(__corsair, __payload, __step);
|
|
42
|
+
})()`,t,{filename:"corsair:workflow",timeout:e.timeoutMs});l.catch(()=>{});let c,d=new Promise((p,g)=>{c=setTimeout(()=>g(new Error(`Workflow exceeded ${e.timeoutMs}ms time limit`)),e.timeoutMs)});return Promise.race([l,d]).finally(()=>clearTimeout(c))}async function Mr(e){let n=e.memoizedSteps??{},t=[],r=0,o=null,i=(async(s,a)=>{if(o)throw o;let u=r++,l=Li(s,u);if(Object.hasOwn(n,l))return he(n[l].output,void 0);try{let c=await a();return t.push({stepId:l,name:s,seq:u,status:"completed",output:c}),c}catch(c){if(Ui(c))throw c;let d=St(c);t.push({stepId:l,name:s,seq:u,status:"failed",error:d});let p=new Error(d);throw p[Ni]=s,p}});i.sleep=async(s,a)=>{if(o)throw o;let u=r++,l=Li(s,u);if(Object.hasOwn(n,l))return;t.push({stepId:l,name:s,seq:u,status:"completed",output:null});let c=Number.isFinite(a)?Math.max(0,a):0;throw o=new Or(Date.now()+c,s),o};try{await $u({code:e.code,corsair:e.corsair,payload:e.payload,step:i,timeoutMs:e.timeoutMs??Fu});let s=o;return s?{status:"sleeping",steps:t,sleepUntil:new Date(s.wakeAt).toISOString()}:{status:"completed",steps:t}}catch(s){if(Ui(s))return{status:"sleeping",steps:t,sleepUntil:new Date(s.wakeAt).toISOString()};let a=St(s),u=s!==null&&typeof s=="object"?s[Ni]:void 0;return{status:"failed",steps:t,error:{message:a,...u?{failedStep:u}:{}}}}}import*as _t from"vm";var Wi=1e4;async function Hr(e){let n=Object.create(null),t=_t.createContext(n,{name:"corsair-probe",codeGeneration:{strings:!1,wasm:!1}});n.corsair=he(e.corsair,void 0);let r=ju(e.timeoutMs),o=`(async () => {
|
|
43
|
+
const __result = await (async () => {
|
|
44
|
+
${e.code}
|
|
45
|
+
})();
|
|
46
|
+
return JSON.stringify(__result) ?? 'null';
|
|
47
|
+
})()`;try{let i=await br(()=>{let s=_t.runInContext(o,t,{filename:"corsair:probe",timeout:r});s.catch(()=>{});let a,u=new Promise((l,c)=>{a=setTimeout(()=>c(new Error(`Probe exceeded ${r}ms time limit`)),r)});return Promise.race([s,u]).finally(()=>clearTimeout(a))});return{status:"ok",value:Wu(i)}}catch(i){return{status:"error",error:St(i)}}}function Wu(e){if(typeof e!="string")throw new Error(`Probe returned a non-string result (${typeof e})`);return JSON.parse(e)}function ju(e){return typeof e!="number"||!Number.isFinite(e)||e<=0?Wi:Math.min(e,Wi)}function Le(e){return e.deliveryMode==="auth.credentials"}function Dn(e){return e.deliveryMode==="connections.sync"}function Et(e){return e.deliveryMode==="connect.create_link"}function On(e){return e.deliveryMode==="permission.approve"||e.deliveryMode==="permission.deny"}function Mn(e){return e.deliveryMode==="oauth.tokens"}function Dt(e){return e.deliveryMode==="oauth.callback"||e.deliveryMode===void 0&&!Le(e)&&!Dn(e)&&!Et(e)&&!On(e)&&!Mn(e)}function Ku(e){return{status:"ok",connectLink:{connectUrl:e.connectUrl,expiresAt:e.expiresAt},webhookResponse:{status:200,body:{status:"ok",connectUrl:e.connectUrl,expiresAt:e.expiresAt}}}}async function qu(e,n){try{return{status:"ok",webhookResponse:{status:200,body:{status:"ok",sync:{encrypted:await En(e,n)}}}}}catch(t){return{status:"failed",retryable:Er(t),error:t instanceof Error?t.message:"Connections sync delivery failed"}}}async function Zu(e,n){try{let t=await at(e,n);return Ku(t)}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Connect link delivery failed"}}}function Br(e,n){if(e instanceof Headers)return e.get(n)??void 0;let t=e[n]??e[n.toLowerCase()];return Array.isArray(t)?t[0]:typeof t=="string"?t:void 0}async function Gu(e,n,t){let r=typeof t.tenantId=="string"?t.tenantId:typeof t.query?.tenantId=="string"?t.query.tenantId:void 0;return r||(!n.database||!t.plugin||!t.linkType||!t.externalId?void 0:await tt({database:n.database,kek:n.kek,pluginId:t.plugin,linkType:t.linkType,externalId:t.externalId})??void 0)}async function zu(e,n,t,r){let o=await Gu(e,n,t),i={...t.query??{},...o?{tenantId:o}:{}},s=await Fi(e,t.headers,t.body,i,{plugin:t.plugin,hubVerified:r&&t.hubVerified===!0});if(!s.plugin)return{status:"failed",retryable:!1,error:"No matching webhook handler found"};if(s.response&&s.response.success===!1)return{status:"failed",retryable:!1,error:typeof s.response.error=="string"?s.response.error:"Webhook handler failed"};let a=s.response?.returnToSender,u=a&&typeof a=="object"&&typeof a.validationToken=="string"&&Object.keys(a).length===1?a.validationToken:a||(s.response?.data??s.response);return{status:"ok",webhookResponse:{status:s.response?.statusCode??200,body:u,headers:s.responseHeaders}}}async function Ju(e,n){return await In(e,{code:n.code,state:n.state,redirectUri:n.redirectUri,callbackParams:n.callbackParams,...n.plugin&&n.tenantId?{trusted:!0,plugin:n.plugin,tenantId:n.tenantId}:{}}),{status:"ok"}}async function Vu(e,n){return await cn(e,{plugin:n.plugin,tenantId:n.tenantId,accessToken:n.accessToken,refreshToken:n.refreshToken,expiresIn:n.expiresIn,scope:n.scope,authType:n.authType,providerData:n.providerData}),{status:"ok"}}async function Nr(e,n,t){let r=await Fr(e,{token:n},t);if(r.status!=="ok")throw new Error(r.error??"Permission decision failed")}async function Fr(e,n,t){let r=v(e),o=n.token?.trim();if(!o)return{status:"failed",retryable:!1,error:"Permission token is required"};if(!r.database)return{status:"failed",retryable:!1,error:"Database not configured"};let i=new Date().toISOString(),s=await r.database.db.selectFrom("corsair_permissions").selectAll().where("token","=",o).executeTakeFirst();return s?s.status!=="pending"?{status:"ok"}:s.expires_at<i?(await r.database.db.updateTable("corsair_permissions").set({status:"expired",updated_at:new Date}).where("id","=",s.id).execute(),{status:"failed",retryable:!1,error:"Permission has expired"}):(await r.database.db.updateTable("corsair_permissions").set({status:t,updated_at:new Date}).where("id","=",s.id).execute(),{status:"ok"}):{status:"failed",retryable:!1,error:"Permission not found"}}async function Yu(e,n){try{return await Rt(e,n),{status:"ok"}}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Credential delivery failed"}}}async function Xu(e,n){try{return await Dr(e,n),{status:"ok"}}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Integration credential delivery failed"}}}function ji(e,n){let t=e;return n&&typeof t?.withTenant=="function"?t.withTenant(n):e}async function Qu(e,n){try{let t=ji(e,n.tenantId);return{status:"ok",webhookResponse:{status:200,body:{status:"ok",run:await Mr({corsair:t,code:n.code,payload:n.trigger?.payload??null,memoizedSteps:n.memoizedSteps})}}}}catch(t){return{status:"failed",retryable:!0,error:t instanceof Error?t.message:"Workflow run failed"}}}async function ec(e,n){try{let t=ji(e,n.tenantId);return{status:"ok",webhookResponse:{status:200,body:{status:"ok",probe:await Hr({corsair:t,code:n.code,timeoutMs:n.timeoutMs})}}}}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Probe failed"}}}async function Hn(e,n,t={}){let r=v(e),o=Br(n.headers,"x-corsair-signature"),i=Br(n.headers,"x-corsair-timestamp"),s=Br(n.headers,"x-corsair-nonce"),a=!1;if(t.signingSecret?.trim()){let l=an({body:n.body,signatureHeader:o,timestampHeader:i,signingSecret:t.signingSecret});if(!l.ok)return{status:"failed",retryable:!1,error:l.error};if(!s?.trim())return{status:"failed",retryable:!1,error:"Missing tunnel nonce"};let c=It(`nonce:${s.trim()}`,Me);if(!c.ok)return{status:"failed",retryable:!1,error:c.error};a=!0}else if(!t.allowUnsignedTunnel)return{status:"failed",retryable:!1,error:"Tunnel signing secret is required"};let u;try{u=JSON.parse(n.body)}catch{return{status:"failed",retryable:!1,error:"Invalid tunnel envelope JSON"}}if(u.type==="connect.status")return{status:"failed",retryable:!1,error:"connect.status is deprecated; use connections.sync signed delivery instead"};switch(u.type){case"webhook":return zu(e,r,u.payload,a);case"oauth.callback":return Ju(e,u.payload);case"oauth.tokens":return Vu(e,u.payload);case"permission.approve":return Fr(e,u.payload,"approved");case"permission.deny":return Fr(e,u.payload,"denied");case"auth.credentials":return Yu(e,u.payload);case"integration.credentials":return Xu(e,u.payload);case"connect.create_link":return Zu(e,u.payload);case"connections.sync":{let l=t.signingSecret?.trim();return l?qu(e,l):{status:"failed",retryable:!1,error:"Tunnel signing secret is required for connections.sync"}}case"run":return t.allowWorkflowExecution?Qu(e,u.payload):{status:"failed",retryable:!1,error:"Workflow execution is not enabled (set allowWorkflowExecution: true)"};case"probe":return t.allowWorkflowExecution?ec(e,u.payload):{status:"failed",retryable:!1,error:"Workflow execution is not enabled (set allowWorkflowExecution: true)"};default:return{status:"failed",retryable:!1,error:`Unsupported tunnel type: ${String(u.type)}`}}}function nc(e){let n=e.webhookResponse;return e.status==="ok"?{status:n?.status??200,body:n?.body??{status:"ok"}}:{status:n?.status??502,body:n?.body??{status:"error",error:e.error??"delivery failed"}}}var Ur=3,tc=250;function rc(e){return e?.name==="AbortError"}async function oc(e){try{return(await e.json())?.ok!==!1}catch{return!0}}async function ic(e,n,t,r,o){for(let i=1;i<=Ur;i++){try{let s=await n.fetch(`${e.apiUrl}/api/dev/ack`,{method:"POST",headers:{...t,"content-type":"application/json"},body:JSON.stringify(r),signal:o});if(s.ok)return await oc(s)||console.warn(`[corsair] hub did not record delivery ${r.deliveryId} (already timed out); the run may be retried`),!0}catch(s){if(rc(s))throw s}i<Ur&&await qi(tc)}return console.warn(`[corsair] failed to acknowledge delivery ${r.deliveryId} after ${Ur} attempts; the run may be retried`),!1}async function sc(e,n,t,r){let o={authorization:`Bearer ${n.projectApiKey}`},i=await t.fetch(`${n.apiUrl}/api/dev/pull`,{headers:o,signal:r});if(i.status===204)return"idle";if(!i.ok)return"error";let{deliveryId:s,body:a,headers:u}=await i.json(),l=await t.process(e,{headers:u,body:a},{signingSecret:n.signingSecret,allowWorkflowExecution:n.allowWorkflowExecution}),{status:c,body:d}=nc(l);return await ic(n,t,o,{deliveryId:s,status:c,body:d},r)?"handled":"error"}var Ki=1e3,ac=5e3,uc=3e4;function qi(e){return new Promise(n=>setTimeout(n,e))}var Ot=globalThis.__corsairConnectLoops??=new Map;function cc(e,n={fetch,process:Hn}){let t;try{t=F(e)}catch{return{stop:()=>{}}}if(!t.projectApiKey.startsWith("ck_dev_"))return{stop:()=>{}};if(!t.allowWorkflowExecution)return console.warn("[corsair] workflow executions not enabled. Please set hub: { ..., allowWorkflowExecution: true }"),{stop:()=>{}};let r=t.projectApiKey;if(Ot.has(r))return{stop:()=>{}};let o=Symbol("corsair-connect-loop");Ot.set(r,o);let i=()=>{Ot.get(r)===o&&Ot.delete(r)},s=!1,a=null;return(async()=>{let l=Ki,c=!1,d=async p=>{c||(console.warn("[corsair] connect loop error; retrying",p),c=!0),s||await qi(l),l=Math.min(l*2,ac)};try{for(;!s;){a=new AbortController;let p=setTimeout(()=>a?.abort(),uc);try{await sc(e,t,n,a.signal)==="error"?await d("pull or ack failed"):(c=!1,l=Ki)}catch(g){if(s)break;await d(g instanceof Error?g.message:g)}finally{clearTimeout(p)}}}finally{i()}})(),{stop:()=>{s=!0,a?.abort(),i()}}}function Zi(e){return e==="oauth_2"||e==="managed"?"oauth":e==="bot_token"?"bot_token":"api_key"}function lc(e,n){return n&&!n.has(e.id)?!1:I(e)!==null}async function Gi(e,n,t={}){let r=v(e),o=n.trim()||"default",i=t.pluginIds?.length?new Set(t.pluginIds):null,s=await An(r,o,{pluginIds:t.pluginIds}),a=new Map(s.map(l=>[l.plugin,l])),u=r.plugins.filter(l=>lc(l,i)).map(l=>{let c=I(l),d=a.get(l.id);return d?{plugin:l.id,providerName:ve(l.id),authKind:Zi(c),status:d.status,connected:d.connected,fields:d.fields.map(p=>({name:p.name,level:p.level,required:p.required,configured:p.configured})),missingRequiredFields:d.missingRequiredFields}:{plugin:l.id,providerName:ve(l.id),authKind:Zi(c),status:"not_started",connected:!1,fields:[],missingRequiredFields:[]}});return{tenantId:o,plugins:u}}async function zi(e,n){let t=F(e);return $({hub:t,path:`/projects/${encodeURIComponent(n.projectId)}/connections`,notFoundMessage:"Hub REST API not found at /projects/:id/connections. Check HUB_API_URL and ensure the Hub API is deployed.",parseResponse:jn})}var Ji=1024*1024,Vi=3e4;function $e(e){return e!==void 0&&Number.isFinite(e)&&e>0?e:Ji}function We(e){return e!==void 0&&Number.isFinite(e)&&e>=0?e:Vi}function ln(e){return new P(413,"payload_too_large",`Request body exceeds the ${e}-byte limit`)}function dc(e){return new P(408,"request_timeout",`Request body stalled: no bytes received for ${e}ms`)}async function Mt(e,n){if(!(n>0))return e();let t;try{return await Promise.race([e(),new Promise((r,o)=>{t=setTimeout(()=>o(dc(n)),n)})])}finally{clearTimeout(t)}}async function Ht(e,n){if(e.body===null)return"";let t=e.body.getReader();try{let r=[],o=0;for(;;){let{done:a,value:u}=await Mt(()=>t.read(),n.bodyStallTimeoutMs);if(a)break;if(o+=u.byteLength,o>n.maxBodyBytes)throw ln(n.maxBodyBytes);r.push(u)}let i=new Uint8Array(o),s=0;for(let a of r)i.set(a,s),s+=a.byteLength;return new TextDecoder().decode(i)}catch(r){throw t.cancel().catch(()=>{}),r}}var Lr=new Map;function Yi(e){let n;try{n=F(e)}catch{return}let t=Jt(n);t&&Lr.get(n.projectApiKey)!==t&&(Lr.set(n.projectApiKey,t),x({hub:n,path:"/apps/announce",body:{deliveryUrl:t},parseResponse:()=>({ok:!0})}).catch(()=>{Lr.delete(n.projectApiKey)}))}var pc=[".corsair.dev"];function gc(e){return e==="localhost"||e==="127.0.0.1"||e==="[::1]"||e==="::1"}function fc(e){try{let{hostname:n,protocol:t}=new URL(e);return t!=="http:"&&t!=="https:"?!1:gc(n)?!0:pc.some(r=>n===r.slice(1)||n.endsWith(r))}catch{return!1}}function Xi(e){return!e||!fc(e)?null:{"Access-Control-Allow-Origin":e,"Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"content-type, x-corsair-signature, x-corsair-timestamp, x-corsair-project, x-corsair-nonce, access-control-request-private-network","Access-Control-Allow-Private-Network":"true","Access-Control-Max-Age":"0",Vary:"Origin"}}function Qi(e,n){if(!n)return e;let t=new Headers(e.headers);for(let[r,o]of Object.entries(n))t.set(r,o);return new Response(e.body,{status:e.status,statusText:e.statusText,headers:t})}function $r(e,n){let t=new URL(e);return n.error?(t.searchParams.set("error",n.error),t.toString()):n.connectedPlugin?(t.searchParams.set("connected",n.connectedPlugin),t.toString()):(n.status!==void 0&&t.searchParams.set("status",Buffer.from(JSON.stringify(n.status)).toString("base64url")),t.toString())}async function Wr(e,n){let t=F(e),o=new URL(n).searchParams.get("d");if(!o)return{type:"json",status:200,body:{status:"ok",message:"Corsair tunnel endpoint is active",timestamp:new Date().toISOString()}};let i=Pe(o,t.signingSecret);if(!i)return{type:"json",status:400,body:{error:"Invalid or expired delivery token"}};let s=It(`browser:${i.jti}`,Te);if(!s.ok)return{type:"json",status:400,body:{error:s.error}};try{if(Dn(i)){if(!i.hubOrigin||!i.requestId)return{type:"json",status:400,body:{error:"Connections sync delivery requires hubOrigin and requestId for client bridge"}};let a=await En(e,t.signingSecret);return{type:"text",status:200,headers:{"Content-Type":"text/html; charset=utf-8"},body:Ze({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!0,body:{status:"ok",sync:{encrypted:a}}})}}if(Et(i)){if(!i.hubOrigin||!i.requestId)return{type:"json",status:400,body:{error:"Connect link delivery requires hubOrigin and requestId for client bridge"}};let a=i.connectLinkPlugins?.filter(Boolean)??[];if(a.length===0)return{type:"json",status:400,body:{error:"Connect link delivery requires at least one plugin in connectLinkPlugins"}};let u=await at(e,{tenantId:i.tenantId,plugins:a});return{type:"text",status:200,headers:{"Content-Type":"text/html; charset=utf-8"},body:Ze({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!0,body:{status:"ok",connectUrl:u.connectUrl,expiresAt:u.expiresAt}})}}if(Le(i))return i.hubSuccessUrl?i.credentials?(await Rt(e,{plugin:i.plugin,tenantId:i.tenantId,credentials:i.credentials}),{type:"redirect",url:$r(i.hubSuccessUrl,{connectedPlugin:i.plugin})}):{type:"redirect",url:$r(i.hubSuccessUrl,{error:"Credential delivery missing credentials"})}:{type:"json",status:400,body:{error:"Credential delivery missing hubSuccessUrl"}};if(On(i)){if(!i.permissionToken)return{type:"json",status:400,body:{error:"Permission delivery missing permission token"}};await Nr(e,i.permissionToken,i.deliveryMode==="permission.approve"?"approved":"denied")}else if(Mn(i)){if(!i.accessToken)return{type:"json",status:400,body:{error:"Managed OAuth delivery missing access_token"}};await cn(e,{plugin:i.plugin,tenantId:i.tenantId,accessToken:i.accessToken,refreshToken:i.refreshToken,expiresIn:i.expiresIn,scope:i.scope,authType:i.authType,providerData:i.providerData})}else{if(!Dt(i)||!i.code||!i.state||!i.redirectUri)return{type:"json",status:400,body:{error:"Invalid BYO OAuth delivery token"}};await In(e,{code:i.code,state:i.state,redirectUri:i.redirectUri,trusted:!0,plugin:i.plugin,tenantId:i.tenantId})}}catch(a){let u=a instanceof Error?a.message:"Hub delivery failed";return Dn(i)&&i.hubOrigin&&i.requestId?{type:"text",status:400,headers:{"Content-Type":"text/html; charset=utf-8"},body:Ze({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!1,error:u})}:Et(i)&&i.hubOrigin&&i.requestId?{type:"text",status:400,headers:{"Content-Type":"text/html; charset=utf-8"},body:Ze({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!1,error:u})}:Le(i)&&i.hubSuccessUrl?{type:"redirect",url:$r(i.hubSuccessUrl,{error:u})}:Le(i)&&i.hubOrigin&&i.requestId?{type:"text",status:400,headers:{"Content-Type":"text/html; charset=utf-8"},body:Ze({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!1,error:u})}:{type:"json",status:400,body:{error:u}}}return{type:"redirect",url:i.hubSuccessUrl}}async function jr(e,n){let t=F(e),r=await Hn(e,n,{signingSecret:t.signingSecret,allowWorkflowExecution:t.allowWorkflowExecution});if(r.status!=="ok")return{type:"json",status:r.retryable===!1?400:502,body:{error:r.error??"Tunnel processing failed"}};let o=r.webhookResponse;if(!o)return{type:"json",status:200,body:{status:"ok"}};let i=o.status??200,s=o.headers;return o.body&&typeof o.body=="object"&&!(o.body instanceof ArrayBuffer)?{type:"json",status:i,body:o.body,headers:s}:{type:"text",status:i,body:typeof o.body=="string"?o.body:o.body?JSON.stringify(o.body):null,headers:s}}function Kr(e){if(e.type==="redirect")return Response.redirect(e.url,302);let n=new Headers;for(let[t,r]of Object.entries(e.headers??{}))typeof r=="string"&&n.set(t,r);return e.type==="json"?Response.json(e.body,{status:e.status,headers:n}):new Response(e.body,{status:e.status,headers:n})}async function qr(e,n){return n.method==="GET"?Wr(e,n.url):jr(e,{headers:n.headers,body:n.body??""})}async function Zr(e,n){try{let t=await qr(e,n);return Kr(t)}catch(t){if(t instanceof de)return Response.json({error:t.message},{status:503});throw t}}async function je(e,n,t){Yi(e);let r=n.method.toUpperCase(),o=Xi(n.headers.get("origin"));if(r==="OPTIONS")return o?new Response(null,{status:204,headers:o}):Response.json({error:"Method not allowed"},{status:405});if(r!=="GET"&&r!=="POST")return Response.json({error:"Method not allowed"},{status:405});let i=await Zr(e,{method:r,url:n.url,headers:n.headers,body:r==="POST"?await Ht(n,{maxBodyBytes:$e(t?.maxBodyBytes),bodyStallTimeoutMs:We(t?.bodyStallTimeoutMs)}):void 0});return Qi(i,o)}var B=class extends Error{pluginId;authType;constructor(n,t,r){super(r??`[auth-missing:${n}:${t}]`),Object.setPrototypeOf(this,new.target.prototype),this.name="AuthMissingError",this.pluginId=n,this.authType=t}};function dn(e){if(e.forceRefresh||!e.accessToken||!e.expiresAt)return!1;let n=e.now??Math.floor(Date.now()/1e3);return Number(e.expiresAt)>n+300}async function pn(e,n,t){let r=Math.floor(Date.now()/1e3),o=t?Number(t):Number.NaN,i=typeof n.expires_in=="number"?r+n.expires_in:Number.isFinite(o)&&o>r?o:r+3600;return await e.set_access_token(n.access_token),await e.set_expires_at(String(i)),n.refresh_token&&await e.set_refresh_token(n.refresh_token),n.scope&&await e.set_scope(n.scope),i}var es=new WeakMap;function Bn(e,n,t){let r=es.get(e);r||(r=new Map,es.set(e,r));let o=r.get(n);if(o!==void 0)return o;let i=t().finally(()=>{r.delete(n)});return r.set(n,i),i}var ns=300;async function Gr(e,n){let{keys:t,hub:r,plugin:o,tenantId:i}=e,s=n?.forceRefresh??!1,a=`managed:${o}:${i}`;return Bn(t,a,async()=>{let[u,l,c]=await Promise.all([t.get_access_token(),t.get_expires_at(),t.get_refresh_token()]);if(!u&&!c)throw new B(o,"managed");let d=Math.floor(Date.now()/1e3);if(!s&&u&&l&&Number(l)>d+ns)return{accessToken:u,expiresAt:Number(l),refreshed:!1};if(!c&&u&&!s){let f=l?Number(l):null;if(f===null||f>d+ns)return{accessToken:u,expiresAt:f??d+3600,refreshed:!1}}if(!c)throw new B(o,"managed");let p=await mc(r,o,i,c),g=await pn(t,p,l);return{accessToken:p.access_token,expiresAt:g,refreshed:!0}})}function yc(e){return e.includes("Managed OAuth connection not found")||e.includes("Managed OAuth connection has no tokens")}async function mc(e,n,t,r){try{return await x({hub:e,path:"/oauth/refresh",body:{plugin:n,tenantId:t,refresh_token:r},parseResponse:qe})}catch(o){let i=o instanceof Error?o.message:"";throw yc(i)?new B(n,"managed"):o}}async function ts(e,n){e._refreshAuth=async()=>(await Gr(n,{forceRefresh:!0})).accessToken}function rs(e){return{delivery:n=>je(e,n),deliveryOptions:n=>je(e,n)}}var os=1200*1e3;function zr(){return le()}function Jr(){return os}function Vr(e,n){return wn(e,n,os)}function Yr(e,n){return ie(e,n)}function Xr(e){return He(e)}var is=600*1e3;function Qr(){return le()}function eo(){return is}function no(e,n){return wn(e,n,is)}function to(e,n){return ie(e,n)}function ro(e){return tr(e)}function oo(e){return He(e)}function io(){return le()}function so(e,n,t){return Gn(e,n,Math.floor(t.getTime()/1e3))}function ao(e,n){return ie(e,n)}function uo(e){return He(e)}var gn=class extends Error{constructor(){super(`Corsair KEK is missing. Pass \`kek\` to createCorsair() or set CORSAIR_KEK in your environment. Generate one with: openssl rand -base64 ${Be}`),this.name="CorsairKekMissingError"}};function Bt(e,n){if(!n)return e??"";if(e===void 0||e==="")throw new gn;return e}function Ft(e,n){let t=[];e||t.push("database"),n||t.push("kek");let r={};return new Proxy(r,{get(o,i){let s=t.length>1;throw new Error(`corsair.keys.${String(i)}: Cannot access keys because ${t.join(" and ")} ${s?"are":"is"} not configured. Provide both 'database' and 'kek' in createCorsair() to enable key management.
|
|
48
|
+
|
|
49
|
+
To generate a KEK, run: openssl rand -base64 ${Be}`)}})}async function hc(e){let n=!1;for(;;){let t=await e.database.db.selectFrom("corsair_integrations").selectAll().where("name","=",e.integrationName).executeTakeFirst();if(!t){if(!n&&e.ensureProvisioned){n=!0,await e.ensureProvisioned();continue}throw new Error(`Integration "${e.integrationName}" not found. Make sure to create the integration first.`)}let r=await e.database.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",e.tenantId).where("integration_id","=",t.id).executeTakeFirst();if(!r){if(!n&&e.ensureProvisioned){n=!0,await e.ensureProvisioned();continue}throw new Error(`Account not found for tenant "${e.tenantId}" and integration "${e.integrationName}". Make sure to create the account first.`)}return{integrationId:t.id,accountId:r.id,integration:{id:t.id,config:t.config,dek:t.dek??null},account:{id:r.id,config:r.config,dek:r.dek??null}}}}async function ss(e){let{integrationId:n,accountId:t}=await hc(e);return{integrationId:n,accountId:t}}function as(e,n){let t=()=>{if(!e)throw new Error("corsair.chats requires Hub to be configured. Pass `hub` to createCorsair({ hub: { projectApiKey, ... } }).");return e};return{create:r=>Vt(t(),{tenantId:n,message:r}),list:()=>Xt(t(),{tenantId:n}),get:r=>({message:o=>Yt(t(),{chatId:r,tenantId:n,message:o}),listMessages:()=>Qt(t(),{chatId:r,tenantId:n})})}}function co(e,n){return`[auth-missing:${e}] Authentication required. Direct the user to connect their account: ${n}`}async function bc(e,n){let t=e.hub;if(!t||!n.database||!n.kek)return null;try{return(await dr(t,{tenantId:n.tenantId,plugin:n.plugin,database:n.database,kek:n.kek,plugins:n.plugins,multiTenancy:n.multiTenancy})).connectUrl}catch{return null}}async function kc(e){let n=e.hub;if(n&&e.database&&e.kek)try{let r=await dr(n,{tenantId:e.tenantId,plugin:e.plugin,database:e.database,kek:e.kek,plugins:e.plugins,multiTenancy:e.multiTenancy});return e.manual?.onAuthMissing?e.manual.onAuthMissing({plugin:e.pluginId,connectUrl:r.connectUrl,state:r.token}):co(e.pluginId,r.connectUrl)}catch{return`[auth-missing:${e.pluginId}:${e.authType}] Authentication required. Could not create connect link. Check hub configuration and server logs.`}let t=await bc({manual:e.manual,hub:e.hub},{plugin:e.plugin,tenantId:e.tenantId,database:e.database,kek:e.kek,plugins:e.plugins,multiTenancy:e.multiTenancy});return t?co(e.pluginId,t):`[auth-missing:${e.pluginId}:${e.authType}]`}function wc(e,n,t){let r=Ye(xe(e,n.tenantId??t??"default"),n.kek),o=new URL(n.baseUrl);o.searchParams.set("state",r);let i=o.toString();return n.onAuthMissing?n.onAuthMissing({plugin:e,connectUrl:i,state:r}):co(e,i)}async function Cc(e){let n=e.tenantId??"default",t=e.error.pluginId;return e.manual&&tn(e.manual)&&e.manual.oauthConfig&&e.manual.kek&&e.error.authType==="oauth_2"?wc(t,{...e.manual,baseUrl:e.manual.baseUrl,kek:e.manual.kek},e.tenantId):e.hub&&e.plugin&&e.kek&&e.database&&e.plugins?kc({manual:e.manual,hub:e.hub,plugin:e.plugin,pluginId:t,tenantId:n,authType:e.error.authType,database:e.database,kek:e.kek,plugins:e.plugins,multiTenancy:e.multiTenancy}):e.error.message}async function us(e){let n=await Cc(e);throw new B(e.error.pluginId,e.error.authType,n)}var vc=async(e,n)=>(console.error(`[corsair:${n.pluginId}:${n.operation}]`,{error:e.message,input:n.input}),{maxRetries:0});async function cs(e,n,t,r,o){let i={pluginId:n,operation:t,input:r,originalError:e},s=Object.keys(o).find(l=>o[l]?.match(e,i));return await(o[s||"DEFAULT"]?.handler||vc)(e,i)}function Tc(e){return typeof e=="function"}function lo({endpoints:e,hooks:n,ctx:t,tree:r,pluginId:o,errorHandlers:i,currentPath:s=[],keyBuilder:a,permissionsConfig:u,endpointMeta:l,database:c,permissionsOptions:d,tenantId:p,manualConfig:g,hubConfig:f,plugin:h,kek:k,allPlugins:b,multiTenancy:C}){for(let[T,D]of Object.entries(e)){let E=n?.[T];if(Tc(D)){let M=E,w=[...s,T].join("."),A=async(R={})=>{let z=l?.[w];kr(w,z?.riskLevel??"write");let ce;if(u){let J=z,{result:Un,reason:re,onComplete:hn,token:ke,id:Oe,expiresAt:V}=await Ai({pluginId:o,endpointPath:w,args:R,mode:u.mode,override:u.overrides?.[w],riskLevel:J?.riskLevel??"write",meta:J,db:c,timeoutMs:d?wr(d.timeout):void 0,tenantId:p,approvalMode:d?.mode});if(Un==="blocked"){let oe;throw re==="denied"?oe=`Action '${w}' was denied by the user. Await further instructions before proceeding.`:re==="policy"?oe=`Action '${w}' is blocked by the permission policy. Update the corsair config to allow it.`:re==="timeout"?oe=`Action '${w}' timed out waiting for approval.`:ke&&Oe?oe=await hr({permissionsOptions:d,manual:g,hub:f,permissionId:Oe,permissionToken:ke,plugin:o,endpoint:w,args:R,tenantId:p??"default",expiresAt:V??new Date(Date.now()+(d?wr(d.timeout):600*1e3)).toISOString(),operationPath:w}):oe=`Action '${w}' requires user approval before it can run.`,new rn(oe)}ce=hn}let S=async(J,Un,re)=>{try{return await D(Un,re)}catch(hn){if(hn instanceof Error){let ke=await cs(hn,o,w,typeof re=="object"&&re!==null?re:{args:re},i);if(J<(ke.maxRetries||0)){let Oe=J+1;console.log(`Retrying (${Oe} / ${ke.maxRetries})...`);let V;if(ke.headersRetryAfterMs)V=ke.headersRetryAfterMs;else switch(ke.retryStrategy){case"exponential_backoff":V=Math.pow(2,Oe-1)*1e3;break;case"exponential_backoff_jitter":let oe=Math.pow(2,Oe-1)*1e3,pa=(Math.random()-.5)*1e3;V=Math.max(0,oe+pa);break;case"linear_1s":V=1e3;break;case"linear_2s":V=2e3;break;case"linear_3s":V=3e3;break;case"linear_4s":V=4e3;break;default:V=1e3;break}return await new Promise(oe=>setTimeout(oe,V)),await S(Oe,Un,re)}}throw hn}},te;try{te=a?await a(t,"endpoint"):void 0}catch(J){throw J instanceof B&&(h&&f&&xn({hub:f,database:c,kek:k,plugins:b??[],plugin:h,tenantId:p,verified:!1}),await us({error:J,manual:g,hub:f,plugin:h,tenantId:p,database:c,kek:k,plugins:b,multiTenancy:C})),J}if(!M?.before&&!M?.after){let J=await S(0,{...t,key:te},R);return await ce?.(),h&&f&&xn({hub:f,database:c,kek:k,plugins:b??[],plugin:h,tenantId:p,verified:!0}),J}let mn={...t,key:te},De=M.before?await M.before(mn,R):{ctx:mn,args:R,continue:!0,passToAfter:void 0};if(De.continue===!1)return;let xo=await S(0,De.ctx,De.args);return await M.after?.(De.ctx,xo,De.passToAfter),await ce?.(),h&&f&&xn({hub:f,database:c,kek:k,plugins:b??[],plugin:h,tenantId:p,verified:!0}),xo};r[T]=A}else if(D&&typeof D=="object"){let M={};lo({endpoints:D,hooks:E,ctx:t,tree:M,pluginId:o,errorHandlers:i,currentPath:[...s,T],keyBuilder:a,permissionsConfig:u,endpointMeta:l,database:c,permissionsOptions:d,tenantId:p,manualConfig:g,hubConfig:f,plugin:h,kek:k,allPlugins:b,multiTenancy:C}),r[T]=M}}}function Pc(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function po({webhooks:e,hooks:n,ctx:t,webhooksTree:r,keyBuilder:o}){for(let[i,s]of Object.entries(e)){let a=n?.[i];if(Pc(s)){let u=a,l=async c=>{let d=(g,f)=>s.handler(g,f),p=o&&c?.hubVerified!==!0?await o(t,"webhook"):void 0;return!u?.before&&!u?.after?d({...t,key:p},c):(async()=>{let g={...t,key:p},f=u.before?await u.before(g,c):{ctx:g,args:c,continue:!0,passToAfter:void 0};if(f.continue===!1)return;let h=await d(f.ctx,f.args);return h?.success===!0&&await u.after?.(f.ctx,h,f.passToAfter),h})()};r[i]={match:s.match,handler:l}}else if(s&&typeof s=="object"){let u={};po({webhooks:s,hooks:a,ctx:t,webhooksTree:u,keyBuilder:o}),r[i]=u}}}function ls(e){return e&&typeof e=="object"?e:{}}async function ds(e,n){return $({hub:e,path:`/workflows?tenantId=${encodeURIComponent(n.tenantId)}`,parseResponse:t=>{let r=ls(t).workflows;return Array.isArray(r)?r:[]}})}async function ps(e,n){return $({hub:e,path:`/workflows/${encodeURIComponent(n.workflowId)}?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Workflow "${n.workflowId}" not found`,parseResponse:t=>ls(t).workflow})}async function gs(e,n){await x({hub:e,path:`/workflows/${encodeURIComponent(n.workflowId)}/status?tenantId=${encodeURIComponent(n.tenantId)}`,body:{status:n.status},notFoundMessage:`Workflow "${n.workflowId}" not found`,parseResponse:t=>t})}async function fs(e,n){await x({hub:e,path:`/workflows/${encodeURIComponent(n.workflowId)}/rename?tenantId=${encodeURIComponent(n.tenantId)}`,body:{name:n.name},notFoundMessage:`Workflow "${n.workflowId}" not found`,parseResponse:t=>t})}async function ys(e,n){return x({hub:e,path:`/workflows/${encodeURIComponent(n.workflowId)}/run?tenantId=${encodeURIComponent(n.tenantId)}`,body:{payload:n.payload,idempotencyKey:n.idempotencyKey},notFoundMessage:`Workflow "${n.workflowId}" not found`,parseResponse:t=>t})}function go(e){return e&&typeof e=="object"?e:{}}async function ms(e,n){return $({hub:e,path:`/runs?tenantId=${encodeURIComponent(n.tenantId)}`,parseResponse:t=>{let r=go(t).runs;return Array.isArray(r)?r:[]}})}async function hs(e,n){return $({hub:e,path:`/workflows/${encodeURIComponent(n.workflowId)}/runs?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Workflow "${n.workflowId}" not found`,parseResponse:t=>{let r=go(t).runs;return Array.isArray(r)?r:[]}})}async function bs(e,n){return $({hub:e,path:`/runs/${encodeURIComponent(n.runId)}?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Run "${n.runId}" not found`,parseResponse:t=>go(t).run})}async function fo(e,n,t){await x({hub:e,path:`/runs/${encodeURIComponent(t.runId)}/${n}?tenantId=${encodeURIComponent(t.tenantId)}`,body:{},notFoundMessage:`Run "${t.runId}" cannot be ${n==="cancel"?"canceled":`${n}d`} in its current state`,parseResponse:r=>r})}var ks=(e,n)=>fo(e,"approve",n),ws=(e,n)=>fo(e,"deny",n),Cs=(e,n)=>fo(e,"cancel",n);function vs(e,n){let t=()=>{if(!e)throw new Error("corsair.workflows.runs requires Hub to be configured. Pass `hub` to createCorsair({ hub: { projectApiKey, ... } }).");return e};return{list:r=>r?.workflowId?hs(t(),{workflowId:r.workflowId,tenantId:n}):ms(t(),{tenantId:n}),get:r=>bs(t(),{runId:r,tenantId:n}),approve:r=>ks(t(),{runId:r,tenantId:n}),deny:r=>ws(t(),{runId:r,tenantId:n}),cancel:r=>Cs(t(),{runId:r,tenantId:n})}}function Ts(e,n){let t=()=>{if(!e)throw new Error("corsair.workflows requires Hub to be configured. Pass `hub` to createCorsair({ hub: { projectApiKey, ... } }).");return e},r=(o,i)=>gs(t(),{workflowId:o,tenantId:n,status:i});return{list:()=>ds(t(),{tenantId:n}),get:o=>ps(t(),{workflowId:o,tenantId:n}),run:(o,i)=>ys(t(),{workflowId:o,tenantId:n,payload:i?.payload,idempotencyKey:i?.idempotencyKey}),runs:vs(e,n),disable:o=>r(o,"inactive"),enable:o=>r(o,"active"),archive:o=>r(o,"archived"),unarchive:o=>r(o,"inactive"),rename:(o,i)=>fs(t(),{workflowId:o,tenantId:n,name:i})}}function Ac(e,n,t,r){let o=null;return async()=>{if(o)return o;if(!e)throw new Error("Database not configured");let{accountId:i}=await ss({database:e,integrationName:n,tenantId:t,ensureProvisioned:r});return o=i,o}}function Rc(e,n,t,r,o){return e?Zt(e.db,n,t,r,o):{findByEntityId:async()=>null,existsByEntityId:async()=>!1,findIdByEntityId:async()=>null,findById:async()=>null,findManyByEntityIds:async()=>[],list:async()=>[],search:async()=>[],upsertByEntityId:async()=>{throw new Error("Database not configured")},deleteById:async()=>!1,deleteByEntityId:async()=>!1,count:async()=>0}}function yo(e,n){let{database:t,tenantId:r,kek:o,rootErrorHandlers:i,permissionsOptions:s,manualConfig:a,hubConfig:u,internalConfig:l}=n,c=r??"default",d=l&&t?()=>Ve(l,c):void 0,p={},g={};for(let f of e)p[f.id]={},g[f.id]={};for(let f of e){let h=f.schema,k=Ac(t,f.id,c,d);if(h?.entities){let S={};for(let[te,mn]of Object.entries(h.entities)){let De=t?Zt(t.db,k,te,h.version,mn):Rc(void 0,k,te,h.version,mn);S[te]=De}g[f.id].db=S,p[f.id].db=S}let b=f.options,C=f.authConfig,T;if(t&&o&&b?.authType){let S=C?.[b.authType]?.account??[];T=H({authType:b.authType,integrationName:f.id,tenantId:c,kek:o,database:t,extraAccountFields:S,ensureProvisioned:d}),p[f.id].keys=T}let D={database:t,db:g[f.id]?.db??{},$getAccountId:k,...f.options?{options:f.options}:{},...T?{keys:T,authType:b?.authType}:{},tenantId:c,...u?{hub:u}:{}},E=f.endpoints??{},M=f.hooks,w={...i,...f.errorHandlers},A={},R=f.options?.permissions;lo({endpoints:E,hooks:M,ctx:D,tree:A,pluginId:f.id,errorHandlers:w,currentPath:[],keyBuilder:f.keyBuilder,permissionsConfig:R,endpointMeta:f.endpointMeta,database:t,permissionsOptions:s,tenantId:r,manualConfig:a?{...a,oauthConfig:f.oauthConfig,kek:o,tenantId:c}:void 0,hubConfig:u,plugin:f,kek:o,allPlugins:e,multiTenancy:l?.multiTenancy}),Object.keys(A).length>0&&(p[f.id].api=A),D.endpoints=A;let z=f.webhooks??{},ce=f.webhookHooks;if(Object.keys(z).length>0){let S={};po({webhooks:z,hooks:ce,ctx:D,webhooksTree:S,keyBuilder:f.keyBuilder}),p[f.id].webhooks=S,f.pluginWebhookMatcher&&(p[f.id].pluginWebhookMatcher=f.pluginWebhookMatcher),f.pluginTenantWebhookMatcher&&(p[f.id].pluginTenantWebhookMatcher=f.pluginTenantWebhookMatcher)}}return p.chats=as(u,c),p.workflows=Ts(u,c),p}function Ps(e,n,t){let r={};for(let o of e){let i=o.options,s=o.authConfig;if(i?.authType){let a=s?.[i.authType]?.integration??[],u=N({authType:i.authType,integrationName:o.id,kek:t,database:n,extraIntegrationFields:a});r[o.id]=u}}return r}var xc="createCorsair({ approval: ... }) is deprecated. Rename to permissions: { timeout, onTimeout, mode }.";function As(e){let{permissions:n,approval:t}=e;if(n&&t)throw new Error("createCorsair was given both permissions and approval config. Use permissions only \u2014 approval is deprecated.");return t?(console.warn(`[corsair] ${xc}`),t):n}var Rs=[{method:"GET",pattern:"/ok",handler:async()=>O(200,pt())},{method:"GET",pattern:"/tenants",handler:async({internal:e})=>O(200,await sn(e))},{method:"POST",pattern:"/tenants",handler:async({internal:e,body:n})=>O(201,await yt(e,n))},{method:"GET",pattern:"/tenants/:id",handler:async({internal:e,params:n})=>O(200,await ft(e,n.id))},{method:"GET",pattern:"/plugins",handler:async({internal:e})=>O(200,await on(e))},{method:"GET",pattern:"/plugins/:id",handler:async({internal:e,params:n})=>O(200,await gt(e,n.id))},{method:"GET",pattern:"/connection-status",handler:async({internal:e,query:n})=>O(200,await mt(e,n.tenantId))},{method:"GET",pattern:"/permissions/:id",handler:async({internal:e,params:n})=>O(200,await Cr(e,n.id))},{method:"POST",pattern:"/permissions/lookup-by-token",handler:async({internal:e,body:n})=>{let t=n?.token?.trim();return t?O(200,await Tr(e,t)):O(400,{error:"bad_request",message:"token is required",missingFields:["token"]})}},{method:"POST",pattern:"/connect/links",handler:async({corsair:e,internal:n,body:t})=>O(200,await ht(e,n,t))},{method:"GET",pattern:"/connect/resolve",handler:async({corsair:e,internal:n,query:t})=>O(200,await bt(e,n,t.state??""))},{method:"POST",pattern:"/connect/oauth/callback",handler:async({corsair:e,internal:n,body:t})=>O(200,await kt(e,n,t))}];(()=>{let e=new Set;for(let n of Rs){let t=`${n.method} ${n.pattern}`;if(e.has(t))throw new Error(`Duplicate management route registered: ${t}`);e.add(t)}})();function Ic(e,n){let t=e.split("/").filter(Boolean),r=n.split("/").filter(Boolean);if(t.length!==r.length)return null;let o={};for(let i=0;i<t.length;i++){let s=t[i],a=r[i];if(s.startsWith(":"))o[s.slice(1)]=decodeURIComponent(a);else if(s!==a)return null}return o}function Sc(e,n){if(!n)return e;let t=n.endsWith("/")?n.slice(0,-1):n;return e===t?"/":e.startsWith(`${t}/`)?e.slice(t.length):e}async function _c(e,n){if(e.method==="GET"||e.method==="HEAD"||!(e.headers.get("content-type")??"").includes("application/json"))return;let r=await Ht(e,n).catch(o=>{throw o instanceof P?o:new P(400,"invalid_json","Request body is not valid JSON")});if(r)try{return JSON.parse(r)}catch{throw new P(400,"invalid_json","Request body is not valid JSON")}}var Ec="/api/corsair";function U(e,n={}){let t=n.basePath??Ec,r=$e(n.maxBodyBytes),o=We(n.bodyStallTimeoutMs),i={maxBodyBytes:r,bodyStallTimeoutMs:o},s=v(e,()=>new Error("managementHandler: invalid corsair instance (missing internal config)"));return async a=>{try{let u=a.headers.get("content-length");if(u!==null&&Number(u)>r)throw ln(r);let l=new URL(a.url),c=Sc(l.pathname,t),d=a.method.toUpperCase();if(d==="OPTIONS"||c==="/"||c==="")return await je(e,a,{maxBodyBytes:r,bodyStallTimeoutMs:o});if(d!=="GET"&&d!=="POST")return O(405,{error:"method_not_allowed",message:`Method ${d} not allowed`});let p=Object.fromEntries(l.searchParams);for(let g of Rs){if(g.method!==d)continue;let f=Ic(g.pattern,c);if(!f)continue;let h=await _c(a,i);return await g.handler({corsair:e,internal:s,req:a,params:f,query:p,body:h})}throw Ie(`No route for ${d} ${c}`)}catch(u){if(n.onError){let c=await n.onError(u,a);if(c)return c}if(u instanceof P)return se(u);let l=u instanceof Error?u.message:"Internal server error";return O(500,{error:"internal_error",message:l})}}}function Dc(e,n){if(e.get)return e.get(n);let t=e.headers[n]??e.headers[n.toLowerCase()];return Array.isArray(t)?t[0]:t}function Oc(e){if(Buffer.isBuffer(e))return e;if(e instanceof Uint8Array)return Buffer.from(e);if(typeof e=="string")return Buffer.from(e,"utf8");throw new TypeError(`corsair adapter: unsupported stream chunk type ${typeof e}`)}async function Mc(e,n,t){let r=[],o=0,i=e();try{let s=await Mt(()=>i.next(),t);for(;s.done!==!0;){let a=Oc(s.value);if(o+=a.byteLength,o>n)throw ln(n);r.push(a),s=await Mt(()=>i.next(),t)}return Buffer.concat(r)}catch(s){try{Promise.resolve(i.return?.()).catch(()=>{})}catch{}throw s}}var xs=!1;function Hc(){xs||(xs=!0,console.warn("[corsair] A JSON body parser consumed this request before the corsair adapter.","Re-serializing the parsed object is lossy and will likely fail Hub signature",'verification ("Invalid tunnel signature"). Fix on the corsair route only:',"Express \u2192 mount express.raw({ type: 'application/json' }) before the handler,","or capture raw bytes via express.json({ verify: (req, _res, buf) => { req.rawBody = buf; } }).","Fastify \u2192 call registerCorsairRawBodyParser(app) before listen()."))}async function Bc(e,n){let t=(e.method??"GET").toUpperCase();if(t==="GET"||t==="HEAD")return;let r=$e(n.maxBodyBytes),o=We(n.bodyStallTimeoutMs),i;if(typeof e.rawBody=="string")i=e.rawBody;else if(e.rawBody instanceof Uint8Array)i=e.rawBody;else if(e.body!==void 0&&e.body!==null)typeof e.body=="string"||e.body instanceof Uint8Array?i=e.body:(Hc(),i=JSON.stringify(e.body));else{let a=e[Symbol.asyncIterator];if(typeof a!="function")return;let u=await Mc(a.bind(e),r,o);u.length>0&&(i=u)}if(i===void 0)return;if((typeof i=="string"?Buffer.byteLength(i,"utf8"):i.byteLength)>r)throw ln(r);return typeof i=="string"?i:i}function K(e){e.resume?.()}async function _e(e,n={}){let t=Dc(e,"host")??"localhost",r=e.protocol??"http",o=e.originalUrl??e.url??"/",i=`${r}://${t}${o}`,s=new Headers;for(let[l,c]of Object.entries(e.headers))if(c!=null&&!Fc.has(l.toLowerCase()))if(Array.isArray(c))for(let d of c)s.append(l,d);else s.set(l,c);let a={method:(e.method??"GET").toUpperCase(),headers:s},u=await Bc(e,n);return u!==void 0&&(a.body=u,s.has("content-type")||s.set("content-type","application/json")),new Request(i,a)}async function q(e,n){typeof e.status=="function"?e.status(n.status):e.statusCode=n.status;let t=n.headers.getSetCookie();n.headers.forEach((o,i)=>{i!=="set-cookie"&&e.setHeader(i,o)}),t.length>0&&e.setHeader("set-cookie",t);let r=Buffer.from(await n.arrayBuffer());e.send?e.send(r):e.end?.(r)}var Fc=new Set(["connection","keep-alive","proxy-authenticate","proxy-authorization","te","trailer","transfer-encoding","upgrade","content-length"]);function Is(e,n){let t=U(e,n);return async(r,o,i)=>{try{let s=await t(await _e(r,{maxBodyBytes:n?.maxBodyBytes,bodyStallTimeoutMs:n?.bodyStallTimeoutMs}));await q(o,s)}catch(s){if(s instanceof P&&o.headersSent!==!0){await q(o,se(s)),K(r);return}K(r),i(s)}}}function Nc(e,n){let t=e[n];return Array.isArray(t)?t[0]:t}function Uc(e){let n=(e.method??"GET").toUpperCase();if(n==="GET"||n==="HEAD"||e.body!==void 0||e.rawBody!==void 0)return;let t=Nc(e.headers,"content-type");if(!(!t||!t.includes("application/json"))&&!(e.raw.readableEnded!==!0&&e.raw.complete!==!0))throw new Error("corsair: Fastify consumed this JSON body before the corsair adapter could read it. Call registerCorsairRawBodyParser(app) before listen() so the original bytes reach the adapter verbatim (Hub signs deliveries over the exact bytes it sent).")}function Ss(e){e.addContentTypeParser("application/json",{parseAs:"buffer"},(n,t,r)=>{n.rawBody=t;try{r(null,JSON.parse(t.toString("utf8")))}catch{r(Object.assign(new Error("Invalid JSON body"),{statusCode:400}))}})}function _s(e,n){let t=U(e,n);return async(r,o)=>{Uc(r);let i={method:r.method??r.raw.method,url:r.url??r.raw.url,headers:r.headers,protocol:r.protocol,body:r.body,rawBody:r.rawBody,resume:r.raw.resume?.bind(r.raw),[Symbol.asyncIterator]:r.raw[Symbol.asyncIterator]?.bind(r.raw)};try{let s=await t(await _e(i,{maxBodyBytes:n?.maxBodyBytes,bodyStallTimeoutMs:n?.bodyStallTimeoutMs}));o.hijack?.(),await q(o.raw,s)}catch(s){if(s instanceof P&&o.raw.headersSent!==!0&&o.hijack){o.hijack(),await q(o.raw,se(s)),K(i);return}throw K(i),s}}}function Es(e,n){let t=U(e,n);return r=>t(r.req.raw)}function Ds(e,n){let t=U(e,n);return{GET:t,POST:t,OPTIONS:t}}function Os(e,n){let t=U(e,n);return async(r,o)=>{try{let i=await t(await _e(r,{maxBodyBytes:n?.maxBodyBytes,bodyStallTimeoutMs:n?.bodyStallTimeoutMs}));await q(o,i)}catch(i){if(o.headersSent===!0){console.error("[corsair] management response failed after headers were sent:",i),o.end?.(),K(r);return}if(i instanceof P){await q(o,se(i)),K(r);return}console.error("[corsair] management handler failed:",i),await q(o,O(500,{error:"internal_error"})),K(r)}}}function Nt(e,n){let t=U(e,n);return r=>t(r.request)}function Ms(e,n){let t=Nt(e,n);return{GET:t,POST:t,OPTIONS:t}}function Hs(e,n){let t=Nt(e,n);return{loader:t,action:t}}function Bs(e,n){let t=Nt(e,n);return{GET:t,POST:t,OPTIONS:t}}function Fs(e,n){let t=Nt(e,n);return{GET:t,POST:t,OPTIONS:t}}function Ns(e,n){let t=U(e,n);return async r=>{let o={method:r.node.req.method,url:r.node.req.url,headers:r.node.req.headers,protocol:r.node.req.protocol,body:r._body,rawBody:r.node.req.rawBody??r._rawBody,resume:r.node.req.resume?.bind(r.node.req),[Symbol.asyncIterator]:r.node.req[Symbol.asyncIterator]?.bind(r.node.req)};try{let i=await t(await _e(o,{maxBodyBytes:n?.maxBodyBytes,bodyStallTimeoutMs:n?.bodyStallTimeoutMs}));await q(r.node.res,i)}catch(i){if(i instanceof P&&r.node.res.headersSent!==!0){await q(r.node.res,se(i)),K(o);return}throw K(o),i}}}function Us(e,n){return U(e,n)}function Ls(e){let n={[Fn]:e};return{ok:pt,tenants:{list:()=>sn(e),create:t=>yt(e,t),get:t=>ft(e,t)},plugins:{list:()=>on(e),get:t=>gt(e,t)},connectionStatus:{get:t=>mt(e,t?.tenantId)},permissions:{get:t=>Ei(e,t)},connect:{createLink:t=>ht(n,e,t),resolve:t=>bt(n,e,t),oauthCallback:t=>kt(n,e,t)}}}async function $s(e,n,t,r,o="pending"){if(!e)return null;try{let i=Oo(),s=new Date;return await e.db.insertInto("corsair_events").values({id:i,created_at:s,updated_at:s,account_id:n,event_type:t,payload:r,status:o}).execute(),i}catch(i){return console.warn("Failed to log event:",i),null}}async function Lc(e,n,t,r="pending"){try{let o=await e.$getAccountId();return $s(e.database,o,n,t,r)}catch(o){return console.warn("Failed to log event:",o),null}}import*as js from"https";import*as Ut from"querystring";var $c=["expires_in","refresh_token_expires_in"];function Ws(e){let n={...e};for(let t of $c){let r=e[t];if(typeof r=="string"){let o=Number(r);n[t]=Number.isFinite(o)?o:void 0}}return n}function Wc(e){try{return Ws(JSON.parse(e))}catch{}if(!e.includes("="))return null;let n=Ut.parse(e);return!n.access_token&&!n.error?null:Ws({...n})}function rt(e,n,t,r,o){let i=new URL(r.tokenUrl),s=r.tokenAuthMethod==="basic";return new Promise((a,u)=>{let l={code:e.trim(),redirect_uri:o,grant_type:"authorization_code"};s||(l.client_id=n,l.client_secret=t);let c=Ut.stringify(l),d={"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json","Content-Length":Buffer.byteLength(c).toString()};s&&(d.Authorization=`Basic ${Buffer.from(`${n}:${t}`).toString("base64")}`);let p=js.request({hostname:i.hostname,...i.port?{port:Number(i.port)}:{},path:i.pathname+i.search,method:"POST",headers:d},g=>{let f="";g.on("data",h=>{f+=h}),g.on("end",()=>{if(g.statusCode!==200){u(new Error(`Token exchange failed (${g.statusCode}): ${f}`));return}let h=Wc(f);h?a(h):u(new Error(`Token endpoint returned non-JSON response: ${f}`))})});p.on("error",g=>u(new Error(`Request failed: ${g.message}`))),p.write(c),p.end()})}async function Ks(e,n){let{keys:t,hub:r,plugin:o,tenantId:i}=e,[s,a,u]=await Promise.all([t.get_access_token(),t.get_expires_at(),t.get_refresh_token()]);if(dn({accessToken:s,expiresAt:a,forceRefresh:n?.forceRefresh}))return{accessToken:s,expiresAt:Number(a),refreshed:!1};if(!u)throw new B(o,"oauth_2");let l=await x({hub:r,path:"/oauth/refresh",body:{plugin:o,tenantId:i,refresh_token:u},parseResponse:qe}),c=await pn(t,l,a);return{accessToken:l.access_token,expiresAt:c,refreshed:!0}}async function qs(e){let{tokenUrl:n,refreshToken:t,clientSecret:r,clientId:o,tokenAuthMethod:i="body",bodyFormat:s="form",extraParams:a}=e,u={grant_type:"refresh_token",refresh_token:t,...a},l={Accept:"application/json"};i==="basic"?l.Authorization=`Basic ${Buffer.from(`${o??""}:${r}`).toString("base64")}`:i==="basic_secret_only"?l.Authorization=`Basic ${Buffer.from(`${r}:`).toString("base64")}`:(o&&(u.client_id=o),u.client_secret=r),s==="json"?l["Content-Type"]="application/json":l["Content-Type"]="application/x-www-form-urlencoded";let c=await fetch(n,{method:"POST",headers:l,body:s==="json"?JSON.stringify(u):new URLSearchParams(u)});if(!c.ok)throw new Error(`OAuth token refresh failed (${c.status}): ${await c.text()}`);let d=JSON.parse(await c.text());if(typeof d.access_token!="string"||d.access_token.length===0)throw new Error("OAuth token refresh returned no access_token");return{access_token:d.access_token,...typeof d.refresh_token=="string"&&d.refresh_token.length>0?{refresh_token:d.refresh_token}:{},...typeof d.expires_in=="number"?{expires_in:d.expires_in}:{},...typeof d.scope=="string"&&d.scope.length>0?{scope:d.scope}:{}}}async function Zs(e,n){let t=await e.keys.get_integration_credentials(),r=`${n.plugin}:${e.tenantId}`;if(!t.client_secret){if(!e.hub)throw new B(n.plugin,"oauth_2");let l={keys:e.keys,hub:e.hub,plugin:n.plugin,tenantId:e.tenantId},c=g=>Bn(e.keys,r,async()=>(await Ks(l,{forceRefresh:g})).accessToken);e._refreshAuth=()=>c(!0);let[d,p]=await Promise.all([e.keys.get_access_token(),e.keys.get_expires_at()]);return dn({accessToken:d,expiresAt:p})?d:c(!1)}let o=t.client_secret,i=t.client_id,s=l=>Bn(e.keys,r,async()=>{let[c,d,p]=await Promise.all([e.keys.get_access_token(),e.keys.get_expires_at(),e.keys.get_refresh_token()]);if(!l&&dn({accessToken:c,expiresAt:d}))return c;if(!p)throw new B(n.plugin,"oauth_2");let g=await qs({tokenUrl:n.tokenUrl,tokenAuthMethod:n.tokenAuthMethod,bodyFormat:n.bodyFormat,extraParams:n.extraParams,clientId:i,clientSecret:o,refreshToken:p});return await pn(e.keys,g,d),g.access_token});e._refreshAuth=()=>s(!0);let[a,u]=await Promise.all([e.keys.get_access_token(),e.keys.get_expires_at()]);return dn({accessToken:a,expiresAt:u})?a:s(!1)}var Gs=" ";function ee(e){let n=e;return n._def??n.def??{}}function ne(e){let n=e.typeName;if(n)return n;let t=e.type;if(t)return`Zod${t.split("_").map(r=>r.charAt(0).toUpperCase()+r.slice(1)).join("")}`}function Q(e){return e.innerType??e.schema??e.out??e.in}function Js(e,n){switch(n){case"ZodPipe":return e.in??e.innerType;case"ZodEffects":return e.schema??e.innerType;case"ZodTransform":return e.schema??e.innerType??e.in;default:return Q(e)}}function Vs(e){let n=e.type;return e.element??(typeof n=="string"?void 0:n)}function $t(e,n){let t=n.shape??e.shape;return typeof t=="function"?t():t}function fn(e){return Array.isArray(e.options)?e.options:Array.isArray(e.values)?e.values:e.entries!==null&&typeof e.entries=="object"&&!Array.isArray(e.entries)?Object.values(e.entries):[]}function Ys(e,n){return e.description??n.description}function jc(e){let n=e;for(;n;){let t=ee(n),r=Ys(n,t);if(r)return r;let o=ne(t);if(wo(o)||o==="ZodPipe"||o==="ZodEffects"||o==="ZodTransform"){n=Js(t,o);continue}break}}function wo(e){return e==="ZodOptional"||e==="ZodNullable"||e==="ZodDefault"||e==="ZodCatch"}function Z(e){let n=ee(e),t=ne(n);switch(t){case"ZodString":return"string";case"ZodNumber":return"number";case"ZodBoolean":return"boolean";case"ZodDate":return"Date";case"ZodNull":return"null";case"ZodUnknown":case"ZodAny":return"any";case"ZodLiteral":return String(n.value??fn(n)[0]??"unknown");case"ZodEnum":return fn(n).map(r=>String(r)).join(" | ");case"ZodOptional":{let r=Q(n);return r?Z(r):"unknown"}case"ZodNullable":{let r=Q(n);return`${r?Z(r):"unknown"} | null`}case"ZodDefault":case"ZodCatch":{let r=Q(n);return r?Z(r):"unknown"}case"ZodArray":{let r=Vs(n);if(!r)return"unknown[]";let o=ee(r),i=ne(o)==="ZodUnion",s=Z(r);return`${i?`(${s})`:s}[]`}case"ZodRecord":return"{}";case"ZodObject":{let r=$t(e,n),o=Object.entries(r);return o.length===0?"{}":`{ ${o.map(([s,a])=>{let u=ne(ee(a));return`${u==="ZodOptional"||u==="ZodNullable"?s+"?":s}: ${Z(a)}`}).join(", ")} }`}case"ZodUnion":return fn(n).map(r=>Z(r)).join(" | ");case"ZodIntersection":return`${Z(n.left)} & ${Z(n.right)}`;case"ZodPipe":case"ZodTransform":case"ZodEffects":{let r=Js(n,t);return r?Z(r):"unknown"}default:return(t??"unknown").replace("Zod","").toLowerCase()}}function be(e){let n=ee(e),t=ne(n),r=Ys(e,n);switch(t){case"ZodString":return{kind:"string",optional:!1,description:r};case"ZodNumber":return{kind:"number",optional:!1,description:r};case"ZodBoolean":return{kind:"boolean",optional:!1,description:r};case"ZodLiteral":{let o=n.value??fn(n)[0],i=typeof o=="string"||typeof o=="number"||typeof o=="boolean"?o:String(o??"");return{kind:"literal",optional:!1,description:r,value:i}}case"ZodEnum":{let o=fn(n).map(i=>String(i));return{kind:"string",optional:!1,description:r,enum:o}}case"ZodOptional":{let o=Q(n),i=o?be(o):{kind:"unknown",optional:!1};return{...i,optional:!0,description:r??i.description}}case"ZodNullable":{let o=Q(n),i=o?be(o):{kind:"unknown",optional:!1};return{...i,optional:!0,description:r??i.description}}case"ZodDefault":case"ZodCatch":{let o=Q(n);return o?{...be(o),description:r}:{kind:"unknown",optional:!1,description:r}}case"ZodArray":{let o=Vs(n);return{kind:"array",optional:!1,description:r,items:o?be(o):{kind:"unknown",optional:!1}}}case"ZodObject":{let o=$t(e,n),i={};for(let[s,a]of Object.entries(o))i[s]=be(a);return{kind:"object",optional:!1,description:r,fields:i}}case"ZodRecord":return{kind:"unknown",optional:!1,description:r};case"ZodUnion":{let o=fn(n);for(let i of o){let s=ee(i);if(ne(s)==="ZodObject")return{...be(i),description:r}}return{kind:"unknown",optional:!1,description:r}}case"ZodIntersection":case"ZodPipe":case"ZodTransform":case"ZodEffects":{let o=Q(n);return o?{...be(o),description:r}:{kind:"unknown",optional:!1,description:r}}default:return{kind:"unknown",optional:!1,description:r}}}function qk(e,n){let t=n.toLowerCase(),r=t.indexOf(".");if(r===-1)return null;let o=t.slice(0,r),i=t.slice(r+1),s=e.find(c=>c.id===o);if(!s)return null;let a=i;a.startsWith("api.")&&(a=a.slice(4));let u=Ee(s.endpointMeta,a),l=Ee(s.endpointSchemas,a);return!u&&!l?null:{input:l?.input?be(l.input):null,output:l?.output?be(l.output):null,description:u?.description}}var Co=["equals","contains","startsWith","endsWith","in"],Kc=["equals","gt","gte","lt","lte","in"],qc=["equals"],Zc=["equals","before","after","between"];function Xs(e){let n=ee(e);switch(ne(n)){case"ZodOptional":case"ZodNullable":case"ZodDefault":case"ZodCatch":{let r=Q(n);return r?Xs(r):null}case"ZodString":return"string";case"ZodNumber":return"number";case"ZodBoolean":return"boolean";case"ZodDate":return"date";default:return null}}function vo(e){let n=ee(e),t=ne(n);if(wo(t)){let i=Q(n);return i?vo(i):{}}if(t!=="ZodObject")return{};let r=$t(e,n),o={};for(let[i,s]of Object.entries(r)){let a=Xs(s);a==="string"?o[i]={type:"string",operators:Co}:a==="number"?o[i]={type:"number",operators:Kc}:a==="boolean"?o[i]={type:"boolean",operators:qc}:a==="date"&&(o[i]={type:"date",operators:Zc})}return o}function Qs(e,n){for(let[t,r]of Object.entries(e))if(t.toLowerCase()===n)return[t,r]}function ho(e,n,t){for(let[r,o]of Object.entries(e)){let i=[...n,r];typeof o=="function"?t.push(i.join(".")):o!==null&&typeof o=="object"&&ho(o,i,t)}}function bo(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function ko(e,n,t){for(let[r,o]of Object.entries(e)){let i=[...n,r];bo(o)?t.push(i.join(".")):o!==null&&typeof o=="object"&&ko(o,i,t)}}function To(e,n){if(n.length===0)return null;let[t,...r]=n,o=Object.entries(e).find(([a])=>a.toLowerCase()===t);if(!o)return null;let[i,s]=o;if(r.length===0)return bo(s)?[i]:null;if(s!==null&&typeof s=="object"&&!bo(s)){let a=To(s,r);if(a!==null)return[i,...a]}return null}function ea(e,n){let t=[];t.push(`${e}({`),t.push(" webhookHooks: {");for(let i=0;i<n.length;i++){let s=" ".repeat(i+2);t.push(`${s}${n[i]}: {`)}let r=" ".repeat(n.length+2),o=r+" ";t.push(`${r}before(ctx, args) {`),t.push(`${o}return { ctx, args };`),t.push(`${r}},`),t.push(`${r}after(ctx, response) {`),t.push(`${r}},`);for(let i=n.length-1;i>=0;i--){let s=" ".repeat(i+2);t.push(`${s}},`)}return t.push(" },"),t.push("})"),t.join(`
|
|
50
|
+
`)}var Gc=new Set($n);function Ke(e,n){let t=n?.type??"api",r=n?.plugin;if(r!==void 0){let i=e.find(a=>a.id===r);if(!i)return Gc.has(r)?`This plugin (${r}) is not configured. Please add it to the Corsair instance to see its associated methods.`:Ke(e);if(t==="webhooks"){if(!i.webhooks)return[];let a=[];return ko(i.webhooks,[],a),a.map(u=>`${i.id}.webhooks.${u}`)}if(t==="db"){let a=i.schema?.entities;return a?Object.keys(a).map(u=>`${i.id}.db.${u}.search`):[]}if(!i.endpoints)return[];let s=[];return ho(i.endpoints,[],s),s.map(a=>`${i.id}.api.${a}`)}let o={};if(t==="webhooks")for(let i of e){if(!i.webhooks)continue;let s=[];ko(i.webhooks,[],s),o[i.id]=s.map(a=>`${i.id}.webhooks.${a}`)}else if(t==="db")for(let i of e){let s=i.schema?.entities;s&&(o[i.id]=Object.keys(s).map(a=>`${i.id}.db.${a}.search`))}else for(let i of e){if(!i.endpoints)continue;let s=[];ho(i.endpoints,[],s),o[i.id]=s.map(a=>`${i.id}.api.${a}`)}return o}function Ee(e,n){if(e){for(let[t,r]of Object.entries(e))if(t.toLowerCase()===n)return r}}function zc(e,n){let t=e.toLowerCase(),r=n.toLowerCase();if(!t.startsWith(`${r}.`)){let i=t.slice(n.length+1),s=i.startsWith(".")?i.slice(1):i;return s.startsWith("api.")&&(s=s.slice(4)),{shortPath:s,lookupKey:s}}let o=e.slice(n.length+1);return o.toLowerCase().startsWith("api.")&&(o=o.slice(4)),{shortPath:o,lookupKey:o.toLowerCase()}}function mo(e,n){return typeof e=="string"?e:Array.isArray(e)?`${n}:
|
|
51
|
+
${e.join(", ")}`:`${n}:
|
|
52
|
+
`+Object.entries(e).map(([t,r])=>` ${t}: ${r.join(", ")}`).join(`
|
|
53
|
+
`)}function Zk(e,n){let t=n.toLowerCase(),r=t.indexOf(".");if(r!==-1){let o=t.slice(0,r),i=t.slice(r+1),s=e.find(a=>a.id===o);if(s){if(i.startsWith("db.")){let c=i.slice(3),d=c.lastIndexOf(".");if(d!==-1){let p=c.slice(0,d),g=c.slice(d+1),f=s.schema?.entities;if(g==="search"&&f){let h=Qs(f,p);if(h){let[k,b]=h,C=vo(b),T=[`Search ${o} ${k} stored in the local database.`,"Pass limit and offset as numbers for pagination.","","filters {",` entity_id: string [${Co.join(", ")}]`];for(let[D,E]of Object.entries(C))T.push(` ${D}?: ${E.type} [${E.operators.join(", ")}]`);return T.push("}"),T.join(`
|
|
54
|
+
`)}}}return mo(Ke(e,{type:"db"}),"Path not found. Available db operations")}if(i.startsWith("webhooks.")){let c=i.slice(9);if(s.webhooks){let d=To(s.webhooks,c.split("."));if(d!==null){let p=d.join("."),g=Ee(s.webhookSchemas,p.toLowerCase()),f=g?.response?Z(g.response):null,h=[];return g?.description&&h.push(g.description),g?.payload&&h.push(`payload ${Lt(yn(g.payload))}`),f&&h.push(`response: ${f}`),h.push(`usage:
|
|
55
|
+
${ea(o,d)}`),h.join(`
|
|
56
|
+
|
|
57
|
+
`)}}return mo(Ke(e,{type:"webhooks"}),"Path not found. Available webhooks")}let a=i;a.startsWith("api.")&&(a=a.slice(4));let u=Ee(s.endpointMeta,a),l=Ee(s.endpointSchemas,a);if(u||l){let c=[],d=[u?.riskLevel?`[${u.riskLevel}]`:"",u?.irreversible?"[irreversible]":""].filter(Boolean).join(" "),p=[u?.description,d].filter(Boolean).join(" ");return p&&c.push(p),l?.input&&c.push(`input ${Lt(yn(l.input))}`),l?.output&&c.push(`output ${Lt(yn(l.output))}`),c.join(`
|
|
58
|
+
|
|
59
|
+
`)}}}return mo(Ke(e),"Path not found. Available operations")}function zs(e){let n=e;for(;;){let t=ee(n),r=ne(t);if(wo(r)){let o=Q(t);if(!o)return n;n=o;continue}return n}}function yn(e){if(e===void 0)return{kind:"inline",type:"unknown"};let n=zs(e),t=ee(n);if(ne(t)==="ZodObject"){let o=$t(n,t),i=[];for(let[s,a]of Object.entries(o)){let u=ee(a),l=ne(u),c=l==="ZodOptional"||l==="ZodNullable",d=zs(a),p=jc(a);i.push({key:s,optional:c,type:Z(d),...p!==void 0?{description:p}:{}})}return{kind:"object",fields:i}}return{kind:"inline",type:Z(n)}}function Lt(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=Gs.repeat(n+1),r=Gs.repeat(n);return`{
|
|
60
|
+
${e.fields.map(i=>{let s=i.optional?`${i.key}?`:i.key,a=i.description?` // ${i.description}`:"";return`${t}${s}: ${i.type}${a}`}).join(`
|
|
61
|
+
`)}
|
|
62
|
+
${r}}`}return"unknown"}function Jc(e,n){let t=Ke(e,{plugin:n,type:"api"});if(typeof t=="string")return{ok:!1,error:t};if(!Array.isArray(t))return{ok:!1,error:"list_operations did not return a path array \u2014 pass a configured plugin id."};let r=e.find(c=>c.id===n);if(!r)return{ok:!1,error:`Plugin "${n}" is not configured on this instance.`};let o=[];for(let c of t){let{shortPath:d,lookupKey:p}=zc(c,n),g=Ee(r.endpointMeta,p),f=Ee(r.endpointSchemas,p);!g&&!f||o.push({path:c,shortPath:d,description:g?.description,riskLevel:g?.riskLevel,irreversible:g?.irreversible,input:yn(f?.input),output:yn(f?.output)})}o.sort((c,d)=>c.path.localeCompare(d.path));let i=[],s=Ke(e,{plugin:n,type:"webhooks"});if(Array.isArray(s)&&r.webhooks)for(let c of s){let p=c.toLowerCase().slice(n.length+1),g=p.startsWith(".")?p.slice(1):p;if(!g.startsWith("webhooks."))continue;let f=g.slice(9),h=To(r.webhooks,f.split("."));if(h===null)continue;let k=h.join("."),b=Ee(r.webhookSchemas,k.toLowerCase()),C=b?.response?Z(b.response):void 0;i.push({path:c,description:b?.description,payload:yn(b?.payload),responseType:C,usageExample:ea(n,h)})}i.sort((c,d)=>c.path.localeCompare(d.path));let a=[],u=Ke(e,{plugin:n,type:"db"}),l=r.schema?.entities;if(Array.isArray(u)&&l)for(let c of u){let p=c.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=Qs(l,k);if(!C)continue;let[T,D]=C,E=vo(D),M=Object.entries(E).map(([w,A])=>({field:w,type:A.type,operators:A.operators}));a.push({path:c,entityName:T,filters:[{field:"entity_id",type:"string",operators:Co},...M]})}return a.sort((c,d)=>c.path.localeCompare(d.path)),{ok:!0,data:{pluginId:n,api:o,webhooks:i,db:a}}}import{randomUUID as na}from"crypto";async function Vc(e,n){let t=await e.keys.get_access_token();if(!t)return null;let r=na(),o=na(),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 Yc}from"crypto";var Wt="https://graph.microsoft.com/v1.0",Po=2e4,Xc=60;async function Qc(e,n){let t=await e.keys.get_access_token();if(!t)return null;let r={authorization:`Bearer ${t}`};try{let u=await fetch(`${Wt}/subscriptions`,{headers:r,signal:AbortSignal.timeout(Po)});if(u.ok){let{value:l}=await u.json(),c=(l??[]).filter(d=>d.notificationUrl===n.webhookUrl);await Promise.all(c.map(d=>fetch(`${Wt}/subscriptions/${d.id}`,{method:"DELETE",headers:r,signal:AbortSignal.timeout(Po)}).catch(()=>{})))}}catch{}let o=Yc(),i=new Date(Date.now()+Xc*6e4).toISOString(),s=await fetch(`${Wt}/subscriptions`,{method:"POST",headers:{...r,"content-type":"application/json"},signal:AbortSignal.timeout(Po),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 ta(e,n){for(let[t,r]of Object.entries(e))if(r?.pluginWebhookMatcher&&r.pluginWebhookMatcher(n))return t;return null}function el(e,n){let t=ta(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 nl(e){let n={};for(let t of e)!t.pluginWebhookMatcher&&!t.pluginTenantWebhookMatcher||(n[t.id]={pluginWebhookMatcher:t.pluginWebhookMatcher,pluginTenantWebhookMatcher:t.pluginTenantWebhookMatcher});return n}function ra(e,n){let t=n.toLowerCase(),r=e[t]??e[n];return Array.isArray(r)?r[0]:typeof r=="string"?r:void 0}function oa(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 Nn(e){return!e||typeof e!="object"||Array.isArray(e)?null:e}function tl(e){return Nn(e.body)}function ia(e,n){let t=e.query;if(!t)return;let r=t[n]??t[n.toLowerCase()];return jt(Array.isArray(r)?r:[r])}function sa(e){let n=e.headers??{},t=[n.validationtoken,n.validationToken,n["validation-token"],n["ms-validation-token"]];for(let u of t){let l=jt(Array.isArray(u)?u:[u]);if(l)return decodeURIComponent(l)}let r=ia({query:e.query},"validationToken");if(r)return r;let o=["x-forwarded-uri","x-original-uri","x-rewrite-url","x-envoy-original-path","referer"];for(let u of o){let l=n[u],c=Array.isArray(l)?l[0]:l;if(!(!c||typeof c!="string"))try{let p=(c.startsWith("http")?new URL(c):new URL(`https://example.invalid${c.startsWith("/")?c:`/${c}`}`)).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=Nn(typeof i=="string"?(()=>{try{return JSON.parse(i)}catch{return i}})():i);return jt([s?.validationToken])??null}function rl(e){if(sa(e))return!0;let n=Nn(e.body??e.payload);return ra(e.headers??{},"content-type")?.includes("text/plain")?!n||Object.keys(n).length===0:!1}function jt(e){for(let n of e){let t=oa(n);if(t)return t}}function ol(e){let t=Nn(e.message)?.data;if(typeof t!="string")return null;try{return JSON.parse(Buffer.from(t,"base64").toString("utf8"))}catch{return null}}var Fn=Symbol.for("corsair:internal");function ca(e){let n=e.database?Io(e.database):void 0,t=Bt(e.kek,!!n),r=n&&t?Ps(e.plugins,n,t):Ft(!!n,!!t),o=As(e),i={plugins:e.plugins,database:n,kek:t,multiTenancy:!!e.multiTenancy,permissions:o,manual:e.manual,hub:e.hub?zn(e.hub):void 0},s=Pi(n),a=Ls(i);if(e.multiTenancy){let c=Object.assign({withTenant:d=>{if(!d)throw new Error("corsair.withTenant(tenantId): tenantId must be a non-empty string");let p=yo(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,{[Fn]:i})},keys:r,permissions:s,manage:a},{[Fn]:i});return aa(c,i.hub),ua(c,i.hub),c}let u=yo(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({},u,{keys:r,permissions:s,manage:a,[Fn]:i});return aa(l,i.hub),ua(l,i.hub),l}function aa(e,n){n?.projectApiKey?.startsWith("ck_dev_")&&import("./loop-UGODWXLA.js").then(t=>t.startConnectLoop(e)).catch(()=>{})}function il(e){return e?.projectApiKey?.startsWith("ck_dev_")?e.tunnel!==!1&&process.env.CORSAIR_TUNNEL!=="0":!1}var Kt=globalThis.__corsairTunnels??=new Set;function ua(e,n){if(!il(n))return;let t=n.projectApiKey;if(Kt.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}Kt.add(t);let o=typeof n.tunnel=="object"?n.tunnel:{},i=process.env.CORSAIR_FRP_HOST??o.shareHost??Gt;import("./hub/tunnel/run-tunnel.js").then(s=>s.runTunnel({port:r,apiUrl:n.apiUrl,apiKey:t,shareHost:i,onClose:()=>Kt.delete(t)})).then(({url:s})=>{console.log(`[corsair] tunnel active: ${s}${zt}`)}).catch(s=>{Kt.delete(t),console.warn(`[corsair] tunnel failed to start: ${s instanceof Error?s.message:String(s)}. Run \`corsair setup\` to enable your dev tunnel.`)})}var sl={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:{}}}},Ao=sl;async function ot(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=_o(e);if(!a)throw new Error("setupCorsair: invalid corsair instance");if(!a.database)throw new Error("setupCorsair: a database must be configured on the corsair instance");let u=bl(e,a.plugins,n),l={...a,database:a.database},c=l.database.db;await Cl(c,i);let d=await vl(c,l,u.tenantId,u.provisionAccounts,o);n?.credentials&&Object.keys(n.credentials).length>0&&await Al(e,u,n.credentials,l,o,i);let p=await xl(d,u,o,s);if(n?.backfill){o("[corsair:setup] Starting backfill...");let g=ca({plugins:a.plugins,database:c,kek:a.kek,multiTenancy:!0}).withTenant(u.tenantId);await Il(g,a.plugins,p,o,i),o("[corsair:setup] Backfill complete.")}return t.join(`
|
|
63
|
+
`)}function Ro(e,n,t){let r=t==="integration"?e.authConfig?.[n]?.integration??[]:e.authConfig?.[n]?.account??[];return new Set([...L[n][t],...r])}function hl(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=Ro(o,i,"account");for(let a of Object.keys(r))if(s.has(a))return!0}return!1}function bl(e,n,t){let r=Eo(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&&hl(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 da(e,n){return Ce(e)?n===0?!0:Object.values(e).every(t=>da(t,n-1)):!1}function kl(e){return da(e,4)}var wl={...Mo};function qt(e){if(e instanceof pl){let n={};for(let[t,r]of Object.entries(e.shape))n[t]=r instanceof ml?qt(r):"unknown";return n}return e instanceof ll?`${qt(e.unwrap())} | null`:e instanceof gl?`${qt(e.unwrap())} | undefined`:e instanceof cl?e.options.join(" | "):e instanceof yl?"string":e instanceof dl?"number":e instanceof al?"boolean":e instanceof ul?"date":e instanceof fl?"jsonb":"unknown"}async function Cl(e,n){let t=await e.introspection.getTables(),r=new Set(t.map(o=>o.name));for(let[o,i]of Object.entries(wl))r.has(o)||n(`[corsair:setup] Table "${o}" does not exist. Run your database migrations before calling setupCorsair.
|
|
64
|
+
Schema: ${JSON.stringify(qt(i),null,2)}`)}async function vl(e,n,t,r,o){let i=new Date,s=new Map;for(let a of n.plugins){let u=a.id,l=I(a),c=await e.selectFrom("corsair_integrations").selectAll().where("name","=",u).executeTakeFirst();if(!c){let h=crypto.randomUUID();await e.insertInto("corsair_integrations").values({id:h,name:u,config:{},created_at:i,updated_at:i}).execute(),c=await e.selectFrom("corsair_integrations").selectAll().where("id","=",h).executeTakeFirst(),o(`[corsair:setup] Created integration: ${u}`)}let d=l?a.authConfig?.[l]?.integration??[]:[],p=l?a.authConfig?.[l]?.account??[]:[],g=l&&c?N({authType:l,integrationName:u,kek:n.kek,database:n.database,extraIntegrationFields:d}):void 0;if(c&&!c.dek&&g&&(await g.issue_new_dek(),o(`[corsair:setup] Issued integration DEK: ${u}`)),!c||!l||!g)continue;let f;if(r){let h=await e.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",t).where("integration_id","=",c.id).executeTakeFirst();if(!h){let k=crypto.randomUUID();await e.insertInto("corsair_accounts").values({id:k,tenant_id:t,integration_id:c.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: ${u}`)}f=h&&H({authType:l,integrationName:u,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: ${u}`))}s.set(u,{pluginId:u,authType:l,integration:g,account:f,integrationFields:[...L[l].integration,...d],accountFields:r?[...L[l].account,...p]:[]})}return s}function Tl(e){if(!Ce(e))return;let n=e.keys;return Ce(n)?n:void 0}function Pl(e,n){return"withTenant"in e&&typeof e.withTenant=="function"?e.withTenant(n):e}async function Al(e,n,t,r,o,i){let s=Tl(e),a=n.provisionAccounts?Pl(e,n.tenantId):void 0;for(let[u,l]of Object.entries(t)){let c=r.plugins.find(b=>b.id===u);if(!c){i(`[corsair:setup] Unknown plugin '${u}' \u2014 skipping credentials.`);continue}let d=I(c);if(!d){i(`[corsair:setup] Plugin '${u}' has no auth type \u2014 skipping credentials.`);continue}let p=Ro(c,d,"integration"),g=Ro(c,d,"account"),f=s?.[u],h=a?.[u],k=Ce(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] '${u}.${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 T=G(f,`set_${b}`);if(!T){i(`[corsair:setup] Cannot set integration field '${b}' for '${u}'.`);continue}await T(C),o(`[corsair:setup] Set ${u} integration.${b}`);continue}if(g.has(b)){if(n.multiTenant&&!n.tenantIdProvided)throw new Error(`setupCorsair: tenantId is required to set account-level credential '${u}.${b}' on a multi-tenant instance`);let T=G(k,`set_${b}`);if(!T){i(`[corsair:setup] Cannot set account field '${b}' for '${u}'.`);continue}await T(C),o(`[corsair:setup] Set ${u} account.${b} (tenant=${n.tenantId})`);continue}i(`[corsair:setup] Unknown credential field '${b}' for plugin '${u}'.`)}}}var la=new Set(["webhook_signature","expires_at","scope","redirect_url"]);async function Rl(e,n,t,r,o,i,s,a,u){let l=[],c=[];for(let p of o){if(la.has(p))continue;let g=G(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(la.has(p))continue;let g=G(r,`get_${p}`);if(!g)continue;let f=null;try{let h=await g();f=typeof h=="string"?h:null}catch{}f||c.push(p)}let d=l.length===0&&c.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,...c];if(u==="cli"){let g=p.map(f=>`${f}=VALUE`).join(" ");a(`[corsair:setup] '${e}' (${n}) needs credentials. Run:
|
|
65
|
+
corsair setup --${e} ${g}`)}else{let g=[`[corsair:setup] '${e}' (${n}) needs credentials. Call:`];for(let f of l)g.push(` await corsair.keys.${e}.set_${f}(value)`);for(let f of c){let h=s.provisionAccounts?s.tenantId==="default"?`corsair.${e}`:`corsair.withTenant(${JSON.stringify(s.tenantId)}).${e}`:`corsair.withTenant(<tenant>).${e}`;g.push(` await ${h}.keys.set_${f}(value)`)}a(g.join(`
|
|
66
|
+
`))}}return d}async function xl(e,n,t,r){let o=new Set;for(let i of e.values())await Rl(i.pluginId,i.authType,i.integration,i.account,i.integrationFields,i.accountFields,n,t,r)&&o.add(i.pluginId);return o}async function Il(e,n,t,r,o){if(!kl(Ao)){o("[corsair:setup] Backfill config is invalid - skipping backfill.");return}let i=Ao,s=new Set(n.map(a=>a.id));for(let[a,u]of Object.entries(i)){if(!s.has(a))continue;if(!t.has(a)){r(`[corsair:setup] Skipping backfill for '${a}' \u2014 auth not configured.`);continue}let l=Ce(e)?e[a]:void 0,c=Ce(l)?l.api:void 0;if(c)for(let[d,p]of Object.entries(u))for(let[g,f]of Object.entries(p)){r(`[corsair:setup] Backfilling ${a} \u203A ${d}.${g}...`);try{let h=Ce(c)?c[d]:void 0;await G(h,g)?.(f)}catch(h){o(`[corsair:setup] ${a} \u203A ${d}.${g} failed: `+(h instanceof Error?h.message:String(h)))}}}}export{Bo as a,ve as b,Wn as c,jn as d,Kn as e,qe as f,Fo as g,qn as h,nr as i,bn as j,jo as k,Ko as l,Te as m,Me as n,le as o,Ge as p,ze as q,Pe as r,rr as s,Zo as t,Cn as u,de as v,vn as w,or as x,zn as y,F as z,Jn as A,Je as B,pe as C,ge as D,Y as E,ir as F,Tn as G,Ae as H,fe as I,Pn as J,N as K,H as L,Qo as M,ei as N,ot as O,Al as P,xe as Q,ar as R,Xe as S,Qe as T,cr as U,tt as V,li as W,Ne as X,j as Y,lr as Z,In as _,fi as $,Ja as aa,it as ba,Up as ca,hi as da,bi as ea,ki as fa,dr as ga,st as ha,pr as ia,ut as ja,ct as ka,rn as la,dt as ma,br as na,Ti as oa,kr as pa,Ar as qa,Rr as ra,wt as sa,xr as ta,an as ua,un as va,Ct as wa,vt as xa,Sn as ya,Ir as za,Sr as Aa,Tt as Ba,_n as Ca,Pt as Da,At as Ea,Se as Fa,cn as Ga,Fi as Ha,Mr as Ia,Hr as Ja,Le as Ka,On as La,Mn as Ma,Dt as Na,Nr as Oa,Hn as Pa,nc as Qa,sc as Ra,cc as Sa,Gi as Ta,zi as Ua,Ji as Va,Vi as Wa,$e as Xa,We as Ya,Wr as Za,jr as _a,Kr as $a,qr as ab,Zr as bb,je as cb,B as db,Gr as eb,ts as fb,rs as gb,zr as hb,Jr as ib,Vr as jb,Yr as kb,Xr as lb,Qr as mb,eo as nb,no as ob,to as pb,ro as qb,oo as rb,io as sb,so as tb,ao as ub,uo as vb,gn as wb,U as xb,Is as yb,Ss as zb,_s as Ab,Es as Bb,Ds as Cb,Os as Db,Ms as Eb,Hs as Fb,Bs as Gb,Fs as Hb,Ns as Ib,Us as Jb,$s as Kb,Lc as Lb,rt as Mb,Zs as Nb,qk as Ob,Ke as Pb,Zk as Qb,Lt as Rb,Jc as Sb,Vc as Tb,Wt as Ub,Qc as Vb,ta as Wb,el as Xb,nl as Yb,ra as Zb,oa as _b,Nn as $b,tl as ac,ia as bc,sa as cc,rl as dc,jt as ec,ol as fc,Fn as gc,ca as hc,il as ic};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { T as Tenant, C as CreateTenantInput, P as PluginInfo, a as ConnectionStatus, b as PermissionRecord, c as ConnectLink, d as CreateConnectLinkInput, O as OAuthCallbackResult, e as OAuthCallbackInput } from '../../types-
|
|
2
|
-
export { f as PermissionLookupInput } from '../../types-
|
|
3
|
-
import { C as CorsairClientOptions, a as CorsairManagementClient } from '../../types-
|
|
1
|
+
import { T as Tenant, C as CreateTenantInput, P as PluginInfo, a as ConnectionStatus, b as PermissionRecord, c as ConnectLink, d as CreateConnectLinkInput, O as OAuthCallbackResult, e as OAuthCallbackInput } from '../../types-TZLkC0wi.js';
|
|
2
|
+
export { f as PermissionLookupInput } from '../../types-TZLkC0wi.js';
|
|
3
|
+
import { C as CorsairClientOptions, a as CorsairManagementClient } from '../../types-OmoMr-B2.js';
|
|
4
4
|
import '../../index-eydqYIn0.js';
|
|
5
5
|
import 'zod';
|
|
6
6
|
|