@vercel/board 0.16.0 → 0.18.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 +27 -27
- package/dist/{a2-C41hD8SF.mjs → a2-ChRLRupa.mjs} +969 -25
- package/dist/access.d.mts +1 -1
- package/dist/access.mjs +3 -3
- package/dist/{actors-DjMeZpnU.mjs → actors-BOamkEuz.mjs} +3 -73
- package/dist/attempts-CLG840Oj.mjs +20 -0
- package/dist/{auth-COzc09sn.mjs → auth-Drg9FiC2.mjs} +225 -2
- package/dist/backend-B-SJ7p6p.d.mts +680 -0
- package/dist/backend-a2/contract.d.mts +873 -2
- package/dist/backend-a2/contract.mjs +2 -2
- package/dist/backend-a2/scheduler-local.d.mts +1 -1
- package/dist/backend-a2/scheduler-local.mjs +1 -1
- package/dist/backend-a2/scheduler-qstash.d.mts +78 -1
- package/dist/backend-a2/scheduler-qstash.mjs +521 -1
- package/dist/backend-a2/scheduler-vercel.d.mts +37 -1
- package/dist/backend-a2/scheduler-vercel.mjs +203 -1
- package/dist/backend-a2/store-memory.d.mts +2 -2
- package/dist/backend-a2/store-memory.mjs +3 -3
- package/dist/backend-a2/store-postgres.d.mts +1 -1
- package/dist/backend-a2/store-postgres.mjs +2850 -2
- package/dist/backend-a2/store-redis-http.d.mts +1 -1
- package/dist/backend-a2/store-redis-http.mjs +490 -2
- package/dist/backend-a2/store-redis.d.mts +10 -2
- package/dist/backend-a2/store-redis.mjs +51 -2
- package/dist/backend-a2/store-sqlite.d.mts +1 -1
- package/dist/backend-a2/store-sqlite.mjs +3 -3
- package/dist/backend-a2.d.mts +2706 -3
- package/dist/backend-a2.mjs +1 -1
- package/dist/{backend-http-Bid7RIpC.d.mts → backend-http-7cNb8nJI.d.mts} +10 -3
- package/dist/{backend-http-0roEmjl0.mjs → backend-http-CMlL3yq3.mjs} +2 -2
- package/dist/{backend-http-BVRno-ca.mjs → backend-http-Ddzd5kTS.mjs} +32 -3
- package/dist/backend-http.d.mts +1 -1
- package/dist/backend-http.mjs +1 -1
- package/dist/backend-http.node.d.mts +1 -1
- package/dist/backend-http.node.mjs +1 -1
- package/dist/{chat-provider-XCnQlxq6.d.mts → chat-provider-DNJQyajS.d.mts} +16 -4
- package/dist/{chat-provider-jFSeyNmB.mjs → chat-provider-YHy-WbrB.mjs} +15 -9
- package/dist/cli.mjs +30 -10
- package/dist/{client-DGDPaN7U.mjs → client-BA-J7usH.mjs} +10 -2
- package/dist/{conformance-DRR23YNy.mjs → conformance-CT5EeHeC.mjs} +5 -2
- package/dist/conformance.d.mts +1 -1
- package/dist/conformance.mjs +1 -1
- package/dist/{engine-Bir5s8ts.mjs → engine-D0oBUBEK.mjs} +249 -163
- package/dist/events-CewD4kw7.mjs +75 -0
- package/dist/{exports-Dvc1o52I.mjs → exports-CgjfMrQ-.mjs} +35 -32
- package/dist/exports-ZsgjzEnM.d.mts +4 -0
- package/dist/external-BV_cUncs.mjs +151 -0
- package/dist/folds-CRYY14kc.d.mts +534 -0
- package/dist/{reducers-mUPFuFJV.mjs → folds-Dyjput8M.mjs} +6 -73
- package/dist/ids-C6AYo1bu.mjs +31 -0
- package/dist/index.d.mts +4 -4
- package/dist/{index.default-Bkg77Pxn.mjs → index.default-C5Cpz3sa.mjs} +1 -1
- package/dist/index.mjs +5 -5
- package/dist/index.node.d.mts +4 -4
- package/dist/index.node.mjs +3 -3
- package/dist/inspect/app.js +31 -31
- package/dist/inspect/engine.js +5 -5
- package/dist/internal-CvsrprnU-CRY89I-b.mjs +203 -0
- package/dist/{local-Cr_dSjvs.mjs → local-DhkrAqPP.mjs} +1 -1
- package/dist/mentions-CB6ShY4R.mjs +72 -0
- package/dist/{targets-yM5JBUgr.mjs → middleware-CqaCwucP.mjs} +1 -33
- package/dist/platform-B4TnJtWu-CwcTyKg2.mjs +32 -0
- package/dist/{project-CFiArraX.mjs → project-DMDST9kl.mjs} +1 -1
- package/dist/{provider-BGjz-mDa.d.mts → provider-B0b9Qxw4.d.mts} +170 -40
- package/dist/provider-B3DpYSDq.mjs +220 -0
- package/dist/redis-tables-DN9PfIDi.mjs +3897 -0
- package/dist/reducer-CYPHsSmd-BQIfozGi.d.mts +170 -0
- package/dist/reducer-CjmvZSAb-D_OSISmj.mjs +74 -0
- package/dist/{contract-CuJmlrhw.mjs → reducers-BFmIXilu.mjs} +260 -287
- package/dist/retryable-lazy-DZWmHpii-Bye-W8q7.mjs +19 -0
- package/dist/scheduler-task-X1SToDjP-BVoWuInI.mjs +69 -0
- package/dist/{serve-BsOOc-6_.mjs → serve-BGYw0uNL.mjs} +5 -5
- package/dist/{server-jwPY7_wi.mjs → server-DPxBSogx.mjs} +4 -4
- package/dist/server-DtFrWxi3-Boa6gdWO.mjs +3602 -0
- package/dist/server-qgez0Xny-D5mLfqFQ.d.mts +385 -0
- package/dist/{serving-BNbzc96L.mjs → serving-CNkgUPW1.mjs} +1 -1
- package/dist/session-clear-wHd5GCpZ-BnKSxReK.mjs +51 -0
- package/dist/{sql-DbiEnqM0.mjs → sql-U9WTxrwJ.mjs} +2 -2
- package/dist/{sqlite-db-Cbj03vmp.mjs → sqlite-db-Ds4majtT.mjs} +1 -1
- package/dist/store-D0MhBvg6-4Z2L0Kqd.d.mts +530 -0
- package/dist/store-N8PXxDAS-BWBgzBHp.mjs +5 -0
- package/dist/store-codec-DwrWlgQx-CYxGW0aD.mjs +61 -0
- package/dist/store-memory-Bas9Uq5C.mjs +872 -0
- package/dist/store-memory-ZLiZbH3R.mjs +2 -0
- package/dist/store-polling-BZt2Rf3D-BiEM6_HB.mjs +148 -0
- package/dist/store-presence-polling-JuAy2Ck2-CYpuK75X.mjs +109 -0
- package/dist/store-sqlite-BmwL3pUR.mjs +2 -0
- package/dist/store-sqlite-CxxPCcCT.mjs +1053 -0
- package/dist/stream-buffer-DrTyiIuo-BKy-vI14.mjs +53 -0
- package/dist/sync-github.d.mts +24 -17
- package/dist/sync-github.mjs +89 -22
- package/dist/sync-kapso.d.mts +15 -13
- package/dist/sync-kapso.mjs +17 -14
- package/dist/sync-linear.d.mts +219 -0
- package/dist/sync-linear.mjs +311 -0
- package/dist/sync-slack.d.mts +12 -17
- package/dist/sync-slack.mjs +54 -42
- package/dist/sync.chat.d.mts +1 -1
- package/dist/sync.chat.mjs +1 -1
- package/dist/sync.d.mts +3 -3
- package/dist/sync.mjs +5 -4
- package/dist/targets-C-wdR5wP.mjs +33 -0
- package/dist/{tokens-DKLn5P9B.mjs → tokens-DhuzKzAl.mjs} +1 -1
- package/dist/{types-BHCjTZdB.d.mts → types-8yq2VnKI.d.mts} +2 -2
- package/dist/{users-Dls7_ANV.mjs → users-yryHKFMo.mjs} +2 -2
- package/dist/{watch-spec-W0c7ypHJ.mjs → watchers-hash-RLtnSF-t.mjs} +233 -28
- package/docs/01-board/01-mounting.md +1 -1
- package/docs/02-sync/01-overview.md +72 -48
- package/docs/02-sync/02-functions.md +398 -0
- package/docs/02-sync/03-slack.md +30 -25
- package/docs/02-sync/04-github.md +62 -26
- package/docs/02-sync/05-whatsapp.md +23 -19
- package/docs/02-sync/06-providers.md +60 -27
- package/docs/02-sync/07-linear.md +129 -0
- package/docs/03-guides/04-triage.md +1 -1
- package/docs/04-reference/01-cli.md +26 -6
- package/docs/04-reference/02-board.md +18 -5
- package/docs/04-reference/03-http.md +5 -2
- package/docs/04-reference/05-conformance.md +1 -1
- package/docs/index.md +5 -10
- package/package.json +31 -6
- package/dist/a2-D24cvwpN.d.mts +0 -3359
- package/dist/access-CJU2-vaa.mjs +0 -226
- package/dist/attempts-Bxp9KgPf.mjs +0 -919
- package/dist/exports-DLiE7fLY.d.mts +0 -4
- package/dist/provider-CuewcDNZ.mjs +0 -205
- package/dist/redis-tables-B35vv4CZ.mjs +0 -842
- package/dist/reducers-B_vUGQRp.d.mts +0 -1172
- package/dist/watchers-hash-CLjsa6od.mjs +0 -225
- package/docs/02-sync/02-callbacks.md +0 -265
package/dist/backend-a2.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as fsBlob, r as memoryBlob, t as a2 } from "./a2-
|
|
1
|
+
import { n as fsBlob, r as memoryBlob, t as a2 } from "./a2-ChRLRupa.mjs";
|
|
2
2
|
export { a2, fsBlob, memoryBlob };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { i as Attachment } from "./schemas-CWxs3ECJ.mjs";
|
|
2
|
-
import { t as Actor } from "./
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { t as Actor } from "./folds-CRYY14kc.mjs";
|
|
3
|
+
import { $ as Discovery, Mt as RegistrationView, Qt as SyncCopiesView, Rt as ScheduleView, Tt as PersonView, Wt as SourceRead, Xt as SyncCodeView, Z as ChannelView, _t as MatchView, bt as MessageView, ct as InboxEntry, dn as ThreadView, fn as ThreadsPage, ht as LinkedAccount, ln as SyncedView, lt as InboxItem, ot as IdentityView, sn as SyncThreadView, tn as SyncFindView, tt as EventsPage, vn as UploadTicket, xt as MessagesPage, yt as Me, z as ProfileOption } from "./provider-B0b9Qxw4.mjs";
|
|
4
|
+
import { i as Caller, n as BackendRoute, r as BoardBinding } from "./backend-B-SJ7p6p.mjs";
|
|
5
5
|
//#region src/server/backend-http.d.ts
|
|
6
6
|
type HttpOptions = {
|
|
7
7
|
/**
|
|
@@ -245,6 +245,12 @@ declare function createHttp(url: string | undefined, options: HttpOptions, envir
|
|
|
245
245
|
target: string;
|
|
246
246
|
limit?: number | undefined;
|
|
247
247
|
}, signal: AbortSignal) => Promise<SourceRead>;
|
|
248
|
+
synced: (caller: Caller, input: {
|
|
249
|
+
id: string;
|
|
250
|
+
}, signal: AbortSignal) => Promise<SyncedView>;
|
|
251
|
+
linked: (caller: Caller, input: {
|
|
252
|
+
url: string;
|
|
253
|
+
}, signal: AbortSignal) => Promise<ThreadView>;
|
|
248
254
|
syncImport: (caller: Caller, input: {
|
|
249
255
|
author: {
|
|
250
256
|
id: string;
|
|
@@ -555,6 +561,7 @@ declare function createHttp(url: string | undefined, options: HttpOptions, envir
|
|
|
555
561
|
owns?: string[] | undefined;
|
|
556
562
|
reply: string | null;
|
|
557
563
|
createRoot: boolean;
|
|
564
|
+
retitled?: boolean | undefined;
|
|
558
565
|
author: {
|
|
559
566
|
id: string;
|
|
560
567
|
handle: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as BoardError } from "./client-
|
|
2
|
-
import { t as createHttp } from "./backend-http-
|
|
1
|
+
import { t as BoardError } from "./client-BA-J7usH.mjs";
|
|
2
|
+
import { t as createHttp } from "./backend-http-Ddzd5kTS.mjs";
|
|
3
3
|
import { execFile } from "node:child_process";
|
|
4
4
|
import { createHash } from "node:crypto";
|
|
5
5
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import "./files-SniSmeEr.mjs";
|
|
2
2
|
import "./schemas-Be08nyfW.mjs";
|
|
3
|
-
import {
|
|
4
|
-
import { n as createBoardClient, t as BoardError } from "./client-
|
|
5
|
-
import { n as
|
|
3
|
+
import { K as routes, k as RegisterBody, n as compileWatcher, o as METHODS, t as canonicalWatchers } from "./watchers-hash-RLtnSF-t.mjs";
|
|
4
|
+
import { n as createBoardClient, t as BoardError } from "./client-BA-J7usH.mjs";
|
|
5
|
+
import { a as sha256, i as keyId, n as derivedId, t as DERIVED_ID } from "./ids-C6AYo1bu.mjs";
|
|
6
6
|
import { a as forbidden, o as json, t as HttpError } from "./errors-DX3hpwWt.mjs";
|
|
7
7
|
//#region src/server/backend-http.ts
|
|
8
8
|
/** A watcher's or client's name is the profile its writes are by. */
|
|
@@ -308,6 +308,35 @@ function createHttp(url, options, environment) {
|
|
|
308
308
|
if ("self" in caller && bound().sync.some((entry) => entry.key === input.key)) return bound().readSource(input.key, input.target, input.limit ?? 50);
|
|
309
309
|
return remoteCall("readSource", caller, input, signal);
|
|
310
310
|
},
|
|
311
|
+
async synced(caller, input, signal) {
|
|
312
|
+
const { targets } = await remoteCall("synced", caller, input, signal);
|
|
313
|
+
return { targets: await Promise.all(targets.map(async (row) => ({
|
|
314
|
+
...row,
|
|
315
|
+
url: row.url ?? (row.thread !== null && row.message !== null ? await bound().linkOf(row.key, row.thread, row.message) : null)
|
|
316
|
+
}))) };
|
|
317
|
+
},
|
|
318
|
+
async linked(caller, input, signal) {
|
|
319
|
+
const missing = () => new HttpError(404, "message_not_found", "no message on this board for that link");
|
|
320
|
+
const first = async () => {
|
|
321
|
+
for (const { platform, thread, message } of bound().locate(input.url)) for (const entry of bound().sync.filter((candidate) => candidate.platform === platform)) {
|
|
322
|
+
const at = await own.syncFind({
|
|
323
|
+
thread: `${entry.key}:${thread}`,
|
|
324
|
+
...message !== null ? { message } : {}
|
|
325
|
+
}, { signal }).catch(rethrow);
|
|
326
|
+
const found = message !== null ? at.message : at.thread === null ? null : (await own.syncThread(at.thread).catch(rethrow)).root;
|
|
327
|
+
if (found !== null) return found;
|
|
328
|
+
}
|
|
329
|
+
return null;
|
|
330
|
+
};
|
|
331
|
+
const id = await first();
|
|
332
|
+
if (id === null) return remoteCall("linked", caller, input, signal);
|
|
333
|
+
try {
|
|
334
|
+
return await methods.message(caller, { id }, signal);
|
|
335
|
+
} catch (error) {
|
|
336
|
+
if (error instanceof HttpError && error.status === 404) throw missing();
|
|
337
|
+
throw error;
|
|
338
|
+
}
|
|
339
|
+
},
|
|
311
340
|
async typing(caller, input, signal) {
|
|
312
341
|
const { targets } = await remoteCall("typing", caller, input, signal);
|
|
313
342
|
if (!("self" in caller) || bound().sync.length === 0) return { targets };
|
package/dist/backend-http.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as HttpOptions, t as HttpBackend } from "./backend-http-
|
|
1
|
+
import { n as HttpOptions, t as HttpBackend } from "./backend-http-7cNb8nJI.mjs";
|
|
2
2
|
//#region src/backend-http/index.default.d.ts
|
|
3
3
|
/**
|
|
4
4
|
* The board at `url`, which keeps the log. Outside Node there's no environment to find it or a
|
package/dist/backend-http.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as http } from "./index.default-
|
|
1
|
+
import { t as http } from "./index.default-C5Cpz3sa.mjs";
|
|
2
2
|
export { http };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as HttpOptions, t as HttpBackend } from "./backend-http-
|
|
1
|
+
import { n as HttpOptions, t as HttpBackend } from "./backend-http-7cNb8nJI.mjs";
|
|
2
2
|
//#region src/backend-http/index.d.ts
|
|
3
3
|
/**
|
|
4
4
|
* The board at `url`, which keeps the log: this board uses it as this deployment. Without a
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as http } from "./backend-http-
|
|
1
|
+
import { t as http } from "./backend-http-CMlL3yq3.mjs";
|
|
2
2
|
export { http };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { d as ExternalFile, f as ExternalLink, l as ExternalAuthor, t as Actor } from "./folds-CRYY14kc.mjs";
|
|
2
|
+
import { M as SyncRoot, O as ProviderEvent, Wt as SourceRead, a as ProviderOptions, c as ReceivedEvent, d as ResolvedTarget, i as ProviderFile, n as FileDelivery, o as ProviderPost, p as SyncProvider, r as ProviderDelivery, s as Receive, t as FetchedLink, y as SyncFn } from "./provider-B0b9Qxw4.mjs";
|
|
3
3
|
import { Adapter, Author, FileUpload, Message, ReactionEvent } from "chat";
|
|
4
4
|
//#region src/sync/types.d.ts
|
|
5
5
|
declare function externalAuthor(platform: string, author: Author): ExternalAuthor;
|
|
@@ -34,6 +34,13 @@ type ChatTransport = Omit<ProviderOptions, 'uploadsFiles'> & {
|
|
|
34
34
|
/** Platform messages a message links to, located under sync key `key`. */
|
|
35
35
|
links?(key: string, message: Message): ExternalLink[];
|
|
36
36
|
fetchLink?(link: ExternalLink): Promise<FetchedLink>;
|
|
37
|
+
/** The message a URL of the platform's names, by its own IDs: `SyncProvider.locate`. */
|
|
38
|
+
locate?(url: string): {
|
|
39
|
+
thread: string;
|
|
40
|
+
message: string | null;
|
|
41
|
+
} | null;
|
|
42
|
+
/** The platform's URL for a message, by its own IDs: `SyncProvider.url`. */
|
|
43
|
+
url?(thread: string, message: string): Promise<string | null>;
|
|
37
44
|
/** A channel or thread, read on demand without syncing it. */
|
|
38
45
|
read?(target: string, options: {
|
|
39
46
|
limit: number;
|
|
@@ -64,10 +71,10 @@ declare abstract class ChatSyncProvider<E extends ProviderEvent = ProviderEvent>
|
|
|
64
71
|
private readonly chat;
|
|
65
72
|
private readonly receiving;
|
|
66
73
|
private initialized;
|
|
67
|
-
constructor(transport: ChatTransport);
|
|
74
|
+
constructor(transport: ChatTransport, sync: SyncFn<E>);
|
|
68
75
|
protected toNative(id: string): string;
|
|
69
76
|
protected toChat(id: string): string;
|
|
70
|
-
protected
|
|
77
|
+
protected locationOf(key: string, chatThread: string): {
|
|
71
78
|
channel: string;
|
|
72
79
|
thread: string;
|
|
73
80
|
subthread: string | null;
|
|
@@ -109,6 +116,11 @@ declare abstract class ChatSyncProvider<E extends ProviderEvent = ProviderEvent>
|
|
|
109
116
|
mention(actor: Actor): string | null;
|
|
110
117
|
fetchRoot(thread: string): Promise<SyncRoot | null>;
|
|
111
118
|
fetchLink(link: ExternalLink): Promise<FetchedLink>;
|
|
119
|
+
locate(url: string): {
|
|
120
|
+
thread: string;
|
|
121
|
+
message: string | null;
|
|
122
|
+
} | null;
|
|
123
|
+
url(thread: string, message: string): Promise<string | null>;
|
|
112
124
|
read(target: string, options: {
|
|
113
125
|
limit: number;
|
|
114
126
|
}): Promise<SourceRead>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import "./
|
|
2
|
-
import { n as ResolvedTarget, r as SyncProvider } from "./provider-
|
|
3
|
-
import { n as userTokensOf } from "./users-
|
|
1
|
+
import "./external-BV_cUncs.mjs";
|
|
2
|
+
import { n as ResolvedTarget, r as SyncProvider } from "./provider-B3DpYSDq.mjs";
|
|
3
|
+
import { n as userTokensOf } from "./users-yryHKFMo.mjs";
|
|
4
4
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
5
5
|
import { Chat, stringifyMarkdown } from "chat";
|
|
6
6
|
//#region src/sync/state.ts
|
|
@@ -128,12 +128,12 @@ var ChatSyncProvider = class extends SyncProvider {
|
|
|
128
128
|
chat;
|
|
129
129
|
receiving = new AsyncLocalStorage();
|
|
130
130
|
initialized;
|
|
131
|
-
constructor(transport) {
|
|
131
|
+
constructor(transport, sync) {
|
|
132
132
|
super({
|
|
133
133
|
...transport,
|
|
134
134
|
users: transport.users ?? userTokensOf(transport.adapter),
|
|
135
135
|
uploadsFiles: !!transport.uploadFiles
|
|
136
|
-
});
|
|
136
|
+
}, sync);
|
|
137
137
|
this.transport = transport;
|
|
138
138
|
this.chat = createChat(transport.adapter);
|
|
139
139
|
const onMessage = async (_thread, message) => this.emit({
|
|
@@ -164,7 +164,7 @@ var ChatSyncProvider = class extends SyncProvider {
|
|
|
164
164
|
toChat(id) {
|
|
165
165
|
return `${this.transport.adapter.name}:${this.transport.toChatId?.(id) ?? id}`;
|
|
166
166
|
}
|
|
167
|
-
|
|
167
|
+
locationOf(key, chatThread) {
|
|
168
168
|
const native = this.toNative(chatThread);
|
|
169
169
|
const precise = `${key}:${native}`;
|
|
170
170
|
const thread = `${key}:${this.transport.groupThread?.(native) ?? native}`;
|
|
@@ -203,7 +203,7 @@ var ChatSyncProvider = class extends SyncProvider {
|
|
|
203
203
|
raw: input.raw,
|
|
204
204
|
event: {
|
|
205
205
|
kind: "deleted",
|
|
206
|
-
...this.
|
|
206
|
+
...this.locationOf(key, input.thread),
|
|
207
207
|
message: input.message
|
|
208
208
|
}
|
|
209
209
|
};
|
|
@@ -215,7 +215,7 @@ var ChatSyncProvider = class extends SyncProvider {
|
|
|
215
215
|
raw: event.raw,
|
|
216
216
|
event: {
|
|
217
217
|
kind: "reaction",
|
|
218
|
-
...this.
|
|
218
|
+
...this.locationOf(key, event.threadId),
|
|
219
219
|
message: event.messageId,
|
|
220
220
|
emoji,
|
|
221
221
|
added: event.added,
|
|
@@ -227,7 +227,7 @@ var ChatSyncProvider = class extends SyncProvider {
|
|
|
227
227
|
const found = this.transport.links?.(key, message) ?? [];
|
|
228
228
|
const links = found.length ? { links: found.slice(0, 10) } : {};
|
|
229
229
|
const common = {
|
|
230
|
-
...this.
|
|
230
|
+
...this.locationOf(key, message.threadId),
|
|
231
231
|
message: message.id,
|
|
232
232
|
text: this.transport.markdown?.(message) ?? markdownOf(message),
|
|
233
233
|
author: await this.authorOf(message),
|
|
@@ -303,6 +303,12 @@ var ChatSyncProvider = class extends SyncProvider {
|
|
|
303
303
|
async fetchLink(link) {
|
|
304
304
|
return this.transport.fetchLink ? this.transport.fetchLink(link) : super.fetchLink(link);
|
|
305
305
|
}
|
|
306
|
+
locate(url) {
|
|
307
|
+
return this.transport.locate ? this.transport.locate(url) : super.locate(url);
|
|
308
|
+
}
|
|
309
|
+
async url(thread, message) {
|
|
310
|
+
return this.transport.url ? this.transport.url(thread, message) : super.url(thread, message);
|
|
311
|
+
}
|
|
306
312
|
async read(target, options) {
|
|
307
313
|
return this.transport.read ? this.transport.read(target, options) : super.read(target, options);
|
|
308
314
|
}
|
package/dist/cli.mjs
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { i as fileSize, n as DIRECT_UPLOAD_BYTES_MAX, t as ATTACHMENT_BYTES_MAX } from "./files-SniSmeEr.mjs";
|
|
3
3
|
import { a as AttachmentId } from "./schemas-Be08nyfW.mjs";
|
|
4
|
-
import {
|
|
4
|
+
import { a as withMentions, f as VERSION, i as FILTER_FLAGS } from "./watchers-hash-RLtnSF-t.mjs";
|
|
5
5
|
import { n as displayEmoji, r as normalizeEmoji } from "./emoji-CTLpvH-A.mjs";
|
|
6
|
-
import { t as BoardError } from "./client-
|
|
7
|
-
import { c as
|
|
8
|
-
import {
|
|
9
|
-
import { t as
|
|
10
|
-
import { t as conformance } from "./conformance-DRR23YNy.mjs";
|
|
6
|
+
import { t as BoardError } from "./client-BA-J7usH.mjs";
|
|
7
|
+
import { a as detectAgent, c as projectUrl, i as connect, n as boardUrl, r as configDir, s as projectDir, t as http } from "./backend-http-CMlL3yq3.mjs";
|
|
8
|
+
import { t as board } from "./server-DPxBSogx.mjs";
|
|
9
|
+
import { t as conformance } from "./conformance-CT5EeHeC.mjs";
|
|
11
10
|
import { t as displayText } from "./bots-CGkO76qH.mjs";
|
|
12
11
|
import { execFileSync, spawn } from "node:child_process";
|
|
13
12
|
import { createHash, randomBytes, timingSafeEqual } from "node:crypto";
|
|
@@ -806,6 +805,19 @@ function formatEvent(event) {
|
|
|
806
805
|
}
|
|
807
806
|
}
|
|
808
807
|
/**
|
|
808
|
+
* Where a thread is synced, for `vb sync <id>`: a row a target, its sync key and where it is, then
|
|
809
|
+
* the link to the message's copy there, or why it didn't reach it.
|
|
810
|
+
*/
|
|
811
|
+
function formatSynced(targets) {
|
|
812
|
+
const where = (row) => row.target.slice(row.key.length + 1);
|
|
813
|
+
const keys = Math.max(...targets.map((row) => row.key.length));
|
|
814
|
+
const wheres = Math.max(...targets.map((row) => where(row).length));
|
|
815
|
+
return targets.map((row) => {
|
|
816
|
+
const copy = row.undelivered !== null ? `didn't reach it: ${row.undelivered}` : row.url ?? (row.message !== null ? `message ${row.message}` : "no copy yet");
|
|
817
|
+
return `${row.key.padEnd(keys)} ${where(row).padEnd(wheres)} ${terminalText(copy)}`;
|
|
818
|
+
}).join("\n");
|
|
819
|
+
}
|
|
820
|
+
/**
|
|
809
821
|
* A channel or thread read with `vb sources <key> read`: a header, then each message under its ID,
|
|
810
822
|
* with the target that reads its thread when it has replies.
|
|
811
823
|
*/
|
|
@@ -1284,6 +1296,7 @@ usage: board <command> [options] (also installed as \`vb\`)
|
|
|
1284
1296
|
read [channel] [filters] [--limit N] the latest threads, one each: root, replies, latest reply
|
|
1285
1297
|
(no channel: every channel)
|
|
1286
1298
|
read <id> one thread, every message (filters: the root and the replies that match)
|
|
1299
|
+
read <link> the thread a Slack or GitHub link names, if the board synced it
|
|
1287
1300
|
|
|
1288
1301
|
post <channel|id> ["<text>"] [--label k=v]... [--attach <file>]... [--sync <target>]... [--no-sync] [--id <key>]
|
|
1289
1302
|
a new thread in a channel, or with an id, a reply in its thread
|
|
@@ -1300,6 +1313,7 @@ usage: board <command> [options] (also installed as \`vb\`)
|
|
|
1300
1313
|
label <id> k=v... [--unset k]...
|
|
1301
1314
|
typing <id> [status] show typing in the thread's synced platform threads (marks WhatsApp read);
|
|
1302
1315
|
Slack shows the status, if given, instead of "Typing…"
|
|
1316
|
+
sync <id> where the thread is synced, with this message's link on each
|
|
1303
1317
|
sync <id> <target> attach the thread to e.g. slack:#incidents, backfilling it
|
|
1304
1318
|
inbox <key> [channel] [--limit N] raw platform events, for debugging sync
|
|
1305
1319
|
sources the board's sources (its sync entries: slack, github, …)
|
|
@@ -1842,8 +1856,9 @@ async function run(command, args) {
|
|
|
1842
1856
|
case "read": {
|
|
1843
1857
|
const target = args[0];
|
|
1844
1858
|
const board = client();
|
|
1845
|
-
|
|
1846
|
-
|
|
1859
|
+
const link = target !== void 0 && /^https?:\/\//i.test(target);
|
|
1860
|
+
if (target && (link || isMessageRef(target))) {
|
|
1861
|
+
const thread = link ? await board.linked(target) : await board.thread(messageId(target));
|
|
1847
1862
|
const narrowed = Object.keys(filters()).length > 0;
|
|
1848
1863
|
const replies = narrowed ? (await board.messages({
|
|
1849
1864
|
...filters(),
|
|
@@ -2099,7 +2114,12 @@ async function run(command, args) {
|
|
|
2099
2114
|
}
|
|
2100
2115
|
case "sync": {
|
|
2101
2116
|
const id = messageId(args[0]);
|
|
2102
|
-
if (!args[1])
|
|
2117
|
+
if (!args[1]) {
|
|
2118
|
+
const { targets } = await client().sync(id);
|
|
2119
|
+
if (flags.json) return targets.forEach(printJson), 0;
|
|
2120
|
+
out(targets.length ? formatSynced(targets) : "not synced anywhere");
|
|
2121
|
+
return 0;
|
|
2122
|
+
}
|
|
2103
2123
|
const result = await client().sync(id, args[1]);
|
|
2104
2124
|
if (flags.json) printJson(result);
|
|
2105
2125
|
else out(result.attached ? `synced with ${result.target}` : `already synced with ${result.target}`);
|
|
@@ -2175,7 +2195,7 @@ async function run(command, args) {
|
|
|
2175
2195
|
if (args.length > 0) throw new UsageError("usage: board serve [--port N] [--dir <dir>] [--no-inspect] [--no-open]");
|
|
2176
2196
|
const port = portFlag();
|
|
2177
2197
|
const root = projectDir();
|
|
2178
|
-
const { localHandle, serveLocal } = await import("./serve-
|
|
2198
|
+
const { localHandle, serveLocal } = await import("./serve-BGYw0uNL.mjs");
|
|
2179
2199
|
const handle = flags.handle ?? process.env.BOARD_HANDLE;
|
|
2180
2200
|
const local = await serveLocal({
|
|
2181
2201
|
dir: flags.dir ?? join(root, ".board"),
|
|
@@ -260,8 +260,16 @@ function createBoardClient(options) {
|
|
|
260
260
|
* `status` replaces "Typing…" on Slack ("running tests…").
|
|
261
261
|
*/
|
|
262
262
|
typing: async (id, status) => (await call("POST", `/messages/${path(id)}/typing`, { body: status ? { status } : {} })).targets,
|
|
263
|
-
/**
|
|
264
|
-
|
|
263
|
+
/**
|
|
264
|
+
* With a target, attaches the message's thread to it, backfilling it: attaching twice is a no-op.
|
|
265
|
+
* Without one, where the thread is synced, and this message's copy on each target, with its link.
|
|
266
|
+
*/
|
|
267
|
+
sync: ((id, target) => target === void 0 ? call("GET", `/messages/${path(id)}/sync`) : call("POST", `/messages/${path(id)}/sync`, { body: { target } })),
|
|
268
|
+
/**
|
|
269
|
+
* The thread of the board message a platform link names (a Slack permalink, a GitHub comment's
|
|
270
|
+
* URL), from what the board synced: the platform is never asked. 404 for one it didn't sync.
|
|
271
|
+
*/
|
|
272
|
+
linked: (url) => call("GET", `/links${queryString({ url })}`),
|
|
265
273
|
/** Raw platform events for a sync entry, newest first. */
|
|
266
274
|
inbox: async (key, opts = {}) => (await call("GET", `/inbox/${key}${queryString(opts)}`)).events,
|
|
267
275
|
/** Registers the caller's watchers, replacing its last registration: what a board on `http()` does. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as BoardError } from "./client-
|
|
1
|
+
import { t as BoardError } from "./client-BA-J7usH.mjs";
|
|
2
2
|
//#region src/conformance/index.ts
|
|
3
3
|
var Mismatch = class extends Error {};
|
|
4
4
|
const show = (value) => JSON.stringify(value) ?? String(value);
|
|
@@ -298,7 +298,7 @@ const CHECKS = [
|
|
|
298
298
|
},
|
|
299
299
|
{
|
|
300
300
|
group: "sync",
|
|
301
|
-
name: "keeps sync's records: an import as a platform author, its lookups by platform ID, and
|
|
301
|
+
name: "keeps sync's records: an import as a platform author, its lookups by platform ID, a receipt, and where it's synced",
|
|
302
302
|
run: async (ctx) => {
|
|
303
303
|
const key = "conformance";
|
|
304
304
|
const thread = `${key}:${ctx.labels.conformance}:1`;
|
|
@@ -411,6 +411,9 @@ const CHECKS = [
|
|
|
411
411
|
external
|
|
412
412
|
});
|
|
413
413
|
same(JSON.stringify((await ctx.board.syncCopies([id]))[id]?.[external.thread]), JSON.stringify(external), "the copy its receipt recorded");
|
|
414
|
+
const { targets } = await ctx.board.sync(id);
|
|
415
|
+
check(targets.some((row) => row.target === external.thread && row.message === external.message), `where the thread is synced should show the copy its receipt recorded, got ${show(targets)}`);
|
|
416
|
+
await rejects(ctx.board.linked(`https://conformance.invalid/${ctx.labels.conformance}`), 404, "message_not_found", "a link no sync here knows");
|
|
414
417
|
} finally {
|
|
415
418
|
await ctx.board.syncImport({
|
|
416
419
|
op: "delete",
|
package/dist/conformance.d.mts
CHANGED
package/dist/conformance.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as conformance } from "./conformance-
|
|
1
|
+
import { t as conformance } from "./conformance-CT5EeHeC.mjs";
|
|
2
2
|
export { conformance };
|