@vercel/connect 0.4.2 → 0.5.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 +17 -1
- package/dist/ai-sdk/index.d.ts +1 -1
- package/dist/authorization.js +2 -35
- package/dist/connector.d.ts +32 -0
- package/dist/connector.js +27 -0
- package/dist/eve/connect-oauth.js +1 -4
- package/dist/eve/index.d.ts +1 -0
- package/dist/eve/index.js +1 -0
- package/dist/eve/photon-credentials.d.ts +34 -0
- package/dist/eve/photon-credentials.js +31 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2 -0
- package/dist/installation.d.ts +42 -0
- package/dist/installation.js +50 -0
- package/dist/internal/env.d.ts +1 -0
- package/dist/internal/env.js +4 -0
- package/dist/internal/url-validation.d.ts +3 -0
- package/dist/internal/url-validation.js +39 -0
- package/dist/mcp/connect-auth-provider.d.ts +3 -3
- package/dist/mcp/connect-auth-provider.js +3 -3
- package/dist/mcp/index.d.ts +1 -1
- package/dist/token.d.ts +6 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -30,6 +30,22 @@ const token = await getToken(process.env.CONNECTOR_LINEAR!, {
|
|
|
30
30
|
});
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
+
To create an operator installation request for an app-scoped connector, use the
|
|
34
|
+
experimental install helper:
|
|
35
|
+
|
|
36
|
+
This feature is gated while experimental. Contact Vercel to enable access
|
|
37
|
+
before using it.
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
import { experimental_startInstallation } from '@vercel/connect';
|
|
41
|
+
|
|
42
|
+
const { url } = await experimental_startInstallation(
|
|
43
|
+
process.env.CONNECTOR_SLACK!,
|
|
44
|
+
{},
|
|
45
|
+
{ returnUrl: 'https://example.com/settings/integrations' }
|
|
46
|
+
);
|
|
47
|
+
```
|
|
48
|
+
|
|
33
49
|
### Chat SDK
|
|
34
50
|
|
|
35
51
|
Spread the helper into the matching `create*Adapter` factory. Each helper
|
|
@@ -123,4 +139,4 @@ import { connect } from '@vercel/connect/authjs';
|
|
|
123
139
|
const providers = [connect({ connector: 'linear' })];
|
|
124
140
|
```
|
|
125
141
|
|
|
126
|
-
See the source under `src/` for the full API (additional helpers like `revokeToken`, `getTokenResponse`, `startAuthorization`, typed error classes, and per-adapter options).
|
|
142
|
+
See the source under `src/` for the full API (additional helpers like `revokeToken`, `getTokenResponse`, `startAuthorization`, `experimental_startInstallation`, typed error classes, and per-adapter options).
|
package/dist/ai-sdk/index.d.ts
CHANGED
|
@@ -49,4 +49,4 @@
|
|
|
49
49
|
* ```
|
|
50
50
|
*/
|
|
51
51
|
export { connectAuthProvider, ConsentRequiredError, type ConnectAuthProviderOptions, type ConsentChallenge, } from '../mcp/connect-auth-provider.js';
|
|
52
|
-
export { ConnectError, ConnectorInstallationRequiredError, NoValidTokenError, UserAuthorizationRequiredError, type ConnectErrorOptions, type ConnectTokenParams, type ConnectTokenSubject, type ConnectVendorErrorPayload, } from '../token.js';
|
|
52
|
+
export { ConnectError, ConnectorInstallationRequiredError, NoValidTokenError, UserAuthorizationRequiredError, type ConnectErrorOptions, type ConnectTokenExchangeSubject, type ConnectTokenParams, type ConnectTokenSubject, type ConnectVendorErrorPayload, } from '../token.js';
|
package/dist/authorization.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { getVercelOidcToken } from '@vercel/oidc';
|
|
2
|
-
|
|
3
|
-
const INTERACTIVE_AUTH_MODE_ENV = 'VERCEL_CONNECT_INTERACTIVE_AUTH_MODE';
|
|
2
|
+
import { isDetachedInteractiveAuth, validateCallbackUrl, validateWebhookUrl, } from './internal/url-validation.js';
|
|
4
3
|
export async function startAuthorization(connector, params, options) {
|
|
5
4
|
if (!connector) {
|
|
6
5
|
throw new Error('connector is required');
|
|
7
6
|
}
|
|
8
|
-
const detachedInteractiveAuth =
|
|
7
|
+
const detachedInteractiveAuth = isDetachedInteractiveAuth();
|
|
9
8
|
if (!detachedInteractiveAuth && options?.callbackUrl !== undefined) {
|
|
10
9
|
validateCallbackUrl(options.callbackUrl);
|
|
11
10
|
}
|
|
@@ -49,35 +48,3 @@ export async function startAuthorization(connector, params, options) {
|
|
|
49
48
|
const data = await response.json();
|
|
50
49
|
return data;
|
|
51
50
|
}
|
|
52
|
-
function validateCallbackUrl(value) {
|
|
53
|
-
let url;
|
|
54
|
-
try {
|
|
55
|
-
url = new URL(value);
|
|
56
|
-
}
|
|
57
|
-
catch {
|
|
58
|
-
throw new Error(`Invalid callbackUrl: ${value}`);
|
|
59
|
-
}
|
|
60
|
-
if (url.protocol === 'https:')
|
|
61
|
-
return;
|
|
62
|
-
if (url.protocol === 'http:' && isLocalHttpCallbackHostname(url.hostname)) {
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
throw new Error(`callbackUrl must be https://, http://localhost, or http://*.localhost, got: ${value}`);
|
|
66
|
-
}
|
|
67
|
-
function isLocalHttpCallbackHostname(hostname) {
|
|
68
|
-
return (hostname === 'localhost' ||
|
|
69
|
-
hostname.endsWith('.localhost') ||
|
|
70
|
-
hostname === '127.0.0.1');
|
|
71
|
-
}
|
|
72
|
-
function validateWebhookUrl(value) {
|
|
73
|
-
let url;
|
|
74
|
-
try {
|
|
75
|
-
url = new URL(value);
|
|
76
|
-
}
|
|
77
|
-
catch {
|
|
78
|
-
throw new Error(`Invalid webhook URL: ${value}`);
|
|
79
|
-
}
|
|
80
|
-
if (url.protocol !== 'https:') {
|
|
81
|
-
throw new Error(`webhook must be https://, got: ${value}`);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type ConnectOptions } from './token.js';
|
|
2
|
+
/**
|
|
3
|
+
* Connector metadata as returned by Vercel Connect. This is the stable, useful
|
|
4
|
+
* subset of the connector object the management APIs return.
|
|
5
|
+
*/
|
|
6
|
+
export interface ConnectorMetadata {
|
|
7
|
+
/** Opaque Vercel Connect connector id (e.g. `scl_…`). */
|
|
8
|
+
id: string;
|
|
9
|
+
/** Human-readable Vercel Connect connector UID. */
|
|
10
|
+
uid: string;
|
|
11
|
+
name: string;
|
|
12
|
+
/** Connector type identifier (e.g. `snowflake`, `oauth`). */
|
|
13
|
+
type: string;
|
|
14
|
+
/** Service the connector integrates with. */
|
|
15
|
+
service: string;
|
|
16
|
+
/** Fully-qualified URL for the connector's service when derivable. */
|
|
17
|
+
clientUrl?: string;
|
|
18
|
+
createdAt: number;
|
|
19
|
+
updatedAt: number;
|
|
20
|
+
/** Vendor-specific public configuration. */
|
|
21
|
+
vendor: Record<string, unknown>;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Fetch a connector's metadata from Vercel Connect.
|
|
25
|
+
*
|
|
26
|
+
* Authenticates with the deployment's Vercel OIDC token (same as
|
|
27
|
+
* {@link getToken}); the connector must be attached to the requesting
|
|
28
|
+
* deployment's project and enabled for its environment.
|
|
29
|
+
*
|
|
30
|
+
* @param connector - The connector id or UID.
|
|
31
|
+
*/
|
|
32
|
+
export declare function getConnectorMetadata(connector: string, options?: ConnectOptions): Promise<ConnectorMetadata>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { getVercelOidcToken } from '@vercel/oidc';
|
|
2
|
+
import { createConnectErrorFromResponse, } from './token.js';
|
|
3
|
+
/**
|
|
4
|
+
* Fetch a connector's metadata from Vercel Connect.
|
|
5
|
+
*
|
|
6
|
+
* Authenticates with the deployment's Vercel OIDC token (same as
|
|
7
|
+
* {@link getToken}); the connector must be attached to the requesting
|
|
8
|
+
* deployment's project and enabled for its environment.
|
|
9
|
+
*
|
|
10
|
+
* @param connector - The connector id or UID.
|
|
11
|
+
*/
|
|
12
|
+
export async function getConnectorMetadata(connector, options) {
|
|
13
|
+
const vercelToken = options?.vercelToken ?? (await getVercelOidcToken());
|
|
14
|
+
const endpoint = `https://api.vercel.com/v1/connect/connectors/${encodeURIComponent(connector)}`;
|
|
15
|
+
const response = await fetch(endpoint, {
|
|
16
|
+
method: 'GET',
|
|
17
|
+
headers: {
|
|
18
|
+
Accept: 'application/json',
|
|
19
|
+
Authorization: `Bearer ${vercelToken}`,
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
if (!response.ok) {
|
|
23
|
+
throw await createConnectErrorFromResponse(response, 'Failed to get connector');
|
|
24
|
+
}
|
|
25
|
+
const { data, ...rest } = (await response.json());
|
|
26
|
+
return { ...rest, vendor: data ?? {} };
|
|
27
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { extractBearerToken, verifyOidc, } from 'eve/channels/auth';
|
|
2
|
+
import { readNonEmptyEnv } from '../internal/env.js';
|
|
2
3
|
export const CONNECT_OAUTH_ISSUER = 'https://connect.vercel.com';
|
|
3
4
|
/**
|
|
4
5
|
* Returns an Eve route auth callback for Vercel Connect OAuth gateway
|
|
@@ -110,10 +111,6 @@ function buildClaimMatchers(opts) {
|
|
|
110
111
|
typ: ['at'],
|
|
111
112
|
};
|
|
112
113
|
}
|
|
113
|
-
function readNonEmptyEnv(name) {
|
|
114
|
-
const value = typeof process === 'undefined' ? undefined : process.env?.[name]?.trim();
|
|
115
|
-
return value === undefined || value.length === 0 ? undefined : value;
|
|
116
|
-
}
|
|
117
114
|
function extractAudiences(payload) {
|
|
118
115
|
const aud = payload.aud;
|
|
119
116
|
if (typeof aud === 'string') {
|
package/dist/eve/index.d.ts
CHANGED
|
@@ -10,4 +10,5 @@ export { connect, type EveAuthorizationInput, type EveAuthorizationOptions, type
|
|
|
10
10
|
export { CONNECT_OAUTH_ISSUER, connectOAuth, type ConnectOAuthAudienceEnvironment, type ConnectOAuthEnvironment, type ConnectOAuthOptions, } from './connect-oauth.js';
|
|
11
11
|
export { connectGitHubCredentials, type ConnectGitHubCredentialsParams, } from './github-credentials.js';
|
|
12
12
|
export { connectLinearCredentials, type ConnectLinearCredentialsParams, } from './linear-credentials.js';
|
|
13
|
+
export { connectPhotonCredentials, type ConnectPhotonCredentialProvider, type PhotonCredentials, type ConnectPhotonCredentialsParams, } from './photon-credentials.js';
|
|
13
14
|
export { connectSlackCredentials, type ConnectSlackCredentialsParams, } from './slack-credentials.js';
|
package/dist/eve/index.js
CHANGED
|
@@ -10,4 +10,5 @@ export { connect, } from './connection-authorization.js';
|
|
|
10
10
|
export { CONNECT_OAUTH_ISSUER, connectOAuth, } from './connect-oauth.js';
|
|
11
11
|
export { connectGitHubCredentials, } from './github-credentials.js';
|
|
12
12
|
export { connectLinearCredentials, } from './linear-credentials.js';
|
|
13
|
+
export { connectPhotonCredentials, } from './photon-credentials.js';
|
|
13
14
|
export { connectSlackCredentials, } from './slack-credentials.js';
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type ConnectOptions, type ConnectTokenParams } from '../index.js';
|
|
2
|
+
/** Photon project credentials resolved by {@link connectPhotonCredentials}. */
|
|
3
|
+
export interface PhotonCredentials {
|
|
4
|
+
projectId: string;
|
|
5
|
+
projectSecret: string;
|
|
6
|
+
}
|
|
7
|
+
/** Lazy Photon credential provider returned by {@link connectPhotonCredentials}. */
|
|
8
|
+
export type ConnectPhotonCredentialProvider = () => Promise<PhotonCredentials>;
|
|
9
|
+
/**
|
|
10
|
+
* Token parameters accepted by {@link connectPhotonCredentials}.
|
|
11
|
+
*
|
|
12
|
+
* Mirrors {@link ConnectTokenParams} from `@vercel/connect`, minus
|
|
13
|
+
* `subject` — Photon project credentials are app-scoped, so `subject`
|
|
14
|
+
* is pinned to `{ type: "app" }` by this helper and cannot be overridden.
|
|
15
|
+
*/
|
|
16
|
+
export type ConnectPhotonCredentialsParams = Omit<ConnectTokenParams, 'subject'>;
|
|
17
|
+
/**
|
|
18
|
+
* Build a lazy Photon credential provider backed by a Vercel Connect
|
|
19
|
+
* connector.
|
|
20
|
+
*
|
|
21
|
+
* Photon connectors issue the project secret as an app-scoped token and the
|
|
22
|
+
* project ID as public token metadata. The returned provider resolves both
|
|
23
|
+
* fields when the Photon client or adapter first needs them.
|
|
24
|
+
*
|
|
25
|
+
* ```ts
|
|
26
|
+
* import { connectPhotonCredentials } from '@vercel/connect/eve';
|
|
27
|
+
* import { createiMessageAdapter } from '@photon-ai/chat-adapter-imessage';
|
|
28
|
+
*
|
|
29
|
+
* const imessage = createiMessageAdapter({
|
|
30
|
+
* credentials: connectPhotonCredentials('photon/my-project'),
|
|
31
|
+
* });
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare function connectPhotonCredentials(connector: string, params?: ConnectPhotonCredentialsParams, options?: ConnectOptions): ConnectPhotonCredentialProvider;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { getTokenResponse, } from '../index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Build a lazy Photon credential provider backed by a Vercel Connect
|
|
4
|
+
* connector.
|
|
5
|
+
*
|
|
6
|
+
* Photon connectors issue the project secret as an app-scoped token and the
|
|
7
|
+
* project ID as public token metadata. The returned provider resolves both
|
|
8
|
+
* fields when the Photon client or adapter first needs them.
|
|
9
|
+
*
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { connectPhotonCredentials } from '@vercel/connect/eve';
|
|
12
|
+
* import { createiMessageAdapter } from '@photon-ai/chat-adapter-imessage';
|
|
13
|
+
*
|
|
14
|
+
* const imessage = createiMessageAdapter({
|
|
15
|
+
* credentials: connectPhotonCredentials('photon/my-project'),
|
|
16
|
+
* });
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export function connectPhotonCredentials(connector, params = {}, options) {
|
|
20
|
+
return async () => {
|
|
21
|
+
const response = await getTokenResponse(connector, { ...params, subject: { type: 'app' } }, options);
|
|
22
|
+
const projectId = response.metadata?.projectId;
|
|
23
|
+
if (typeof projectId !== 'string' || projectId.length === 0) {
|
|
24
|
+
throw new Error('Photon connector returned invalid credentials.');
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
projectId,
|
|
28
|
+
projectSecret: response.token,
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
export { deleteTokenCacheEntry, getToken, getTokenResponse, revokeToken, ConnectError, NoValidTokenError, UserAuthorizationRequiredError, ConnectorInstallationRequiredError, type ConnectErrorOptions, type ConnectOptions, type ConnectTokenParams, type ConnectTokenResponse, type ConnectTokenSubject, type ConnectVendorErrorPayload, } from './token.js';
|
|
1
|
+
export { deleteTokenCacheEntry, getToken, getTokenResponse, revokeToken, ConnectError, NoValidTokenError, UserAuthorizationRequiredError, ConnectorInstallationRequiredError, type ConnectErrorOptions, type ConnectOptions, type ConnectTokenExchangeSubject, type ConnectTokenParams, type ConnectTokenResponse, type ConnectTokenSubject, type ConnectVendorErrorPayload, } from './token.js';
|
|
2
2
|
export { startAuthorization, type ConnectAuthorizationOptions, type ConnectAuthorizationResponse, } from './authorization.js';
|
|
3
|
+
export { experimental_startInstallation, type ConnectInstallationOptions, type ConnectInstallationParams, type ConnectInstallationResponse, } from './installation.js';
|
|
3
4
|
export type { ConnectAuthorizationDetail } from './authorization-details.js';
|
|
5
|
+
export { getConnectorMetadata, type ConnectorMetadata, } from './connector.js';
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
export { deleteTokenCacheEntry, getToken, getTokenResponse, revokeToken, ConnectError, NoValidTokenError, UserAuthorizationRequiredError, ConnectorInstallationRequiredError, } from './token.js';
|
|
2
2
|
export { startAuthorization, } from './authorization.js';
|
|
3
|
+
export { experimental_startInstallation, } from './installation.js';
|
|
4
|
+
export { getConnectorMetadata, } from './connector.js';
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { ConnectTokenParams } from './token.js';
|
|
2
|
+
export type ConnectInstallationParams = Omit<ConnectTokenParams, 'subject'>;
|
|
3
|
+
export interface ConnectInstallationOptions {
|
|
4
|
+
vercelToken?: string;
|
|
5
|
+
returnUrl?: string;
|
|
6
|
+
webhook?: string;
|
|
7
|
+
tenantId?: string;
|
|
8
|
+
deviceCode?: boolean;
|
|
9
|
+
expiresInMs?: number;
|
|
10
|
+
}
|
|
11
|
+
export interface ConnectInstallationResponse {
|
|
12
|
+
request: string;
|
|
13
|
+
verifier: string;
|
|
14
|
+
url: string;
|
|
15
|
+
deviceCode?: string;
|
|
16
|
+
expiresAt: number;
|
|
17
|
+
connector: {
|
|
18
|
+
/** Client id. */
|
|
19
|
+
id: string;
|
|
20
|
+
/** Client uid. */
|
|
21
|
+
uid: string;
|
|
22
|
+
/** Client type, eg. `oauth`, `salesforce`. */
|
|
23
|
+
type: string;
|
|
24
|
+
/** Resolved service id when known, eg. `salesforce`. */
|
|
25
|
+
service?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Curated display name of the resolved service, eg. `Salesforce`,
|
|
28
|
+
* present when the service is known to Vercel Connect. Suited for
|
|
29
|
+
* end-user surfaces like "Sign in with {serviceName}".
|
|
30
|
+
*/
|
|
31
|
+
serviceName?: string;
|
|
32
|
+
/** The connector's own (operator-given) name. */
|
|
33
|
+
name: string;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Create an operator installation request for an app-scoped connector.
|
|
38
|
+
*
|
|
39
|
+
* @experimental This API is feature-gated while experimental. Contact Vercel
|
|
40
|
+
* to enable access before using it.
|
|
41
|
+
*/
|
|
42
|
+
export declare function experimental_startInstallation(connector: string, params?: ConnectInstallationParams, options?: ConnectInstallationOptions): Promise<ConnectInstallationResponse>;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { getVercelOidcToken } from '@vercel/oidc';
|
|
2
|
+
import { isDetachedInteractiveAuth, validateCallbackUrl, validateWebhookUrl, } from './internal/url-validation.js';
|
|
3
|
+
import { createConnectErrorFromResponse } from './token.js';
|
|
4
|
+
/**
|
|
5
|
+
* Create an operator installation request for an app-scoped connector.
|
|
6
|
+
*
|
|
7
|
+
* @experimental This API is feature-gated while experimental. Contact Vercel
|
|
8
|
+
* to enable access before using it.
|
|
9
|
+
*/
|
|
10
|
+
export async function experimental_startInstallation(connector, params = {}, options) {
|
|
11
|
+
if (!connector) {
|
|
12
|
+
throw new Error('connector is required');
|
|
13
|
+
}
|
|
14
|
+
const detachedInteractiveAuth = isDetachedInteractiveAuth();
|
|
15
|
+
if (!detachedInteractiveAuth && options?.returnUrl !== undefined) {
|
|
16
|
+
validateCallbackUrl(options.returnUrl, 'returnUrl');
|
|
17
|
+
}
|
|
18
|
+
if (options?.webhook !== undefined) {
|
|
19
|
+
validateWebhookUrl(options.webhook);
|
|
20
|
+
}
|
|
21
|
+
const vercelToken = options?.vercelToken ?? (await getVercelOidcToken());
|
|
22
|
+
const endpoint = `https://api.vercel.com/v1/connect/install/${encodeURIComponent(connector)}`;
|
|
23
|
+
const deviceCode = options?.deviceCode ?? (detachedInteractiveAuth ? true : undefined);
|
|
24
|
+
const returnUrl = !detachedInteractiveAuth && options?.returnUrl !== undefined
|
|
25
|
+
? { returnUrl: options.returnUrl }
|
|
26
|
+
: {};
|
|
27
|
+
const response = await fetch(endpoint, {
|
|
28
|
+
method: 'POST',
|
|
29
|
+
headers: {
|
|
30
|
+
Accept: 'application/json',
|
|
31
|
+
'Content-Type': 'application/json',
|
|
32
|
+
Authorization: `Bearer ${vercelToken}`,
|
|
33
|
+
},
|
|
34
|
+
body: JSON.stringify({
|
|
35
|
+
...params,
|
|
36
|
+
...returnUrl,
|
|
37
|
+
...(options?.webhook !== undefined && { webhook: options.webhook }),
|
|
38
|
+
...(options?.tenantId !== undefined && { tenantId: options.tenantId }),
|
|
39
|
+
...(deviceCode !== undefined && { deviceCode }),
|
|
40
|
+
...(options?.expiresInMs !== undefined && {
|
|
41
|
+
expiresInMs: options.expiresInMs,
|
|
42
|
+
}),
|
|
43
|
+
}),
|
|
44
|
+
});
|
|
45
|
+
if (!response.ok) {
|
|
46
|
+
throw await createConnectErrorFromResponse(response, 'Failed to start installation');
|
|
47
|
+
}
|
|
48
|
+
const data = await response.json();
|
|
49
|
+
return data;
|
|
50
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function readNonEmptyEnv(name: string): string | undefined;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { readNonEmptyEnv } from './env.js';
|
|
2
|
+
const DETACHED_INTERACTIVE_AUTH_MODE = 'detached';
|
|
3
|
+
const INTERACTIVE_AUTH_MODE_ENV = 'VERCEL_CONNECT_INTERACTIVE_AUTH_MODE';
|
|
4
|
+
export function isDetachedInteractiveAuth() {
|
|
5
|
+
return (readNonEmptyEnv(INTERACTIVE_AUTH_MODE_ENV) ===
|
|
6
|
+
DETACHED_INTERACTIVE_AUTH_MODE);
|
|
7
|
+
}
|
|
8
|
+
export function validateCallbackUrl(value, label = 'callbackUrl') {
|
|
9
|
+
let url;
|
|
10
|
+
try {
|
|
11
|
+
url = new URL(value);
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
throw new Error(`Invalid ${label}: ${value}`);
|
|
15
|
+
}
|
|
16
|
+
if (url.protocol === 'https:')
|
|
17
|
+
return;
|
|
18
|
+
if (url.protocol === 'http:' && isLocalHttpCallbackHostname(url.hostname)) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
throw new Error(`${label} must be https://, http://localhost, or http://*.localhost, got: ${value}`);
|
|
22
|
+
}
|
|
23
|
+
export function validateWebhookUrl(value) {
|
|
24
|
+
let url;
|
|
25
|
+
try {
|
|
26
|
+
url = new URL(value);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
throw new Error(`Invalid webhook URL: ${value}`);
|
|
30
|
+
}
|
|
31
|
+
if (url.protocol !== 'https:') {
|
|
32
|
+
throw new Error(`webhook must be https://, got: ${value}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function isLocalHttpCallbackHostname(hostname) {
|
|
36
|
+
return (hostname === 'localhost' ||
|
|
37
|
+
hostname.endsWith('.localhost') ||
|
|
38
|
+
hostname === '127.0.0.1');
|
|
39
|
+
}
|
|
@@ -91,9 +91,9 @@ export declare class ConsentRequiredError extends Error {
|
|
|
91
91
|
* @param connector Vercel Connect connector UID (e.g. `oauth/linear`)
|
|
92
92
|
* or opaque connector id.
|
|
93
93
|
* @param params Token request parameters — always specify a
|
|
94
|
-
* `subject`; the
|
|
95
|
-
* (`'app'` / `'user'` / `'jwt-bearer'`) have distinct
|
|
96
|
-
* semantics.
|
|
94
|
+
* `subject`; the supported subject types
|
|
95
|
+
* (`'app'` / `'user'` / `'jwt-bearer'` / `'token'`) have distinct
|
|
96
|
+
* security semantics.
|
|
97
97
|
* @param options Optional adapter behavior overrides.
|
|
98
98
|
*/
|
|
99
99
|
export declare function connectAuthProvider(connector: string, params: ConnectTokenParams, options?: ConnectAuthProviderOptions): OAuthClientProvider;
|
|
@@ -41,9 +41,9 @@ const EMPTY_CLIENT_METADATA = {
|
|
|
41
41
|
* @param connector Vercel Connect connector UID (e.g. `oauth/linear`)
|
|
42
42
|
* or opaque connector id.
|
|
43
43
|
* @param params Token request parameters — always specify a
|
|
44
|
-
* `subject`; the
|
|
45
|
-
* (`'app'` / `'user'` / `'jwt-bearer'`) have distinct
|
|
46
|
-
* semantics.
|
|
44
|
+
* `subject`; the supported subject types
|
|
45
|
+
* (`'app'` / `'user'` / `'jwt-bearer'` / `'token'`) have distinct
|
|
46
|
+
* security semantics.
|
|
47
47
|
* @param options Optional adapter behavior overrides.
|
|
48
48
|
*/
|
|
49
49
|
export function connectAuthProvider(connector, params, options) {
|
package/dist/mcp/index.d.ts
CHANGED
|
@@ -30,4 +30,4 @@
|
|
|
30
30
|
* ```
|
|
31
31
|
*/
|
|
32
32
|
export { connectAuthProvider, ConsentRequiredError, type ConnectAuthProviderOptions, type ConsentChallenge, } from './connect-auth-provider.js';
|
|
33
|
-
export { ConnectError, ConnectorInstallationRequiredError, NoValidTokenError, UserAuthorizationRequiredError, type ConnectErrorOptions, type ConnectTokenParams, type ConnectTokenSubject, type ConnectVendorErrorPayload, } from '../token.js';
|
|
33
|
+
export { ConnectError, ConnectorInstallationRequiredError, NoValidTokenError, UserAuthorizationRequiredError, type ConnectErrorOptions, type ConnectTokenExchangeSubject, type ConnectTokenParams, type ConnectTokenSubject, type ConnectVendorErrorPayload, } from '../token.js';
|
package/dist/token.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ConnectAuthorizationDetail } from './authorization-details.js';
|
|
2
|
-
export type ConnectSubjectType = 'app' | 'user' | 'jwt-bearer';
|
|
3
|
-
export type ConnectTokenSubject = ConnectAppTokenSubject | ConnectUserTokenSubject | ConnectJwtBearerTokenSubject;
|
|
2
|
+
export type ConnectSubjectType = 'app' | 'user' | 'jwt-bearer' | 'token';
|
|
3
|
+
export type ConnectTokenSubject = ConnectAppTokenSubject | ConnectUserTokenSubject | ConnectJwtBearerTokenSubject | ConnectTokenExchangeSubject;
|
|
4
4
|
export interface ConnectAppTokenSubject {
|
|
5
5
|
type: 'app';
|
|
6
6
|
}
|
|
@@ -18,6 +18,10 @@ export interface ConnectJwtBearerTokenSubject {
|
|
|
18
18
|
aud?: string;
|
|
19
19
|
additionalClaims?: Record<string, unknown>;
|
|
20
20
|
}
|
|
21
|
+
export interface ConnectTokenExchangeSubject {
|
|
22
|
+
type: 'token';
|
|
23
|
+
token: string;
|
|
24
|
+
}
|
|
21
25
|
export interface ConnectTokenParams {
|
|
22
26
|
subject: ConnectTokenSubject;
|
|
23
27
|
installationId?: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vercel/connect",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"dist"
|
|
43
43
|
],
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@vercel/oidc": "3.8.
|
|
45
|
+
"@vercel/oidc": "3.8.1"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
48
|
"@ai-sdk/mcp": "^1 || ^2",
|