corsair 0.1.122 → 0.1.124
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-IXPIBTH2.js +66 -0
- package/dist/client/react/index.d.ts +3 -3
- package/dist/{connect-T3HADHZ2.js → connect-K3DEFQJW.js} +1 -1
- package/dist/core.d.ts +6 -6
- package/dist/core.js +1 -1
- package/dist/hub/tunnel/run-tunnel.js +1 -1
- 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-HRJJRT5L.js → loop-C3QS4HV3.js} +1 -1
- package/dist/oauth.d.ts +2 -2
- package/dist/oauth.js +1 -1
- package/dist/setup-Y6N7P6MY.js +1 -0
- package/dist/setup-introspect-JISZAHLI.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 +2 -2
- package/dist/chunk-3TC2WIUS.js +0 -1
- package/dist/chunk-H66F2BLQ.js +0 -66
- package/dist/setup-QTI7NP2N.js +0 -1
- package/dist/setup-introspect-AGBGQAOZ.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 Zt,c as Gt}from"./chunk-4OLKWKJG.js";import{a as Io,b as Ce,c as So,d as v,e as W,f as _o,g as G,h as L,i as I,j as Ln,k as Eo,l as Do,m as qt,n as Oo,o as Mo}from"./chunk-VOH7OVWP.js";import{a as xo}from"./chunk-F2EV3CHK.js";import{ZodBoolean as sl,ZodDate as al,ZodEnum as ul,ZodNullable as cl,ZodNumber as ll,ZodObject as dl,ZodOptional as pl,ZodRecord as gl,ZodString as fl,ZodType as yl}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"],Ho={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=Ho[e];return n||e.charAt(0).toUpperCase()+e.slice(1)}function _(e){return typeof e=="string"&&e.length>0}function pa(e){return e==="ready"||e==="partial"||e==="not_started"||e==="missing_integration"}function ga(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)||!pa(r.status)||!ga(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 Ze(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 fa(e){return Array.isArray(e)?e.filter(n=>typeof n=="string"):[]}function ya(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 ma(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 Bo(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=ya(o.fields),a=fa(o.missingRequiredFields),u=ma(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 Fo(e){return e.replace(/\/$/,"")}function zt(e){if(!e.projectApiKey.startsWith("ck_dev_"))return null;try{return we()}catch{return null}}function No(e){let n=zt(e);return n?{"x-corsair-delivery-url":n}:{}}async function Uo(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 Lo(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=Fo(e.hub.apiUrl),t=await fetch(`${n}${e.path}`,{method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${e.hub.projectApiKey}`,...No(e.hub)},body:JSON.stringify(e.body)}),r=await Uo(t);if(!t.ok)throw new Error(Lo(r,t.status,e.notFoundMessage));return e.parseResponse(r)}async function $(e){let n=Fo(e.hub.apiUrl),t=await fetch(`${n}${e.path}`,{method:"GET",headers:{authorization:`Bearer ${e.hub.projectApiKey}`,...No(e.hub)}}),r=await Uo(t);if(!t.ok)throw new Error(Lo(r,t.status,e.notFoundMessage));return e.parseResponse(r)}function Zn(e){return e&&typeof e=="object"?e:{}}function $o(e){let n=Zn(e);return{chatId:n.threadId,message:n.message,workflowId:n.workflowId??null,action:n.action}}async function Jt(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:$o(r.reply)}}})}async function Vt(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:$o})}async function Yt(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 Xt(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 Ta}from"crypto";var ha="corsair:client-bridge";function Qt(e){return new URL(e).origin}function Ge(e){let n=JSON.stringify({type:ha,requestId:e.requestId,ok:e.ok,body:e.body??null,error:e.error??null}),t=JSON.stringify(Qt(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 ba=new Set(["localhost","127.0.0.1","[::1]","::1"]);function er(e){try{let{hostname:n,protocol:t}=new URL(e);return t!=="http:"&&t!=="https:"?!1:ba.has(n)}catch{return!1}}function bn(e){return e==="development"?"browser":"server"}function Wo(e){return bn(e)==="browser"}function jo(e){return er(e)?"Production delivery URL must be a public URL, not localhost":null}import{randomBytes as va}from"crypto";var Te=60*1e3,Me=300*1e3;import{createHmac as ka,randomBytes as wa,timingSafeEqual as Ca}from"crypto";function le(){return wa(16).toString("base64url")}function kn(e,n){let t=n.trim();if(!t)throw new Error("Signing secret is required");return ka("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(!Ca(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 nr(e){return encodeURIComponent(e).replace(/\./g,"%2E")}function Ko(e){let n=e.trim();return n.length>0?n:null}function ze(e,n){let t=new URL(e);return t.searchParams.set("d",n),t.toString()}function Je(e,n){if(!Ko(n))throw new Error("Signing secret is required for browser delivery tokens");let t=Math.floor(Date.now()/1e3),r={...e,jti:e.jti??va(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 Ko(n)?ie(e,n):null}function Pa(e){let n=Qt(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 tr(e){let n=Je(Pa(e),e.signingSecret);return ze(e.deliveryUrl,n)}function qo(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=Ta(),r={...e,hubOrigin:e.hubOrigin,requestId:t};return{transport:"browser",requestId:t,deliveryUrl:tr(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 rr(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 rr(e)}function Aa(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||!Aa(n))throw new de;return n}function Zo(e){return e.replace(/\/$/,"")}function Jn(e){return e.oauthCallbackUrl?Zo(e.oauthCallbackUrl.trim()):`${Zo(e.apiUrl)}/oauth/callback`}function Ve(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 Go,createDecipheriv as zo,randomBytes as Vn,scrypt as Ra}from"crypto";import{promisify as xa}from"util";var Jo=xa(Ra),Yn="aes-256-gcm",Vo=12,Xn=16,Ia=16,Be=32;function pe(){return Vn(Be).toString("base64")}async function ge(e,n){let t=Vn(Ia),r=await Jo(n,t,Be),o=Vn(Vo),i=Go(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 Jo(n,s,Be),d=zo(Yn,c,a,{authTagLength:Xn});return d.setAuthTag(u),Buffer.concat([d.update(l),d.final()]).toString("utf8")}function or(e,n){let t=Buffer.from(n,"base64"),r=Vn(Vo),o=Go(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=zo(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]=or(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 Yo(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 ir=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:ir(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},...Yo(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:ir(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:ir(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},...Yo(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 Xo(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 Qo(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 Sa=new Set(["webhook_signature","expires_at","scope","redirect_url","refresh_token"]);function Re(e){return Sa.has(e)}function _a(e,n){return Re(n)?!1:e==="oauth_2"?n==="client_id"||n==="client_secret":!0}function Ea(e){return!Re(e)}function Da(e){switch(e){case"oauth_2":case"managed":return["access_token"];case"api_key":return["api_key"];case"bot_token":return["bot_token"]}}function Oa(e,n){return e!=="oauth_2"&&e!=="managed"?!1:n.some(t=>t.level==="account"&&t.name==="expires_at"&&t.configured)}function Ma(e,n){let t=i=>n.find(s=>s.level==="account"&&s.name===i);if(!Da(e).every(i=>t(i)?.configured))return!1;let o=t("refresh_token");return o?.required?!!o.configured:!0}async function ei(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 Ha(e,n){let r=e.authConfig?.[n]?.integration??[];return[...L[n].integration,...r]}function Ba(e,n){let r=e.authConfig?.[n]?.account??[];return[...L[n].account,...r]}function Fa(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:Ma(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=Ha(n,r),d=Ba(n,r),p=[];for(let g of c)p.push({name:g,level:"integration",required:_a(r,g),configured:await ei(u,g)});for(let g of d)p.push({name:g,level:"account",required:Ea(g),configured:await ei(l,g)});if(Oa(r,p)){let g=p.find(f=>f.level==="account"&&f.name==="refresh_token");g&&(g.required=!0)}return Fa(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 ni=Symbol.for("corsair:internal"),ti=new WeakMap,ri=new WeakMap;function Na(e,n){let t=n.map(r=>r.id).sort().join("\0");return`${e}\0${t}`}function Ua(e){if(e.database){let t=ti.get(e.database);return t||(t=new Map,ti.set(e.database,t)),t}let n=ri.get(e);return n||(n=new Map,ri.set(e,n)),n}function La(e){return e.multiTenancy?{withTenant:()=>({}),[ni]:e}:{[ni]:e}}async function Ye(e,n){if(!e.database)return;let t=n.trim()||"default",r=Ua(e),o=Na(t,e.plugins),i=r.get(o);if(i){await i;return}let s=(async()=>{let{setupCorsair:a}=await import("./setup-Y6N7P6MY.js");await a(La(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 sr(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 Xe(e,n){let t=Rn.createHmac("sha256",n).update(e).digest("base64url");return`${e}.${t}`}var ar=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:sr(r,{maxAgeMs:ar})}function oi(e){return{tenantId:e.tenantId,plugin:e.plugin,authType:e.authType??"oauth_2",status:"ready",connected:!0,verified:!0,webhookLink:e.link}}function ii(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 Qe(e,n){await x({hub:e,path:"/connections/report",body:oi(n),parseResponse:()=>({ok:!0})}).catch(()=>{})}function $a(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 Wa(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&&ai(e.hub,ii({tenantId:r,plugin:e.plugin.id,authType:o.authType,status:o.status,connected:o.connected,verified:e.verified??o.connected,missingFields:o.missingRequiredFields}))}function si(e,n){$a(e,n)}function ai(e,n){x({hub:e,path:"/connections/report",body:n,parseResponse:()=>({ok:!0})}).catch(()=>{})}function xn(e){Wa(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&&si(e,ii({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 ui=e=>{if(!e)return{};if(typeof e=="string")try{return JSON.parse(e)}catch{return{}}return e};async function ja(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 Ka(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=ui(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 en(e){let{database:n,kek:t,pluginId:r,tenantId:o,link:i,authType:s,extraAccountFields:a=[]}=e,{accountId:u}=await ja({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 Ka({database:n,kek:t,accountId:u,link:i})}async function ur(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=ui(a.config)[o];if(!c)continue;if(Tn(c,u)===i)return a}catch{continue}return null}async function tt(e){return(await ur(e))?.tenant_id??null}async function ci(e){return tt({database:e.database,kek:e.kek,pluginId:e.pluginId,linkType:e.match.linkType,externalId:e.match.externalId})}import*as li 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}?${li.stringify(i)}`}async function di(e,n){try{return await $({hub:e,path:`/webhooks/endpoint?plugin=${encodeURIComponent(n)}`,parseResponse:t=>t?.url??null})}catch{return null}}async function nn(e,n,t,r){if(!n.subscribe)return;let o=F(e),i=await di(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 pi(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 qa(e,n,t,r){let o=Mo(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 cr(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=pi(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=Xe(xe(n,r),s.kek);return{url:Ne({oauthConfig:u,clientId:c,redirectUri:o,state:d}),state:d}}function Za(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=pi(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 qa(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=Za(g,n.callbackParams),k=await nt(i.plugins,s,h);if(k){try{let b=u.authConfig?.oauth_2?.account??[];await en({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&&Qe(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 nn(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 Ga(e){let{corsair:n,internal:t,rows:r}=e,o=e.subscribeAndReport??nn,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 gi(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 Ga({corsair:e,internal:n,rows:t.filter(r=>!!r.tenantId)})}function za(e,n={}){let t=!1,r=()=>{t||(t=!0,gi(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 fi(e){if(!v(e).database)throw new Error("A database must be configured to provision Corsair integrations");await ot(e,{silent:!0})}async function tn(e,n){let t=v(e);if(!t.database)throw new Error("A database must be configured to provision Corsair for connect");await Ye(t,n)}var Ja=Symbol.for("corsair:internal"),Va=new Set(["access_token","refresh_token","expires_at","scope"]);function Ya(e){return e==="oauth_2"||e==="managed"?"oauth":e==="bot_token"?"bot_token":"api_key"}function Xa(e,n){return e==="oauth_2"||e==="managed"?n.filter(t=>!Re(t)&&!Va.has(t)):n.filter(t=>!Re(t))}function yi(e){return{plugins:e.plugins,database:e.database,kek:e.kek,multiTenancy:e.multiTenancy??!1}}function Qa(e){return{plugins:e.plugins,database:e.database,kek:e.kek,multiTenancy:e.multiTenancy??!1}}function eu(e){return{[Ja]:yi(e)}}async function it(e,n,t={}){let r=Jn(e.hub),o=[],i=t.pluginIds?new Set(t.pluginIds):null,s=yi(e),a=eu(e);for(let u of e.plugins){if(i&&!i.has(u.id))continue;let l=I(u);if(!l)continue;let c=Ya(l),d=t.providerNameOverrides?.[u.id]??ve(u.id),p=await Fe(s,u,n),g=Ln(u,l),f=Xa(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 cr(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 Np(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 mi(e,n){if(!e.database)throw new Error("A database must be configured to provision Corsair for connect");await Ye(e.internalConfig??Qa(e),n)}async function hi(e,n){await tn(e,n)}async function bi(e,n){let t=Ve(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 lr(e,n){let t={plugins:n.plugins,database:n.database,kek:n.kek,hub:e,multiTenancy:n.multiTenancy};await mi(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 bi(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 hi(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 bi(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 nu(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 nu(e,n,t){let{buildConnectPluginManifestFromContext:r,ensureConnectAccountRowsFromContext:o}=await import("./setup-introspect-JISZAHLI.js"),{postHubConnectSession:i}=await import("./connect-K3DEFQJW.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 rn(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 tu(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 dr(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=tu(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 ou}from"async_hooks";import{randomBytes as iu}from"crypto";import{v4 as su}from"uuid";async function ut(e,n){let t=Ve(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 pr="Permission approval required. Set manual.approvalBaseUrl (or use hub for hosted approval) so an approval URL can be generated. Optionally set manual.onApprovalRequired to customize the agent message.";function fr(e){return e?e.approvalBaseUrl!==void 0||e.onApprovalRequired!==void 0:!1}function ki(e,n){return`${e.replace(/\/+$/,"")}/${n}`}function gr(e){return ct(e)}async function yr(e,n){if(fr(e.manual)){let r=e.manual?.approvalBaseUrl?.trim();return r?ki(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:ru(n.args),tenantId:n.tenant_id,expiresAt:n.expires_at})).approvalUrl}catch{return null}}function ru(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 yr(e,n);return{...n,approvalUrl:r}}async function mr(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 yr({manual:t,hub:r},{id:o,token:i,plugin:s,endpoint:a,args:JSON.stringify(u),tenant_id:l,expires_at:c});return fr(t)?g?t?.onApprovalRequired?t.onApprovalRequired({approvalUrl:g}):gr(g):pr:r?g?gr(g):`Action '${d}' requires user approval before it can run. Could not create approval link. Check hub configuration and server logs.`:pr}var on=class extends Error{constructor(n){super(n),Object.setPrototypeOf(this,new.target.prototype),this.name="PermissionRequiredError"}};var Ci=new ou,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 hr(e){return Ci.run(!0,e)}function vi(){return Ci.getStore()===!0}function br(e,n){if(vi()&&n!=="read")throw new dt(e,n)}var au={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 uu(e,n,t){return t!==void 0?t:au[n][e]}function kr(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 Ti(e){return{async find_by_permission_id(n){if(e)return e.db.selectFrom("corsair_permissions").selectAll().where("id","=",n).executeTakeFirst()},async find_by_token(n){if(e)return e.db.selectFrom("corsair_permissions").selectAll().where("token","=",n).executeTakeFirst()},async set_executing(n){e&&await e.db.updateTable("corsair_permissions").set({status:"executing",updated_at:new Date}).where("id","=",n).execute()},async set_completed(n){e&&await e.db.updateTable("corsair_permissions").set({status:"completed",updated_at:new Date}).where("id","=",n).execute()}}}async function wi(e,n,t){let r=Date.now()+t;for(;Date.now()<r;){let o=await e.db.selectFrom("corsair_permissions").select(["id","status"]).where("id","=",n).executeTakeFirst();if(!o)return{result:"blocked",reason:"pending"};if(o.status==="approved")return{result:"allow",onComplete:async()=>{await e.db.updateTable("corsair_permissions").set({status:"completed",updated_at:new Date}).where("id","=",n).execute()}};if(o.status==="denied")return{result:"blocked",reason:"denied"};if(o.status==="expired"||o.status==="failed")return{result:"blocked",reason:"timeout"};await new Promise(i=>setTimeout(i,500))}return{result:"blocked",reason:"timeout"}}async function Pi(e){let n=uu(e.riskLevel,e.mode,e.override);if(n==="allow")return{result:"allow"};let t=e.meta?.irreversible?" (irreversible)":"",r=e.meta?.description?`${e.meta.description}${t}`:`${e.pluginId}.${e.endpointPath}${t}`;if(n==="deny"||!e.db)return console.log(`[corsair/${e.pluginId}] '${e.endpointPath}' blocked \u2014 denied by permission mode '${e.mode}'.`,`
|
|
10
|
+
Action: ${r}`,`
|
|
11
|
+
To allow this, update the permission mode or add an override in your corsair config.`),{result:"blocked",reason:"policy"};let o=JSON.stringify(e.args),i=new Date().toISOString(),s=e.tenantId??"default",a=await e.db.db.selectFrom("corsair_permissions").selectAll().where("plugin","=",e.pluginId).where("endpoint","=",e.endpointPath).where("args","=",o).where("tenant_id","=",s).where("expires_at",">",i).where("status","in",["pending","approved","executing"]).orderBy("created_at","desc").limit(1).executeTakeFirst();if(a){if(a.status==="approved"){let f=e.db,h=a.id;return{result:"allow",onComplete:async()=>{await f.db.updateTable("corsair_permissions").set({status:"completed",updated_at:new Date}).where("id","=",h).execute()}}}return a.status==="executing"?{result:"allow"}:(console.log(`[corsair/${e.pluginId}] '${e.endpointPath}' blocked \u2014 approval already pending.`,`
|
|
12
|
+
Action: ${r}`,`
|
|
13
|
+
Permission ID: ${a.id}`,`
|
|
14
|
+
Use the token to approve or deny this request.`),(typeof e.approvalMode=="function"?e.approvalMode():e.approvalMode)==="synchronous"?wi(e.db,a.id,e.timeoutMs??600*1e3):{result:"blocked",reason:"pending",id:a.id,token:a.token,expiresAt:a.expires_at})}let u=su(),l=iu(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"?wi(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 Ai(e,n){return W(e,n,t=>Ie(t))}async function Ri(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 xi(e,n){let t=e.options?.authType??null,r=e.oauthConfig,{configured:o,missingFields:i}=await Ri(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 sn(e){return Promise.all(e.plugins.map(n=>xi(n,e)))}async function gt(e,n){let t=Ai(e,n);return xi(t,e)}async function cu(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 Ii(e,n){let t=await cu(e,n),r=t.filter(o=>o.hasCredentials).map(o=>o.integrationName);return{id:n,accounts:t,connectedPlugins:r}}async function an(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 Ii(e,n)}async function yt(e,n){let t=n?.id?.trim();if(!t)throw me("Tenant id is required",{missingFields:["id"]});return Ii(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 wr(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 lu(e){if(!e.oauthConfig)throw me(`Plugin '${e.id}' has no oauthConfig`)}function du(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 Cr(e){let n=du(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 pu(e){let n=!!e.hub,t=rn(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 Si(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 gu(e,n){let t=n?.plugin?.trim();if(!t)throw me("Plugin id is required",{missingFields:["plugin"]});let r=n.tenantId?.trim()||"default",o=Ai(e,t);lu(o);let i=Cr(e);Si(e);let s=await Ri(o,e);if(!s.configured)throw new P(400,"missing_credentials",`Plugin '${t}' is missing OAuth client credentials`,{missingFields:s.missingFields});let a=Xe(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()+ar).toISOString()}}async function fu(e,n,t){Si(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 pu(n),n.hub?fu(e,n,t):gu(n,t)}async function bt(e,n,t){if(n.hub&&!rn(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"]});Cr(n);try{return await dr(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&&!rn(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=Cr(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 vr(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 _i(e,n){return"id"in n?wr(e,n.id):vr(e,n.token)}import{createCipheriv as Cu,createDecipheriv as jg,randomBytes as Mi,scryptSync as vu}from"crypto";import{createHmac as Tr,randomUUID as yu,timingSafeEqual as Di}from"crypto";function Pr(e){return e.run??null}function Ar(e){return e.probe??null}function Oi(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=Tr("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":yu()}}}function Rr(e){let n=e.signingSecret.trim();if(!n)return!1;let t=Oi(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=Tr("sha256",n).update(e.body).digest("hex");try{return Di(Buffer.from(i,"utf8"),Buffer.from(t,"utf8"))}catch{return!1}}function un(e){let n=e.signingSecret.trim();if(!n)return{ok:!1,error:"Tunnel signing secret is required"};let t=Oi(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=Tr("sha256",n).update(e.body).digest("hex");try{if(!Di(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 cn(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 xr(e){return Sn(cn(e))}async function Ir(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=cn(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(cn(e))}function mu(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 Ei(e,n=200){let t=e.trim();return t.length<=n?t:`${t.slice(0,n)}\u2026`}var hu="Verify hub.signingSecret in your app matches the signing secret shown in Hub project settings.",bu="Check the delivery URL configured for this environment.";function ku(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})`}. ${hu}`}function wu(e){return`${e.ack.error?`${e.ack.error} (HTTP 404 from ${e.deliveryUrl})`:`Delivery endpoint not found at ${e.deliveryUrl} (HTTP 404)`}. ${bu}`}function _n(e,n){let t=mu(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 ku(e);if(e.status===404)return wu(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}): ${Ei(t)}`:`App failed while processing the delivery (HTTP ${e.status} from ${e.deliveryUrl})`}let n=e.body.trim();return n?`${Ei(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 Tu="aes-256-gcm",Pu=12,Au=16,Ru=16,xu=32;function Iu(e,n){return vu(e.trim(),n,xu)}function Sr(e,n){let t=n.trim();if(!t)throw new Error("Signing secret is required to encrypt sync manifest");let r=Mi(Ru),o=Iu(t,r),i=Mi(Pu),s=Cu(Tu,o,i,{authTagLength:Au}),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 Su=["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 _r(e){if(e instanceof Io)return!1;if(!(e instanceof Error))return!0;let n=e.message.toLowerCase();return!Su.some(t=>n.includes(t))}function _u(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([an(t),sn(t)]),i={tenants:r.map(s=>({id:s.id})),plugins:o.map(s=>{let a=_u(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 Sr(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 tn(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 Er(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 fi(e);let i=new Set(Eo(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 Eu(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();Eu(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 ln(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 tn(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 en({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&&Qe(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 nn(e,d,r,p).catch(g=>{console.warn(`[corsair:managed-oauth] subscribe failed for '${t}' tenant '${r}':`,g)}),{plugin:t,tenantId:r}}function Du(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function Hi(e,n,t=[]){for(let[r,o]of Object.entries(e))if(Du(o)){if(o.match(n))return{webhook:o,path:[...t,r]}}else if(o&&typeof o=="object"){let i=Hi(o,n,[...t,r]);if(i)return i}return null}function Ou(e){let n={};for(let[t,r]of Object.entries(e))n[t.toLowerCase()]=Array.isArray(r)?r[0]:r;return n}function Mu(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 Bi(e,n,t,r,o){let i=Ou(n),s=typeof t=="string"?JSON.parse(t):t;(!s||typeof s=="object"&&Object.keys(s).length===0)&&i["x-goog-resource-uri"]&&(s=Mu(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=Hi(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 Hu}from"crypto";import*as Ue from"vm";var Fi="__corsairFailedStep",Bu=3e4,Dr=class{constructor(n,t){this.wakeAt=n;this.stepName=t}__corsairSleep=!0};function Ni(e){return typeof e=="object"&&e!==null&&e.__corsairSleep===!0}function Ui(e,n){return`st_${Hu("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 Li=new Set(["constructor","prototype","__proto__"]);function he(e,n){if(e===null)return null;let t=typeof e;return t==="function"?Nu(e,n):t==="object"?Fu(e):e}function Fu(e){return new Proxy(e,{get(n,t){if(!Li.has(t))return he(Reflect.get(n,t,n),n)},getPrototypeOf:()=>null,setPrototypeOf:()=>!1,defineProperty:()=>!1,set:()=>!1,deleteProperty:()=>!1})}function Nu(e,n){return new Proxy(e,{apply:(t,r,o)=>Uu(Reflect.apply(t,n,o)),construct(){throw new Error("Workflow code may not construct host objects")},get(t,r){if(!Li.has(r))return he(Reflect.get(t,r,t),t)},getPrototypeOf:()=>null,setPrototypeOf:()=>!1,defineProperty:()=>!1,set:()=>!1,deleteProperty:()=>!1})}function Uu(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 Lu(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 Or(e){let n=e.memoizedSteps??{},t=[],r=0,o=null,i=(async(s,a)=>{if(o)throw o;let u=r++,l=Ui(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(Ni(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[Fi]=s,p}});i.sleep=async(s,a)=>{if(o)throw o;let u=r++,l=Ui(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 Dr(Date.now()+c,s),o};try{await Lu({code:e.code,corsair:e.corsair,payload:e.payload,step:i,timeoutMs:e.timeoutMs??Bu});let s=o;return s?{status:"sleeping",steps:t,sleepUntil:new Date(s.wakeAt).toISOString()}:{status:"completed",steps:t}}catch(s){if(Ni(s))return{status:"sleeping",steps:t,sleepUntil:new Date(s.wakeAt).toISOString()};let a=St(s),u=s!==null&&typeof s=="object"?s[Fi]:void 0;return{status:"failed",steps:t,error:{message:a,...u?{failedStep:u}:{}}}}}import*as _t from"vm";var $i=1e4;async function Mr(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=Wu(e.timeoutMs),o=`(async () => {
|
|
43
|
+
const __result = await (async () => {
|
|
44
|
+
${e.code}
|
|
45
|
+
})();
|
|
46
|
+
return JSON.stringify(__result) ?? 'null';
|
|
47
|
+
})()`;try{let i=await hr(()=>{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:$u(i)}}catch(i){return{status:"error",error:St(i)}}}function $u(e){if(typeof e!="string")throw new Error(`Probe returned a non-string result (${typeof e})`);return JSON.parse(e)}function Wu(e){return typeof e!="number"||!Number.isFinite(e)||e<=0?$i:Math.min(e,$i)}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 ju(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 Ku(e,n){try{return{status:"ok",webhookResponse:{status:200,body:{status:"ok",sync:{encrypted:await En(e,n)}}}}}catch(t){return{status:"failed",retryable:_r(t),error:t instanceof Error?t.message:"Connections sync delivery failed"}}}async function qu(e,n){try{let t=await at(e,n);return ju(t)}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Connect link delivery failed"}}}function Hr(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 Zu(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 Gu(e,n,t,r){let o=await Zu(e,n,t),i={...t.query??{},...o?{tenantId:o}:{}},s=await Bi(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 zu(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 Ju(e,n){return await ln(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 Fr(e,n,t){let r=await Br(e,{token:n},t);if(r.status!=="ok")throw new Error(r.error??"Permission decision failed")}async function Br(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 Vu(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 Yu(e,n){try{return await Er(e,n),{status:"ok"}}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Integration credential delivery failed"}}}function Wi(e,n){let t=e;return n&&typeof t?.withTenant=="function"?t.withTenant(n):e}async function Xu(e,n){try{let t=Wi(e,n.tenantId);return{status:"ok",webhookResponse:{status:200,body:{status:"ok",run:await Or({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 Qu(e,n){try{let t=Wi(e,n.tenantId);return{status:"ok",webhookResponse:{status:200,body:{status:"ok",probe:await Mr({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=Hr(n.headers,"x-corsair-signature"),i=Hr(n.headers,"x-corsair-timestamp"),s=Hr(n.headers,"x-corsair-nonce"),a=!1;if(t.signingSecret?.trim()){let l=un({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 Gu(e,r,u.payload,a);case"oauth.callback":return zu(e,u.payload);case"oauth.tokens":return Ju(e,u.payload);case"permission.approve":return Br(e,u.payload,"approved");case"permission.deny":return Br(e,u.payload,"denied");case"auth.credentials":return Vu(e,u.payload);case"integration.credentials":return Yu(e,u.payload);case"connect.create_link":return qu(e,u.payload);case"connections.sync":{let l=t.signingSecret?.trim();return l?Ku(e,l):{status:"failed",retryable:!1,error:"Tunnel signing secret is required for connections.sync"}}case"run":return t.allowWorkflowExecution?Xu(e,u.payload):{status:"failed",retryable:!1,error:"Workflow execution is not enabled (set allowWorkflowExecution: true)"};case"probe":return t.allowWorkflowExecution?Qu(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 ec(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 Nr=3,nc=250;function tc(e){return e?.name==="AbortError"}async function rc(e){try{return(await e.json())?.ok!==!1}catch{return!0}}async function oc(e,n,t,r,o){for(let i=1;i<=Nr;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 rc(s)||console.warn(`[corsair] hub did not record delivery ${r.deliveryId} (already timed out); the run may be retried`),!0}catch(s){if(tc(s))throw s}i<Nr&&await Ki(nc)}return console.warn(`[corsair] failed to acknowledge delivery ${r.deliveryId} after ${Nr} attempts; the run may be retried`),!1}async function ic(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}=ec(l);return await oc(n,t,o,{deliveryId:s,status:c,body:d},r)?"handled":"error"}var ji=1e3,sc=5e3,ac=3e4;function Ki(e){return new Promise(n=>setTimeout(n,e))}var Ot=globalThis.__corsairConnectLoops??=new Map;function uc(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=ji,c=!1,d=async p=>{c||(console.warn("[corsair] connect loop error; retrying",p),c=!0),s||await Ki(l),l=Math.min(l*2,sc)};try{for(;!s;){a=new AbortController;let p=setTimeout(()=>a?.abort(),ac);try{await ic(e,t,n,a.signal)==="error"?await d("pull or ack failed"):(c=!1,l=ji)}catch(g){if(s)break;await d(g instanceof Error?g.message:g)}finally{clearTimeout(p)}}}finally{i()}})(),{stop:()=>{s=!0,a?.abort(),i()}}}function qi(e){return e==="oauth_2"||e==="managed"?"oauth":e==="bot_token"?"bot_token":"api_key"}function cc(e,n){return n&&!n.has(e.id)?!1:I(e)!==null}async function Zi(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=>cc(l,i)).map(l=>{let c=I(l),d=a.get(l.id);return d?{plugin:l.id,providerName:ve(l.id),authKind:qi(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:qi(c),status:"not_started",connected:!1,fields:[],missingRequiredFields:[]}});return{tenantId:o,plugins:u}}async function Gi(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 zi=1024*1024,Ji=3e4;function $e(e){return e!==void 0&&Number.isFinite(e)&&e>0?e:zi}function We(e){return e!==void 0&&Number.isFinite(e)&&e>=0?e:Ji}function dn(e){return new P(413,"payload_too_large",`Request body exceeds the ${e}-byte limit`)}function lc(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(lc(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 dn(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 Ur=new Map;function Vi(e){let n;try{n=F(e)}catch{return}let t=zt(n);t&&Ur.get(n.projectApiKey)!==t&&(Ur.set(n.projectApiKey,t),x({hub:n,path:"/apps/announce",body:{deliveryUrl:t},parseResponse:()=>({ok:!0})}).catch(()=>{Ur.delete(n.projectApiKey)}))}var dc=[".corsair.dev"];function pc(e){return e==="localhost"||e==="127.0.0.1"||e==="[::1]"||e==="::1"}function gc(e){try{let{hostname:n,protocol:t}=new URL(e);return t!=="http:"&&t!=="https:"?!1:pc(n)?!0:dc.some(r=>n===r.slice(1)||n.endsWith(r))}catch{return!1}}function Yi(e){return!e||!gc(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 Xi(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 Lr(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 $r(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:Ge({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:Ge({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:Lr(i.hubSuccessUrl,{connectedPlugin:i.plugin})}):{type:"redirect",url:Lr(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 Fr(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 ln(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:Ge({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:Ge({hubOrigin:i.hubOrigin,requestId:i.requestId,ok:!1,error:u})}:Le(i)&&i.hubSuccessUrl?{type:"redirect",url:Lr(i.hubSuccessUrl,{error:u})}:Le(i)&&i.hubOrigin&&i.requestId?{type:"text",status:400,headers:{"Content-Type":"text/html; charset=utf-8"},body:Ge({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 Wr(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 jr(e){if(e.type==="redirect")return Response.redirect(e.url,302);let n=new Headers;for(let[t,r]of Object.entries(e.headers??{}))typeof r=="string"&&n.set(t,r);return e.type==="json"?Response.json(e.body,{status:e.status,headers:n}):new Response(e.body,{status:e.status,headers:n})}async function Kr(e,n){return n.method==="GET"?$r(e,n.url):Wr(e,{headers:n.headers,body:n.body??""})}async function qr(e,n){try{let t=await Kr(e,n);return jr(t)}catch(t){if(t instanceof de)return Response.json({error:t.message},{status:503});throw t}}async function je(e,n,t){Vi(e);let r=n.method.toUpperCase(),o=Yi(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 qr(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 Xi(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 pn(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 gn(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 Qi=new WeakMap;function Bn(e,n,t){let r=Qi.get(e);r||(r=new Map,Qi.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 es=300;async function Zr(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+es)return{accessToken:u,expiresAt:Number(l),refreshed:!1};if(!c&&u&&!s){let f=l?Number(l):null;if(f===null||f>d+es)return{accessToken:u,expiresAt:f??d+3600,refreshed:!1}}if(!c)throw new B(o,"managed");let p=await yc(r,o,i,c),g=await gn(t,p,l);return{accessToken:p.access_token,expiresAt:g,refreshed:!0}})}function fc(e){return e.includes("Managed OAuth connection not found")||e.includes("Managed OAuth connection has no tokens")}async function yc(e,n,t,r){try{return await x({hub:e,path:"/oauth/refresh",body:{plugin:n,tenantId:t,refresh_token:r},parseResponse:Ze})}catch(o){let i=o instanceof Error?o.message:"";throw fc(i)?new B(n,"managed"):o}}async function ns(e,n){e._refreshAuth=async()=>(await Zr(n,{forceRefresh:!0})).accessToken}function ts(e){return{delivery:n=>je(e,n),deliveryOptions:n=>je(e,n)}}var rs=1200*1e3;function Gr(){return le()}function zr(){return rs}function Jr(e,n){return wn(e,n,rs)}function Vr(e,n){return ie(e,n)}function Yr(e){return He(e)}var os=600*1e3;function Xr(){return le()}function Qr(){return os}function eo(e,n){return wn(e,n,os)}function no(e,n){return ie(e,n)}function to(e){return nr(e)}function ro(e){return He(e)}function oo(){return le()}function io(e,n,t){return Gn(e,n,Math.floor(t.getTime()/1e3))}function so(e,n){return ie(e,n)}function ao(e){return He(e)}var Ke=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){let t=[];e||t.push("database"),n||t.push("kek");let r={};return new Proxy(r,{get(o,i){if(e&&!n)throw new Ke;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 mc(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 is(e){let{integrationId:n,accountId:t}=await mc(e);return{integrationId:n,accountId:t}}function ss(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=>Jt(t(),{tenantId:n,message:r}),list:()=>Yt(t(),{tenantId:n}),get:r=>({message:o=>Vt(t(),{chatId:r,tenantId:n,message:o}),listMessages:()=>Xt(t(),{chatId:r,tenantId:n})})}}function uo(e,n){return`[auth-missing:${e}] Authentication required. Direct the user to connect their account: ${n}`}async function hc(e,n){let t=e.hub;if(!t||!n.database||!n.kek)return null;try{return(await lr(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 bc(e){let n=e.hub;if(n&&e.database&&e.kek)try{let r=await lr(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}):uo(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 hc({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?uo(e.pluginId,t):`[auth-missing:${e.pluginId}:${e.authType}]`}function kc(e,n,t){let r=Xe(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}):uo(e,i)}async function wc(e){let n=e.tenantId??"default",t=e.error.pluginId;return e.manual&&rn(e.manual)&&e.manual.oauthConfig&&e.manual.kek&&e.error.authType==="oauth_2"?kc(t,{...e.manual,baseUrl:e.manual.baseUrl,kek:e.manual.kek},e.tenantId):e.hub&&e.plugin&&e.kek&&e.database&&e.plugins?bc({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 as(e){let n=await wc(e);throw new B(e.error.pluginId,e.error.authType,n)}var Cc=async(e,n)=>(console.error(`[corsair:${n.pluginId}:${n.operation}]`,{error:e.message,input:n.input}),{maxRetries:0});async function us(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||Cc)(e,i)}function vc(e){return typeof e=="function"}function co({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(vc(D)){let M=E,w=[...s,T].join("."),A=async(R={})=>{let z=l?.[w];br(w,z?.riskLevel??"write");let ce;if(u){let J=z,{result:Un,reason:re,onComplete:hn,token:ke,id:Oe,expiresAt:V}=await Pi({pluginId:o,endpointPath:w,args:R,mode:u.mode,override:u.overrides?.[w],riskLevel:J?.riskLevel??"write",meta:J,db:c,timeoutMs:d?kr(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 mr({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?kr(d.timeout):600*1e3)).toISOString(),operationPath:w}):oe=`Action '${w}' requires user approval before it can run.`,new on(oe)}ce=hn}let S=async(J,Un,re)=>{try{return await D(Un,re)}catch(hn){if(hn instanceof Error){let ke=await us(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,da=(Math.random()-.5)*1e3;V=Math.max(0,oe+da);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 as({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 Ro=await S(0,De.ctx,De.args);return await M.after?.(De.ctx,Ro,De.passToAfter),await ce?.(),h&&f&&xn({hub:f,database:c,kek:k,plugins:b??[],plugin:h,tenantId:p,verified:!0}),Ro};r[T]=A}else if(D&&typeof D=="object"){let M={};co({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 Tc(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function lo({webhooks:e,hooks:n,ctx:t,webhooksTree:r,keyBuilder:o}){for(let[i,s]of Object.entries(e)){let a=n?.[i];if(Tc(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={};lo({webhooks:s,hooks:a,ctx:t,webhooksTree:u,keyBuilder:o}),r[i]=u}}}function cs(e){return e&&typeof e=="object"?e:{}}async function ls(e,n){return $({hub:e,path:`/workflows?tenantId=${encodeURIComponent(n.tenantId)}`,parseResponse:t=>{let r=cs(t).workflows;return Array.isArray(r)?r:[]}})}async function ds(e,n){return $({hub:e,path:`/workflows/${encodeURIComponent(n.workflowId)}?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Workflow "${n.workflowId}" not found`,parseResponse:t=>cs(t).workflow})}async function ps(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 gs(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 fs(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 po(e){return e&&typeof e=="object"?e:{}}async function ys(e,n){return $({hub:e,path:`/runs?tenantId=${encodeURIComponent(n.tenantId)}`,parseResponse:t=>{let r=po(t).runs;return Array.isArray(r)?r:[]}})}async function ms(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=po(t).runs;return Array.isArray(r)?r:[]}})}async function hs(e,n){return $({hub:e,path:`/runs/${encodeURIComponent(n.runId)}?tenantId=${encodeURIComponent(n.tenantId)}`,notFoundMessage:`Run "${n.runId}" not found`,parseResponse:t=>po(t).run})}async function go(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 bs=(e,n)=>go(e,"approve",n),ks=(e,n)=>go(e,"deny",n),ws=(e,n)=>go(e,"cancel",n);function Cs(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?ms(t(),{workflowId:r.workflowId,tenantId:n}):ys(t(),{tenantId:n}),get:r=>hs(t(),{runId:r,tenantId:n}),approve:r=>bs(t(),{runId:r,tenantId:n}),deny:r=>ks(t(),{runId:r,tenantId:n}),cancel:r=>ws(t(),{runId:r,tenantId:n})}}function vs(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)=>ps(t(),{workflowId:o,tenantId:n,status:i});return{list:()=>ls(t(),{tenantId:n}),get:o=>ds(t(),{workflowId:o,tenantId:n}),run:(o,i)=>fs(t(),{workflowId:o,tenantId:n,payload:i?.payload,idempotencyKey:i?.idempotencyKey}),runs:Cs(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)=>gs(t(),{workflowId:o,tenantId:n,name:i})}}function Pc(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 is({database:e,integrationName:n,tenantId:t,ensureProvisioned:r});return o=i,o}}function Ac(e,n,t,r,o){return e?qt(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 fo(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?()=>Ye(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=Pc(t,f.id,c,d);if(h?.entities){let S={};for(let[te,mn]of Object.entries(h.entities)){let De=t?qt(t.db,k,te,h.version,mn):Ac(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;co({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={};lo({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=ss(u,c),p.workflows=vs(u,c),p}function Ts(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 Rc="createCorsair({ approval: ... }) is deprecated. Rename to permissions: { timeout, onTimeout, mode }.";function Ps(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] ${Rc}`),t):n}var As=[{method:"GET",pattern:"/ok",handler:async()=>O(200,pt())},{method:"GET",pattern:"/tenants",handler:async({internal:e})=>O(200,await an(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 sn(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 wr(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 vr(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 As){let t=`${n.method} ${n.pattern}`;if(e.has(t))throw new Error(`Duplicate management route registered: ${t}`);e.add(t)}})();function xc(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 Ic(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 Sc(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 _c="/api/corsair";function U(e,n={}){let t=n.basePath??_c,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 dn(r);let l=new URL(a.url),c=Ic(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 As){if(g.method!==d)continue;let f=xc(g.pattern,c);if(!f)continue;let h=await Sc(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 Ec(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 Dc(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 Oc(e,n,t){let r=[],o=0,i=e();try{let s=await Mt(()=>i.next(),t);for(;s.done!==!0;){let a=Dc(s.value);if(o+=a.byteLength,o>n)throw dn(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 Rs=!1;function Mc(){Rs||(Rs=!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 Hc(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:(Mc(),i=JSON.stringify(e.body));else{let a=e[Symbol.asyncIterator];if(typeof a!="function")return;let u=await Oc(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 dn(r);return typeof i=="string"?i:i}function K(e){e.resume?.()}async function _e(e,n={}){let t=Ec(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&&!Bc.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 Hc(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 Bc=new Set(["connection","keep-alive","proxy-authenticate","proxy-authorization","te","trailer","transfer-encoding","upgrade","content-length"]);function xs(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 Fc(e,n){let t=e[n];return Array.isArray(t)?t[0]:t}function Nc(e){let n=(e.method??"GET").toUpperCase();if(n==="GET"||n==="HEAD"||e.body!==void 0||e.rawBody!==void 0)return;let t=Fc(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 Is(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 Ss(e,n){let t=U(e,n);return async(r,o)=>{Nc(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 _s(e,n){let t=U(e,n);return r=>t(r.req.raw)}function Es(e,n){let t=U(e,n);return{GET:t,POST:t,OPTIONS:t}}function Ds(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 Ft(e,n){let t=U(e,n);return r=>t(r.request)}function Os(e,n){let t=Ft(e,n);return{GET:t,POST:t,OPTIONS:t}}function Ms(e,n){let t=Ft(e,n);return{loader:t,action:t}}function Hs(e,n){let t=Ft(e,n);return{GET:t,POST:t,OPTIONS:t}}function Bs(e,n){let t=Ft(e,n);return{GET:t,POST:t,OPTIONS:t}}function Fs(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 Ns(e,n){return U(e,n)}function Us(e){let n={[Fn]:e};return{ok:pt,tenants:{list:()=>an(e),create:t=>yt(e,t),get:t=>ft(e,t)},plugins:{list:()=>sn(e),get:t=>gt(e,t)},connectionStatus:{get:t=>mt(e,t?.tenantId)},permissions:{get:t=>_i(e,t)},connect:{createLink:t=>ht(n,e,t),resolve:t=>bt(n,e,t),oauthCallback:t=>kt(n,e,t)}}}async function Ls(e,n,t,r,o="pending"){if(!e)return null;try{let i=Do(),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 Uc(e,n,t,r="pending"){try{let o=await e.$getAccountId();return Ls(e.database,o,n,t,r)}catch(o){return console.warn("Failed to log event:",o),null}}import*as Ws from"https";import*as Nt from"querystring";var Lc=["expires_in","refresh_token_expires_in"];function $s(e){let n={...e};for(let t of Lc){let r=e[t];if(typeof r=="string"){let o=Number(r);n[t]=Number.isFinite(o)?o:void 0}}return n}function $c(e){try{return $s(JSON.parse(e))}catch{}if(!e.includes("="))return null;let n=Nt.parse(e);return!n.access_token&&!n.error?null:$s({...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=Nt.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=Ws.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=$c(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 js(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(pn({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:Ze}),c=await gn(t,l,a);return{accessToken:l.access_token,expiresAt:c,refreshed:!0}}async function Ks(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 qs(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 js(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 pn({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&&pn({accessToken:c,expiresAt:d}))return c;if(!p)throw new B(n.plugin,"oauth_2");let g=await Ks({tokenUrl:n.tokenUrl,tokenAuthMethod:n.tokenAuthMethod,bodyFormat:n.bodyFormat,extraParams:n.extraParams,clientId:i,clientSecret:o,refreshToken:p});return await gn(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 pn({accessToken:a,expiresAt:u})?a:s(!1)}var Zs=" ";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 zs(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 Js(e){let n=e.type;return e.element??(typeof n=="string"?void 0:n)}function Lt(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 Vs(e,n){return e.description??n.description}function Wc(e){let n=e;for(;n;){let t=ee(n),r=Vs(n,t);if(r)return r;let o=ne(t);if(ko(o)||o==="ZodPipe"||o==="ZodEffects"||o==="ZodTransform"){n=zs(t,o);continue}break}}function ko(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=Js(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=Lt(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=zs(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=Vs(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=Js(n);return{kind:"array",optional:!1,description:r,items:o?be(o):{kind:"unknown",optional:!1}}}case"ZodObject":{let o=Lt(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 wo=["equals","contains","startsWith","endsWith","in"],jc=["equals","gt","gte","lt","lte","in"],Kc=["equals"],qc=["equals","before","after","between"];function Ys(e){let n=ee(e);switch(ne(n)){case"ZodOptional":case"ZodNullable":case"ZodDefault":case"ZodCatch":{let r=Q(n);return r?Ys(r):null}case"ZodString":return"string";case"ZodNumber":return"number";case"ZodBoolean":return"boolean";case"ZodDate":return"date";default:return null}}function Co(e){let n=ee(e),t=ne(n);if(ko(t)){let i=Q(n);return i?Co(i):{}}if(t!=="ZodObject")return{};let r=Lt(e,n),o={};for(let[i,s]of Object.entries(r)){let a=Ys(s);a==="string"?o[i]={type:"string",operators:wo}:a==="number"?o[i]={type:"number",operators:jc}:a==="boolean"?o[i]={type:"boolean",operators:Kc}:a==="date"&&(o[i]={type:"date",operators:qc})}return o}function Xs(e,n){for(let[t,r]of Object.entries(e))if(t.toLowerCase()===n)return[t,r]}function mo(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"&&mo(o,i,t)}}function ho(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function bo(e,n,t){for(let[r,o]of Object.entries(e)){let i=[...n,r];ho(o)?t.push(i.join(".")):o!==null&&typeof o=="object"&&bo(o,i,t)}}function vo(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 ho(s)?[i]:null;if(s!==null&&typeof s=="object"&&!ho(s)){let a=vo(s,r);if(a!==null)return[i,...a]}return null}function Qs(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 Zc=new Set($n);function qe(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 Zc.has(r)?`This plugin (${r}) is not configured. Please add it to the Corsair instance to see its associated methods.`:qe(e);if(t==="webhooks"){if(!i.webhooks)return[];let a=[];return bo(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 mo(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=[];bo(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=[];mo(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 Gc(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 yo(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=Xs(f,p);if(h){let[k,b]=h,C=Co(b),T=[`Search ${o} ${k} stored in the local database.`,"Pass limit and offset as numbers for pagination.","","filters {",` entity_id: string [${wo.join(", ")}]`];for(let[D,E]of Object.entries(C))T.push(` ${D}?: ${E.type} [${E.operators.join(", ")}]`);return T.push("}"),T.join(`
|
|
54
|
+
`)}}}return yo(qe(e,{type:"db"}),"Path not found. Available db operations")}if(i.startsWith("webhooks.")){let c=i.slice(9);if(s.webhooks){let d=vo(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 ${Ut(yn(g.payload))}`),f&&h.push(`response: ${f}`),h.push(`usage:
|
|
55
|
+
${Qs(o,d)}`),h.join(`
|
|
56
|
+
|
|
57
|
+
`)}}return yo(qe(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 ${Ut(yn(l.input))}`),l?.output&&c.push(`output ${Ut(yn(l.output))}`),c.join(`
|
|
58
|
+
|
|
59
|
+
`)}}}return yo(qe(e),"Path not found. Available operations")}function Gs(e){let n=e;for(;;){let t=ee(n),r=ne(t);if(ko(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=Gs(e),t=ee(n);if(ne(t)==="ZodObject"){let o=Lt(n,t),i=[];for(let[s,a]of Object.entries(o)){let u=ee(a),l=ne(u),c=l==="ZodOptional"||l==="ZodNullable",d=Gs(a),p=Wc(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 Ut(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=Zs.repeat(n+1),r=Zs.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 zc(e,n){let t=qe(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}=Gc(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=qe(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=vo(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:Qs(n,h)})}i.sort((c,d)=>c.path.localeCompare(d.path));let a=[],u=qe(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=Xs(l,k);if(!C)continue;let[T,D]=C,E=Co(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:wo},...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 ea}from"crypto";async function Jc(e,n){let t=await e.keys.get_access_token();if(!t)return null;let r=ea(),o=ea(),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 Vc}from"crypto";var $t="https://graph.microsoft.com/v1.0",To=2e4,Yc=60;async function Xc(e,n){let t=await e.keys.get_access_token();if(!t)return null;let r={authorization:`Bearer ${t}`};try{let u=await fetch(`${$t}/subscriptions`,{headers:r,signal:AbortSignal.timeout(To)});if(u.ok){let{value:l}=await u.json(),c=(l??[]).filter(d=>d.notificationUrl===n.webhookUrl);await Promise.all(c.map(d=>fetch(`${$t}/subscriptions/${d.id}`,{method:"DELETE",headers:r,signal:AbortSignal.timeout(To)}).catch(()=>{})))}}catch{}let o=Vc(),i=new Date(Date.now()+Yc*6e4).toISOString(),s=await fetch(`${$t}/subscriptions`,{method:"POST",headers:{...r,"content-type":"application/json"},signal:AbortSignal.timeout(To),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 na(e,n){for(let[t,r]of Object.entries(e))if(r?.pluginWebhookMatcher&&r.pluginWebhookMatcher(n))return t;return null}function Qc(e,n){let t=na(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 el(e){let n={};for(let t of e)!t.pluginWebhookMatcher&&!t.pluginTenantWebhookMatcher||(n[t.id]={pluginWebhookMatcher:t.pluginWebhookMatcher,pluginTenantWebhookMatcher:t.pluginTenantWebhookMatcher});return n}function ta(e,n){let t=n.toLowerCase(),r=e[t]??e[n];return Array.isArray(r)?r[0]:typeof r=="string"?r:void 0}function ra(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 nl(e){return Nn(e.body)}function oa(e,n){let t=e.query;if(!t)return;let r=t[n]??t[n.toLowerCase()];return Wt(Array.isArray(r)?r:[r])}function ia(e){let n=e.headers??{},t=[n.validationtoken,n.validationToken,n["validation-token"],n["ms-validation-token"]];for(let u of t){let l=Wt(Array.isArray(u)?u:[u]);if(l)return decodeURIComponent(l)}let r=oa({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 Wt([s?.validationToken])??null}function tl(e){if(ia(e))return!0;let n=Nn(e.body??e.payload);return ta(e.headers??{},"content-type")?.includes("text/plain")?!n||Object.keys(n).length===0:!1}function Wt(e){for(let n of e){let t=ra(n);if(t)return t}}function rl(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 ua(e){let n=e.database?xo(e.database):void 0,t=e.kek,r=n&&t?Ts(e.plugins,n,t):Bt(!!n,!!t),o=Ps(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=Ti(n),a=Us(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=fo(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 sa(c,i.hub),aa(c,i.hub),c}let u=fo(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 sa(l,i.hub),aa(l,i.hub),l}function sa(e,n){n?.projectApiKey?.startsWith("ck_dev_")&&import("./loop-C3QS4HV3.js").then(t=>t.startConnectLoop(e)).catch(()=>{})}function ol(e){return e?.projectApiKey?.startsWith("ck_dev_")?e.tunnel!==!1&&process.env.CORSAIR_TUNNEL!=="0":!1}var jt=globalThis.__corsairTunnels??=new Set;function aa(e,n){if(!ol(n))return;let t=n.projectApiKey;if(jt.has(t))return;let r=Number(process.env.PORT);if(!Number.isInteger(r)||r<1||r>65535){console.error("[corsair] PORT is not set \u2014 dev tunnel skipped. Set PORT to your app port, or run `corsair http <port>`.");return}jt.add(t);let o=typeof n.tunnel=="object"?n.tunnel:{},i=process.env.CORSAIR_FRP_HOST??o.shareHost??Zt;import("./hub/tunnel/run-tunnel.js").then(s=>s.runTunnel({port:r,apiUrl:n.apiUrl,apiKey:t,shareHost:i,onClose:()=>jt.delete(t)})).then(({url:s})=>{console.log(`[corsair] tunnel active: ${s}${Gt}`)}).catch(s=>{jt.delete(t),console.warn(`[corsair] tunnel failed to start: ${s instanceof Error?s.message:String(s)}. Run \`corsair setup\` to enable your dev tunnel.`)})}var il={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:{}}}},Po=il;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=So(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=hl(e,a.plugins,n),l={...a,database:a.database},c=l.database.db;await wl(c,i);let d=await Cl(c,l,u.tenantId,u.provisionAccounts,o);n?.credentials&&Object.keys(n.credentials).length>0&&await Pl(e,u,n.credentials,l,o,i);let p=await Rl(d,u,o,s);if(n?.backfill){o("[corsair:setup] Starting backfill...");let g=ua({plugins:a.plugins,database:c,kek:a.kek,multiTenancy:!0}).withTenant(u.tenantId);await xl(g,a.plugins,p,o,i),o("[corsair:setup] Backfill complete.")}return t.join(`
|
|
63
|
+
`)}function Ao(e,n,t){let r=t==="integration"?e.authConfig?.[n]?.integration??[]:e.authConfig?.[n]?.account??[];return new Set([...L[n][t],...r])}function ml(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=Ao(o,i,"account");for(let a of Object.keys(r))if(s.has(a))return!0}return!1}function hl(e,n,t){let r=_o(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&&ml(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 la(e,n){return Ce(e)?n===0?!0:Object.values(e).every(t=>la(t,n-1)):!1}function bl(e){return la(e,4)}var kl={...Oo};function Kt(e){if(e instanceof dl){let n={};for(let[t,r]of Object.entries(e.shape))n[t]=r instanceof yl?Kt(r):"unknown";return n}return e instanceof cl?`${Kt(e.unwrap())} | null`:e instanceof pl?`${Kt(e.unwrap())} | undefined`:e instanceof ul?e.options.join(" | "):e instanceof fl?"string":e instanceof ll?"number":e instanceof sl?"boolean":e instanceof al?"date":e instanceof gl?"jsonb":"unknown"}async function wl(e,n){let t=await e.introspection.getTables(),r=new Set(t.map(o=>o.name));for(let[o,i]of Object.entries(kl))r.has(o)||n(`[corsair:setup] Table "${o}" does not exist. Run your database migrations before calling setupCorsair.
|
|
64
|
+
Schema: ${JSON.stringify(Kt(i),null,2)}`)}async function Cl(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 vl(e){if(!Ce(e))return;let n=e.keys;return Ce(n)?n:void 0}function Tl(e,n){return"withTenant"in e&&typeof e.withTenant=="function"?e.withTenant(n):e}async function Pl(e,n,t,r,o,i){let s=vl(e),a=n.provisionAccounts?Tl(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=Ao(c,d,"integration"),g=Ao(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 ca=new Set(["webhook_signature","expires_at","scope","redirect_url"]);async function Al(e,n,t,r,o,i,s,a,u){let l=[],c=[];for(let p of o){if(ca.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(ca.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 Rl(e,n,t,r){let o=new Set;for(let i of e.values())await Al(i.pluginId,i.authType,i.integration,i.account,i.integrationFields,i.accountFields,n,t,r)&&o.add(i.pluginId);return o}async function xl(e,n,t,r,o){if(!bl(Po)){o("[corsair:setup] Backfill config is invalid - skipping backfill.");return}let i=Po,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{Ho as a,ve as b,Wn as c,jn as d,Kn as e,Ze as f,Bo as g,qn as h,er as i,bn as j,Wo as k,jo as l,Te as m,Me as n,le as o,ze as p,Je as q,Pe as r,tr as s,qo as t,Cn as u,de as v,vn as w,rr as x,zn as y,F as z,Jn as A,Ve as B,pe as C,ge as D,Y as E,or as F,Tn as G,Ae as H,fe as I,Pn as J,N as K,H as L,Xo as M,Qo as N,ot as O,Pl as P,xe as Q,sr as R,Qe as S,en as T,ur as U,tt as V,ci as W,Ne as X,j as Y,cr as Z,In as _,gi as $,za as aa,it as ba,Np as ca,mi as da,hi as ea,bi as fa,lr as ga,st as ha,dr as ia,ut as ja,ct as ka,on as la,dt as ma,hr as na,vi as oa,br as pa,Pr as qa,Ar as ra,wt as sa,Rr as ta,un as ua,cn as va,Ct as wa,vt as xa,Sn as ya,xr as za,Ir as Aa,Tt as Ba,_n as Ca,Pt as Da,At as Ea,Se as Fa,ln as Ga,Bi as Ha,Or as Ia,Mr as Ja,Le as Ka,On as La,Mn as Ma,Dt as Na,Fr as Oa,Hn as Pa,ec as Qa,ic as Ra,uc as Sa,Zi as Ta,Gi as Ua,zi as Va,Ji as Wa,$e as Xa,We as Ya,$r as Za,Wr as _a,jr as $a,Kr as ab,qr as bb,je as cb,B as db,Zr as eb,ns as fb,ts as gb,Gr as hb,zr as ib,Jr as jb,Vr as kb,Yr as lb,Xr as mb,Qr as nb,eo as ob,no as pb,to as qb,ro as rb,oo as sb,io as tb,so as ub,ao as vb,Ke as wb,U as xb,xs as yb,Is as zb,Ss as Ab,_s as Bb,Es as Cb,Ds as Db,Os as Eb,Ms as Fb,Hs as Gb,Bs as Hb,Fs as Ib,Ns as Jb,Ls as Kb,Uc as Lb,rt as Mb,qs as Nb,qk as Ob,qe as Pb,Zk as Qb,Ut as Rb,zc as Sb,Jc as Tb,$t as Ub,Xc as Vb,na as Wb,Qc as Xb,el as Yb,ta as Zb,ra as _b,Nn as $b,nl as ac,oa as bc,ia as cc,tl as dc,Wt as ec,rl as fc,Fn as gc,ua as hc,ol 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
|
|