@vercel/connect 0.2.9 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -2
- package/dist/chat/github-adapter.d.ts +43 -0
- package/dist/chat/github-adapter.js +39 -0
- package/dist/chat/index.d.ts +27 -0
- package/dist/chat/index.js +26 -0
- package/dist/chat/linear-adapter.d.ts +40 -0
- package/dist/chat/linear-adapter.js +37 -0
- package/dist/chat/slack-adapter.d.ts +52 -0
- package/dist/chat/slack-adapter.js +39 -0
- package/dist/chat/types.d.ts +28 -0
- package/dist/chat/types.js +1 -0
- package/dist/chat/webhook-verifier.d.ts +51 -0
- package/dist/chat/webhook-verifier.js +47 -0
- package/dist/eve/connection-authorization.d.ts +19 -2
- package/dist/eve/connection-authorization.js +43 -18
- package/dist/eve/provision-oauth-connector.d.ts +9 -0
- package/dist/eve/provision-oauth-connector.js +96 -0
- package/package.json +11 -2
package/README.md
CHANGED
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
SDK for obtaining scoped tokens for third-party services on behalf of apps or users. Authenticates the calling Vercel project via [`@vercel/oidc`](https://www.npmjs.com/package/@vercel/oidc) and exchanges the OIDC token for a Vercel Connect-issued credential.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Seven entrypoints, all ESM:
|
|
6
6
|
|
|
7
7
|
- `@vercel/connect` — core token / authorization SDK
|
|
8
|
+
- `@vercel/connect/chat` — adapter helpers for the [Chat SDK](https://chat-sdk.dev) (`chat`): `connectSlackAdapter`, `connectGitHubAdapter`, `connectLinearAdapter` (no Chat SDK dependency — returns structural config)
|
|
8
9
|
- `@vercel/connect/ai-sdk` — [Vercel AI SDK](https://ai-sdk.dev) glue: re-exports `connectAuthProvider` for MCP transports (optional peers: `ai`, `@ai-sdk/mcp`)
|
|
9
10
|
- `@vercel/connect/mcp` — canonical MCP-spec `OAuthClientProvider` for any MCP client (optional peer: `@ai-sdk/mcp`)
|
|
10
11
|
- `@vercel/connect/eve` — adapter helpers for [Eve](https://github.com/vercel/eve) connections (optional peer: `eve`)
|
|
@@ -29,6 +30,27 @@ const token = await getToken(process.env.CONNECTOR_LINEAR!, {
|
|
|
29
30
|
});
|
|
30
31
|
```
|
|
31
32
|
|
|
33
|
+
### Chat SDK
|
|
34
|
+
|
|
35
|
+
Spread the helper into the matching `create*Adapter` factory. Each helper
|
|
36
|
+
wires both outbound app-scoped tokens and inbound Connect trigger-forwarded
|
|
37
|
+
webhook verification (Vercel OIDC), so no provider secret lives in your env.
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
import { createSlackAdapter } from '@chat-adapter/slack';
|
|
41
|
+
import { connectSlackAdapter } from '@vercel/connect/chat';
|
|
42
|
+
|
|
43
|
+
createSlackAdapter({
|
|
44
|
+
...connectSlackAdapter('slack/acme-slack'),
|
|
45
|
+
userName: 'my-bot',
|
|
46
|
+
});
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
`connectGitHubAdapter` (`installationToken`) and `connectLinearAdapter`
|
|
50
|
+
(`accessToken`) follow the same shape. See the
|
|
51
|
+
[Chat SDK integration guide](https://github.com/vercel/vercel/blob/main/packages/connect/docs/chat-integration.md)
|
|
52
|
+
for connector setup, trigger forwarding, and per-platform examples.
|
|
53
|
+
|
|
32
54
|
### Vercel AI SDK + MCP
|
|
33
55
|
|
|
34
56
|
```ts
|
|
@@ -68,7 +90,7 @@ SDK's `toolApproval` option or `wrapMcpTools` from `@ai-sdk/policy-opa`.
|
|
|
68
90
|
Non-AI-SDK MCP clients (the official MCP TypeScript SDK, Mastra, etc.)
|
|
69
91
|
can import the same `connectAuthProvider` from `@vercel/connect/mcp`.
|
|
70
92
|
|
|
71
|
-
###
|
|
93
|
+
### eve
|
|
72
94
|
|
|
73
95
|
```ts
|
|
74
96
|
import { defineMcpClientConnection } from 'eve/connections';
|
|
@@ -80,6 +102,10 @@ export default defineMcpClientConnection({
|
|
|
80
102
|
});
|
|
81
103
|
```
|
|
82
104
|
|
|
105
|
+
By default, `connect()` provisions or links the connector for the deploying
|
|
106
|
+
Vercel project on first use. Pass `autoProvision: false` when the connector is
|
|
107
|
+
managed elsewhere.
|
|
108
|
+
|
|
83
109
|
### Better Auth
|
|
84
110
|
|
|
85
111
|
```ts
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { type ConnectOptions, type ConnectTokenParams } from '../index.js';
|
|
2
|
+
import type { ConnectGitHubAdapterConfig } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Token parameters accepted by {@link connectGitHubAdapter}.
|
|
5
|
+
*
|
|
6
|
+
* Mirrors {@link ConnectTokenParams} from `@vercel/connect`, minus
|
|
7
|
+
* `subject` — the helper acts as the application itself, so `subject`
|
|
8
|
+
* is pinned to `{ type: "app" }` and cannot be overridden. (The issued
|
|
9
|
+
* GitHub credential is an installation-scoped access token.)
|
|
10
|
+
*/
|
|
11
|
+
export type ConnectGitHubAdapterParams = Omit<ConnectTokenParams, 'subject'>;
|
|
12
|
+
/**
|
|
13
|
+
* Build a GitHub adapter config fragment backed by a Vercel Connect
|
|
14
|
+
* connector that stores a GitHub installation access token.
|
|
15
|
+
*
|
|
16
|
+
* Spread the result into `createGitHubAdapter` from
|
|
17
|
+
* `@chat-adapter/github`:
|
|
18
|
+
*
|
|
19
|
+
* ```ts
|
|
20
|
+
* import { createGitHubAdapter } from "@chat-adapter/github";
|
|
21
|
+
* import { connectGitHubAdapter } from "@vercel/connect/chat";
|
|
22
|
+
*
|
|
23
|
+
* createGitHubAdapter({
|
|
24
|
+
* ...connectGitHubAdapter("github/acme-github"),
|
|
25
|
+
* userName: "my-bot[bot]",
|
|
26
|
+
* });
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* The returned `installationToken` is the installation access token a
|
|
30
|
+
* GitHub App would normally mint via its private-key JWT exchange — the
|
|
31
|
+
* adapter uses it directly and skips that exchange. The token is a
|
|
32
|
+
* function form so rotation, refresh, and installation tenancy stay
|
|
33
|
+
* delegated to Vercel Connect.
|
|
34
|
+
*
|
|
35
|
+
* `webhookVerifier` validates Connect trigger-forwarded webhooks via the
|
|
36
|
+
* Vercel OIDC token Connect attaches, replacing GitHub's webhook-secret
|
|
37
|
+
* check.
|
|
38
|
+
*
|
|
39
|
+
* The optional `params` and `options` arguments mirror the signature of
|
|
40
|
+
* {@link getToken}, allowing callers to pass through fields like
|
|
41
|
+
* `installationId`, `scopes`, or `validityBufferMs`.
|
|
42
|
+
*/
|
|
43
|
+
export declare function connectGitHubAdapter(connector: string, params?: ConnectGitHubAdapterParams, options?: ConnectOptions): ConnectGitHubAdapterConfig;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { getToken, } from '../index.js';
|
|
2
|
+
import { createConnectWebhookVerifier } from './webhook-verifier.js';
|
|
3
|
+
/**
|
|
4
|
+
* Build a GitHub adapter config fragment backed by a Vercel Connect
|
|
5
|
+
* connector that stores a GitHub installation access token.
|
|
6
|
+
*
|
|
7
|
+
* Spread the result into `createGitHubAdapter` from
|
|
8
|
+
* `@chat-adapter/github`:
|
|
9
|
+
*
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { createGitHubAdapter } from "@chat-adapter/github";
|
|
12
|
+
* import { connectGitHubAdapter } from "@vercel/connect/chat";
|
|
13
|
+
*
|
|
14
|
+
* createGitHubAdapter({
|
|
15
|
+
* ...connectGitHubAdapter("github/acme-github"),
|
|
16
|
+
* userName: "my-bot[bot]",
|
|
17
|
+
* });
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* The returned `installationToken` is the installation access token a
|
|
21
|
+
* GitHub App would normally mint via its private-key JWT exchange — the
|
|
22
|
+
* adapter uses it directly and skips that exchange. The token is a
|
|
23
|
+
* function form so rotation, refresh, and installation tenancy stay
|
|
24
|
+
* delegated to Vercel Connect.
|
|
25
|
+
*
|
|
26
|
+
* `webhookVerifier` validates Connect trigger-forwarded webhooks via the
|
|
27
|
+
* Vercel OIDC token Connect attaches, replacing GitHub's webhook-secret
|
|
28
|
+
* check.
|
|
29
|
+
*
|
|
30
|
+
* The optional `params` and `options` arguments mirror the signature of
|
|
31
|
+
* {@link getToken}, allowing callers to pass through fields like
|
|
32
|
+
* `installationId`, `scopes`, or `validityBufferMs`.
|
|
33
|
+
*/
|
|
34
|
+
export function connectGitHubAdapter(connector, params = {}, options) {
|
|
35
|
+
return {
|
|
36
|
+
installationToken: () => getToken(connector, { ...params, subject: { type: 'app' } }, options),
|
|
37
|
+
webhookVerifier: createConnectWebhookVerifier(),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public surface of the `@vercel/connect/chat` subpath.
|
|
3
|
+
*
|
|
4
|
+
* Holds helpers that adapt the Vercel Connect SDK to the Chat SDK
|
|
5
|
+
* (`chat`) platform adapters. Each helper returns a config fragment you
|
|
6
|
+
* spread into the matching `create*Adapter` factory, wiring a Connect
|
|
7
|
+
* connector for both outbound tokens (`getToken`) and inbound
|
|
8
|
+
* trigger-forwarded webhooks (Vercel OIDC verification).
|
|
9
|
+
*
|
|
10
|
+
* The helpers stay decoupled from `@chat-adapter/*`: they return
|
|
11
|
+
* structural config types rather than importing the adapter packages,
|
|
12
|
+
* so this subpath has no Chat SDK dependency.
|
|
13
|
+
*
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { createSlackAdapter } from "@chat-adapter/slack";
|
|
16
|
+
* import { connectSlackAdapter } from "@vercel/connect/chat";
|
|
17
|
+
*
|
|
18
|
+
* createSlackAdapter({
|
|
19
|
+
* ...connectSlackAdapter("slack/acme-slack"),
|
|
20
|
+
* });
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export { createConnectWebhookVerifier, type ConnectWebhookVerifier, type ConnectWebhookVerifierOptions, } from './webhook-verifier.js';
|
|
24
|
+
export type { ConnectGitHubAdapterConfig, ConnectLinearAdapterConfig, ConnectTokenResolver, } from './types.js';
|
|
25
|
+
export { connectSlackAdapter, type ConnectSlackAdapterConfig, type ConnectSlackAdapterParams, } from './slack-adapter.js';
|
|
26
|
+
export { connectGitHubAdapter, type ConnectGitHubAdapterParams, } from './github-adapter.js';
|
|
27
|
+
export { connectLinearAdapter, type ConnectLinearAdapterParams, } from './linear-adapter.js';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public surface of the `@vercel/connect/chat` subpath.
|
|
3
|
+
*
|
|
4
|
+
* Holds helpers that adapt the Vercel Connect SDK to the Chat SDK
|
|
5
|
+
* (`chat`) platform adapters. Each helper returns a config fragment you
|
|
6
|
+
* spread into the matching `create*Adapter` factory, wiring a Connect
|
|
7
|
+
* connector for both outbound tokens (`getToken`) and inbound
|
|
8
|
+
* trigger-forwarded webhooks (Vercel OIDC verification).
|
|
9
|
+
*
|
|
10
|
+
* The helpers stay decoupled from `@chat-adapter/*`: they return
|
|
11
|
+
* structural config types rather than importing the adapter packages,
|
|
12
|
+
* so this subpath has no Chat SDK dependency.
|
|
13
|
+
*
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { createSlackAdapter } from "@chat-adapter/slack";
|
|
16
|
+
* import { connectSlackAdapter } from "@vercel/connect/chat";
|
|
17
|
+
*
|
|
18
|
+
* createSlackAdapter({
|
|
19
|
+
* ...connectSlackAdapter("slack/acme-slack"),
|
|
20
|
+
* });
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export { createConnectWebhookVerifier, } from './webhook-verifier.js';
|
|
24
|
+
export { connectSlackAdapter, } from './slack-adapter.js';
|
|
25
|
+
export { connectGitHubAdapter, } from './github-adapter.js';
|
|
26
|
+
export { connectLinearAdapter, } from './linear-adapter.js';
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type ConnectOptions, type ConnectTokenParams } from '../index.js';
|
|
2
|
+
import type { ConnectLinearAdapterConfig } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Token parameters accepted by {@link connectLinearAdapter}.
|
|
5
|
+
*
|
|
6
|
+
* Mirrors {@link ConnectTokenParams} from `@vercel/connect`, minus
|
|
7
|
+
* `subject` — Linear app tokens are app-scoped, so `subject` is pinned
|
|
8
|
+
* to `{ type: "app" }` by this helper and cannot be overridden.
|
|
9
|
+
*/
|
|
10
|
+
export type ConnectLinearAdapterParams = Omit<ConnectTokenParams, 'subject'>;
|
|
11
|
+
/**
|
|
12
|
+
* Build a Linear adapter config fragment backed by a Vercel Connect
|
|
13
|
+
* connector that stores a Linear app access token.
|
|
14
|
+
*
|
|
15
|
+
* Spread the result into `createLinearAdapter` from
|
|
16
|
+
* `@chat-adapter/linear`:
|
|
17
|
+
*
|
|
18
|
+
* ```ts
|
|
19
|
+
* import { createLinearAdapter } from "@chat-adapter/linear";
|
|
20
|
+
* import { connectLinearAdapter } from "@vercel/connect/chat";
|
|
21
|
+
*
|
|
22
|
+
* createLinearAdapter({
|
|
23
|
+
* ...connectLinearAdapter("linear/acme-linear"),
|
|
24
|
+
* mode: "agent-sessions",
|
|
25
|
+
* });
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* The returned `accessToken` is the token the adapter uses for Linear
|
|
29
|
+
* GraphQL calls. It is a function form so rotation, refresh, and
|
|
30
|
+
* multi-workspace tenancy stay delegated to Vercel Connect.
|
|
31
|
+
*
|
|
32
|
+
* `webhookVerifier` validates Connect trigger-forwarded webhooks via the
|
|
33
|
+
* Vercel OIDC token Connect attaches, replacing Linear's
|
|
34
|
+
* webhook-secret check.
|
|
35
|
+
*
|
|
36
|
+
* The optional `params` and `options` arguments mirror the signature of
|
|
37
|
+
* {@link getToken}, allowing callers to pass through fields like
|
|
38
|
+
* `installationId`, `scopes`, or `validityBufferMs`.
|
|
39
|
+
*/
|
|
40
|
+
export declare function connectLinearAdapter(connector: string, params?: ConnectLinearAdapterParams, options?: ConnectOptions): ConnectLinearAdapterConfig;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { getToken, } from '../index.js';
|
|
2
|
+
import { createConnectWebhookVerifier } from './webhook-verifier.js';
|
|
3
|
+
/**
|
|
4
|
+
* Build a Linear adapter config fragment backed by a Vercel Connect
|
|
5
|
+
* connector that stores a Linear app access token.
|
|
6
|
+
*
|
|
7
|
+
* Spread the result into `createLinearAdapter` from
|
|
8
|
+
* `@chat-adapter/linear`:
|
|
9
|
+
*
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { createLinearAdapter } from "@chat-adapter/linear";
|
|
12
|
+
* import { connectLinearAdapter } from "@vercel/connect/chat";
|
|
13
|
+
*
|
|
14
|
+
* createLinearAdapter({
|
|
15
|
+
* ...connectLinearAdapter("linear/acme-linear"),
|
|
16
|
+
* mode: "agent-sessions",
|
|
17
|
+
* });
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* The returned `accessToken` is the token the adapter uses for Linear
|
|
21
|
+
* GraphQL calls. It is a function form so rotation, refresh, and
|
|
22
|
+
* multi-workspace tenancy stay delegated to Vercel Connect.
|
|
23
|
+
*
|
|
24
|
+
* `webhookVerifier` validates Connect trigger-forwarded webhooks via the
|
|
25
|
+
* Vercel OIDC token Connect attaches, replacing Linear's
|
|
26
|
+
* webhook-secret check.
|
|
27
|
+
*
|
|
28
|
+
* The optional `params` and `options` arguments mirror the signature of
|
|
29
|
+
* {@link getToken}, allowing callers to pass through fields like
|
|
30
|
+
* `installationId`, `scopes`, or `validityBufferMs`.
|
|
31
|
+
*/
|
|
32
|
+
export function connectLinearAdapter(connector, params = {}, options) {
|
|
33
|
+
return {
|
|
34
|
+
accessToken: () => getToken(connector, { ...params, subject: { type: 'app' } }, options),
|
|
35
|
+
webhookVerifier: createConnectWebhookVerifier(),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { SlackAdapterConfig } from '@chat-adapter/slack';
|
|
2
|
+
import { type ConnectOptions, type ConnectTokenParams } from '../index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Token parameters accepted by {@link connectSlackAdapter}.
|
|
5
|
+
*
|
|
6
|
+
* Mirrors {@link ConnectTokenParams} from `@vercel/connect`, minus
|
|
7
|
+
* `subject` — Slack bot tokens are always app-scoped, so `subject`
|
|
8
|
+
* is pinned to `{ type: "app" }` by this helper and cannot be
|
|
9
|
+
* overridden.
|
|
10
|
+
*/
|
|
11
|
+
export type ConnectSlackAdapterParams = Omit<ConnectTokenParams, 'subject'>;
|
|
12
|
+
/**
|
|
13
|
+
* Slack adapter config fragment produced by {@link connectSlackAdapter}.
|
|
14
|
+
*
|
|
15
|
+
* Derived from `@chat-adapter/slack`'s `SlackAdapterConfig` so the helper's
|
|
16
|
+
* output is type-checked against the real adapter config at compile time.
|
|
17
|
+
* `@chat-adapter/slack` is an optional peer dependency used for types only —
|
|
18
|
+
* there is no runtime dependency on the Chat SDK.
|
|
19
|
+
*/
|
|
20
|
+
export type ConnectSlackAdapterConfig = Required<Pick<SlackAdapterConfig, 'botToken' | 'webhookVerifier'>>;
|
|
21
|
+
/**
|
|
22
|
+
* Build a Slack adapter config fragment backed by a Vercel Connect
|
|
23
|
+
* connector that stores a Slack workspace's bot token.
|
|
24
|
+
*
|
|
25
|
+
* Spread the result into `createSlackAdapter` from `@chat-adapter/slack`:
|
|
26
|
+
*
|
|
27
|
+
* ```ts
|
|
28
|
+
* import { createSlackAdapter } from "@chat-adapter/slack";
|
|
29
|
+
* import { connectSlackAdapter } from "@vercel/connect/chat";
|
|
30
|
+
*
|
|
31
|
+
* createSlackAdapter({
|
|
32
|
+
* ...connectSlackAdapter("slack/acme-slack"),
|
|
33
|
+
* userName: "my-bot",
|
|
34
|
+
* });
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* The returned `botToken` is a function form, invoked once per Slack
|
|
38
|
+
* API call so the adapter always picks up a fresh token from Vercel
|
|
39
|
+
* Connect (rotation, refresh, and multi-workspace tenancy are handled
|
|
40
|
+
* server-side). Slack bot tokens are app-scoped — one token per
|
|
41
|
+
* workspace install — so this helper calls Vercel Connect with
|
|
42
|
+
* `subject: { type: "app" }`.
|
|
43
|
+
*
|
|
44
|
+
* `webhookVerifier` validates Connect trigger-forwarded webhooks via the
|
|
45
|
+
* Vercel OIDC token Connect attaches, replacing Slack's signing-secret
|
|
46
|
+
* check. Omit `signingSecret` / `SLACK_SIGNING_SECRET` when using this.
|
|
47
|
+
*
|
|
48
|
+
* The optional `params` and `options` arguments mirror the signature of
|
|
49
|
+
* {@link getToken}, allowing callers to pass through fields like
|
|
50
|
+
* `installationId`, `scopes`, or `validityBufferMs`.
|
|
51
|
+
*/
|
|
52
|
+
export declare function connectSlackAdapter(connector: string, params?: ConnectSlackAdapterParams, options?: ConnectOptions): ConnectSlackAdapterConfig;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { getToken, } from '../index.js';
|
|
2
|
+
import { createConnectWebhookVerifier } from './webhook-verifier.js';
|
|
3
|
+
/**
|
|
4
|
+
* Build a Slack adapter config fragment backed by a Vercel Connect
|
|
5
|
+
* connector that stores a Slack workspace's bot token.
|
|
6
|
+
*
|
|
7
|
+
* Spread the result into `createSlackAdapter` from `@chat-adapter/slack`:
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { createSlackAdapter } from "@chat-adapter/slack";
|
|
11
|
+
* import { connectSlackAdapter } from "@vercel/connect/chat";
|
|
12
|
+
*
|
|
13
|
+
* createSlackAdapter({
|
|
14
|
+
* ...connectSlackAdapter("slack/acme-slack"),
|
|
15
|
+
* userName: "my-bot",
|
|
16
|
+
* });
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* The returned `botToken` is a function form, invoked once per Slack
|
|
20
|
+
* API call so the adapter always picks up a fresh token from Vercel
|
|
21
|
+
* Connect (rotation, refresh, and multi-workspace tenancy are handled
|
|
22
|
+
* server-side). Slack bot tokens are app-scoped — one token per
|
|
23
|
+
* workspace install — so this helper calls Vercel Connect with
|
|
24
|
+
* `subject: { type: "app" }`.
|
|
25
|
+
*
|
|
26
|
+
* `webhookVerifier` validates Connect trigger-forwarded webhooks via the
|
|
27
|
+
* Vercel OIDC token Connect attaches, replacing Slack's signing-secret
|
|
28
|
+
* check. Omit `signingSecret` / `SLACK_SIGNING_SECRET` when using this.
|
|
29
|
+
*
|
|
30
|
+
* The optional `params` and `options` arguments mirror the signature of
|
|
31
|
+
* {@link getToken}, allowing callers to pass through fields like
|
|
32
|
+
* `installationId`, `scopes`, or `validityBufferMs`.
|
|
33
|
+
*/
|
|
34
|
+
export function connectSlackAdapter(connector, params = {}, options) {
|
|
35
|
+
return {
|
|
36
|
+
botToken: () => getToken(connector, { ...params, subject: { type: 'app' } }, options),
|
|
37
|
+
webhookVerifier: createConnectWebhookVerifier(),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ConnectWebhookVerifier } from './webhook-verifier.js';
|
|
2
|
+
/**
|
|
3
|
+
* Function form of a Chat SDK adapter token field. The adapter invokes
|
|
4
|
+
* it per API call, so it composes naturally with Vercel Connect's
|
|
5
|
+
* short-lived tokens — each call returns a fresh token (the
|
|
6
|
+
* `@vercel/connect` SDK caches and refreshes server-side).
|
|
7
|
+
*/
|
|
8
|
+
export type ConnectTokenResolver = () => Promise<string>;
|
|
9
|
+
/**
|
|
10
|
+
* Partial GitHub adapter config backed by Vercel Connect.
|
|
11
|
+
*
|
|
12
|
+
* Structurally matches the `installationToken` and `webhookVerifier`
|
|
13
|
+
* options of `createGitHubAdapter` from `@chat-adapter/github`.
|
|
14
|
+
*/
|
|
15
|
+
export interface ConnectGitHubAdapterConfig {
|
|
16
|
+
installationToken: ConnectTokenResolver;
|
|
17
|
+
webhookVerifier: ConnectWebhookVerifier;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Partial Linear adapter config backed by Vercel Connect.
|
|
21
|
+
*
|
|
22
|
+
* Structurally matches the `accessToken` and `webhookVerifier` options
|
|
23
|
+
* of `createLinearAdapter` from `@chat-adapter/linear`.
|
|
24
|
+
*/
|
|
25
|
+
export interface ConnectLinearAdapterConfig {
|
|
26
|
+
accessToken: ConnectTokenResolver;
|
|
27
|
+
webhookVerifier: ConnectWebhookVerifier;
|
|
28
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { verifyVercelOidcToken } from '@vercel/oidc';
|
|
2
|
+
/**
|
|
3
|
+
* Webhook verifier signature used by Chat SDK adapters. Returning a
|
|
4
|
+
* truthy value marks the request as verified; throwing (or returning a
|
|
5
|
+
* falsy value) makes the adapter respond `401`.
|
|
6
|
+
*
|
|
7
|
+
* Mirrors the `webhookVerifier` option accepted by the Slack, GitHub,
|
|
8
|
+
* and Linear adapters from the `chat` package, so the helpers in this
|
|
9
|
+
* subpath stay decoupled from `@chat-adapter/*` while remaining
|
|
10
|
+
* structurally compatible.
|
|
11
|
+
*/
|
|
12
|
+
export type ConnectWebhookVerifier = (request: Request, body: string) => Promise<unknown> | unknown;
|
|
13
|
+
/**
|
|
14
|
+
* Options forwarded to {@link verifyVercelOidcToken}. Defaults to
|
|
15
|
+
* matching `project_id` / `environment` against the current Vercel
|
|
16
|
+
* deployment's `VERCEL_PROJECT_ID` and `VERCEL_TARGET_ENV` / `VERCEL_ENV`.
|
|
17
|
+
*/
|
|
18
|
+
export type ConnectWebhookVerifierOptions = Parameters<typeof verifyVercelOidcToken>[1];
|
|
19
|
+
/**
|
|
20
|
+
* Build a webhook verifier for Vercel Connect trigger-forwarded
|
|
21
|
+
* webhooks.
|
|
22
|
+
*
|
|
23
|
+
* When Vercel Connect forwards a verified provider webhook to your
|
|
24
|
+
* project, it attaches a Vercel OIDC token as a `Bearer` credential in
|
|
25
|
+
* the `Authorization` header. This verifier extracts that token and
|
|
26
|
+
* validates it against Vercel's JWKS via
|
|
27
|
+
* {@link verifyVercelOidcToken}, replacing the provider's native
|
|
28
|
+
* signature check (Slack signing secret, GitHub webhook secret, Linear
|
|
29
|
+
* webhook secret).
|
|
30
|
+
*
|
|
31
|
+
* Trust boundary: by default the token must be issued by
|
|
32
|
+
* `https://oidc.vercel.com` (issuer is hard-pinned) and match the
|
|
33
|
+
* current deployment's project and environment (`projectId` defaults to
|
|
34
|
+
* `VERCEL_PROJECT_ID`, `environment` to `VERCEL_TARGET_ENV` then
|
|
35
|
+
* `VERCEL_ENV`). Verification fails closed — if those values are absent
|
|
36
|
+
* and not supplied via `options`, every request is rejected. The
|
|
37
|
+
* accepted set is therefore "any Vercel OIDC token for this
|
|
38
|
+
* project + environment"; it is not pinned to a specific Connect
|
|
39
|
+
* connector or to a single deployment. To tighten or broaden it (extra
|
|
40
|
+
* audiences, multiple environments, an explicit project id), pass
|
|
41
|
+
* `options` through to {@link verifyVercelOidcToken}.
|
|
42
|
+
*
|
|
43
|
+
* Pass it as the `webhookVerifier` option to a Chat SDK adapter:
|
|
44
|
+
*
|
|
45
|
+
* ```ts
|
|
46
|
+
* createSlackAdapter({
|
|
47
|
+
* webhookVerifier: createConnectWebhookVerifier(),
|
|
48
|
+
* });
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export declare function createConnectWebhookVerifier(options?: ConnectWebhookVerifierOptions): ConnectWebhookVerifier;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { verifyVercelOidcToken } from '@vercel/oidc';
|
|
2
|
+
const BEARER_TOKEN_PATTERN = /^Bearer\s+(.+)$/i;
|
|
3
|
+
/**
|
|
4
|
+
* Build a webhook verifier for Vercel Connect trigger-forwarded
|
|
5
|
+
* webhooks.
|
|
6
|
+
*
|
|
7
|
+
* When Vercel Connect forwards a verified provider webhook to your
|
|
8
|
+
* project, it attaches a Vercel OIDC token as a `Bearer` credential in
|
|
9
|
+
* the `Authorization` header. This verifier extracts that token and
|
|
10
|
+
* validates it against Vercel's JWKS via
|
|
11
|
+
* {@link verifyVercelOidcToken}, replacing the provider's native
|
|
12
|
+
* signature check (Slack signing secret, GitHub webhook secret, Linear
|
|
13
|
+
* webhook secret).
|
|
14
|
+
*
|
|
15
|
+
* Trust boundary: by default the token must be issued by
|
|
16
|
+
* `https://oidc.vercel.com` (issuer is hard-pinned) and match the
|
|
17
|
+
* current deployment's project and environment (`projectId` defaults to
|
|
18
|
+
* `VERCEL_PROJECT_ID`, `environment` to `VERCEL_TARGET_ENV` then
|
|
19
|
+
* `VERCEL_ENV`). Verification fails closed — if those values are absent
|
|
20
|
+
* and not supplied via `options`, every request is rejected. The
|
|
21
|
+
* accepted set is therefore "any Vercel OIDC token for this
|
|
22
|
+
* project + environment"; it is not pinned to a specific Connect
|
|
23
|
+
* connector or to a single deployment. To tighten or broaden it (extra
|
|
24
|
+
* audiences, multiple environments, an explicit project id), pass
|
|
25
|
+
* `options` through to {@link verifyVercelOidcToken}.
|
|
26
|
+
*
|
|
27
|
+
* Pass it as the `webhookVerifier` option to a Chat SDK adapter:
|
|
28
|
+
*
|
|
29
|
+
* ```ts
|
|
30
|
+
* createSlackAdapter({
|
|
31
|
+
* webhookVerifier: createConnectWebhookVerifier(),
|
|
32
|
+
* });
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export function createConnectWebhookVerifier(options) {
|
|
36
|
+
return async (request, _body) => {
|
|
37
|
+
const token = request.headers
|
|
38
|
+
.get('authorization')
|
|
39
|
+
?.match(BEARER_TOKEN_PATTERN)?.[1]
|
|
40
|
+
?.trim();
|
|
41
|
+
if (!token) {
|
|
42
|
+
throw new Error('Missing Authorization bearer token');
|
|
43
|
+
}
|
|
44
|
+
await verifyVercelOidcToken(token, options);
|
|
45
|
+
return true;
|
|
46
|
+
};
|
|
47
|
+
}
|
|
@@ -115,6 +115,22 @@ export interface EveAuthorizationOptions {
|
|
|
115
115
|
* and rely on `@vercel/oidc` auto-discovery.
|
|
116
116
|
*/
|
|
117
117
|
readonly connectOptions?: ConnectOptions;
|
|
118
|
+
/**
|
|
119
|
+
* Create or link the declared connector against the deploying Vercel
|
|
120
|
+
* project before the first token / authorization call. Defaults to
|
|
121
|
+
* `true`.
|
|
122
|
+
*
|
|
123
|
+
* The provision request is authenticated with the deployment OIDC token
|
|
124
|
+
* and carries the eve connection's `url` plus this connector UID. Connect
|
|
125
|
+
* creates the managed OAuth connector when missing, links an existing
|
|
126
|
+
* OAuth connector when the UID already exists, and scopes the new project
|
|
127
|
+
* link to the OIDC token's environment and higher promotion targets.
|
|
128
|
+
*
|
|
129
|
+
* Set this to `false` for callers that intentionally manage the connector
|
|
130
|
+
* linkage elsewhere. Opaque connector ids (`scl_...`) and connections
|
|
131
|
+
* without a URL are skipped automatically.
|
|
132
|
+
*/
|
|
133
|
+
readonly autoProvision?: boolean;
|
|
118
134
|
/**
|
|
119
135
|
* Re-validate the grant against Vercel Connect on every `getToken`
|
|
120
136
|
* instead of trusting the in-process token cache.
|
|
@@ -170,9 +186,10 @@ export type EveAuthorizationInput = string | EveAuthorizationOptions;
|
|
|
170
186
|
* both forms address the same connector.
|
|
171
187
|
*
|
|
172
188
|
* The marker is purely metadata — it does not influence the runtime
|
|
173
|
-
* token-fetching
|
|
189
|
+
* token-fetching identity, which continues to be driven by the
|
|
174
190
|
* `getToken` / `startAuthorization` / `completeAuthorization`
|
|
175
|
-
* callbacks.
|
|
191
|
+
* callbacks. When auto-provisioning is enabled, the same connector value is
|
|
192
|
+
* also sent as the managed OAuth UID.
|
|
176
193
|
*/
|
|
177
194
|
export interface VercelConnectMetadata {
|
|
178
195
|
readonly connector: string;
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
import { ConnectionAuthorizationFailedError, ConnectionAuthorizationRequiredError, } from 'eve/connections';
|
|
32
32
|
import { startAuthorization } from '../authorization.js';
|
|
33
33
|
import { ConnectorInstallationRequiredError, deleteTokenCacheEntry, getTokenResponse, NoValidTokenError, revokeToken, UserAuthorizationRequiredError, } from '../token.js';
|
|
34
|
+
import { provisionEveOAuthConnector } from './provision-oauth-connector.js';
|
|
34
35
|
export function connect(input) {
|
|
35
36
|
const options = normalizeAuthorizationOptions(input);
|
|
36
37
|
const vercelConnect = { connector: options.connector };
|
|
@@ -84,6 +85,7 @@ function buildInteractiveDefinition(options) {
|
|
|
84
85
|
principalType: 'user',
|
|
85
86
|
async getToken({ principal, connection, }) {
|
|
86
87
|
try {
|
|
88
|
+
await autoProvisionConnectorIfEnabled(options, connection);
|
|
87
89
|
const response = await getTokenResponse(options.connector, await buildTokenParams(options, principal, connection), getTokenConnectOptions(options));
|
|
88
90
|
return { token: response.token, expiresAt: response.expiresAt };
|
|
89
91
|
}
|
|
@@ -93,30 +95,30 @@ function buildInteractiveDefinition(options) {
|
|
|
93
95
|
},
|
|
94
96
|
async startAuthorization({ principal, connection, callbackUrl, webhook, }) {
|
|
95
97
|
try {
|
|
96
|
-
|
|
97
|
-
//
|
|
98
|
-
//
|
|
99
|
-
//
|
|
100
|
-
//
|
|
101
|
-
//
|
|
102
|
-
//
|
|
98
|
+
await autoProvisionConnectorIfEnabled(options, connection);
|
|
99
|
+
// eve's `webhook` parameter is also the browser-redirect
|
|
100
|
+
// target when `callbackUrl` is absent — the orchestrator mints
|
|
101
|
+
// it via `createWebhook({ respondWith:
|
|
102
|
+
// buildAuthorizationCompletePage() })` so the user lands on a
|
|
103
|
+
// friendly "you can close this tab" page after consent. That
|
|
104
|
+
// maps to Vercel Connect's `callbackUrl:` semantics, which
|
|
105
|
+
// accepts both `https://` (prod) and `http://localhost`
|
|
106
|
+
// (vercel dev).
|
|
107
|
+
//
|
|
108
|
+
// When the eve webhook is HTTPS, also pass it as Vercel
|
|
109
|
+
// Connect's server-side completion webhook. That lets Connect
|
|
110
|
+
// resume the eve session even when the OAuth callback fails
|
|
111
|
+
// before the browser can be redirected back, such as a token
|
|
112
|
+
// exchange error after provider consent.
|
|
113
|
+
//
|
|
103
114
|
// Vercel Connect authenticates the calling Vercel project via
|
|
104
115
|
// OIDC, which is what lets per-workflow dynamic webhook URLs
|
|
105
116
|
// work without an OAuth-style redirect-URI allowlist.
|
|
106
|
-
|
|
107
|
-
// We don't route `https://` URLs into Vercel Connect's
|
|
108
|
-
// `webhook:` (server-POST) field, even though it would
|
|
109
|
-
// survive the user closing the consent tab right after IdP
|
|
110
|
-
// callback. That mode shows the user Vercel Connect's
|
|
111
|
-
// generic "close this window" page instead of Eve's branded
|
|
112
|
-
// landing page, and the helper would need to grow
|
|
113
|
-
// protocol-aware logic that diverges from the simple "Eve
|
|
114
|
-
// mints one URL, Vercel Connect redirects there" mental
|
|
115
|
-
// model. Revisit if tab-close timeouts become a real problem
|
|
116
|
-
// in production.
|
|
117
|
+
const completionWebhook = connectCompletionWebhook(webhook);
|
|
117
118
|
const response = await startAuthorization(options.connector, await buildTokenParams(options, principal, connection), {
|
|
118
119
|
...options.connectOptions,
|
|
119
120
|
callbackUrl: callbackUrl ?? webhook,
|
|
121
|
+
...(completionWebhook ? { webhook: completionWebhook } : null),
|
|
120
122
|
deviceCode: true,
|
|
121
123
|
});
|
|
122
124
|
return {
|
|
@@ -138,6 +140,7 @@ function buildInteractiveDefinition(options) {
|
|
|
138
140
|
},
|
|
139
141
|
async completeAuthorization({ principal, connection, }) {
|
|
140
142
|
try {
|
|
143
|
+
await autoProvisionConnectorIfEnabled(options, connection);
|
|
141
144
|
const response = await getTokenResponse(options.connector, await buildTokenParams(options, principal, connection), options.connectOptions);
|
|
142
145
|
return { token: response.token, expiresAt: response.expiresAt };
|
|
143
146
|
}
|
|
@@ -147,11 +150,23 @@ function buildInteractiveDefinition(options) {
|
|
|
147
150
|
},
|
|
148
151
|
};
|
|
149
152
|
}
|
|
153
|
+
function connectCompletionWebhook(webhook) {
|
|
154
|
+
if (!webhook) {
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
try {
|
|
158
|
+
return new URL(webhook).protocol === 'https:' ? webhook : null;
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
150
164
|
function buildNonInteractiveDefinition(options) {
|
|
151
165
|
return {
|
|
152
166
|
principalType: 'app',
|
|
153
167
|
async getToken({ principal, connection, }) {
|
|
154
168
|
try {
|
|
169
|
+
await autoProvisionConnectorIfEnabled(options, connection);
|
|
155
170
|
const response = await getTokenResponse(options.connector, await buildTokenParams(options, principal, connection), getTokenConnectOptions(options));
|
|
156
171
|
return { token: response.token, expiresAt: response.expiresAt };
|
|
157
172
|
}
|
|
@@ -161,6 +176,16 @@ function buildNonInteractiveDefinition(options) {
|
|
|
161
176
|
},
|
|
162
177
|
};
|
|
163
178
|
}
|
|
179
|
+
async function autoProvisionConnectorIfEnabled(options, connection) {
|
|
180
|
+
if (options.autoProvision === false) {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
await provisionEveOAuthConnector({
|
|
184
|
+
connector: options.connector,
|
|
185
|
+
connection,
|
|
186
|
+
connectOptions: options.connectOptions,
|
|
187
|
+
});
|
|
188
|
+
}
|
|
164
189
|
/**
|
|
165
190
|
* Connect SDK options for `getToken` calls. When {@link
|
|
166
191
|
* EveAuthorizationOptions.validate} is set, forces a cache-bypassing
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ConnectOptions } from '../token.js';
|
|
2
|
+
import type { EveConnectionAuthorizationContext } from './connection-authorization.js';
|
|
3
|
+
interface ProvisionEveOAuthConnectorOptions {
|
|
4
|
+
readonly connector: string;
|
|
5
|
+
readonly connection: EveConnectionAuthorizationContext;
|
|
6
|
+
readonly connectOptions?: ConnectOptions;
|
|
7
|
+
}
|
|
8
|
+
export declare function provisionEveOAuthConnector({ connector, connection, connectOptions, }: ProvisionEveOAuthConnectorOptions): Promise<void>;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { getVercelOidcToken } from '@vercel/oidc';
|
|
2
|
+
import { ConnectError, createConnectErrorFromResponse } from '../token.js';
|
|
3
|
+
const MANAGED_OAUTH_CONNECTOR_ENDPOINT = 'https://api.vercel.com/v1/connect/connectors/managed/oauth';
|
|
4
|
+
const RESERVED_UID_PATTERN = /^(vc\/|[^/]*\.vercel\.com\/)/;
|
|
5
|
+
const ALLOWED_RESERVED_UID_PREFIXES = ['mcp.vercel.com/'];
|
|
6
|
+
const RESERVED_ID_PREFIXES = ['scl_', 'sca_', 'store_', 'ir_'];
|
|
7
|
+
const INVALID_UID_CHARS = /[\s%#]/;
|
|
8
|
+
const provisionCache = new Map();
|
|
9
|
+
export async function provisionEveOAuthConnector({ connector, connection, connectOptions, }) {
|
|
10
|
+
const serverUrl = resolveServerUrl(connection);
|
|
11
|
+
if (serverUrl === undefined || !isProvisionableConnectorUid(connector)) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const vercelToken = connectOptions?.vercelToken ?? (await getVercelOidcToken());
|
|
15
|
+
const cacheKey = JSON.stringify({
|
|
16
|
+
connector,
|
|
17
|
+
serverUrl,
|
|
18
|
+
token: await tokenCacheKeyPart(vercelToken),
|
|
19
|
+
});
|
|
20
|
+
let promise = provisionCache.get(cacheKey);
|
|
21
|
+
if (promise === undefined) {
|
|
22
|
+
promise = provisionManagedOAuthConnector({
|
|
23
|
+
connector,
|
|
24
|
+
serverUrl,
|
|
25
|
+
vercelToken,
|
|
26
|
+
}).catch(error => {
|
|
27
|
+
if (isNonOAuthConnectorConflict(error)) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
provisionCache.delete(cacheKey);
|
|
31
|
+
throw error;
|
|
32
|
+
});
|
|
33
|
+
provisionCache.set(cacheKey, promise);
|
|
34
|
+
}
|
|
35
|
+
await promise;
|
|
36
|
+
}
|
|
37
|
+
function resolveServerUrl(connection) {
|
|
38
|
+
const url = connection.url;
|
|
39
|
+
if (typeof url !== 'string') {
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
const trimmed = url.trim();
|
|
43
|
+
return trimmed === '' ? undefined : trimmed;
|
|
44
|
+
}
|
|
45
|
+
function isProvisionableConnectorUid(connector) {
|
|
46
|
+
if (connector === '' || INVALID_UID_CHARS.test(connector)) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
for (let index = 0; index < connector.length; index++) {
|
|
50
|
+
const code = connector.charCodeAt(index);
|
|
51
|
+
if (code <= 0x1f || (code >= 0x7f && code <= 0x9f)) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
const normalized = connector.toLowerCase();
|
|
56
|
+
if (RESERVED_ID_PREFIXES.some(prefix => normalized.startsWith(prefix))) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
if (RESERVED_UID_PATTERN.test(normalized) &&
|
|
60
|
+
!ALLOWED_RESERVED_UID_PREFIXES.some(prefix => normalized.startsWith(prefix))) {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
async function tokenCacheKeyPart(token) {
|
|
66
|
+
const subtle = globalThis.crypto?.subtle;
|
|
67
|
+
if (subtle) {
|
|
68
|
+
const digest = await subtle.digest('SHA-256', new TextEncoder().encode(token));
|
|
69
|
+
return Array.from(new Uint8Array(digest), byte => byte.toString(16).padStart(2, '0')).join('');
|
|
70
|
+
}
|
|
71
|
+
let hash = 2166136261;
|
|
72
|
+
for (let index = 0; index < token.length; index++) {
|
|
73
|
+
hash ^= token.charCodeAt(index);
|
|
74
|
+
hash = Math.imul(hash, 16777619);
|
|
75
|
+
}
|
|
76
|
+
return `${token.length}:${hash >>> 0}`;
|
|
77
|
+
}
|
|
78
|
+
function isNonOAuthConnectorConflict(error) {
|
|
79
|
+
return (error instanceof ConnectError &&
|
|
80
|
+
error.status === 409 &&
|
|
81
|
+
/not an OAuth connector/i.test(error.message));
|
|
82
|
+
}
|
|
83
|
+
async function provisionManagedOAuthConnector({ connector, serverUrl, vercelToken, }) {
|
|
84
|
+
const response = await fetch(MANAGED_OAUTH_CONNECTOR_ENDPOINT, {
|
|
85
|
+
method: 'POST',
|
|
86
|
+
headers: {
|
|
87
|
+
Accept: 'application/json',
|
|
88
|
+
'Content-Type': 'application/json',
|
|
89
|
+
Authorization: `Bearer ${vercelToken}`,
|
|
90
|
+
},
|
|
91
|
+
body: JSON.stringify({ serverUrl, uid: connector }),
|
|
92
|
+
});
|
|
93
|
+
if (!response.ok) {
|
|
94
|
+
throw await createConnectErrorFromResponse(response, 'Failed to provision connector');
|
|
95
|
+
}
|
|
96
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vercel/connect",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -13,6 +13,10 @@
|
|
|
13
13
|
"types": "./dist/index.d.ts",
|
|
14
14
|
"default": "./dist/index.js"
|
|
15
15
|
},
|
|
16
|
+
"./chat": {
|
|
17
|
+
"types": "./dist/chat/index.d.ts",
|
|
18
|
+
"default": "./dist/chat/index.js"
|
|
19
|
+
},
|
|
16
20
|
"./eve": {
|
|
17
21
|
"types": "./dist/eve/index.d.ts",
|
|
18
22
|
"default": "./dist/eve/index.js"
|
|
@@ -38,11 +42,12 @@
|
|
|
38
42
|
"dist"
|
|
39
43
|
],
|
|
40
44
|
"dependencies": {
|
|
41
|
-
"@vercel/oidc": "3.7.
|
|
45
|
+
"@vercel/oidc": "3.7.1"
|
|
42
46
|
},
|
|
43
47
|
"peerDependencies": {
|
|
44
48
|
"@ai-sdk/mcp": "^1 || ^2",
|
|
45
49
|
"@auth/core": ">=0.37.0",
|
|
50
|
+
"@chat-adapter/slack": "^4.0.0",
|
|
46
51
|
"ai": "^6 || ^7.0.0-beta.0",
|
|
47
52
|
"better-auth": ">=1.5.0",
|
|
48
53
|
"eve": ">=0.13.7"
|
|
@@ -54,6 +59,9 @@
|
|
|
54
59
|
"@auth/core": {
|
|
55
60
|
"optional": true
|
|
56
61
|
},
|
|
62
|
+
"@chat-adapter/slack": {
|
|
63
|
+
"optional": true
|
|
64
|
+
},
|
|
57
65
|
"ai": {
|
|
58
66
|
"optional": true
|
|
59
67
|
},
|
|
@@ -67,6 +75,7 @@
|
|
|
67
75
|
"devDependencies": {
|
|
68
76
|
"@ai-sdk/mcp": "2.0.0-beta.37",
|
|
69
77
|
"@auth/core": "0.37.4",
|
|
78
|
+
"@chat-adapter/slack": "4.31.0",
|
|
70
79
|
"ai": "7.0.0-beta.116",
|
|
71
80
|
"better-auth": "1.5.5",
|
|
72
81
|
"eve": "0.6.0-beta.1",
|