@protobase/server 0.69.1 → 0.69.2
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/better-auth/auth-settings.d.ts +22 -0
- package/dist/better-auth/connections/connection-events.d.ts +7 -0
- package/dist/better-auth/connections/connection-events.js +2 -1
- package/dist/better-auth/connections/connections-plugin.js +9 -19
- package/dist/better-auth/connections/list-connections.js +34 -0
- package/dist/better-auth/create-auth.d.ts +31 -2
- package/dist/better-auth/create-auth.js +11 -2
- package/dist/create-admin.js +1 -0
- package/dist/package.js +1 -1
- package/dist/workflows/connections/connection-uses.js +28 -0
- package/dist/workflows/mcp/connection-tools.d.ts +15 -0
- package/dist/workflows/mcp/connection-tools.js +32 -0
- package/dist/workflows/mcp/workflow-instructions.js +1 -1
- package/dist/workflows/mcp/workflow-read-tools.d.ts +4 -1
- package/dist/workflows/mcp/workflow-read-tools.js +4 -2
- package/dist/workflows/workflow-engine.js +9 -1
- package/package.json +6 -6
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { UserColumn } from "./user-table.js";
|
|
2
2
|
import { Mailer } from "../mail/mail-message.js";
|
|
3
|
+
import { Session } from "../types.js";
|
|
3
4
|
import { SignInPolicy } from "./sign-in-policy.js";
|
|
4
5
|
import { StaffSignIn } from "./staff-log.js";
|
|
5
6
|
import { Person } from "./organizations/people-endpoint.js";
|
|
@@ -3327,6 +3328,10 @@ export declare const buildAppAuth: (settings: AuthSettings, input: AppAuthInput)
|
|
|
3327
3328
|
scopes: string[];
|
|
3328
3329
|
created_at: Date;
|
|
3329
3330
|
needs_sign_in: boolean;
|
|
3331
|
+
used_by: {
|
|
3332
|
+
id: string;
|
|
3333
|
+
name: string;
|
|
3334
|
+
}[];
|
|
3330
3335
|
}[];
|
|
3331
3336
|
}[];
|
|
3332
3337
|
}>;
|
|
@@ -9157,6 +9162,23 @@ export declare const buildAppAuth: (settings: AuthSettings, input: AppAuthInput)
|
|
|
9157
9162
|
events: {
|
|
9158
9163
|
set: (next: ConnectionListener) => undefined;
|
|
9159
9164
|
};
|
|
9165
|
+
list: (session: Session) => Promise<{
|
|
9166
|
+
key: string;
|
|
9167
|
+
label: string;
|
|
9168
|
+
provider: string;
|
|
9169
|
+
scopes: string[];
|
|
9170
|
+
link_params: Record<string, string>;
|
|
9171
|
+
accounts: {
|
|
9172
|
+
id: string;
|
|
9173
|
+
scopes: string[];
|
|
9174
|
+
created_at: Date;
|
|
9175
|
+
needs_sign_in: boolean;
|
|
9176
|
+
used_by: {
|
|
9177
|
+
id: string;
|
|
9178
|
+
name: string;
|
|
9179
|
+
}[];
|
|
9180
|
+
}[];
|
|
9181
|
+
}[]>;
|
|
9160
9182
|
};
|
|
9161
9183
|
mcp: {
|
|
9162
9184
|
resource: string;
|
|
@@ -7,5 +7,12 @@ export type ConnectionListener = {
|
|
|
7
7
|
disconnected: (accountId: string) => Promise<void>;
|
|
8
8
|
/** The accounts among `accountIds` that a trigger waits on to be signed in again. */
|
|
9
9
|
needsSignIn: (accountIds: string[]) => Promise<string[]>;
|
|
10
|
+
/** The workflows among those `userId` turned on, and may still change, whose enabled version binds one of `accountIds`, by account. */
|
|
11
|
+
uses: (userId: string, accountIds: string[]) => Promise<AccountUses>;
|
|
10
12
|
};
|
|
13
|
+
/** The workflows that use each account, by its id. */
|
|
14
|
+
export type AccountUses = Record<string, {
|
|
15
|
+
id: string;
|
|
16
|
+
name: string;
|
|
17
|
+
}[]>;
|
|
11
18
|
//#endregion
|
|
@@ -9,7 +9,8 @@ const connectionEvents = () => {
|
|
|
9
9
|
set: (next) => void (listener = next),
|
|
10
10
|
linked: async (accountId) => listener?.linked(accountId),
|
|
11
11
|
disconnected: async (accountId) => listener?.disconnected(accountId),
|
|
12
|
-
needsSignIn: async (accountIds) => listener && accountIds.length > 0 ? listener.needsSignIn(accountIds) : []
|
|
12
|
+
needsSignIn: async (accountIds) => listener && accountIds.length > 0 ? listener.needsSignIn(accountIds) : [],
|
|
13
|
+
uses: async (userId, accountIds) => listener && accountIds.length > 0 ? listener.uses(userId, accountIds) : {}
|
|
13
14
|
};
|
|
14
15
|
};
|
|
15
16
|
//#endregion
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { holdsScopes } from "../../workflows/connections/connection-provider.js";
|
|
1
|
+
import { listConnections } from "./list-connections.js";
|
|
3
2
|
import { revokeToken } from "./revoke-token.js";
|
|
4
3
|
import * as z$1 from "zod";
|
|
5
4
|
import { decryptOAuthToken } from "better-auth/oauth2";
|
|
@@ -15,7 +14,8 @@ const notFound = () => new APIError("NOT_FOUND", {
|
|
|
15
14
|
});
|
|
16
15
|
/**
|
|
17
16
|
* The signed-in person's connections: `GET /connections` lists each connection the app's workflow plugins declare with
|
|
18
|
-
* the person's accounts that fit it,
|
|
17
|
+
* the person's accounts that fit it, whether a trigger waits for one to be signed in again and the workflows that use
|
|
18
|
+
* it, never a token (see `listConnections`).
|
|
19
19
|
* `POST /connections/disconnect` revokes an account's token at its provider, then deletes it whatever the provider
|
|
20
20
|
* answered, and stops the triggers on it; their own account only, and never the last account they sign in with. Connecting is
|
|
21
21
|
* Better Auth's `/link-social`; a sign-in (not a link) through a provider only connections use is refused.
|
|
@@ -29,22 +29,12 @@ const connectionsPlugin = ({ connections, events, allowPrivateAddresses }) => {
|
|
|
29
29
|
method: "GET",
|
|
30
30
|
use: [sessionMiddleware]
|
|
31
31
|
}, async (ctx) => {
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
provider: connection.providerId,
|
|
39
|
-
scopes: connection.declaration.scopes ?? [],
|
|
40
|
-
link_params: connection.declaration.link_params ?? {},
|
|
41
|
-
accounts: fitting(connection).map((account) => ({
|
|
42
|
-
id: account.id,
|
|
43
|
-
scopes: storedScopes(account.scope),
|
|
44
|
-
created_at: account.createdAt,
|
|
45
|
-
needs_sign_in: waiting.has(account.id)
|
|
46
|
-
}))
|
|
47
|
-
})) });
|
|
32
|
+
const adapter = ctx.context.internalAdapter;
|
|
33
|
+
return ctx.json({ connections: await listConnections({
|
|
34
|
+
findAccounts: (userId) => adapter.findAccounts(userId),
|
|
35
|
+
connections,
|
|
36
|
+
events
|
|
37
|
+
}, ctx.context.session.user.id) });
|
|
48
38
|
}),
|
|
49
39
|
disconnectConnection: createAuthEndpoint(connectionPaths.disconnect, {
|
|
50
40
|
method: "POST",
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { storedScopes } from "../../personal-mail/linked-accounts.js";
|
|
2
|
+
import { holdsScopes } from "../../workflows/connections/connection-provider.js";
|
|
3
|
+
//#region src/better-auth/connections/list-connections.ts
|
|
4
|
+
/**
|
|
5
|
+
* A person's connections: each connection the app's workflow plugins declare with the person's accounts that fit it,
|
|
6
|
+
* whether a trigger waits for one to be signed in again, and the workflows that use it. Each account's fields are picked
|
|
7
|
+
* one by one, so no token leaves. `user` is the signed-in person's own id, from their session; reading without one fails,
|
|
8
|
+
* since the store would read every person's accounts.
|
|
9
|
+
*/
|
|
10
|
+
const listConnections = async ({ findAccounts, connections, events }, user) => {
|
|
11
|
+
if (user === "" || user === void 0 || user === null) throw new Error("Connections are listed for a signed-in person's id");
|
|
12
|
+
const userId = String(user);
|
|
13
|
+
const accounts = await findAccounts(userId);
|
|
14
|
+
const fitting = (connection) => accounts.filter((account) => account.providerId === connection.providerId && holdsScopes(storedScopes(account.scope), connection.declaration));
|
|
15
|
+
const ids = connections.flatMap((connection) => fitting(connection).map((account) => account.id));
|
|
16
|
+
const waiting = new Set(await events.needsSignIn(ids));
|
|
17
|
+
const uses = await events.uses(userId, ids);
|
|
18
|
+
return connections.map((connection) => ({
|
|
19
|
+
key: connection.key,
|
|
20
|
+
label: connection.declaration.label,
|
|
21
|
+
provider: connection.providerId,
|
|
22
|
+
scopes: connection.declaration.scopes ?? [],
|
|
23
|
+
link_params: connection.declaration.link_params ?? {},
|
|
24
|
+
accounts: fitting(connection).map((account) => ({
|
|
25
|
+
id: account.id,
|
|
26
|
+
scopes: storedScopes(account.scope),
|
|
27
|
+
created_at: account.createdAt,
|
|
28
|
+
needs_sign_in: waiting.has(account.id),
|
|
29
|
+
used_by: uses[account.id] ?? []
|
|
30
|
+
}))
|
|
31
|
+
}));
|
|
32
|
+
};
|
|
33
|
+
//#endregion
|
|
34
|
+
export { listConnections };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { UserColumn, UserTableOptions } from "./user-table.js";
|
|
2
2
|
import { Mailer } from "../mail/mail-message.js";
|
|
3
|
+
import { Session } from "../types.js";
|
|
3
4
|
import { SignInPolicy } from "./sign-in-policy.js";
|
|
4
5
|
import { StaffSignIn } from "./staff-log.js";
|
|
5
6
|
import { Person } from "./organizations/people-endpoint.js";
|
|
@@ -3215,7 +3216,11 @@ export declare const createAuth: (options: CreateAuthOptions, plugins?: AuthPlug
|
|
|
3215
3216
|
email: string;
|
|
3216
3217
|
emailVerified: boolean;
|
|
3217
3218
|
name: string;
|
|
3218
|
-
image
|
|
3219
|
+
image? /**
|
|
3220
|
+
* Refuses a new password that appears in a known data breach, by Have I Been Pwned's password list: at sign-up, from
|
|
3221
|
+
* an invitation, and when a password is set, changed, reset or given by an admin. Only the first five characters of
|
|
3222
|
+
* the password's SHA-1 hash leave the server. While the list cannot be reached, setting a password fails. Default off.
|
|
3223
|
+
*/ : string | null | undefined;
|
|
3219
3224
|
};
|
|
3220
3225
|
};
|
|
3221
3226
|
}>>[];
|
|
@@ -3472,6 +3477,10 @@ export declare const createAuth: (options: CreateAuthOptions, plugins?: AuthPlug
|
|
|
3472
3477
|
scopes: string[];
|
|
3473
3478
|
created_at: Date;
|
|
3474
3479
|
needs_sign_in: boolean;
|
|
3480
|
+
used_by: {
|
|
3481
|
+
id: string;
|
|
3482
|
+
name: string;
|
|
3483
|
+
}[];
|
|
3475
3484
|
}[];
|
|
3476
3485
|
}[];
|
|
3477
3486
|
}>;
|
|
@@ -9339,12 +9348,32 @@ export declare const createAuth: (options: CreateAuthOptions, plugins?: AuthPlug
|
|
|
9339
9348
|
signInProviders: string[];
|
|
9340
9349
|
clients: string[];
|
|
9341
9350
|
};
|
|
9342
|
-
/**
|
|
9351
|
+
/**
|
|
9352
|
+
* The workflow connections people connect accounts through, the listener (`set`) the workflows give for their links
|
|
9353
|
+
* and disconnects, and `list`, on the server only, of the session's own person's accounts, as `GET /connections` lists them.
|
|
9354
|
+
*/
|
|
9343
9355
|
connections: {
|
|
9344
9356
|
declared: ResolvedConnection[];
|
|
9345
9357
|
events: {
|
|
9346
9358
|
set: (next: ConnectionListener) => undefined;
|
|
9347
9359
|
};
|
|
9360
|
+
list: (session: Session) => Promise<{
|
|
9361
|
+
key: string;
|
|
9362
|
+
label: string;
|
|
9363
|
+
provider: string;
|
|
9364
|
+
scopes: string[];
|
|
9365
|
+
link_params: Record<string, string>;
|
|
9366
|
+
accounts: {
|
|
9367
|
+
id: string;
|
|
9368
|
+
scopes: string[];
|
|
9369
|
+
created_at: Date;
|
|
9370
|
+
needs_sign_in: boolean;
|
|
9371
|
+
used_by: {
|
|
9372
|
+
id: string;
|
|
9373
|
+
name: string;
|
|
9374
|
+
}[];
|
|
9375
|
+
}[];
|
|
9376
|
+
}[]>;
|
|
9348
9377
|
};
|
|
9349
9378
|
/** The OAuth provider for MCP clients, when on: the endpoint's resource (its URL) and path, and the scope its tokens carry. */
|
|
9350
9379
|
mcp: {
|
|
@@ -12,6 +12,7 @@ import { personalMailer } from "../personal-mail/personal-mailer.js";
|
|
|
12
12
|
import { mailLinkHooks } from "../personal-mail/mail-link-hooks.js";
|
|
13
13
|
import { bothAccountHooks, connectionAccountHooks } from "./connections/connection-account-hooks.js";
|
|
14
14
|
import { connectionEvents } from "./connections/connection-events.js";
|
|
15
|
+
import { listConnections } from "./connections/list-connections.js";
|
|
15
16
|
import { connectionProvidersPlugin } from "./connections/connection-oauth-provider.js";
|
|
16
17
|
import { connectionsPlugin } from "./connections/connections-plugin.js";
|
|
17
18
|
import { resolveConnections } from "./connections/declared-connections.js";
|
|
@@ -552,10 +553,18 @@ const createAuth = (options, plugins = {}) => {
|
|
|
552
553
|
signInProviders: socialProviders,
|
|
553
554
|
clients: connectionClients
|
|
554
555
|
},
|
|
555
|
-
/**
|
|
556
|
+
/**
|
|
557
|
+
* The workflow connections people connect accounts through, the listener (`set`) the workflows give for their links
|
|
558
|
+
* and disconnects, and `list`, on the server only, of the session's own person's accounts, as `GET /connections` lists them.
|
|
559
|
+
*/
|
|
556
560
|
connections: {
|
|
557
561
|
declared: resolvedConnections,
|
|
558
|
-
events: { set: events.set }
|
|
562
|
+
events: { set: events.set },
|
|
563
|
+
list: async (session) => listConnections({
|
|
564
|
+
findAccounts: async (userId) => (await auth.$context).internalAdapter.findAccounts(userId),
|
|
565
|
+
connections: resolvedConnections,
|
|
566
|
+
events
|
|
567
|
+
}, session.user.id)
|
|
559
568
|
},
|
|
560
569
|
/** The OAuth provider for MCP clients, when on: the endpoint's resource (its URL) and path, and the scope its tokens carry. */
|
|
561
570
|
mcp: mcp && {
|
package/dist/create-admin.js
CHANGED
|
@@ -391,6 +391,7 @@ const createAdmin = ({ resources: appResources, views: appViews = [], userTables
|
|
|
391
391
|
commented,
|
|
392
392
|
...engine && { workflows: {
|
|
393
393
|
...engine.types,
|
|
394
|
+
listConnections: auth.connections.list,
|
|
394
395
|
issueWebhook: (session, id, secret) => issueWebhook(engine.issue, session, id, {
|
|
395
396
|
...secret !== void 0 && { secret },
|
|
396
397
|
origin: new URL(auth.mcp.resource).origin
|
package/dist/package.js
CHANGED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { enablerMayUpdate } from "./enabler-authority.js";
|
|
2
|
+
import { sql } from "kysely";
|
|
3
|
+
//#region src/workflows/connections/connection-uses.ts
|
|
4
|
+
/**
|
|
5
|
+
* The workflows that use a person's accounts: those whose enabled version they turned on and binds one of the
|
|
6
|
+
* accounts in its `connections`, kept only while they may still update the workflow, as a step's token needs.
|
|
7
|
+
*/
|
|
8
|
+
const connectionUses = ({ deps, schema, roles }) => async (userId, accountIds) => {
|
|
9
|
+
const uses = {};
|
|
10
|
+
if (accountIds.length === 0) return uses;
|
|
11
|
+
const db = deps().db;
|
|
12
|
+
const { rows } = await sql`select w.id, w.name, v.tenant_id, c.value as account
|
|
13
|
+
from ${sql.id(schema, "workflows")} w
|
|
14
|
+
join ${sql.id(schema, "versions")} v on v.workflow_id = w.id and v.version = w.enabled_version
|
|
15
|
+
cross join lateral jsonb_each_text(coalesce(v.definition -> 'connections', '{}'::jsonb)) c
|
|
16
|
+
where v.enabled_by = ${userId} and c.value in (${sql.join(accountIds)})
|
|
17
|
+
order by w.name, w.id`.execute(db);
|
|
18
|
+
for (const row of rows) {
|
|
19
|
+
if (!await enablerMayUpdate(db, deps(), roles, userId, row.tenant_id ?? void 0, row.id)) continue;
|
|
20
|
+
uses[row.account] = [...uses[row.account] ?? [], {
|
|
21
|
+
id: row.id,
|
|
22
|
+
name: row.name
|
|
23
|
+
}];
|
|
24
|
+
}
|
|
25
|
+
return uses;
|
|
26
|
+
};
|
|
27
|
+
//#endregion
|
|
28
|
+
export { connectionUses };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Session } from "../../types.js";
|
|
2
|
+
import "../../index.js";
|
|
3
|
+
//#region src/workflows/mcp/connection-tools.d.ts
|
|
4
|
+
type Connection = {
|
|
5
|
+
key: string;
|
|
6
|
+
label: string;
|
|
7
|
+
accounts: {
|
|
8
|
+
id: string;
|
|
9
|
+
scopes: string[];
|
|
10
|
+
needs_sign_in: boolean;
|
|
11
|
+
}[];
|
|
12
|
+
};
|
|
13
|
+
/** The session's own person's connections, each with their accounts that fit it, such as `auth.connections.list`. */
|
|
14
|
+
export type ListConnections = (session: Session) => Promise<Connection[]>;
|
|
15
|
+
//#endregion
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { defineTool } from "../../assistant/tools.js";
|
|
2
|
+
//#region src/workflows/mcp/connection-tools.ts
|
|
3
|
+
/**
|
|
4
|
+
* The caller's own accounts, by connection, which a definition's `connections` binds by id. Each field is picked one by
|
|
5
|
+
* one, so nothing more than the list reads leaves, and never a token; it takes no argument, so it lists no one else's.
|
|
6
|
+
*/
|
|
7
|
+
const listConnectionsTool = (list) => defineTool({
|
|
8
|
+
name: "list_connections",
|
|
9
|
+
description: "Lists the connections the app's workflow plugins declare with your own connected accounts, as JSON ({ connections }), each with its key, label and accounts, each account with its id, scopes and needs_sign_in. A workflow binds an account in its definition's connections, as { \"<key>\": \"<account id>\" }; an account is connected, or connected again when it needs a sign-in, on the account page.",
|
|
10
|
+
parameters: {
|
|
11
|
+
type: "object",
|
|
12
|
+
properties: {}
|
|
13
|
+
},
|
|
14
|
+
annotations: {
|
|
15
|
+
readOnlyHint: true,
|
|
16
|
+
openWorldHint: false
|
|
17
|
+
},
|
|
18
|
+
run: async (_args, context) => {
|
|
19
|
+
const connections = list ? await list(context.session) : [];
|
|
20
|
+
return JSON.stringify({ connections: connections.map(({ key, label, accounts }) => ({
|
|
21
|
+
key,
|
|
22
|
+
label,
|
|
23
|
+
accounts: accounts.map(({ id, scopes, needs_sign_in }) => ({
|
|
24
|
+
id,
|
|
25
|
+
scopes,
|
|
26
|
+
needs_sign_in
|
|
27
|
+
}))
|
|
28
|
+
})) });
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
//#endregion
|
|
32
|
+
export { listConnectionsTool };
|
|
@@ -4,7 +4,7 @@ import { limits } from "@protobase/workflows";
|
|
|
4
4
|
* profile of the States Language with JSONata, and how the workflow tools find, make, change and test-run them.
|
|
5
5
|
*/
|
|
6
6
|
const workflowInstructions = [
|
|
7
|
-
"Workflows: list_workflow_types names the step types and triggers with their arguments and inputs; list_workflows and get_workflow read workflows; validate_workflow checks a definition without saving it; create_workflow and update_workflow save one; run_workflow starts a run with an input, and get_workflow_run reads it with each step's input, output, logs and error. A run goes on in the background: read it again until its status is succeeded or failed, then fix the step that failed with update_workflow and run it again. A trigger starts runs only once enable_workflow turned the workflow on. A webhook trigger whose sender you give a URL, such as app:webhook, gets its URL and secret from new_webhook_url, shown once; one that registers its own URL with its service as the workflow is turned on needs none, and new_webhook_url refuses it.",
|
|
7
|
+
"Workflows: list_workflow_types names the step types and triggers with their arguments and inputs; list_workflows and get_workflow read workflows; validate_workflow checks a definition without saving it; create_workflow and update_workflow save one; run_workflow starts a run with an input, and get_workflow_run reads it with each step's input, output, logs and error. A run goes on in the background: read it again until its status is succeeded or failed, then fix the step that failed with update_workflow and run it again. A trigger starts runs only once enable_workflow turned the workflow on. A webhook trigger whose sender you give a URL, such as app:webhook, gets its URL and secret from new_webhook_url, shown once; one that registers its own URL with its service as the workflow is turned on needs none, and new_webhook_url refuses it. A step or trigger that signs in through a connection uses the account the definition's \"connections\" binds, { \"<connection key>\": \"<account id>\" }: list_connections gives your accounts.",
|
|
8
8
|
"A definition is one JSON document: { \"trigger\": <trigger>, \"stateMachine\": { \"QueryLanguage\": \"JSONata\", \"StartAt\": \"<state>\", \"States\": { \"<state>\": <state>, ... } } }, the States Language with JSONata expressions, in a profile where every value is read by name. It holds no layout. <trigger> is an object with one key: { \"<trigger id>\": <its input> } for a trigger list_workflow_types names, or { \"manual\": {} } for a workflow that runs only when someone starts it.",
|
|
9
9
|
"States: Task { Resource: <step type>, Arguments, TimeoutSeconds, Retry, Catch }; Pass { Output, Assign }; Choice { Choices: [{ Condition, Next, Output?, Assign? }], Default }; Map { Items, ItemProcessor: { StartAt, States }, MaxConcurrency }; Wait { Seconds | Timestamp }; Succeed { Output }; Fail { Error, Cause }. Every state may have Comment, Output and Assign. Task, Pass, Map and Wait have exactly one of Next (a state name) and End: true. State names are unique across the document, Maps included, and every state must be reachable from StartAt. InputPath, Parameters, ResultPath and the other JSONPath fields, and Parallel, are not part of the profile.",
|
|
10
10
|
"Expressions: a string that is whole \"{% ... %}\" is a JSONata expression whose value, of any type, the field takes; any other string is literal text. Build text inside one expression with &: \"{% 'Order ' & $order.id %}\". Expressions sit at any depth in Arguments, Output and Assign, and in Items, Condition, Seconds, Timestamp, Error and Cause.",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AssistantTool, ToolContext } from "../../assistant/tools.js";
|
|
2
2
|
import { IssueWebhook } from "./webhook-tools.js";
|
|
3
|
+
import { ListConnections } from "./connection-tools.js";
|
|
3
4
|
import "../../index.js";
|
|
4
5
|
import { ResourceModel } from "@protobase/schema";
|
|
5
6
|
import { CheckOptions, TypeEntry } from "@protobase/workflows";
|
|
@@ -13,7 +14,9 @@ export type WorkflowCatalog = {
|
|
|
13
14
|
checkWith: (models: (name: string) => ResourceModel | undefined) => CheckOptions;
|
|
14
15
|
/** Issues a workflow's webhook URL as the caller, for `new_webhook_url`. */
|
|
15
16
|
issueWebhook?: IssueWebhook;
|
|
17
|
+
/** The caller's own connected accounts, for `list_connections`; none without it. */
|
|
18
|
+
listConnections?: ListConnections;
|
|
16
19
|
};
|
|
17
|
-
/** The tools that read workflows, their types and runs, and check definitions. */
|
|
20
|
+
/** The tools that read workflows, their types and runs and the caller's connections, and check definitions. */
|
|
18
21
|
export declare const workflowReadTools: (catalog: WorkflowCatalog) => AssistantTool<ToolContext>[];
|
|
19
22
|
//#endregion
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { defineTool } from "../../assistant/tools.js";
|
|
2
2
|
import { refused } from "../../assistant/record-tool-args.js";
|
|
3
|
+
import { listConnectionsTool } from "./connection-tools.js";
|
|
3
4
|
import { mergePatch } from "./merge-patch.js";
|
|
4
5
|
import { definitionParameter, editParameter, idOf, idParameter, objectOf, pageSizeOf, textOf } from "./workflow-tool-args.js";
|
|
5
6
|
import { checkDefinition, typeCatalog } from "@protobase/workflows";
|
|
@@ -194,13 +195,14 @@ const getWorkflowRunTool = defineTool({
|
|
|
194
195
|
}), refused);
|
|
195
196
|
}
|
|
196
197
|
});
|
|
197
|
-
/** The tools that read workflows, their types and runs, and check definitions. */
|
|
198
|
+
/** The tools that read workflows, their types and runs and the caller's connections, and check definitions. */
|
|
198
199
|
const workflowReadTools = (catalog) => [
|
|
199
200
|
listWorkflowTypesTool(catalog),
|
|
200
201
|
listWorkflowsTool,
|
|
201
202
|
getWorkflowTool,
|
|
202
203
|
validateWorkflowTool(catalog),
|
|
203
|
-
getWorkflowRunTool
|
|
204
|
+
getWorkflowRunTool,
|
|
205
|
+
listConnectionsTool(catalog.listConnections)
|
|
204
206
|
];
|
|
205
207
|
//#endregion
|
|
206
208
|
export { getWorkflowRunTool, getWorkflowTool, listWorkflowsTool, workflowReadTools };
|
|
@@ -11,6 +11,7 @@ import { triggerJobs } from "./triggers/trigger-jobs.js";
|
|
|
11
11
|
import { workflowTypes } from "./workflow-types.js";
|
|
12
12
|
import { betterAuthConnectionAccounts } from "./connections/connection-accounts.js";
|
|
13
13
|
import { connectionWiring } from "./connections/connection-wiring.js";
|
|
14
|
+
import { connectionUses } from "./connections/connection-uses.js";
|
|
14
15
|
import { connectionTriggers } from "./connections/connection-triggers.js";
|
|
15
16
|
import { secretRedactor } from "@protobase/workflows";
|
|
16
17
|
//#region src/workflows/workflow-engine.ts
|
|
@@ -60,7 +61,14 @@ const workflowEngine = (options, deps, auth) => {
|
|
|
60
61
|
origin: () => auth?.origins[0],
|
|
61
62
|
systemPath: () => deps().systemPath
|
|
62
63
|
});
|
|
63
|
-
auth?.connections.events.set(
|
|
64
|
+
auth?.connections.events.set({
|
|
65
|
+
...connectionTriggers(() => deps().db, schema, triggers),
|
|
66
|
+
uses: connectionUses({
|
|
67
|
+
deps,
|
|
68
|
+
schema,
|
|
69
|
+
roles
|
|
70
|
+
})
|
|
71
|
+
});
|
|
64
72
|
const webhooks = usable(types.webhooks);
|
|
65
73
|
const issue = {
|
|
66
74
|
deps,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@protobase/server",
|
|
3
|
-
"version": "0.69.
|
|
3
|
+
"version": "0.69.2",
|
|
4
4
|
"description": "The Protobase REST API as a Hono app, with Better Auth sign-in.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -44,11 +44,11 @@
|
|
|
44
44
|
"@better-auth/sso": "^1.7.12",
|
|
45
45
|
"@livekit/protocol": "1.53.1",
|
|
46
46
|
"@modelcontextprotocol/server": "^2.3.1",
|
|
47
|
-
"@protobase/layout": "0.69.
|
|
48
|
-
"@protobase/query": "0.69.
|
|
49
|
-
"@protobase/schema": "0.69.
|
|
50
|
-
"@protobase/workflow-plugins": "0.69.
|
|
51
|
-
"@protobase/workflows": "0.69.
|
|
47
|
+
"@protobase/layout": "0.69.2",
|
|
48
|
+
"@protobase/query": "0.69.2",
|
|
49
|
+
"@protobase/schema": "0.69.2",
|
|
50
|
+
"@protobase/workflow-plugins": "0.69.2",
|
|
51
|
+
"@protobase/workflows": "0.69.2",
|
|
52
52
|
"@react-email/render": "^2.1.0",
|
|
53
53
|
"@react-pdf/primitives": "^4.4.0",
|
|
54
54
|
"@react-pdf/renderer": "^4.9.0",
|