@protobase/client 0.62.4 → 0.63.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/dist/account-security.d.ts +9 -0
- package/dist/account-security.js +24 -0
- package/dist/auth-types.d.ts +14 -1
- package/dist/auth.d.ts +3 -1
- package/dist/auth.js +1 -0
- package/dist/call-guests.js +24 -0
- package/dist/calls/guest-lobby.d.ts +34 -0
- package/dist/calls/guest-lobby.js +53 -0
- package/dist/calls/guest-requests.d.ts +25 -0
- package/dist/calls/guest-requests.js +68 -0
- package/dist/calls/index.d.ts +4 -2
- package/dist/calls/index.js +3 -1
- package/dist/calls/join-call.d.ts +11 -1
- package/dist/calls/join-call.js +21 -4
- package/dist/client.d.ts +4 -0
- package/dist/client.js +3 -1
- package/dist/index.d.ts +2 -2
- package/dist/routed-client.js +1 -0
- package/dist/static-session.js +2 -0
- package/package.json +3 -3
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { BetterAuthClient } from "./better-auth-client.js";
|
|
2
|
+
import { PersonalMailLink } from "./auth-types.js";
|
|
2
3
|
import { SignInPolicy } from "./sign-in-policy.js";
|
|
3
4
|
//#region src/account-security.d.ts
|
|
4
5
|
/** What a sign-in policy can require that an account sets up once. */
|
|
@@ -68,6 +69,14 @@ export declare const accountSecurity: (client: BetterAuthClient) => {
|
|
|
68
69
|
* `?error=<code>` when the link did not go through, for example `account_already_linked_to_different_user`.
|
|
69
70
|
*/
|
|
70
71
|
linkProvider: (provider: string, callbackURL: string) => Promise<string>;
|
|
72
|
+
/** The ids of the mail providers of `links` the account is linked to with every scope they ask for, for example `gmail`. */
|
|
73
|
+
linkedPersonalMail: (links: PersonalMailLink[]) => Promise<string[]>;
|
|
74
|
+
/**
|
|
75
|
+
* Starts linking a mailbox, such as Gmail through Google sign-in with leave to send mail: resolves with the provider's
|
|
76
|
+
* authorization URL, for the page to go to. The provider sends the browser back to `callbackURL`, with
|
|
77
|
+
* `?error=<code>` when the link did not go through.
|
|
78
|
+
*/
|
|
79
|
+
linkPersonalMail: (link: PersonalMailLink, callbackURL: string) => Promise<string>;
|
|
71
80
|
/** The apps the person allowed to act as them, newest first; on an app with MCP on. */
|
|
72
81
|
connectedApps: () => Promise<ConnectedApp[]>;
|
|
73
82
|
/** Disconnects an app: it is forgotten, and its access ends within 15 minutes; it has to ask again to come back. */
|
package/dist/account-security.js
CHANGED
|
@@ -85,6 +85,30 @@ const accountSecurity = (client) => ({
|
|
|
85
85
|
if (error || !data?.url) throw authError(error, "Could not start linking the account");
|
|
86
86
|
return data.url;
|
|
87
87
|
},
|
|
88
|
+
/** The ids of the mail providers of `links` the account is linked to with every scope they ask for, for example `gmail`. */
|
|
89
|
+
linkedPersonalMail: async (links) => {
|
|
90
|
+
const { data, error } = await client.listAccounts();
|
|
91
|
+
if (error || !data) throw authError(error, "Could not read your linked accounts");
|
|
92
|
+
const holds = (link) => data.some((account) => account.providerId === link.provider && link.scopes.every((scope) => account.scopes.includes(scope)));
|
|
93
|
+
return links.filter(holds).map((link) => link.id);
|
|
94
|
+
},
|
|
95
|
+
/**
|
|
96
|
+
* Starts linking a mailbox, such as Gmail through Google sign-in with leave to send mail: resolves with the provider's
|
|
97
|
+
* authorization URL, for the page to go to. The provider sends the browser back to `callbackURL`, with
|
|
98
|
+
* `?error=<code>` when the link did not go through.
|
|
99
|
+
*/
|
|
100
|
+
linkPersonalMail: async (link, callbackURL) => {
|
|
101
|
+
const { data, error } = await client.linkSocial({
|
|
102
|
+
provider: link.provider,
|
|
103
|
+
scopes: link.scopes,
|
|
104
|
+
additionalParams: link.params,
|
|
105
|
+
callbackURL,
|
|
106
|
+
errorCallbackURL: callbackURL,
|
|
107
|
+
disableRedirect: true
|
|
108
|
+
});
|
|
109
|
+
if (error || !data?.url) throw authError(error, "Could not start linking the mailbox");
|
|
110
|
+
return data.url;
|
|
111
|
+
},
|
|
88
112
|
/** The apps the person allowed to act as them, newest first; on an app with MCP on. */
|
|
89
113
|
connectedApps: async () => {
|
|
90
114
|
const { data, error } = await client.$fetch("/account/connected-apps");
|
package/dist/auth-types.d.ts
CHANGED
|
@@ -24,6 +24,18 @@ export type PlatformSignIn = {
|
|
|
24
24
|
provider: string;
|
|
25
25
|
name: string;
|
|
26
26
|
};
|
|
27
|
+
/**
|
|
28
|
+
* A mail provider people may link their own mailbox with, for the app to send mail from it: its id and name, such as
|
|
29
|
+
* `gmail` and `Gmail`, the sign-in provider it links through, such as `google`, the scopes the link asks for and more
|
|
30
|
+
* authorization parameters of the link.
|
|
31
|
+
*/
|
|
32
|
+
export type PersonalMailLink = {
|
|
33
|
+
id: string;
|
|
34
|
+
name: string;
|
|
35
|
+
provider: string;
|
|
36
|
+
scopes: string[];
|
|
37
|
+
params: Record<string, string>;
|
|
38
|
+
};
|
|
27
39
|
/** A SAML identity provider of the app: its id, for `signInSaml`, and the name to show. */
|
|
28
40
|
export type SamlSignIn = {
|
|
29
41
|
id: string;
|
|
@@ -37,7 +49,7 @@ export type SamlSignIn = {
|
|
|
37
49
|
* `sendSignUpCode`); `socialProviders` the ids of the sign-in providers, for example
|
|
38
50
|
* `github`; `platformSignIn` the one of them the platform adds; `samlProviders` the app's SAML identity providers; `staffSignIn` the operator provider's name when its staff
|
|
39
51
|
* can sign in as people; `organizations` when the app has them; `anonymous` when visitors may browse what the project's
|
|
40
|
-
* anonymous role reads without signing in; `mcp` when MCP clients can connect, with the `url` of the app's MCP endpoint, so the account page shows it and lists the clients; `plugins`
|
|
52
|
+
* anonymous role reads without signing in; `personalMail` the mail providers people may link their mailbox with (see `account.linkPersonalMail`); `mcp` when MCP clients can connect, with the `url` of the app's MCP endpoint, so the account page shows it and lists the clients; `plugins`
|
|
41
53
|
* those the app loads before anyone signs in; `locale` the language the app sets for everyone, which the screens before
|
|
42
54
|
* `/meta` are in.
|
|
43
55
|
*/
|
|
@@ -67,6 +79,7 @@ export type SetupStatus = {
|
|
|
67
79
|
mcp?: {
|
|
68
80
|
url: string;
|
|
69
81
|
};
|
|
82
|
+
personalMail?: PersonalMailLink[];
|
|
70
83
|
plugins?: PluginRef[];
|
|
71
84
|
locale?: Locale;
|
|
72
85
|
};
|
package/dist/auth.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { DeviceSession } from "./account-profile.js";
|
|
2
|
+
import { AuthUser, PersonalMailLink, RoleLabel, SetupStatus, SignInResult, TwoFactorMethod } from "./auth-types.js";
|
|
2
3
|
import { SignInPolicy, SignInPolicyState } from "./sign-in-policy.js";
|
|
3
4
|
import { AccountSignIn, AuthenticatorSetup, ConnectedApp, Passkey } from "./account-security.js";
|
|
4
5
|
import { ConnectingClient } from "./connect.js";
|
|
5
6
|
import { CurrentOrganization, InvitationPreview, InvitationSent, Organization, OrganizationInvitation, OrganizationMember, OrganizationPerson, OrganizationRole, OrganizationsFound } from "./organizations.js";
|
|
6
7
|
import { ActiveRole } from "./roles.js";
|
|
7
|
-
import { AuthUser, RoleLabel, SetupStatus, SignInResult, TwoFactorMethod } from "./auth-types.js";
|
|
8
8
|
import { AppUser, UserInvitation, UserInvitationSent, UsersFound } from "./users.js";
|
|
9
9
|
import { StaffSignIn } from "./staff-sign-in.js";
|
|
10
10
|
import { AuthError } from "./auth-error.js";
|
|
@@ -76,6 +76,8 @@ export declare const createAuthSession: (options?: AuthSessionOptions) => {
|
|
|
76
76
|
turnOffTwoFactor: (password?: string) => Promise<void>;
|
|
77
77
|
linkedProviders: () => Promise<string[]>;
|
|
78
78
|
linkProvider: (provider: string, callbackURL: string) => Promise<string>;
|
|
79
|
+
linkedPersonalMail: (links: PersonalMailLink[]) => Promise<string[]>;
|
|
80
|
+
linkPersonalMail: (link: PersonalMailLink, callbackURL: string) => Promise<string>;
|
|
79
81
|
connectedApps: () => Promise<ConnectedApp[]>;
|
|
80
82
|
disconnectApp: (clientId: string) => Promise<void>;
|
|
81
83
|
newBackupCodes: (password?: string) => Promise<string[]>;
|
package/dist/auth.js
CHANGED
|
@@ -89,6 +89,7 @@ const createAuthSession = (options = {}) => {
|
|
|
89
89
|
...body.organizations && { organizations: body.organizations },
|
|
90
90
|
...body.anonymous && { anonymous: true },
|
|
91
91
|
...body.mcp && { mcp: { url: body.mcp.url } },
|
|
92
|
+
...body.personalMail && body.personalMail.length > 0 && { personalMail: body.personalMail },
|
|
92
93
|
...body.plugins && body.plugins.length > 0 && { plugins: body.plugins },
|
|
93
94
|
...isLocale(body.locale) && { locale: body.locale }
|
|
94
95
|
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { guestCallsPath } from "@protobase/schema/internal";
|
|
2
|
+
//#region src/call-guests.ts
|
|
3
|
+
/**
|
|
4
|
+
* Whether the calls of the organization the signed-in user works in take guests (`/api/calls/guests/organization`):
|
|
5
|
+
* `allowed` for any member, `setAllowed` for its owner or an admin. Turning them off revokes every guest link of its
|
|
6
|
+
* calls and takes their guests out at once.
|
|
7
|
+
*/
|
|
8
|
+
const callGuestsClient = (send) => ({
|
|
9
|
+
allowed: async () => (await (await send({
|
|
10
|
+
method: "GET",
|
|
11
|
+
path: guestCallsPath("", "organization"),
|
|
12
|
+
system: true
|
|
13
|
+
})).json()).allowed,
|
|
14
|
+
setAllowed: async (allowed) => {
|
|
15
|
+
await send({
|
|
16
|
+
method: "PUT",
|
|
17
|
+
path: guestCallsPath("", "organization"),
|
|
18
|
+
system: true,
|
|
19
|
+
body: { allowed }
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
//#endregion
|
|
24
|
+
export { callGuestsClient };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { CallGuestState, CallTrackSource } from "@protobase/schema/internal";
|
|
2
|
+
//#region src/calls/guest-lobby.d.ts
|
|
3
|
+
/** A guest's wait in the lobby, as the server tells it: once let in, the call and what the guest may send. */
|
|
4
|
+
export type GuestWait = {
|
|
5
|
+
state: CallGuestState;
|
|
6
|
+
call?: string;
|
|
7
|
+
publish?: CallTrackSource[];
|
|
8
|
+
};
|
|
9
|
+
/** Why the lobby did not answer: no live link, too many tries for now, or a name it does not take. */
|
|
10
|
+
export declare class LobbyRefused extends Error {
|
|
11
|
+
readonly status: number;
|
|
12
|
+
constructor(status: number, message: string);
|
|
13
|
+
}
|
|
14
|
+
export type GuestLobbyOptions = {
|
|
15
|
+
/** The API's system path on the page's origin, `/api` by default. */
|
|
16
|
+
systemPath?: string;
|
|
17
|
+
fetch?: typeof fetch;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* The lobby a guest of a call waits in, with no account: `enter` with the link's token and the guest's name gives the
|
|
21
|
+
* guest's own token, which `wait` and `leave` send, and which `joinCall` takes as `guest` at `socketUrl` once a member
|
|
22
|
+
* let them in. No cookie is sent or kept.
|
|
23
|
+
*/
|
|
24
|
+
export declare const guestLobby: ({ systemPath, fetch: fetchOf }?: GuestLobbyOptions) => {
|
|
25
|
+
/** The guest's call socket, for `joinCall`'s `url`. */
|
|
26
|
+
socketUrl: string;
|
|
27
|
+
enter: (link: string, name: string) => Promise<{
|
|
28
|
+
guest: string;
|
|
29
|
+
token: string;
|
|
30
|
+
}>;
|
|
31
|
+
wait: (token: string) => Promise<GuestWait>;
|
|
32
|
+
leave: (token: string) => Promise<void>;
|
|
33
|
+
};
|
|
34
|
+
//#endregion
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { guestCallsPath } from "@protobase/schema/internal";
|
|
2
|
+
//#region src/calls/guest-lobby.ts
|
|
3
|
+
/** Why the lobby did not answer: no live link, too many tries for now, or a name it does not take. */
|
|
4
|
+
var LobbyRefused = class extends Error {
|
|
5
|
+
status;
|
|
6
|
+
constructor(status, message) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.status = status;
|
|
9
|
+
this.name = "LobbyRefused";
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* The lobby a guest of a call waits in, with no account: `enter` with the link's token and the guest's name gives the
|
|
14
|
+
* guest's own token, which `wait` and `leave` send, and which `joinCall` takes as `guest` at `socketUrl` once a member
|
|
15
|
+
* let them in. No cookie is sent or kept.
|
|
16
|
+
*/
|
|
17
|
+
const guestLobby = ({ systemPath = "/api", fetch: fetchOf = globalThis.fetch } = {}) => {
|
|
18
|
+
const lobby = guestCallsPath(systemPath, "lobby");
|
|
19
|
+
const ask = async (init) => {
|
|
20
|
+
const response = await fetchOf(lobby, {
|
|
21
|
+
...init,
|
|
22
|
+
credentials: "omit",
|
|
23
|
+
cache: "no-store"
|
|
24
|
+
});
|
|
25
|
+
if (!response.ok) throw new LobbyRefused(response.status, (await response.json().catch(() => void 0))?.detail ?? response.statusText);
|
|
26
|
+
return response;
|
|
27
|
+
};
|
|
28
|
+
const bearer = (token) => ({ authorization: `Bearer ${token}` });
|
|
29
|
+
return {
|
|
30
|
+
/** The guest's call socket, for `joinCall`'s `url`. */
|
|
31
|
+
socketUrl: guestCallsPath(systemPath, "socket"),
|
|
32
|
+
enter: async (link, name) => await (await ask({
|
|
33
|
+
method: "POST",
|
|
34
|
+
headers: { "content-type": "application/json" },
|
|
35
|
+
body: JSON.stringify({
|
|
36
|
+
link,
|
|
37
|
+
name
|
|
38
|
+
})
|
|
39
|
+
})).json(),
|
|
40
|
+
wait: async (token) => await (await ask({
|
|
41
|
+
method: "GET",
|
|
42
|
+
headers: bearer(token)
|
|
43
|
+
})).json(),
|
|
44
|
+
leave: async (token) => {
|
|
45
|
+
await ask({
|
|
46
|
+
method: "DELETE",
|
|
47
|
+
headers: bearer(token)
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
//#endregion
|
|
53
|
+
export { LobbyRefused, guestLobby };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { CallGuestLink, CallGuestRefusal, CallTrackSource } from "@protobase/schema/internal";
|
|
2
|
+
//#region src/calls/guest-requests.d.ts
|
|
3
|
+
/** A guest request the server did not do, with why: see `CallGuestRefusal`. */
|
|
4
|
+
export declare class GuestRefused extends Error {
|
|
5
|
+
readonly reason: CallGuestRefusal;
|
|
6
|
+
constructor(reason: CallGuestRefusal);
|
|
7
|
+
}
|
|
8
|
+
/** What a member who invites does with the call's guests. Each rejects with `GuestRefused` when the server did not. */
|
|
9
|
+
export type CallGuests = {
|
|
10
|
+
/** A new link to the call that lets a guest send these sources, until `expiresAt` or the call's end; its token once. */
|
|
11
|
+
link: (options: {
|
|
12
|
+
publish: CallTrackSource[];
|
|
13
|
+
expiresAt?: Date;
|
|
14
|
+
}) => Promise<{
|
|
15
|
+
link: CallGuestLink;
|
|
16
|
+
token: string;
|
|
17
|
+
}>;
|
|
18
|
+
/** Revokes a link: its guests are out of the call, and nobody else waits on it. */
|
|
19
|
+
revoke: (link: string) => Promise<void>;
|
|
20
|
+
admit: (guest: string) => Promise<void>;
|
|
21
|
+
deny: (guest: string) => Promise<void>;
|
|
22
|
+
/** Takes a guest out of the call, for good. */
|
|
23
|
+
remove: (guest: string) => Promise<void>;
|
|
24
|
+
};
|
|
25
|
+
//#endregion
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
//#region src/calls/guest-requests.ts
|
|
2
|
+
/** A guest request the server did not do, with why: see `CallGuestRefusal`. */
|
|
3
|
+
var GuestRefused = class extends Error {
|
|
4
|
+
reason;
|
|
5
|
+
constructor(reason) {
|
|
6
|
+
super(`The guest request was refused: ${reason}`);
|
|
7
|
+
this.reason = reason;
|
|
8
|
+
this.name = "GuestRefused";
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* The member's guest requests over the call's socket: the server answers each once, in order, so the answers are paired
|
|
13
|
+
* with the requests in the order they were sent. A request whose socket closed before its answer rejects.
|
|
14
|
+
*/
|
|
15
|
+
const guestRequests = (send) => {
|
|
16
|
+
const pending = [];
|
|
17
|
+
const ask = (message) => new Promise((resolve, reject) => {
|
|
18
|
+
pending.push({
|
|
19
|
+
resolve,
|
|
20
|
+
reject
|
|
21
|
+
});
|
|
22
|
+
send(message);
|
|
23
|
+
});
|
|
24
|
+
return {
|
|
25
|
+
guests: {
|
|
26
|
+
link: ({ publish, expiresAt }) => ask({
|
|
27
|
+
type: "guest-link",
|
|
28
|
+
publish,
|
|
29
|
+
...expiresAt && { expires_at: expiresAt.toISOString() }
|
|
30
|
+
}),
|
|
31
|
+
revoke: (link) => ask({
|
|
32
|
+
type: "guest-link-revoke",
|
|
33
|
+
link
|
|
34
|
+
}),
|
|
35
|
+
admit: (guest) => ask({
|
|
36
|
+
type: "guest-decide",
|
|
37
|
+
guest,
|
|
38
|
+
admit: true
|
|
39
|
+
}),
|
|
40
|
+
deny: (guest) => ask({
|
|
41
|
+
type: "guest-decide",
|
|
42
|
+
guest,
|
|
43
|
+
admit: false
|
|
44
|
+
}),
|
|
45
|
+
remove: (guest) => ask({
|
|
46
|
+
type: "guest-remove",
|
|
47
|
+
guest
|
|
48
|
+
})
|
|
49
|
+
},
|
|
50
|
+
/** Whether the message answered a request, which it then settles. */
|
|
51
|
+
receive: (message) => {
|
|
52
|
+
if (message.type !== "guest-link" && message.type !== "guest-done" && message.type !== "guest-refused") return false;
|
|
53
|
+
const request = pending.shift();
|
|
54
|
+
if (message.type === "guest-refused") request?.reject(new GuestRefused(message.reason));
|
|
55
|
+
else request?.resolve(message.type === "guest-link" ? {
|
|
56
|
+
link: message.link,
|
|
57
|
+
token: message.token
|
|
58
|
+
} : void 0);
|
|
59
|
+
return true;
|
|
60
|
+
},
|
|
61
|
+
/** The socket closed: the requests on it are not answered. */
|
|
62
|
+
lost: () => {
|
|
63
|
+
for (const request of pending.splice(0)) request.reject(/* @__PURE__ */ new Error("The link to the call was lost before the server answered"));
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
//#endregion
|
|
68
|
+
export { GuestRefused, guestRequests };
|
package/dist/calls/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { CallConnection } from "./connection-stats.js";
|
|
2
|
+
import { CallGuests, GuestRefused } from "./guest-requests.js";
|
|
2
3
|
import { CallTrack, PublishOptions } from "./media-link.js";
|
|
3
4
|
import { Call, CallState, JoinCallOptions, joinCall } from "./join-call.js";
|
|
4
5
|
import { PublishRefused } from "./publish-refused.js";
|
|
5
|
-
import {
|
|
6
|
-
|
|
6
|
+
import { GuestLobbyOptions, GuestWait, LobbyRefused, guestLobby } from "./guest-lobby.js";
|
|
7
|
+
import { CallGuestLink, CallGuestRefusal, CallGuestState, CallLeftReason, CallLobbyGuest, CallMode, CallRosterMember, CallTrackSource } from "@protobase/schema/internal";
|
|
8
|
+
export { type Call, type CallConnection, type CallGuestLink, type CallGuestRefusal, type CallGuestState, type CallGuests, type CallLeftReason, type CallLobbyGuest, type CallMode, type CallRosterMember, type CallState, type CallTrack, type CallTrackSource, type GuestLobbyOptions, GuestRefused, type GuestWait, type JoinCallOptions, LobbyRefused, type PublishOptions, PublishRefused, guestLobby, joinCall };
|
package/dist/calls/index.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { GuestRefused } from "./guest-requests.js";
|
|
1
2
|
import { PublishRefused } from "./publish-refused.js";
|
|
2
3
|
import { joinCall } from "./join-call.js";
|
|
3
|
-
|
|
4
|
+
import { LobbyRefused, guestLobby } from "./guest-lobby.js";
|
|
5
|
+
export { GuestRefused, LobbyRefused, PublishRefused, guestLobby, joinCall };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { CallConnection } from "./connection-stats.js";
|
|
2
|
+
import { CallGuests } from "./guest-requests.js";
|
|
2
3
|
import { CallTrack, PublishOptions } from "./media-link.js";
|
|
3
|
-
import { CallLeftReason, CallRosterMember, CallTrackSource } from "@protobase/schema/internal";
|
|
4
|
+
import { CallGuestLink, CallLeftReason, CallLobbyGuest, CallRosterMember, CallTrackSource } from "@protobase/schema/internal";
|
|
4
5
|
//#region src/calls/join-call.d.ts
|
|
5
6
|
/** Where a call stands: `resuming` while the link to Protobase is restored, with media still flowing. */
|
|
6
7
|
export type CallState = {
|
|
@@ -20,6 +21,13 @@ export type JoinCallOptions = {
|
|
|
20
21
|
* page's origin, or an absolute `http(s)` or `ws(s)` URL. The browser sends its session cookie with it.
|
|
21
22
|
*/
|
|
22
23
|
url: string;
|
|
24
|
+
/** A guest's token from `guestLobby`, with the lobby's `socketUrl` as `url`: the guest joins as themselves, whom no cookie names. */
|
|
25
|
+
guest?: string;
|
|
26
|
+
/** With a member who may invite: who waits in the call's lobby, and its guest links, whenever that changes. */
|
|
27
|
+
onLobby?: (lobby: {
|
|
28
|
+
guests: CallLobbyGuest[];
|
|
29
|
+
links: CallGuestLink[];
|
|
30
|
+
}) => void;
|
|
23
31
|
/** Every track of other members the member hears, whenever one comes, goes or its media arrives. */
|
|
24
32
|
onTracks?: (tracks: CallTrack[]) => void;
|
|
25
33
|
/** Everyone in the call, the member too, in the order they came, whenever that changes. */
|
|
@@ -62,6 +70,8 @@ export type Call = {
|
|
|
62
70
|
tracks: () => CallTrack[];
|
|
63
71
|
/** How each of the member's connections fares now: to each other member, or to the media server. */
|
|
64
72
|
connections: () => Promise<CallConnection[]>;
|
|
73
|
+
/** With a member who may invite: guest links, and letting the lobby's guests in. */
|
|
74
|
+
guests: CallGuests;
|
|
65
75
|
};
|
|
66
76
|
/**
|
|
67
77
|
* Joins a call through the app's function socket and resolves once the member is in it. Media flows over plain
|
package/dist/calls/join-call.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { guestRequests } from "./guest-requests.js";
|
|
1
2
|
import { peerLink } from "./peer-link.js";
|
|
2
3
|
import { sfuLink } from "./sfu-link.js";
|
|
3
4
|
//#region src/calls/join-call.ts
|
|
@@ -45,6 +46,8 @@ const joinCall = (options) => {
|
|
|
45
46
|
const send = (message) => {
|
|
46
47
|
if (socket.readyState === WebSocketOf.OPEN) socket.send(JSON.stringify(message));
|
|
47
48
|
};
|
|
49
|
+
const requests = guestRequests(send);
|
|
50
|
+
const guest = options.guest !== void 0 ? { guest: options.guest } : {};
|
|
48
51
|
const setState = (state) => options.onState?.(state);
|
|
49
52
|
const end = (reason, error) => {
|
|
50
53
|
if (ended) return;
|
|
@@ -103,7 +106,15 @@ const joinCall = (options) => {
|
|
|
103
106
|
if (message.reason === "rejoin") rejoin = true;
|
|
104
107
|
else end(message.reason);
|
|
105
108
|
return;
|
|
106
|
-
|
|
109
|
+
case "lobby":
|
|
110
|
+
options.onLobby?.({
|
|
111
|
+
guests: message.guests,
|
|
112
|
+
links: message.links
|
|
113
|
+
});
|
|
114
|
+
return;
|
|
115
|
+
default:
|
|
116
|
+
if (requests.receive(message)) return;
|
|
117
|
+
await link?.receive(message);
|
|
107
118
|
}
|
|
108
119
|
};
|
|
109
120
|
const connect = (mode) => {
|
|
@@ -117,8 +128,12 @@ const joinCall = (options) => {
|
|
|
117
128
|
send(resume ? {
|
|
118
129
|
type: "resume",
|
|
119
130
|
call: callId,
|
|
120
|
-
...resume
|
|
121
|
-
|
|
131
|
+
...resume,
|
|
132
|
+
...guest
|
|
133
|
+
} : {
|
|
134
|
+
type: "join",
|
|
135
|
+
...guest
|
|
136
|
+
});
|
|
122
137
|
});
|
|
123
138
|
};
|
|
124
139
|
socket.onmessage = (event) => {
|
|
@@ -126,6 +141,7 @@ const joinCall = (options) => {
|
|
|
126
141
|
chain = chain.then(() => handle(message)).catch((error) => end("ended", error));
|
|
127
142
|
};
|
|
128
143
|
socket.onclose = (event) => {
|
|
144
|
+
requests.lost();
|
|
129
145
|
chain = chain.then(() => closed(mode, event.code));
|
|
130
146
|
};
|
|
131
147
|
};
|
|
@@ -182,7 +198,8 @@ const joinCall = (options) => {
|
|
|
182
198
|
end("ended");
|
|
183
199
|
},
|
|
184
200
|
tracks: () => remote,
|
|
185
|
-
connections: async () => link ? link.connections() : []
|
|
201
|
+
connections: async () => link ? link.connections() : [],
|
|
202
|
+
guests: requests.guests
|
|
186
203
|
};
|
|
187
204
|
setState({ state: "connecting" });
|
|
188
205
|
connect("join");
|
package/dist/client.d.ts
CHANGED
|
@@ -125,6 +125,10 @@ export declare const createClient: (options?: ClientOptions) => {
|
|
|
125
125
|
list: () => Promise<import("@protobase/schema/internal").CallRing[]>;
|
|
126
126
|
decline: (call: string) => Promise<void>;
|
|
127
127
|
};
|
|
128
|
+
callGuests: {
|
|
129
|
+
allowed: () => Promise<boolean>;
|
|
130
|
+
setAllowed: (allowed: boolean) => Promise<void>;
|
|
131
|
+
};
|
|
128
132
|
};
|
|
129
133
|
export type Client = ReturnType<typeof createClient>;
|
|
130
134
|
//#endregion
|
package/dist/client.js
CHANGED
|
@@ -10,6 +10,7 @@ import { statusClient } from "./status.js";
|
|
|
10
10
|
import { notificationHistoryClient } from "./notification-history.js";
|
|
11
11
|
import { recordCallsClient } from "./record-calls.js";
|
|
12
12
|
import { ringsClient } from "./rings.js";
|
|
13
|
+
import { callGuestsClient } from "./call-guests.js";
|
|
13
14
|
import { encodeKey } from "@protobase/schema/internal";
|
|
14
15
|
//#region src/client.ts
|
|
15
16
|
const nameOf = (resource) => typeof resource === "string" ? resource : resource.toModel().name;
|
|
@@ -475,7 +476,8 @@ const createClient = (options = {}) => {
|
|
|
475
476
|
status: statusClient(send),
|
|
476
477
|
calls,
|
|
477
478
|
watchCalls,
|
|
478
|
-
rings: ringsClient(send)
|
|
479
|
+
rings: ringsClient(send),
|
|
480
|
+
callGuests: callGuestsClient(send)
|
|
479
481
|
};
|
|
480
482
|
};
|
|
481
483
|
//#endregion
|
package/dist/index.d.ts
CHANGED
|
@@ -17,12 +17,12 @@ import { fileUrl } from "./file-urls.js";
|
|
|
17
17
|
import { routedClient } from "./routed-client.js";
|
|
18
18
|
import { SourceMeta, sourceMeta } from "./source-meta.js";
|
|
19
19
|
import { DeviceSession } from "./account-profile.js";
|
|
20
|
+
import { AuthUser, PersonalMailLink, PlatformSignIn, RoleLabel, SamlSignIn, SetupStatus, SignInMethod, SignInResult, TwoFactorMethod } from "./auth-types.js";
|
|
20
21
|
import { SignInPolicy, SignInPolicyClient, SignInPolicyState, SignInRule, StaffAccessRule } from "./sign-in-policy.js";
|
|
21
22
|
import { AccountSecurity, AccountSignIn, AuthenticatorSetup, ConnectedApp, Passkey, RequiredSetup } from "./account-security.js";
|
|
22
23
|
import { ConnectClient, ConnectingClient } from "./connect.js";
|
|
23
24
|
import { CurrentOrganization, InvitationPreview, InvitationSent, Organization, OrganizationInvitation, OrganizationMember, OrganizationPerson, OrganizationRole, OrganizationsClient, OrganizationsFound } from "./organizations.js";
|
|
24
25
|
import { ActiveRole, RoleOption, RolesClient } from "./roles.js";
|
|
25
|
-
import { AuthUser, PlatformSignIn, RoleLabel, SamlSignIn, SetupStatus, SignInMethod, SignInResult, TwoFactorMethod } from "./auth-types.js";
|
|
26
26
|
import { AppUser, UserInvitation, UserInvitationSent, UsersClient, UsersFound } from "./users.js";
|
|
27
27
|
import { StaffSignIn, StaffSignInClient } from "./staff-sign-in.js";
|
|
28
28
|
import { AuthError } from "./auth-error.js";
|
|
@@ -31,4 +31,4 @@ import { createStaticSession } from "./static-session.js";
|
|
|
31
31
|
import { AssistantClient, AssistantClientOptions, AssistantConnection, createAssistantClient } from "./assistant.js";
|
|
32
32
|
import { RuntimeClient, RuntimeClientOptions, RuntimeLastUpdate, RuntimePolicy, RuntimeStatus, RuntimeUpdateStage, createRuntimeClient } from "./runtime.js";
|
|
33
33
|
import { availabilities, heldStatus, maxStatusText, statusTextProblem } from "@protobase/schema/internal";
|
|
34
|
-
export { type AccountSecurity, type AccountSignIn, type ActiveRole, type Aggregate, type AggregateGroup, type AggregateParams, type AggregateSplitTotal, ApiError, type AppUser, type AssistantClient, type AssistantClientOptions, type AssistantConnection, AuthError, type AuthSession, type AuthSessionOptions, type AuthUser, type AuthenticatorSetup, type Availability, type BatchOp, type BatchRef, type BatchResult, type CallRing, type Channel, type ChannelError, type ChannelMessage, ChannelRefusal, type ChannelStatus, type ChannelUser, type Client, type ClientOptions, type CommentPage, type CommentPerson, type ConnectClient, type ConnectedApp, type ConnectingClient, type CurrentOrganization, type DeviceSession, type DevicesClient, type Facet, type FilterInput, type FormChallenge, type FormProof, type Histogram, type HistogramBucket, type HistoryChange, type HistoryPage, type InboxNotification, type InboxPage, type InvitationPreview, type InvitationSent, type InvokeOptions, type ListPage, type ListParams, type LiveChange, type LiveHandlers, type MapBounds, type MapBucket, type MapLayerModel, type MapParams, type MapResult, type MentionableUser, type Meta, type MetaResult, type NotificationHistoryClient, type Organization, type OrganizationInvitation, type OrganizationMember, type OrganizationPerson, type OrganizationRole, type OrganizationsClient, type OrganizationsFound, type Passkey, type PersonStatus, type PlatformSignIn, type PluginRef, PreconditionFailedError, type PresenceChange, type PresenceEntry, type ProblemDetails, type ProblemError, type PublicForm, type RecordCall, type RecordCallsHandlers, type RecordComment, type RecordOf, type RecordPermissions, type RecordPhotos, type RegisteredDevice, type RelatedLabels, type RequiredSetup, type ResourcePermissions, type ResourceRef, type RingsClient, type RoleLabel, type RoleOption, type RolesClient, type RuntimeClient, type RuntimeClientOptions, type RuntimeLastUpdate, type RuntimePolicy, type RuntimeStatus, type RuntimeUpdateStage, type SamlSignIn, type Series, type SeriesParams, type SeriesPoint, type SetupStatus, type SignInMethod, type SignInPolicy, type SignInPolicyClient, type SignInPolicyState, type SignInResult, type SignInRule, type SocketLike, type SourceMeta, type SourceRef, type StaffAccessRule, type StaffSignIn, type StaffSignInClient, type StatusClient, type StatusInput, type Stored, type StoredFile, type StoredFileVariant, type TwoFactorMethod, type UploadOptions, type UploadProgress, type UploadResult, type UserInvitation, type UserInvitationSent, type UsersClient, type UsersFound, type WebDeviceRegistration, availabilities, createAssistantClient, createAuthSession, createClient, createRuntimeClient, createStaticSession, fileUrl, filterText, heldStatus, isApiError, listWire, maxStatusText, routedClient, sourceMeta, statusTextProblem, tokenExpiry };
|
|
34
|
+
export { type AccountSecurity, type AccountSignIn, type ActiveRole, type Aggregate, type AggregateGroup, type AggregateParams, type AggregateSplitTotal, ApiError, type AppUser, type AssistantClient, type AssistantClientOptions, type AssistantConnection, AuthError, type AuthSession, type AuthSessionOptions, type AuthUser, type AuthenticatorSetup, type Availability, type BatchOp, type BatchRef, type BatchResult, type CallRing, type Channel, type ChannelError, type ChannelMessage, ChannelRefusal, type ChannelStatus, type ChannelUser, type Client, type ClientOptions, type CommentPage, type CommentPerson, type ConnectClient, type ConnectedApp, type ConnectingClient, type CurrentOrganization, type DeviceSession, type DevicesClient, type Facet, type FilterInput, type FormChallenge, type FormProof, type Histogram, type HistogramBucket, type HistoryChange, type HistoryPage, type InboxNotification, type InboxPage, type InvitationPreview, type InvitationSent, type InvokeOptions, type ListPage, type ListParams, type LiveChange, type LiveHandlers, type MapBounds, type MapBucket, type MapLayerModel, type MapParams, type MapResult, type MentionableUser, type Meta, type MetaResult, type NotificationHistoryClient, type Organization, type OrganizationInvitation, type OrganizationMember, type OrganizationPerson, type OrganizationRole, type OrganizationsClient, type OrganizationsFound, type Passkey, type PersonStatus, type PersonalMailLink, type PlatformSignIn, type PluginRef, PreconditionFailedError, type PresenceChange, type PresenceEntry, type ProblemDetails, type ProblemError, type PublicForm, type RecordCall, type RecordCallsHandlers, type RecordComment, type RecordOf, type RecordPermissions, type RecordPhotos, type RegisteredDevice, type RelatedLabels, type RequiredSetup, type ResourcePermissions, type ResourceRef, type RingsClient, type RoleLabel, type RoleOption, type RolesClient, type RuntimeClient, type RuntimeClientOptions, type RuntimeLastUpdate, type RuntimePolicy, type RuntimeStatus, type RuntimeUpdateStage, type SamlSignIn, type Series, type SeriesParams, type SeriesPoint, type SetupStatus, type SignInMethod, type SignInPolicy, type SignInPolicyClient, type SignInPolicyState, type SignInResult, type SignInRule, type SocketLike, type SourceMeta, type SourceRef, type StaffAccessRule, type StaffSignIn, type StaffSignInClient, type StatusClient, type StatusInput, type Stored, type StoredFile, type StoredFileVariant, type TwoFactorMethod, type UploadOptions, type UploadProgress, type UploadResult, type UserInvitation, type UserInvitationSent, type UsersClient, type UsersFound, type WebDeviceRegistration, availabilities, createAssistantClient, createAuthSession, createClient, createRuntimeClient, createStaticSession, fileUrl, filterText, heldStatus, isApiError, listWire, maxStatusText, routedClient, sourceMeta, statusTextProblem, tokenExpiry };
|
package/dist/routed-client.js
CHANGED
|
@@ -45,6 +45,7 @@ const routedClient = (own, sourceOf) => {
|
|
|
45
45
|
notifications: own.notifications,
|
|
46
46
|
status: own.status,
|
|
47
47
|
rings: own.rings,
|
|
48
|
+
callGuests: own.callGuests,
|
|
48
49
|
calls: (resource, key) => to(resource).calls(resource, key),
|
|
49
50
|
watchCalls: (resource, key, handlers) => to(resource).watchCalls(resource, key, handlers)
|
|
50
51
|
};
|
package/dist/static-session.js
CHANGED
|
@@ -75,6 +75,8 @@ const createStaticSession = (token, user = {
|
|
|
75
75
|
newBackupCodes: unsupported("make backup codes"),
|
|
76
76
|
linkedProviders: async () => [],
|
|
77
77
|
linkProvider: unsupported("link a sign-in provider"),
|
|
78
|
+
linkedPersonalMail: async () => [],
|
|
79
|
+
linkPersonalMail: unsupported("link a mailbox"),
|
|
78
80
|
connectedApps: async () => [],
|
|
79
81
|
disconnectApp: unsupported("disconnect an app"),
|
|
80
82
|
updateName: unsupported("change its name"),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@protobase/client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.63.0",
|
|
4
4
|
"description": "Typed fetch client for the Protobase REST API.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@better-auth/passkey": "^1.7.12",
|
|
34
|
-
"@protobase/layout": "0.
|
|
35
|
-
"@protobase/schema": "0.
|
|
34
|
+
"@protobase/layout": "0.63.0",
|
|
35
|
+
"@protobase/schema": "0.63.0",
|
|
36
36
|
"@simplewebauthn/browser": "^13.3.0",
|
|
37
37
|
"better-auth": "^1.7.12"
|
|
38
38
|
}
|