corsair 0.1.14 → 0.1.16

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.
Files changed (199) hide show
  1. package/dist/core/client/index.d.ts +10 -2
  2. package/dist/core/client/index.d.ts.map +1 -1
  3. package/dist/core/client/index.js +13 -1
  4. package/dist/core/constants.d.ts +2 -2
  5. package/dist/core/constants.d.ts.map +1 -1
  6. package/dist/core/constants.js +1 -0
  7. package/dist/core/endpoints/bind.d.ts +17 -2
  8. package/dist/core/endpoints/bind.d.ts.map +1 -1
  9. package/dist/core/endpoints/bind.js +32 -2
  10. package/dist/core/endpoints/index.d.ts +28 -0
  11. package/dist/core/endpoints/index.d.ts.map +1 -1
  12. package/dist/core/index.d.ts +8 -2
  13. package/dist/core/index.d.ts.map +1 -1
  14. package/dist/core/index.js +5 -0
  15. package/dist/core/inspect/index.d.ts +57 -0
  16. package/dist/core/inspect/index.d.ts.map +1 -0
  17. package/dist/core/inspect/index.js +150 -0
  18. package/dist/core/permissions/index.d.ts +29 -0
  19. package/dist/core/permissions/index.d.ts.map +1 -0
  20. package/dist/core/permissions/index.js +87 -0
  21. package/dist/core/plugins/index.d.ts +136 -1
  22. package/dist/core/plugins/index.d.ts.map +1 -1
  23. package/dist/core/webhooks/bind.d.ts.map +1 -1
  24. package/dist/core/webhooks/bind.js +6 -1
  25. package/dist/db/index.d.ts +65 -1
  26. package/dist/db/index.d.ts.map +1 -1
  27. package/dist/db/index.js +28 -0
  28. package/dist/db/kysely/database.d.ts +2 -1
  29. package/dist/db/kysely/database.d.ts.map +1 -1
  30. package/dist/index.d.ts +1 -0
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +1 -0
  33. package/dist/plugins/discord/index.d.ts +1 -1
  34. package/dist/plugins/discord/index.d.ts.map +1 -1
  35. package/dist/plugins/discord/index.js +30 -0
  36. package/dist/plugins/discord/schema/database.d.ts +2 -2
  37. package/dist/plugins/discord/schema/index.d.ts +2 -2
  38. package/dist/plugins/github/endpoints/index.d.ts +8 -8
  39. package/dist/plugins/github/endpoints/types.d.ts +8276 -36
  40. package/dist/plugins/github/endpoints/types.d.ts.map +1 -1
  41. package/dist/plugins/github/endpoints/types.js +26 -0
  42. package/dist/plugins/github/index.d.ts +17 -1
  43. package/dist/plugins/github/index.d.ts.map +1 -1
  44. package/dist/plugins/github/index.js +82 -0
  45. package/dist/plugins/github/schema/database.d.ts +2 -2
  46. package/dist/plugins/github/schema/index.d.ts +2 -2
  47. package/dist/plugins/gmail/client.d.ts +7 -2
  48. package/dist/plugins/gmail/client.d.ts.map +1 -1
  49. package/dist/plugins/gmail/client.js +11 -21
  50. package/dist/plugins/gmail/endpoints/types.d.ts +1702 -0
  51. package/dist/plugins/gmail/endpoints/types.d.ts.map +1 -1
  52. package/dist/plugins/gmail/endpoints/types.js +31 -0
  53. package/dist/plugins/gmail/index.d.ts +1 -0
  54. package/dist/plugins/gmail/index.d.ts.map +1 -1
  55. package/dist/plugins/gmail/index.js +107 -6
  56. package/dist/plugins/googlecalendar/client.d.ts +7 -2
  57. package/dist/plugins/googlecalendar/client.d.ts.map +1 -1
  58. package/dist/plugins/googlecalendar/client.js +11 -21
  59. package/dist/plugins/googlecalendar/endpoints/types.d.ts +2316 -2
  60. package/dist/plugins/googlecalendar/endpoints/types.d.ts.map +1 -1
  61. package/dist/plugins/googlecalendar/endpoints/types.js +11 -0
  62. package/dist/plugins/googlecalendar/index.d.ts +1 -0
  63. package/dist/plugins/googlecalendar/index.d.ts.map +1 -1
  64. package/dist/plugins/googlecalendar/index.js +35 -6
  65. package/dist/plugins/googlecalendar/schema/database.d.ts +4 -4
  66. package/dist/plugins/googlecalendar/schema/index.d.ts +4 -4
  67. package/dist/plugins/googledrive/client.d.ts +7 -2
  68. package/dist/plugins/googledrive/client.d.ts.map +1 -1
  69. package/dist/plugins/googledrive/client.js +11 -21
  70. package/dist/plugins/googledrive/endpoints/index.d.ts +1 -1
  71. package/dist/plugins/googledrive/endpoints/types.d.ts +2468 -30
  72. package/dist/plugins/googledrive/endpoints/types.d.ts.map +1 -1
  73. package/dist/plugins/googledrive/endpoints/types.js +26 -0
  74. package/dist/plugins/googledrive/index.d.ts +1 -0
  75. package/dist/plugins/googledrive/index.d.ts.map +1 -1
  76. package/dist/plugins/googledrive/index.js +68 -6
  77. package/dist/plugins/googledrive/schema/database.d.ts +8 -8
  78. package/dist/plugins/googledrive/schema/index.d.ts +8 -8
  79. package/dist/plugins/googlesheets/client.d.ts +7 -2
  80. package/dist/plugins/googlesheets/client.d.ts.map +1 -1
  81. package/dist/plugins/googlesheets/client.js +11 -21
  82. package/dist/plugins/googlesheets/endpoints/types.d.ts +588 -0
  83. package/dist/plugins/googlesheets/endpoints/types.d.ts.map +1 -1
  84. package/dist/plugins/googlesheets/endpoints/types.js +15 -0
  85. package/dist/plugins/googlesheets/index.d.ts +1 -0
  86. package/dist/plugins/googlesheets/index.d.ts.map +1 -1
  87. package/dist/plugins/googlesheets/index.js +53 -6
  88. package/dist/plugins/hubspot/endpoints/index.d.ts +8 -8
  89. package/dist/plugins/hubspot/endpoints/types.d.ts +7307 -16
  90. package/dist/plugins/hubspot/endpoints/types.d.ts.map +1 -1
  91. package/dist/plugins/hubspot/endpoints/types.js +39 -0
  92. package/dist/plugins/hubspot/index.d.ts +1 -0
  93. package/dist/plugins/hubspot/index.d.ts.map +1 -1
  94. package/dist/plugins/hubspot/index.js +88 -0
  95. package/dist/plugins/hubspot/schema/database.d.ts +8 -8
  96. package/dist/plugins/hubspot/schema/index.d.ts +8 -8
  97. package/dist/plugins/linear/api.test.js +55 -0
  98. package/dist/plugins/linear/endpoints/index.d.ts +99 -62
  99. package/dist/plugins/linear/endpoints/index.d.ts.map +1 -1
  100. package/dist/plugins/linear/endpoints/index.js +5 -0
  101. package/dist/plugins/linear/endpoints/types.d.ts +2529 -411
  102. package/dist/plugins/linear/endpoints/types.d.ts.map +1 -1
  103. package/dist/plugins/linear/endpoints/types.js +44 -0
  104. package/dist/plugins/linear/endpoints/users.d.ts +4 -0
  105. package/dist/plugins/linear/endpoints/users.d.ts.map +1 -0
  106. package/dist/plugins/linear/endpoints/users.js +81 -0
  107. package/dist/plugins/linear/index.d.ts +14 -1
  108. package/dist/plugins/linear/index.d.ts.map +1 -1
  109. package/dist/plugins/linear/index.js +69 -1
  110. package/dist/plugins/linear/schema/database.d.ts +12 -12
  111. package/dist/plugins/linear/schema/database.js +2 -2
  112. package/dist/plugins/linear/schema/index.d.ts +12 -12
  113. package/dist/plugins/posthog/endpoints/index.d.ts +3 -3
  114. package/dist/plugins/posthog/endpoints/types.d.ts +145 -6
  115. package/dist/plugins/posthog/endpoints/types.d.ts.map +1 -1
  116. package/dist/plugins/posthog/endpoints/types.js +10 -0
  117. package/dist/plugins/posthog/index.d.ts +1 -0
  118. package/dist/plugins/posthog/index.d.ts.map +1 -1
  119. package/dist/plugins/posthog/index.js +21 -0
  120. package/dist/plugins/posthog/schema/database.d.ts +2 -2
  121. package/dist/plugins/posthog/schema/index.d.ts +2 -2
  122. package/dist/plugins/resend/endpoints/types.d.ts +318 -0
  123. package/dist/plugins/resend/endpoints/types.d.ts.map +1 -1
  124. package/dist/plugins/resend/endpoints/types.js +13 -0
  125. package/dist/plugins/resend/index.d.ts +1 -0
  126. package/dist/plugins/resend/index.d.ts.map +1 -1
  127. package/dist/plugins/resend/index.js +28 -0
  128. package/dist/plugins/slack/endpoints/types.d.ts +17323 -0
  129. package/dist/plugins/slack/endpoints/types.d.ts.map +1 -1
  130. package/dist/plugins/slack/endpoints/types.js +47 -0
  131. package/dist/plugins/slack/index.d.ts +8 -1
  132. package/dist/plugins/slack/index.d.ts.map +1 -1
  133. package/dist/plugins/slack/index.js +148 -0
  134. package/dist/plugins/spotify/api.test.d.ts +2 -0
  135. package/dist/plugins/spotify/api.test.d.ts.map +1 -0
  136. package/dist/plugins/spotify/api.test.js +200 -0
  137. package/dist/plugins/spotify/client.d.ts +17 -0
  138. package/dist/plugins/spotify/client.d.ts.map +1 -0
  139. package/dist/plugins/spotify/client.js +112 -0
  140. package/dist/plugins/spotify/endpoints/albums.d.ts +6 -0
  141. package/dist/plugins/spotify/endpoints/albums.d.ts.map +1 -0
  142. package/dist/plugins/spotify/endpoints/albums.js +63 -0
  143. package/dist/plugins/spotify/endpoints/artists.d.ts +7 -0
  144. package/dist/plugins/spotify/endpoints/artists.d.ts.map +1 -0
  145. package/dist/plugins/spotify/endpoints/artists.js +53 -0
  146. package/dist/plugins/spotify/endpoints/index.d.ts +958 -0
  147. package/dist/plugins/spotify/endpoints/index.d.ts.map +1 -0
  148. package/dist/plugins/spotify/endpoints/index.js +52 -0
  149. package/dist/plugins/spotify/endpoints/library.d.ts +3 -0
  150. package/dist/plugins/spotify/endpoints/library.d.ts.map +1 -0
  151. package/dist/plugins/spotify/endpoints/library.js +11 -0
  152. package/dist/plugins/spotify/endpoints/my-data.d.ts +3 -0
  153. package/dist/plugins/spotify/endpoints/my-data.d.ts.map +1 -0
  154. package/dist/plugins/spotify/endpoints/my-data.js +19 -0
  155. package/dist/plugins/spotify/endpoints/player.d.ts +11 -0
  156. package/dist/plugins/spotify/endpoints/player.d.ts.map +1 -0
  157. package/dist/plugins/spotify/endpoints/player.js +124 -0
  158. package/dist/plugins/spotify/endpoints/playlists.d.ts +9 -0
  159. package/dist/plugins/spotify/endpoints/playlists.d.ts.map +1 -0
  160. package/dist/plugins/spotify/endpoints/playlists.js +90 -0
  161. package/dist/plugins/spotify/endpoints/tracks.d.ts +5 -0
  162. package/dist/plugins/spotify/endpoints/tracks.d.ts.map +1 -0
  163. package/dist/plugins/spotify/endpoints/tracks.js +37 -0
  164. package/dist/plugins/spotify/endpoints/types.d.ts +12433 -0
  165. package/dist/plugins/spotify/endpoints/types.d.ts.map +1 -0
  166. package/dist/plugins/spotify/endpoints/types.js +572 -0
  167. package/dist/plugins/spotify/error-handlers.d.ts +77 -0
  168. package/dist/plugins/spotify/error-handlers.d.ts.map +1 -0
  169. package/dist/plugins/spotify/error-handlers.js +124 -0
  170. package/dist/plugins/spotify/index.d.ts +132 -0
  171. package/dist/plugins/spotify/index.d.ts.map +1 -0
  172. package/dist/plugins/spotify/index.js +159 -0
  173. package/dist/plugins/spotify/integration.test.d.ts +2 -0
  174. package/dist/plugins/spotify/integration.test.d.ts.map +1 -0
  175. package/dist/plugins/spotify/integration.test.js +448 -0
  176. package/dist/plugins/spotify/schema/database.d.ts +640 -0
  177. package/dist/plugins/spotify/schema/database.d.ts.map +1 -0
  178. package/dist/plugins/spotify/schema/database.js +201 -0
  179. package/dist/plugins/spotify/schema/index.d.ts +638 -0
  180. package/dist/plugins/spotify/schema/index.d.ts.map +1 -0
  181. package/dist/plugins/spotify/schema/index.js +12 -0
  182. package/dist/plugins/spotify/webhooks/example.d.ts +3 -0
  183. package/dist/plugins/spotify/webhooks/example.d.ts.map +1 -0
  184. package/dist/plugins/spotify/webhooks/example.js +31 -0
  185. package/dist/plugins/spotify/webhooks/index.d.ts +8 -0
  186. package/dist/plugins/spotify/webhooks/index.d.ts.map +1 -0
  187. package/dist/plugins/spotify/webhooks/index.js +5 -0
  188. package/dist/plugins/spotify/webhooks/types.d.ts +103 -0
  189. package/dist/plugins/spotify/webhooks/types.d.ts.map +1 -0
  190. package/dist/plugins/spotify/webhooks/types.js +82 -0
  191. package/dist/plugins/tavily/endpoints/index.d.ts +2 -2
  192. package/dist/plugins/tavily/endpoints/types.d.ts +4 -4
  193. package/dist/plugins/tavily/index.d.ts +2 -2
  194. package/dist/plugins/tavily/index.d.ts.map +1 -1
  195. package/dist/plugins/tavily/index.js +8 -0
  196. package/dist/templates/plugin/generate.js +55 -1
  197. package/dist/tsup.config.d.ts.map +1 -1
  198. package/dist/tsup.config.js +9 -1
  199. package/package.json +6 -1
@@ -1,5 +1,6 @@
1
1
  import type { ZodTypeAny } from 'zod';
2
2
  import type { CorsairDatabase } from '../../db/kysely/database';
3
+ import { type CorsairInspectMethods } from '../inspect';
3
4
  import type { CorsairPluginSchema, PluginEntityClients } from '../../db/orm';
4
5
  import type { AccountKeyManagerFor, IntegrationKeyManagerFor, PluginAuthConfig } from '../auth/types';
5
6
  import type { AuthTypes } from '../constants';
@@ -86,11 +87,13 @@ type InferAllIntegrationKeys<Plugins extends readonly CorsairPlugin[]> = UnionTo
86
87
  type InferPluginNamespaces<Plugins extends readonly CorsairPlugin[]> = UnionToIntersection<InferPluginNamespace<Plugins[number]>>;
87
88
  /**
88
89
  * The main Corsair client type that provides access to all plugin APIs, entities, webhooks, and keys.
90
+ * Also includes get_methods() and get_schema() for agent-facing endpoint discovery.
89
91
  */
90
- export type CorsairClient<Plugins extends readonly CorsairPlugin[]> = InferPluginNamespaces<Plugins>;
92
+ export type CorsairClient<Plugins extends readonly CorsairPlugin[]> = InferPluginNamespaces<Plugins> & CorsairInspectMethods;
91
93
  /**
92
94
  * Multi-tenant wrapper that provides a `withTenant` method to scope operations to a specific tenant.
93
95
  * Also includes integration-level `keys` for managing shared secrets (OAuth2 client credentials, etc.)
96
+ * Inspect methods (get_methods / get_schema) are available at the root — no need to call withTenant().
94
97
  */
95
98
  export type CorsairTenantWrapper<Plugins extends readonly CorsairPlugin[]> = {
96
99
  withTenant: (tenantId: string) => CorsairClient<Plugins>;
@@ -99,7 +102,7 @@ export type CorsairTenantWrapper<Plugins extends readonly CorsairPlugin[]> = {
99
102
  * Used to manage secrets shared across all tenants (e.g., OAuth2 client_id, client_secret).
100
103
  */
101
104
  keys: InferAllIntegrationKeys<Plugins>;
102
- };
105
+ } & CorsairInspectMethods;
103
106
  /**
104
107
  * Single-tenant client that includes both plugin APIs and integration-level keys.
105
108
  */
@@ -115,6 +118,11 @@ export type BuildCorsairClientOptions = {
115
118
  tenantId: string | undefined;
116
119
  kek: string | undefined;
117
120
  rootErrorHandlers?: CorsairErrorHandler;
121
+ /** Approval timeout from createCorsair({ approval: ... }). Forwarded to the permission guard. */
122
+ approvalConfig?: {
123
+ timeout: string;
124
+ onTimeout: 'deny' | 'approve';
125
+ };
118
126
  };
119
127
  /**
120
128
  * Builds a Corsair client instance with all plugin APIs, entities, webhooks, and account-level keys bound.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../core/client/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../core/client/index.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { createKyselyEntityClient } from '../../db/kysely/orm';
2
+ import { buildInspectMethods, } from '../inspect';
2
3
  import { createAccountKeyManager, createIntegrationKeyManager, } from '../auth/key-manager';
3
4
  import { bindEndpointsRecursively } from '../endpoints/bind';
4
5
  import { bindWebhooksRecursively } from '../webhooks/bind';
@@ -78,7 +79,7 @@ function createEntityClient(database, getAccountId, entityTypeName, version, dat
78
79
  * @returns A fully configured Corsair client with account-level keys
79
80
  */
80
81
  export function buildCorsairClient(plugins, options) {
81
- const { database, tenantId, kek, rootErrorHandlers } = options;
82
+ const { database, tenantId, kek, rootErrorHandlers, approvalConfig, } = options;
82
83
  const apiUnsafe = {};
83
84
  const pluginEntitiesUnsafe = {};
84
85
  for (const plugin of plugins) {
@@ -141,6 +142,10 @@ export function buildCorsairClient(plugins, options) {
141
142
  };
142
143
  // Create bound endpoints under `api` (supports nested structures)
143
144
  const boundTree = {};
145
+ // Extract permission config from plugin options.
146
+ // options is Record<string, unknown> — permissions is not in the base CorsairPlugin type
147
+ // because it's plugin-specific (typed via PluginPermissionsConfig<T> in each plugin).
148
+ const pluginPermsConfig = plugin.options?.permissions;
144
149
  bindEndpointsRecursively({
145
150
  endpoints,
146
151
  hooks,
@@ -150,6 +155,11 @@ export function buildCorsairClient(plugins, options) {
150
155
  errorHandlers: allErrorHandlers,
151
156
  currentPath: [],
152
157
  keyBuilder: plugin.keyBuilder,
158
+ permissionsConfig: pluginPermsConfig,
159
+ // endpointMeta is typed with plugin-specific literal keys — cast to runtime Record
160
+ endpointMeta: plugin.endpointMeta,
161
+ database,
162
+ approvalConfig,
153
163
  });
154
164
  if (Object.keys(boundTree).length > 0) {
155
165
  apiUnsafe[plugin.id].api = boundTree;
@@ -177,8 +187,10 @@ export function buildCorsairClient(plugins, options) {
177
187
  }
178
188
  }
179
189
  const api = apiUnsafe;
190
+ const inspect = buildInspectMethods(plugins);
180
191
  return {
181
192
  ...api,
193
+ ...inspect,
182
194
  };
183
195
  }
184
196
  // ─────────────────────────────────────────────────────────────────────────────
@@ -1,6 +1,6 @@
1
1
  export 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
- export declare const BaseProviders: readonly ["discord", "github", "gmail", "googlecalendar", "googledrive", "googlesheets", "hubspot", "linear", "posthog", "resend", "slack", "tavily"];
3
- export type AllProviders = 'discord' | 'github' | 'gmail' | 'googlecalendar' | 'googledrive' | 'googlesheets' | 'hubspot' | 'linear' | 'posthog' | 'resend' | 'slack' | 'tavily' | (string & {});
2
+ export declare const BaseProviders: readonly ["discord", "github", "gmail", "googlecalendar", "googledrive", "googlesheets", "hubspot", "linear", "posthog", "resend", "slack", "spotify", "tavily"];
3
+ export type AllProviders = 'discord' | 'github' | 'gmail' | 'googlecalendar' | 'googledrive' | 'googlesheets' | 'hubspot' | 'linear' | 'posthog' | 'resend' | 'slack' | 'spotify' | 'tavily' | (string & {});
4
4
  export type AuthTypes = 'oauth_2' | 'api_key' | 'bot_token';
5
5
  export type PickAuth<T extends AuthTypes> = T;
6
6
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../core/constants.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAClB,kBAAkB,GAClB,YAAY,GACZ,kBAAkB,GAClB,eAAe,GACf,eAAe,GACf,cAAc,GACd,kBAAkB,GAClB,iBAAiB,GACjB,mBAAmB,GACnB,eAAe,GACf,SAAS,GACT,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAEjB,eAAO,MAAM,aAAa,uJAahB,CAAC;AAEX,MAAM,MAAM,YAAY,GACrB,SAAS,GACT,QAAQ,GACR,OAAO,GACP,gBAAgB,GAChB,aAAa,GACb,cAAc,GACd,SAAS,GACT,QAAQ,GACR,SAAS,GACT,QAAQ,GACR,OAAO,GACP,QAAQ,GACR,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAEjB,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,CAAC;AAE5D,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,SAAS,IAAI,CAAC,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../core/constants.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAClB,kBAAkB,GAClB,YAAY,GACZ,kBAAkB,GAClB,eAAe,GACf,eAAe,GACf,cAAc,GACd,kBAAkB,GAClB,iBAAiB,GACjB,mBAAmB,GACnB,eAAe,GACf,SAAS,GACT,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAEjB,eAAO,MAAM,aAAa,kKAchB,CAAC;AAEX,MAAM,MAAM,YAAY,GACrB,SAAS,GACT,QAAQ,GACR,OAAO,GACP,gBAAgB,GAChB,aAAa,GACb,cAAc,GACd,SAAS,GACT,QAAQ,GACR,SAAS,GACT,QAAQ,GACR,OAAO,GACP,SAAS,GACT,QAAQ,GACR,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAEjB,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,CAAC;AAE5D,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,SAAS,IAAI,CAAC,CAAC"}
@@ -10,5 +10,6 @@ export const BaseProviders = [
10
10
  'posthog',
11
11
  'resend',
12
12
  'slack',
13
+ 'spotify',
13
14
  'tavily',
14
15
  ];
@@ -1,5 +1,6 @@
1
+ import type { CorsairDatabase } from '../../db/kysely/database';
1
2
  import type { CorsairErrorHandler } from '../errors';
2
- import type { CorsairKeyBuilderBase } from '../plugins';
3
+ import type { CorsairKeyBuilderBase, EndpointMetaEntry, PermissionMode, PermissionPolicy } from '../plugins';
3
4
  /**
4
5
  * Checks if a value is an endpoint/function (has function signature).
5
6
  * @param value - The value to check
@@ -18,7 +19,7 @@ export declare function isEndpoint(value: unknown): value is Function;
18
19
  * @param currentPath - The current path for tracking nested endpoint operations
19
20
  * @param keyBuilder - Optional async callback to generate a key from the plugin context
20
21
  */
21
- export declare function bindEndpointsRecursively({ endpoints, hooks, ctx, tree, pluginId, errorHandlers, currentPath, keyBuilder, }: {
22
+ export declare function bindEndpointsRecursively({ endpoints, hooks, ctx, tree, pluginId, errorHandlers, currentPath, keyBuilder, permissionsConfig, endpointMeta, database, approvalConfig, }: {
22
23
  endpoints: Record<string, unknown>;
23
24
  hooks: Record<string, unknown> | undefined;
24
25
  ctx: Record<string, unknown>;
@@ -27,5 +28,19 @@ export declare function bindEndpointsRecursively({ endpoints, hooks, ctx, tree,
27
28
  errorHandlers: CorsairErrorHandler;
28
29
  currentPath: string[];
29
30
  keyBuilder?: CorsairKeyBuilderBase;
31
+ /** Permission mode + per-endpoint overrides from plugin options. When set, every call is gated. */
32
+ permissionsConfig?: {
33
+ mode: PermissionMode;
34
+ overrides?: Record<string, PermissionPolicy>;
35
+ };
36
+ /** Risk level metadata per dot-notation endpoint path. Defaults riskLevel to 'write' when missing. */
37
+ endpointMeta?: Record<string, EndpointMetaEntry>;
38
+ /** Required for 'require_approval' to persist the approval record to the DB. */
39
+ database?: CorsairDatabase;
40
+ /** Approval timeout config from createCorsair({ approval: ... }). */
41
+ approvalConfig?: {
42
+ timeout: string;
43
+ onTimeout: 'deny' | 'approve';
44
+ };
30
45
  }): void;
31
46
  //# sourceMappingURL=bind.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bind.d.ts","sourceRoot":"","sources":["../../../core/endpoints/bind.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAErD,OAAO,KAAK,EAAE,qBAAqB,EAAiB,MAAM,YAAY,CAAC;AAMvE;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAE5D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CAAC,EACxC,SAAS,EACT,KAAK,EACL,GAAG,EACH,IAAI,EACJ,QAAQ,EACR,aAAa,EACb,WAAgB,EAChB,UAAU,GACV,EAAE;IACF,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IAC3C,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,mBAAmB,CAAC;IACnC,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,UAAU,CAAC,EAAE,qBAAqB,CAAC;CACnC,GAAG,IAAI,CAuHP"}
1
+ {"version":3,"file":"bind.d.ts","sourceRoot":"","sources":["../../../core/endpoints/bind.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAGrD,OAAO,KAAK,EACX,qBAAqB,EAErB,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,MAAM,YAAY,CAAC;AAMpB;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAE5D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CAAC,EACxC,SAAS,EACT,KAAK,EACL,GAAG,EACH,IAAI,EACJ,QAAQ,EACR,aAAa,EACb,WAAgB,EAChB,UAAU,EACV,iBAAiB,EACjB,YAAY,EACZ,QAAQ,EACR,cAAc,GACd,EAAE;IACF,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IAC3C,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,mBAAmB,CAAC;IACnC,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,UAAU,CAAC,EAAE,qBAAqB,CAAC;IACnC,mGAAmG;IACnG,iBAAiB,CAAC,EAAE;QACnB,IAAI,EAAE,cAAc,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;KAC7C,CAAC;IACF,sGAAsG;IACtG,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IACjD,gFAAgF;IAChF,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,qEAAqE;IACrE,cAAc,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC;CACpE,GAAG,IAAI,CAwJP"}
@@ -1,4 +1,5 @@
1
1
  import { handleCorsairError } from '../errors/handler';
2
+ import { enforcePermission, parseDurationMs } from '../permissions';
2
3
  // ─────────────────────────────────────────────────────────────────────────────
3
4
  // Endpoint Utilities
4
5
  // ─────────────────────────────────────────────────────────────────────────────
@@ -22,7 +23,7 @@ export function isEndpoint(value) {
22
23
  * @param currentPath - The current path for tracking nested endpoint operations
23
24
  * @param keyBuilder - Optional async callback to generate a key from the plugin context
24
25
  */
25
- export function bindEndpointsRecursively({ endpoints, hooks, ctx, tree, pluginId, errorHandlers, currentPath = [], keyBuilder, }) {
26
+ export function bindEndpointsRecursively({ endpoints, hooks, ctx, tree, pluginId, errorHandlers, currentPath = [], keyBuilder, permissionsConfig, endpointMeta, database, approvalConfig, }) {
26
27
  for (const [key, value] of Object.entries(endpoints)) {
27
28
  // we have to retype this now because it's nested webhooks
28
29
  const nodeHooks = hooks?.[key];
@@ -31,6 +32,26 @@ export function bindEndpointsRecursively({ endpoints, hooks, ctx, tree, pluginId
31
32
  const endpointHooks = nodeHooks;
32
33
  const operationPath = [...currentPath, key].join('.');
33
34
  const boundFn = async (args) => {
35
+ // ── Permission guard ────────────────────────────────────────────────────────────────
36
+ if (permissionsConfig) {
37
+ const meta = endpointMeta?.[operationPath];
38
+ const permResult = await enforcePermission({
39
+ pluginId,
40
+ endpointPath: operationPath,
41
+ args,
42
+ mode: permissionsConfig.mode,
43
+ override: permissionsConfig.overrides?.[operationPath],
44
+ // Default to 'write' when no meta declared — conservative fallback
45
+ riskLevel: meta?.riskLevel ?? 'write',
46
+ meta,
47
+ db: database,
48
+ timeoutMs: approvalConfig
49
+ ? parseDurationMs(approvalConfig.timeout)
50
+ : undefined,
51
+ });
52
+ if (permResult === 'blocked')
53
+ return null;
54
+ }
34
55
  const call = async (attemptNumber, callCtx, callArgs) => {
35
56
  try {
36
57
  return await value(callCtx, callArgs);
@@ -90,7 +111,12 @@ export function bindEndpointsRecursively({ endpoints, hooks, ctx, tree, pluginId
90
111
  const ctxWithKey = { ...ctx, key };
91
112
  const beforeResult = endpointHooks.before
92
113
  ? await endpointHooks.before(ctxWithKey, args)
93
- : { ctx: ctxWithKey, args, continue: true, passToAfter: undefined };
114
+ : {
115
+ ctx: ctxWithKey,
116
+ args,
117
+ continue: true,
118
+ passToAfter: undefined,
119
+ };
94
120
  if (beforeResult.continue === false)
95
121
  return;
96
122
  const res = await call(0, beforeResult.ctx, beforeResult.args);
@@ -112,6 +138,10 @@ export function bindEndpointsRecursively({ endpoints, hooks, ctx, tree, pluginId
112
138
  errorHandlers,
113
139
  currentPath: [...currentPath, key],
114
140
  keyBuilder,
141
+ permissionsConfig,
142
+ endpointMeta,
143
+ database,
144
+ approvalConfig,
115
145
  });
116
146
  tree[key] = nestedTree;
117
147
  }
@@ -72,5 +72,33 @@ export type EndpointTree = {
72
72
  export type BindEndpoints<T extends EndpointTree> = {
73
73
  [K in keyof T]: T[K] extends CorsairEndpoint<any, infer A, infer R> ? (args: A) => Promise<R> : T[K] extends EndpointTree ? BindEndpoints<T[K]> : never;
74
74
  };
75
+ /**
76
+ * Derives all dot-notation endpoint paths from an EndpointTree as a string literal union.
77
+ * Used to provide compile-time validation for permission overrides and endpoint metadata keys.
78
+ * Passing an invalid path to any config that accepts EndpointPathsOf<T> is a type error.
79
+ *
80
+ * Design note: The constraint on `T` is intentionally loosened to `object` (not `EndpointTree`)
81
+ * on the recursive call because `as const` endpoint trees have specific readonly literal keys —
82
+ * `{ readonly issues: { readonly list: fn } }` — which do NOT satisfy `EndpointTree`'s string
83
+ * index signature (`{ [key: string]: ... }`), even though the values are valid endpoints.
84
+ * If we recurse with `T extends EndpointTree`, TypeScript widens the subtypes and loses the
85
+ * literal keys we need. The outer-facing `PluginEndpointMeta<T extends EndpointTree>` and
86
+ * `PluginPermissionsConfig<T extends EndpointTree>` still enforce the EndpointTree constraint
87
+ * at the call site.
88
+ *
89
+ * Similarly, `T[K] extends Record<string, unknown>` fails for named-property objects without an
90
+ * index signature (a plain `{ list: fn }` does not satisfy `{ [key: string]: unknown }`), so we
91
+ * use `extends object` instead, which all non-primitive values satisfy.
92
+ *
93
+ * @example
94
+ * Given: `{ issues: { list: Endpoint, create: Endpoint }, repos: { list: Endpoint } }`
95
+ * Result: `'issues.list' | 'issues.create' | 'repos.list'`
96
+ *
97
+ * @template T - The endpoint tree to extract paths from (unconstrained to allow recursion through as-const types)
98
+ * @template Prefix - Internal accumulator for the current path prefix (do not supply manually)
99
+ */
100
+ export type EndpointPathsOf<T, Prefix extends string = ''> = {
101
+ [K in keyof T & string]: T[K] extends (...args: any[]) => any ? Prefix extends '' ? K : `${Prefix}.${K}` : T[K] extends object ? EndpointPathsOf<T[K], Prefix extends '' ? K : `${Prefix}.${K}`> : never;
102
+ }[keyof T & string];
75
103
  export {};
76
104
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../core/endpoints/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAMhE;;;;GAIG;AACH,KAAK,SAAS,CAAC,IAAI,SAAS,OAAO,EAAE,EAAE,CAAC,IAAI;IAC3C,cAAc,CAAC,GAAG,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC;CACjC,CAAC,gBAAgB,CAAC,CAAC;AAMpB;;;;GAIG;AACH,MAAM,MAAM,eAAe,CAAC,IAAI,GAAG,OAAO,EAAE,GAAG,GAAG,OAAO,IAAI,CAC5D,IAAI,EAAE,IAAI,KACN,OAAO,CAAC,GAAG,CAAC,CAAC;AAElB;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC/B,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,iBAAiB,CAAC;CACnD,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,cAAc,CACzB,SAAS,SAAS,iBAAiB,GAAG,iBAAiB,IACpD;IACH,yEAAyE;IACzE,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,iFAAiF;IACjF,SAAS,EAAE,SAAS,CAAC;CACrB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,eAAe,CAC1B,GAAG,SAAS,cAAc,GAAG,cAAc,EAC3C,IAAI,GAAG,OAAO,EACd,GAAG,GAAG,OAAO,IACV,SAAS,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;AAMpD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,MAAM,YAAY,GAAG;IAC1B,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,YAAY,CAAC;CAC7D,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,YAAY,IAAI;KAClD,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,GAChE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GACvB,CAAC,CAAC,CAAC,CAAC,SAAS,YAAY,GACxB,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GACnB,KAAK;CACT,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../core/endpoints/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAMhE;;;;GAIG;AACH,KAAK,SAAS,CAAC,IAAI,SAAS,OAAO,EAAE,EAAE,CAAC,IAAI;IAC3C,cAAc,CAAC,GAAG,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC;CACjC,CAAC,gBAAgB,CAAC,CAAC;AAMpB;;;;GAIG;AACH,MAAM,MAAM,eAAe,CAAC,IAAI,GAAG,OAAO,EAAE,GAAG,GAAG,OAAO,IAAI,CAC5D,IAAI,EAAE,IAAI,KACN,OAAO,CAAC,GAAG,CAAC,CAAC;AAElB;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC/B,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,iBAAiB,CAAC;CACnD,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,cAAc,CACzB,SAAS,SAAS,iBAAiB,GAAG,iBAAiB,IACpD;IACH,yEAAyE;IACzE,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,iFAAiF;IACjF,SAAS,EAAE,SAAS,CAAC;CACrB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,eAAe,CAC1B,GAAG,SAAS,cAAc,GAAG,cAAc,EAC3C,IAAI,GAAG,OAAO,EACd,GAAG,GAAG,OAAO,IACV,SAAS,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;AAMpD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,MAAM,YAAY,GAAG;IAC1B,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,YAAY,CAAC;CAC7D,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,YAAY,IAAI;KAClD,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,GAChE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GACvB,CAAC,CAAC,CAAC,CAAC,SAAS,YAAY,GACxB,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GACnB,KAAK;CACT,CAAC;AAMF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,MAAM,eAAe,CAAC,CAAC,EAAE,MAAM,SAAS,MAAM,GAAG,EAAE,IAAI;KAC3D,CAAC,IAAI,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,GAE3D,MAAM,SAAS,EAAE,GACf,CAAC,GACD,GAAG,MAAM,IAAI,CAAC,EAAE,GACjB,CAAC,CAAC,CAAC,CAAC,SAAS,MAAM,GAEnB,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,SAAS,EAAE,GAAG,CAAC,GAAG,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,GAC9D,KAAK;CACT,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC"}
@@ -7,6 +7,10 @@ export type CorsairInternalConfig = {
7
7
  database: CorsairDatabase | undefined;
8
8
  kek: string;
9
9
  multiTenancy: boolean;
10
+ approval?: {
11
+ timeout: string;
12
+ onTimeout: 'deny' | 'approve';
13
+ };
10
14
  };
11
15
  /**
12
16
  * Creates a Corsair integration with multi-tenancy enabled.
@@ -30,10 +34,12 @@ export declare function createCorsair<const Plugins extends readonly CorsairPlug
30
34
  export type { AccountFieldNames, AccountKeyManagerFor, BaseAuthFieldConfig, BaseKeyManager, IntegrationFieldNames, IntegrationKeyManagerFor, OAuth2IntegrationCredentials, PluginAuthConfig, } from './auth';
31
35
  export { BASE_AUTH_FIELDS, createAccountKeyManager, createIntegrationKeyManager, decryptConfig, decryptDEK, decryptWithDEK, encryptConfig, encryptDEK, encryptWithDEK, generateDEK, initializeAccountDEK, initializeIntegrationDEK, reEncryptConfig, } from './auth';
32
36
  export type { CorsairClient, CorsairSingleTenantClient, CorsairTenantWrapper, } from './client';
37
+ export type { CorsairInspectMethods, EndpointSchemaResult } from './inspect';
33
38
  export type { AllProviders, AuthTypes, BaseProviders } from './constants';
34
- export type { BindEndpoints, BoundEndpointFn, BoundEndpointTree, CorsairContext, CorsairEndpoint, EndpointTree, } from './endpoints';
39
+ export type { BindEndpoints, BoundEndpointFn, BoundEndpointTree, CorsairContext, CorsairEndpoint, EndpointPathsOf, EndpointTree, } from './endpoints';
35
40
  export type { CorsairErrorHandler, ErrorContext, ErrorHandler, ErrorHandlerAndMatchFunction, ErrorMatcher, RetryStrategies, RetryStrategy, } from './errors';
36
- export type { BeforeHookResult, CorsairIntegration, CorsairKeyBuilder, CorsairKeyBuilderBase, CorsairPlugin, CorsairPluginContext, EndpointHooks, KeyBuilderContext, WebhookHooks, } from './plugins';
41
+ export type { EnforcePermissionOptions } from './permissions';
42
+ export type { BeforeHookResult, CorsairIntegration, CorsairKeyBuilder, CorsairKeyBuilderBase, CorsairPlugin, CorsairPluginContext, EndpointHooks, EndpointMetaEntry, EndpointRiskLevel, KeyBuilderContext, PermissionMode, PermissionPolicy, PluginEndpointMeta, PluginPermissionsConfig, WebhookHooks, } from './plugins';
37
43
  export type { Bivariant, UnionToIntersection } from './utils';
38
44
  export type { BindWebhooks, BoundWebhook, BoundWebhookTree, CorsairWebhook, CorsairWebhookHandler, CorsairWebhookMatcher, RawWebhookRequest, WebhookRequest, WebhookResponse, WebhookTree, } from './webhooks';
39
45
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../core/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAG7D,OAAO,KAAK,EAAE,yBAAyB,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAEhF,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAMnE,eAAO,MAAM,gBAAgB,eAAiC,CAAC;AAE/D,MAAM,MAAM,qBAAqB,GAAG;IACnC,OAAO,EAAE,SAAS,aAAa,EAAE,CAAC;IAClC,QAAQ,EAAE,eAAe,GAAG,SAAS,CAAC;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,OAAO,CAAC;CACtB,CAAC;AAMF;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,CAAC,OAAO,SAAS,SAAS,aAAa,EAAE,EAC3E,MAAM,EAAE,kBAAkB,CAAC,OAAO,CAAC,GAAG;IAAE,YAAY,EAAE,IAAI,CAAA;CAAE,GAC1D,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAEjC;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,CAAC,OAAO,SAAS,SAAS,aAAa,EAAE,EAC3E,MAAM,EAAE,kBAAkB,CAAC,OAAO,CAAC,GAAG;IAAE,YAAY,CAAC,EAAE,KAAK,GAAG,SAAS,CAAA;CAAE,GACxE,yBAAyB,CAAC,OAAO,CAAC,CAAC;AAyEtC,YAAY,EACX,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,EACnB,cAAc,EACd,qBAAqB,EACrB,wBAAwB,EACxB,4BAA4B,EAC5B,gBAAgB,GAChB,MAAM,QAAQ,CAAC;AAEhB,OAAO,EACN,gBAAgB,EAChB,uBAAuB,EACvB,2BAA2B,EAC3B,aAAa,EACb,UAAU,EACV,cAAc,EACd,aAAa,EACb,UAAU,EACV,cAAc,EACd,WAAW,EACX,oBAAoB,EACpB,wBAAwB,EACxB,eAAe,GACf,MAAM,QAAQ,CAAC;AAEhB,YAAY,EACX,aAAa,EACb,yBAAyB,EACzB,oBAAoB,GACpB,MAAM,UAAU,CAAC;AAElB,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG1E,YAAY,EACX,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,YAAY,GACZ,MAAM,aAAa,CAAC;AAErB,YAAY,EACX,mBAAmB,EACnB,YAAY,EACZ,YAAY,EACZ,4BAA4B,EAC5B,YAAY,EACZ,eAAe,EACf,aAAa,GACb,MAAM,UAAU,CAAC;AAElB,YAAY,EACX,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,EACrB,aAAa,EACb,oBAAoB,EACpB,aAAa,EACb,iBAAiB,EACjB,YAAY,GACZ,MAAM,WAAW,CAAC;AAGnB,YAAY,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAE9D,YAAY,EACX,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,cAAc,EACd,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,WAAW,GACX,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../core/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAG7D,OAAO,KAAK,EAAE,yBAAyB,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAGhF,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAMnE,eAAO,MAAM,gBAAgB,eAAiC,CAAC;AAE/D,MAAM,MAAM,qBAAqB,GAAG;IACnC,OAAO,EAAE,SAAS,aAAa,EAAE,CAAC;IAClC,QAAQ,EAAE,eAAe,GAAG,SAAS,CAAC;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE;QACV,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;KAC9B,CAAC;CACF,CAAC;AAMF;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,CAAC,OAAO,SAAS,SAAS,aAAa,EAAE,EAC3E,MAAM,EAAE,kBAAkB,CAAC,OAAO,CAAC,GAAG;IAAE,YAAY,EAAE,IAAI,CAAA;CAAE,GAC1D,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAEjC;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,CAAC,OAAO,SAAS,SAAS,aAAa,EAAE,EAC3E,MAAM,EAAE,kBAAkB,CAAC,OAAO,CAAC,GAAG;IAAE,YAAY,CAAC,EAAE,KAAK,GAAG,SAAS,CAAA;CAAE,GACxE,yBAAyB,CAAC,OAAO,CAAC,CAAC;AA6EtC,YAAY,EACX,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,EACnB,cAAc,EACd,qBAAqB,EACrB,wBAAwB,EACxB,4BAA4B,EAC5B,gBAAgB,GAChB,MAAM,QAAQ,CAAC;AAEhB,OAAO,EACN,gBAAgB,EAChB,uBAAuB,EACvB,2BAA2B,EAC3B,aAAa,EACb,UAAU,EACV,cAAc,EACd,aAAa,EACb,UAAU,EACV,cAAc,EACd,WAAW,EACX,oBAAoB,EACpB,wBAAwB,EACxB,eAAe,GACf,MAAM,QAAQ,CAAC;AAEhB,YAAY,EACX,aAAa,EACb,yBAAyB,EACzB,oBAAoB,GACpB,MAAM,UAAU,CAAC;AAElB,YAAY,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAE7E,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG1E,YAAY,EACX,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,eAAe,EACf,YAAY,GACZ,MAAM,aAAa,CAAC;AAErB,YAAY,EACX,mBAAmB,EACnB,YAAY,EACZ,YAAY,EACZ,4BAA4B,EAC5B,YAAY,EACZ,eAAe,EACf,aAAa,GACb,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAG9D,YAAY,EACX,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,EACrB,aAAa,EACb,oBAAoB,EACpB,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,EACvB,YAAY,GACZ,MAAM,WAAW,CAAC;AAGnB,YAAY,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAE9D,YAAY,EACX,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,cAAc,EACd,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,WAAW,GACX,MAAM,YAAY,CAAC"}
@@ -1,6 +1,7 @@
1
1
  import { createCorsairDatabase } from '../db/kysely/database';
2
2
  import { createMissingConfigProxy } from './auth/errors';
3
3
  import { buildCorsairClient, buildIntegrationKeys } from './client';
4
+ import { buildInspectMethods } from './inspect';
4
5
  // ─────────────────────────────────────────────────────────────────────────────
5
6
  // Internal access for CLI tooling
6
7
  // ─────────────────────────────────────────────────────────────────────────────
@@ -23,6 +24,7 @@ export function createCorsair(config) {
23
24
  database: resolvedDatabase,
24
25
  kek: config.kek,
25
26
  multiTenancy: !!config.multiTenancy,
27
+ approval: config.approval,
26
28
  };
27
29
  if (config.multiTenancy) {
28
30
  return Object.assign({
@@ -35,9 +37,11 @@ export function createCorsair(config) {
35
37
  tenantId,
36
38
  kek: config.kek,
37
39
  rootErrorHandlers: config.errorHandlers,
40
+ approvalConfig: config.approval,
38
41
  });
39
42
  },
40
43
  keys: integrationKeys,
44
+ ...buildInspectMethods(config.plugins),
41
45
  }, { [CORSAIR_INTERNAL]: internalConfig });
42
46
  }
43
47
  const client = buildCorsairClient(config.plugins, {
@@ -45,6 +49,7 @@ export function createCorsair(config) {
45
49
  tenantId: undefined,
46
50
  kek: config.kek,
47
51
  rootErrorHandlers: config.errorHandlers,
52
+ approvalConfig: config.approval,
48
53
  });
49
54
  return Object.assign({}, client, {
50
55
  keys: integrationKeys,
@@ -0,0 +1,57 @@
1
+ import type { CorsairPlugin } from '../plugins';
2
+ export type EndpointSchemaResult = {
3
+ /** Human-readable description of what this endpoint does. */
4
+ description?: string;
5
+ /** Risk classification: 'read' | 'write' | 'destructive' */
6
+ riskLevel?: 'read' | 'write' | 'destructive';
7
+ /** Whether this action cannot be undone. */
8
+ irreversible?: boolean;
9
+ /** JSON Schema representation of the input arguments object. */
10
+ input?: unknown;
11
+ /** JSON Schema representation of the response object. */
12
+ output?: unknown;
13
+ /**
14
+ * Present when the requested method was not found.
15
+ * Lists all available full-form paths so the caller can pick a valid one.
16
+ */
17
+ availableMethods?: Record<string, string[]>;
18
+ };
19
+ export type CorsairInspectMethods = {
20
+ /**
21
+ * Returns all available endpoint paths for every registered plugin.
22
+ * Keys are plugin IDs, values are arrays of full-form paths (plugin.group.method).
23
+ *
24
+ * @example
25
+ * corsair.get_methods()
26
+ * // { slack: ['slack.channels.list', 'slack.messages.post', ...], github: ['github.issues.list', ...] }
27
+ */
28
+ get_methods(): Record<string, string[]>;
29
+ /**
30
+ * Returns all available endpoint paths for a specific plugin.
31
+ * Paths are full-form (plugin.group.method) so they can be passed directly to get_schema().
32
+ *
33
+ * @example
34
+ * corsair.get_methods('slack')
35
+ * // ['slack.channels.list', 'slack.channels.get', 'slack.messages.post', ...]
36
+ */
37
+ get_methods(plugin: string): string[];
38
+ /**
39
+ * Returns schema and metadata for a specific endpoint.
40
+ * Pass the full dot-path including the plugin ID: 'slack.channels.list'.
41
+ * If the method is not found, returns an empty result with `availableMethods` listing all valid paths.
42
+ *
43
+ * @example
44
+ * corsair.get_schema('slack.channels.list')
45
+ * // { description: '...', riskLevel: 'read', input: { type: 'object', ... }, output: { ... } }
46
+ *
47
+ * corsair.get_schema('slack.invalid')
48
+ * // { availableMethods: { slack: ['slack.channels.list', ...], ... } }
49
+ */
50
+ get_schema(method: string): EndpointSchemaResult;
51
+ };
52
+ /**
53
+ * Creates the get_methods / get_schema functions bound to a specific plugin list.
54
+ * Used by both single-tenant and multi-tenant client builders.
55
+ */
56
+ export declare function buildInspectMethods(plugins: readonly CorsairPlugin[]): CorsairInspectMethods;
57
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../core/inspect/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAqB,MAAM,YAAY,CAAC;AAqFnE,MAAM,MAAM,oBAAoB,GAAG;IAClC,6DAA6D;IAC7D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,aAAa,CAAC;IAC7C,4CAA4C;IAC5C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gEAAgE;IAChE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,yDAAyD;IACzD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IACnC;;;;;;;OAOG;IACH,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACxC;;;;;;;OAOG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACtC;;;;;;;;;;;OAWG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,oBAAoB,CAAC;CACjD,CAAC;AAmFF;;;GAGG;AACH,wBAAgB,mBAAmB,CAClC,OAAO,EAAE,SAAS,aAAa,EAAE,GAC/B,qBAAqB,CASvB"}
@@ -0,0 +1,150 @@
1
+ // ─────────────────────────────────────────────────────────────────────────────
2
+ // Zod → JSON Schema Converter
3
+ // ─────────────────────────────────────────────────────────────────────────────
4
+ /**
5
+ * Converts a Zod schema to a plain JSON Schema-compatible object.
6
+ * Used to produce human-readable type information for get_schema().
7
+ */
8
+ function zodToJsonSchema(schema) {
9
+ // Access Zod internals via a generic cast — avoids importing internal Zod types
10
+ const def = schema._def;
11
+ const typeName = def.typeName;
12
+ switch (typeName) {
13
+ case 'ZodString':
14
+ return { type: 'string' };
15
+ case 'ZodNumber':
16
+ return { type: 'number' };
17
+ case 'ZodBoolean':
18
+ return { type: 'boolean' };
19
+ case 'ZodNull':
20
+ return { type: 'null' };
21
+ case 'ZodUnknown':
22
+ case 'ZodAny':
23
+ return {};
24
+ case 'ZodLiteral':
25
+ return { const: def.value };
26
+ case 'ZodEnum':
27
+ return { enum: def.values };
28
+ case 'ZodOptional':
29
+ // Optional is reflected in the parent object's required[] array, not here
30
+ return zodToJsonSchema(def.innerType);
31
+ case 'ZodNullable': {
32
+ const inner = zodToJsonSchema(def.innerType);
33
+ return { anyOf: [inner, { type: 'null' }] };
34
+ }
35
+ case 'ZodArray':
36
+ return { type: 'array', items: zodToJsonSchema(def.type) };
37
+ case 'ZodRecord':
38
+ return {
39
+ type: 'object',
40
+ additionalProperties: zodToJsonSchema(def.valueType),
41
+ };
42
+ case 'ZodObject': {
43
+ const shape = def.shape();
44
+ const properties = {};
45
+ const required = [];
46
+ for (const [key, val] of Object.entries(shape)) {
47
+ properties[key] = zodToJsonSchema(val);
48
+ const fieldTypeName = val._def.typeName;
49
+ if (fieldTypeName !== 'ZodOptional' && fieldTypeName !== 'ZodNullable') {
50
+ required.push(key);
51
+ }
52
+ }
53
+ const result = { type: 'object', properties };
54
+ if (required.length > 0)
55
+ result.required = required;
56
+ return result;
57
+ }
58
+ case 'ZodUnion':
59
+ return { anyOf: def.options.map(zodToJsonSchema) };
60
+ case 'ZodIntersection':
61
+ return {
62
+ allOf: [
63
+ zodToJsonSchema(def.left),
64
+ zodToJsonSchema(def.right),
65
+ ],
66
+ };
67
+ case 'ZodEffects':
68
+ // .refine(), .transform(), etc. — unwrap to the inner schema
69
+ return zodToJsonSchema(def.schema);
70
+ default:
71
+ return { type: (typeName ?? 'unknown').replace('Zod', '').toLowerCase() };
72
+ }
73
+ }
74
+ // ─────────────────────────────────────────────────────────────────────────────
75
+ // Endpoint Tree Walker
76
+ // ─────────────────────────────────────────────────────────────────────────────
77
+ function walkEndpointTree(tree, pathParts, result) {
78
+ for (const [key, value] of Object.entries(tree)) {
79
+ const current = [...pathParts, key];
80
+ if (typeof value === 'function') {
81
+ result.push(current.join('.'));
82
+ }
83
+ else if (value !== null && typeof value === 'object') {
84
+ walkEndpointTree(value, current, result);
85
+ }
86
+ }
87
+ }
88
+ // ─────────────────────────────────────────────────────────────────────────────
89
+ // Core Functions
90
+ // ─────────────────────────────────────────────────────────────────────────────
91
+ function getMethods(plugins, plugin) {
92
+ if (plugin !== undefined) {
93
+ const found = plugins.find((p) => p.id === plugin);
94
+ if (!found?.endpoints)
95
+ return [];
96
+ const paths = [];
97
+ walkEndpointTree(found.endpoints, [], paths);
98
+ return paths.map((path) => `${found.id}.${path}`);
99
+ }
100
+ const result = {};
101
+ for (const p of plugins) {
102
+ if (!p.endpoints)
103
+ continue;
104
+ const paths = [];
105
+ walkEndpointTree(p.endpoints, [], paths);
106
+ result[p.id] = paths.map((path) => `${p.id}.${path}`);
107
+ }
108
+ return result;
109
+ }
110
+ function getSchema(plugins, method) {
111
+ const dotIndex = method.indexOf('.');
112
+ if (dotIndex !== -1) {
113
+ const pluginId = method.slice(0, dotIndex);
114
+ const endpointPath = method.slice(dotIndex + 1);
115
+ const plugin = plugins.find((p) => p.id === pluginId);
116
+ if (plugin) {
117
+ const meta = plugin.endpointMeta?.[endpointPath];
118
+ const schemas = plugin.endpointSchemas?.[endpointPath];
119
+ // Valid entry — meta or schemas found
120
+ if (meta || schemas) {
121
+ return {
122
+ description: meta?.description,
123
+ riskLevel: meta?.riskLevel,
124
+ irreversible: meta?.irreversible,
125
+ input: schemas?.input ? zodToJsonSchema(schemas.input) : undefined,
126
+ output: schemas?.output ? zodToJsonSchema(schemas.output) : undefined,
127
+ };
128
+ }
129
+ }
130
+ }
131
+ // Invalid or unknown method — return all available methods so the caller can self-correct
132
+ return { availableMethods: getMethods(plugins) };
133
+ }
134
+ // ─────────────────────────────────────────────────────────────────────────────
135
+ // Factory — binds inspect methods to a fixed plugin list
136
+ // ─────────────────────────────────────────────────────────────────────────────
137
+ /**
138
+ * Creates the get_methods / get_schema functions bound to a specific plugin list.
139
+ * Used by both single-tenant and multi-tenant client builders.
140
+ */
141
+ export function buildInspectMethods(plugins) {
142
+ return {
143
+ get_methods(plugin) {
144
+ return getMethods(plugins, plugin);
145
+ },
146
+ get_schema(method) {
147
+ return getSchema(plugins, method);
148
+ },
149
+ };
150
+ }
@@ -0,0 +1,29 @@
1
+ import type { CorsairDatabase } from '../../db/kysely/database';
2
+ import type { EndpointMetaEntry, EndpointRiskLevel, PermissionMode, PermissionPolicy } from '../plugins';
3
+ /** Resolves the effective permission policy for an endpoint. The override (from permissions.overrides) takes precedence. */
4
+ export declare function evaluatePermission(riskLevel: EndpointRiskLevel, mode: PermissionMode, override?: PermissionPolicy): PermissionPolicy;
5
+ /** Parses a duration string ('30s', '10m', '1h', '2h30m', '1d') into milliseconds. */
6
+ export declare function parseDurationMs(duration: string): number;
7
+ export type EnforcePermissionOptions = {
8
+ pluginId: string;
9
+ endpointPath: string;
10
+ /** unknown: caller-supplied args vary per endpoint — not statically knowable here */
11
+ args: unknown;
12
+ mode: PermissionMode;
13
+ override?: PermissionPolicy;
14
+ riskLevel: EndpointRiskLevel;
15
+ meta?: EndpointMetaEntry;
16
+ /** Required to create an approval record. Without a DB, 'require_approval' falls back to deny. */
17
+ db?: CorsairDatabase;
18
+ timeoutMs?: number;
19
+ };
20
+ /**
21
+ * Evaluates the permission policy and returns whether the action is allowed.
22
+ *
23
+ * - `'allow'` → returns 'allow', caller proceeds normally
24
+ * - `'deny'` → logs a blocked message, returns 'blocked'
25
+ * - `'require_approval'` → creates a `corsair_permissions` record, logs the token, returns 'blocked'
26
+ * (falls back to deny if no database is configured)
27
+ */
28
+ export declare function enforcePermission(opts: EnforcePermissionOptions): Promise<'allow' | 'blocked'>;
29
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../core/permissions/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,KAAK,EACX,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,MAAM,YAAY,CAAC;AAgBpB,4HAA4H;AAC5H,wBAAgB,kBAAkB,CACjC,SAAS,EAAE,iBAAiB,EAC5B,IAAI,EAAE,cAAc,EACpB,QAAQ,CAAC,EAAE,gBAAgB,GACzB,gBAAgB,CAGlB;AAMD,sFAAsF;AACtF,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAsBxD;AAMD,MAAM,MAAM,wBAAwB,GAAG;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,qFAAqF;IACrF,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,cAAc,CAAC;IACrB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,SAAS,EAAE,iBAAiB,CAAC;IAC7B,IAAI,CAAC,EAAE,iBAAiB,CAAC;IACzB,kGAAkG;IAClG,EAAE,CAAC,EAAE,eAAe,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACtC,IAAI,EAAE,wBAAwB,GAC5B,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAkD9B"}