fauna-api 1.0.682 → 1.0.692
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/src/authentification.d.ts +34 -0
- package/dist/src/authentification.js +135 -0
- package/dist/src/calendar.d.ts +5 -2
- package/dist/src/calendar.js +5 -2
- package/dist/src/cicada/contacts.d.ts +19 -25
- package/dist/src/cicada/contacts.js +17 -5
- package/dist/src/cicada/inboxes.d.ts +16 -0
- package/dist/src/cicada/inboxes.js +10 -0
- package/dist/src/extensions/web/session.d.ts +1 -3
- package/dist/src/extensions/web/session.js +0 -1
- package/dist/src/groups.d.ts +167 -20
- package/dist/src/groups.js +287 -31
- package/dist/src/marmot/web.d.ts +27 -9
- package/dist/src/marmot/web.js +118 -79
- package/dist/src/parrot/room.d.ts +6 -2
- package/dist/src/parrot/room.js +11 -0
- package/dist/src/parrot/share.d.ts +4 -1
- package/dist/src/parrot/share.js +4 -2
- package/dist/src/rooms.d.ts +37 -11
- package/dist/src/rooms.js +46 -14
- package/dist/src/shared/server.d.ts +23 -0
- package/dist/src/shared/server.js +41 -0
- package/dist/src/ui/authentification.d.ts +6 -2
- package/dist/src/ui/authentification.js +36 -10
- package/dist/src/ui/browser.js +1 -1
- package/dist/src/ui/chat.js +8 -6
- package/dist/src/ui/chatSequence.d.ts +3 -2
- package/dist/src/ui/chatSequence.js +7 -2
- package/dist/src/ui/drive.js +1 -1
- package/dist/src/ui/index.d.ts +2 -0
- package/dist/src/ui/index.js +2 -0
- package/dist/src/ui/integrations.js +74 -0
- package/dist/src/ui/maps.d.ts +1 -1
- package/dist/src/ui/maps.js +3 -1
- package/dist/src/ui/markdown.d.ts +5 -0
- package/dist/src/ui/markdown.js +33 -0
- package/dist/src/ui/toast.d.ts +2 -2
- package/dist/src/ui/toast.js +5 -5
- package/dist/src/ui/ui.css +137 -0
- package/dist/src/webhooks.d.ts +2 -0
- package/package.json +2 -2
package/dist/src/groups.js
CHANGED
|
@@ -1,5 +1,95 @@
|
|
|
1
1
|
import { Fauna } from "../index.js";
|
|
2
2
|
import { LastMessage } from "./parrot/chat.js";
|
|
3
|
+
export const GroupRef = {
|
|
4
|
+
fromJSON(json) {
|
|
5
|
+
return {
|
|
6
|
+
id: String(json.id),
|
|
7
|
+
name: String(json.name),
|
|
8
|
+
...(json.icon ? { icon: String(json.icon) } : {}),
|
|
9
|
+
};
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
export const GroupMember = {
|
|
13
|
+
fromJSON(json) {
|
|
14
|
+
return {
|
|
15
|
+
email: String(json.email),
|
|
16
|
+
...(json.displayName ? { displayName: String(json.displayName) } : {}),
|
|
17
|
+
...(json.icon ? { icon: String(json.icon) } : {}),
|
|
18
|
+
through: String(json.through),
|
|
19
|
+
};
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
export const Group = {
|
|
23
|
+
fromJSON(json) {
|
|
24
|
+
return {
|
|
25
|
+
id: String(json.id),
|
|
26
|
+
name: String(json.name),
|
|
27
|
+
...(json.icon ? { icon: String(json.icon) } : {}),
|
|
28
|
+
balance: Number(json.balance),
|
|
29
|
+
createdAt: new Date(json.createdAt),
|
|
30
|
+
admins: json.admins.map(String),
|
|
31
|
+
people: json.people.map(String),
|
|
32
|
+
groups: json.groups.map(GroupRef.fromJSON),
|
|
33
|
+
members: json.members.map(GroupMember.fromJSON),
|
|
34
|
+
through: String(json.through),
|
|
35
|
+
};
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
export const JoinLink = {
|
|
39
|
+
fromJSON(json) {
|
|
40
|
+
return {
|
|
41
|
+
code: String(json.code),
|
|
42
|
+
uses: Number(json.uses),
|
|
43
|
+
...(typeof json.maxUses === 'number' ? { maxUses: json.maxUses } : {}),
|
|
44
|
+
expires: new Date(json.expires),
|
|
45
|
+
};
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
export const GroupSummary = {
|
|
49
|
+
fromJSON(json) {
|
|
50
|
+
return {
|
|
51
|
+
id: String(json.id),
|
|
52
|
+
name: String(json.name),
|
|
53
|
+
...(json.icon ? { icon: String(json.icon) } : {}),
|
|
54
|
+
memberCount: Number(json.memberCount),
|
|
55
|
+
};
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
export const MatchedGroup = {
|
|
59
|
+
fromJSON(json) {
|
|
60
|
+
return { ...GroupSummary.fromJSON(json), through: String(json.through) };
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
export const GroupMatch = {
|
|
64
|
+
fromJSON(json) {
|
|
65
|
+
return {
|
|
66
|
+
profile: {
|
|
67
|
+
email: String(json.profile.email),
|
|
68
|
+
...(json.profile.displayName ? { displayName: String(json.profile.displayName) } : {}),
|
|
69
|
+
...(json.profile.icon ? { icon: String(json.profile.icon) } : {}),
|
|
70
|
+
},
|
|
71
|
+
groups: json.groups.map(MatchedGroup.fromJSON),
|
|
72
|
+
};
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
export const GroupNest = {
|
|
76
|
+
fromJSON(json) {
|
|
77
|
+
return {
|
|
78
|
+
token: String(json.token),
|
|
79
|
+
parent: GroupRef.fromJSON(json.parent),
|
|
80
|
+
child: GroupRef.fromJSON(json.child),
|
|
81
|
+
from: json.from === 'child' ? 'child' : 'parent',
|
|
82
|
+
...(json.by ? { by: String(json.by) } : {}),
|
|
83
|
+
expires: new Date(json.expires),
|
|
84
|
+
};
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
export const NestOffer = {
|
|
88
|
+
fromJSON(json) {
|
|
89
|
+
return json.nested === true ? { nested: true } : { nested: false, token: String(json.token) };
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
/** Start a group. You are its first admin. Needs a subscription. */
|
|
3
93
|
export async function create(credentials, name) {
|
|
4
94
|
const response = await fetch(`${Fauna.getURL()}/groups`, {
|
|
5
95
|
method: "POST",
|
|
@@ -12,9 +102,10 @@ export async function create(credentials, name) {
|
|
|
12
102
|
if (!response.ok) {
|
|
13
103
|
throw new Error(await response.text());
|
|
14
104
|
}
|
|
15
|
-
|
|
16
|
-
return { ...raw, createdAt: new Date(raw.createdAt) };
|
|
105
|
+
return Group.fromJSON(await response.json());
|
|
17
106
|
}
|
|
107
|
+
/** Every group you are in, directly or through a nested group, oldest first.
|
|
108
|
+
* Each says how you are in it (`through`). */
|
|
18
109
|
export async function list(authorization) {
|
|
19
110
|
const response = await fetch(`${Fauna.getURL()}/groups`, {
|
|
20
111
|
method: "GET",
|
|
@@ -25,11 +116,10 @@ export async function list(authorization) {
|
|
|
25
116
|
if (!response.ok) {
|
|
26
117
|
throw new Error(await response.text());
|
|
27
118
|
}
|
|
28
|
-
|
|
29
|
-
return raw.map((group) => ({ ...group, createdAt: new Date(group.createdAt) }));
|
|
119
|
+
return (await response.json()).map(Group.fromJSON);
|
|
30
120
|
}
|
|
31
|
-
/** People matching a partial email or name, best first, each with
|
|
32
|
-
* Only people in at least one group come back. */
|
|
121
|
+
/** People matching a partial email or name, best first, each with every group
|
|
122
|
+
* they are in and how. Only people in at least one group come back. */
|
|
33
123
|
export async function query(authorization, profile) {
|
|
34
124
|
const response = await fetch(`${Fauna.getURL()}/groups/query`, {
|
|
35
125
|
method: "POST",
|
|
@@ -42,7 +132,7 @@ export async function query(authorization, profile) {
|
|
|
42
132
|
if (!response.ok) {
|
|
43
133
|
throw new Error(await response.text());
|
|
44
134
|
}
|
|
45
|
-
return await response.json();
|
|
135
|
+
return (await response.json()).map(GroupMatch.fromJSON);
|
|
46
136
|
}
|
|
47
137
|
/** Name, icon and member count of groups by id, including groups you are not in.
|
|
48
138
|
* Unknown ids are left out. */
|
|
@@ -58,8 +148,9 @@ export async function summaries(authorization, ids) {
|
|
|
58
148
|
if (!response.ok) {
|
|
59
149
|
throw new Error(await response.text());
|
|
60
150
|
}
|
|
61
|
-
return await response.json();
|
|
151
|
+
return (await response.json()).map(GroupSummary.fromJSON);
|
|
62
152
|
}
|
|
153
|
+
/** A group you are in, directly or through a nested group. */
|
|
63
154
|
export async function get(authorization, id) {
|
|
64
155
|
const response = await fetch(`${Fauna.getURL()}/groups/${encodeURIComponent(id)}`, {
|
|
65
156
|
method: "GET",
|
|
@@ -70,9 +161,9 @@ export async function get(authorization, id) {
|
|
|
70
161
|
if (!response.ok) {
|
|
71
162
|
throw new Error(await response.text());
|
|
72
163
|
}
|
|
73
|
-
|
|
74
|
-
return { ...raw, createdAt: new Date(raw.createdAt) };
|
|
164
|
+
return Group.fromJSON(await response.json());
|
|
75
165
|
}
|
|
166
|
+
/** Change the group's name or icon. Admins only. */
|
|
76
167
|
export async function edit(credentials, id, update) {
|
|
77
168
|
const response = await fetch(`${Fauna.getURL()}/groups/${encodeURIComponent(id)}`, {
|
|
78
169
|
method: "PATCH",
|
|
@@ -85,14 +176,27 @@ export async function edit(credentials, id, update) {
|
|
|
85
176
|
if (!response.ok) {
|
|
86
177
|
throw new Error(await response.text());
|
|
87
178
|
}
|
|
88
|
-
|
|
89
|
-
return { ...raw, createdAt: new Date(raw.createdAt) };
|
|
179
|
+
return Group.fromJSON(await response.json());
|
|
90
180
|
}
|
|
91
|
-
/**
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
|
|
95
|
-
|
|
181
|
+
/** Delete a group with its chats, files, calendar, rooms, webhooks and
|
|
182
|
+
* partnerships. It leaves every group it was in; the groups inside it stay.
|
|
183
|
+
* Its direct admins may, and so may anyone holding `fauna/groups:delete:global`. */
|
|
184
|
+
export async function remove(credentials, id) {
|
|
185
|
+
const response = await fetch(`${Fauna.getURL()}/groups/${encodeURIComponent(id)}`, {
|
|
186
|
+
method: "DELETE",
|
|
187
|
+
headers: {
|
|
188
|
+
"Authorization": `Token ${credentials.token}`
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
if (!response.ok) {
|
|
192
|
+
throw new Error(await response.text());
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
/** Invite an email to a group. Admins only. Nobody joins until they accept the
|
|
196
|
+
* invite with its token (`acceptInvite`), whether or not the email already has
|
|
197
|
+
* a Fauna account, and the answer is the same either way. Fauna emails the
|
|
198
|
+
* invite unless `notify` is false, so an app can send its own email carrying
|
|
199
|
+
* the token. Resolves to the token. */
|
|
96
200
|
export async function invite(credentials, id, email, options = {}) {
|
|
97
201
|
const response = await fetch(`${Fauna.getURL()}/groups/${encodeURIComponent(id)}/invite`, {
|
|
98
202
|
method: "POST",
|
|
@@ -105,9 +209,10 @@ export async function invite(credentials, id, email, options = {}) {
|
|
|
105
209
|
if (!response.ok) {
|
|
106
210
|
throw new Error(await response.text());
|
|
107
211
|
}
|
|
108
|
-
return await response.json();
|
|
212
|
+
return (await response.json()).token;
|
|
109
213
|
}
|
|
110
|
-
/** Join the group an email invite points at, using the token from the invite.
|
|
214
|
+
/** Join the group an email invite points at, using the token from the invite.
|
|
215
|
+
* `alreadyMember` says you were directly in it already. */
|
|
111
216
|
export async function acceptInvite(credentials, token) {
|
|
112
217
|
const response = await fetch(`${Fauna.getURL()}/groups/invites/accept`, {
|
|
113
218
|
method: "POST",
|
|
@@ -121,17 +226,19 @@ export async function acceptInvite(credentials, token) {
|
|
|
121
226
|
throw new Error(await response.text());
|
|
122
227
|
}
|
|
123
228
|
const raw = await response.json();
|
|
124
|
-
return {
|
|
125
|
-
group: { ...raw.group, createdAt: new Date(raw.group.createdAt) },
|
|
126
|
-
alreadyMember: raw.alreadyMember
|
|
127
|
-
};
|
|
229
|
+
return { group: Group.fromJSON(raw.group), alreadyMember: raw.alreadyMember === true };
|
|
128
230
|
}
|
|
129
|
-
|
|
231
|
+
/** A join code good for seven days. Admins only. People join with it, and admins
|
|
232
|
+
* of other groups put their group inside this one with it. `maxUses` caps how
|
|
233
|
+
* many it lets in; without it, any number can join until it expires. */
|
|
234
|
+
export async function generateLink(credentials, id, options = {}) {
|
|
130
235
|
const response = await fetch(`${Fauna.getURL()}/groups/${encodeURIComponent(id)}/link`, {
|
|
131
236
|
method: "POST",
|
|
132
237
|
headers: {
|
|
238
|
+
"Content-Type": "application/json",
|
|
133
239
|
"Authorization": `Token ${credentials.token}`
|
|
134
|
-
}
|
|
240
|
+
},
|
|
241
|
+
body: JSON.stringify({ maxUses: options.maxUses })
|
|
135
242
|
});
|
|
136
243
|
if (!response.ok) {
|
|
137
244
|
throw new Error(await response.text());
|
|
@@ -139,24 +246,52 @@ export async function generateLink(credentials, id) {
|
|
|
139
246
|
const json = await response.json();
|
|
140
247
|
return json.code;
|
|
141
248
|
}
|
|
142
|
-
|
|
249
|
+
/** The group's join links that still work, newest first. Admins only. */
|
|
250
|
+
export async function links(credentials, id) {
|
|
251
|
+
const response = await fetch(`${Fauna.getURL()}/groups/${encodeURIComponent(id)}/links`, {
|
|
252
|
+
method: "GET",
|
|
253
|
+
headers: {
|
|
254
|
+
"Authorization": `Token ${credentials.token}`
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
if (!response.ok) {
|
|
258
|
+
throw new Error(await response.text());
|
|
259
|
+
}
|
|
260
|
+
return (await response.json()).map(JoinLink.fromJSON);
|
|
261
|
+
}
|
|
262
|
+
/** A join link stops working. Admins only. */
|
|
263
|
+
export async function revokeLink(credentials, id, code) {
|
|
264
|
+
const response = await fetch(`${Fauna.getURL()}/groups/${encodeURIComponent(id)}/links/${encodeURIComponent(code)}`, {
|
|
265
|
+
method: "DELETE",
|
|
266
|
+
headers: {
|
|
267
|
+
"Authorization": `Token ${credentials.token}`
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
if (!response.ok) {
|
|
271
|
+
throw new Error(await response.text());
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
/** Join a group with a join code. With `group`, a group you administer goes
|
|
275
|
+
* inside it instead, and you are in it through that group. `alreadyMember` says
|
|
276
|
+
* you (or `group`) were in it already. */
|
|
277
|
+
export async function join(credentials, code, group) {
|
|
143
278
|
const response = await fetch(`${Fauna.getURL()}/groups/join`, {
|
|
144
279
|
method: "POST",
|
|
145
280
|
headers: {
|
|
146
281
|
"Content-Type": "application/json",
|
|
147
282
|
"Authorization": `Token ${credentials.token}`
|
|
148
283
|
},
|
|
149
|
-
body: JSON.stringify({ code })
|
|
284
|
+
body: JSON.stringify({ code, group })
|
|
150
285
|
});
|
|
151
286
|
if (!response.ok) {
|
|
152
287
|
throw new Error(await response.text());
|
|
153
288
|
}
|
|
154
289
|
const raw = await response.json();
|
|
155
|
-
return {
|
|
156
|
-
group: { ...raw.group, createdAt: new Date(raw.group.createdAt) },
|
|
157
|
-
alreadyMember: raw.alreadyMember
|
|
158
|
-
};
|
|
290
|
+
return { group: Group.fromJSON(raw.group), alreadyMember: raw.alreadyMember === true };
|
|
159
291
|
}
|
|
292
|
+
/** Leave a group you are directly in. The last admin can't while anyone else is
|
|
293
|
+
* in it, directly or through a nested group: make someone else an admin, or
|
|
294
|
+
* delete the group. When nobody else is in it, leaving deletes it. */
|
|
160
295
|
export async function leave(credentials, id) {
|
|
161
296
|
const response = await fetch(`${Fauna.getURL()}/groups/${encodeURIComponent(id)}/membership`, {
|
|
162
297
|
method: "DELETE",
|
|
@@ -168,6 +303,7 @@ export async function leave(credentials, id) {
|
|
|
168
303
|
throw new Error(await response.text());
|
|
169
304
|
}
|
|
170
305
|
}
|
|
306
|
+
/** Remove a person who is directly in the group. Admins only. */
|
|
171
307
|
export async function kick(credentials, id, email) {
|
|
172
308
|
const response = await fetch(`${Fauna.getURL()}/groups/${encodeURIComponent(id)}/members/${encodeURIComponent(email)}`, {
|
|
173
309
|
method: "DELETE",
|
|
@@ -179,6 +315,126 @@ export async function kick(credentials, id, email) {
|
|
|
179
315
|
throw new Error(await response.text());
|
|
180
316
|
}
|
|
181
317
|
}
|
|
318
|
+
/** Make a person who is directly in the group an admin. Admins only. Someone in
|
|
319
|
+
* it only through a nested group is invited directly first. */
|
|
320
|
+
export async function promote(credentials, id, email) {
|
|
321
|
+
const response = await fetch(`${Fauna.getURL()}/groups/${encodeURIComponent(id)}/admins/${encodeURIComponent(email)}`, {
|
|
322
|
+
method: "POST",
|
|
323
|
+
headers: {
|
|
324
|
+
"Authorization": `Token ${credentials.token}`
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
if (!response.ok) {
|
|
328
|
+
throw new Error(await response.text());
|
|
329
|
+
}
|
|
330
|
+
return Group.fromJSON(await response.json());
|
|
331
|
+
}
|
|
332
|
+
/** Make an admin a member again. Admins only; a group keeps at least one admin. */
|
|
333
|
+
export async function demote(credentials, id, email) {
|
|
334
|
+
const response = await fetch(`${Fauna.getURL()}/groups/${encodeURIComponent(id)}/admins/${encodeURIComponent(email)}`, {
|
|
335
|
+
method: "DELETE",
|
|
336
|
+
headers: {
|
|
337
|
+
"Authorization": `Token ${credentials.token}`
|
|
338
|
+
}
|
|
339
|
+
});
|
|
340
|
+
if (!response.ok) {
|
|
341
|
+
throw new Error(await response.text());
|
|
342
|
+
}
|
|
343
|
+
return Group.fromJSON(await response.json());
|
|
344
|
+
}
|
|
345
|
+
/** Invite group `child` inside group `id`; the child's admins accept with the
|
|
346
|
+
* token (`acceptNest`). Admins of `id` only. Nests at once when you administer
|
|
347
|
+
* both. Unless `notify` is false, the child's admins hear about it in their
|
|
348
|
+
* Fauna inbox. Nesting is at most 5 groups deep and never makes a loop. */
|
|
349
|
+
export async function inviteGroup(credentials, id, child, options = {}) {
|
|
350
|
+
const response = await fetch(`${Fauna.getURL()}/groups/${encodeURIComponent(id)}/groups`, {
|
|
351
|
+
method: "POST",
|
|
352
|
+
headers: {
|
|
353
|
+
"Content-Type": "application/json",
|
|
354
|
+
"Authorization": `Token ${credentials.token}`
|
|
355
|
+
},
|
|
356
|
+
body: JSON.stringify({ group: child, notify: options.notify })
|
|
357
|
+
});
|
|
358
|
+
if (!response.ok) {
|
|
359
|
+
throw new Error(await response.text());
|
|
360
|
+
}
|
|
361
|
+
return NestOffer.fromJSON(await response.json());
|
|
362
|
+
}
|
|
363
|
+
/** Ask to put group `id` inside group `parent`; the parent's admins approve with
|
|
364
|
+
* the token (`acceptNest`). Admins of `id` only. Nests at once when you
|
|
365
|
+
* administer both. Unless `notify` is false, the parent's admins hear about it
|
|
366
|
+
* in their Fauna inbox. */
|
|
367
|
+
export async function requestGroup(credentials, id, parent, options = {}) {
|
|
368
|
+
const response = await fetch(`${Fauna.getURL()}/groups/${encodeURIComponent(id)}/parents`, {
|
|
369
|
+
method: "POST",
|
|
370
|
+
headers: {
|
|
371
|
+
"Content-Type": "application/json",
|
|
372
|
+
"Authorization": `Token ${credentials.token}`
|
|
373
|
+
},
|
|
374
|
+
body: JSON.stringify({ group: parent, notify: options.notify })
|
|
375
|
+
});
|
|
376
|
+
if (!response.ok) {
|
|
377
|
+
throw new Error(await response.text());
|
|
378
|
+
}
|
|
379
|
+
return NestOffer.fromJSON(await response.json());
|
|
380
|
+
}
|
|
381
|
+
/** The invites and requests waiting on or from a group, newest first. Admins only. */
|
|
382
|
+
export async function nests(credentials, id, query) {
|
|
383
|
+
const params = new URLSearchParams({ cursor: String(query.cursor), max: String(query.max) });
|
|
384
|
+
const response = await fetch(`${Fauna.getURL()}/groups/${encodeURIComponent(id)}/nests?${params}`, {
|
|
385
|
+
method: "GET",
|
|
386
|
+
headers: {
|
|
387
|
+
"Authorization": `Token ${credentials.token}`
|
|
388
|
+
}
|
|
389
|
+
});
|
|
390
|
+
if (!response.ok) {
|
|
391
|
+
throw new Error(await response.text());
|
|
392
|
+
}
|
|
393
|
+
return (await response.json()).map(GroupNest.fromJSON);
|
|
394
|
+
}
|
|
395
|
+
/** Accept an invite into a group, or approve a request to join one, by its
|
|
396
|
+
* token. An admin of the side it waits on only. Resolves to the parent group. */
|
|
397
|
+
export async function acceptNest(credentials, token) {
|
|
398
|
+
const response = await fetch(`${Fauna.getURL()}/groups/nests/accept`, {
|
|
399
|
+
method: "POST",
|
|
400
|
+
headers: {
|
|
401
|
+
"Content-Type": "application/json",
|
|
402
|
+
"Authorization": `Token ${credentials.token}`
|
|
403
|
+
},
|
|
404
|
+
body: JSON.stringify({ token })
|
|
405
|
+
});
|
|
406
|
+
if (!response.ok) {
|
|
407
|
+
throw new Error(await response.text());
|
|
408
|
+
}
|
|
409
|
+
return Group.fromJSON(await response.json());
|
|
410
|
+
}
|
|
411
|
+
/** Drop a waiting invite or request by its token. An admin of either group. */
|
|
412
|
+
export async function revokeNest(credentials, token) {
|
|
413
|
+
const response = await fetch(`${Fauna.getURL()}/groups/nests/revoke`, {
|
|
414
|
+
method: "POST",
|
|
415
|
+
headers: {
|
|
416
|
+
"Content-Type": "application/json",
|
|
417
|
+
"Authorization": `Token ${credentials.token}`
|
|
418
|
+
},
|
|
419
|
+
body: JSON.stringify({ token })
|
|
420
|
+
});
|
|
421
|
+
if (!response.ok) {
|
|
422
|
+
throw new Error(await response.text());
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
/** Take group `child` out of group `id`. An admin of either group. Everyone who
|
|
426
|
+
* was in `id` only through it loses it. */
|
|
427
|
+
export async function unnest(credentials, id, child) {
|
|
428
|
+
const response = await fetch(`${Fauna.getURL()}/groups/${encodeURIComponent(id)}/groups/${encodeURIComponent(child)}`, {
|
|
429
|
+
method: "DELETE",
|
|
430
|
+
headers: {
|
|
431
|
+
"Authorization": `Token ${credentials.token}`
|
|
432
|
+
}
|
|
433
|
+
});
|
|
434
|
+
if (!response.ok) {
|
|
435
|
+
throw new Error(await response.text());
|
|
436
|
+
}
|
|
437
|
+
}
|
|
182
438
|
function hydratePartnership(raw) {
|
|
183
439
|
return {
|
|
184
440
|
...raw,
|
package/dist/src/marmot/web.d.ts
CHANGED
|
@@ -162,8 +162,9 @@ export declare class DomRecorder {
|
|
|
162
162
|
stop(): void;
|
|
163
163
|
}
|
|
164
164
|
/**
|
|
165
|
-
* Re-render a
|
|
166
|
-
*
|
|
165
|
+
* Re-render a shared page into a frame inside `mount` and apply incoming `WebMutation`s.
|
|
166
|
+
* The page is someone else's, so the frame is sandboxed without scripts: the replayer
|
|
167
|
+
* writes into it from this page, and nothing the page carries ever runs. The replayer
|
|
167
168
|
* keeps its own id->Node map mirroring the recorder's synthetic ids.
|
|
168
169
|
*/
|
|
169
170
|
export declare class DomReplayer {
|
|
@@ -185,9 +186,15 @@ export declare class DomReplayer {
|
|
|
185
186
|
} | null;
|
|
186
187
|
private docRoot;
|
|
187
188
|
/**
|
|
188
|
-
*
|
|
189
|
-
*
|
|
190
|
-
*
|
|
189
|
+
* A fresh frame for a replay, loaded with `srcdoc`. Same origin without scripts: this
|
|
190
|
+
* page can write into it, and the shared page can't run anything there. Null when a
|
|
191
|
+
* newer replay started while it loaded.
|
|
192
|
+
*/
|
|
193
|
+
private openFrame;
|
|
194
|
+
private flushQueued;
|
|
195
|
+
/**
|
|
196
|
+
* Apply a cleaned HTML document, or a fragment, which the frame parses into one.
|
|
197
|
+
* The `<html>/<head>/<body>` structure and DFS ids match the host's.
|
|
191
198
|
*/
|
|
192
199
|
applyHtml(html: string, viewport?: {
|
|
193
200
|
width: number;
|
|
@@ -229,10 +236,11 @@ export declare class DomReplayer {
|
|
|
229
236
|
*/
|
|
230
237
|
private mirrorStates;
|
|
231
238
|
private ownerDoc;
|
|
239
|
+
/** `seen` keeps a subtree that names a node twice (or itself) from building forever. */
|
|
232
240
|
private build;
|
|
233
241
|
private buildFromList;
|
|
234
242
|
/** Render a fresh snapshot, replacing whatever the mount currently holds. */
|
|
235
|
-
apply(snapshot: WebSnapshot): void
|
|
243
|
+
apply(snapshot: WebSnapshot): Promise<void>;
|
|
236
244
|
/** Apply one incremental mutation to the rendered tree. */
|
|
237
245
|
mutate(mutation: WebMutation): void;
|
|
238
246
|
}
|
|
@@ -249,10 +257,20 @@ export declare function pageToHtml(root?: Node): {
|
|
|
249
257
|
clone: Element;
|
|
250
258
|
cssUrls: string[];
|
|
251
259
|
};
|
|
252
|
-
/** Install a MutationObserver that posts WebMutations to `window[pushName]
|
|
260
|
+
/** Install a MutationObserver that posts WebMutations to `window[pushName]` as
|
|
261
|
+
* `{ token, mutation }`, so the host knows which recorder sent each one.
|
|
253
262
|
* Framed documents are walked, observed, and re-inlined on navigation, with
|
|
254
|
-
* their html, head, and body addressed as the divs `pageToHtml` emits.
|
|
255
|
-
|
|
263
|
+
* their html, head, and body addressed as the divs `pageToHtml` emits.
|
|
264
|
+
* With `remoteFrames`, a frame whose document this page can't read is left to
|
|
265
|
+
* the host, which streams it from the frame itself: its wrapper says
|
|
266
|
+
* `data-fauna-iframe="remote"` and holds nothing. With `framed`, this document
|
|
267
|
+
* is such a frame, recorded the way a parent would inline it, and
|
|
268
|
+
* `__faunaRecorder.snapshot()` serializes it. */
|
|
269
|
+
export declare function pageInstallRecorder(pushName: string, options: {
|
|
270
|
+
token: string;
|
|
271
|
+
framed?: boolean;
|
|
272
|
+
remoteFrames?: boolean;
|
|
273
|
+
}): void;
|
|
256
274
|
export declare function pageStopRecorder(): void;
|
|
257
275
|
/** Runs in the page: the pointer at (x, y) with the CSS cursor of whatever is under it,
|
|
258
276
|
* looking inside frames the recorder inlines. */
|