@withone/connect 0.19.0 → 0.20.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 +13 -3
- package/dist/config.cjs.js +7 -0
- package/dist/config.d.ts +18 -5
- package/dist/config.esm.js +7 -0
- package/dist/types.d.ts +3 -3
- package/package.json +1 -1
- package/skills/one-connect/SKILL.md +9 -4
- package/src/config.ts +18 -3
- package/src/types.ts +3 -3
package/README.md
CHANGED
|
@@ -57,7 +57,7 @@ The button, the routes and the calls are the same either way. Only what your ser
|
|
|
57
57
|
| Expires | Nothing | The access token per your app's Token lifetime; the refresh token after 30 days |
|
|
58
58
|
| You also run | Nothing | A daily refresh job |
|
|
59
59
|
| When a user revokes | The next call throws `reconnect_required` | The next refresh throws `refresh_failed` |
|
|
60
|
-
| A call outside the grant | `403` with `blockedByGrant: true` |
|
|
60
|
+
| A call outside the grant | `403` with `blockedByGrant: true` | The same |
|
|
61
61
|
| Pick it when | You are starting out | You need the bearer token itself, or your app already stores tokens |
|
|
62
62
|
|
|
63
63
|
The mode is the credential you pass to `createOneConnect`: `connectKey` and `userStore` for key mode, `tokenStore` for token mode. Sections 1 to 6 use key mode; [section 7](#7--token-mode) shows what changes for token mode.
|
|
@@ -104,12 +104,22 @@ export default defineConnectApp({
|
|
|
104
104
|
});
|
|
105
105
|
```
|
|
106
106
|
|
|
107
|
+
An agent or CLI that works across whatever its users have asks for everything instead:
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
export default defineConnectApp({
|
|
111
|
+
name: "Mastra",
|
|
112
|
+
redirectUris: ["http://localhost:3000/api/one/callback"],
|
|
113
|
+
ask: "everything",
|
|
114
|
+
});
|
|
115
|
+
```
|
|
116
|
+
|
|
107
117
|
```bash
|
|
108
118
|
one connect types # optional: tool slugs and action names autocomplete
|
|
109
119
|
one connect create # opens your browser to approve it, then writes .env
|
|
110
120
|
```
|
|
111
121
|
|
|
112
|
-
The CLI opens a page in your signed-in browser showing the app as your users will see it. You approve it there; a new app's client secret and connect key are made on that page and shown once, so they never pass through the terminal. The CLI then writes `ONE_CLIENT_ID`, `
|
|
122
|
+
The CLI opens a page in your signed-in browser showing the app as your users will see it. You approve it there; a new app's client secret and connect key are made on that page and shown once, so they never pass through the terminal. The CLI then writes `ONE_CLIENT_ID`, `ONE_REDIRECT_URI` and, for a list of tools, `ONE_PERMISSION_SET` to `.env` (an app that asks for everything has none, so the CLI removes it). `access` is `read-only`, `read-write`, `full-access`, or `custom` with `actions`, named as `one connect types` wrote them or by id. On Node older than 22.18, name the file `one.connect.mjs` and type it with `/** @type {import("@withone/connect/config").ConnectAppConfig} */`.
|
|
113
123
|
|
|
114
124
|
| Prop | |
|
|
115
125
|
|---|---|
|
|
@@ -117,7 +127,7 @@ The CLI opens a page in your signed-in browser showing the app as your users wil
|
|
|
117
127
|
| `reason` | One sentence on the card telling users why, at most 200 characters. |
|
|
118
128
|
| `description`, `logoUrl`, `homepageUrl` | Optional. |
|
|
119
129
|
| `branding` | `panelColor`, `buttonColor` (`#RRGGBB`), `cobrandEmail`. |
|
|
120
|
-
| `ask` | Per tool slug: `access` is `read-only`, `read-write`, `full-access`, or `custom` with `actions
|
|
130
|
+
| `ask` | Required. Per tool slug: `access` is `read-only`, `read-write`, `full-access`, or `custom` with `actions`; users see those and can only narrow them. Or `"everything"`: users see every connection they have at full access, can connect any other app from Popular apps or Browse all, and can narrow any of them. |
|
|
121
131
|
|
|
122
132
|
## 2 · The server client
|
|
123
133
|
|
package/dist/config.cjs.js
CHANGED
|
@@ -16,6 +16,9 @@
|
|
|
16
16
|
* },
|
|
17
17
|
* });
|
|
18
18
|
*
|
|
19
|
+
* Or, for an agent or CLI that works across whatever its users have,
|
|
20
|
+
* `ask: "everything"`.
|
|
21
|
+
*
|
|
19
22
|
* Types and one identity helper; nothing here calls One. `one connect
|
|
20
23
|
* create` reads the file and opens a page in your signed-in browser, where
|
|
21
24
|
* you approve the app (or, on a re-run, its new version). A new app's
|
|
@@ -54,6 +57,10 @@
|
|
|
54
57
|
|
|
55
58
|
/** One tool's ask: a level, or a hand-picked list of actions. */
|
|
56
59
|
|
|
60
|
+
/** The tools an app asks for, keyed by slug. */
|
|
61
|
+
|
|
62
|
+
/** What an app asks for: named tools, or everything its users have. */
|
|
63
|
+
|
|
57
64
|
/** A colour as `#RRGGBB`. */
|
|
58
65
|
|
|
59
66
|
/** How the connect card and its sign-in email look. Omit it to keep
|
package/dist/config.d.ts
CHANGED
|
@@ -14,6 +14,9 @@
|
|
|
14
14
|
* },
|
|
15
15
|
* });
|
|
16
16
|
*
|
|
17
|
+
* Or, for an agent or CLI that works across whatever its users have,
|
|
18
|
+
* `ask: "everything"`.
|
|
19
|
+
*
|
|
17
20
|
* Types and one identity helper; nothing here calls One. `one connect
|
|
18
21
|
* create` reads the file and opens a page in your signed-in browser, where
|
|
19
22
|
* you approve the app (or, on a re-run, its new version). A new app's
|
|
@@ -61,6 +64,12 @@ export type ConnectToolAsk<T extends string = string> = {
|
|
|
61
64
|
access: "custom";
|
|
62
65
|
actions: readonly [ConnectActionRef<T>, ...ConnectActionRef<T>[]];
|
|
63
66
|
};
|
|
67
|
+
/** The tools an app asks for, keyed by slug. */
|
|
68
|
+
export type ConnectToolsAsk = {
|
|
69
|
+
[T in ConnectToolSlug]?: ConnectToolAsk<T>;
|
|
70
|
+
};
|
|
71
|
+
/** What an app asks for: named tools, or everything its users have. */
|
|
72
|
+
export type ConnectAppAsk = ConnectToolsAsk | "everything";
|
|
64
73
|
/** A colour as `#RRGGBB`. */
|
|
65
74
|
export type ConnectHexColor = `#${string}`;
|
|
66
75
|
/** How the connect card and its sign-in email look. Omit it to keep
|
|
@@ -88,11 +97,15 @@ export interface ConnectAppConfig {
|
|
|
88
97
|
* 200 characters. */
|
|
89
98
|
reason?: string;
|
|
90
99
|
branding?: ConnectAppBranding;
|
|
91
|
-
/**
|
|
92
|
-
*
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
100
|
+
/**
|
|
101
|
+
* What the app asks for. Required, so the file always says it:
|
|
102
|
+
* - a map of tools, keyed by slug: users see exactly those and can only
|
|
103
|
+
* narrow them;
|
|
104
|
+
* - `"everything"`: users see every connection they have, at full
|
|
105
|
+
* access, and can connect any other app from Popular apps or Browse
|
|
106
|
+
* all. They can narrow any of them before they authorize.
|
|
107
|
+
*/
|
|
108
|
+
ask: ConnectAppAsk;
|
|
96
109
|
}
|
|
97
110
|
/**
|
|
98
111
|
* Returns `config` unchanged. It exists for the editor: the argument is
|
package/dist/config.esm.js
CHANGED
|
@@ -14,6 +14,9 @@
|
|
|
14
14
|
* },
|
|
15
15
|
* });
|
|
16
16
|
*
|
|
17
|
+
* Or, for an agent or CLI that works across whatever its users have,
|
|
18
|
+
* `ask: "everything"`.
|
|
19
|
+
*
|
|
17
20
|
* Types and one identity helper; nothing here calls One. `one connect
|
|
18
21
|
* create` reads the file and opens a page in your signed-in browser, where
|
|
19
22
|
* you approve the app (or, on a re-run, its new version). A new app's
|
|
@@ -52,6 +55,10 @@
|
|
|
52
55
|
|
|
53
56
|
/** One tool's ask: a level, or a hand-picked list of actions. */
|
|
54
57
|
|
|
58
|
+
/** The tools an app asks for, keyed by slug. */
|
|
59
|
+
|
|
60
|
+
/** What an app asks for: named tools, or everything its users have. */
|
|
61
|
+
|
|
55
62
|
/** A colour as `#RRGGBB`. */
|
|
56
63
|
|
|
57
64
|
/** How the connect card and its sign-in email look. Omit it to keep
|
package/dist/types.d.ts
CHANGED
|
@@ -77,9 +77,9 @@ export interface ConnectButtonLogo {
|
|
|
77
77
|
name: string;
|
|
78
78
|
imageUrl: string;
|
|
79
79
|
}
|
|
80
|
-
/** @deprecated Renamed to `ConnectButtonLogoInput`; removed in 0.
|
|
80
|
+
/** @deprecated Renamed to `ConnectButtonLogoInput`; removed in 0.21.0. */
|
|
81
81
|
export type ConnectButtonPlatformInput = ConnectButtonLogoInput;
|
|
82
|
-
/** @deprecated Renamed to `ConnectButtonLogo`; removed in 0.
|
|
82
|
+
/** @deprecated Renamed to `ConnectButtonLogo`; removed in 0.21.0. */
|
|
83
83
|
export type ConnectButtonPlatform = ConnectButtonLogo;
|
|
84
84
|
export type ConnectButtonVariant = "default" | "accent" | "block";
|
|
85
85
|
export type ConnectButtonSize = "sm" | "md" | "lg";
|
|
@@ -94,7 +94,7 @@ export interface ConnectButtonProps {
|
|
|
94
94
|
* into a "+N" chip. Decoration only; the permission set decides what
|
|
95
95
|
* One asks for. */
|
|
96
96
|
logos?: ConnectButtonLogoInput[];
|
|
97
|
-
/** @deprecated Renamed to `logos`; removed in 0.
|
|
97
|
+
/** @deprecated Renamed to `logos`; removed in 0.21.0. */
|
|
98
98
|
platforms?: ConnectButtonLogoInput[];
|
|
99
99
|
/** Whether this user has a live grant, from your server. When set, it
|
|
100
100
|
* decides the Connected state. When omitted, the button shows
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@withone/connect",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"description": "One Connect for your app: the button your users press, the two backend routes as one import, and a server client that calls One with the grant. Users keep their connections in One; your app holds only what they granted.",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -30,7 +30,7 @@ the server keeps differs.
|
|
|
30
30
|
| Server keeps | one connect key for the app, one id per user | an access and a refresh token per user |
|
|
31
31
|
| Expires | nothing | yes; the app runs a daily refresh job |
|
|
32
32
|
| User revoked | next call throws `reconnect_required` | next refresh throws `refresh_failed` |
|
|
33
|
-
| Call outside the grant | `403`, `blockedByGrant: true` |
|
|
33
|
+
| Call outside the grant | `403`, `blockedByGrant: true` | the same |
|
|
34
34
|
|
|
35
35
|
Use **key mode** unless the human asks for token mode, the app needs the
|
|
36
36
|
bearer token itself, or the app already passes a `tokenStore`. Do not switch
|
|
@@ -61,7 +61,7 @@ export default defineConnectApp({
|
|
|
61
61
|
logoUrl: "https://acme.app/logo.png", // optional, square, public https
|
|
62
62
|
homepageUrl: "https://acme.app", // optional
|
|
63
63
|
branding: { panelColor: "#0A0C0B", buttonColor: "#0A0C0B", cobrandEmail: false }, // optional
|
|
64
|
-
ask: { //
|
|
64
|
+
ask: { // required: these tools, or "everything"
|
|
65
65
|
gmail: { access: "custom", actions: ["sendEmail", "listAndViewEmailThreads"] },
|
|
66
66
|
"google-calendar": { access: "full-access" },
|
|
67
67
|
notion: { access: "read-write" },
|
|
@@ -72,6 +72,11 @@ export default defineConnectApp({
|
|
|
72
72
|
Each tool in `ask` is keyed by its slug and takes `access`: `read-only`,
|
|
73
73
|
`read-write` (no deletes), `full-access`, or `custom` with `actions`.
|
|
74
74
|
|
|
75
|
+
For an agent or CLI that works across whatever its users have, write
|
|
76
|
+
`ask: "everything"` instead: users see every connection they have, at full
|
|
77
|
+
access, can connect any other app, and can narrow any of them. The CLI then
|
|
78
|
+
writes no `ONE_PERMISSION_SET`.
|
|
79
|
+
|
|
75
80
|
**2. Find slugs and action names** with the CLI, which reads One's catalog
|
|
76
81
|
with its own key:
|
|
77
82
|
|
|
@@ -396,8 +401,8 @@ const accessToken = await oneConnect.getAccessToken(userId); // when the app nee
|
|
|
396
401
|
- When the user revokes access, the next refresh throws `refresh_failed`
|
|
397
402
|
(not `reconnect_required`) and the tokens are cleared. Ask them to connect
|
|
398
403
|
again.
|
|
399
|
-
-
|
|
400
|
-
|
|
404
|
+
- A call outside the grant comes back as in key mode: `403`,
|
|
405
|
+
`blockedByGrant: true`, `refusal: "grant"`.
|
|
401
406
|
|
|
402
407
|
Tokens expire, and two things keep them fresh. Only the first is automatic:
|
|
403
408
|
|
package/src/config.ts
CHANGED
|
@@ -14,6 +14,9 @@
|
|
|
14
14
|
* },
|
|
15
15
|
* });
|
|
16
16
|
*
|
|
17
|
+
* Or, for an agent or CLI that works across whatever its users have,
|
|
18
|
+
* `ask: "everything"`.
|
|
19
|
+
*
|
|
17
20
|
* Types and one identity helper; nothing here calls One. `one connect
|
|
18
21
|
* create` reads the file and opens a page in your signed-in browser, where
|
|
19
22
|
* you approve the app (or, on a re-run, its new version). A new app's
|
|
@@ -74,6 +77,12 @@ export type ConnectToolAsk<T extends string = string> =
|
|
|
74
77
|
actions: readonly [ConnectActionRef<T>, ...ConnectActionRef<T>[]];
|
|
75
78
|
};
|
|
76
79
|
|
|
80
|
+
/** The tools an app asks for, keyed by slug. */
|
|
81
|
+
export type ConnectToolsAsk = { [T in ConnectToolSlug]?: ConnectToolAsk<T> };
|
|
82
|
+
|
|
83
|
+
/** What an app asks for: named tools, or everything its users have. */
|
|
84
|
+
export type ConnectAppAsk = ConnectToolsAsk | "everything";
|
|
85
|
+
|
|
77
86
|
/** A colour as `#RRGGBB`. */
|
|
78
87
|
export type ConnectHexColor = `#${string}`;
|
|
79
88
|
|
|
@@ -103,9 +112,15 @@ export interface ConnectAppConfig {
|
|
|
103
112
|
* 200 characters. */
|
|
104
113
|
reason?: string;
|
|
105
114
|
branding?: ConnectAppBranding;
|
|
106
|
-
/**
|
|
107
|
-
*
|
|
108
|
-
|
|
115
|
+
/**
|
|
116
|
+
* What the app asks for. Required, so the file always says it:
|
|
117
|
+
* - a map of tools, keyed by slug: users see exactly those and can only
|
|
118
|
+
* narrow them;
|
|
119
|
+
* - `"everything"`: users see every connection they have, at full
|
|
120
|
+
* access, and can connect any other app from Popular apps or Browse
|
|
121
|
+
* all. They can narrow any of them before they authorize.
|
|
122
|
+
*/
|
|
123
|
+
ask: ConnectAppAsk;
|
|
109
124
|
}
|
|
110
125
|
|
|
111
126
|
/**
|
package/src/types.ts
CHANGED
|
@@ -83,9 +83,9 @@ export interface ConnectButtonLogo {
|
|
|
83
83
|
imageUrl: string;
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
/** @deprecated Renamed to `ConnectButtonLogoInput`; removed in 0.
|
|
86
|
+
/** @deprecated Renamed to `ConnectButtonLogoInput`; removed in 0.21.0. */
|
|
87
87
|
export type ConnectButtonPlatformInput = ConnectButtonLogoInput;
|
|
88
|
-
/** @deprecated Renamed to `ConnectButtonLogo`; removed in 0.
|
|
88
|
+
/** @deprecated Renamed to `ConnectButtonLogo`; removed in 0.21.0. */
|
|
89
89
|
export type ConnectButtonPlatform = ConnectButtonLogo;
|
|
90
90
|
|
|
91
91
|
export type ConnectButtonVariant = "default" | "accent" | "block";
|
|
@@ -102,7 +102,7 @@ export interface ConnectButtonProps {
|
|
|
102
102
|
* into a "+N" chip. Decoration only; the permission set decides what
|
|
103
103
|
* One asks for. */
|
|
104
104
|
logos?: ConnectButtonLogoInput[];
|
|
105
|
-
/** @deprecated Renamed to `logos`; removed in 0.
|
|
105
|
+
/** @deprecated Renamed to `logos`; removed in 0.21.0. */
|
|
106
106
|
platforms?: ConnectButtonLogoInput[];
|
|
107
107
|
/** Whether this user has a live grant, from your server. When set, it
|
|
108
108
|
* decides the Connected state. When omitted, the button shows
|