corsair 0.1.76 → 0.1.78
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-3X6WVI5I.js +1 -0
- package/dist/chunk-IGGCNGU2.js +1 -0
- package/dist/chunk-J6HIPZAR.js +26 -0
- package/dist/{chunk-UPIMTWVI.js → chunk-KLJBBN2T.js} +3 -3
- package/dist/core.d.ts +8 -18
- package/dist/core.js +1 -1
- package/dist/db.js +1 -1
- package/dist/hub.d.ts +140 -0
- package/dist/hub.js +1 -0
- package/dist/{index-DSVPkmM-.d.ts → index-BHyMcpwm.d.ts} +389 -492
- package/dist/index-aVkEGoHG.d.ts +53 -0
- package/dist/index-mZfhN-6e.d.ts +55 -0
- package/dist/index.d.ts +17 -6
- package/dist/index.js +3 -3
- package/dist/oauth.d.ts +6 -1
- package/dist/oauth.js +1 -1
- package/dist/orm.js +1 -1
- package/dist/setup.d.ts +5 -3
- package/dist/setup.js +1 -1
- package/dist/tenant-links-UNTSO7K7.d.ts +43 -0
- package/dist/{index-BnkJ_TYy.d.ts → tenant-match-utils-DXoUP9o9.d.ts} +42 -2
- package/dist/tunnel.d.ts +35 -0
- package/dist/tunnel.js +1 -0
- package/dist/types-B1We8TTP.d.ts +249 -0
- package/package.json +12 -2
- package/dist/chunk-3USHGH6P.js +0 -1
- package/dist/chunk-FL4GOHVN.js +0 -1
- package/dist/chunk-LIZVHWQK.js +0 -26
- package/dist/chunk-OZHME3EO.js +0 -1
- package/dist/chunk-UBM25HVI.js +0 -1
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
type HubConnectSource = 'client' | 'server';
|
|
2
|
+
type HubOAuthMode = 'byo' | 'managed';
|
|
3
|
+
declare const DEFAULT_HUB_API_URL = "https://auth.corsair.dev";
|
|
4
|
+
type HubConfigInput = {
|
|
5
|
+
projectApiKey: string;
|
|
6
|
+
signingSecret: string;
|
|
7
|
+
deliveryUrl: string;
|
|
8
|
+
apiUrl?: string;
|
|
9
|
+
oauthCallbackUrl?: string;
|
|
10
|
+
};
|
|
11
|
+
type HubConfig = {
|
|
12
|
+
apiUrl: string;
|
|
13
|
+
projectApiKey: string;
|
|
14
|
+
signingSecret: string;
|
|
15
|
+
deliveryUrl: string;
|
|
16
|
+
oauthCallbackUrl?: string;
|
|
17
|
+
};
|
|
18
|
+
type HubConnectSessionInput = {
|
|
19
|
+
plugin: string;
|
|
20
|
+
tenantId: string;
|
|
21
|
+
/** Inferred from hub deliveryUrl when omitted (loopback → client, else server). */
|
|
22
|
+
source?: HubConnectSource;
|
|
23
|
+
providerName?: string;
|
|
24
|
+
oauthMode?: HubOAuthMode;
|
|
25
|
+
};
|
|
26
|
+
type HubConnectSessionResult = {
|
|
27
|
+
connectUrl: string;
|
|
28
|
+
token: string;
|
|
29
|
+
projectId: string;
|
|
30
|
+
expiresAt?: string;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
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 & {});
|
|
34
|
+
declare const BaseProviders: readonly ["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"];
|
|
35
|
+
declare const ProviderDisplayNames: {
|
|
36
|
+
readonly ahrefs: "Ahrefs";
|
|
37
|
+
readonly airtable: "Airtable";
|
|
38
|
+
readonly amplitude: "Amplitude";
|
|
39
|
+
readonly asana: "Asana";
|
|
40
|
+
readonly bitwarden: "Bitwarden";
|
|
41
|
+
readonly bluesky: "Bluesky";
|
|
42
|
+
readonly box: "Box";
|
|
43
|
+
readonly cal: "Cal";
|
|
44
|
+
readonly calendly: "Calendly";
|
|
45
|
+
readonly cloudflare: "Cloudflare";
|
|
46
|
+
readonly cursor: "Cursor";
|
|
47
|
+
readonly discord: "Discord";
|
|
48
|
+
readonly dodopayments: "Dodo Payments";
|
|
49
|
+
readonly dropbox: "Dropbox";
|
|
50
|
+
readonly exa: "Exa";
|
|
51
|
+
readonly figma: "Figma";
|
|
52
|
+
readonly firecrawl: "Firecrawl";
|
|
53
|
+
readonly fireflies: "Fireflies";
|
|
54
|
+
readonly github: "GitHub";
|
|
55
|
+
readonly gitlab: "GitLab";
|
|
56
|
+
readonly gmail: "Gmail";
|
|
57
|
+
readonly googlecalendar: "Google Calendar";
|
|
58
|
+
readonly googledrive: "Google Drive";
|
|
59
|
+
readonly googlesheets: "Google Sheets";
|
|
60
|
+
readonly grafana: "Grafana";
|
|
61
|
+
readonly hackernews: "Hacker News";
|
|
62
|
+
readonly hubspot: "HubSpot";
|
|
63
|
+
readonly intercom: "Intercom";
|
|
64
|
+
readonly jira: "Jira";
|
|
65
|
+
readonly linear: "Linear";
|
|
66
|
+
readonly monday: "Monday";
|
|
67
|
+
readonly notion: "Notion";
|
|
68
|
+
readonly onedrive: "OneDrive";
|
|
69
|
+
readonly openweathermap: "OpenWeatherMap";
|
|
70
|
+
readonly oura: "Oura";
|
|
71
|
+
readonly outlook: "Outlook";
|
|
72
|
+
readonly pagerduty: "PagerDuty";
|
|
73
|
+
readonly posthog: "PostHog";
|
|
74
|
+
readonly razorpay: "Razorpay";
|
|
75
|
+
readonly reddit: "Reddit";
|
|
76
|
+
readonly resend: "Resend";
|
|
77
|
+
readonly sentry: "Sentry";
|
|
78
|
+
readonly sharepoint: "SharePoint";
|
|
79
|
+
readonly slack: "Slack";
|
|
80
|
+
readonly spotify: "Spotify";
|
|
81
|
+
readonly strava: "Strava";
|
|
82
|
+
readonly stripe: "Stripe";
|
|
83
|
+
readonly tally: "Tally";
|
|
84
|
+
readonly tavily: "Tavily";
|
|
85
|
+
readonly teams: "Teams";
|
|
86
|
+
readonly telegram: "Telegram";
|
|
87
|
+
readonly todoist: "Todoist";
|
|
88
|
+
readonly trello: "Trello";
|
|
89
|
+
readonly twilio: "Twilio";
|
|
90
|
+
readonly twitter: "Twitter";
|
|
91
|
+
readonly twitterapiio: "Twitter API IO";
|
|
92
|
+
readonly typeform: "Typeform";
|
|
93
|
+
readonly vapi: "Vapi";
|
|
94
|
+
readonly xquik: "XQuik";
|
|
95
|
+
readonly youtube: "YouTube";
|
|
96
|
+
readonly zendesk: "Zendesk";
|
|
97
|
+
readonly zohomail: "Zoho Mail";
|
|
98
|
+
readonly zoom: "Zoom";
|
|
99
|
+
};
|
|
100
|
+
declare function formatProviderDisplayName(plugin: string): string;
|
|
101
|
+
type AllProviders = '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 & {});
|
|
102
|
+
type AuthTypes = 'oauth_2' | 'api_key' | 'bot_token' | 'managed';
|
|
103
|
+
type PickAuth<T extends AuthTypes> = T;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Utility type that converts a union type to an intersection type.
|
|
107
|
+
* This is useful for combining multiple plugin interfaces into a single client interface.
|
|
108
|
+
* @template U - The union type to convert
|
|
109
|
+
*/
|
|
110
|
+
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
|
|
111
|
+
/**
|
|
112
|
+
* Bivariance hack for function types to ensure proper type inference.
|
|
113
|
+
* This helps TypeScript correctly infer function parameters and return types.
|
|
114
|
+
* @template Args - The function arguments array
|
|
115
|
+
* @template R - The function return type
|
|
116
|
+
*/
|
|
117
|
+
type Bivariant<Args extends unknown[], R> = {
|
|
118
|
+
bivarianceHack(...args: Args): R;
|
|
119
|
+
}['bivarianceHack'];
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Defines the default fields for each auth type at the integration and account levels.
|
|
123
|
+
* These are the base fields that every key manager of that auth type will have.
|
|
124
|
+
* Plugins can extend these with additional fields via `authConfig`.
|
|
125
|
+
*/
|
|
126
|
+
declare const BASE_AUTH_FIELDS: {
|
|
127
|
+
readonly oauth_2: {
|
|
128
|
+
readonly integration: readonly ["client_id", "client_secret", "redirect_url"];
|
|
129
|
+
readonly account: readonly ["access_token", "refresh_token", "expires_at", "scope", "webhook_signature"];
|
|
130
|
+
};
|
|
131
|
+
readonly api_key: {
|
|
132
|
+
readonly integration: readonly [];
|
|
133
|
+
readonly account: readonly ["api_key", "webhook_signature"];
|
|
134
|
+
};
|
|
135
|
+
readonly bot_token: {
|
|
136
|
+
readonly integration: readonly [];
|
|
137
|
+
readonly account: readonly ["bot_token", "webhook_signature"];
|
|
138
|
+
};
|
|
139
|
+
readonly managed: {
|
|
140
|
+
readonly integration: readonly [];
|
|
141
|
+
readonly account: readonly ["access_token", "refresh_token", "expires_at", "scope", "webhook_signature"];
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
/**
|
|
145
|
+
* Type-level representation of the base auth field config.
|
|
146
|
+
*/
|
|
147
|
+
type BaseAuthFieldConfig = typeof BASE_AUTH_FIELDS;
|
|
148
|
+
/**
|
|
149
|
+
* Configuration that plugins can provide to extend the base auth fields.
|
|
150
|
+
* Each auth type can have additional integration-level and/or account-level fields.
|
|
151
|
+
*
|
|
152
|
+
* @example
|
|
153
|
+
* ```ts
|
|
154
|
+
* const gmailAuthConfig = {
|
|
155
|
+
* oauth_2: {
|
|
156
|
+
* integration: ["topic_id"] as const,
|
|
157
|
+
* account: ["history_id"] as const,
|
|
158
|
+
* },
|
|
159
|
+
* } as const satisfies PluginAuthConfig;
|
|
160
|
+
* ```
|
|
161
|
+
*/
|
|
162
|
+
type PluginAuthConfig = {
|
|
163
|
+
[K in AuthTypes]?: {
|
|
164
|
+
integration?: readonly string[];
|
|
165
|
+
account?: readonly string[];
|
|
166
|
+
};
|
|
167
|
+
};
|
|
168
|
+
/**
|
|
169
|
+
* Extracts extra integration fields from a plugin auth config for a given auth type.
|
|
170
|
+
*/
|
|
171
|
+
type ExtraIntegrationFields<Config extends PluginAuthConfig | undefined, T extends AuthTypes> = Config extends PluginAuthConfig ? T extends keyof Config ? NonNullable<Config[T]> extends {
|
|
172
|
+
integration: infer F extends readonly string[];
|
|
173
|
+
} ? F[number] : never : never : never;
|
|
174
|
+
/**
|
|
175
|
+
* Extracts extra account fields from a plugin auth config for a given auth type.
|
|
176
|
+
*/
|
|
177
|
+
type ExtraAccountFields<Config extends PluginAuthConfig | undefined, T extends AuthTypes> = Config extends PluginAuthConfig ? T extends keyof Config ? NonNullable<Config[T]> extends {
|
|
178
|
+
account: infer F extends readonly string[];
|
|
179
|
+
} ? F[number] : never : never : never;
|
|
180
|
+
/**
|
|
181
|
+
* All integration field names for a given auth type (base + extension).
|
|
182
|
+
*/
|
|
183
|
+
type IntegrationFieldNames<T extends AuthTypes, Config extends PluginAuthConfig | undefined = undefined> = BaseAuthFieldConfig[T]['integration'][number] | ExtraIntegrationFields<Config, T>;
|
|
184
|
+
/**
|
|
185
|
+
* All account field names for a given auth type (base + extension).
|
|
186
|
+
*/
|
|
187
|
+
type AccountFieldNames<T extends AuthTypes, Config extends PluginAuthConfig | undefined = undefined> = BaseAuthFieldConfig[T]['account'][number] | ExtraAccountFields<Config, T>;
|
|
188
|
+
/**
|
|
189
|
+
* Generates getter and setter types for a single field.
|
|
190
|
+
* e.g., "client_id" → { get_client_id: () => Promise<string | null>, set_client_id: (value: string | null) => Promise<void> }
|
|
191
|
+
*/
|
|
192
|
+
type FieldAccessors<Field extends string> = {
|
|
193
|
+
[K in `get_${Field}`]: () => Promise<string | null>;
|
|
194
|
+
} & {
|
|
195
|
+
[K in `set_${Field}`]: (value: string | null) => Promise<void>;
|
|
196
|
+
};
|
|
197
|
+
/**
|
|
198
|
+
* Generates getters and setters for all fields in a union.
|
|
199
|
+
* Uses UnionToIntersection to merge individual field accessor types.
|
|
200
|
+
*/
|
|
201
|
+
type AllFieldAccessors<Fields extends string> = [Fields] extends [never] ? {} : UnionToIntersection<FieldAccessors<Fields>>;
|
|
202
|
+
/**
|
|
203
|
+
* Base key manager interface with DEK operations.
|
|
204
|
+
* All key managers (integration and account) include these.
|
|
205
|
+
*/
|
|
206
|
+
type BaseKeyManager = {
|
|
207
|
+
/**
|
|
208
|
+
* Get the current DEK (decrypted using KEK)
|
|
209
|
+
*/
|
|
210
|
+
get_dek: () => Promise<string>;
|
|
211
|
+
/**
|
|
212
|
+
* Issue a new DEK and re-encrypt all associated secrets
|
|
213
|
+
* @returns The new DEK (for reference, not typically needed)
|
|
214
|
+
*/
|
|
215
|
+
issue_new_dek: () => Promise<string>;
|
|
216
|
+
};
|
|
217
|
+
/**
|
|
218
|
+
* Integration credentials returned by get_integration_credentials (OAuth2 only).
|
|
219
|
+
*/
|
|
220
|
+
type OAuth2IntegrationCredentials = {
|
|
221
|
+
client_id: string | null;
|
|
222
|
+
client_secret: string | null;
|
|
223
|
+
redirect_url: string | null;
|
|
224
|
+
};
|
|
225
|
+
/**
|
|
226
|
+
* Integration-level key manager for a given auth type.
|
|
227
|
+
* Includes base DEK operations + auto-generated getters/setters for all fields.
|
|
228
|
+
*
|
|
229
|
+
* @template T - The auth type
|
|
230
|
+
* @template Config - Optional plugin auth config for extension fields
|
|
231
|
+
*/
|
|
232
|
+
type IntegrationKeyManagerFor<T extends AuthTypes, Config extends PluginAuthConfig | undefined = undefined> = BaseKeyManager & AllFieldAccessors<IntegrationFieldNames<T, Config>>;
|
|
233
|
+
/**
|
|
234
|
+
* Account-level key manager for a given auth type.
|
|
235
|
+
* Includes base DEK operations + auto-generated getters/setters for all fields.
|
|
236
|
+
* OAuth2 account managers also include `get_integration_credentials`.
|
|
237
|
+
*
|
|
238
|
+
* @template T - The auth type
|
|
239
|
+
* @template Config - Optional plugin auth config for extension fields
|
|
240
|
+
*/
|
|
241
|
+
type AccountKeyManagerFor<T extends AuthTypes, Config extends PluginAuthConfig | undefined = undefined> = BaseKeyManager & AllFieldAccessors<AccountFieldNames<T, Config>> & (T extends 'oauth_2' ? {
|
|
242
|
+
/**
|
|
243
|
+
* Get the integration-level OAuth2 credentials (client_id, client_secret, redirect_url).
|
|
244
|
+
* Useful for token refresh flows that need access to both account and integration secrets.
|
|
245
|
+
*/
|
|
246
|
+
get_integration_credentials: () => Promise<OAuth2IntegrationCredentials>;
|
|
247
|
+
} : {});
|
|
248
|
+
|
|
249
|
+
export { type AuthTypes as A, type BaseAuthFieldConfig as B, DEFAULT_HUB_API_URL as D, type HubConfig as H, type IntegrationKeyManagerFor as I, type OAuth2IntegrationCredentials as O, type PluginAuthConfig as P, type UnionToIntersection as U, type AccountKeyManagerFor as a, type AccountFieldNames as b, type BaseKeyManager as c, type IntegrationFieldNames as d, BASE_AUTH_FIELDS as e, type AllProviders as f, BaseProviders as g, type PickAuth as h, formatProviderDisplayName as i, ProviderDisplayNames as j, type Bivariant as k, type HubConnectSource as l, type HubOAuthMode as m, type HubConfigInput as n, type HubConnectSessionInput as o, type HubConnectSessionResult as p, type AllErrors as q };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "corsair",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.78",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -42,6 +42,16 @@
|
|
|
42
42
|
"types": "./dist/oauth.d.ts",
|
|
43
43
|
"default": "./dist/oauth.js"
|
|
44
44
|
},
|
|
45
|
+
"./tunnel": {
|
|
46
|
+
"dev-source": "./tunnel.ts",
|
|
47
|
+
"types": "./dist/tunnel.d.ts",
|
|
48
|
+
"default": "./dist/tunnel.js"
|
|
49
|
+
},
|
|
50
|
+
"./hub": {
|
|
51
|
+
"dev-source": "./hub.ts",
|
|
52
|
+
"types": "./dist/hub.d.ts",
|
|
53
|
+
"default": "./dist/hub.js"
|
|
54
|
+
},
|
|
45
55
|
"./tests": {
|
|
46
56
|
"dev-source": "./tests.ts",
|
|
47
57
|
"types": "./dist/tests.d.ts",
|
|
@@ -83,7 +93,7 @@
|
|
|
83
93
|
"test:api": "jest --testPathPattern=api\\.test\\.ts",
|
|
84
94
|
"build": "tsup",
|
|
85
95
|
"build:watch": "tsup --watch",
|
|
86
|
-
"typecheck": "tsc --noEmit",
|
|
96
|
+
"typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.test.json",
|
|
87
97
|
"ind": "tsx index.ts"
|
|
88
98
|
}
|
|
89
99
|
}
|
package/dist/chunk-3USHGH6P.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{z as t}from"zod";var n=t.object({id:t.string(),created_at:t.coerce.date(),updated_at:t.coerce.date(),name:t.string(),config:t.record(t.string(),t.unknown()).nullable().transform(e=>e??{}),dek:t.string().nullish()}),i=t.object({id:t.string(),created_at:t.coerce.date(),updated_at:t.coerce.date(),tenant_id:t.string(),integration_id:t.string(),config:t.record(t.string(),t.unknown()).nullable().transform(e=>e??{}),dek:t.string().nullish()}),a=t.object({id:t.string(),created_at:t.coerce.date(),updated_at:t.coerce.date(),account_id:t.string(),entity_id:t.string(),entity_type:t.string(),version:t.string(),data:t.record(t.string(),t.unknown()).nullable().transform(e=>e??{})}),o=t.object({id:t.string(),created_at:t.coerce.date(),updated_at:t.coerce.date(),account_id:t.string(),event_type:t.string(),payload:t.record(t.string(),t.unknown()).nullable().transform(e=>e??{}),status:t.enum(["pending","processing","completed","failed"]).optional()}),s=t.object({id:t.string(),created_at:t.coerce.date(),updated_at:t.coerce.date(),token:t.string(),plugin:t.string(),endpoint:t.string(),args:t.string(),tenant_id:t.string(),status:t.enum(["pending","approved","executing","completed","denied","expired","failed"]).default("pending"),expires_at:t.string(),error:t.string().nullable().optional()});export{n as a,i as b,a as c,o as d,s as e};
|
package/dist/chunk-FL4GOHVN.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{a as i}from"./chunk-QAIKSQAD.js";import{Kysely as s,PostgresDialect as b,SqliteDialect as w}from"kysely";import{PostgresJSDialect as C}from"kysely-postgres-js";function D(e){return typeof e.query=="function"&&typeof e.connect=="function"}function d(e){let n=e;return typeof n.prepare=="function"&&typeof n.exec=="function"&&typeof n.close=="function"&&!("query"in e)}function S(e){return typeof e=="function"&&typeof e.begin=="function"&&typeof e.end=="function"}function u(e,n){return typeof e=="function"?e.bind(n):e}var g=114,m=3802;function q(e){if(typeof e!="object"||e===null||Buffer.isBuffer(e))return!1;if(Array.isArray(e))return!0;let n=Object.getPrototypeOf(e);return n===Object.prototype||n===null}function k(e){return e instanceof Date?e.toISOString():q(e)?JSON.stringify(e):e}function P(e){let n=e.options?.serializers;if(!n)return;let t=r=>r;n[g]=t,n[m]=t}function K(e){return new Proxy(e,{get(n,t,r){return t!=="reserve"?u(Reflect.get(n,t,r),n):async function(){let c=await n.reserve();return new Proxy(c,{get(o,a,f){return a!=="unsafe"?u(Reflect.get(o,a,f),o):function(y,l,p){return o.unsafe(y,l?.map(k),p)}}})}}})}function I(e){return typeof e.selectFrom=="function"}function J(e){if(I(e))return{db:e};if(d(e))return{db:new s({dialect:new w({database:e}),plugins:[new i]})};if(D(e))return{db:new s({dialect:new b({pool:e})})};if(S(e))return P(e),{db:new s({dialect:new C({postgres:K(e)})})};throw new Error("Unsupported database input. Expected a pg Pool, postgres.js Sql, better-sqlite3 Database, or a Kysely instance.")}export{J as a};
|
package/dist/chunk-LIZVHWQK.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import{a as Ke,b as Pe}from"./chunk-OZHME3EO.js";import{a as Ze}from"./chunk-FL4GOHVN.js";var L=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}};import{createCipheriv as Be,createDecipheriv as He,randomBytes as ie,scrypt as In}from"crypto";import{promisify as _n}from"util";var Le=_n(In),se="aes-256-gcm",je=12,ae=16,Dn=16,te=32;function j(){return ie(te).toString("base64")}async function W(e,n){let t=ie(Dn),r=await Le(n,t,te),o=ie(je),i=Be(se,r,o,{authTagLength:ae}),s=Buffer.concat([i.update(e,"utf8"),i.final()]),a=i.getAuthTag();return[t.toString("base64"),o.toString("base64"),a.toString("base64"),s.toString("base64")].join(":")}async function N(e,n){let[t,r,o,i]=e.split(":");if(!t||!r||!o||!i)throw new Error("Invalid encrypted DEK format");let s=Buffer.from(t,"base64"),a=Buffer.from(r,"base64"),d=Buffer.from(o,"base64"),u=Buffer.from(i,"base64"),c=await Le(n,s,te),p=He(se,c,a,{authTagLength:ae});return p.setAuthTag(d),Buffer.concat([p.update(u),p.final()]).toString("utf8")}function Te(e,n){let t=Buffer.from(n,"base64"),r=ie(je),o=Be(se,t,r,{authTagLength:ae}),i=Buffer.concat([o.update(e,"utf8"),o.final()]),s=o.getAuthTag();return[r.toString("base64"),s.toString("base64"),i.toString("base64")].join(":")}function xe(e,n){let[t,r,o]=e.split(":");if(!t||!r||!o)throw new Error("Invalid encrypted data format");let i=Buffer.from(n,"base64"),s=Buffer.from(t,"base64"),a=Buffer.from(r,"base64"),d=Buffer.from(o,"base64"),u=He(se,i,s,{authTagLength:ae});return u.setAuthTag(a),Buffer.concat([u.update(d),u.final()]).toString("utf8")}function Q(e,n){let t={};for(let[r,o]of Object.entries(e))t[r]=Te(o,n);return t}function U(e,n){let t={};for(let[r,o]of Object.entries(e))t[r]=xe(o,n);return t}function re(e,n,t){let r=U(e,n);return Q(r,t)}function ce(e,n){let t=[];e||t.push("database"),n||t.push("kek");let r={};return new Proxy(r,{get(o,i){let s=t.length>1;throw new Error(`corsair.keys.${String(i)}: Cannot access keys because ${t.join(" and ")} ${s?"are":"is"} not configured. Provide both 'database' and 'kek' in createCorsair() to enable key management.
|
|
2
|
-
|
|
3
|
-
To generate a KEK, run: openssl rand -base64 ${te}`)}})}var q={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"]}};function We(e,n,t){let r={};for(let o of t)r[`get_${o}`]=async()=>(await e())[o]??null,r[`set_${o}`]=async i=>{let s=[null,void 0,""].includes(i)?null:i;await n({[o]:s})};return r}var Ae=e=>{if(!e)return{};if(typeof e=="string")try{return JSON.parse(e)}catch{return{}}return e};function Z(e){let{authType:n,integrationName:t,kek:r,database:o,extraIntegrationFields:i=[]}=e,s=[...q[n].integration,...i],a=null,d={kek:r,integrationName:t,getIntegration:async()=>{if(a)return a;let l=await o.db.selectFrom("corsair_integrations").selectAll().where("name","=",t).executeTakeFirst();if(!l)throw new Error(`Integration "${t}" not found. Make sure to create the integration first.`);return a={id:l.id,config:Ae(l.config),dek:l.dek??null},a},updateIntegration:async l=>{let m=await d.getIntegration();await o.db.updateTable("corsair_integrations").set({...l.config!==void 0?{config:l.config}:{},...l.dek!==void 0?{dek:l.dek}:{},updated_at:new Date}).where("id","=",m.id).execute(),a=null}},u=null,c=async()=>{if(u)return u;let l=await d.getIntegration();if(!l.dek)throw new Error(`No DEK found for integration "${t}". Initialize the integration first.`);return u=await N(l.dek,r),u},p=async()=>{let l=await d.getIntegration(),m=await c(),b=l.config;return!b||Object.keys(b).length===0?{}:U(b,m)};return{get_dek:c,issue_new_dek:async()=>{let l=await d.getIntegration(),m=j(),b={};if(l.dek){let w=await N(l.dek,r),T=l.config;T&&Object.keys(T).length>0&&(b=re(T,w,m))}let k=await W(m,r);return await d.updateIntegration({config:b,dek:k}),u=m,m},...We(p,async l=>{let m=await c(),b;try{b=await p()}catch(T){console.error(`[corsair] Failed to decrypt config for integration "${t}", starting fresh:`,T),b={}}let k={...b};for(let[T,y]of Object.entries(l))y===null?delete k[T]:k[T]=y;let w=Q(k,m);await d.updateIntegration({config:w})},s)}}function de(e){let{authType:n,integrationName:t,tenantId:r,kek:o,database:i,extraAccountFields:s=[]}=e,a=[...q[n].account,...s],d=null,u=null,c=async()=>{if(u)return u;let y=await i.db.selectFrom("corsair_integrations").selectAll().where("name","=",t).executeTakeFirst();if(!y)throw new Error(`Integration "${t}" not found. Make sure to create the integration first.`);return u={id:y.id,config:Ae(y.config),dek:y.dek??null},u},p={kek:o,integrationName:t,tenantId:r,getIntegration:c,getAccount:async()=>{if(d)return d;let y=await c(),h=await i.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",r).where("integration_id","=",y.id).executeTakeFirst();if(!h)throw new Error(`Account not found for tenant "${r}" and integration "${t}". Make sure to create the account first.`);return d={id:h.id,config:Ae(h.config),dek:h.dek??null},d},updateAccount:async y=>{let h=await p.getAccount();await i.db.updateTable("corsair_accounts").set({...y.config!==void 0?{config:y.config}:{},...y.dek!==void 0?{dek:y.dek}:{},updated_at:new Date}).where("id","=",h.id).execute(),d=null}},f=null,g=null,l=async()=>{if(f)return f;let y=await p.getAccount();if(!y.dek)throw new Error(`No DEK found for account (tenant: "${r}", integration: "${t}"). Initialize the account first.`);return f=await N(y.dek,o),f},m=async()=>{if(g)return g;let y=await p.getIntegration();if(!y.dek)throw new Error(`No DEK found for integration "${t}". Initialize the integration first.`);return g=await N(y.dek,o),g},b=async()=>{let y=await p.getAccount(),h=await l(),P=y.config;return!P||Object.keys(P).length===0?{}:U(P,h)},k=async()=>{let y=await p.getIntegration(),h=await m(),P=y.config;return!P||Object.keys(P).length===0?{}:U(P,h)},T={get_dek:l,issue_new_dek:async()=>{let y=await p.getAccount(),h=j(),P={};if(y.dek){let _=await N(y.dek,o),C=y.config;C&&Object.keys(C).length>0&&(P=re(C,_,h))}let A=await W(h,o);return await p.updateAccount({config:P,dek:A}),f=h,h},...We(b,async y=>{let h=await l(),P;try{P=await b()}catch(C){console.error(`[corsair] Failed to decrypt config for account (tenant: "${r}", integration: "${t}"), starting fresh:`,C),P={}}let A={...P};for(let[C,M]of Object.entries(y))M===null?delete A[C]:A[C]=M;let _=Q(A,h);await p.updateAccount({config:_})},a)};return n==="oauth_2"&&(T.get_integration_credentials=async()=>{let y=await k();return{client_id:y.client_id||null,client_secret:y.client_secret||null,redirect_url:y.redirect_url??null}}),T}async function Ue(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=j(),i=await W(o,t);return await e.db.updateTable("corsair_integrations").set({dek:i,updated_at:new Date}).where("id","=",r.id).execute(),o}async function qe(e,n,t,r){let o=await e.db.selectFrom("corsair_integrations").selectAll().where("name","=",n).executeTakeFirst();if(!o)throw new Error(`Integration "${n}" not found.`);let i=await e.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",t).where("integration_id","=",o.id).executeTakeFirst();if(!i)throw new Error(`Account not found for tenant "${t}" and integration "${n}".`);let s=j(),a=await W(s,r);return await e.db.updateTable("corsair_accounts").set({dek:a,updated_at:new Date}).where("id","=",i.id).execute(),s}import*as oe from"crypto";function ze(e,n){return Buffer.from(JSON.stringify({plugin:e,tenantId:n,iat:Date.now()})).toString("base64url")}function vn(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 Ge(e,n){let t=oe.createHmac("sha256",n).update(e).digest("base64url");return`${e}.${t}`}var Sn=600*1e3;function Je(e,n){let t=e.lastIndexOf(".");if(t===-1)return null;let r=e.slice(0,t),o=e.slice(t+1),i=oe.createHmac("sha256",n).update(r).digest("base64url"),s=Buffer.from(o,"base64url"),a=Buffer.from(i,"base64url");return s.length!==a.length||!oe.timingSafeEqual(s,a)?null:vn(r,{maxAgeMs:Sn})}var On=async(e,n)=>(console.error(`[corsair:${n.pluginId}:${n.operation}]`,{error:e.message,input:n.input}),{maxRetries:0});async function Ve(e,n,t,r,o){let i={pluginId:n,operation:t,input:r,originalError:e},s=Object.keys(o).find(u=>o[u]?.match(e,i));return await(o[s||"DEFAULT"]?.handler||On)(e,i)}import{randomBytes as Mn}from"crypto";import{v4 as Fn}from"uuid";var $n={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 Nn(e,n,t){return t!==void 0?t:$n[n][e]}function Qe(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 Xe(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 Ye(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 en(e){let n=Nn(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}'.`,`
|
|
4
|
-
Action: ${r}`,`
|
|
5
|
-
To allow this, update the permission mode or add an override in your corsair config.`),{result:"blocked",reason:"policy"};let o=JSON.stringify(e.args),i=new Date().toISOString(),s=e.tenantId??"default",a=await e.db.db.selectFrom("corsair_permissions").selectAll().where("plugin","=",e.pluginId).where("endpoint","=",e.endpointPath).where("args","=",o).where("tenant_id","=",s).where("expires_at",">",i).where("status","in",["pending","approved","executing"]).orderBy("created_at","desc").limit(1).executeTakeFirst();if(a){if(a.status==="approved"){let l=e.db,m=a.id;return{result:"allow",onComplete:async()=>{await l.db.updateTable("corsair_permissions").set({status:"completed",updated_at:new Date}).where("id","=",m).execute()}}}return a.status==="executing"?{result:"allow"}:(console.log(`[corsair/${e.pluginId}] '${e.endpointPath}' blocked \u2014 approval already pending.`,`
|
|
6
|
-
Action: ${r}`,`
|
|
7
|
-
Permission ID: ${a.id}`,`
|
|
8
|
-
Use the token to approve or deny this request.`),(typeof e.approvalMode=="function"?e.approvalMode():e.approvalMode)==="synchronous"?Ye(e.db,a.id,e.timeoutMs??600*1e3):{result:"blocked",reason:"pending",id:a.id,token:a.token})}let d=Fn(),u=Mn(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:d,created_at:new Date,updated_at:new Date,token:u,plugin:e.pluginId,endpoint:e.endpointPath,args:o,tenant_id:s,status:"pending",expires_at:p}).execute(),console.log(`[corsair/${e.pluginId}] '${e.endpointPath}' blocked \u2014 approval required.`,`
|
|
9
|
-
Action: ${r}`,`
|
|
10
|
-
Permission ID: ${d}`,`
|
|
11
|
-
Permission token: ${u}`,`
|
|
12
|
-
Expires at: ${p}`,`
|
|
13
|
-
Use the token to approve or deny this request.`),(typeof e.approvalMode=="function"?e.approvalMode():e.approvalMode)==="synchronous"?Ye(e.db,d,c):{result:"blocked",reason:"pending",id:d,token:u}}function Zn(e){return typeof e=="function"}function Kn(e,n,t){let r=Ge(ze(e,n.tenantId??t??"default"),n.kek),o=new URL(n.baseUrl);o.searchParams.set("state",r);let i=o.toString(),s=n.onAuthMissing?n.onAuthMissing({plugin:e,connectUrl:i,state:r}):`[auth-missing:${e}] Authentication required. Direct the user to connect their account: ${i}`;return new Error(s)}function Re({endpoints:e,hooks:n,ctx:t,tree:r,pluginId:o,errorHandlers:i,currentPath:s=[],keyBuilder:a,permissionsConfig:d,endpointMeta:u,database:c,approvalConfig:p,tenantId:f,connectConfig:g}){for(let[l,m]of Object.entries(e)){let b=n?.[l];if(Zn(m)){let k=b,w=[...s,l].join("."),T=async(y={})=>{let h;if(d){let R=u?.[w],{result:Y,reason:O,onComplete:ne,token:F,id:H}=await en({pluginId:o,endpointPath:w,args:y,mode:d.mode,override:d.overrides?.[w],riskLevel:R?.riskLevel??"write",meta:R,db:c,timeoutMs:p?Qe(p.timeout):void 0,tenantId:f,approvalMode:p?.mode});if(Y==="blocked"){let x;throw O==="denied"?x=`Action '${w}' was denied by the user. Await further instructions before proceeding.`:O==="policy"?x=`Action '${w}' is blocked by the permission policy. Update the corsair config to allow it.`:O==="timeout"?x=`Action '${w}' timed out waiting for approval.`:p?.formatAsyncMessage&&F&&H?x=p.formatAsyncMessage({token:F,id:H,plugin:o,endpoint:w,args:y}):x=`Action '${w}' requires user approval before it can run.`,new Error(x)}h=ne}let P=async(R,Y,O)=>{try{return await m(Y,O)}catch(ne){if(ne instanceof Error){let F=await Ve(ne,o,w,typeof O=="object"&&O!==null?O:{args:O},i);if(R<(F.maxRetries||0)){let H=R+1;console.log(`Retrying (${H} / ${F.maxRetries})...`);let x;if(F.headersRetryAfterMs)x=F.headersRetryAfterMs;else switch(F.retryStrategy){case"exponential_backoff":x=Math.pow(2,H-1)*1e3;break;case"exponential_backoff_jitter":let Ce=Math.pow(2,H-1)*1e3,En=(Math.random()-.5)*1e3;x=Math.max(0,Ce+En);break;case"linear_1s":x=1e3;break;case"linear_2s":x=2e3;break;case"linear_3s":x=3e3;break;case"linear_4s":x=4e3;break;default:x=1e3;break}await new Promise(Ce=>setTimeout(Ce,x)),await P(H,Y,O),console.log(`[corsair:${o}:${w}] Retry strategy:`,F)}}throw ne}},A;try{A=a?await a(t,"endpoint"):void 0}catch(R){throw g?.oauthConfig&&g.kek&&R instanceof L&&R.authType==="oauth_2"?Kn(o,g,f):R}if(!k?.before&&!k?.after){let R=await P(0,{...t,key:A},y);return await h?.(),R}let _={...t,key:A},C=k.before?await k.before(_,y):{ctx:_,args:y,continue:!0,passToAfter:void 0};if(C.continue===!1)return;let M=await P(0,C.ctx,C.args);return await k.after?.(C.ctx,M,C.passToAfter),await h?.(),M};r[l]=T}else if(m&&typeof m=="object"){let k={};Re({endpoints:m,hooks:b,ctx:t,tree:k,pluginId:o,errorHandlers:i,currentPath:[...s,l],keyBuilder:a,permissionsConfig:d,endpointMeta:u,database:c,approvalConfig:p,tenantId:f,connectConfig:g}),r[l]=k}}}function Bn(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function Ee({webhooks:e,hooks:n,ctx:t,webhooksTree:r,keyBuilder:o}){for(let[i,s]of Object.entries(e)){let a=n?.[i];if(Bn(s)){let d=a,u=async c=>{let p=(g,l)=>s.handler(g,l),f=o?await o(t,"webhook"):void 0;return!d?.before&&!d?.after?p({...t,key:f},c):(async()=>{let g={...t,key:f},l=d.before?await d.before(g,c):{ctx:g,args:c,continue:!0,passToAfter:void 0};if(l.continue===!1)return;let m=await p(l.ctx,l.args);return m?.success===!0&&await d.after?.(l.ctx,m,l.passToAfter),m})()};r[i]={match:s.match,handler:u}}else if(s&&typeof s=="object"){let d={};Ee({webhooks:s,hooks:a,ctx:t,webhooksTree:d,keyBuilder:o}),r[i]=d}}}function Hn(e,n,t){let r=null;return async()=>{if(r)return r;if(!e)throw new Error("Database not configured");let o=await e.db.selectFrom("corsair_integrations").selectAll().where("name","=",n).executeTakeFirst();if(!o)throw new Error(`Integration "${n}" not found. Make sure to create the integration first.`);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}". Make sure to create the account first.`);return r=i.id,r}}function Ln(e,n,t,r,o){return e?Pe(e.db,n,t,r,o):{findByEntityId: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 Ie(e,n){let{database:t,tenantId:r,kek:o,rootErrorHandlers:i,approvalConfig:s,connectConfig:a}=n,d={},u={};for(let c of e)d[c.id]={},u[c.id]={};for(let c of e){let p=c.schema,f=r??"default",g=Hn(t,c.id,f);if(p?.entities){let C={};for(let[M,R]of Object.entries(p.entities)){let Y=t?Pe(t.db,g,M,p.version,R):Ln(void 0,g,M,p.version,R);C[M]=Y}u[c.id].db=C,d[c.id].db=C}let l=c.options,m=c.authConfig,b;if(t&&o&&l?.authType){let C=m?.[l.authType]?.account??[];b=de({authType:l.authType,integrationName:c.id,tenantId:f,kek:o,database:t,extraAccountFields:C}),d[c.id].keys=b}let k={database:t,db:u[c.id]?.db??{},$getAccountId:g,...c.options?{options:c.options}:{},...b?{keys:b,authType:l?.authType}:{},...r?{tenantId:r}:{}},w=c.endpoints??{},T=c.hooks,y={...i,...c.errorHandlers},h={},P=c.options?.permissions;Re({endpoints:w,hooks:T,ctx:k,tree:h,pluginId:c.id,errorHandlers:y,currentPath:[],keyBuilder:c.keyBuilder,permissionsConfig:P,endpointMeta:c.endpointMeta,database:t,approvalConfig:s,tenantId:r,connectConfig:a?{...a,oauthConfig:c.oauthConfig,kek:o,tenantId:f}:void 0}),Object.keys(h).length>0&&(d[c.id].api=h),k.endpoints=h;let A=c.webhooks??{},_=c.webhookHooks;if(Object.keys(A).length>0){let C={};Ee({webhooks:A,hooks:_,ctx:k,webhooksTree:C,keyBuilder:c.keyBuilder}),d[c.id].webhooks=C,c.pluginWebhookMatcher&&(d[c.id].pluginWebhookMatcher=c.pluginWebhookMatcher)}}return d}function nn(e,n,t){let r={};for(let o of e){let i=o.options,s=o.authConfig;if(i?.authType){let a=s?.[i.authType]?.integration??[],d=Z({authType:i.authType,integrationName:o.id,kek:t,database:n,extraIntegrationFields:a});r[o.id]=d}}return r}var z=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 E(e,n){return new Response(JSON.stringify(n),{status:e,headers:{"content-type":"application/json"}})}function tn(e){let n={error:e.code,message:e.message,...e.extra};return E(e.status,n)}function K(e){return new z(404,"not_found",e)}function _e(e,n={}){return new z(400,"bad_request",e,n)}function jn(e,n){let t=e.plugins.find(r=>r.id===n);if(!t)throw K(`Plugin '${n}' not found`);return t}async function rn(e,n){let t=e.options?.authType;if(!t||!n.database||!n.kek)return{configured:!1,missingFields:[]};let r=Z({authType:t,integrationName:e.id,kek:n.kek,database:n.database}),o=q[t].integration,i=r,s;try{s=await Promise.all(o.map(u=>i[`get_${u}`]()))}catch{s=o.map(()=>null)}let a=o.filter((u,c)=>s[c]==null),d;return t==="oauth_2"?d=!a.includes("client_id")&&!a.includes("client_secret"):d=a.length===0,{configured:d,missingFields:a}}async function on(e,n){let t=e.options?.authType??null,r=e.oauthConfig,{configured:o,missingFields:i}=await rn(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 ue(){return{ok:!0}}async function le(e){return Promise.all(e.plugins.map(n=>on(n,e)))}async function pe(e,n){let t=jn(e,n);return on(t,e)}async function sn(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 an(e,n){let t=await sn(e,n),r=t.filter(o=>o.hasCredentials).map(o=>o.integrationName);return{id:n,accounts:t,connectedPlugins:r}}async function ge(e){let n=new Map;if(n.set("default",{id:"default",accounts:[],connectedPlugins:[]}),e.database){let t=await e.database.db.selectFrom("corsair_accounts as a").innerJoin("corsair_integrations as i","i.id","a.integration_id").select(["a.tenant_id","a.dek as dek","i.name as integrationName"]).execute();for(let r of t){let o=r.tenant_id;if(!o)continue;let i=n.get(o);i||(i={id:o,accounts:[],connectedPlugins:[]},n.set(o,i));let s=!!r.dek;i.accounts.push({integrationName:r.integrationName,hasCredentials:s}),s&&i.connectedPlugins.push(r.integrationName)}}return[...n.values()]}async function fe(e,n){if(!n)throw _e("Tenant id must be a non-empty string");return an(e,n)}async function ye(e,n){let t=n?.id?.trim();if(!t)throw _e("Tenant id is required",{missingFields:["id"]});return an(e,t)}async function me(e,n){let t=n?.trim()||"default",r={},o=e.database?await sn(e,t):[],i=new Map(o.map(s=>[s.integrationName,s]));for(let s of e.plugins){if(!(await rn(s,e)).configured){r[s.id]="missing_credentials";continue}let d=i.get(s.id),u;d&&d.hasCredentials?u="connected":u="not_connected",r[s.id]=u}return r}async function he(e,n){if(!e.database)throw K(`Permission '${n}' not found`);let t=await e.database.db.selectFrom("corsair_permissions").selectAll().where("id","=",n).executeTakeFirst();if(!t)throw K(`Permission '${n}' not found`);return t}async function ke(e,n){if(!e.database)throw K("Permission not found");let t=await e.database.db.selectFrom("corsair_permissions").selectAll().where("token","=",n).executeTakeFirst();if(!t)throw K("Permission not found");return t}var cn=[{method:"GET",pattern:"/ok",handler:async()=>E(200,ue())},{method:"GET",pattern:"/tenants",handler:async({internal:e})=>E(200,await ge(e))},{method:"POST",pattern:"/tenants",handler:async({internal:e,body:n})=>E(201,await ye(e,n))},{method:"GET",pattern:"/tenants/:id",handler:async({internal:e,params:n})=>E(200,await fe(e,n.id))},{method:"GET",pattern:"/plugins",handler:async({internal:e})=>E(200,await le(e))},{method:"GET",pattern:"/plugins/:id",handler:async({internal:e,params:n})=>E(200,await pe(e,n.id))},{method:"GET",pattern:"/connection-status",handler:async({internal:e,query:n})=>E(200,await me(e,n.tenantId))},{method:"GET",pattern:"/permissions/:id",handler:async({internal:e,params:n})=>E(200,await he(e,n.id))},{method:"POST",pattern:"/permissions/lookup-by-token",handler:async({internal:e,body:n})=>{let t=n?.token?.trim();return t?E(200,await ke(e,t)):E(400,{error:"bad_request",message:"token is required",missingFields:["token"]})}}];(()=>{let e=new Set;for(let n of cn){let t=`${n.method} ${n.pattern}`;if(e.has(t))throw new Error(`Duplicate management route registered: ${t}`);e.add(t)}})();function Wn(e,n){let t=e.split("/").filter(Boolean),r=n.split("/").filter(Boolean);if(t.length!==r.length)return null;let o={};for(let i=0;i<t.length;i++){let s=t[i],a=r[i];if(s.startsWith(":"))o[s.slice(1)]=decodeURIComponent(a);else if(s!==a)return null}return o}function Un(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}function qn(e){let n=e[J];if(!n)throw new Error("managementHandler: invalid corsair instance (missing internal config)");return n}async function zn(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 z(400,"invalid_json","Request body is not valid JSON")}}var Gn="/api/corsair";function G(e,n={}){let t=n.basePath??Gn,r=qn(e);return async o=>{try{let i=new URL(o.url),s=Un(i.pathname,t),a=o.method.toUpperCase(),d=Object.fromEntries(i.searchParams);for(let u of cn){if(u.method!==a)continue;let c=Wn(u.pattern,s);if(!c)continue;let p=await zn(o);return await u.handler({internal:r,req:o,params:c,query:d,body:p})}throw K(`No route for ${a} ${s}`)}catch(i){if(n.onError){let a=await n.onError(i,o);if(a)return a}if(i instanceof z)return tn(i);let s=i instanceof Error?i.message:"Internal server error";return E(500,{error:"internal_error",message:s})}}}function Jn(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[d,u]of Object.entries(e.headers))if(u!=null)if(Array.isArray(u))for(let c of u)i.append(d,c);else i.set(d,u);let s=e.method!=="GET"&&e.method!=="HEAD",a={method:e.method,headers:i};return s&&e.body!==void 0&&(a.body=typeof e.body=="string"?e.body:JSON.stringify(e.body),i.has("content-type")||i.set("content-type","application/json")),new Request(o,a)}async function Vn(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 dn(e,n){let t=G(e,n);return async(r,o,i)=>{try{let s=await t(Jn(r));await Vn(o,s)}catch(s){i(s)}}}function un(e,n){let t=G(e,n);return r=>t(r.req.raw)}function ln(e,n){let t=G(e,n);return{GET:t,POST:t}}function pn(e){return{ok:ue,tenants:{list:()=>ge(e),create:n=>ye(e,n),get:n=>fe(e,n)},plugins:{list:()=>le(e),get:n=>pe(e,n)},connectionStatus:{get:n=>me(e,n?.tenantId)},permissions:{get:n=>he(e,n),getByToken:n=>ke(e,n)}}}async function gn(e,n,t,r,o="pending"){if(!e)return null;try{let i=Ke(),s=new Date;return await e.db.insertInto("corsair_events").values({id:i,created_at:s,updated_at:s,account_id:n,event_type:t,payload:r,status:o}).execute(),i}catch(i){return console.warn("Failed to log event:",i),null}}async function Yn(e,n,t,r="pending"){try{let o=await e.$getAccountId();return gn(e.database,o,n,t,r)}catch(o){return console.warn("Failed to log event:",o),null}}import*as fn from"https";import*as yn from"querystring";function mn(e,n,t,r,o){let i=new URL(r.tokenUrl),s=r.tokenAuthMethod==="basic";return new Promise((a,d)=>{let u={code:e.trim(),redirect_uri:o,grant_type:"authorization_code"};s||(u.client_id=n,u.client_secret=t);let c=yn.stringify(u),p={"Content-Type":"application/x-www-form-urlencoded","Content-Length":Buffer.byteLength(c).toString()};s&&(p.Authorization=`Basic ${Buffer.from(`${n}:${t}`).toString("base64")}`);let f=fn.request({hostname:i.hostname,...i.port?{port:Number(i.port)}:{},path:i.pathname+i.search,method:"POST",headers:p},g=>{let l="";g.on("data",m=>{l+=m}),g.on("end",()=>{if(g.statusCode!==200){d(new Error(`Token exchange failed (${g.statusCode}): ${l}`));return}try{a(JSON.parse(l))}catch{d(new Error(`Token endpoint returned non-JSON response: ${l}`))}})});f.on("error",g=>d(new Error(`Request failed: ${g.message}`))),f.write(c),f.end()})}import*as hn from"querystring";function Qn(e){let n=e[J];if(!n)throw new Error("Invalid corsair instance");return n}function Xn(e,n){let t=e.plugins.find(r=>r.id===n);if(!t)throw new Error(`Plugin '${n}' not found`);return t}function et(e){let n=e.oauthConfig;if(!n)throw new Error(`Plugin '${e.id}' has no oauthConfig`);return n}async function nt(e,n){let t=Qn(e);if(!t.database)throw new Error("No database configured on corsair instance");let r=t.connect?.redirectUri;if(!r)throw new Error("No redirectUri configured. Set connect.redirectUri in createCorsair().");let o=Je(n,t.kek);if(!o)throw new Error("Invalid or tampered state parameter");let{plugin:i,tenantId:s}=o,a=Xn(t,i),d=et(a),c=await Z({authType:"oauth_2",integrationName:i,kek:t.kek,database:t.database}).get_client_id();if(!c)throw new Error(`client_id not configured for '${i}'`);let p={...d.authParams,client_id:c,redirect_uri:r,response_type:"code",scope:d.scopes.join(" "),state:n},f=`${d.authUrl}?${hn.stringify(p)}`;return{plugin:i,tenantId:s,providerName:d.providerName,oauthUrl:f,state:n}}var kn=["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","twitter","twitterapiio","typeform","vapi","xquik","youtube","zendesk","zohomail","zoom"];var bn=" ";function v(e){let n=e;return n._def??n.def??{}}function S(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 D(e){return e.innerType??e.schema??e.out??e.in}function Cn(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 D(e)}}function Pn(e){let n=e.type;return e.element??(typeof n=="string"?void 0:n)}function we(e,n){let t=n.shape??e.shape;return typeof t=="function"?t():t}function X(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 Tn(e,n){return e.description??n.description}function tt(e){let n=e;for(;n;){let t=v(n),r=Tn(n,t);if(r)return r;let o=S(t);if(Me(o)||o==="ZodPipe"||o==="ZodEffects"||o==="ZodTransform"){n=Cn(t,o);continue}break}}function Me(e){return e==="ZodOptional"||e==="ZodNullable"||e==="ZodDefault"||e==="ZodCatch"}function I(e){let n=v(e),t=S(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??X(n)[0]??"unknown");case"ZodEnum":return X(n).map(r=>String(r)).join(" | ");case"ZodOptional":{let r=D(n);return r?I(r):"unknown"}case"ZodNullable":{let r=D(n);return`${r?I(r):"unknown"} | null`}case"ZodDefault":case"ZodCatch":{let r=D(n);return r?I(r):"unknown"}case"ZodArray":{let r=Pn(n);if(!r)return"unknown[]";let o=v(r),i=S(o)==="ZodUnion",s=I(r);return`${i?`(${s})`:s}[]`}case"ZodRecord":return"{}";case"ZodObject":{let r=we(e,n),o=Object.entries(r);return o.length===0?"{}":`{ ${o.map(([s,a])=>{let d=S(v(a));return`${d==="ZodOptional"||d==="ZodNullable"?s+"?":s}: ${I(a)}`}).join(", ")} }`}case"ZodUnion":return X(n).map(r=>I(r)).join(" | ");case"ZodIntersection":return`${I(n.left)} & ${I(n.right)}`;case"ZodPipe":case"ZodTransform":case"ZodEffects":{let r=Cn(n,t);return r?I(r):"unknown"}default:return(t??"unknown").replace("Zod","").toLowerCase()}}function $(e){let n=v(e),t=S(n),r=Tn(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??X(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=X(n).map(i=>String(i));return{kind:"string",optional:!1,description:r,enum:o}}case"ZodOptional":{let o=D(n),i=o?$(o):{kind:"unknown",optional:!1};return{...i,optional:!0,description:r??i.description}}case"ZodNullable":{let o=D(n),i=o?$(o):{kind:"unknown",optional:!1};return{...i,optional:!0,description:r??i.description}}case"ZodDefault":case"ZodCatch":{let o=D(n);return o?{...$(o),description:r}:{kind:"unknown",optional:!1,description:r}}case"ZodArray":{let o=Pn(n);return{kind:"array",optional:!1,description:r,items:o?$(o):{kind:"unknown",optional:!1}}}case"ZodObject":{let o=we(e,n),i={};for(let[s,a]of Object.entries(o))i[s]=$(a);return{kind:"object",optional:!1,description:r,fields:i}}case"ZodRecord":return{kind:"unknown",optional:!1,description:r};case"ZodUnion":{let o=X(n);for(let i of o){let s=v(i);if(S(s)==="ZodObject")return{...$(i),description:r}}return{kind:"unknown",optional:!1,description:r}}case"ZodIntersection":case"ZodPipe":case"ZodTransform":case"ZodEffects":{let o=D(n);return o?{...$(o),description:r}:{kind:"unknown",optional:!1,description:r}}default:return{kind:"unknown",optional:!1,description:r}}}function Cr(e,n){let t=n.toLowerCase(),r=t.indexOf(".");if(r===-1)return null;let o=t.slice(0,r),i=t.slice(r+1),s=e.find(c=>c.id===o);if(!s)return null;let a=i;a.startsWith("api.")&&(a=a.slice(4));let d=B(s.endpointMeta,a),u=B(s.endpointSchemas,a);return!d&&!u?null:{input:u?.input?$(u.input):null,output:u?.output?$(u.output):null,description:d?.description}}var Fe=["equals","contains","startsWith","endsWith","in"],rt=["equals","gt","gte","lt","lte","in"],ot=["equals"],it=["equals","before","after","between"];function xn(e){let n=v(e);switch(S(n)){case"ZodOptional":case"ZodNullable":case"ZodDefault":case"ZodCatch":{let r=D(n);return r?xn(r):null}case"ZodString":return"string";case"ZodNumber":return"number";case"ZodBoolean":return"boolean";case"ZodDate":return"date";default:return null}}function $e(e){let n=v(e),t=S(n);if(Me(t)){let i=D(n);return i?$e(i):{}}if(t!=="ZodObject")return{};let r=we(e,n),o={};for(let[i,s]of Object.entries(r)){let a=xn(s);a==="string"?o[i]={type:"string",operators:Fe}:a==="number"?o[i]={type:"number",operators:rt}:a==="boolean"?o[i]={type:"boolean",operators:ot}:a==="date"&&(o[i]={type:"date",operators:it})}return o}function An(e,n){for(let[t,r]of Object.entries(e))if(t.toLowerCase()===n)return[t,r]}function ve(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"&&ve(o,i,t)}}function Se(e){return e!==null&&typeof e=="object"&&"match"in e&&"handler"in e&&typeof e.match=="function"&&typeof e.handler=="function"}function Oe(e,n,t){for(let[r,o]of Object.entries(e)){let i=[...n,r];Se(o)?t.push(i.join(".")):o!==null&&typeof o=="object"&&Oe(o,i,t)}}function Ne(e,n){if(n.length===0)return null;let[t,...r]=n,o=Object.entries(e).find(([a])=>a.toLowerCase()===t);if(!o)return null;let[i,s]=o;if(r.length===0)return Se(s)?[i]:null;if(s!==null&&typeof s=="object"&&!Se(s)){let a=Ne(s,r);if(a!==null)return[i,...a]}return null}function Rn(e,n){let t=[];t.push(`${e}({`),t.push(" webhookHooks: {");for(let i=0;i<n.length;i++){let s=" ".repeat(i+2);t.push(`${s}${n[i]}: {`)}let r=" ".repeat(n.length+2),o=r+" ";t.push(`${r}before(ctx, args) {`),t.push(`${o}return { ctx, args };`),t.push(`${r}},`),t.push(`${r}after(ctx, response) {`),t.push(`${r}},`);for(let i=n.length-1;i>=0;i--){let s=" ".repeat(i+2);t.push(`${s}},`)}return t.push(" },"),t.push("})"),t.join(`
|
|
14
|
-
`)}var st=new Set(kn);function V(e,n){let t=n?.type??"api",r=n?.plugin;if(r!==void 0){let i=e.find(a=>a.id===r);if(!i)return st.has(r)?`This plugin (${r}) is not configured. Please add it to the Corsair instance to see its associated methods.`:V(e);if(t==="webhooks"){if(!i.webhooks)return[];let a=[];return Oe(i.webhooks,[],a),a.map(d=>`${i.id}.webhooks.${d}`)}if(t==="db"){let a=i.schema?.entities;return a?Object.keys(a).map(d=>`${i.id}.db.${d}.search`):[]}if(!i.endpoints)return[];let s=[];return ve(i.endpoints,[],s),s.map(a=>`${i.id}.api.${a}`)}let o={};if(t==="webhooks")for(let i of e){if(!i.webhooks)continue;let s=[];Oe(i.webhooks,[],s),o[i.id]=s.map(a=>`${i.id}.webhooks.${a}`)}else if(t==="db")for(let i of e){let s=i.schema?.entities;s&&(o[i.id]=Object.keys(s).map(a=>`${i.id}.db.${a}.search`))}else for(let i of e){if(!i.endpoints)continue;let s=[];ve(i.endpoints,[],s),o[i.id]=s.map(a=>`${i.id}.api.${a}`)}return o}function B(e,n){if(e){for(let[t,r]of Object.entries(e))if(t.toLowerCase()===n)return r}}function at(e,n){let t=e.toLowerCase(),r=n.toLowerCase();if(!t.startsWith(`${r}.`)){let i=t.slice(n.length+1),s=i.startsWith(".")?i.slice(1):i;return s.startsWith("api.")&&(s=s.slice(4)),{shortPath:s,lookupKey:s}}let o=e.slice(n.length+1);return o.toLowerCase().startsWith("api.")&&(o=o.slice(4)),{shortPath:o,lookupKey:o.toLowerCase()}}function De(e,n){return typeof e=="string"?e:Array.isArray(e)?`${n}:
|
|
15
|
-
${e.join(", ")}`:`${n}:
|
|
16
|
-
`+Object.entries(e).map(([t,r])=>` ${t}: ${r.join(", ")}`).join(`
|
|
17
|
-
`)}function Pr(e,n){let t=n.toLowerCase(),r=t.indexOf(".");if(r!==-1){let o=t.slice(0,r),i=t.slice(r+1),s=e.find(a=>a.id===o);if(s){if(i.startsWith("db.")){let c=i.slice(3),p=c.lastIndexOf(".");if(p!==-1){let f=c.slice(0,p),g=c.slice(p+1),l=s.schema?.entities;if(g==="search"&&l){let m=An(l,f);if(m){let[b,k]=m,w=$e(k),T=[`Search ${o} ${b} stored in the local database.`,"Pass limit and offset as numbers for pagination.","","filters {",` entity_id: string [${Fe.join(", ")}]`];for(let[y,h]of Object.entries(w))T.push(` ${y}?: ${h.type} [${h.operators.join(", ")}]`);return T.push("}"),T.join(`
|
|
18
|
-
`)}}}return De(V(e,{type:"db"}),"Path not found. Available db operations")}if(i.startsWith("webhooks.")){let c=i.slice(9);if(s.webhooks){let p=Ne(s.webhooks,c.split("."));if(p!==null){let f=p.join("."),g=B(s.webhookSchemas,f.toLowerCase()),l=g?.response?I(g.response):null,m=[];return g?.description&&m.push(g.description),g?.payload&&m.push(`payload ${be(ee(g.payload))}`),l&&m.push(`response: ${l}`),m.push(`usage:
|
|
19
|
-
${Rn(o,p)}`),m.join(`
|
|
20
|
-
|
|
21
|
-
`)}}return De(V(e,{type:"webhooks"}),"Path not found. Available webhooks")}let a=i;a.startsWith("api.")&&(a=a.slice(4));let d=B(s.endpointMeta,a),u=B(s.endpointSchemas,a);if(d||u){let c=[],p=[d?.riskLevel?`[${d.riskLevel}]`:"",d?.irreversible?"[irreversible]":""].filter(Boolean).join(" "),f=[d?.description,p].filter(Boolean).join(" ");return f&&c.push(f),u?.input&&c.push(`input ${be(ee(u.input))}`),u?.output&&c.push(`output ${be(ee(u.output))}`),c.join(`
|
|
22
|
-
|
|
23
|
-
`)}}}return De(V(e),"Path not found. Available operations")}function wn(e){let n=e;for(;;){let t=v(n),r=S(t);if(Me(r)){let o=D(t);if(!o)return n;n=o;continue}return n}}function ee(e){if(e===void 0)return{kind:"inline",type:"unknown"};let n=wn(e),t=v(n);if(S(t)==="ZodObject"){let o=we(n,t),i=[];for(let[s,a]of Object.entries(o)){let d=v(a),u=S(d),c=u==="ZodOptional"||u==="ZodNullable",p=wn(a),f=tt(a);i.push({key:s,optional:c,type:I(p),...f!==void 0?{description:f}:{}})}return{kind:"object",fields:i}}return{kind:"inline",type:I(n)}}function be(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=bn.repeat(n+1),r=bn.repeat(n);return`{
|
|
24
|
-
${e.fields.map(i=>{let s=i.optional?`${i.key}?`:i.key,a=i.description?` // ${i.description}`:"";return`${t}${s}: ${i.type}${a}`}).join(`
|
|
25
|
-
`)}
|
|
26
|
-
${r}}`}return"unknown"}function ct(e,n){let t=V(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:f}=at(c,n),g=B(r.endpointMeta,f),l=B(r.endpointSchemas,f);!g&&!l||o.push({path:c,shortPath:p,description:g?.description,riskLevel:g?.riskLevel,irreversible:g?.irreversible,input:ee(l?.input),output:ee(l?.output)})}o.sort((c,p)=>c.path.localeCompare(p.path));let i=[],s=V(e,{plugin:n,type:"webhooks"});if(Array.isArray(s)&&r.webhooks)for(let c of s){let f=c.toLowerCase().slice(n.length+1),g=f.startsWith(".")?f.slice(1):f;if(!g.startsWith("webhooks."))continue;let l=g.slice(9),m=Ne(r.webhooks,l.split("."));if(m===null)continue;let b=m.join("."),k=B(r.webhookSchemas,b.toLowerCase()),w=k?.response?I(k.response):void 0;i.push({path:c,description:k?.description,payload:ee(k?.payload),responseType:w,usageExample:Rn(n,m)})}i.sort((c,p)=>c.path.localeCompare(p.path));let a=[],d=V(e,{plugin:n,type:"db"}),u=r.schema?.entities;if(Array.isArray(d)&&u)for(let c of d){let f=c.toLowerCase().slice(n.length+1),g=f.startsWith(".")?f.slice(1):f;if(!g.startsWith("db."))continue;let l=g.slice(3),m=l.lastIndexOf(".");if(m===-1)continue;let b=l.slice(0,m);if(l.slice(m+1)!=="search")continue;let w=An(u,b);if(!w)continue;let[T,y]=w,h=$e(y),P=Object.entries(h).map(([A,_])=>({field:A,type:_.type,operators:_.operators}));a.push({path:c,entityName:T,filters:[{field:"entity_id",type:"string",operators:Fe},...P]})}return a.sort((c,p)=>c.path.localeCompare(p.path)),{ok:!0,data:{pluginId:n,api:o,webhooks:i,db:a}}}var J=Symbol.for("corsair:internal");function _r(e){let n=e.database?Ze(e.database):void 0,t=n&&e.kek?nn(e.plugins,n,e.kek):ce(!!n,!!e.kek),r={plugins:e.plugins,database:n,kek:e.kek,multiTenancy:!!e.multiTenancy,approval:e.approval,connect:e.connect},o=Xe(n),i=pn(r);if(e.multiTenancy)return Object.assign({withTenant:a=>{if(!a)throw new Error("corsair.withTenant(tenantId): tenantId must be a non-empty string");let d=Ie(e.plugins,{database:n,tenantId:a,kek:e.kek,rootErrorHandlers:e.errorHandlers,approvalConfig:e.approval,connectConfig:e.connect});return Object.assign(d,{[J]:r})},keys:t,permissions:o,manage:i},{[J]:r});let s=Ie(e.plugins,{database:n,tenantId:void 0,kek:e.kek,rootErrorHandlers:e.errorHandlers,approvalConfig:e.approval,connectConfig:e.connect});return Object.assign({},s,{keys:t,permissions:o,manage:i,[J]:r})}export{L as a,j as b,W as c,N as d,Te as e,xe as f,Q as g,U as h,re as i,q as j,Z as k,de as l,Ue as m,qe as n,ze as o,vn as p,Ge as q,Je as r,G as s,dn as t,un as u,ln as v,gn as w,Yn as x,mn as y,nt as z,kn as A,Cr as B,V as C,Pr as D,be as E,ct as F,J as G,_r as H};
|
package/dist/chunk-OZHME3EO.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{v7 as j}from"uuid";function g(){return j()}import{z as d}from"zod";import{sql as f}from"kysely";function m(e){return e.replace(/'/g,"''")}function k(e){let t=m(e);return f`data->>'${f.raw(t)}'`}function D(e){let t=m(e);return f`(data->>'${f.raw(t)}')::numeric`}function F(e){let t=m(e);return f`(data->>'${f.raw(t)}')::boolean`}function T(e){let t=m(e);return f`(data->>'${f.raw(t)}')::timestamptz`}function A(e){if(typeof e=="string")try{return JSON.parse(e)}catch{return e}return e}function _(e){let t=e;for(;t;){if(t instanceof d.ZodOptional||t instanceof d.ZodNullable){t=t._def.innerType;continue}if(t instanceof d.ZodDefault){t=t._def.innerType;continue}break}return t}function R(e){let t=_(e);if(t instanceof d.ZodString)return"string";if(t instanceof d.ZodNumber)return"number";if(t instanceof d.ZodBoolean)return"boolean";if(t instanceof d.ZodDate)return"date"}function x(e){let t=_(e);if(!(t instanceof d.ZodObject))return{};let r=t.shape,n={};for(let[u,w]of Object.entries(r)){let s=R(w);s&&(n[u]=s)}return n}function B(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 Z(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 C(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 S(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[u,w]=n.between;u instanceof Date&&(e=e.where(t,">=",u)),w instanceof Date&&(e=e.where(t,"<=",w))}}return e}function I(e,t,r,n){return r==="number"?Z(e,D(t),n):r==="boolean"?C(e,F(t),n):r==="date"?S(e,T(t),n):B(e,k(t),n)}function W(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 Q(e){return typeof e=="number"?e:typeof e=="bigint"?Number(e):Number.parseInt(String(e??0),10)}function p(e,t,r){return e.selectFrom("corsair_entities").selectAll().where("account_id","=",t).where("entity_type","=",r)}function z(e,t,r,n,u){let w=x(u);function s(i){let o=A(i.data);return{...i,data:u.parse(o)}}return{findByEntityId:async i=>{let o=await t(),a=await p(e,o,r).where("entity_id","=",i).executeTakeFirst();return a?s(a):null},findById:async i=>{let o=await t(),a=await p(e,o,r).where("id","=",i).executeTakeFirst();return a?s(a):null},findManyByEntityIds:async i=>{if(i.length===0)return[];let o=await t();return(await p(e,o,r).where("entity_id","in",i).execute()).map(s)},list:async i=>{let o=await t(),a=p(e,o,r);return typeof i?.limit=="number"&&(a=a.limit(i.limit)),typeof i?.offset=="number"&&(a=a.offset(i.offset)),(await a.execute()).map(s)},search:async i=>{let o=await t(),a=p(e,o,r),l=new Set(["data","limit","offset"]);for(let[c,y]of Object.entries(i))l.has(c)||y===void 0||(a=W(a,c,y));if(i.data&&typeof i.data=="object")for(let[c,y]of Object.entries(i.data)){if(y===void 0)continue;let b=w[c]??"string";a=I(a,c,b,y)}return typeof i.limit=="number"&&(a=a.limit(i.limit)),typeof i.offset=="number"&&(a=a.offset(i.offset)),(await a.execute()).map(s)},upsertByEntityId:async(i,o)=>{let a=await t(),l=u.parse(o),h=new Date,c=await p(e,a,r).select("id").where("entity_id","=",i).executeTakeFirst();if(c?.id){await e.updateTable("corsair_entities").set({version:n,data:l,updated_at:h}).where("id","=",c.id).execute();let E=await e.selectFrom("corsair_entities").selectAll().where("id","=",c.id).executeTakeFirst();return s(E)}let y=g();await e.insertInto("corsair_entities").values({id:y,created_at:h,updated_at:h,account_id:a,entity_id:i,entity_type:r,version:n,data:l}).execute();let b=await e.selectFrom("corsair_entities").selectAll().where("id","=",y).executeTakeFirst();return s(b)},deleteById:async i=>{let o=await t(),a=await e.deleteFrom("corsair_entities").where("account_id","=",o).where("entity_type","=",r).where("id","=",i).executeTakeFirst();return Number(a.numDeletedRows)>0},deleteByEntityId:async i=>{let o=await t(),a=await e.deleteFrom("corsair_entities").where("account_id","=",o).where("entity_type","=",r).where("entity_id","=",i).executeTakeFirst();return Number(a.numDeletedRows)>0},count:async()=>{let i=await t(),o=await e.selectFrom("corsair_entities").select(a=>a.fn.countAll().as("count")).where("account_id","=",i).where("entity_type","=",r).executeTakeFirst();return Q(o?.count)}}}export{g as a,z as b};
|
package/dist/chunk-UBM25HVI.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{a as h,b}from"./chunk-OZHME3EO.js";import{a as E,b as I,c as x,d as D}from"./chunk-3USHGH6P.js";var k={corsair_integrations:E,corsair_accounts:I,corsair_entities:x,corsair_events:D};function F(t){return k[t]}function _(t){if(typeof t=="string")try{return JSON.parse(t)}catch{return t}return t}function d(t){if(!t)throw new Error("Corsair database is not configured. Pass `database` to createCorsair(...) to enable ORM.")}function g(t){if(!t)return[];let n=[];for(let r in t){let e=r,i=t[e];if(i!==void 0)if(typeof i=="object"&&i!==null&&!Array.isArray(i)&&!(i instanceof Date)){let s=i;"in"in s&&Array.isArray(s.in)?n.push({field:e,operator:"in",value:s.in}):"like"in s&&typeof s.like=="string"&&n.push({field:e,operator:"like",value:s.like})}else n.push({field:e,value:i})}return n}function p(t,n){if(!n?.length)return t;let r=t;for(let e of n){let i=e.operator??"=";r=r.where(e.field,i,e.value)}return r}function S(t){return typeof t=="number"?t:typeof t=="bigint"?Number(t):Number.parseInt(String(t??0),10)}function T(t,n){let r=F(n),e=()=>(d(t),t),i=()=>e().db.selectFrom(n),s=()=>e().db.insertInto(n),u=()=>e().db.updateTable(n),c=()=>e().db.deleteFrom(n);function m(o){let a={};for(let[l,y]of Object.entries(o))a[l]=_(y);return r.parse(a)}function C(o){let a={};for(let[l,y]of Object.entries(o))a[l]=_(y);return r.parse(a)}return{findById:async o=>{d(t);let a=i().selectAll();a=p(a,[{field:"id",value:o}]);let l=await a.executeTakeFirst();return l?m(l):null},findOne:async o=>{d(t);let a=i().selectAll();a=p(a,g(o));let l=await a.executeTakeFirst();return l?m(l):null},findMany:async o=>{d(t);let a=i().selectAll();return a=p(a,g(o?.where)),typeof o?.limit=="number"&&(a=a.limit(o.limit)),typeof o?.offset=="number"&&(a=a.offset(o.offset)),(await a.execute()).map(y=>m(y))},create:async o=>{d(t);let a=new Date,l={id:o.id??h(),created_at:a,updated_at:a,...o},y=await s().values(l).returningAll().executeTakeFirst();return y?m(y):C(l)},update:async(o,a)=>{d(t);let l={...a,updated_at:new Date},y=u().set(l).returningAll();y=p(y,[{field:"id",value:o}]);let f=await y.executeTakeFirst();return f?m(f):null},updateMany:async(o,a)=>{d(t);let l={...a,updated_at:new Date},y=i().select("id");y=p(y,g(o));let f=await y.execute();for(let P of f){let w=u().set(l);w=p(w,[{field:"id",value:P.id}]),await w.execute()}return f.length},delete:async o=>{d(t);let a=c();a=p(a,[{field:"id",value:o}]);let l=await a.executeTakeFirst();return Number(l?.numDeletedRows??0)>0},deleteMany:async o=>{d(t);let a=c();a=p(a,g(o));let l=await a.executeTakeFirst();return Number(l?.numDeletedRows??0)},count:async o=>{d(t);let a=i().select(y=>y.fn.countAll().as("count"));a=p(a,g(o));let l=await a.executeTakeFirst();return S(l?.count)}}}function R(t){let n=T(t,"corsair_integrations");return{...n,findByName:r=>n.findOne({name:r}),upsertByName:async(r,e)=>{let i=await n.findOne({name:r});return i?await n.update(i.id,e):n.create({...e,name:r})}}}function O(t){let n=T(t,"corsair_accounts");return{...n,findByTenantAndIntegration:async(r,e)=>{d(t);let i=await t.db.selectFrom("corsair_integrations").selectAll().where("name","=",e).executeTakeFirst();return i?n.findOne({tenant_id:r,integration_id:i.id}):null},listByTenant:(r,e)=>n.findMany({where:{tenant_id:r},limit:e?.limit,offset:e?.offset}),upsertByTenantAndIntegration:async(r,e,i)=>{let s=await n.findOne({tenant_id:r,integration_id:e});return s?await n.update(s.id,i):n.create({...i,tenant_id:r,integration_id:e})}}}function v(t){let n=T(t,"corsair_entities");return{...n,findByEntityId:({accountId:r,entityType:e,entityId:i})=>n.findOne({account_id:r,entity_type:e,entity_id:i}),findManyByEntityIds:async({accountId:r,entityType:e,entityIds:i})=>i.length===0?[]:(d(t),await t.db.selectFrom("corsair_entities").selectAll().where("account_id","=",r).where("entity_type","=",e).where("entity_id","in",i).execute()),listByScope:({accountId:r,entityType:e,limit:i,offset:s})=>n.findMany({where:{account_id:r,entity_type:e},limit:i,offset:s}),searchByEntityId:async({accountId:r,entityType:e,query:i,limit:s,offset:u})=>{d(t);let c=t.db.selectFrom("corsair_entities").selectAll().where("account_id","=",r).where("entity_type","=",e).where("entity_id","like",`%${i}%`);return typeof s=="number"&&(c=c.limit(s)),typeof u=="number"&&(c=c.offset(u)),await c.execute()},upsertByEntityId:async({accountId:r,entityType:e,entityId:i,version:s,data:u})=>{let c=await n.findOne({account_id:r,entity_type:e,entity_id:i});return c?await n.update(c.id,{version:s,data:u}):n.create({account_id:r,entity_type:e,entity_id:i,version:s,data:u})},deleteByEntityId:async({accountId:r,entityType:e,entityId:i})=>{d(t);let s=await t.db.deleteFrom("corsair_entities").where("account_id","=",r).where("entity_type","=",e).where("entity_id","=",i).executeTakeFirst();return Number(s.numDeletedRows)>0}}}function N(t){let n=T(t,"corsair_events");return{...n,listByAccount:(r,e)=>n.findMany({where:{account_id:r},limit:e?.limit,offset:e?.offset}),listByStatus:(r,e)=>{let i={status:r};return e?.accountId&&(i.account_id=e.accountId),n.findMany({where:i,limit:e?.limit,offset:e?.offset})},listPending:r=>{let e={status:"pending"};return r?.accountId&&(e.account_id=r.accountId),n.findMany({where:e,limit:r?.limit??100})},updateStatus:(r,e)=>n.update(r,{status:e})}}function A(t){return{integrations:R(t),accounts:O(t),entities:v(t),events:N(t)}}function W(t,n,r,e,i){let s=null;async function u(){if(s!==null)return s;d(t);let c=await t.db.selectFrom("corsair_integrations").selectAll().where("name","=",n.integrationName).executeTakeFirst();if(!c)throw new Error(`Integration "${n.integrationName}" not found. Make sure to create the integration first.`);let m=await t.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",n.tenantId).where("integration_id","=",c.id).executeTakeFirst();if(!m)throw new Error(`Account not found for tenant "${n.tenantId}" and integration "${n.integrationName}". Make sure to create the account first.`);return s=m.id,s}return d(t),b(t.db,u,r,e,i)}function B(t){let{database:n,integrationName:r,schema:e,tenantId:i}=t,s=A(n),u={tenantId:i,integrationName:r},c=null;async function m(){if(c!==null)return c;d(n);let o=await n.db.selectFrom("corsair_integrations").selectAll().where("name","=",r).executeTakeFirst();if(!o)throw new Error(`Integration "${r}" not found. Make sure to create the integration first.`);let a=await n.db.selectFrom("corsair_accounts").selectAll().where("tenant_id","=",i).where("integration_id","=",o.id).executeTakeFirst();if(!a)throw new Error(`Account not found for tenant "${i}" and integration "${r}". Make sure to create the account first.`);return c=a.id,c}let C={};for(let[o,a]of Object.entries(e.entities))C[o]=W(n,u,o,e.version,a);return{...C,$orm:s,$integrationName:r,$tenantId:i,$getAccountId:m}}function q(t,n){let r=A(t);return{$tenantId:n,$orm:r,listAccounts:e=>r.accounts.listByTenant(n,e),findAccountByIntegration:e=>r.accounts.findByTenantAndIntegration(n,e),listEntities:async e=>{d(t);let i=await t.db.selectFrom("corsair_accounts").select("id").where("tenant_id","=",n).execute();if(i.length===0)return[];let s=i.map(c=>c.id),u=t.db.selectFrom("corsair_entities").selectAll().where("account_id","in",s);return e?.entityType&&(u=u.where("entity_type","=",e.entityType)),typeof e?.limit=="number"&&(u=u.limit(e.limit)),typeof e?.offset=="number"&&(u=u.offset(e.offset)),await u.execute()},listEvents:async e=>{d(t);let i=await t.db.selectFrom("corsair_accounts").select("id").where("tenant_id","=",n).execute();if(i.length===0)return[];let s=i.map(c=>c.id),u=t.db.selectFrom("corsair_events").selectAll().where("account_id","in",s);return e?.status&&(u=u.where("status","=",e.status)),typeof e?.limit=="number"&&(u=u.limit(e.limit)),typeof e?.offset=="number"&&(u=u.offset(e.offset)),await u.execute()},forIntegration:e=>B({database:t,integrationName:e.integrationName,schema:e.schema,tenantId:n})}}function K(t,n){return{forTenant:r=>B({database:t,integrationName:n.integrationName,schema:n.schema,tenantId:r})}}export{k as a,A as b,B as c,q as d,K as e};
|