@project-ajax/sdk 0.0.66 → 0.0.67
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/capabilities/oauth.d.ts +145 -0
- package/dist/capabilities/oauth.d.ts.map +1 -0
- package/dist/capabilities/oauth.js +53 -0
- package/dist/capabilities/oauth.test.d.ts +2 -0
- package/dist/capabilities/oauth.test.d.ts.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/package.json +1 -1
- package/src/capabilities/oauth.test.ts +51 -0
- package/src/capabilities/oauth.ts +181 -0
- package/src/index.ts +6 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration for a Notion-managed OAuth provider.
|
|
3
|
+
*
|
|
4
|
+
* Notion owns the OAuth app credentials (client ID/secret) and the backend has
|
|
5
|
+
* pre-configured provider settings.
|
|
6
|
+
*/
|
|
7
|
+
export interface NotionManagedOAuthConfiguration {
|
|
8
|
+
/**
|
|
9
|
+
* The unique identifier for this OAuth provider instance.
|
|
10
|
+
*/
|
|
11
|
+
name: string;
|
|
12
|
+
/**
|
|
13
|
+
* The pre-configured provider to use (e.g., "google", "github", "salesforce").
|
|
14
|
+
* The backend will use this to look up the OAuth configuration.
|
|
15
|
+
*/
|
|
16
|
+
provider: string;
|
|
17
|
+
/**
|
|
18
|
+
* Optional default access token expiry (in milliseconds) to use when the OAuth provider
|
|
19
|
+
* does not return `expires_in` in token responses.
|
|
20
|
+
*
|
|
21
|
+
* Some providers (e.g. Salesforce in certain configurations) may omit expiry information.
|
|
22
|
+
*/
|
|
23
|
+
accessTokenExpireMs?: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Configuration for a user-managed OAuth provider.
|
|
27
|
+
*
|
|
28
|
+
* You own the OAuth app credentials and must explicitly provide endpoints and
|
|
29
|
+
* other OAuth parameters.
|
|
30
|
+
*/
|
|
31
|
+
export interface UserManagedOAuthConfiguration {
|
|
32
|
+
/**
|
|
33
|
+
* The unique identifier for this OAuth provider instance.
|
|
34
|
+
*/
|
|
35
|
+
name: string;
|
|
36
|
+
/**
|
|
37
|
+
* The client ID for the OAuth app.
|
|
38
|
+
*/
|
|
39
|
+
clientId: string;
|
|
40
|
+
/**
|
|
41
|
+
* The client secret for the OAuth app.
|
|
42
|
+
*/
|
|
43
|
+
clientSecret: string;
|
|
44
|
+
/**
|
|
45
|
+
* The OAuth 2.0 authorization endpoint URL.
|
|
46
|
+
*/
|
|
47
|
+
authorizationEndpoint: string;
|
|
48
|
+
/**
|
|
49
|
+
* The OAuth 2.0 token endpoint URL.
|
|
50
|
+
*/
|
|
51
|
+
tokenEndpoint: string;
|
|
52
|
+
/**
|
|
53
|
+
* The OAuth scope(s) to request.
|
|
54
|
+
*/
|
|
55
|
+
scope: string;
|
|
56
|
+
/**
|
|
57
|
+
* Optional additional authorization parameters to include in the authorization request.
|
|
58
|
+
*/
|
|
59
|
+
authorizationParams?: Record<string, string>;
|
|
60
|
+
/**
|
|
61
|
+
* Optional callback URL for OAuth redirect.
|
|
62
|
+
*/
|
|
63
|
+
callbackUrl?: string;
|
|
64
|
+
/**
|
|
65
|
+
* Optional default access token expiry (in milliseconds) to use when the OAuth provider
|
|
66
|
+
* does not return `expires_in` in token responses.
|
|
67
|
+
*
|
|
68
|
+
* Some providers (e.g. Salesforce in certain configurations) may omit expiry information.
|
|
69
|
+
*/
|
|
70
|
+
accessTokenExpireMs?: number;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Union type representing either Notion-managed or user-managed OAuth configuration.
|
|
74
|
+
*/
|
|
75
|
+
export type OAuthConfiguration = NotionManagedOAuthConfiguration | UserManagedOAuthConfiguration;
|
|
76
|
+
/**
|
|
77
|
+
* Creates an OAuth provider configuration for authenticating with third-party services.
|
|
78
|
+
*
|
|
79
|
+
* There are two ways to configure OAuth:
|
|
80
|
+
*
|
|
81
|
+
* 1. Notion-managed providers:
|
|
82
|
+
* ```ts
|
|
83
|
+
* oauth({
|
|
84
|
+
* type: "notion_managed",
|
|
85
|
+
* name: "my-google-auth",
|
|
86
|
+
* provider: "google"
|
|
87
|
+
* })
|
|
88
|
+
* ```
|
|
89
|
+
*
|
|
90
|
+
* 2. User-managed OAuth configuration:
|
|
91
|
+
* ```ts
|
|
92
|
+
* oauth({
|
|
93
|
+
* type: "user_managed",
|
|
94
|
+
* name: "my-custom-oauth",
|
|
95
|
+
* authorizationEndpoint: "https://provider.com/oauth/authorize",
|
|
96
|
+
* tokenEndpoint: "https://provider.com/oauth/token",
|
|
97
|
+
* scope: "read write",
|
|
98
|
+
* clientId: process.env.CLIENT_ID,
|
|
99
|
+
* clientSecret: process.env.CLIENT_SECRET,
|
|
100
|
+
* authorizationParams: {
|
|
101
|
+
* access_type: "offline",
|
|
102
|
+
* prompt: "consent"
|
|
103
|
+
* }
|
|
104
|
+
* })
|
|
105
|
+
* ```
|
|
106
|
+
*
|
|
107
|
+
* @param config - The OAuth configuration (Notion-managed or user-managed).
|
|
108
|
+
* @returns An OAuth provider definition.
|
|
109
|
+
*/
|
|
110
|
+
export declare function oauth(config: OAuthConfiguration): {
|
|
111
|
+
_tag: string;
|
|
112
|
+
envKey: string;
|
|
113
|
+
accessToken(): Promise<string>;
|
|
114
|
+
config: {
|
|
115
|
+
type: "notion_managed";
|
|
116
|
+
name: string;
|
|
117
|
+
provider: string;
|
|
118
|
+
accessTokenExpireMs: number | undefined;
|
|
119
|
+
authorizationEndpoint?: never;
|
|
120
|
+
tokenEndpoint?: never;
|
|
121
|
+
scope?: never;
|
|
122
|
+
clientId?: never;
|
|
123
|
+
clientSecret?: never;
|
|
124
|
+
authorizationParams?: never;
|
|
125
|
+
callbackUrl?: never;
|
|
126
|
+
};
|
|
127
|
+
} | {
|
|
128
|
+
_tag: string;
|
|
129
|
+
envKey: string;
|
|
130
|
+
accessToken(): Promise<string>;
|
|
131
|
+
config: {
|
|
132
|
+
type: "user_managed";
|
|
133
|
+
name: string;
|
|
134
|
+
authorizationEndpoint: string;
|
|
135
|
+
tokenEndpoint: string;
|
|
136
|
+
scope: string;
|
|
137
|
+
clientId: string;
|
|
138
|
+
clientSecret: string;
|
|
139
|
+
authorizationParams: Record<string, string> | undefined;
|
|
140
|
+
callbackUrl: string | undefined;
|
|
141
|
+
accessTokenExpireMs: number | undefined;
|
|
142
|
+
provider?: never;
|
|
143
|
+
};
|
|
144
|
+
};
|
|
145
|
+
//# sourceMappingURL=oauth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../src/capabilities/oauth.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,WAAW,+BAA+B;IAC/C;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;GAKG;AACH,MAAM,WAAW,6BAA6B;IAC7C;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,qBAAqB,EAAE,MAAM,CAAC;IAE9B;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE7C;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAC3B,+BAA+B,GAC/B,6BAA6B,CAAC;AAEjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,KAAK,CAAC,MAAM,EAAE,kBAAkB;;;mBAOxB,OAAO,CAAC,MAAM,CAAC;;;;;;;;;;;;;;;;;mBAehB,OAAO,CAAC,MAAM,CAAC;;;;;;;;;;;;;;EAgBrC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
function oauth(config) {
|
|
2
|
+
const envKey = oauthNameToEnvKey(config.name);
|
|
3
|
+
if ("provider" in config) {
|
|
4
|
+
return {
|
|
5
|
+
_tag: "oauth",
|
|
6
|
+
envKey,
|
|
7
|
+
async accessToken() {
|
|
8
|
+
return readRequiredEnvVar(envKey, { name: config.name });
|
|
9
|
+
},
|
|
10
|
+
config: {
|
|
11
|
+
type: "notion_managed",
|
|
12
|
+
name: config.name,
|
|
13
|
+
provider: config.provider,
|
|
14
|
+
accessTokenExpireMs: config.accessTokenExpireMs
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
_tag: "oauth",
|
|
20
|
+
envKey,
|
|
21
|
+
async accessToken() {
|
|
22
|
+
return readRequiredEnvVar(envKey, { name: config.name });
|
|
23
|
+
},
|
|
24
|
+
config: {
|
|
25
|
+
type: "user_managed",
|
|
26
|
+
name: config.name,
|
|
27
|
+
authorizationEndpoint: config.authorizationEndpoint,
|
|
28
|
+
tokenEndpoint: config.tokenEndpoint,
|
|
29
|
+
scope: config.scope,
|
|
30
|
+
clientId: config.clientId,
|
|
31
|
+
clientSecret: config.clientSecret,
|
|
32
|
+
authorizationParams: config.authorizationParams,
|
|
33
|
+
callbackUrl: config.callbackUrl,
|
|
34
|
+
accessTokenExpireMs: config.accessTokenExpireMs
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function oauthNameToEnvKey(identifier) {
|
|
39
|
+
const encoded = Buffer.from(identifier).toString("hex").toUpperCase();
|
|
40
|
+
return `OAUTH_${encoded}_ACCESS_TOKEN`;
|
|
41
|
+
}
|
|
42
|
+
function readRequiredEnvVar(key, context) {
|
|
43
|
+
const value = process.env[key];
|
|
44
|
+
if (value) {
|
|
45
|
+
return value;
|
|
46
|
+
}
|
|
47
|
+
throw new Error(
|
|
48
|
+
`Missing OAuth access token env var "${key}" (name: "${context.name}"). Make sure you've completed OAuth for this capability and are running inside the worker runtime.`
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
export {
|
|
52
|
+
oauth
|
|
53
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth.test.d.ts","sourceRoot":"","sources":["../../src/capabilities/oauth.test.ts"],"names":[],"mappings":""}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export { emojiIcon, imageIcon, notionIcon } from "./builder.js";
|
|
2
2
|
export type { AutomationConfiguration, AutomationContext, PageObjectResponse, } from "./capabilities/automation.js";
|
|
3
3
|
export { automation } from "./capabilities/automation.js";
|
|
4
|
+
export type { NotionManagedOAuthConfiguration, OAuthConfiguration, UserManagedOAuthConfiguration, } from "./capabilities/oauth.js";
|
|
5
|
+
export { oauth } from "./capabilities/oauth.js";
|
|
4
6
|
export type { SyncConfiguration, SyncExecutionResult, SyncedObject, } from "./capabilities/sync.js";
|
|
5
7
|
export { sync } from "./capabilities/sync.js";
|
|
6
8
|
export { tool } from "./capabilities/tool.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAChE,YAAY,EACX,uBAAuB,EACvB,iBAAiB,EACjB,kBAAkB,GAClB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,YAAY,EACX,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,GACZ,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAC9C,YAAY,EACX,IAAI,EACJ,SAAS,EACT,YAAY,EACZ,WAAW,EACX,QAAQ,GACR,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAChE,YAAY,EACX,uBAAuB,EACvB,iBAAiB,EACjB,kBAAkB,GAClB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,YAAY,EACX,+BAA+B,EAC/B,kBAAkB,EAClB,6BAA6B,GAC7B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAChD,YAAY,EACX,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,GACZ,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAC9C,YAAY,EACX,IAAI,EACJ,SAAS,EACT,YAAY,EACZ,WAAW,EACX,QAAQ,GACR,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { emojiIcon, imageIcon, notionIcon } from "./builder.js";
|
|
2
2
|
import { automation } from "./capabilities/automation.js";
|
|
3
|
+
import { oauth } from "./capabilities/oauth.js";
|
|
3
4
|
import { sync } from "./capabilities/sync.js";
|
|
4
5
|
import { tool } from "./capabilities/tool.js";
|
|
5
6
|
export {
|
|
@@ -7,6 +8,7 @@ export {
|
|
|
7
8
|
emojiIcon,
|
|
8
9
|
imageIcon,
|
|
9
10
|
notionIcon,
|
|
11
|
+
oauth,
|
|
10
12
|
sync,
|
|
11
13
|
tool
|
|
12
14
|
};
|
package/package.json
CHANGED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
2
|
+
import { oauth } from "./oauth.js";
|
|
3
|
+
|
|
4
|
+
describe("oauth", () => {
|
|
5
|
+
afterEach(() => {
|
|
6
|
+
// Clean up env changes between tests
|
|
7
|
+
delete process.env.OAUTH_676F6F676C6541757468_ACCESS_TOKEN;
|
|
8
|
+
delete process.env.OAUTH_676F6F676C652D63616C656E646172_ACCESS_TOKEN;
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it("creates notion-managed oauth capability with accessToken helper", async () => {
|
|
12
|
+
const myOauth = oauth({
|
|
13
|
+
name: "googleAuth",
|
|
14
|
+
provider: "google",
|
|
15
|
+
accessTokenExpireMs: 60_000,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
expect(myOauth._tag).toBe("oauth");
|
|
19
|
+
expect(myOauth.config.type).toBe("notion_managed");
|
|
20
|
+
expect(myOauth.config.accessTokenExpireMs).toBe(60_000);
|
|
21
|
+
expect(myOauth.envKey).toBe("OAUTH_676F6F676C6541757468_ACCESS_TOKEN");
|
|
22
|
+
expect(typeof myOauth.accessToken).toBe("function");
|
|
23
|
+
|
|
24
|
+
process.env.OAUTH_676F6F676C6541757468_ACCESS_TOKEN = "token-123";
|
|
25
|
+
await expect(myOauth.accessToken()).resolves.toBe("token-123");
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("normalizes non-alphanumeric characters in the identifier", () => {
|
|
29
|
+
const myOauth = oauth({
|
|
30
|
+
name: "google-calendar",
|
|
31
|
+
provider: "google",
|
|
32
|
+
accessTokenExpireMs: 3600_000,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
expect(myOauth.envKey).toBe(
|
|
36
|
+
"OAUTH_676F6F676C652D63616C656E646172_ACCESS_TOKEN",
|
|
37
|
+
);
|
|
38
|
+
expect(myOauth.config.accessTokenExpireMs).toBe(3600_000);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("throws a helpful error when the token env var is missing", async () => {
|
|
42
|
+
const myOauth = oauth({
|
|
43
|
+
name: "googleAuth",
|
|
44
|
+
provider: "google",
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
await expect(myOauth.accessToken()).rejects.toThrow(
|
|
48
|
+
/Missing OAuth access token env var "OAUTH_676F6F676C6541757468_ACCESS_TOKEN"/,
|
|
49
|
+
);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration for a Notion-managed OAuth provider.
|
|
3
|
+
*
|
|
4
|
+
* Notion owns the OAuth app credentials (client ID/secret) and the backend has
|
|
5
|
+
* pre-configured provider settings.
|
|
6
|
+
*/
|
|
7
|
+
export interface NotionManagedOAuthConfiguration {
|
|
8
|
+
/**
|
|
9
|
+
* The unique identifier for this OAuth provider instance.
|
|
10
|
+
*/
|
|
11
|
+
name: string;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The pre-configured provider to use (e.g., "google", "github", "salesforce").
|
|
15
|
+
* The backend will use this to look up the OAuth configuration.
|
|
16
|
+
*/
|
|
17
|
+
provider: string;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Optional default access token expiry (in milliseconds) to use when the OAuth provider
|
|
21
|
+
* does not return `expires_in` in token responses.
|
|
22
|
+
*
|
|
23
|
+
* Some providers (e.g. Salesforce in certain configurations) may omit expiry information.
|
|
24
|
+
*/
|
|
25
|
+
accessTokenExpireMs?: number;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Configuration for a user-managed OAuth provider.
|
|
30
|
+
*
|
|
31
|
+
* You own the OAuth app credentials and must explicitly provide endpoints and
|
|
32
|
+
* other OAuth parameters.
|
|
33
|
+
*/
|
|
34
|
+
export interface UserManagedOAuthConfiguration {
|
|
35
|
+
/**
|
|
36
|
+
* The unique identifier for this OAuth provider instance.
|
|
37
|
+
*/
|
|
38
|
+
name: string;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* The client ID for the OAuth app.
|
|
42
|
+
*/
|
|
43
|
+
clientId: string;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* The client secret for the OAuth app.
|
|
47
|
+
*/
|
|
48
|
+
clientSecret: string;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* The OAuth 2.0 authorization endpoint URL.
|
|
52
|
+
*/
|
|
53
|
+
authorizationEndpoint: string;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* The OAuth 2.0 token endpoint URL.
|
|
57
|
+
*/
|
|
58
|
+
tokenEndpoint: string;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* The OAuth scope(s) to request.
|
|
62
|
+
*/
|
|
63
|
+
scope: string;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Optional additional authorization parameters to include in the authorization request.
|
|
67
|
+
*/
|
|
68
|
+
authorizationParams?: Record<string, string>;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Optional callback URL for OAuth redirect.
|
|
72
|
+
*/
|
|
73
|
+
callbackUrl?: string;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Optional default access token expiry (in milliseconds) to use when the OAuth provider
|
|
77
|
+
* does not return `expires_in` in token responses.
|
|
78
|
+
*
|
|
79
|
+
* Some providers (e.g. Salesforce in certain configurations) may omit expiry information.
|
|
80
|
+
*/
|
|
81
|
+
accessTokenExpireMs?: number;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Union type representing either Notion-managed or user-managed OAuth configuration.
|
|
86
|
+
*/
|
|
87
|
+
export type OAuthConfiguration =
|
|
88
|
+
| NotionManagedOAuthConfiguration
|
|
89
|
+
| UserManagedOAuthConfiguration;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Creates an OAuth provider configuration for authenticating with third-party services.
|
|
93
|
+
*
|
|
94
|
+
* There are two ways to configure OAuth:
|
|
95
|
+
*
|
|
96
|
+
* 1. Notion-managed providers:
|
|
97
|
+
* ```ts
|
|
98
|
+
* oauth({
|
|
99
|
+
* type: "notion_managed",
|
|
100
|
+
* name: "my-google-auth",
|
|
101
|
+
* provider: "google"
|
|
102
|
+
* })
|
|
103
|
+
* ```
|
|
104
|
+
*
|
|
105
|
+
* 2. User-managed OAuth configuration:
|
|
106
|
+
* ```ts
|
|
107
|
+
* oauth({
|
|
108
|
+
* type: "user_managed",
|
|
109
|
+
* name: "my-custom-oauth",
|
|
110
|
+
* authorizationEndpoint: "https://provider.com/oauth/authorize",
|
|
111
|
+
* tokenEndpoint: "https://provider.com/oauth/token",
|
|
112
|
+
* scope: "read write",
|
|
113
|
+
* clientId: process.env.CLIENT_ID,
|
|
114
|
+
* clientSecret: process.env.CLIENT_SECRET,
|
|
115
|
+
* authorizationParams: {
|
|
116
|
+
* access_type: "offline",
|
|
117
|
+
* prompt: "consent"
|
|
118
|
+
* }
|
|
119
|
+
* })
|
|
120
|
+
* ```
|
|
121
|
+
*
|
|
122
|
+
* @param config - The OAuth configuration (Notion-managed or user-managed).
|
|
123
|
+
* @returns An OAuth provider definition.
|
|
124
|
+
*/
|
|
125
|
+
export function oauth(config: OAuthConfiguration) {
|
|
126
|
+
const envKey = oauthNameToEnvKey(config.name);
|
|
127
|
+
|
|
128
|
+
if ("provider" in config) {
|
|
129
|
+
return {
|
|
130
|
+
_tag: "oauth",
|
|
131
|
+
envKey,
|
|
132
|
+
async accessToken(): Promise<string> {
|
|
133
|
+
return readRequiredEnvVar(envKey, { name: config.name });
|
|
134
|
+
},
|
|
135
|
+
config: {
|
|
136
|
+
type: "notion_managed" as const,
|
|
137
|
+
name: config.name,
|
|
138
|
+
provider: config.provider,
|
|
139
|
+
accessTokenExpireMs: config.accessTokenExpireMs,
|
|
140
|
+
},
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return {
|
|
145
|
+
_tag: "oauth",
|
|
146
|
+
envKey,
|
|
147
|
+
async accessToken(): Promise<string> {
|
|
148
|
+
return readRequiredEnvVar(envKey, { name: config.name });
|
|
149
|
+
},
|
|
150
|
+
config: {
|
|
151
|
+
type: "user_managed" as const,
|
|
152
|
+
name: config.name,
|
|
153
|
+
authorizationEndpoint: config.authorizationEndpoint,
|
|
154
|
+
tokenEndpoint: config.tokenEndpoint,
|
|
155
|
+
scope: config.scope,
|
|
156
|
+
clientId: config.clientId,
|
|
157
|
+
clientSecret: config.clientSecret,
|
|
158
|
+
authorizationParams: config.authorizationParams,
|
|
159
|
+
callbackUrl: config.callbackUrl,
|
|
160
|
+
accessTokenExpireMs: config.accessTokenExpireMs,
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function oauthNameToEnvKey(identifier: string): string {
|
|
166
|
+
const encoded = Buffer.from(identifier).toString("hex").toUpperCase();
|
|
167
|
+
|
|
168
|
+
return `OAUTH_${encoded}_ACCESS_TOKEN`;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function readRequiredEnvVar(key: string, context: { name: string }): string {
|
|
172
|
+
const value = process.env[key];
|
|
173
|
+
if (value) {
|
|
174
|
+
return value;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
throw new Error(
|
|
178
|
+
`Missing OAuth access token env var "${key}" (name: "${context.name}"). ` +
|
|
179
|
+
`Make sure you've completed OAuth for this capability and are running inside the worker runtime.`,
|
|
180
|
+
);
|
|
181
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -5,6 +5,12 @@ export type {
|
|
|
5
5
|
PageObjectResponse,
|
|
6
6
|
} from "./capabilities/automation.js";
|
|
7
7
|
export { automation } from "./capabilities/automation.js";
|
|
8
|
+
export type {
|
|
9
|
+
NotionManagedOAuthConfiguration,
|
|
10
|
+
OAuthConfiguration,
|
|
11
|
+
UserManagedOAuthConfiguration,
|
|
12
|
+
} from "./capabilities/oauth.js";
|
|
13
|
+
export { oauth } from "./capabilities/oauth.js";
|
|
8
14
|
export type {
|
|
9
15
|
SyncConfiguration,
|
|
10
16
|
SyncExecutionResult,
|