corsair 0.1.97 → 0.1.99

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { B as BrowserDeliveryPayload } from './index-BHI3widx.js';
1
+ import { B as BrowserDeliveryPayload } from './index-B0R9rnZt.js';
2
2
 
3
3
  /**
4
4
  * Browser (client) delivery — hub redirects the user's browser to the app with `?d=<token>`.
@@ -0,0 +1 @@
1
+ import{b as D,c as P,d as B,e as R}from"./chunk-IGGCNGU2.js";import{Kysely as L}from"kysely";var J=Symbol.for("corsair:internal"),x=class extends Error{constructor(t="Invalid corsair instance"){super(t),this.name="InvalidCorsairInstanceError"}};function _(e){return typeof e=="object"&&e!==null}function S(e){return!_(e)||!Array.isArray(e.plugins)||typeof e.kek!="string"||typeof e.multiTenancy!="boolean"?!1:e.database===void 0?!0:_(e.database)?e.database.db instanceof L:!1}function O(e){if(!e||typeof e!="object")return;let r=Object.getOwnPropertyDescriptor(e,J)?.value;return S(r)?r:void 0}function H(e,t){let r=O(e);if(!r)throw t?.()??new x;return r}function v(e,t){return e.plugins.find(r=>r.id===t)}function G(e,t,r){let n=v(e,t);if(!n)throw r(`Plugin '${t}' not found`);return n}function X(e){return"withTenant"in e&&typeof e.withTenant=="function"}function Y(e,t){if(!e||typeof e!="object")return;let r=e[t];return typeof r=="function"?(...n)=>Reflect.apply(r,e,n):void 0}var F={oauth_2:{integration:["client_id","client_secret","redirect_url"],account:["access_token","refresh_token","expires_at","scope","webhook_signature"]},api_key:{integration:[],account:["api_key","webhook_signature"]},bot_token:{integration:[],account:["bot_token","webhook_signature"]},managed:{integration:[],account:["access_token","refresh_token","expires_at","scope","webhook_signature"]}};function N(e){return e==="oauth_2"||e==="api_key"||e==="bot_token"||e==="managed"}function q(e){let t=e.options?.authType;return N(t)?t:void 0}function V(e,t){let r=e.authConfig,n=F[t].account,i=r?.[t]?.account??[];return[...n,...i]}function Ae(e,t){let r=e.authConfig,n=F[t].integration,i=r?.[t]?.integration??[];return[...n,...i]}import{v7 as ee}from"uuid";function T(){return ee()}import{z as C}from"zod";import{sql as w}from"kysely";function k(e){return e.replace(/'/g,"''")}function W(e){let t=k(e);return w`data->>'${w.raw(t)}'`}function j(e){let t=k(e);return w`(data->>'${w.raw(t)}')::numeric`}function K(e){let t=k(e);return w`(data->>'${w.raw(t)}')::boolean`}function U(e){let t=k(e);return w`(data->>'${w.raw(t)}')::timestamptz`}function te(e){if(typeof e=="string")try{return JSON.parse(e)}catch{return e}return e}function Z(e){let t=e;for(;t;){if(t instanceof C.ZodOptional||t instanceof C.ZodNullable){t=t._def.innerType;continue}if(t instanceof C.ZodDefault){t=t._def.innerType;continue}break}return t}function ne(e){let t=Z(e);if(t instanceof C.ZodString)return"string";if(t instanceof C.ZodNumber)return"number";if(t instanceof C.ZodBoolean)return"boolean";if(t instanceof C.ZodDate)return"date"}function re(e){let t=Z(e);if(!(t instanceof C.ZodObject))return{};let r=t.shape,n={};for(let[i,a]of Object.entries(r)){let u=ne(a);u&&(n[i]=u)}return n}function ie(e,t,r){if(typeof r=="string")return e.where(t,"=",r);if(typeof r=="object"&&r!==null&&!Array.isArray(r)){let n=r;"equals"in n&&typeof n.equals=="string"&&(e=e.where(t,"=",n.equals)),"contains"in n&&typeof n.contains=="string"&&(e=e.where(t,"like",`%${n.contains}%`)),"startsWith"in n&&typeof n.startsWith=="string"&&(e=e.where(t,"like",`${n.startsWith}%`)),"endsWith"in n&&typeof n.endsWith=="string"&&(e=e.where(t,"like",`%${n.endsWith}`)),"in"in n&&Array.isArray(n.in)&&(e=e.where(t,"in",n.in))}return e}function oe(e,t,r){if(typeof r=="number")return e.where(t,"=",r);if(typeof r=="object"&&r!==null&&!Array.isArray(r)){let n=r;typeof n.equals=="number"&&(e=e.where(t,"=",n.equals)),typeof n.gt=="number"&&(e=e.where(t,">",n.gt)),typeof n.gte=="number"&&(e=e.where(t,">=",n.gte)),typeof n.lt=="number"&&(e=e.where(t,"<",n.lt)),typeof n.lte=="number"&&(e=e.where(t,"<=",n.lte)),Array.isArray(n.in)&&(e=e.where(t,"in",n.in))}return e}function se(e,t,r){if(typeof r=="boolean")return e.where(t,"=",r);if(typeof r=="object"&&r!==null&&!Array.isArray(r)){let n=r;typeof n.equals=="boolean"&&(e=e.where(t,"=",n.equals))}return e}function ae(e,t,r){if(r instanceof Date)return e.where(t,"=",r);if(typeof r=="object"&&r!==null&&!Array.isArray(r)){let n=r;if(n.equals instanceof Date&&(e=e.where(t,"=",n.equals)),n.before instanceof Date&&(e=e.where(t,"<",n.before)),n.after instanceof Date&&(e=e.where(t,">",n.after)),Array.isArray(n.between)&&n.between.length===2){let[i,a]=n.between;i instanceof Date&&(e=e.where(t,">=",i)),a instanceof Date&&(e=e.where(t,"<=",a))}}return e}function ue(e,t,r,n){return r==="number"?oe(e,j(t),n):r==="boolean"?se(e,K(t),n):r==="date"?ae(e,U(t),n):ie(e,W(t),n)}function ce(e,t,r){if(typeof r=="object"&&r!==null&&!Array.isArray(r)){let n=r;return"equals"in n&&(e=e.where(t,"=",n.equals)),"contains"in n&&typeof n.contains=="string"&&(e=e.where(t,"like",`%${n.contains}%`)),"startsWith"in n&&typeof n.startsWith=="string"&&(e=e.where(t,"like",`${n.startsWith}%`)),"endsWith"in n&&typeof n.endsWith=="string"&&(e=e.where(t,"like",`%${n.endsWith}`)),"in"in n&&Array.isArray(n.in)&&(e=e.where(t,"in",n.in)),e}return e.where(t,"=",r)}function de(e){return typeof e=="number"?e:typeof e=="bigint"?Number(e):Number.parseInt(String(e??0),10)}function h(e,t,r){return e.selectFrom("corsair_entities").selectAll().where("account_id","=",t).where("entity_type","=",r)}function $(e,t,r,n,i){let a=re(i);function u(o){let l=te(o.data);return{...o,data:i.parse(l)}}return{findByEntityId:async o=>{let l=await t(),c=await h(e,l,r).where("entity_id","=",o).executeTakeFirst();return c?u(c):null},existsByEntityId:async o=>{let l=await t();return await h(e,l,r).select("id").where("entity_id","=",o).executeTakeFirst()!==void 0},findIdByEntityId:async o=>{let l=await t();return(await h(e,l,r).select("id").where("entity_id","=",o).executeTakeFirst())?.id??null},findById:async o=>{let l=await t(),c=await h(e,l,r).where("id","=",o).executeTakeFirst();return c?u(c):null},findManyByEntityIds:async o=>{if(o.length===0)return[];let l=await t();return(await h(e,l,r).where("entity_id","in",o).execute()).map(u)},list:async o=>{let l=await t(),c=h(e,l,r);return typeof o?.limit=="number"&&(c=c.limit(o.limit)),typeof o?.offset=="number"&&(c=c.offset(o.offset)),(await c.execute()).map(u)},search:async o=>{let l=await t(),c=h(e,l,r),d=new Set(["data","limit","offset"]);for(let[y,f]of Object.entries(o))d.has(y)||f===void 0||(c=ce(c,y,f));if(o.data&&typeof o.data=="object")for(let[y,f]of Object.entries(o.data)){if(f===void 0)continue;let g=a[y]??"string";c=ue(c,y,g,f)}return typeof o.limit=="number"&&(c=c.limit(o.limit)),typeof o.offset=="number"&&(c=c.offset(o.offset)),(await c.execute()).map(u)},upsertByEntityId:async(o,l)=>{let c=await t(),d=i.parse(l),s=new Date,y=await h(e,c,r).select("id").where("entity_id","=",o).executeTakeFirst();if(y?.id){await e.updateTable("corsair_entities").set({version:n,data:d,updated_at:s}).where("id","=",y.id).execute();let I=await e.selectFrom("corsair_entities").selectAll().where("id","=",y.id).executeTakeFirst();return u(I)}let f=T();await e.insertInto("corsair_entities").values({id:f,created_at:s,updated_at:s,account_id:c,entity_id:o,entity_type:r,version:n,data:d}).execute();let g=await e.selectFrom("corsair_entities").selectAll().where("id","=",f).executeTakeFirst();return u(g)},deleteById:async o=>{let l=await t(),c=await e.deleteFrom("corsair_entities").where("account_id","=",l).where("entity_type","=",r).where("id","=",o).executeTakeFirst();return Number(c.numDeletedRows)>0},deleteByEntityId:async o=>{let l=await t(),c=await e.deleteFrom("corsair_entities").where("account_id","=",l).where("entity_type","=",r).where("entity_id","=",o).executeTakeFirst();return Number(c.numDeletedRows)>0},count:async()=>{let o=await t(),l=await e.selectFrom("corsair_entities").select(c=>c.fn.countAll().as("count")).where("account_id","=",o).where("entity_type","=",r).executeTakeFirst();return de(l?.count)}}}var le={corsair_integrations:D,corsair_accounts:P,corsair_entities:B,corsair_events:R};function ye(e){return le[e]}function M(e){if(typeof e=="string")try{return JSON.parse(e)}catch{return e}return e}function p(e){if(!e)throw new Error("Corsair database is not configured. Pass `database` to createCorsair(...) to enable ORM.")}function b(e){if(!e)return[];let t=[];for(let r in e){let n=r,i=e[n];if(i!==void 0)if(typeof i=="object"&&i!==null&&!Array.isArray(i)&&!(i instanceof Date)){let a=i;"in"in a&&Array.isArray(a.in)?t.push({field:n,operator:"in",value:a.in}):"like"in a&&typeof a.like=="string"&&t.push({field:n,operator:"like",value:a.like})}else t.push({field:n,value:i})}return t}function m(e,t){if(!t?.length)return e;let r=e;for(let n of t){let i=n.operator??"=";r=r.where(n.field,i,n.value)}return r}function fe(e){return typeof e=="number"?e:typeof e=="bigint"?Number(e):Number.parseInt(String(e??0),10)}function A(e,t){let r=ye(t),n=()=>(p(e),e),i=()=>n().db.selectFrom(t),a=()=>n().db.insertInto(t),u=()=>n().db.updateTable(t),o=()=>n().db.deleteFrom(t);function l(d){let s={};for(let[y,f]of Object.entries(d))s[y]=M(f);return r.parse(s)}function c(d){let s={};for(let[y,f]of Object.entries(d))s[y]=M(f);return r.parse(s)}return{findById:async d=>{p(e);let s=i().selectAll();s=m(s,[{field:"id",value:d}]);let y=await s.executeTakeFirst();return y?l(y):null},findOne:async d=>{p(e);let s=i().selectAll();s=m(s,b(d));let y=await s.executeTakeFirst();return y?l(y):null},findMany:async d=>{p(e);let s=i().selectAll();return s=m(s,b(d?.where)),typeof d?.limit=="number"&&(s=s.limit(d.limit)),typeof d?.offset=="number"&&(s=s.offset(d.offset)),(await s.execute()).map(f=>l(f))},create:async d=>{p(e);let s=new Date,y={id:d.id??T(),created_at:s,updated_at:s,...d},f=await a().values(y).returningAll().executeTakeFirst();return f?l(f):c(y)},update:async(d,s)=>{p(e);let y={...s,updated_at:new Date},f=u().set(y).returningAll();f=m(f,[{field:"id",value:d}]);let g=await f.executeTakeFirst();return g?l(g):null},updateMany:async(d,s)=>{p(e);let y={...s,updated_at:new Date},f=i().select("id");f=m(f,b(d));let g=await f.execute();for(let I of g){let E=u().set(y);E=m(E,[{field:"id",value:I.id}]),await E.execute()}return g.length},delete:async d=>{p(e);let s=o();s=m(s,[{field:"id",value:d}]);let y=await s.executeTakeFirst();return Number(y?.numDeletedRows??0)>0},deleteMany:async d=>{p(e);let s=o();s=m(s,b(d));let y=await s.executeTakeFirst();return Number(y?.numDeletedRows??0)},count:async d=>{p(e);let s=i().select(f=>f.fn.countAll().as("count"));s=m(s,b(d));let y=await s.executeTakeFirst();return fe(y?.count)}}}function pe(e){let t=A(e,"corsair_integrations");return{...t,findByName:r=>t.findOne({name:r}),upsertByName:async(r,n)=>{let i=await t.findOne({name:r});return i?await t.update(i.id,n):t.create({...n,name:r})}}}function ge(e){let t=A(e,"corsair_accounts");return{...t,findByTenantAndIntegration:async(r,n)=>{p(e);let i=await e.db.selectFrom("corsair_integrations").selectAll().where("name","=",n).executeTakeFirst();return i?t.findOne({tenant_id:r,integration_id:i.id}):null},listByTenant:(r,n)=>t.findMany({where:{tenant_id:r},limit:n?.limit,offset:n?.offset}),upsertByTenantAndIntegration:async(r,n,i)=>{let a=await t.findOne({tenant_id:r,integration_id:n});return a?await t.update(a.id,i):t.create({...i,tenant_id:r,integration_id:n})}}}function me(e){let t=A(e,"corsair_entities");return{...t,findByEntityId:({accountId:r,entityType:n,entityId:i})=>t.findOne({account_id:r,entity_type:n,entity_id:i}),findManyByEntityIds:async({accountId:r,entityType:n,entityIds:i})=>i.length===0?[]:(p(e),await e.db.selectFrom("corsair_entities").selectAll().where("account_id","=",r).where("entity_type","=",n).where("entity_id","in",i).execute()),listByScope:({accountId:r,entityType:n,limit:i,offset:a})=>t.findMany({where:{account_id:r,entity_type:n},limit:i,offset:a}),searchByEntityId:async({accountId:r,entityType:n,query:i,limit:a,offset:u})=>{p(e);let o=e.db.selectFrom("corsair_entities").selectAll().where("account_id","=",r).where("entity_type","=",n).where("entity_id","like",`%${i}%`);return typeof a=="number"&&(o=o.limit(a)),typeof u=="number"&&(o=o.offset(u)),await o.execute()},upsertByEntityId:async({accountId:r,entityType:n,entityId:i,version:a,data:u})=>{let o=await t.findOne({account_id:r,entity_type:n,entity_id:i});return o?await t.update(o.id,{version:a,data:u}):t.create({account_id:r,entity_type:n,entity_id:i,version:a,data:u})},deleteByEntityId:async({accountId:r,entityType:n,entityId:i})=>{p(e);let a=await e.db.deleteFrom("corsair_entities").where("account_id","=",r).where("entity_type","=",n).where("entity_id","=",i).executeTakeFirst();return Number(a.numDeletedRows)>0}}}function we(e){let t=A(e,"corsair_events");return{...t,listByAccount:(r,n)=>t.findMany({where:{account_id:r},limit:n?.limit,offset:n?.offset}),listByStatus:(r,n)=>{let i={status:r};return n?.accountId&&(i.account_id=n.accountId),t.findMany({where:i,limit:n?.limit,offset:n?.offset})},listPending:r=>{let n={status:"pending"};return r?.accountId&&(n.account_id=r.accountId),t.findMany({where:n,limit:r?.limit??100})},updateStatus:(r,n)=>t.update(r,{status:n})}}function Q(e){return{integrations:pe(e),accounts:ge(e),entities:me(e),events:we(e)}}function he(e,t,r,n,i){let a=null;async function u(){if(a!==null)return a;p(e);let o=await e.db.selectFrom("corsair_integrations").selectAll().where("name","=",t.integrationName).executeTakeFirst();if(!o)throw new Error(`Integration "${t.integrationName}" not found. Make sure to create the integration first.`);let l=await e.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",t.tenantId).where("integration_id","=",o.id).executeTakeFirst();if(!l)throw new Error(`Account not found for tenant "${t.tenantId}" and integration "${t.integrationName}". Make sure to create the account first.`);return a=l.id,a}return p(e),$(e.db,u,r,n,i)}function z(e){let{database:t,integrationName:r,schema:n,tenantId:i}=e,a=Q(t),u={tenantId:i,integrationName:r},o=null;async function l(){if(o!==null)return o;p(t);let d=await t.db.selectFrom("corsair_integrations").selectAll().where("name","=",r).executeTakeFirst();if(!d)throw new Error(`Integration "${r}" not found. Make sure to create the integration first.`);let s=await t.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",i).where("integration_id","=",d.id).executeTakeFirst();if(!s)throw new Error(`Account not found for tenant "${i}" and integration "${r}". Make sure to create the account first.`);return o=s.id,o}let c={};for(let[d,s]of Object.entries(n.entities))c[d]=he(t,u,d,n.version,s);return{...c,$orm:a,$integrationName:r,$tenantId:i,$getAccountId:l}}function Me(e,t){let r=Q(e);return{$tenantId:t,$orm:r,listAccounts:n=>r.accounts.listByTenant(t,n),findAccountByIntegration:n=>r.accounts.findByTenantAndIntegration(t,n),listEntities:async n=>{p(e);let i=await e.db.selectFrom("corsair_accounts").select("id").where("tenant_id","=",t).execute();if(i.length===0)return[];let a=i.map(o=>o.id),u=e.db.selectFrom("corsair_entities").selectAll().where("account_id","in",a);return n?.entityType&&(u=u.where("entity_type","=",n.entityType)),typeof n?.limit=="number"&&(u=u.limit(n.limit)),typeof n?.offset=="number"&&(u=u.offset(n.offset)),await u.execute()},listEvents:async n=>{p(e);let i=await e.db.selectFrom("corsair_accounts").select("id").where("tenant_id","=",t).execute();if(i.length===0)return[];let a=i.map(o=>o.id),u=e.db.selectFrom("corsair_events").selectAll().where("account_id","in",a);return n?.status&&(u=u.where("status","=",n.status)),typeof n?.limit=="number"&&(u=u.limit(n.limit)),typeof n?.offset=="number"&&(u=u.offset(n.offset)),await u.execute()},forIntegration:n=>z({database:e,integrationName:n.integrationName,schema:n.schema,tenantId:t})}}function Qe(e,t){return{forTenant:r=>z({database:e,integrationName:t.integrationName,schema:t.schema,tenantId:r})}}export{x as a,_ as b,O as c,H as d,G as e,X as f,Y as g,F as h,q as i,V as j,Ae as k,T as l,$ as m,le as n,Q as o,z as p,Me as q,Qe as r};
@@ -0,0 +1,38 @@
1
+ import{a as hr,b as ce,c as kr,d as w,e as H,f as br,g as B,h as O,i as I,j as sn,k as Cr,l as wr,m as Yn,n as Pr,o as Tr}from"./chunk-BPFUYXOD.js";import{a as mr}from"./chunk-IGGCNGU2.js";var an=["agentql","ahrefs","airtable","amplitude","asana","bitwarden","bluesky","box","cal","calendly","cloudflare","cursor","discord","dodopayments","dropbox","exa","figma","firecrawl","fireflies","github","gitlab","gmail","googlecalendar","googledrive","googlemeet","googlesheets","grafana","hackernews","hubspot","instagram","intercom","jira","linear","monday","notion","onedrive","openweathermap","oura","outlook","pagerduty","posthog","razorpay","reddit","resend","sentry","sharepoint","slack","spotify","strava","stripe","supabase","tally","tavily","teams","telegram","todoist","trello","twilio","twitter","twitterapiio","typeform","vapi","xquik","youtube","zendesk","zohomail","zoom"],vr={agentql:"AgentQL",ahrefs:"Ahrefs",airtable:"Airtable",amplitude:"Amplitude",asana:"Asana",bitwarden:"Bitwarden",bluesky:"Bluesky",box:"Box",cal:"Cal",calendly:"Calendly",cloudflare:"Cloudflare",cursor:"Cursor",discord:"Discord",dodopayments:"Dodo Payments",dropbox:"Dropbox",exa:"Exa",figma:"Figma",firecrawl:"Firecrawl",fireflies:"Fireflies",github:"GitHub",gitlab:"GitLab",gmail:"Gmail",googlecalendar:"Google Calendar",googledrive:"Google Drive",googlemeet:"Google Meet",googlesheets:"Google Sheets",grafana:"Grafana",hackernews:"Hacker News",hubspot:"HubSpot",instagram:"Instagram",intercom:"Intercom",jira:"Jira",linear:"Linear",monday:"Monday",notion:"Notion",onedrive:"OneDrive",openweathermap:"OpenWeatherMap",oura:"Oura",outlook:"Outlook",pagerduty:"PagerDuty",posthog:"PostHog",razorpay:"Razorpay",reddit:"Reddit",resend:"Resend",sentry:"Sentry",sharepoint:"SharePoint",slack:"Slack",spotify:"Spotify",strava:"Strava",stripe:"Stripe",supabase:"Supabase",tally:"Tally",tavily:"Tavily",teams:"Teams",telegram:"Telegram",todoist:"Todoist",trello:"Trello",twilio:"Twilio",twitter:"Twitter",twitterapiio:"Twitter API IO",typeform:"Typeform",vapi:"Vapi",xquik:"XQuik",youtube:"YouTube",zendesk:"Zendesk",zohomail:"Zoho Mail",zoom:"Zoom"};function le(e){let n=vr[e];return n||e.charAt(0).toUpperCase()+e.slice(1)}var Ke="https://auth.corsair.dev";var de=class extends Error{constructor(){super("Hub is not configured. Pass hub: { projectApiKey, signingSecret } to createCorsair()."),this.name="HubNotConfiguredError"}};function un(e){let n=(e.apiUrl?.trim()||Ke).replace(/\/$/,""),t=e.projectApiKey.trim(),r=e.signingSecret.trim();if(!t||!r)throw new Error("Hub config requires non-empty projectApiKey and signingSecret");return{apiUrl:n,projectApiKey:t,signingSecret:r,oauthCallbackUrl:e.oauthCallbackUrl?.trim().replace(/\/$/,"")}}function ai(e){return e.apiUrl.trim().length>0&&e.projectApiKey.trim().length>0&&e.signingSecret.trim().length>0}function J(e){let n=w(e).hub;if(!n||!ai(n))throw new de;return n}function Ar(e){return e.replace(/\/$/,"")}function cn(e){return e.oauthCallbackUrl?Ar(e.oauthCallbackUrl.trim()):`${Ar(e.apiUrl)}/oauth/callback`}function Re(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)")}function v(e){return typeof e=="string"&&e.length>0}function ui(e){return e==="ready"||e==="partial"||e==="not_started"||e==="missing_integration"}function ci(e){return e==="oauth_2"||e==="api_key"||e==="bot_token"||e==="managed"}function ln(e){if(!e||typeof e!="object")throw new Error("Hub API returned an empty connect session");let n=e;if(!v(n.connectUrl)||!v(n.token)||!v(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:v(n.environmentId)?n.environmentId:n.projectId};return v(n.expiresAt)&&(t.expiresAt=n.expiresAt),t}function dn(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(!v(r.tenantId)||!v(r.plugin)||!ui(r.status)||!ci(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:v(r.reportedAt)?r.reportedAt:new Date().toISOString()})}return n}function pn(e){if(!e||typeof e!="object")throw new Error("Hub API returned an empty permission session");let n=e;if(!v(n.approvalUrl)||!v(n.token)||!v(n.projectId)||!v(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 gn(e){if(!e||typeof e!="object")throw new Error("Hub token refresh returned an empty response");let n=e;if(v(n.access_token))return{access_token:n.access_token,refresh_token:v(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:v(n.scope)?n.scope:void 0};throw new Error(v(n.error)?v(n.error_description)?n.error_description:n.error:"Hub token refresh returned no access_token")}function li(e){return Array.isArray(e)?e.filter(n=>typeof n=="string"):[]}function di(e){if(!Array.isArray(e))return[];let n=[];for(let t of e){if(!t||typeof t!="object")continue;let r=t;v(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 pi(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 xr(e){if(!e||typeof e!="object")throw new Error("Connect status response was empty");let n=e;if(!v(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(!v(o.plugin)||typeof o.connected!="boolean")continue;let i=o.authKind==="oauth"||o.authKind==="api_key"||o.authKind==="bot_token"?o.authKind:"api_key",a=di(o.fields),s=li(o.missingRequiredFields),u=pi(o.status,o.connected,a,s);t.push({plugin:o.plugin,providerName:v(o.providerName)?o.providerName:o.plugin,authKind:i,status:u,connected:o.connected,fields:a,missingRequiredFields:s})}return{tenantId:n.tenantId,plugins:t}}function fn(e){if(!e||typeof e!="object")return null;let n=e;return n.error??n.message??null}function Ir(e){return e.replace(/\/$/,"")}async function Sr(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 Rr(e,n,t){if(n===404&&t)return t;let r=fn(e);return r||`Hub API returned HTTP ${n}`}async function pe(e){let n=Ir(e.hub.apiUrl),t=await fetch(`${n}${e.path}`,{method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${e.hub.projectApiKey}`},body:JSON.stringify(e.body)}),r=await Sr(t);if(!t.ok)throw new Error(Rr(r,t.status,e.notFoundMessage));return e.parseResponse(r)}async function _r(e){let n=Ir(e.hub.apiUrl),t=await fetch(`${n}${e.path}`,{method:"GET",headers:{authorization:`Bearer ${e.hub.projectApiKey}`}}),r=await Sr(t);if(!t.ok)throw new Error(Rr(r,t.status,e.notFoundMessage));return e.parseResponse(r)}var gi="3000",fi="/api/corsair";function Qn(e){return e.replace(/\/$/,"")}function yi(e,n){return`${Qn(e)}${n}`}function Er(e){return e.startsWith("http")?e:`https://${e}`}function _e(e){let n=e?.deliveryUrl?.trim();if(n)return Qn(n);let t=e?.deliveryPath?.trim()||fi,r=t.startsWith("/")?t:`/${t}`,o=process.env.CORSAIR_DELIVERY_URL?.trim();if(o)return Qn(Er(o));let i=process.env.APP_URL?.trim()||process.env.NEXT_PUBLIC_APP_URL?.trim()||process.env.VERCEL_URL?.trim();return i?yi(Er(i),r):`http://localhost:${process.env.PORT?.trim()||gi}${r}`}import{createCipheriv as Dr,createDecipheriv as Or,randomBytes as yn,scrypt as mi}from"crypto";import{promisify as hi}from"util";var Mr=hi(mi),mn="aes-256-gcm",Hr=12,hn=16,ki=16,qe=32;function te(){return yn(qe).toString("base64")}async function re(e,n){let t=yn(ki),r=await Mr(n,t,qe),o=yn(Hr),i=Dr(mn,r,o,{authTagLength:hn}),a=Buffer.concat([i.update(e,"utf8"),i.final()]),s=i.getAuthTag();return[t.toString("base64"),o.toString("base64"),s.toString("base64"),a.toString("base64")].join(":")}async function $(e,n){let[t,r,o,i]=e.split(":");if(!t||!r||!o||!i)throw new Error("Invalid encrypted DEK format");let a=Buffer.from(t,"base64"),s=Buffer.from(r,"base64"),u=Buffer.from(o,"base64"),l=Buffer.from(i,"base64"),c=await Mr(n,a,qe),p=Or(mn,c,s,{authTagLength:hn});return p.setAuthTag(u),Buffer.concat([p.update(l),p.final()]).toString("utf8")}function Xn(e,n){let t=Buffer.from(n,"base64"),r=yn(Hr),o=Dr(mn,t,r,{authTagLength:hn}),i=Buffer.concat([o.update(e,"utf8"),o.final()]),a=o.getAuthTag();return[r.toString("base64"),a.toString("base64"),i.toString("base64")].join(":")}function Ze(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"),a=Buffer.from(t,"base64"),s=Buffer.from(r,"base64"),u=Buffer.from(o,"base64"),l=Or(mn,i,a,{authTagLength:hn});return l.setAuthTag(s),Buffer.concat([l.update(u),l.final()]).toString("utf8")}function ge(e,n){let t={};for(let[r,o]of Object.entries(e))t[r]=Xn(o,n);return t}function oe(e,n){let t={};for(let[r,o]of Object.entries(e))t[r]=Ze(o,n);return t}function Ge(e,n,t){let r=oe(e,n);return ge(r,t)}function Fr(e,n,t){let r={};for(let o of t)r[`get_${o}`]=async()=>(await e())[o]??null,r[`set_${o}`]=async i=>{let a=[null,void 0,""].includes(i)?null:i;await n({[o]:a})};return r}var et=e=>{if(!e)return{};if(typeof e=="string")try{return JSON.parse(e)}catch{return{}}return e};function S(e){let{authType:n,integrationName:t,kek:r,database:o,extraIntegrationFields:i=[]}=e,a=[...O[n].integration,...i],s=null,u={kek:r,integrationName:t,getIntegration:async()=>{if(s)return s;let f=await o.db.selectFrom("corsair_integrations").selectAll().where("name","=",t).executeTakeFirst();if(!f)throw new Error(`Integration "${t}" not found. Make sure to create the integration first.`);return s={id:f.id,config:et(f.config),dek:f.dek??null},s},updateIntegration:async f=>{let y=await u.getIntegration();await o.db.updateTable("corsair_integrations").set({...f.config!==void 0?{config:f.config}:{},...f.dek!==void 0?{dek:f.dek}:{},updated_at:new Date}).where("id","=",y.id).execute(),s=null}},l=null,c=async()=>{if(l)return l;let f=await u.getIntegration();if(!f.dek)throw new Error(`No DEK found for integration "${t}". Initialize the integration first.`);return l=await $(f.dek,r),l},p=async()=>{let f=await u.getIntegration(),y=await c(),m=f.config;return!m||Object.keys(m).length===0?{}:oe(m,y)};return{get_dek:c,issue_new_dek:async()=>{let f=await u.getIntegration(),y=te(),m={};if(f.dek){let P=await $(f.dek,r),C=f.config;C&&Object.keys(C).length>0&&(m=Ge(C,P,y))}let h=await re(y,r);return await u.updateIntegration({config:m,dek:h}),l=y,y},...Fr(p,async f=>{let y=await c(),m;try{m=await p()}catch(C){console.error(`[corsair] Failed to decrypt config for integration "${t}", starting fresh:`,C),m={}}let h={...m};for(let[C,_]of Object.entries(f))_===null?delete h[C]:h[C]=_;let P=ge(h,y);await u.updateIntegration({config:P})},a)}}function E(e){let{authType:n,integrationName:t,tenantId:r,kek:o,database:i,extraAccountFields:a=[],ensureProvisioned:s}=e,u=[...O[n].account,...a],l=null,c=null,p=async()=>{if(c)return c;let k=!1;for(;;){let b=await i.db.selectFrom("corsair_integrations").selectAll().where("name","=",t).executeTakeFirst();if(!b){if(!k&&s){k=!0,await s();continue}throw new Error(`Integration "${t}" not found. Make sure to create the integration first.`)}return c={id:b.id,config:et(b.config),dek:b.dek??null},c}},g={kek:o,integrationName:t,tenantId:r,getIntegration:p,getAccount:async()=>{if(l)return l;let k=!1;for(;;){let b=await p(),T=await i.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",r).where("integration_id","=",b.id).executeTakeFirst();if(!T){if(!k&&s){k=!0,await s();continue}throw new Error(`Account not found for tenant "${r}" and integration "${t}". Make sure to create the account first.`)}return l={id:T.id,config:et(T.config),dek:T.dek??null},l}},updateAccount:async k=>{let b=await g.getAccount();await i.db.updateTable("corsair_accounts").set({...k.config!==void 0?{config:k.config}:{},...k.dek!==void 0?{dek:k.dek}:{},updated_at:new Date}).where("id","=",b.id).execute(),l=null}},d=null,f=null,y=async()=>{if(d)return d;let k=await g.getAccount();if(!k.dek)throw new Error(`No DEK found for account (tenant: "${r}", integration: "${t}"). Initialize the account first.`);return d=await $(k.dek,o),d},m=async()=>{if(f)return f;let k=await g.getIntegration();if(!k.dek)throw new Error(`No DEK found for integration "${t}". Initialize the integration first.`);return f=await $(k.dek,o),f},h=async()=>{let k=await g.getAccount(),b=await y(),T=k.config;return!T||Object.keys(T).length===0?{}:oe(T,b)},P=async()=>{let k=await g.getIntegration(),b=await m(),T=k.config;return!T||Object.keys(T).length===0?{}:oe(T,b)},_={get_dek:y,issue_new_dek:async()=>{let k=await g.getAccount(),b=te(),T={};if(k.dek){let X=await $(k.dek,o),D=k.config;D&&Object.keys(D).length>0&&(T=Ge(D,X,b))}let x=await re(b,o);return await g.updateAccount({config:T,dek:x}),d=b,b},...Fr(h,async k=>{let b=await y(),T;try{T=await h()}catch(D){console.error(`[corsair] Failed to decrypt config for account (tenant: "${r}", integration: "${t}"), starting fresh:`,D),T={}}let x={...T};for(let[D,ue]of Object.entries(k))ue===null?delete x[D]:x[D]=ue;let X=ge(x,b);await g.updateAccount({config:X})},u)};return n==="oauth_2"&&(_.get_integration_credentials=async()=>{let k=await P();return{client_id:k.client_id||null,client_secret:k.client_secret||null,redirect_url:k.redirect_url??null}}),_}async function Br(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=te(),i=await re(o,t);return await e.db.updateTable("corsair_integrations").set({dek:i,updated_at:new Date}).where("id","=",r.id).execute(),o}async function Ur(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 a=te(),s=await re(a,r);return await e.db.updateTable("corsair_accounts").set({dek:s,updated_at:new Date}).where("id","=",i.id).execute(),a}var bi=new Set(["webhook_signature","expires_at","scope","redirect_url"]);function Ee(e){return bi.has(e)}function Ci(e,n){return Ee(n)?!1:e==="oauth_2"?n==="client_id"||n==="client_secret":!0}function wi(e){return!Ee(e)}function Pi(e){switch(e){case"oauth_2":case"managed":return["access_token","refresh_token"];case"api_key":return["api_key"];case"bot_token":return["bot_token"]}}function Ti(e,n){return Pi(e).every(r=>n.find(i=>i.level==="account"&&i.name===r)?.configured??!1)}async function Lr(e,n){if(!e)return!1;let t=B(e,`get_${n}`);if(!t)return!1;try{let r=await t();return typeof r=="string"&&r.length>0}catch{return!1}}function vi(e,n){let r=e.authConfig?.[n]?.integration??[];return[...O[n].integration,...r]}function Ai(e,n){let r=e.authConfig?.[n]?.account??[];return[...O[n].account,...r]}function xi(e,n,t){let r=t.filter(s=>s.required&&!s.configured).map(s=>s.name),o=t.filter(s=>s.level==="integration"&&s.required&&!s.configured).map(s=>s.name),i=t.filter(s=>s.level==="account"&&s.required&&s.configured),a;return o.length>0?a="missing_integration":r.length===0?a="ready":i.length>0?a="partial":a="not_started",{plugin:e,authType:n,status:a,connected:Ti(n,t),fields:t,missingRequiredFields:r}}async function De(e,n,t){let r=I(n);if(!r||!e.database||!e.kek)return null;let o=t.trim()||"default",i=n.authConfig,a=i?.[r]?.integration??[],s=i?.[r]?.account??[],u=S({authType:r,integrationName:n.id,kek:e.kek,database:e.database,extraIntegrationFields:a}),l=E({authType:r,integrationName:n.id,tenantId:o,kek:e.kek,database:e.database,extraAccountFields:s}),c=vi(n,r),p=Ai(n,r),g=[];for(let d of c)g.push({name:d,level:"integration",required:Ci(r,d),configured:await Lr(u,d)});for(let d of p)g.push({name:d,level:"account",required:wi(d),configured:await Lr(l,d)});return xi(n.id,r,g)}async function Je(e,n,t={}){let r=n.trim()||"default",o=t.pluginIds?.length?new Set(t.pluginIds):null,i=[];for(let a of e.plugins){if(o&&!o.has(a.id))continue;let s=await De(e,a,r);s&&i.push(s)}return i}function kn(e){return e.connected?"connected":e.status==="missing_integration"?"missing_credentials":"not_connected"}var Nr=Symbol.for("corsair:internal"),$r=new WeakMap;function Ii(e){let n=$r.get(e);return n||(n=new Map,$r.set(e,n)),n}function Si(e){return e.multiTenancy?{withTenant:()=>({}),[Nr]:e}:{[Nr]:e}}async function bn(e,n){if(!e.database)return;let t=n.trim()||"default",r=Ii(e),o=t,i=r.get(o);if(i){await i;return}let a=(async()=>{let{setupCorsair:s}=await import("./setup-LQDKMNCB.js");await s(Si(e),{tenantId:e.multiTenancy?t:void 0,silent:!0})})().finally(()=>{r.delete(o)});r.set(o,a),await a}import{ZodBoolean as _i,ZodDate as Ei,ZodEnum as Di,ZodNullable as Oi,ZodNumber as Mi,ZodObject as Hi,ZodOptional as Fi,ZodRecord as Bi,ZodString as Ui,ZodType as Li}from"zod";var Ri={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:{}}}},nt=Ri;async function wn(e,n){let t=[],r=n?.silent??!1,o=d=>{t.push(d),r||console.log(d)},i=d=>{t.push(d),r||console.warn(d)},a=n?.caller??"script",s=kr(e);if(!s)throw new Error("setupCorsair: invalid corsair instance");if(!s.database)throw new Error("setupCorsair: a database must be configured on the corsair instance");let u=$i(e,s.plugins,n),l={...s,database:s.database},c=l.database.db;await Ki(c,i);let p=await qi(c,l,u.tenantId,u.provisionAccounts,o);n?.credentials&&Object.keys(n.credentials).length>0&&await Ji(e,u,n.credentials,l,o,i);let g=await Vi(p,u,o,a);if(n?.backfill){o("[corsair:setup] Starting backfill...");let d=Kr({plugins:s.plugins,database:c,kek:s.kek,multiTenancy:!0}).withTenant(u.tenantId);await Yi(d,s.plugins,g,o,i),o("[corsair:setup] Backfill complete.")}return t.join(`
2
+ `)}function tt(e,n,t){let r=t==="integration"?e.authConfig?.[n]?.integration??[]:e.authConfig?.[n]?.account??[];return new Set([...O[n][t],...r])}function Ni(e,n){if(!e)return!1;for(let[t,r]of Object.entries(e)){let o=n.find(s=>s.id===t);if(!o)continue;let i=I(o);if(!i)continue;let a=tt(o,i,"account");for(let s of Object.keys(r))if(a.has(s))return!0}return!1}function $i(e,n,t){let r=br(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&&Ni(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 jr(e,n){return ce(e)?n===0?!0:Object.values(e).every(t=>jr(t,n-1)):!1}function Wi(e){return jr(e,4)}var ji={...Pr};function Cn(e){if(e instanceof Hi){let n={};for(let[t,r]of Object.entries(e.shape))n[t]=r instanceof Li?Cn(r):"unknown";return n}return e instanceof Oi?`${Cn(e.unwrap())} | null`:e instanceof Fi?`${Cn(e.unwrap())} | undefined`:e instanceof Di?e.options.join(" | "):e instanceof Ui?"string":e instanceof Mi?"number":e instanceof _i?"boolean":e instanceof Ei?"date":e instanceof Bi?"jsonb":"unknown"}async function Ki(e,n){let t=await e.introspection.getTables(),r=new Set(t.map(o=>o.name));for(let[o,i]of Object.entries(ji))r.has(o)||n(`[corsair:setup] Table "${o}" does not exist. Run your database migrations before calling setupCorsair.
3
+ Schema: ${JSON.stringify(Cn(i),null,2)}`)}async function qi(e,n,t,r,o){let i=new Date,a=new Map;for(let s of n.plugins){let u=s.id,l=I(s),c=await e.selectFrom("corsair_integrations").selectAll().where("name","=",u).executeTakeFirst();if(!c){let y=crypto.randomUUID();await e.insertInto("corsair_integrations").values({id:y,name:u,config:{},created_at:i,updated_at:i}).execute(),c=await e.selectFrom("corsair_integrations").selectAll().where("id","=",y).executeTakeFirst(),o(`[corsair:setup] Created integration: ${u}`)}let p=l?s.authConfig?.[l]?.integration??[]:[],g=l?s.authConfig?.[l]?.account??[]:[],d=l&&c?S({authType:l,integrationName:u,kek:n.kek,database:n.database,extraIntegrationFields:p}):void 0;if(c&&!c.dek&&d&&(await d.issue_new_dek(),o(`[corsair:setup] Issued integration DEK: ${u}`)),!c||!l||!d)continue;let f;if(r){let y=await e.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",t).where("integration_id","=",c.id).executeTakeFirst();if(!y){let m=crypto.randomUUID();await e.insertInto("corsair_accounts").values({id:m,tenant_id:t,integration_id:c.id,config:{},created_at:i,updated_at:i}).execute(),y=await e.selectFrom("corsair_accounts").selectAll().where("id","=",m).executeTakeFirst(),o(`[corsair:setup] Created account: ${u}`)}f=y&&E({authType:l,integrationName:u,tenantId:t,kek:n.kek,database:n.database,extraAccountFields:g}),y&&f&&!y.dek&&(await f.issue_new_dek(),o(`[corsair:setup] Issued account DEK: ${u}`))}a.set(u,{pluginId:u,authType:l,integration:d,account:f,integrationFields:[...O[l].integration,...p],accountFields:r?[...O[l].account,...g]:[]})}return a}function Zi(e){if(!ce(e))return;let n=e.keys;return ce(n)?n:void 0}function Gi(e,n){return"withTenant"in e&&typeof e.withTenant=="function"?e.withTenant(n):e}async function Ji(e,n,t,r,o,i){let a=Zi(e),s=n.provisionAccounts?Gi(e,n.tenantId):void 0;for(let[u,l]of Object.entries(t)){let c=r.plugins.find(h=>h.id===u);if(!c){i(`[corsair:setup] Unknown plugin '${u}' \u2014 skipping credentials.`);continue}let p=I(c);if(!p){i(`[corsair:setup] Plugin '${u}' has no auth type \u2014 skipping credentials.`);continue}let g=tt(c,p,"integration"),d=tt(c,p,"account"),f=a?.[u],y=s?.[u],m=ce(y)?y.keys:void 0;for(let[h,P]of Object.entries(l))if(P){if(g.has(h)){if(n.multiTenant&&n.tenantIdProvided)throw new Error(`[corsair:setup] '${u}.${h}' 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 C=B(f,`set_${h}`);if(!C){i(`[corsair:setup] Cannot set integration field '${h}' for '${u}'.`);continue}await C(P),o(`[corsair:setup] Set ${u} integration.${h}`);continue}if(d.has(h)){if(n.multiTenant&&!n.tenantIdProvided)throw new Error(`setupCorsair: tenantId is required to set account-level credential '${u}.${h}' on a multi-tenant instance`);let C=B(m,`set_${h}`);if(!C){i(`[corsair:setup] Cannot set account field '${h}' for '${u}'.`);continue}await C(P),o(`[corsair:setup] Set ${u} account.${h} (tenant=${n.tenantId})`);continue}i(`[corsair:setup] Unknown credential field '${h}' for plugin '${u}'.`)}}}var Wr=new Set(["webhook_signature","expires_at","scope","redirect_url"]);async function zi(e,n,t,r,o,i,a,s,u){let l=[],c=[];for(let g of o){if(Wr.has(g))continue;let d=B(t,`get_${g}`);if(!d)continue;let f=null;try{let y=await d();f=typeof y=="string"?y:null}catch{}f||l.push(g)}if(r&&i.length>0)for(let g of i){if(Wr.has(g))continue;let d=B(r,`get_${g}`);if(!d)continue;let f=null;try{let y=await d();f=typeof y=="string"?y:null}catch{}f||c.push(g)}let p=l.length===0&&c.length===0;if(p)s(`[corsair:setup] '${e}' (${n}) is configured \u2713`);else if(n==="managed")s(`[corsair:setup] '${e}' (managed) is not connected yet. Use Connect in your app \u2014 Corsair Hub delivers OAuth tokens after authorization.`);else{let g=[...l,...c];if(u==="cli"){let d=g.map(f=>`${f}=VALUE`).join(" ");s(`[corsair:setup] '${e}' (${n}) needs credentials. Run:
4
+ corsair setup --${e} ${d}`)}else{let d=[`[corsair:setup] '${e}' (${n}) needs credentials. Call:`];for(let f of l)d.push(` await corsair.keys.${e}.set_${f}(value)`);for(let f of c){let y=a.provisionAccounts?a.tenantId==="default"?`corsair.${e}`:`corsair.withTenant(${JSON.stringify(a.tenantId)}).${e}`:`corsair.withTenant(<tenant>).${e}`;d.push(` await ${y}.keys.set_${f}(value)`)}s(d.join(`
5
+ `))}}return p}async function Vi(e,n,t,r){let o=new Set;for(let i of e.values())await zi(i.pluginId,i.authType,i.integration,i.account,i.integrationFields,i.accountFields,n,t,r)&&o.add(i.pluginId);return o}async function Yi(e,n,t,r,o){if(!Wi(nt)){o("[corsair:setup] Backfill config is invalid - skipping backfill.");return}let i=nt,a=new Set(n.map(s=>s.id));for(let[s,u]of Object.entries(i)){if(!a.has(s))continue;if(!t.has(s)){r(`[corsair:setup] Skipping backfill for '${s}' \u2014 auth not configured.`);continue}let l=ce(e)?e[s]:void 0,c=ce(l)?l.api:void 0;if(c)for(let[p,g]of Object.entries(u))for(let[d,f]of Object.entries(g)){r(`[corsair:setup] Backfilling ${s} \u203A ${p}.${d}...`);try{let y=ce(c)?c[p]:void 0;await B(y,d)?.(f)}catch(y){o(`[corsair:setup] ${s} \u203A ${p}.${d} failed: `+(y instanceof Error?y.message:String(y)))}}}}async function qr(e){if(!w(e).database)throw new Error("A database must be configured to provision Corsair integrations");await wn(e,{silent:!0})}async function we(e,n){let t=w(e);if(!t.database)throw new Error("A database must be configured to provision Corsair for connect");await bn(t,n)}var Qi=Symbol.for("corsair:internal"),Xi=new Set(["access_token","refresh_token","expires_at","scope"]);function es(e){return e==="oauth_2"||e==="managed"?"oauth":e==="bot_token"?"bot_token":"api_key"}function ns(e,n){return e==="oauth_2"||e==="managed"?n.filter(t=>!Ee(t)&&!Xi.has(t)):n.filter(t=>!Ee(t))}function Zr(e){return{plugins:e.plugins,database:e.database,kek:e.kek,multiTenancy:!1}}function Gr(e){return{[Qi]:Zr(e)}}async function Pn(e,n,t={}){let r=cn(e.hub),o=[],i=t.pluginIds?new Set(t.pluginIds):null,a=Zr(e),s=Gr(e);for(let u of e.plugins){if(i&&!i.has(u.id))continue;let l=I(u);if(!l)continue;let c=es(l),p=t.providerNameOverrides?.[u.id]??le(u.id),g=await De(a,u,n),d=sn(u,l),f=ns(l,d),y={plugin:u.id,providerName:p,authKind:c,alreadyConfigured:g?.connected??!1};if(f.length>0&&(y.credentialFields=f),c==="oauth"){let h=t.oauthModeOverrides?.[u.id]??(l==="managed"?"managed":"byo");if(y.oauthMode=h,!t.skipOAuthUrlGeneration&&h!=="managed")try{let P=await rt(s,u.id,{tenantId:n,redirectUri:r,hubConnect:!0});y.oauthUrl=P.url}catch(P){y.setupError=P instanceof Error?P.message:`Could not prepare OAuth for ${u.id}`}}o.push(y)}return o}async function Cu(e,n,t={}){let r=w(e),o=r.hub;if(!o)throw new Error("Hub is not configured");return Pn({plugins:r.plugins,database:r.database,kek:r.kek,hub:o},n,t)}async function ot(e,n){if(!e.database)throw new Error("A database must be configured to provision Corsair for connect");await we(Gr(e),n)}async function wu(e,n){await we(e,n)}async function Jr(e,n){let t=Re(e.projectApiKey),r={tenantId:n.tenantId,plugins:n.plugins};return t==="development"&&(r.deliveryUrl=_e({deliveryUrl:n.deliveryUrl})),pe({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:ln})}async function it(e,n){let t={plugins:n.plugins,database:n.database,kek:n.kek,hub:e};await ot(t,n.tenantId);let r=await Pn(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 Jr(e,{tenantId:n.tenantId,plugins:r,deliveryUrl:n.deliveryUrl})}async function Tn(e,n){let t=w(e),r=J(e),o={plugins:t.plugins,database:t.database,kek:t.kek,hub:r};await ot(o,n.tenantId);let i=n.plugin?[n.plugin]:void 0,a=n.plugin&&n.oauthMode?{[n.plugin]:n.oauthMode}:void 0,s=n.plugin&&n.providerName?{[n.plugin]:n.providerName}:void 0,u=await Pn(o,n.tenantId,{pluginIds:i,oauthModeOverrides:a,providerNameOverrides:s});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 Jr(r,{tenantId:n.tenantId,plugins:u,deliveryUrl:n.deliveryUrl})}function zr(e){return e==="oauth_2"||e==="managed"?"oauth":e==="bot_token"?"bot_token":"api_key"}function ts(e,n){return n&&!n.has(e.id)?!1:I(e)!==null}async function Vr(e,n,t={}){let r=w(e),o=n.trim()||"default",i=t.pluginIds?.length?new Set(t.pluginIds):null,a=await Je(r,o,{pluginIds:t.pluginIds}),s=new Map(a.map(l=>[l.plugin,l])),u=r.plugins.filter(l=>ts(l,i)).map(l=>{let c=I(l),p=s.get(l.id);return p?{plugin:l.id,providerName:le(l.id),authKind:zr(c),status:p.status,connected:p.connected,fields:p.fields.map(g=>({name:g.name,level:g.level,required:g.required,configured:g.configured})),missingRequiredFields:p.missingRequiredFields}:{plugin:l.id,providerName:le(l.id),authKind:zr(c),status:"not_started",connected:!1,fields:[],missingRequiredFields:[]}});return{tenantId:o,plugins:u}}async function Yr(e,n){let t=J(e);return _r({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:dn})}import*as ze from"crypto";function fe(e,n){return Buffer.from(JSON.stringify({plugin:e,tenantId:n,iat:Date.now()})).toString("base64url")}function st(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 Oe(e,n){let t=ze.createHmac("sha256",n).update(e).digest("base64url");return`${e}.${t}`}var at=600*1e3;function vn(e,n){let t=e.lastIndexOf(".");if(t===-1)return null;let r=e.slice(0,t),o=e.slice(t+1),i=ze.createHmac("sha256",n).update(r).digest("base64url"),a=Buffer.from(o,"base64url"),s=Buffer.from(i,"base64url");return a.length!==s.length||!ze.timingSafeEqual(a,s)?null:st(r,{maxAgeMs:at})}function Me(e){return!!(e?.baseUrl?.trim()&&e?.redirectUri?.trim())}import*as Qr from"querystring";function Pe(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}?${Qr.stringify(i)}`}var W=class extends Error{code;constructor(n,t){super(t),this.name="ConnectError",this.code=n}};function rs(e){let n=e.oauthConfig;if(!n)throw new W("plugin_has_no_oauth_config",`Plugin '${e.id}' has no oauthConfig`);return n}async function ut(e,n){let t=w(e,()=>new W("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new W("no_database","No database configured on corsair instance");let r=t.manual?.redirectUri;if(!r)throw new W("no_redirect_uri","No redirectUri configured. Set manual.redirectUri in createCorsair().");let o=vn(n,t.kek);if(!o)throw new W("invalid_state","Invalid or tampered state parameter");let{plugin:i,tenantId:a}=o,s=H(t,i,g=>new W("plugin_not_found",g)),u=rs(s),c=await S({authType:"oauth_2",integrationName:i,kek:t.kek,database:t.database}).get_client_id();if(!c)throw new W("client_id_not_configured",`client_id not configured for '${i}'`);let p=Pe({oauthConfig:u,clientId:c,redirectUri:r,state:n});return{plugin:i,tenantId:a,providerName:u.providerName,oauthUrl:p,state:n}}import{randomBytes as is}from"crypto";import{v4 as ss}from"uuid";async function An(e,n){let t=Re(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 t==="development"&&(r.deliveryUrl=_e({deliveryUrl:n.deliveryUrl})),pe({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:pn})}function xn(e){return`Approval required. Visit ${e} to approve or deny, then tell the agent to retry this action.`}var ct="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 dt(e){return e?e.approvalBaseUrl!==void 0||e.onApprovalRequired!==void 0:!1}function Xr(e,n){return`${e.replace(/\/+$/,"")}/${n}`}function lt(e){return xn(e)}async function pt(e,n){if(dt(e.manual)){let r=e.manual?.approvalBaseUrl?.trim();return r?Xr(r,n.token):null}let t=e.hub;if(!t)return null;try{return(await An(t,{permissionId:n.id,permissionToken:n.token,plugin:n.plugin,endpoint:n.endpoint,args:os(n.args),tenantId:n.tenant_id,expiresAt:n.expires_at})).approvalUrl}catch{return null}}function os(e){try{return JSON.parse(e)}catch{return e}}async function In(e,n){if(!(n.status==="pending"||n.status==="approved"))return{...n,approvalUrl:null};let r=await pt(e,n);return{...n,approvalUrl:r}}async function gt(e){let{permissionsOptions:n,manual:t,hub:r,permissionId:o,permissionToken:i,plugin:a,endpoint:s,args:u,tenantId:l,expiresAt:c,operationPath:p}=e;if(n?.formatAsyncMessage)return n.formatAsyncMessage({token:i,id:o,plugin:a,endpoint:s,args:u});let d=await pt({manual:t,hub:r},{id:o,token:i,plugin:a,endpoint:s,args:JSON.stringify(u),tenant_id:l,expires_at:c});return dt(t)?d?t?.onApprovalRequired?t.onApprovalRequired({approvalUrl:d}):lt(d):ct:r?d?lt(d):`Action '${p}' requires user approval before it can run. Could not create approval link. Check hub configuration and server logs.`:ct}var as={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 us(e,n,t){return t!==void 0?t:as[n][e]}function ft(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 no(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 eo(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 to(e){let n=us(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}'.`,`
6
+ Action: ${r}`,`
7
+ 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(),a=e.tenantId??"default",s=await e.db.db.selectFrom("corsair_permissions").selectAll().where("plugin","=",e.pluginId).where("endpoint","=",e.endpointPath).where("args","=",o).where("tenant_id","=",a).where("expires_at",">",i).where("status","in",["pending","approved","executing"]).orderBy("created_at","desc").limit(1).executeTakeFirst();if(s){if(s.status==="approved"){let f=e.db,y=s.id;return{result:"allow",onComplete:async()=>{await f.db.updateTable("corsair_permissions").set({status:"completed",updated_at:new Date}).where("id","=",y).execute()}}}return s.status==="executing"?{result:"allow"}:(console.log(`[corsair/${e.pluginId}] '${e.endpointPath}' blocked \u2014 approval already pending.`,`
8
+ Action: ${r}`,`
9
+ Permission ID: ${s.id}`,`
10
+ Use the token to approve or deny this request.`),(typeof e.approvalMode=="function"?e.approvalMode():e.approvalMode)==="synchronous"?eo(e.db,s.id,e.timeoutMs??600*1e3):{result:"blocked",reason:"pending",id:s.id,token:s.token,expiresAt:s.expires_at})}let u=ss(),l=is(32).toString("hex"),c=e.timeoutMs??600*1e3,p=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:a,status:"pending",expires_at:p}).execute(),console.log(`[corsair/${e.pluginId}] '${e.endpointPath}' blocked \u2014 approval required.`,`
11
+ Action: ${r}`,`
12
+ Permission ID: ${u}`,`
13
+ Permission token: ${l}`,`
14
+ Expires at: ${p}`,`
15
+ Use the token to approve or deny this request.`),(typeof e.approvalMode=="function"?e.approvalMode():e.approvalMode)==="synchronous"?eo(e.db,u,c):{result:"blocked",reason:"pending",id:u,token:l,expiresAt:p}}var A=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 R(e,n){return new Response(JSON.stringify(n),{status:e,headers:{"content-type":"application/json"}})}function ro(e){let n={error:e.code,message:e.message,...e.extra};return R(e.status,n)}function ye(e){return new A(404,"not_found",e)}function ie(e,n={}){return new A(400,"bad_request",e,n)}function oo(e,n){return H(e,n,t=>ye(t))}async function io(e,n){let t=e.options?.authType;if(!t||!n.database||!n.kek)return{configured:!1,missingFields:[]};let r=S({authType:t,integrationName:e.id,kek:n.kek,database:n.database}),o=O[t].integration,i=r,a;try{a=await Promise.all(o.map(l=>i[`get_${l}`]()))}catch{a=o.map(()=>null)}let s=o.filter((l,c)=>a[c]==null),u;return t==="oauth_2"?u=!s.includes("client_id")&&!s.includes("client_secret"):u=s.length===0,{configured:u,missingFields:s}}async function so(e,n){let t=e.options?.authType??null,r=e.oauthConfig,{configured:o,missingFields:i}=await io(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 Sn(){return{ok:!0}}async function He(e){return Promise.all(e.plugins.map(n=>so(n,e)))}async function Rn(e,n){let t=oo(e,n);return so(t,e)}async function cs(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 ao(e,n){let t=await cs(e,n),r=t.filter(o=>o.hasCredentials).map(o=>o.integrationName);return{id:n,accounts:t,connectedPlugins:r}}async function Fe(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 a=!!r.dek;i.accounts.push({integrationName:r.integrationName,hasCredentials:a}),a&&i.connectedPlugins.push(r.integrationName)}}return[...n.values()]}async function _n(e,n){if(!n)throw ie("Tenant id must be a non-empty string");return ao(e,n)}async function En(e,n){let t=n?.id?.trim();if(!t)throw ie("Tenant id is required",{missingFields:["id"]});return ao(e,t)}async function Dn(e,n){let t=n?.trim()||"default",r={},o=await Je(e,t);for(let i of o)r[i.plugin]=kn(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 yt(e,n){if(!e.database)throw ye(`Permission '${n}' not found`);let t=await e.database.db.selectFrom("corsair_permissions").selectAll().where("id","=",n).executeTakeFirst();if(!t)throw ye(`Permission '${n}' not found`);return In(e,t)}function ls(e){if(!e.oauthConfig)throw ie(`Plugin '${e.id}' has no oauthConfig`)}function ds(e){if(!e.manual)throw new A(500,"connect_not_configured","createCorsair was not given manual config. Set { manual: { baseUrl, redirectUri } } to enable manual connect routes.");return e.manual}function mt(e){let n=ds(e);if(!n.baseUrl?.trim()||!n.redirectUri?.trim())throw new A(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 ps(e){let n=!!e.hub,t=Me(e.manual);if(!n&&!t)throw new A(500,"connect_not_configured","createCorsair was not given connect config. Set hub: { ... } for Hub mode, or manual: { baseUrl, redirectUri } for manual connect.")}function uo(e){if(!e.database||!e.kek)throw new A(500,"database_not_configured","A database and kek are required to issue connect links.")}async function gs(e,n){let t=n?.plugin?.trim();if(!t)throw ie("Plugin id is required",{missingFields:["plugin"]});let r=n.tenantId?.trim()||"default",o=oo(e,t);ls(o);let i=mt(e);uo(e);let a=await io(o,e);if(!a.configured)throw new A(400,"missing_credentials",`Plugin '${t}' is missing OAuth client credentials`,{missingFields:a.missingFields});let s=Oe(fe(t,r),e.kek),u;try{u=new URL(i.baseUrl)}catch{throw new A(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",s),{connectUrl:u.toString(),expiresAt:new Date(Date.now()+at).toISOString()}}async function fs(e,n,t){uo(n);let o={tenantId:t.tenantId?.trim()||"default",oauthMode:t.oauthMode},i=t.plugin?.trim();i&&(o.plugin=i);let a=t.providerName?.trim();a&&(o.providerName=a);let s=await Tn(e,o);return{connectUrl:s.connectUrl,expiresAt:s.expiresAt}}async function On(e,n,t){return ps(n),n.hub?fs(e,n,t):gs(n,t)}async function Mn(e,n,t){if(n.hub&&!Me(n.manual))throw new A(400,"hub_mode","resolve is not used with hub config. Redirect users to connectUrl from createLink.");let r=t?.trim();if(!r)throw ie("state is required",{missingFields:["state"]});mt(n);try{return await ut(e,r)}catch(o){if(o instanceof W)switch(o.code){case"invalid_state":throw ie("Invalid or expired state");case"client_id_not_configured":throw new A(400,"missing_credentials","OAuth client_id is not configured for this plugin",{missingFields:["client_id"]});case"no_redirect_uri":break}throw new A(500,"resolve_failed","Could not resolve connect link. Check server logs for details.")}}async function Hn(e,n,t){if(n.hub&&!Me(n.manual))throw new A(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 ie("Missing required fields",{missingFields:i});let a=mt(n),{processOAuthCallback:s}=await import("./oauth.js");try{return await s(e,{code:r,state:o,redirectUri:a.redirectUri})}catch(u){if(u instanceof Error&&u.name==="OAuthCallbackError")switch(u.code){case"invalid_state":throw ie("Invalid or expired state");case"credentials_not_configured":throw new A(400,"missing_credentials","OAuth client credentials are not configured for this plugin",{missingFields:["client_id","client_secret"]})}throw new A(502,"oauth_callback_failed","OAuth callback did not complete. Check server logs for details.")}}async function ht(e,n){if(!e.database)throw ye("Permission not found");let t=await e.database.db.selectFrom("corsair_permissions").selectAll().where("token","=",n).executeTakeFirst();if(!t)throw ye("Permission not found");return In(e,t)}async function co(e,n){return"id"in n?yt(e,n.id):ht(e,n.token)}import{createCipheriv as ms,createDecipheriv as wc,randomBytes as fo,scryptSync as hs}from"crypto";import{createHmac as kt,randomUUID as ys,timingSafeEqual as po}from"crypto";var lo=new Set(["oauth.callback","oauth.tokens","webhook","permission.approve","permission.deny","auth.credentials","integration.credentials","connect.create_link","connections.sync"]),me=60*1e3,Te=300*1e3;function go(e){if(e)return e.startsWith("sha256=")?e.slice(7):e}function Fn(e){let n=JSON.stringify({type:e.type,payload:e.payload}),t=Math.floor(Date.now()/1e3).toString(),r=kt("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":ys()}}}function bt(e){let n=e.signingSecret.trim();if(!n)return!1;let t=go(e.signatureHeader);if(!t)return!1;let r=Number(e.timestampHeader);if(!Number.isFinite(r)||Math.abs(Date.now()-r*1e3)>Te)return!1;let i=kt("sha256",n).update(e.body).digest("hex");try{return po(Buffer.from(i,"utf8"),Buffer.from(t,"utf8"))}catch{return!1}}function Be(e){let n=e.signingSecret.trim();if(!n)return{ok:!1,error:"Tunnel signing secret is required"};let t=go(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)>Te)return{ok:!1,error:"Tunnel request timestamp is outside the allowed window"};let i=kt("sha256",n).update(e.body).digest("hex");try{if(!po(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 Ct(e){if(!e)return{};try{return JSON.parse(e)}catch{return{}}}function wt(e){return e.httpOk&&(e.status===204||e.body.status==="ok"||e.body.ok===!0)}function Pt(e){return e.status===0?`Could not reach delivery URL (${e.deliveryUrl}): ${e.ack.error??e.body}`:e.ack.error??e.body??`HTTP ${e.status}`}async function Tt(e){let{body:n,headers:t}=Fn(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:r instanceof Error?r.message:"Delivery request failed"}}}var ks="aes-256-gcm",bs=12,Cs=16,ws=16,Ps=32;function Ts(e,n){return hs(e.trim(),n,Ps)}function vt(e,n){let t=n.trim();if(!t)throw new Error("Signing secret is required to encrypt sync manifest");let r=fo(ws),o=Ts(t,r),i=fo(bs),a=ms(ks,o,i,{authTagLength:Cs}),s=JSON.stringify(e),u=Buffer.concat([a.update(s,"utf8"),a.final()]),l=a.getAuthTag();return[r.toString("base64"),i.toString("base64"),l.toString("base64"),u.toString("base64")].join(":")}var vs=["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 At(e){if(e instanceof hr)return!1;if(!(e instanceof Error))return!0;let n=e.message.toLowerCase();return!vs.some(t=>n.includes(t))}async function xt(e,n){let t=w(e);if(!t.database)throw new Error("A database must be configured to sync connections from the app");await wn(e,{silent:!0});let[r,o]=await Promise.all([Fe(t),He(t)]),i={tenants:r.map(a=>({id:a.id})),plugins:o.map(a=>({id:a.id,authType:a.authType,configured:a.configured,missingFields:a.missingFields})),syncedAt:new Date().toISOString()};return vt(i,n)}var As=new Set(["localhost","127.0.0.1","[::1]","::1"]);function It(e){try{let{hostname:n,protocol:t}=new URL(e);return t!=="http:"&&t!=="https:"?!1:As.has(n)}catch{return!1}}function St(e){return e==="development"?"browser":"server"}function mo(e){return St(e)==="browser"}function ho(e){return It(e)?"Production delivery URL must be a public URL, not localhost":null}async function ko(e,n){let t=n.tenantId.trim();if(!t)throw new Error("tenantId is required");let r=n.plugins.map(a=>a.trim()).filter(Boolean);if(r.length===0)throw new Error("At least one plugin is required");let o=w(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 xs(o.hub,{plugins:o.plugins,database:o.database,kek:o.kek},{tenantId:t,pluginIds:r});return{connectUrl:i.connectUrl,expiresAt:i.expiresAt}}async function xs(e,n,t){let{buildConnectPluginManifestFromContext:r,ensureConnectAccountRowsFromContext:o}=await import("./setup-introspect-CZF7ZGHP.js"),{postHubConnectSession:i}=await import("./connect-DUNMIE64.js"),a={plugins:n.plugins,database:n.database,kek:n.kek,hub:e};await o(a,t.tenantId);let s=await r(a,t.tenantId,{pluginIds:t.pluginIds});if(s.length===0)throw new Error("No connectable plugins found for this tenant");let u=s.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:s})}var z=class extends Error{code;constructor(n,t){super(t),this.name="AuthCredentialsDeliveryError",this.code=n}};async function Bn(e,n){let t=w(e,()=>new z("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new z("no_database","Database not configured");let r=H(t,n.plugin,c=>new z("plugin_not_found",c)),o=I(r);if(!o)throw new z("invalid_credentials",`Plugin '${r.id}' has no authType configured`);if(o==="oauth_2"||o==="managed")throw new z("invalid_credentials","OAuth plugins must be connected via sign-in, not credentials delivery");await we(e,n.tenantId);let i=new Set(sn(r,o)),s=r.authConfig?.[o]?.account??[],u=E({authType:o,integrationName:n.plugin,tenantId:n.tenantId,kek:t.kek,database:t.database,extraAccountFields:s}),l=0;for(let[c,p]of Object.entries(n.credentials)){if(!p.trim())continue;if(!i.has(c))throw new z("invalid_credentials",`Unknown credential field '${c}' for plugin '${n.plugin}'`);let g=B(u,`set_${c}`);if(!g)throw new z("invalid_credentials",`Cannot set credential field '${c}' for plugin '${n.plugin}'`);await g(p.trim()),l+=1}if(l===0)throw new z("invalid_credentials","Provide at least one credential field to save");return{plugin:n.plugin,tenantId:n.tenantId}}var V=class extends Error{code;constructor(n,t){super(t),this.name="IntegrationCredentialsDeliveryError",this.code=n}};async function Rt(e,n){let t=w(e,()=>new V("invalid_corsair_instance","Invalid corsair instance"));if(!t.database)throw new V("no_database","Database not configured");let r=H(t,n.plugin,c=>new V("plugin_not_found",c)),o=I(r);if(!o)throw new V("invalid_credentials",`Plugin '${r.id}' has no authType configured`);await qr(e);let i=new Set(Cr(r,o)),s=r.authConfig?.[o]?.integration??[],u=S({authType:o,integrationName:n.plugin,kek:t.kek,database:t.database,extraIntegrationFields:s}),l=0;for(let[c,p]of Object.entries(n.credentials)){if(!p.trim())continue;if(!i.has(c))throw new V("invalid_credentials",`Unknown integration credential field '${c}' for plugin '${n.plugin}'`);let g=B(u,`set_${c}`);if(!g)throw new V("invalid_credentials",`Cannot set integration field '${c}' for plugin '${n.plugin}'`);await g(p.trim()),l+=1}if(l===0)throw new V("invalid_credentials","Provide at least one integration credential field to save");return{plugin:n.plugin}}var Un=new Map;function Is(e){for(let[n,t]of Un)t<=e&&Un.delete(n)}function Ln(e,n){let t=e.trim();if(!t)return{ok:!1,error:"Delivery replay key is required"};let r=Date.now();return Is(r),Un.has(t)?{ok:!1,error:"Delivery request already consumed"}:(Un.set(t,r+n),{ok:!0})}async function Nn(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 bo=e=>{if(!e)return{};if(typeof e=="string")try{return JSON.parse(e)}catch{return{}}return e};async function Ss(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 Rs(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 $(n.dek,e.kek),r=bo(n.config),o={};Object.keys(r).length>0&&(o=oe(r,t)),o[e.link.linkType]=e.link.externalId;let i=ge(o,t);await e.database.db.updateTable("corsair_accounts").set({config:i,updated_at:new Date}).where("id","=",n.id).execute()}async function Ue(e){let{database:n,kek:t,pluginId:r,tenantId:o,link:i,authType:a,extraAccountFields:s=[]}=e,{accountId:u}=await Ss({database:n,pluginId:r,tenantId:o}),l=!1;if(a){let c=E({authType:a,integrationName:r,tenantId:o,kek:t,database:n,extraAccountFields:s}),p=`set_${i.linkType}`,g=c[p];typeof g=="function"&&(await g(i.externalId),l=!0)}l||await Rs({database:n,kek:t,accountId:u,link:i})}async function _t(e){let{database:n,kek:t,pluginId:r,linkType:o,externalId:i}=e,a=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 s of a)if(s.dek)try{let u=await $(s.dek,t),c=bo(s.config)[o];if(!c)continue;if(Ze(c,u)===i)return s}catch{continue}return null}async function $n(e){return(await _t(e))?.tenant_id??null}async function Co(e){return $n({database:e.database,kek:e.kek,pluginId:e.pluginId,linkType:e.match.linkType,externalId:e.match.externalId})}var he=class extends Error{code;constructor(n,t){super(t),this.name="ManagedOAuthDeliveryError",this.code=n}};async function Le(e,n){let{plugin:t,tenantId:r,accessToken:o,refreshToken:i,expiresIn:a,scope:s}=n;if(!o.trim())throw new he("no_access_token","Managed OAuth delivery missing access_token");let u=w(e,()=>new he("invalid_corsair_instance","Invalid corsair instance"));if(!u.database)throw new he("no_database","No database configured on corsair instance");let l=H(u,t,p=>new he("plugin_not_found",p));await we(e,r);let c=E({authType:"managed",integrationName:t,tenantId:r,kek:u.kek,database:u.database});await c.set_access_token(o),i&&await c.set_refresh_token(i),a&&await c.set_expires_at(String(Math.floor(Date.now()/1e3)+a)),s&&await c.set_scope(s);try{let p=await Nn(u.plugins,t,{access_token:o,refresh_token:i,scope:s});if(p)try{let g=l.authConfig?.managed?.account??[];await Ue({database:u.database,kek:u.kek,pluginId:t,tenantId:r,link:p,authType:"managed",extraAccountFields:g})}catch(g){console.warn(`[corsair:managed-oauth] Failed to persist webhook tenant link for '${t}' tenant '${r}':`,g)}}catch(p){console.warn(`[corsair:managed-oauth] Failed to resolve webhook tenant link for '${t}' tenant '${r}':`,p)}return{plugin:t,tenantId:r}}function _s(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function wo(e,n,t=[]){for(let[r,o]of Object.entries(e))if(_s(o)){if(o.match(n))return{webhook:o,path:[...t,r]}}else if(o&&typeof o=="object"){let i=wo(o,n,[...t,r]);if(i)return i}return null}function Es(e){let n={};for(let[t,r]of Object.entries(e))n[t.toLowerCase()]=Array.isArray(r)?r[0]:r;return n}function Ds(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 Po(e,n,t,r){let o=Es(n),i=typeof t=="string"?JSON.parse(t):t;(!i||typeof i=="object"&&Object.keys(i).length===0)&&o["x-goog-resource-uri"]&&(i=Ds(o)||i);let s={headers:o,body:i,...r?{query:r}:{}},u=r?.tenantId||"default",l=e.withTenant?e.withTenant(u):e,c=an;for(let p of c){let g=l[p];if(!g||!g.webhooks||g.pluginWebhookMatcher&&!g.pluginWebhookMatcher(s))continue;let d=wo(g.webhooks,s);if(!d)continue;let f=d.path.join("."),y={payload:i,headers:o,rawBody:typeof t=="string"?t:JSON.stringify(t),...r?{query:r}:{}};try{let m=await d.webhook.handler(y),h=!!Object.keys(m.returnToSender||{})?.length;return{plugin:p,action:f,body:i,response:h?{...m?.returnToSender,success:!0}:{success:!0},...m.responseHeaders&&{responseHeaders:m.responseHeaders}}}catch(m){return console.error(`Error executing webhook handler for ${p}.${f}:`,m),{plugin:p,action:f,body:i,response:{success:!1,error:m instanceof Error?m.message:"Unknown error"}}}}return{plugin:null,action:null,body:null}}import{randomBytes as Fs}from"crypto";import{createHmac as Os,randomBytes as Ms,timingSafeEqual as Hs}from"crypto";function se(){return Ms(16).toString("base64url")}function Ve(e,n){let t=n.trim();if(!t)throw new Error("Signing secret is required");return Os("sha256",t).update(e).digest("base64url")}function Y(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 a=Ve(o,t);try{if(!Hs(Buffer.from(i,"utf8"),Buffer.from(a,"utf8")))return null}catch{return null}let s;try{s=JSON.parse(Buffer.from(o,"base64url").toString("utf8"))}catch{return null}return s.exp*1e3<Date.now()?null:s}function Wn(e,n,t){let r=Math.floor(Date.now()/1e3),o={...e,iat:r,exp:t},i=Buffer.from(JSON.stringify(o)).toString("base64url"),a=Ve(i,n);return`${i}.${a}`}function Ye(e,n,t){let r=Math.floor(Date.now()/1e3);return Wn(e,n,r+Math.floor(t/1e3))}function ve(e){return decodeURIComponent(e)}function Et(e){return encodeURIComponent(e)}function To(e){let n=e.trim();return n.length>0?n:null}function jn(e,n){let t=new URL(e);return t.searchParams.set("d",n),t.toString()}function Kn(e,n){if(!To(n))throw new Error("Signing secret is required for browser delivery tokens");let t=Math.floor(Date.now()/1e3),r={...e,jti:e.jti??Fs(16).toString("base64url"),iat:t,exp:t+Math.floor(me/1e3)},o=Buffer.from(JSON.stringify(r)).toString("base64url"),i=Ve(o,n);return`${o}.${i}`}function ke(e,n){return To(n)?Y(e,n):null}function Ae(e){return e.deliveryMode==="auth.credentials"}function Qe(e){return e.deliveryMode==="permission.approve"||e.deliveryMode==="permission.deny"}function Xe(e){return e.deliveryMode==="oauth.tokens"}function qn(e){return e.deliveryMode==="oauth.callback"||e.deliveryMode===void 0&&!Ae(e)&&!Qe(e)&&!Xe(e)}async function Bs(e,n){try{return{status:"ok",webhookResponse:{status:200,body:{status:"ok",sync:{encrypted:await xt(e,n)}}}}}catch(t){return{status:"failed",retryable:At(t),error:t instanceof Error?t.message:"Connections sync delivery failed"}}}async function Us(e,n){try{return{status:"ok",connectLink:await ko(e,n)}}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Connect link delivery failed"}}}function Dt(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 Ls(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 $n({database:n.database,kek:n.kek,pluginId:t.plugin,linkType:t.linkType,externalId:t.externalId})??void 0)}async function Ns(e,n,t){let r=await Ls(e,n,t),o={...t.query??{},...r?{tenantId:r}:{}},i=await Po(e,t.headers,t.body,o);if(!i.plugin)return{status:"failed",retryable:!1,error:"No matching webhook handler found"};if(i.response&&i.response.success===!1)return{status:"failed",retryable:!1,error:typeof i.response.error=="string"?i.response.error:"Webhook handler failed"};let a=i.response?.returnToSender,s=a&&typeof a=="object"&&typeof a.validationToken=="string"&&Object.keys(a).length===1?a.validationToken:a||(i.response?.data??i.response);return{status:"ok",webhookResponse:{status:i.response?.statusCode??200,body:s,headers:i.responseHeaders}}}async function $s(e,n){return await en(e,n),{status:"ok"}}async function Ws(e,n){return await Le(e,{plugin:n.plugin,tenantId:n.tenantId,accessToken:n.accessToken,refreshToken:n.refreshToken,expiresIn:n.expiresIn,scope:n.scope}),{status:"ok"}}async function Mt(e,n,t){let r=await Ot(e,{token:n},t);if(r.status!=="ok")throw new Error(r.error??"Permission decision failed")}async function Ot(e,n,t){let r=w(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(),a=await r.database.db.selectFrom("corsair_permissions").selectAll().where("token","=",o).executeTakeFirst();return a?a.status!=="pending"?{status:"ok"}:a.expires_at<i?(await r.database.db.updateTable("corsair_permissions").set({status:"expired",updated_at:new Date}).where("id","=",a.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","=",a.id).execute(),{status:"ok"}):{status:"failed",retryable:!1,error:"Permission not found"}}async function js(e,n){try{return await Bn(e,n),{status:"ok"}}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Credential delivery failed"}}}async function Ks(e,n){try{return await Rt(e,n),{status:"ok"}}catch(t){return{status:"failed",retryable:!1,error:t instanceof Error?t.message:"Integration credential delivery failed"}}}async function Ht(e,n,t={}){let r=w(e),o=Dt(n.headers,"x-corsair-signature"),i=Dt(n.headers,"x-corsair-timestamp"),a=Dt(n.headers,"x-corsair-nonce");if(t.signingSecret?.trim()){let u=Be({body:n.body,signatureHeader:o,timestampHeader:i,signingSecret:t.signingSecret});if(!u.ok)return{status:"failed",retryable:!1,error:u.error};if(!a?.trim())return{status:"failed",retryable:!1,error:"Missing tunnel nonce"};let l=Ln(`nonce:${a.trim()}`,Te);if(!l.ok)return{status:"failed",retryable:!1,error:l.error}}else if(!t.allowUnsignedTunnel)return{status:"failed",retryable:!1,error:"Tunnel signing secret is required"};let s;try{s=JSON.parse(n.body)}catch{return{status:"failed",retryable:!1,error:"Invalid tunnel envelope JSON"}}if(s.type==="connect.status")return{status:"failed",retryable:!1,error:"connect.status is deprecated; use connections.sync signed delivery instead"};switch(s.type){case"webhook":return Ns(e,r,s.payload);case"oauth.callback":return $s(e,s.payload);case"oauth.tokens":return Ws(e,s.payload);case"permission.approve":return Ot(e,s.payload,"approved");case"permission.deny":return Ot(e,s.payload,"denied");case"auth.credentials":return js(e,s.payload);case"integration.credentials":return Ks(e,s.payload);case"connect.create_link":return Us(e,s.payload);case"connections.sync":{let u=t.signingSecret?.trim();return u?Bs(e,u):{status:"failed",retryable:!1,error:"Tunnel signing secret is required for connections.sync"}}default:return qs(String(s.type))}}function qs(e){return lo.has(e)?{status:"failed",retryable:!1,error:`Unsupported tunnel type: ${e}`}:{status:"failed",retryable:!1,error:`Unsupported tunnel type: ${e}`}}var Zs="corsair:client-bridge";function vo(e){let n=JSON.stringify({type:Zs,requestId:e.requestId,ok:e.ok,body:e.body??null,error:e.error??null}),t=JSON.stringify(e.hubOrigin);return`<!DOCTYPE html><html><head><meta charset="utf-8"></head><body><script>
16
+ (function () {
17
+ var message = ${n};
18
+ var targetOrigin = ${t};
19
+ if (window.parent && window.parent !== window) {
20
+ window.parent.postMessage(message, targetOrigin);
21
+ }
22
+ })();
23
+ </script></body></html>`}var Gs=[".corsair.dev"];function Js(e){return e==="localhost"||e==="127.0.0.1"||e==="[::1]"||e==="::1"}function zs(e){try{let{hostname:n,protocol:t}=new URL(e);return t!=="http:"&&t!=="https:"?!1:Js(n)?!0:Gs.some(r=>n===r.slice(1)||n.endsWith(r))}catch{return!1}}function Ao(e){return!e||!zs(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 xo(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 Ft(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 Bt(e,n){let t=J(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=ke(o,t.signingSecret);if(!i)return{type:"json",status:400,body:{error:"Invalid or expired delivery token"}};let a=Ln(`browser:${i.jti}`,me);if(!a.ok)return{type:"json",status:400,body:{error:a.error}};try{if(Ae(i))return i.hubSuccessUrl?i.credentials?(await Bn(e,{plugin:i.plugin,tenantId:i.tenantId,credentials:i.credentials}),{type:"redirect",url:Ft(i.hubSuccessUrl,{connectedPlugin:i.plugin})}):{type:"redirect",url:Ft(i.hubSuccessUrl,{error:"Credential delivery missing credentials"})}:{type:"json",status:400,body:{error:"Credential delivery missing hubSuccessUrl"}};if(Qe(i)){if(!i.permissionToken)return{type:"json",status:400,body:{error:"Permission delivery missing permission token"}};await Mt(e,i.permissionToken,i.deliveryMode==="permission.approve"?"approved":"denied")}else if(Xe(i)){if(!i.accessToken)return{type:"json",status:400,body:{error:"Managed OAuth delivery missing access_token"}};await Le(e,{plugin:i.plugin,tenantId:i.tenantId,accessToken:i.accessToken,refreshToken:i.refreshToken,expiresIn:i.expiresIn,scope:i.scope})}else{if(!qn(i)||!i.code||!i.state||!i.redirectUri)return{type:"json",status:400,body:{error:"Invalid BYO OAuth delivery token"}};await en(e,{code:i.code,state:i.state,redirectUri:i.redirectUri})}}catch(s){let u=s instanceof Error?s.message:"Hub delivery failed";return Ae(i)&&i.hubSuccessUrl?{type:"redirect",url:Ft(i.hubSuccessUrl,{error:u})}:Ae(i)&&i.hubOrigin&&i.requestId?{type:"text",status:400,headers:{"Content-Type":"text/html; charset=utf-8"},body:vo({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 Ut(e,n){let t=J(e),r=await Ht(e,n,{signingSecret:t.signingSecret});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(r.connectLink)return{type:"json",status:200,body:{status:"ok",connectUrl:r.connectLink.connectUrl,expiresAt:r.connectLink.expiresAt}};if(!o)return{type:"json",status:200,body:{status:"ok"}};let i=o.status??200,a=o.headers;return o.body&&typeof o.body=="object"&&!(o.body instanceof ArrayBuffer)?{type:"json",status:i,body:o.body,headers:a}:{type:"text",status:i,body:typeof o.body=="string"?o.body:o.body?JSON.stringify(o.body):null,headers:a}}function Lt(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 Nt(e,n){return n.method==="GET"?Bt(e,n.url):Ut(e,{headers:n.headers,body:n.body??""})}async function $t(e,n){try{let t=await Nt(e,n);return Lt(t)}catch(t){if(t instanceof de)return Response.json({error:t.message},{status:503});throw t}}async function xe(e,n){let t=n.method.toUpperCase(),r=Ao(n.headers.get("origin"));if(t==="OPTIONS")return r?new Response(null,{status:204,headers:r}):Response.json({error:"Method not allowed"},{status:405});if(t!=="GET"&&t!=="POST")return Response.json({error:"Method not allowed"},{status:405});let o=await $t(e,{method:t,url:n.url,headers:n.headers,body:t==="POST"?await n.text():void 0});return xo(o,r)}var Q=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}};var Io=300;async function Wt(e,n){let{keys:t,hub:r,plugin:o,tenantId:i}=e,a=n?.forceRefresh??!1,[s,u,l]=await Promise.all([t.get_access_token(),t.get_expires_at(),t.get_refresh_token()]);if(!s&&!l)throw new Q(o,"managed");let c=Math.floor(Date.now()/1e3);if(!a&&s&&u&&Number(u)>c+Io)return{accessToken:s,expiresAt:Number(u),refreshed:!1};if(!l&&s&&!a){let d=u?Number(u):null;if(d===null||d>c+Io)return{accessToken:s,expiresAt:d??c+3600,refreshed:!1}}let p=await Ys(r,o,i),g=p.expires_in?c+p.expires_in:u?Number(u):c+3600;return await t.set_access_token(p.access_token),await t.set_expires_at(String(g)),p.refresh_token&&await t.set_refresh_token(p.refresh_token),p.scope&&await t.set_scope(p.scope),{accessToken:p.access_token,expiresAt:g,refreshed:!0}}function Vs(e){return e.includes("Managed OAuth connection not found")||e.includes("Managed OAuth connection has no tokens")}async function Ys(e,n,t){try{return await pe({hub:e,path:"/oauth/refresh",body:{plugin:n,tenantId:t},parseResponse:gn})}catch(r){let o=r instanceof Error?r.message:"";throw Vs(o)?new Q(n,"managed"):r}}async function So(e,n){e._refreshAuth=async()=>(await Wt(n,{forceRefresh:!0})).accessToken}function Qs(e){return{tenantId:e.tenantId,plugin:e.plugin,authType:e.authType,status:e.status,connected:e.connected,verified:e.verified,missingFields:e.missingFields}}async function Xs(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 De(n,e.plugin,r);o&&Ro(e.hub,Qs({tenantId:r,plugin:e.plugin.id,authType:o.authType,status:o.status,connected:o.connected,verified:e.verified??o.connected,missingFields:o.missingRequiredFields}))}function Ro(e,n){pe({hub:e,path:"/connections/report",body:n,parseResponse:()=>({ok:!0})}).catch(()=>{})}function nn(e){Xs(e).catch(()=>{})}function _o(e){return{delivery:n=>xe(e,n),deliveryOptions:n=>xe(e,n)}}var Eo=1200*1e3;function jt(){return se()}function Kt(){return Eo}function qt(e,n){return Ye(e,n,Eo)}function Zt(e,n){return Y(e,n)}function Gt(e){return ve(e)}var Do=600*1e3;function Jt(){return se()}function zt(){return Do}function Vt(e,n){return Ye(e,n,Do)}function Yt(e,n){return Y(e,n)}function Qt(e){return Et(e)}function Xt(e){return ve(e)}function er(){return se()}function nr(e,n,t){return Wn(e,n,Math.floor(t.getTime()/1e3))}function tr(e,n){return Y(e,n)}function rr(e){return ve(e)}function Zn(e,n){let t=[];e||t.push("database"),n||t.push("kek");let r={};return new Proxy(r,{get(o,i){let a=t.length>1;throw new Error(`corsair.keys.${String(i)}: Cannot access keys because ${t.join(" and ")} ${a?"are":"is"} not configured. Provide both 'database' and 'kek' in createCorsair() to enable key management.
24
+
25
+ To generate a KEK, run: openssl rand -base64 ${qe}`)}})}async function na(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 Oo(e){let{integrationId:n,accountId:t}=await na(e);return{integrationId:n,accountId:t}}function or(e,n){return`[auth-missing:${e}] Authentication required. Direct the user to connect their account: ${n}`}async function ta(e,n){let t=e.hub;if(!t||!n.database||!n.kek)return null;try{return(await it(t,{tenantId:n.tenantId,plugin:n.plugin,database:n.database,kek:n.kek,plugins:n.plugins})).connectUrl}catch{return null}}async function ra(e){let n=e.hub;if(n&&e.database&&e.kek)try{let r=await it(n,{tenantId:e.tenantId,plugin:e.plugin,database:e.database,kek:e.kek,plugins:e.plugins});return e.manual?.onAuthMissing?e.manual.onAuthMissing({plugin:e.pluginId,connectUrl:r.connectUrl,state:r.token}):or(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 ta({manual:e.manual,hub:e.hub},{plugin:e.plugin,tenantId:e.tenantId,database:e.database,kek:e.kek,plugins:e.plugins});return t?or(e.pluginId,t):`[auth-missing:${e.pluginId}:${e.authType}]`}function oa(e,n,t){let r=Oe(fe(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}):or(e,i)}async function Mo(e){let n=e.tenantId??"default",t=e.error.pluginId;return e.manual&&Me(e.manual)&&e.manual.oauthConfig&&e.manual.kek&&e.error.authType==="oauth_2"?oa(t,{...e.manual,baseUrl:e.manual.baseUrl,kek:e.manual.kek},e.tenantId):e.hub&&e.plugin&&e.kek&&e.database&&e.plugins?ra({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}):e.error.message}var ia=async(e,n)=>(console.error(`[corsair:${n.pluginId}:${n.operation}]`,{error:e.message,input:n.input}),{maxRetries:0});async function Ho(e,n,t,r,o){let i={pluginId:n,operation:t,input:r,originalError:e},a=Object.keys(o).find(l=>o[l]?.match(e,i));return await(o[a||"DEFAULT"]?.handler||ia)(e,i)}function sa(e){return typeof e=="function"}function ir({endpoints:e,hooks:n,ctx:t,tree:r,pluginId:o,errorHandlers:i,currentPath:a=[],keyBuilder:s,permissionsConfig:u,endpointMeta:l,database:c,permissionsOptions:p,tenantId:g,manualConfig:d,hubConfig:f,plugin:y,kek:m,allPlugins:h}){for(let[P,C]of Object.entries(e)){let _=n?.[P];if(sa(C)){let k=_,b=[...a,P].join("."),T=async(x={})=>{let X;if(u){let M=l?.[b],{result:on,reason:Z,onComplete:je,token:ne,id:Ce,expiresAt:N}=await to({pluginId:o,endpointPath:b,args:x,mode:u.mode,override:u.overrides?.[b],riskLevel:M?.riskLevel??"write",meta:M,db:c,timeoutMs:p?ft(p.timeout):void 0,tenantId:g,approvalMode:p?.mode});if(on==="blocked"){let G;throw Z==="denied"?G=`Action '${b}' was denied by the user. Await further instructions before proceeding.`:Z==="policy"?G=`Action '${b}' is blocked by the permission policy. Update the corsair config to allow it.`:Z==="timeout"?G=`Action '${b}' timed out waiting for approval.`:ne&&Ce?G=await gt({permissionsOptions:p,manual:d,hub:f,permissionId:Ce,permissionToken:ne,plugin:o,endpoint:b,args:x,tenantId:g??"default",expiresAt:N??new Date(Date.now()+(p?ft(p.timeout):600*1e3)).toISOString(),operationPath:b}):G=`Action '${b}' requires user approval before it can run.`,new Error(G)}X=je}let D=async(M,on,Z)=>{try{return await C(on,Z)}catch(je){if(je instanceof Error){let ne=await Ho(je,o,b,typeof Z=="object"&&Z!==null?Z:{args:Z},i);if(M<(ne.maxRetries||0)){let Ce=M+1;console.log(`Retrying (${Ce} / ${ne.maxRetries})...`);let N;if(ne.headersRetryAfterMs)N=ne.headersRetryAfterMs;else switch(ne.retryStrategy){case"exponential_backoff":N=Math.pow(2,Ce-1)*1e3;break;case"exponential_backoff_jitter":let G=Math.pow(2,Ce-1)*1e3,si=(Math.random()-.5)*1e3;N=Math.max(0,G+si);break;case"linear_1s":N=1e3;break;case"linear_2s":N=2e3;break;case"linear_3s":N=3e3;break;case"linear_4s":N=4e3;break;default:N=1e3;break}await new Promise(G=>setTimeout(G,N)),await D(Ce,on,Z),console.log(`[corsair:${o}:${b}] Retry strategy:`,ne)}}throw je}},ue;try{ue=s?await s(t,"endpoint"):void 0}catch(M){if(M instanceof Q)return y&&f&&nn({hub:f,database:c,kek:m,plugins:h??[],plugin:y,tenantId:g,verified:!1}),Mo({error:M,manual:d,hub:f,plugin:y,tenantId:g,database:c,kek:m,plugins:h});throw M}if(!k?.before&&!k?.after){let M=await D(0,{...t,key:ue},x);return await X?.(),y&&f&&nn({hub:f,database:c,kek:m,plugins:h??[],plugin:y,tenantId:g,verified:!0}),M}let L={...t,key:ue},ee=k.before?await k.before(L,x):{ctx:L,args:x,continue:!0,passToAfter:void 0};if(ee.continue===!1)return;let We=await D(0,ee.ctx,ee.args);return await k.after?.(ee.ctx,We,ee.passToAfter),await X?.(),y&&f&&nn({hub:f,database:c,kek:m,plugins:h??[],plugin:y,tenantId:g,verified:!0}),We};r[P]=T}else if(C&&typeof C=="object"){let k={};ir({endpoints:C,hooks:_,ctx:t,tree:k,pluginId:o,errorHandlers:i,currentPath:[...a,P],keyBuilder:s,permissionsConfig:u,endpointMeta:l,database:c,permissionsOptions:p,tenantId:g,manualConfig:d,hubConfig:f,plugin:y,kek:m,allPlugins:h}),r[P]=k}}}function aa(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function sr({webhooks:e,hooks:n,ctx:t,webhooksTree:r,keyBuilder:o}){for(let[i,a]of Object.entries(e)){let s=n?.[i];if(aa(a)){let u=s,l=async c=>{let p=(d,f)=>a.handler(d,f),g=o?await o(t,"webhook"):void 0;return!u?.before&&!u?.after?p({...t,key:g},c):(async()=>{let d={...t,key:g},f=u.before?await u.before(d,c):{ctx:d,args:c,continue:!0,passToAfter:void 0};if(f.continue===!1)return;let y=await p(f.ctx,f.args);return y?.success===!0&&await u.after?.(f.ctx,y,f.passToAfter),y})()};r[i]={match:a.match,handler:l}}else if(a&&typeof a=="object"){let u={};sr({webhooks:a,hooks:s,ctx:t,webhooksTree:u,keyBuilder:o}),r[i]=u}}}function ua(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 Oo({database:e,integrationName:n,tenantId:t,ensureProvisioned:r});return o=i,o}}function ca(e,n,t,r,o){return e?Yn(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 ar(e,n){let{database:t,tenantId:r,kek:o,rootErrorHandlers:i,permissionsOptions:a,manualConfig:s,hubConfig:u,internalConfig:l}=n,c=l&&t?()=>bn(l,r??"default"):void 0,p={},g={};for(let d of e)p[d.id]={},g[d.id]={};for(let d of e){let f=d.schema,y=r??"default",m=ua(t,d.id,y,c);if(f?.entities){let L={};for(let[ee,We]of Object.entries(f.entities)){let M=t?Yn(t.db,m,ee,f.version,We):ca(void 0,m,ee,f.version,We);L[ee]=M}g[d.id].db=L,p[d.id].db=L}let h=d.options,P=d.authConfig,C;if(t&&o&&h?.authType){let L=P?.[h.authType]?.account??[];C=E({authType:h.authType,integrationName:d.id,tenantId:y,kek:o,database:t,extraAccountFields:L,ensureProvisioned:c}),p[d.id].keys=C}let _={database:t,db:g[d.id]?.db??{},$getAccountId:m,...d.options?{options:d.options}:{},...C?{keys:C,authType:h?.authType}:{},tenantId:y,...u?{hub:u}:{}},k=d.endpoints??{},b=d.hooks,T={...i,...d.errorHandlers},x={},X=d.options?.permissions;ir({endpoints:k,hooks:b,ctx:_,tree:x,pluginId:d.id,errorHandlers:T,currentPath:[],keyBuilder:d.keyBuilder,permissionsConfig:X,endpointMeta:d.endpointMeta,database:t,permissionsOptions:a,tenantId:r,manualConfig:s?{...s,oauthConfig:d.oauthConfig,kek:o,tenantId:y}:void 0,hubConfig:u,plugin:d,kek:o,allPlugins:e}),Object.keys(x).length>0&&(p[d.id].api=x),_.endpoints=x;let D=d.webhooks??{},ue=d.webhookHooks;if(Object.keys(D).length>0){let L={};sr({webhooks:D,hooks:ue,ctx:_,webhooksTree:L,keyBuilder:d.keyBuilder}),p[d.id].webhooks=L,d.pluginWebhookMatcher&&(p[d.id].pluginWebhookMatcher=d.pluginWebhookMatcher),d.pluginTenantWebhookMatcher&&(p[d.id].pluginTenantWebhookMatcher=d.pluginTenantWebhookMatcher)}}return p}function Fo(e,n,t){let r={};for(let o of e){let i=o.options,a=o.authConfig;if(i?.authType){let s=a?.[i.authType]?.integration??[],u=S({authType:i.authType,integrationName:o.id,kek:t,database:n,extraIntegrationFields:s});r[o.id]=u}}return r}var la="createCorsair({ approval: ... }) is deprecated. Rename to permissions: { timeout, onTimeout, mode }.";function Bo(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] ${la}`),t):n}var Uo=[{method:"GET",pattern:"/ok",handler:async()=>R(200,Sn())},{method:"GET",pattern:"/tenants",handler:async({internal:e})=>R(200,await Fe(e))},{method:"POST",pattern:"/tenants",handler:async({internal:e,body:n})=>R(201,await En(e,n))},{method:"GET",pattern:"/tenants/:id",handler:async({internal:e,params:n})=>R(200,await _n(e,n.id))},{method:"GET",pattern:"/plugins",handler:async({internal:e})=>R(200,await He(e))},{method:"GET",pattern:"/plugins/:id",handler:async({internal:e,params:n})=>R(200,await Rn(e,n.id))},{method:"GET",pattern:"/connection-status",handler:async({internal:e,query:n})=>R(200,await Dn(e,n.tenantId))},{method:"GET",pattern:"/permissions/:id",handler:async({internal:e,params:n})=>R(200,await yt(e,n.id))},{method:"POST",pattern:"/permissions/lookup-by-token",handler:async({internal:e,body:n})=>{let t=n?.token?.trim();return t?R(200,await ht(e,t)):R(400,{error:"bad_request",message:"token is required",missingFields:["token"]})}},{method:"POST",pattern:"/connect/links",handler:async({corsair:e,internal:n,body:t})=>R(200,await On(e,n,t))},{method:"GET",pattern:"/connect/resolve",handler:async({corsair:e,internal:n,query:t})=>R(200,await Mn(e,n,t.state??""))},{method:"POST",pattern:"/connect/oauth/callback",handler:async({corsair:e,internal:n,body:t})=>R(200,await Hn(e,n,t))}];(()=>{let e=new Set;for(let n of Uo){let t=`${n.method} ${n.pattern}`;if(e.has(t))throw new Error(`Duplicate management route registered: ${t}`);e.add(t)}})();function da(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 a=t[i],s=r[i];if(a.startsWith(":"))o[a.slice(1)]=decodeURIComponent(s);else if(a!==s)return null}return o}function pa(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 ga(e){if(!(e.method==="GET"||e.method==="HEAD"||!(e.headers.get("content-type")??"").includes("application/json")))try{let t=await e.text();return t?JSON.parse(t):void 0}catch{throw new A(400,"invalid_json","Request body is not valid JSON")}}var fa="/api/corsair";function Ie(e,n={}){let t=n.basePath??fa,r=w(e,()=>new Error("managementHandler: invalid corsair instance (missing internal config)"));return async o=>{try{let i=new URL(o.url),a=pa(i.pathname,t),s=o.method.toUpperCase();if(s==="OPTIONS"||a==="/"||a==="")return await xe(e,o);if(s!=="GET"&&s!=="POST")return R(405,{error:"method_not_allowed",message:`Method ${s} not allowed`});let u=Object.fromEntries(i.searchParams);for(let l of Uo){if(l.method!==s)continue;let c=da(l.pattern,a);if(!c)continue;let p=await ga(o);return await l.handler({corsair:e,internal:r,req:o,params:c,query:u,body:p})}throw ye(`No route for ${s} ${a}`)}catch(i){if(n.onError){let s=await n.onError(i,o);if(s)return s}if(i instanceof A)return ro(i);let a=i instanceof Error?i.message:"Internal server error";return R(500,{error:"internal_error",message:a})}}}function ya(e){let n=e.get?.("host")??"localhost",t=e.protocol??"http",r=e.originalUrl??e.url,o=`${t}://${n}${r}`,i=new Headers;for(let[u,l]of Object.entries(e.headers))if(l!=null)if(Array.isArray(l))for(let c of l)i.append(u,c);else i.set(u,l);let a=e.method!=="GET"&&e.method!=="HEAD",s={method:e.method,headers:i};return a&&e.body!==void 0&&(s.body=typeof e.body=="string"?e.body:JSON.stringify(e.body),i.has("content-type")||i.set("content-type","application/json")),new Request(o,s)}async function ma(e,n){e.status(n.status),n.headers.forEach((r,o)=>e.setHeader(o,r));let t=Buffer.from(await n.arrayBuffer());e.send(t)}function Lo(e,n){let t=Ie(e,n);return async(r,o,i)=>{try{let a=await t(ya(r));await ma(o,a)}catch(a){i(a)}}}function No(e,n){let t=Ie(e,n);return r=>t(r.req.raw)}function $o(e,n){let t=Ie(e,n);return{GET:t,POST:t,OPTIONS:t}}function Wo(e){let n={[tn]:e};return{ok:Sn,tenants:{list:()=>Fe(e),create:t=>En(e,t),get:t=>_n(e,t)},plugins:{list:()=>He(e),get:t=>Rn(e,t)},connectionStatus:{get:t=>Dn(e,t?.tenantId)},permissions:{get:t=>co(e,t)},connect:{createLink:t=>On(n,e,t),resolve:t=>Mn(n,e,t),oauthCallback:t=>Hn(n,e,t)}}}async function jo(e,n,t,r,o="pending"){if(!e)return null;try{let i=wr(),a=new Date;return await e.db.insertInto("corsair_events").values({id:i,created_at:a,updated_at:a,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 ha(e,n,t,r="pending"){try{let o=await e.$getAccountId();return jo(e.database,o,n,t,r)}catch(o){return console.warn("Failed to log event:",o),null}}import*as Ko from"https";import*as qo from"querystring";function Gn(e,n,t,r,o){let i=new URL(r.tokenUrl),a=r.tokenAuthMethod==="basic";return new Promise((s,u)=>{let l={code:e.trim(),redirect_uri:o,grant_type:"authorization_code"};a||(l.client_id=n,l.client_secret=t);let c=qo.stringify(l),p={"Content-Type":"application/x-www-form-urlencoded","Content-Length":Buffer.byteLength(c).toString()};a&&(p.Authorization=`Basic ${Buffer.from(`${n}:${t}`).toString("base64")}`);let g=Ko.request({hostname:i.hostname,...i.port?{port:Number(i.port)}:{},path:i.pathname+i.search,method:"POST",headers:p},d=>{let f="";d.on("data",y=>{f+=y}),d.on("end",()=>{if(d.statusCode!==200){u(new Error(`Token exchange failed (${d.statusCode}): ${f}`));return}try{s(JSON.parse(f))}catch{u(new Error(`Token endpoint returned non-JSON response: ${f}`))}})});g.on("error",d=>u(new Error(`Request failed: ${d.message}`))),g.write(c),g.end()})}var Zo=" ";function K(e){let n=e;return n._def??n.def??{}}function q(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 j(e){return e.innerType??e.schema??e.out??e.in}function Jo(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 j(e)}}function zo(e){let n=e.type;return e.element??(typeof n=="string"?void 0:n)}function zn(e,n){let t=n.shape??e.shape;return typeof t=="function"?t():t}function Ne(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 Vo(e,n){return e.description??n.description}function ka(e){let n=e;for(;n;){let t=K(n),r=Vo(n,t);if(r)return r;let o=q(t);if(pr(o)||o==="ZodPipe"||o==="ZodEffects"||o==="ZodTransform"){n=Jo(t,o);continue}break}}function pr(e){return e==="ZodOptional"||e==="ZodNullable"||e==="ZodDefault"||e==="ZodCatch"}function F(e){let n=K(e),t=q(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??Ne(n)[0]??"unknown");case"ZodEnum":return Ne(n).map(r=>String(r)).join(" | ");case"ZodOptional":{let r=j(n);return r?F(r):"unknown"}case"ZodNullable":{let r=j(n);return`${r?F(r):"unknown"} | null`}case"ZodDefault":case"ZodCatch":{let r=j(n);return r?F(r):"unknown"}case"ZodArray":{let r=zo(n);if(!r)return"unknown[]";let o=K(r),i=q(o)==="ZodUnion",a=F(r);return`${i?`(${a})`:a}[]`}case"ZodRecord":return"{}";case"ZodObject":{let r=zn(e,n),o=Object.entries(r);return o.length===0?"{}":`{ ${o.map(([a,s])=>{let u=q(K(s));return`${u==="ZodOptional"||u==="ZodNullable"?a+"?":a}: ${F(s)}`}).join(", ")} }`}case"ZodUnion":return Ne(n).map(r=>F(r)).join(" | ");case"ZodIntersection":return`${F(n.left)} & ${F(n.right)}`;case"ZodPipe":case"ZodTransform":case"ZodEffects":{let r=Jo(n,t);return r?F(r):"unknown"}default:return(t??"unknown").replace("Zod","").toLowerCase()}}function ae(e){let n=K(e),t=q(n),r=Vo(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??Ne(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=Ne(n).map(i=>String(i));return{kind:"string",optional:!1,description:r,enum:o}}case"ZodOptional":{let o=j(n),i=o?ae(o):{kind:"unknown",optional:!1};return{...i,optional:!0,description:r??i.description}}case"ZodNullable":{let o=j(n),i=o?ae(o):{kind:"unknown",optional:!1};return{...i,optional:!0,description:r??i.description}}case"ZodDefault":case"ZodCatch":{let o=j(n);return o?{...ae(o),description:r}:{kind:"unknown",optional:!1,description:r}}case"ZodArray":{let o=zo(n);return{kind:"array",optional:!1,description:r,items:o?ae(o):{kind:"unknown",optional:!1}}}case"ZodObject":{let o=zn(e,n),i={};for(let[a,s]of Object.entries(o))i[a]=ae(s);return{kind:"object",optional:!1,description:r,fields:i}}case"ZodRecord":return{kind:"unknown",optional:!1,description:r};case"ZodUnion":{let o=Ne(n);for(let i of o){let a=K(i);if(q(a)==="ZodObject")return{...ae(i),description:r}}return{kind:"unknown",optional:!1,description:r}}case"ZodIntersection":case"ZodPipe":case"ZodTransform":case"ZodEffects":{let o=j(n);return o?{...ae(o),description:r}:{kind:"unknown",optional:!1,description:r}}default:return{kind:"unknown",optional:!1,description:r}}}function Kp(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),a=e.find(c=>c.id===o);if(!a)return null;let s=i;s.startsWith("api.")&&(s=s.slice(4));let u=be(a.endpointMeta,s),l=be(a.endpointSchemas,s);return!u&&!l?null:{input:l?.input?ae(l.input):null,output:l?.output?ae(l.output):null,description:u?.description}}var gr=["equals","contains","startsWith","endsWith","in"],ba=["equals","gt","gte","lt","lte","in"],Ca=["equals"],wa=["equals","before","after","between"];function Yo(e){let n=K(e);switch(q(n)){case"ZodOptional":case"ZodNullable":case"ZodDefault":case"ZodCatch":{let r=j(n);return r?Yo(r):null}case"ZodString":return"string";case"ZodNumber":return"number";case"ZodBoolean":return"boolean";case"ZodDate":return"date";default:return null}}function fr(e){let n=K(e),t=q(n);if(pr(t)){let i=j(n);return i?fr(i):{}}if(t!=="ZodObject")return{};let r=zn(e,n),o={};for(let[i,a]of Object.entries(r)){let s=Yo(a);s==="string"?o[i]={type:"string",operators:gr}:s==="number"?o[i]={type:"number",operators:ba}:s==="boolean"?o[i]={type:"boolean",operators:Ca}:s==="date"&&(o[i]={type:"date",operators:wa})}return o}function Qo(e,n){for(let[t,r]of Object.entries(e))if(t.toLowerCase()===n)return[t,r]}function cr(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"&&cr(o,i,t)}}function lr(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function dr(e,n,t){for(let[r,o]of Object.entries(e)){let i=[...n,r];lr(o)?t.push(i.join(".")):o!==null&&typeof o=="object"&&dr(o,i,t)}}function yr(e,n){if(n.length===0)return null;let[t,...r]=n,o=Object.entries(e).find(([s])=>s.toLowerCase()===t);if(!o)return null;let[i,a]=o;if(r.length===0)return lr(a)?[i]:null;if(a!==null&&typeof a=="object"&&!lr(a)){let s=yr(a,r);if(s!==null)return[i,...s]}return null}function Xo(e,n){let t=[];t.push(`${e}({`),t.push(" webhookHooks: {");for(let i=0;i<n.length;i++){let a=" ".repeat(i+2);t.push(`${a}${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 a=" ".repeat(i+2);t.push(`${a}},`)}return t.push(" },"),t.push("})"),t.join(`
26
+ `)}var Pa=new Set(an);function Se(e,n){let t=n?.type??"api",r=n?.plugin;if(r!==void 0){let i=e.find(s=>s.id===r);if(!i)return Pa.has(r)?`This plugin (${r}) is not configured. Please add it to the Corsair instance to see its associated methods.`:Se(e);if(t==="webhooks"){if(!i.webhooks)return[];let s=[];return dr(i.webhooks,[],s),s.map(u=>`${i.id}.webhooks.${u}`)}if(t==="db"){let s=i.schema?.entities;return s?Object.keys(s).map(u=>`${i.id}.db.${u}.search`):[]}if(!i.endpoints)return[];let a=[];return cr(i.endpoints,[],a),a.map(s=>`${i.id}.api.${s}`)}let o={};if(t==="webhooks")for(let i of e){if(!i.webhooks)continue;let a=[];dr(i.webhooks,[],a),o[i.id]=a.map(s=>`${i.id}.webhooks.${s}`)}else if(t==="db")for(let i of e){let a=i.schema?.entities;a&&(o[i.id]=Object.keys(a).map(s=>`${i.id}.db.${s}.search`))}else for(let i of e){if(!i.endpoints)continue;let a=[];cr(i.endpoints,[],a),o[i.id]=a.map(s=>`${i.id}.api.${s}`)}return o}function be(e,n){if(e){for(let[t,r]of Object.entries(e))if(t.toLowerCase()===n)return r}}function Ta(e,n){let t=e.toLowerCase(),r=n.toLowerCase();if(!t.startsWith(`${r}.`)){let i=t.slice(n.length+1),a=i.startsWith(".")?i.slice(1):i;return a.startsWith("api.")&&(a=a.slice(4)),{shortPath:a,lookupKey:a}}let o=e.slice(n.length+1);return o.toLowerCase().startsWith("api.")&&(o=o.slice(4)),{shortPath:o,lookupKey:o.toLowerCase()}}function ur(e,n){return typeof e=="string"?e:Array.isArray(e)?`${n}:
27
+ ${e.join(", ")}`:`${n}:
28
+ `+Object.entries(e).map(([t,r])=>` ${t}: ${r.join(", ")}`).join(`
29
+ `)}function qp(e,n){let t=n.toLowerCase(),r=t.indexOf(".");if(r!==-1){let o=t.slice(0,r),i=t.slice(r+1),a=e.find(s=>s.id===o);if(a){if(i.startsWith("db.")){let c=i.slice(3),p=c.lastIndexOf(".");if(p!==-1){let g=c.slice(0,p),d=c.slice(p+1),f=a.schema?.entities;if(d==="search"&&f){let y=Qo(f,g);if(y){let[m,h]=y,P=fr(h),C=[`Search ${o} ${m} stored in the local database.`,"Pass limit and offset as numbers for pagination.","","filters {",` entity_id: string [${gr.join(", ")}]`];for(let[_,k]of Object.entries(P))C.push(` ${_}?: ${k.type} [${k.operators.join(", ")}]`);return C.push("}"),C.join(`
30
+ `)}}}return ur(Se(e,{type:"db"}),"Path not found. Available db operations")}if(i.startsWith("webhooks.")){let c=i.slice(9);if(a.webhooks){let p=yr(a.webhooks,c.split("."));if(p!==null){let g=p.join("."),d=be(a.webhookSchemas,g.toLowerCase()),f=d?.response?F(d.response):null,y=[];return d?.description&&y.push(d.description),d?.payload&&y.push(`payload ${Jn($e(d.payload))}`),f&&y.push(`response: ${f}`),y.push(`usage:
31
+ ${Xo(o,p)}`),y.join(`
32
+
33
+ `)}}return ur(Se(e,{type:"webhooks"}),"Path not found. Available webhooks")}let s=i;s.startsWith("api.")&&(s=s.slice(4));let u=be(a.endpointMeta,s),l=be(a.endpointSchemas,s);if(u||l){let c=[],p=[u?.riskLevel?`[${u.riskLevel}]`:"",u?.irreversible?"[irreversible]":""].filter(Boolean).join(" "),g=[u?.description,p].filter(Boolean).join(" ");return g&&c.push(g),l?.input&&c.push(`input ${Jn($e(l.input))}`),l?.output&&c.push(`output ${Jn($e(l.output))}`),c.join(`
34
+
35
+ `)}}}return ur(Se(e),"Path not found. Available operations")}function Go(e){let n=e;for(;;){let t=K(n),r=q(t);if(pr(r)){let o=j(t);if(!o)return n;n=o;continue}return n}}function $e(e){if(e===void 0)return{kind:"inline",type:"unknown"};let n=Go(e),t=K(n);if(q(t)==="ZodObject"){let o=zn(n,t),i=[];for(let[a,s]of Object.entries(o)){let u=K(s),l=q(u),c=l==="ZodOptional"||l==="ZodNullable",p=Go(s),g=ka(s);i.push({key:a,optional:c,type:F(p),...g!==void 0?{description:g}:{}})}return{kind:"object",fields:i}}return{kind:"inline",type:F(n)}}function Jn(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=Zo.repeat(n+1),r=Zo.repeat(n);return`{
36
+ ${e.fields.map(i=>{let a=i.optional?`${i.key}?`:i.key,s=i.description?` // ${i.description}`:"";return`${t}${a}: ${i.type}${s}`}).join(`
37
+ `)}
38
+ ${r}}`}return"unknown"}function va(e,n){let t=Se(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:p,lookupKey:g}=Ta(c,n),d=be(r.endpointMeta,g),f=be(r.endpointSchemas,g);!d&&!f||o.push({path:c,shortPath:p,description:d?.description,riskLevel:d?.riskLevel,irreversible:d?.irreversible,input:$e(f?.input),output:$e(f?.output)})}o.sort((c,p)=>c.path.localeCompare(p.path));let i=[],a=Se(e,{plugin:n,type:"webhooks"});if(Array.isArray(a)&&r.webhooks)for(let c of a){let g=c.toLowerCase().slice(n.length+1),d=g.startsWith(".")?g.slice(1):g;if(!d.startsWith("webhooks."))continue;let f=d.slice(9),y=yr(r.webhooks,f.split("."));if(y===null)continue;let m=y.join("."),h=be(r.webhookSchemas,m.toLowerCase()),P=h?.response?F(h.response):void 0;i.push({path:c,description:h?.description,payload:$e(h?.payload),responseType:P,usageExample:Xo(n,y)})}i.sort((c,p)=>c.path.localeCompare(p.path));let s=[],u=Se(e,{plugin:n,type:"db"}),l=r.schema?.entities;if(Array.isArray(u)&&l)for(let c of u){let g=c.toLowerCase().slice(n.length+1),d=g.startsWith(".")?g.slice(1):g;if(!d.startsWith("db."))continue;let f=d.slice(3),y=f.lastIndexOf(".");if(y===-1)continue;let m=f.slice(0,y);if(f.slice(y+1)!=="search")continue;let P=Qo(l,m);if(!P)continue;let[C,_]=P,k=fr(_),b=Object.entries(k).map(([T,x])=>({field:T,type:x.type,operators:x.operators}));s.push({path:c,entityName:C,filters:[{field:"entity_id",type:"string",operators:gr},...b]})}return s.sort((c,p)=>c.path.localeCompare(p.path)),{ok:!0,data:{pluginId:n,api:o,webhooks:i,db:s}}}function ei(e,n){for(let[t,r]of Object.entries(e))if(r?.pluginWebhookMatcher&&r.pluginWebhookMatcher(n))return t;return null}function Aa(e,n){let t=ei(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 xa(e){let n={};for(let t of e)!t.pluginWebhookMatcher&&!t.pluginTenantWebhookMatcher||(n[t.id]={pluginWebhookMatcher:t.pluginWebhookMatcher,pluginTenantWebhookMatcher:t.pluginTenantWebhookMatcher});return n}function ni(e,n){let t=n.toLowerCase(),r=e[t]??e[n];return Array.isArray(r)?r[0]:typeof r=="string"?r:void 0}function ti(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 rn(e){return!e||typeof e!="object"||Array.isArray(e)?null:e}function Ia(e){return rn(e.body)}function ri(e,n){let t=e.query;if(!t)return;let r=t[n]??t[n.toLowerCase()];return Vn(Array.isArray(r)?r:[r])}function oi(e){let n=e.headers??{},t=[n.validationtoken,n.validationToken,n["validation-token"],n["ms-validation-token"]];for(let u of t){let l=Vn(Array.isArray(u)?u:[u]);if(l)return decodeURIComponent(l)}let r=ri({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 g=(c.startsWith("http")?new URL(c):new URL(`https://example.invalid${c.startsWith("/")?c:`/${c}`}`)).searchParams.get("validationToken");if(g?.trim())return g.trim()}catch{continue}}let i=e.payload!==void 0?e.payload:e.body!==void 0?e.body:void 0,a=rn(typeof i=="string"?(()=>{try{return JSON.parse(i)}catch{return i}})():i);return Vn([a?.validationToken])??null}function Sa(e){if(oi(e))return!0;let n=rn(e.body??e.payload);return ni(e.headers??{},"content-type")?.includes("text/plain")?!n||Object.keys(n).length===0:!1}function Vn(e){for(let n of e){let t=ti(n);if(t)return t}}function Ra(e){let t=rn(e.message)?.data;if(typeof t!="string")return null;try{return JSON.parse(Buffer.from(t,"base64").toString("utf8"))}catch{return null}}var tn=Symbol.for("corsair:internal");function Kr(e){let n=e.database?mr(e.database):void 0,t=n&&e.kek?Fo(e.plugins,n,e.kek):Zn(!!n,!!e.kek),r=Bo(e),o={plugins:e.plugins,database:n,kek:e.kek,multiTenancy:!!e.multiTenancy,permissions:r,manual:e.manual,hub:e.hub?un(e.hub):void 0},i=no(n),a=Wo(o);if(e.multiTenancy)return Object.assign({withTenant:u=>{if(!u)throw new Error("corsair.withTenant(tenantId): tenantId must be a non-empty string");let l=ar(e.plugins,{database:n,tenantId:u,kek:e.kek,rootErrorHandlers:e.errorHandlers,permissionsOptions:r,manualConfig:e.manual,hubConfig:o.hub,internalConfig:o});return Object.assign(l,{[tn]:o})},keys:t,permissions:i,manage:a},{[tn]:o});let s=ar(e.plugins,{database:n,tenantId:void 0,kek:e.kek,rootErrorHandlers:e.errorHandlers,permissionsOptions:r,manualConfig:e.manual,hubConfig:o.hub,internalConfig:o});return Object.assign({},s,{keys:t,permissions:i,manage:a,[tn]:o})}var U=class extends Error{code;constructor(n,t){super(t),this.name="OAuthCallbackError",this.code=n}};function ii(e){let n=e.oauthConfig;if(!n)throw new U("plugin_has_no_oauth_config",`Plugin '${e.id}' has no oauthConfig`);return n}async function _a(e,n,t,r){let o=Tr(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 s=te(),u=await re(s,r);await o.accounts.create({tenant_id:t,integration_id:i.id,config:{},dek:u})}async function rt(e,n,t){let{tenantId:r,redirectUri:o,hubConnect:i=!1}=t,a=w(e,()=>new U("invalid_corsair_instance","Invalid corsair instance"));if(!a.database)throw new Error("No database configured on corsair instance");let s=H(a,n,g=>new U("plugin_not_found",g)),u=ii(s),c=await S({authType:"oauth_2",integrationName:n,kek:a.kek,database:a.database}).get_client_id();if(!c)throw new Error(`client_id not configured for '${n}'`);if(i){let g=new URL(Pe({oauthConfig:u,clientId:c,redirectUri:o,state:""}));return g.searchParams.delete("state"),{url:g.toString(),state:""}}let p=Oe(fe(n,r),a.kek);return{url:Pe({oauthConfig:u,clientId:c,redirectUri:o,state:p}),state:p}}async function en(e,n){let{code:t,state:r,redirectUri:o}=n,i=w(e,()=>new U("invalid_corsair_instance","Invalid corsair instance")),a=vn(r,i.kek);if(!a)throw new U("invalid_state","Invalid or tampered state parameter");let{plugin:s,tenantId:u}=a;if(!i.database)throw new U("no_database","No database configured on corsair instance");let l=H(i,s,m=>new U("plugin_not_found",m)),c=ii(l),p=S({authType:"oauth_2",integrationName:s,kek:i.kek,database:i.database}),g=await p.get_client_id(),d=await p.get_client_secret();if(!g||!d)throw new U("credentials_not_configured",`Credentials not configured for '${s}'`);await _a(i.database,s,u,i.kek);let f=await Gn(t,g,d,c,o);if(!f.access_token)throw new U("no_access_token",`No access_token returned from ${c.providerName}`);let y=E({authType:"oauth_2",integrationName:s,tenantId:u,kek:i.kek,database:i.database});await y.set_access_token(f.access_token),f.refresh_token&&await y.set_refresh_token(f.refresh_token),f.expires_in&&await y.set_expires_at(String(Math.floor(Date.now()/1e3)+f.expires_in));try{let m=await Nn(i.plugins,s,f);if(m)try{let h=l.authConfig?.oauth_2?.account??[];await Ue({database:i.database,kek:i.kek,pluginId:s,tenantId:u,link:m,authType:"oauth_2",extraAccountFields:h})}catch(h){console.warn(`[corsair:oauth] Failed to persist webhook tenant link for '${s}' tenant '${u}':`,h)}}catch(m){console.warn(`[corsair:oauth] Failed to resolve webhook tenant link for '${s}' tenant '${u}':`,m)}return{plugin:s,tenantId:u}}export{vr as a,le as b,Ke as c,de as d,un as e,J as f,cn as g,Re as h,ln as i,dn as j,pn as k,gn as l,xr as m,fn as n,_e as o,te as p,re as q,$ as r,Xn as s,Ze as t,ge as u,oe as v,Ge as w,S as x,E as y,Br as z,Ur as A,fe as B,st as C,Ue as D,_t as E,$n as F,Co as G,Pe as H,U as I,rt as J,en as K,wn as L,Ji as M,Pn as N,Cu as O,ot as P,wu as Q,Jr as R,it as S,Tn as T,Vr as U,Yr as V,ut as W,An as X,xn as Y,me as Z,Te as _,Fn as $,bt as aa,Be as ba,Ct as ca,wt as da,Pt as ea,Tt as fa,It as ga,St as ha,mo as ia,ho as ja,he as ka,Le as la,Po as ma,se as na,jn as oa,Kn as pa,ke as qa,Ae as ra,Qe as sa,Xe as ta,qn as ua,Mt as va,Ht as wa,Bt as xa,Ut as ya,Lt as za,Nt as Aa,$t as Ba,xe as Ca,Q as Da,Wt as Ea,So as Fa,_o as Ga,jt as Ha,Kt as Ia,qt as Ja,Zt as Ka,Gt as La,Jt as Ma,zt as Na,Vt as Oa,Yt as Pa,Qt as Qa,Xt as Ra,er as Sa,nr as Ta,tr as Ua,rr as Va,Ie as Wa,Lo as Xa,No as Ya,$o as Za,jo as _a,ha as $a,Gn as ab,Kp as bb,Se as cb,qp as db,Jn as eb,va as fb,ei as gb,Aa as hb,xa as ib,ni as jb,ti as kb,rn as lb,Ia as mb,ri as nb,oi as ob,Sa as pb,Vn as qb,Ra as rb,tn as sb,Kr as tb};
@@ -1,9 +1,9 @@
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-cJXSdmph.js';
2
- export { f as PermissionLookupInput } from '../../types-cJXSdmph.js';
3
- import { C as CorsairClientOptions, a as CorsairManagementClient } from '../../types-B2mWx_9M.js';
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-CzXqyIs-.js';
2
+ export { f as PermissionLookupInput } from '../../types-CzXqyIs-.js';
3
+ import { C as CorsairClientOptions, a as CorsairManagementClient } from '../../types-Cy9zP96e.js';
4
4
  import '../../index-ggMa1Rj6.js';
5
5
  import 'zod';
6
- import '../../constants-DnSLjl7e.js';
6
+ import '../../constants-CQtdZMk5.js';
7
7
 
8
8
  type AsyncState<T> = {
9
9
  status: 'idle';
@@ -0,0 +1 @@
1
+ import{R as a,S as b,T as c}from"./chunk-KVHTNDXM.js";import"./chunk-BPFUYXOD.js";import"./chunk-IGGCNGU2.js";import"./chunk-QAIKSQAD.js";export{c as createHubConnectSession,b as createHubConnectSessionForPlugin,a as postHubConnectSession};
@@ -1,5 +1,5 @@
1
1
  type AllErrors = 'RATE_LIMIT_ERROR' | 'AUTH_ERROR' | 'PERMISSION_ERROR' | 'NETWORK_ERROR' | 'TIMEOUT_ERROR' | 'SERVER_ERROR' | 'VALIDATION_ERROR' | 'NOT_FOUND_ERROR' | 'BAD_REQUEST_ERROR' | 'PARSING_ERROR' | 'DEFAULT' | (string & {});
2
- declare const BaseProviders: readonly ["agentql", "ahrefs", "airtable", "amplitude", "asana", "bitwarden", "bluesky", "box", "cal", "calendly", "cloudflare", "cursor", "discord", "dodopayments", "dropbox", "exa", "figma", "firecrawl", "fireflies", "github", "gitlab", "gmail", "googlecalendar", "googledrive", "googlesheets", "grafana", "hackernews", "hubspot", "intercom", "jira", "linear", "monday", "notion", "onedrive", "openweathermap", "oura", "outlook", "pagerduty", "posthog", "razorpay", "reddit", "resend", "sentry", "sharepoint", "slack", "spotify", "strava", "stripe", "tally", "tavily", "teams", "telegram", "todoist", "trello", "twilio", "twitter", "twitterapiio", "typeform", "vapi", "xquik", "youtube", "zendesk", "zohomail", "zoom"];
2
+ declare const BaseProviders: readonly ["agentql", "ahrefs", "airtable", "amplitude", "asana", "bitwarden", "bluesky", "box", "cal", "calendly", "cloudflare", "cursor", "discord", "dodopayments", "dropbox", "exa", "figma", "firecrawl", "fireflies", "github", "gitlab", "gmail", "googlecalendar", "googledrive", "googlemeet", "googlesheets", "grafana", "hackernews", "hubspot", "instagram", "intercom", "jira", "linear", "monday", "notion", "onedrive", "openweathermap", "oura", "outlook", "pagerduty", "posthog", "razorpay", "reddit", "resend", "sentry", "sharepoint", "slack", "spotify", "strava", "stripe", "supabase", "tally", "tavily", "teams", "telegram", "todoist", "trello", "twilio", "twitter", "twitterapiio", "typeform", "vapi", "xquik", "youtube", "zendesk", "zohomail", "zoom"];
3
3
  declare const ProviderDisplayNames: {
4
4
  readonly agentql: "AgentQL";
5
5
  readonly ahrefs: "Ahrefs";
@@ -25,10 +25,12 @@ declare const ProviderDisplayNames: {
25
25
  readonly gmail: "Gmail";
26
26
  readonly googlecalendar: "Google Calendar";
27
27
  readonly googledrive: "Google Drive";
28
+ readonly googlemeet: "Google Meet";
28
29
  readonly googlesheets: "Google Sheets";
29
30
  readonly grafana: "Grafana";
30
31
  readonly hackernews: "Hacker News";
31
32
  readonly hubspot: "HubSpot";
33
+ readonly instagram: "Instagram";
32
34
  readonly intercom: "Intercom";
33
35
  readonly jira: "Jira";
34
36
  readonly linear: "Linear";
@@ -49,6 +51,7 @@ declare const ProviderDisplayNames: {
49
51
  readonly spotify: "Spotify";
50
52
  readonly strava: "Strava";
51
53
  readonly stripe: "Stripe";
54
+ readonly supabase: "Supabase";
52
55
  readonly tally: "Tally";
53
56
  readonly tavily: "Tavily";
54
57
  readonly teams: "Teams";
@@ -67,7 +70,7 @@ declare const ProviderDisplayNames: {
67
70
  readonly zoom: "Zoom";
68
71
  };
69
72
  declare function formatProviderDisplayName(plugin: string): string;
70
- type AllProviders = 'agentql' | 'ahrefs' | 'airtable' | 'amplitude' | 'asana' | 'bitwarden' | 'bluesky' | 'box' | 'cal' | 'calendly' | 'cloudflare' | 'cursor' | 'discord' | 'dodopayments' | 'dropbox' | 'exa' | 'figma' | 'firecrawl' | 'fireflies' | 'github' | 'gitlab' | 'gmail' | 'googlecalendar' | 'googledrive' | 'googlesheets' | 'grafana' | 'hackernews' | 'hubspot' | 'intercom' | 'jira' | 'linear' | 'monday' | 'notion' | 'onedrive' | 'openweathermap' | 'oura' | 'outlook' | 'pagerduty' | 'posthog' | 'razorpay' | 'reddit' | 'resend' | 'sentry' | 'sharepoint' | 'slack' | 'spotify' | 'strava' | 'stripe' | 'tally' | 'tavily' | 'teams' | 'telegram' | 'todoist' | 'trello' | 'twilio' | 'twitter' | 'twitterapiio' | 'typeform' | 'vapi' | 'xquik' | 'youtube' | 'zendesk' | 'zohomail' | 'zoom' | (string & {});
73
+ type AllProviders = 'agentql' | 'ahrefs' | 'airtable' | 'amplitude' | 'asana' | 'bitwarden' | 'bluesky' | 'box' | 'cal' | 'calendly' | 'cloudflare' | 'cursor' | 'discord' | 'dodopayments' | 'dropbox' | 'exa' | 'figma' | 'firecrawl' | 'fireflies' | 'github' | 'gitlab' | 'gmail' | 'googlecalendar' | 'googledrive' | 'googlemeet' | 'googlesheets' | 'grafana' | 'hackernews' | 'hubspot' | 'instagram' | 'intercom' | 'jira' | 'linear' | 'monday' | 'notion' | 'onedrive' | 'openweathermap' | 'oura' | 'outlook' | 'pagerduty' | 'posthog' | 'razorpay' | 'reddit' | 'resend' | 'sentry' | 'sharepoint' | 'slack' | 'spotify' | 'strava' | 'stripe' | 'supabase' | 'tally' | 'tavily' | 'teams' | 'telegram' | 'todoist' | 'trello' | 'twilio' | 'twitter' | 'twitterapiio' | 'typeform' | 'vapi' | 'xquik' | 'youtube' | 'zendesk' | 'zohomail' | 'zoom' | (string & {});
71
74
  type AuthTypes = 'oauth_2' | 'api_key' | 'bot_token' | 'managed';
72
75
  type PickAuth<T extends AuthTypes> = T;
73
76
 
package/dist/core.d.ts CHANGED
@@ -1,18 +1,18 @@
1
- export { C as CORSAIR_INTERNAL, a as CorsairInternalConfig, c as createCorsair } from './index-8JfaxmWD.js';
1
+ export { C as CORSAIR_INTERNAL, a as CorsairInternalConfig, c as createCorsair } from './index-CY6fUO8K.js';
2
2
  import { CorsairDatabase } from './db.js';
3
- import { A as AccountKeyManagerFor, I as IntegrationKeyManagerFor } from './types-BZ-KI4kd.js';
4
- export { a as AccountFieldNames, d as BASE_AUTH_FIELDS, B as BaseAuthFieldConfig, b as BaseKeyManager, e as Bivariant, c as IntegrationFieldNames, O as OAuth2IntegrationCredentials, P as PluginAuthConfig, U as UnionToIntersection } from './types-BZ-KI4kd.js';
5
- export { v as BeforeHookResult, B as BindEndpoints, N as BindWebhooks, h as BoundEndpointFn, i as BoundEndpointTree, Q as BoundWebhook, S as BoundWebhookTree, g as CorsairClient, j as CorsairContext, k as CorsairEndpoint, m as CorsairErrorHandler, c as CorsairIntegration, w as CorsairKeyBuilder, x as CorsairKeyBuilderBase, U as CorsairOAuthWebhookTenantLinkResolver, s as CorsairPermissionsNamespace, C as CorsairPlugin, y as CorsairPluginContext, e as CorsairSingleTenantClient, d as CorsairTenantWrapper, V as CorsairWebhook, X as CorsairWebhookHandler, Y as CorsairWebhookMatcher, Z as CorsairWebhookTenantMatcher, z as EndpointHooks, A as EndpointMetaEntry, E as EndpointPathsOf, D as EndpointRiskLevel, l as EndpointTree, t as EnforcePermissionOptions, u as EnforcePermissionResult, n as ErrorContext, o as ErrorHandler, p as ErrorHandlerAndMatchFunction, q as ErrorMatcher, K as KeyBuilderContext, O as OAuthConfig, P as PermissionMode, F as PermissionPolicy, G as PluginEndpointMeta, H as PluginPermissionsConfig, _ as RawWebhookRequest, I as RequiredPluginEndpointMeta, J as RequiredPluginEndpointSchemas, L as RequiredPluginWebhookSchemas, R as RetryStrategies, r as RetryStrategy, T as TokenResponse, M as WebhookHooks, $ as WebhookPathsOf, a0 as WebhookRequest, a1 as WebhookResponse, W as WebhookTenantMatch, a2 as WebhookTree, f as exchangeCodeForTokens } from './index-BjEnNYJD.js';
6
- export { A as AuthMissingError, D as DocSchemaFieldRow, a as DocSchemaShape, b as DocsApiEndpoint, c as DocsDbEntity, d as DocsDbFilterField, e as DocsWebhook, E as EndpointSchemaResult, I as IntrospectPluginForDocsResult, L as ListOperationsOptions, P as PluginDocsIntrospection, j as PluginWebhookMatchers, R as ResolveConnectLinkResult, W as WebhookPluginTenantMatch, k as asRecord, g as collectPluginWebhookMatchers, l as decodePubSubData, n as extractMicrosoftGraphValidationToken, o as firstString, f as formatDocSchemaShape, p as getHeader, i as introspectPluginForDocs, q as isMicrosoftGraphValidationHandshake, m as matchWebhookPlugin, h as matchWebhookPluginAndTenant, s as readBodyRecord, t as readQueryParam, r as resolveConnectLink, u as toExternalId } from './tenant-match-utils-DU4saqFg.js';
7
- import { A as AuthTypes } from './constants-DnSLjl7e.js';
8
- export { a as AllProviders, B as BaseProviders, P as PickAuth, b as ProviderDisplayNames, f as formatProviderDisplayName } from './constants-DnSLjl7e.js';
3
+ import { A as AccountKeyManagerFor, I as IntegrationKeyManagerFor } from './types-DpJORHx2.js';
4
+ export { a as AccountFieldNames, d as BASE_AUTH_FIELDS, B as BaseAuthFieldConfig, b as BaseKeyManager, e as Bivariant, c as IntegrationFieldNames, O as OAuth2IntegrationCredentials, P as PluginAuthConfig, U as UnionToIntersection } from './types-DpJORHx2.js';
5
+ export { v as BeforeHookResult, B as BindEndpoints, N as BindWebhooks, h as BoundEndpointFn, i as BoundEndpointTree, Q as BoundWebhook, S as BoundWebhookTree, g as CorsairClient, j as CorsairContext, k as CorsairEndpoint, m as CorsairErrorHandler, c as CorsairIntegration, w as CorsairKeyBuilder, x as CorsairKeyBuilderBase, U as CorsairOAuthWebhookTenantLinkResolver, s as CorsairPermissionsNamespace, C as CorsairPlugin, y as CorsairPluginContext, e as CorsairSingleTenantClient, d as CorsairTenantWrapper, V as CorsairWebhook, X as CorsairWebhookHandler, Y as CorsairWebhookMatcher, Z as CorsairWebhookTenantMatcher, z as EndpointHooks, A as EndpointMetaEntry, E as EndpointPathsOf, D as EndpointRiskLevel, l as EndpointTree, t as EnforcePermissionOptions, u as EnforcePermissionResult, n as ErrorContext, o as ErrorHandler, p as ErrorHandlerAndMatchFunction, q as ErrorMatcher, K as KeyBuilderContext, O as OAuthConfig, P as PermissionMode, F as PermissionPolicy, G as PluginEndpointMeta, H as PluginPermissionsConfig, _ as RawWebhookRequest, I as RequiredPluginEndpointMeta, J as RequiredPluginEndpointSchemas, L as RequiredPluginWebhookSchemas, R as RetryStrategies, r as RetryStrategy, T as TokenResponse, M as WebhookHooks, $ as WebhookPathsOf, a0 as WebhookRequest, a1 as WebhookResponse, W as WebhookTenantMatch, a2 as WebhookTree, f as exchangeCodeForTokens } from './index-BwQsXpxI.js';
6
+ export { A as AuthMissingError, D as DocSchemaFieldRow, a as DocSchemaShape, b as DocsApiEndpoint, c as DocsDbEntity, d as DocsDbFilterField, e as DocsWebhook, E as EndpointSchemaResult, I as IntrospectPluginForDocsResult, L as ListOperationsOptions, P as PluginDocsIntrospection, j as PluginWebhookMatchers, R as ResolveConnectLinkResult, W as WebhookPluginTenantMatch, k as asRecord, g as collectPluginWebhookMatchers, l as decodePubSubData, n as extractMicrosoftGraphValidationToken, o as firstString, f as formatDocSchemaShape, p as getHeader, i as introspectPluginForDocs, q as isMicrosoftGraphValidationHandshake, m as matchWebhookPlugin, h as matchWebhookPluginAndTenant, s as readBodyRecord, t as readQueryParam, r as resolveConnectLink, u as toExternalId } from './tenant-match-utils-mRNSoG3k.js';
7
+ import { A as AuthTypes } from './constants-CQtdZMk5.js';
8
+ export { a as AllProviders, B as BaseProviders, P as PickAuth, b as ProviderDisplayNames, f as formatProviderDisplayName } from './constants-CQtdZMk5.js';
9
9
  import 'kysely';
10
10
  import './index-ggMa1Rj6.js';
11
11
  import 'zod';
12
12
  import 'pg';
13
13
  import 'postgres';
14
14
  import './orm.js';
15
- import './types-cJXSdmph.js';
15
+ import './types-CzXqyIs-.js';
16
16
 
17
17
  /**
18
18
  * Context interface with account ID resolver for logging events.
@@ -136,6 +136,7 @@ type AccountKeyManagerOptions<T extends AuthTypes> = {
136
136
  database: CorsairDatabase;
137
137
  /** Extra account-level fields from plugin authConfig */
138
138
  extraAccountFields?: readonly string[];
139
+ ensureProvisioned?: () => Promise<void>;
139
140
  };
140
141
  /**
141
142
  * Creates an account-level key manager for the given auth type.
package/dist/core.js CHANGED
@@ -1 +1 @@
1
- import{$a as v,A as o,Pa as q,Ua as r,Va as s,Wa as t,_a as u,a,ab as w,b,bb as x,cb as y,db as z,eb as A,fb as B,gb as C,hb as D,ib as E,jb as F,kb as G,lb as H,mb as I,nb as J,p as d,q as e,r as f,s as g,t as h,u as i,ua as p,v as j,w as k,x as l,y as m,z as n}from"./chunk-OVJRYUB3.js";import{g as c}from"./chunk-67EXGXPK.js";import"./chunk-IGGCNGU2.js";import"./chunk-QAIKSQAD.js";export{p as AuthMissingError,c as BASE_AUTH_FIELDS,I as CORSAIR_INTERNAL,a as ProviderDisplayNames,B as asRecord,y as collectPluginWebhookMatchers,m as createAccountKeyManager,J as createCorsair,l as createIntegrationKeyManager,H as decodePubSubData,j as decryptConfig,f as decryptDEK,h as decryptWithDEK,i as encryptConfig,e as encryptDEK,g as encryptWithDEK,t as exchangeCodeForTokens,E as extractMicrosoftGraphValidationToken,G as firstString,u as formatDocSchemaShape,b as formatProviderDisplayName,d as generateDEK,z as getHeader,o as initializeAccountDEK,n as initializeIntegrationDEK,v as introspectPluginForDocs,F as isMicrosoftGraphValidationHandshake,r as logEvent,s as logEventFromContext,w as matchWebhookPlugin,x as matchWebhookPluginAndTenant,k as reEncryptConfig,C as readBodyRecord,D as readQueryParam,q as resolveConnectLink,A as toExternalId};
1
+ import{$a as s,A as o,Da as q,W as p,_a as r,a,ab as t,b,eb as u,fb as v,gb as w,hb as x,ib as y,jb as z,kb as A,lb as B,mb as C,nb as D,ob as E,p as d,pb as F,q as e,qb as G,r as f,rb as H,s as g,sb as I,t as h,tb as J,u as i,v as j,w as k,x as l,y as m,z as n}from"./chunk-KVHTNDXM.js";import{h as c}from"./chunk-BPFUYXOD.js";import"./chunk-IGGCNGU2.js";import"./chunk-QAIKSQAD.js";export{q as AuthMissingError,c as BASE_AUTH_FIELDS,I as CORSAIR_INTERNAL,a as ProviderDisplayNames,B as asRecord,y as collectPluginWebhookMatchers,m as createAccountKeyManager,J as createCorsair,l as createIntegrationKeyManager,H as decodePubSubData,j as decryptConfig,f as decryptDEK,h as decryptWithDEK,i as encryptConfig,e as encryptDEK,g as encryptWithDEK,t as exchangeCodeForTokens,E as extractMicrosoftGraphValidationToken,G as firstString,u as formatDocSchemaShape,b as formatProviderDisplayName,d as generateDEK,z as getHeader,o as initializeAccountDEK,n as initializeIntegrationDEK,v as introspectPluginForDocs,F as isMicrosoftGraphValidationHandshake,r as logEvent,s as logEventFromContext,w as matchWebhookPlugin,x as matchWebhookPluginAndTenant,k as reEncryptConfig,C as readBodyRecord,D as readQueryParam,p as resolveConnectLink,A as toExternalId};
package/dist/hub.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { A as AuthTypes } from './constants-DnSLjl7e.js';
2
- export { f as formatProviderDisplayName } from './constants-DnSLjl7e.js';
3
- import { g as HubOAuthMode, h as HubConnectSessionResult, i as HubPermissionSessionResult, H as HubConfig, f as HubConfigInput, j as HubConnectSessionInput, k as HubListProjectConnectionsInput, A as AccountKeyManagerFor, l as HubPermissionSessionInput } from './types-BZ-KI4kd.js';
4
- export { D as DEFAULT_HUB_API_URL, m as HubEnvironmentSlug } from './types-BZ-KI4kd.js';
5
- import { e as TunnelType, c as ProcessCorsairRequest } from './index-BHI3widx.js';
6
- export { f as BROWSER_DELIVERY_TTL_MS, g as BrowserDeliveryMode, B as BrowserDeliveryPayload, S as SIGNED_TUNNEL_REPLAY_WINDOW_MS, d as TunnelEnvelope } from './index-BHI3widx.js';
7
- export { b as buildBrowserDeliveryRedirectUrl, s as signBrowserDeliveryToken, v as verifyBrowserDeliveryToken } from './browser-delivery-DW81SP-j.js';
1
+ import { A as AuthTypes } from './constants-CQtdZMk5.js';
2
+ export { f as formatProviderDisplayName } from './constants-CQtdZMk5.js';
3
+ import { g as HubOAuthMode, h as HubConnectSessionResult, i as HubPermissionSessionResult, H as HubConfig, f as HubConfigInput, j as HubConnectSessionInput, k as HubListProjectConnectionsInput, A as AccountKeyManagerFor, l as HubPermissionSessionInput } from './types-DpJORHx2.js';
4
+ export { D as DEFAULT_HUB_API_URL, m as HubEnvironmentSlug } from './types-DpJORHx2.js';
5
+ import { e as TunnelType, c as ProcessCorsairRequest } from './index-B0R9rnZt.js';
6
+ export { f as BROWSER_DELIVERY_TTL_MS, g as BrowserDeliveryMode, B as BrowserDeliveryPayload, S as SIGNED_TUNNEL_REPLAY_WINDOW_MS, d as TunnelEnvelope } from './index-B0R9rnZt.js';
7
+ export { b as buildBrowserDeliveryRedirectUrl, s as signBrowserDeliveryToken, v as verifyBrowserDeliveryToken } from './browser-delivery-e1gccz5W.js';
8
8
 
9
9
  type ConnectAuthKind = 'oauth' | 'api_key' | 'bot_token';
10
10
  type ConnectPluginManifestEntry = {
@@ -20,8 +20,7 @@ type ConnectPluginManifestEntry = {
20
20
  type HubProjectConnection = {
21
21
  tenantId: string;
22
22
  plugin: string;
23
- authKind: ConnectAuthKind;
24
- authType?: AuthTypes;
23
+ authType: AuthTypes;
25
24
  status: ConnectAuthStatusLevel;
26
25
  connected: boolean;
27
26
  verified: boolean;
@@ -157,6 +156,14 @@ type ServerDeliveryAckBody = {
157
156
  status?: string;
158
157
  /** Human-readable error when delivery was rejected by the app. */
159
158
  error?: string;
159
+ /** Hosted connect URL returned by connect.create_link deliveries. */
160
+ connectUrl?: string;
161
+ /** ISO expiry for connect.create_link deliveries. */
162
+ expiresAt?: string;
163
+ /** Encrypted tenant/plugin manifest returned by connections.sync deliveries. */
164
+ sync?: {
165
+ encrypted: string;
166
+ };
160
167
  };
161
168
  /**
162
169
  * Signs a tunnel envelope for server POST delivery.
package/dist/hub.js CHANGED
@@ -1 +1 @@
1
- import{$ as C,Aa as V,Ba as W,Ca as X,Da as Y,Ea as Z,Fa as _,Ga as $,Ha as aa,Ia as ba,Ja as ca,Ka as da,La as ea,Ma as fa,N as o,Na as ga,O as p,Oa as ha,P as q,Q as r,R as s,S as t,T as u,U as v,V as w,W as x,X as y,Y as z,Z as A,_ as B,aa as D,b as a,ba as E,c as b,ca as F,d as c,e as d,ea as G,f as e,fa as H,g as f,ga as I,h as g,ha as J,i as h,j as i,k as j,l as k,m as l,n as m,o as n,oa as K,pa as L,qa as M,ra as N,sa as O,ta as P,va as Q,wa as R,xa as S,ya as T,za as U}from"./chunk-OVJRYUB3.js";import"./chunk-67EXGXPK.js";import"./chunk-IGGCNGU2.js";import"./chunk-QAIKSQAD.js";export{v as BROWSER_DELIVERY_TTL_MS,b as DEFAULT_HUB_API_URL,c as HubNotConfiguredError,x as ManagedOAuthDeliveryError,w as SIGNED_TUNNEL_REPLAY_WINDOW_MS,R as attachManagedRefreshAuth,H as buildBrowserDeliveryRedirectUrl,V as createConnectSessionJti,_ as createConnectTokenJti,o as createHubConnectSession,S as createHubPermissionSession,U as createHubRouteHandlers,ea as createPermissionSessionJti,G as createSignedTokenJti,Z as decodeConnectSessionTokenFromPath,da as decodeConnectTokenFromPath,ha as decodePermissionTokenFromPath,F as deliverSignedEnvelope,ca as encodeConnectTokenForPath,T as formatHubApprovalMessage,a as formatProviderDisplayName,E as formatServerDeliveryError,W as getConnectSessionExpiryMs,p as getConnectStatusForTenant,$ as getConnectTokenExpiryMs,e as getHubConfig,Q as getManagedAccessToken,K as handleHubDeliveryGet,L as handleHubDeliveryPost,N as handleHubDeliveryRequest,M as hubDeliveryToResponse,g as inferHubEnvironmentSlug,r as isLoopbackUrl,D as isServerDeliveryAckSuccessful,q as listHubProjectConnections,d as normalizeHubConfig,h as parseConnectSessionResponse,l as parseConnectStatusResponse,m as parseHubApiErrorBody,k as parseOAuthRefreshResponse,j as parsePermissionSessionResponse,i as parseProjectConnectionsResponse,C as parseServerDeliveryAckBody,y as processManagedOAuthDelivery,s as resolveDeliveryTransport,n as resolveHubDeliveryUrl,f as resolveHubOAuthCallbackUrl,O as respondToHubDelivery,P as respondToHubDeliveryFromRequest,I as signBrowserDeliveryToken,X as signConnectSessionToken,aa as signConnectToken,z as signDeliveryEnvelope,fa as signPermissionToken,t as usesBrowserDelivery,u as validateProductionDeliveryUrl,J as verifyBrowserDeliveryToken,Y as verifyConnectSessionToken,ba as verifyConnectToken,A as verifyDeliveryEnvelope,ga as verifyPermissionToken,B as verifySignedTunnelDelivery};
1
+ import{$ as v,Aa as P,Ba as Q,Ca as R,Ea as S,Fa as T,Ga as U,Ha as V,Ia as W,Ja as X,Ka as Y,La as Z,Ma as _,Na as $,Oa as aa,Pa as ba,Qa as ca,Ra as da,Sa as ea,T as o,Ta as fa,U as p,Ua as ga,V as q,Va as ha,X as r,Y as s,Z as t,_ as u,aa as w,b as a,ba as x,c as b,ca as y,d as c,da as z,e as d,ea as A,f as e,fa as B,g as f,ga as C,h as g,ha as D,i as h,ia as E,j as i,ja as F,k as j,ka as G,l as k,la as H,m as l,n as m,na as I,o as n,oa as J,pa as K,qa as L,xa as M,ya as N,za as O}from"./chunk-KVHTNDXM.js";import"./chunk-BPFUYXOD.js";import"./chunk-IGGCNGU2.js";import"./chunk-QAIKSQAD.js";export{t as BROWSER_DELIVERY_TTL_MS,b as DEFAULT_HUB_API_URL,c as HubNotConfiguredError,G as ManagedOAuthDeliveryError,u as SIGNED_TUNNEL_REPLAY_WINDOW_MS,T as attachManagedRefreshAuth,J as buildBrowserDeliveryRedirectUrl,V as createConnectSessionJti,_ as createConnectTokenJti,o as createHubConnectSession,r as createHubPermissionSession,U as createHubRouteHandlers,ea as createPermissionSessionJti,I as createSignedTokenJti,Z as decodeConnectSessionTokenFromPath,da as decodeConnectTokenFromPath,ha as decodePermissionTokenFromPath,B as deliverSignedEnvelope,ca as encodeConnectTokenForPath,s as formatHubApprovalMessage,a as formatProviderDisplayName,A as formatServerDeliveryError,W as getConnectSessionExpiryMs,p as getConnectStatusForTenant,$ as getConnectTokenExpiryMs,e as getHubConfig,S as getManagedAccessToken,M as handleHubDeliveryGet,N as handleHubDeliveryPost,P as handleHubDeliveryRequest,O as hubDeliveryToResponse,g as inferHubEnvironmentSlug,C as isLoopbackUrl,z as isServerDeliveryAckSuccessful,q as listHubProjectConnections,d as normalizeHubConfig,h as parseConnectSessionResponse,l as parseConnectStatusResponse,m as parseHubApiErrorBody,k as parseOAuthRefreshResponse,j as parsePermissionSessionResponse,i as parseProjectConnectionsResponse,y as parseServerDeliveryAckBody,H as processManagedOAuthDelivery,D as resolveDeliveryTransport,n as resolveHubDeliveryUrl,f as resolveHubOAuthCallbackUrl,Q as respondToHubDelivery,R as respondToHubDeliveryFromRequest,K as signBrowserDeliveryToken,X as signConnectSessionToken,aa as signConnectToken,v as signDeliveryEnvelope,fa as signPermissionToken,E as usesBrowserDelivery,F as validateProductionDeliveryUrl,L as verifyBrowserDeliveryToken,Y as verifyConnectSessionToken,ba as verifyConnectToken,w as verifyDeliveryEnvelope,ga as verifyPermissionToken,x as verifySignedTunnelDelivery};
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * Each value maps to a handler in the app's tunnel/delivery endpoint.
8
8
  */
9
- type TunnelType = 'oauth.callback' | 'oauth.tokens' | 'webhook' | 'permission.approve' | 'permission.deny' | 'auth.credentials' | 'integration.credentials' | 'run';
9
+ type TunnelType = 'oauth.callback' | 'oauth.tokens' | 'webhook' | 'permission.approve' | 'permission.deny' | 'auth.credentials' | 'integration.credentials' | 'connect.create_link' | 'connections.sync' | 'run';
10
10
  /**
11
11
  * JSON body of a server-side delivery POST from the hub.
12
12
  *
@@ -82,6 +82,10 @@ type TunnelAck = {
82
82
  status: 'ok' | 'failed';
83
83
  retryable?: boolean;
84
84
  error?: string;
85
+ connectLink?: {
86
+ connectUrl: string;
87
+ expiresAt?: string;
88
+ };
85
89
  webhookResponse?: {
86
90
  status?: number;
87
91
  body?: unknown;
@@ -1,9 +1,9 @@
1
1
  import { ZodTypeAny } from 'zod';
2
2
  import { CorsairDatabase, CorsairDatabaseInput } from './db.js';
3
3
  import { CorsairPluginSchema, PluginEntityClients } from './orm.js';
4
- import { c as AllErrors, A as AuthTypes, a as AllProviders } from './constants-DnSLjl7e.js';
5
- import { A as AccountKeyManagerFor, P as PluginAuthConfig, I as IntegrationKeyManagerFor, H as HubConfig, f as HubConfigInput } from './types-BZ-KI4kd.js';
6
- import { M as ManagementOk, T as Tenant, C as CreateTenantInput, P as PluginInfo, a as ConnectionStatus, f as PermissionLookupInput, b as PermissionRecord, d as CreateConnectLinkInput, c as ConnectLink, R as ResolvedConnectLink, e as OAuthCallbackInput, O as OAuthCallbackResult } from './types-cJXSdmph.js';
4
+ import { c as AllErrors, A as AuthTypes, a as AllProviders } from './constants-CQtdZMk5.js';
5
+ import { A as AccountKeyManagerFor, P as PluginAuthConfig, I as IntegrationKeyManagerFor, H as HubConfig, f as HubConfigInput } from './types-DpJORHx2.js';
6
+ import { M as ManagementOk, T as Tenant, C as CreateTenantInput, P as PluginInfo, a as ConnectionStatus, f as PermissionLookupInput, b as PermissionRecord, d as CreateConnectLinkInput, c as ConnectLink, R as ResolvedConnectLink, e as OAuthCallbackInput, O as OAuthCallbackResult } from './types-CzXqyIs-.js';
7
7
  import { a as CorsairPermission } from './index-ggMa1Rj6.js';
8
8
 
9
9
  /**