@vercel/board 0.29.0 → 0.30.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/{a2-HUbQJ0RD.mjs → a2-D_28Pdip.mjs} +190 -76
- package/dist/access-CQ39gqEV.mjs +226 -0
- package/dist/access.d.mts +1 -1
- package/dist/access.mjs +3 -3
- package/dist/{actors-DcJhFbwJ.mjs → actors-xPiamLWk.mjs} +2 -2
- package/dist/{auth-JO22iIwr.mjs → auth-BPinwfN0.mjs} +3 -226
- package/dist/backend-a2/blob-vercel.d.mts +1 -1
- package/dist/backend-a2/contract.d.mts +2 -2
- package/dist/backend-a2/contract.mjs +1 -1
- 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 +3 -3
- package/dist/backend-a2/scheduler-qstash.mjs +8 -8
- package/dist/backend-a2/scheduler-vercel.d.mts +3 -3
- package/dist/backend-a2/scheduler-vercel.mjs +6 -6
- 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 +34 -15
- package/dist/backend-a2/store-redis-http.d.mts +1 -1
- package/dist/backend-a2/store-redis-http.mjs +6 -6
- package/dist/backend-a2/store-redis.d.mts +2 -2
- package/dist/backend-a2/store-redis.mjs +5 -5
- 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 +17 -7
- package/dist/backend-a2.mjs +2 -2
- package/dist/{backend-http-Bmp0IgD3.mjs → backend-http-16SbvnAK.mjs} +2 -2
- package/dist/{backend-http-CqfKhrnn.d.mts → backend-http-3PoBYQoo.d.mts} +13 -3
- package/dist/{backend-http-CzIJMm58.mjs → backend-http-BPaNYLWj.mjs} +2 -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/{backend-CPC_vyOo.d.mts → backend-n3hajfrD.d.mts} +11 -5
- package/dist/{backend-vercel-BNauAs7w.mjs → backend-vercel-C4Kee2-K.mjs} +203 -31
- package/dist/{backend-vercel-DQc_TaHp.mjs → backend-vercel-Kd8nvW5A.mjs} +3 -3
- package/dist/{backend-vercel-4tvcPKqX.d.mts → backend-vercel-qznuDxnN.d.mts} +16 -5
- package/dist/backend-vercel.d.mts +1 -1
- package/dist/backend-vercel.mjs +1 -1
- package/dist/backend-vercel.node.d.mts +1 -1
- package/dist/backend-vercel.node.mjs +1 -1
- package/dist/{blob-DmiQjrYy.d.mts → blob-CqILvdmr.d.mts} +2 -2
- package/dist/{blob-DdbpJqN1.mjs → blob-DQK5prXT.mjs} +1 -1
- package/dist/{chat-provider-BWHbChcQ.d.mts → chat-provider-D6jVT4wS.d.mts} +3 -3
- package/dist/cli-commands.d.mts +1 -1
- package/dist/cli-commands.mjs +1 -1
- package/dist/cli-embedded.d.mts +2 -2
- package/dist/cli-embedded.mjs +1 -1
- package/dist/cli.mjs +4 -4
- package/dist/{client-BqAjk0Q4.d.mts → client-CjAatpV4.d.mts} +60 -10
- package/dist/{commands-C3R1AWgm.mjs → commands-B5DHjZKK.mjs} +50 -9
- package/dist/{commands-D6gvrOh3.d.mts → commands-BtH69yqt.d.mts} +17 -0
- package/dist/{conformance-DlnfuzEB.mjs → conformance-C7fwIvmN.mjs} +258 -18
- package/dist/conformance.d.mts +1 -1
- package/dist/conformance.mjs +1 -1
- package/dist/{engine-DQxXk7dX.mjs → engine-DkdkXQEy.mjs} +2 -2
- package/dist/{errors-DDktVeUa.d.mts → errors-87TVtXeb.d.mts} +1 -1
- package/dist/{client-D0Px7KzF.mjs → errors-C_5rB8Iz.mjs} +104 -4
- package/dist/{exports-BG-0Wyn-.mjs → exports-CG0P8Qi4.mjs} +54 -28
- package/dist/exports-CrGA5_yN.d.mts +5 -0
- package/dist/{folds-ZkHM4M-v.d.mts → folds-8wRRXjAt.d.mts} +2 -0
- package/dist/{folds-BDMSxBUf.mjs → folds-DGYkMW19.mjs} +1 -0
- package/dist/{index-D3VvNfh_.d.mts → index-BygAXP7t.d.mts} +2 -2
- package/dist/index.d.mts +6 -6
- package/dist/{index.default-rB8sJ9RX.mjs → index.default-DhkgpfR2.mjs} +1 -1
- package/dist/index.mjs +5 -6
- package/dist/index.node.d.mts +6 -6
- package/dist/index.node.mjs +3 -4
- package/dist/inspect/app.js +29 -29
- package/dist/{internal-CvsrprnU-CRY89I-b.mjs → internal-CvsrprnU-zZMpDiRY.mjs} +1 -1
- package/dist/{local-DhkrAqPP.mjs → local-C76Fy5ad.mjs} +1 -1
- package/dist/{main-CVBqe3VO.mjs → main-D2s-QBOK.mjs} +70 -23
- package/dist/{middleware-CXjEeef4.mjs → middleware-DlJQYiwV.mjs} +1 -1
- package/dist/{node-Zd_C-gxP.mjs → node-D8Rtg1su.mjs} +1 -1
- package/dist/{platform-B4TnJtWu-CwcTyKg2.mjs → platform-B4TnJtWu-Do3agKr5.mjs} +1 -1
- package/dist/{project-CBXlLftU.mjs → project-C_2xs57L.mjs} +1 -1
- package/dist/{provider-DmSTp9lI.d.mts → provider-Bm46LAdp.d.mts} +2 -2
- package/dist/{redis-tables-BJQVUspu.mjs → redis-tables-BWJZHUGg.mjs} +40 -24
- package/dist/{reducer-CjmvZSAb-D_OSISmj.mjs → reducer-Bswr11ar-P324o9vn.mjs} +2 -2
- package/dist/{reducer-CYPHsSmd-BQIfozGi.d.mts → reducer-CYPHsSmd-BXjGiptm.d.mts} +1 -1
- package/dist/{reducers-DJzVpXwM.mjs → reducers-8jqLewgw.mjs} +3 -3
- package/dist/{retryable-lazy-DZWmHpii-Bye-W8q7.mjs → retryable-lazy-DZWmHpii-DpTc5PIP.mjs} +1 -1
- package/dist/{scheduler-task-X1SToDjP-BVoWuInI.mjs → scheduler-task-X1SToDjP-D2Il2rln.mjs} +1 -1
- package/dist/{serve-G9RuaDSr.mjs → serve-lPoBDEds.mjs} +7 -7
- package/dist/{server-qgez0Xny-D5mLfqFQ.d.mts → server-B9gu0qi1-DI1WvcVK.d.mts} +10 -4
- package/dist/{server-BixV_byP.mjs → server-D82a4uMe.mjs} +4 -4
- package/dist/{server-DtFrWxi3-Boa6gdWO.mjs → server-DX7mM6nm-D7N_7bug.mjs} +32 -23
- package/dist/{serving-B75Y4BF-.mjs → serving-DKny38LK.mjs} +1 -1
- package/dist/{session-clear-wHd5GCpZ-BnKSxReK.mjs → session-clear-XJYpmUpg-2q8l_FJR.mjs} +14 -2
- package/dist/{sql-D4Z_efJX.mjs → sql-Bj0fk6dn.mjs} +1 -1
- package/dist/{sqlite-db-Bz2JkfCU.mjs → sqlite-db-Dc8G78XV.mjs} +1 -1
- package/dist/{store-D0MhBvg6-4Z2L0Kqd.d.mts → store-DEzcHZOA-B-5vhxef.d.mts} +12 -2
- package/dist/store-N8PXxDAS-DWWgv-Vz.mjs +5 -0
- package/dist/{store-codec-DwrWlgQx-CYxGW0aD.mjs → store-codec-pAG2oPgQ-SqDXlPBR.mjs} +4 -4
- package/dist/store-memory-4IBl0Ztu.mjs +2 -0
- package/dist/{store-memory-Bas9Uq5C.mjs → store-memory-B0PkVSuQ.mjs} +14 -7
- package/dist/{store-polling-BZt2Rf3D-BiEM6_HB.mjs → store-polling-BZt2Rf3D-Div-bJ_D.mjs} +2 -2
- package/dist/{store-presence-polling-JuAy2Ck2-CYpuK75X.mjs → store-presence-polling-JuAy2Ck2-Dh-g_KYM.mjs} +3 -3
- package/dist/{store-sqlite-CxxPCcCT.mjs → store-sqlite-D85t3tE7.mjs} +14 -7
- package/dist/store-sqlite-iBTYYKBj.mjs +2 -0
- package/dist/{stream-buffer-DrTyiIuo-BKy-vI14.mjs → stream-buffer-DrTyiIuo-Be10yOBR.mjs} +2 -2
- package/dist/sync-github.d.mts +2 -2
- package/dist/sync-kapso.d.mts +2 -2
- package/dist/sync-linear.d.mts +3 -3
- package/dist/sync-linear.mjs +4 -2
- package/dist/sync-slack.d.mts +3 -3
- package/dist/sync.chat.d.mts +1 -1
- package/dist/sync.d.mts +2 -2
- package/dist/{tokens-CC3izSNr.mjs → tokens-C5_yGRlL.mjs} +2 -2
- package/dist/{types-No0WdhE5.d.mts → types-shZmGZ-q.d.mts} +2 -2
- package/dist/{watchers-hash-BDhLVkV5.mjs → watchers-hash-B_5b0-ZG.mjs} +46 -17
- package/docs/01-board/04-messages.md +93 -0
- package/docs/01-board/08-middleware.md +5 -2
- package/docs/04-reference/01-cli.md +23 -10
- package/docs/04-reference/02-board.md +20 -5
- package/docs/04-reference/03-http.md +17 -6
- package/docs/04-reference/05-conformance.md +14 -3
- package/package.json +2 -2
- package/dist/errors-CusN4x2l.mjs +0 -88
- package/dist/exports-mhAYiU4i.d.mts +0 -5
- package/dist/store-N8PXxDAS-BWBgzBHp.mjs +0 -5
- package/dist/store-memory-ZLiZbH3R.mjs +0 -2
- package/dist/store-sqlite-BmwL3pUR.mjs +0 -2
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { r as IMPORT_BYTES_MAX } from "./files-SniSmeEr.mjs";
|
|
2
2
|
import { _ as RemoteWatcherId } from "./schemas-DBmUO6pr.mjs";
|
|
3
|
-
import {
|
|
3
|
+
import { a as METHODS, d as VERSION, k as RegisterBody, n as compileWatcher, t as canonicalWatchers } from "./watchers-hash-B_5b0-ZG.mjs";
|
|
4
|
+
import { a as forbidden, f as duration, o as json, r as badRequest, s as notFound, t as HttpError } from "./errors-C_5rB8Iz.mjs";
|
|
4
5
|
import { o as sha256, r as derivedId } from "./wait-until-Dw4XrIDQ.mjs";
|
|
5
|
-
import { a as
|
|
6
|
-
import {
|
|
7
|
-
import { o as mediaType, r as fileName } from "./blob-DdbpJqN1.mjs";
|
|
6
|
+
import { a as wakePath, i as registrant, n as callerProfile, t as PROJECTS_OWN } from "./backend-http-BPaNYLWj.mjs";
|
|
7
|
+
import { o as mediaType, r as fileName } from "./blob-DQK5prXT.mjs";
|
|
8
8
|
//#region src/server/backend-vercel.ts
|
|
9
9
|
const PROFILE = /^[A-Za-z][A-Za-z0-9-]{0,31}$/;
|
|
10
10
|
const SESSION = /^[A-Za-z0-9_.:-]{1,128}$/;
|
|
@@ -19,14 +19,6 @@ const PAGE_MAX = 100;
|
|
|
19
19
|
const WAIT_MAX_S = 25;
|
|
20
20
|
/** Pages a filtered read of one channel scans for matches before it answers with what it found. */
|
|
21
21
|
const SCAN_PAGES = 10;
|
|
22
|
-
/** What the API keeps none of: a check that gets one of these is told it isn't kept here. */
|
|
23
|
-
const UNKEPT = {
|
|
24
|
-
schedule: ["no_scheduler", "Vercel's boards don't schedule messages yet"],
|
|
25
|
-
schedules: ["no_scheduler", "Vercel's boards don't schedule messages yet"],
|
|
26
|
-
cancelSchedule: ["no_scheduler", "Vercel's boards don't schedule messages yet"],
|
|
27
|
-
uploadStart: ["no_direct_uploads", "Vercel's boards take files up to 4 MB in one upload for now"],
|
|
28
|
-
uploadFinish: ["no_direct_uploads", "Vercel's boards take files up to 4 MB in one upload for now"]
|
|
29
|
-
};
|
|
30
22
|
/** A file as the board names it. */
|
|
31
23
|
const fileOf = ({ id, name, type, size }) => ({
|
|
32
24
|
id,
|
|
@@ -74,6 +66,13 @@ const authorOf = (actor) => ({
|
|
|
74
66
|
profile: actor.profile?.name ?? null,
|
|
75
67
|
session: actor.session ?? null
|
|
76
68
|
});
|
|
69
|
+
/** Who cancels a schedule when no one did: the API, once its creator can no longer post it, as a2()'s scheduler. */
|
|
70
|
+
const SCHEDULER = {
|
|
71
|
+
actor: "board:schedule",
|
|
72
|
+
principal: "board:schedule",
|
|
73
|
+
profile: null,
|
|
74
|
+
session: null
|
|
75
|
+
};
|
|
77
76
|
/** The API names nobody, so an actor's handle is its profile, or a short form of its principal. */
|
|
78
77
|
function actorView(actor) {
|
|
79
78
|
const { principal } = actor;
|
|
@@ -90,8 +89,8 @@ function actorView(actor) {
|
|
|
90
89
|
}
|
|
91
90
|
/**
|
|
92
91
|
* Vercel's board for your team, in Vercel's API: this deployment keeps nothing and reads and writes
|
|
93
|
-
* it as itself, its people as themselves. Messages, threads, reactions, labels,
|
|
94
|
-
* changes work; what the API keeps none of yet (
|
|
92
|
+
* it as itself, its people as themselves. Messages, threads, reactions, labels, a channel's
|
|
93
|
+
* changes, schedules, files, and watchers work; what the API keeps none of yet (sync) answers 501.
|
|
95
94
|
*/
|
|
96
95
|
function createVercel(options, environment) {
|
|
97
96
|
const origin = (options.api ?? "https://api.vercel.com").replace(/\/+$/, "");
|
|
@@ -331,7 +330,39 @@ function createVercel(options, environment) {
|
|
|
331
330
|
attachments: message.attachments ?? [],
|
|
332
331
|
links: [],
|
|
333
332
|
version: message.version,
|
|
334
|
-
|
|
333
|
+
revision: message.revision,
|
|
334
|
+
author: await nameOf(who, message.createdBy),
|
|
335
|
+
...message.schedule ? { schedule: {
|
|
336
|
+
id: message.schedule.id,
|
|
337
|
+
n: message.schedule.n
|
|
338
|
+
} } : {}
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
async function scheduleView(who, schedule) {
|
|
342
|
+
const { canceled } = schedule;
|
|
343
|
+
return {
|
|
344
|
+
id: schedule.id,
|
|
345
|
+
channel: (await channelById(who, schedule.channelId)).name,
|
|
346
|
+
re: schedule.threadId === void 0 ? null : idAt(schedule.threadId, 1),
|
|
347
|
+
text: schedule.text,
|
|
348
|
+
labels: { ...schedule.labels },
|
|
349
|
+
noSync: false,
|
|
350
|
+
attachments: [],
|
|
351
|
+
first: iso(schedule.firstAt),
|
|
352
|
+
every: schedule.every ?? null,
|
|
353
|
+
until: schedule.until === void 0 ? null : iso(schedule.until),
|
|
354
|
+
times: schedule.times ?? null,
|
|
355
|
+
sent: schedule.sent,
|
|
356
|
+
next: schedule.nextAt === null ? null : iso(schedule.nextAt),
|
|
357
|
+
last: schedule.lastMessageId ?? null,
|
|
358
|
+
state: schedule.state,
|
|
359
|
+
canceled: canceled ? {
|
|
360
|
+
by: canceled.by ? authorOf(canceled.by) : SCHEDULER,
|
|
361
|
+
reason: canceled.reason === "disabled" ? "revoked" : canceled.reason
|
|
362
|
+
} : null,
|
|
363
|
+
by: authorOf(schedule.createdBy),
|
|
364
|
+
author: await nameOf(who, schedule.createdBy),
|
|
365
|
+
createdAt: iso(schedule.createdAt)
|
|
335
366
|
};
|
|
336
367
|
}
|
|
337
368
|
const positions = /* @__PURE__ */ new Map();
|
|
@@ -796,6 +827,22 @@ function createVercel(options, environment) {
|
|
|
796
827
|
function checkCaller(method, caller) {
|
|
797
828
|
if ("identity" in caller && PROJECTS_OWN.has(method)) throw forbidden(`this board's callers act as its project on Vercel's board, which can't tell them apart: ${method} is the project's own to do there`);
|
|
798
829
|
}
|
|
830
|
+
/**
|
|
831
|
+
* The API owns messages and schedules by principal, and sees every caller here as this project:
|
|
832
|
+
* a caller that is the project (its own deployment's token) changes what it wrote, as on any
|
|
833
|
+
* board, and anyone else would be changing what the project wrote for others.
|
|
834
|
+
*/
|
|
835
|
+
/** Whether a caller is this project: the deployment's own code, or a caller verified as its principal. */
|
|
836
|
+
const isProject = async (caller, who) => !("identity" in caller) || caller.identity.principal.id === principalId((await self(who)).actor.principal);
|
|
837
|
+
async function checkOwner(what, caller, who) {
|
|
838
|
+
if (!await isProject(caller, who)) throw forbidden(`this board's callers act as its project on Vercel's board, which owns what any of them wrote: only the project itself may ${what} there`);
|
|
839
|
+
}
|
|
840
|
+
/** A file is no use until a post or an import carries it, so uploading takes `post` or `sync` somewhere, as on a2(). */
|
|
841
|
+
async function checkUploader(caller, who) {
|
|
842
|
+
await checkOwner("upload", caller, who);
|
|
843
|
+
const access = accessOf(caller);
|
|
844
|
+
if (access && !access.anywhere("post") && !access.anywhere("sync")) throw forbidden("this token can't post anywhere, so it can't upload");
|
|
845
|
+
}
|
|
799
846
|
const meOf = (identity) => {
|
|
800
847
|
const { principal, author, actor } = identity;
|
|
801
848
|
return {
|
|
@@ -975,8 +1022,6 @@ function createVercel(options, environment) {
|
|
|
975
1022
|
});
|
|
976
1023
|
const methods = {
|
|
977
1024
|
...Object.fromEntries(METHODS.map((method) => [method, async () => {
|
|
978
|
-
const unkept = UNKEPT[method];
|
|
979
|
-
if (unkept) throw new HttpError(501, unkept[0], unkept[1]);
|
|
980
1025
|
throw notSupported(method === "register" || method === "watchers" || method === "matches" || method === "ack" ? "watchers" : method);
|
|
981
1026
|
}])),
|
|
982
1027
|
async discovery() {
|
|
@@ -1155,10 +1200,10 @@ function createVercel(options, environment) {
|
|
|
1155
1200
|
};
|
|
1156
1201
|
},
|
|
1157
1202
|
async upload(caller, { data, name, type }) {
|
|
1158
|
-
|
|
1203
|
+
const who = whoOf(caller);
|
|
1204
|
+
await checkUploader(caller, who);
|
|
1159
1205
|
if (data.byteLength === 0) throw new HttpError(400, "bad_request", "the file is empty");
|
|
1160
1206
|
if (data.byteLength > 26214400) throw new HttpError(413, "too_large", `attachments are at most ${IMPORT_BYTES_MAX / 1024 / 1024} MB`);
|
|
1161
|
-
const who = whoOf(caller);
|
|
1162
1207
|
const bytes = new Uint8Array(data);
|
|
1163
1208
|
const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", bytes));
|
|
1164
1209
|
const started = await api(who, "POST", await onBoard(who, "/attachments"), { body: {
|
|
@@ -1178,12 +1223,37 @@ function createVercel(options, environment) {
|
|
|
1178
1223
|
const { attachment } = await api(who, "POST", await onBoard(who, `/attachments/${encodeURIComponent(started.attachment.id)}/complete`));
|
|
1179
1224
|
return { attachment: fileOf(attachment) };
|
|
1180
1225
|
},
|
|
1226
|
+
async uploadStart(caller, { name, type, size, sha256 }) {
|
|
1227
|
+
const who = whoOf(caller);
|
|
1228
|
+
await checkUploader(caller, who);
|
|
1229
|
+
if (sha256 === void 0) throw new HttpError(400, "invalid_request", "Vercel's API signs a direct upload for its bytes' SHA-256: send `sha256`, as board's client does");
|
|
1230
|
+
const started = await api(who, "POST", await onBoard(who, "/attachments"), { body: {
|
|
1231
|
+
operationId: operationId(),
|
|
1232
|
+
name: fileName(name ?? null),
|
|
1233
|
+
type: mediaType(type ?? null),
|
|
1234
|
+
size,
|
|
1235
|
+
sha256
|
|
1236
|
+
} });
|
|
1237
|
+
return {
|
|
1238
|
+
id: started.attachment.id,
|
|
1239
|
+
url: started.upload.url,
|
|
1240
|
+
headers: started.upload.headers,
|
|
1241
|
+
expiresAt: iso(started.upload.expiresAt)
|
|
1242
|
+
};
|
|
1243
|
+
},
|
|
1244
|
+
async uploadFinish(caller, { id }) {
|
|
1245
|
+
const who = whoOf(caller);
|
|
1246
|
+
await checkUploader(caller, who);
|
|
1247
|
+
const { attachment } = await api(who, "POST", await onBoard(who, `/attachments/${encodeURIComponent(id)}/complete`));
|
|
1248
|
+
return { attachment: fileOf(attachment) };
|
|
1249
|
+
},
|
|
1181
1250
|
async attachment(caller, { id }, signal) {
|
|
1182
1251
|
const who = whoOf(caller);
|
|
1183
1252
|
const access = accessOf(caller);
|
|
1184
1253
|
const found = await api(who, "GET", await onBoard(who, `/attachments/${encodeURIComponent(id)}`), signal ? { signal } : {});
|
|
1185
|
-
if (access) {
|
|
1186
|
-
if (!
|
|
1254
|
+
if (access && !found.attachment.messageId) {
|
|
1255
|
+
if (!await isProject(caller, who)) throw notFound(`no attachment: ${id}`, "attachment_not_found");
|
|
1256
|
+
} else if (access) {
|
|
1187
1257
|
const { message } = await readableMessage(who, access, found.attachment.messageId, signal).catch((error) => {
|
|
1188
1258
|
if (error instanceof HttpError && error.status === 404) throw notFound(`no attachment: ${id}`, "attachment_not_found");
|
|
1189
1259
|
throw error;
|
|
@@ -1205,7 +1275,7 @@ function createVercel(options, environment) {
|
|
|
1205
1275
|
if (input.sync?.length) throw notSupported("sync");
|
|
1206
1276
|
const who = whoOf(caller);
|
|
1207
1277
|
const access = accessOf(caller);
|
|
1208
|
-
if (
|
|
1278
|
+
if (input.attachments?.length) await checkOwner("post files", caller, who);
|
|
1209
1279
|
const labeled = Object.keys(input.labels ?? {}).length > 0;
|
|
1210
1280
|
const clientId = input.id !== void 0 ? await postId(caller, input.id) : void 0;
|
|
1211
1281
|
let made;
|
|
@@ -1228,15 +1298,25 @@ function createVercel(options, environment) {
|
|
|
1228
1298
|
const { thread, message: to, channel } = await readableMessage(who, access, input.re, signal);
|
|
1229
1299
|
need(access, "post", channel.name);
|
|
1230
1300
|
if (labeled) need(access, "label", channel.name);
|
|
1301
|
+
const after = input.after === void 0 ? void 0 : locate(input.after);
|
|
1302
|
+
if (after !== void 0 && after?.threadId !== thread.id) {
|
|
1303
|
+
const landed = clientId ? await api(who, "GET", await onBoard(who, `/posts/${encodeURIComponent(clientId)}`), { signal }).catch(() => null) : null;
|
|
1304
|
+
if (landed?.thread.id === thread.id) return { message: await view(who, landed.message, channel.name) };
|
|
1305
|
+
throw badRequest(`after: ${input.after} isn't in ${input.re}'s thread`, "invalid_after");
|
|
1306
|
+
}
|
|
1231
1307
|
made = await api(who, "POST", await onBoard(who, `/threads/${encodeURIComponent(thread.id)}/messages`), {
|
|
1232
1308
|
body: {
|
|
1233
1309
|
operationId: operationId(),
|
|
1234
1310
|
text: input.text,
|
|
1235
1311
|
...to.sequence > 1 ? { replyTo: to.sequence } : {},
|
|
1236
1312
|
...clientId ? { clientId } : {},
|
|
1237
|
-
...input.attachments?.length ? { attachments: input.attachments } : {}
|
|
1313
|
+
...input.attachments?.length ? { attachments: input.attachments } : {},
|
|
1314
|
+
...after ? { after: after.sequence } : {}
|
|
1238
1315
|
},
|
|
1239
1316
|
signal
|
|
1317
|
+
}).catch((error) => {
|
|
1318
|
+
if (error instanceof HttpError && error.code === "newer_message") throw new HttpError(409, "newer_message", `a message came after ${input.after}`);
|
|
1319
|
+
throw error;
|
|
1240
1320
|
});
|
|
1241
1321
|
if (input.labels && Object.keys(input.labels).length) {
|
|
1242
1322
|
const labeled = await api(who, "POST", await onBoard(who, `/threads/${encodeURIComponent(thread.id)}/messages/${made.message.sequence}/labels`), {
|
|
@@ -1268,27 +1348,35 @@ function createVercel(options, environment) {
|
|
|
1268
1348
|
if (access && !access.readable(channel.name)) throw notFound(`no post of yours has id ${id}`, "post_not_found");
|
|
1269
1349
|
return { message: await view(who, found.message, channel.name) };
|
|
1270
1350
|
},
|
|
1271
|
-
async edit(caller, { id, text }, signal) {
|
|
1272
|
-
checkCaller("edit", caller);
|
|
1351
|
+
async edit(caller, { id, text, revision }, signal) {
|
|
1273
1352
|
const who = whoOf(caller);
|
|
1353
|
+
await checkOwner("edit", caller, who);
|
|
1274
1354
|
const at = locate(id);
|
|
1275
1355
|
if (!at) throw notFound(`message not found: ${id}`, "message_not_found");
|
|
1356
|
+
const access = accessOf(caller);
|
|
1357
|
+
if (access) need(access, "post", (await readableMessage(who, access, id, signal)).channel.name);
|
|
1276
1358
|
await api(who, "PATCH", await onBoard(who, `/threads/${encodeURIComponent(at.threadId)}/messages/${at.sequence}`), {
|
|
1277
1359
|
body: {
|
|
1278
1360
|
operationId: operationId(),
|
|
1279
|
-
text
|
|
1361
|
+
text,
|
|
1362
|
+
...revision !== void 0 ? { revision } : {}
|
|
1280
1363
|
},
|
|
1281
1364
|
signal
|
|
1282
1365
|
});
|
|
1283
1366
|
return { ok: true };
|
|
1284
1367
|
},
|
|
1285
|
-
async delete(caller, { id }, signal) {
|
|
1286
|
-
checkCaller("delete", caller);
|
|
1368
|
+
async delete(caller, { id, revision }, signal) {
|
|
1287
1369
|
const who = whoOf(caller);
|
|
1370
|
+
await checkOwner("delete", caller, who);
|
|
1288
1371
|
const at = locate(id);
|
|
1289
1372
|
if (!at) throw notFound(`message not found: ${id}`, "message_not_found");
|
|
1373
|
+
const access = accessOf(caller);
|
|
1374
|
+
if (access) need(access, "post", (await readableMessage(who, access, id, signal)).channel.name);
|
|
1290
1375
|
await api(who, "POST", await onBoard(who, `/threads/${encodeURIComponent(at.threadId)}/messages/${at.sequence}/delete`), {
|
|
1291
|
-
body: {
|
|
1376
|
+
body: {
|
|
1377
|
+
operationId: operationId(),
|
|
1378
|
+
...revision !== void 0 ? { revision } : {}
|
|
1379
|
+
},
|
|
1292
1380
|
signal
|
|
1293
1381
|
});
|
|
1294
1382
|
return { ok: true };
|
|
@@ -1310,7 +1398,7 @@ function createVercel(options, environment) {
|
|
|
1310
1398
|
});
|
|
1311
1399
|
return { ok: true };
|
|
1312
1400
|
},
|
|
1313
|
-
async label(caller, { id, set, unset }, signal) {
|
|
1401
|
+
async label(caller, { id, set, unset, if: expected }, signal) {
|
|
1314
1402
|
checkCaller("label", caller);
|
|
1315
1403
|
const who = whoOf(caller);
|
|
1316
1404
|
const at = locate(id);
|
|
@@ -1321,12 +1409,95 @@ function createVercel(options, environment) {
|
|
|
1321
1409
|
body: {
|
|
1322
1410
|
operationId: operationId(),
|
|
1323
1411
|
...set ? { set } : {},
|
|
1324
|
-
...unset ? { unset } : {}
|
|
1412
|
+
...unset ? { unset } : {},
|
|
1413
|
+
...expected && Object.keys(expected).length ? { if: expected } : {}
|
|
1325
1414
|
},
|
|
1326
1415
|
signal
|
|
1327
1416
|
});
|
|
1328
1417
|
return { ok: true };
|
|
1329
1418
|
},
|
|
1419
|
+
async schedule(caller, input, signal) {
|
|
1420
|
+
if (input.attachments?.length) throw notSupported("files on scheduled messages");
|
|
1421
|
+
const who = whoOf(caller);
|
|
1422
|
+
await checkOwner("schedule", caller, who);
|
|
1423
|
+
const access = accessOf(caller);
|
|
1424
|
+
const labels = input.labels && Object.keys(input.labels).length ? input.labels : void 0;
|
|
1425
|
+
let target;
|
|
1426
|
+
if (input.channel !== void 0) {
|
|
1427
|
+
need(access, "post", input.channel);
|
|
1428
|
+
if (labels) need(access, "label", input.channel);
|
|
1429
|
+
target = { channelId: (await channelToPost(who, input.channel)).id };
|
|
1430
|
+
} else {
|
|
1431
|
+
if (labels) throw notSupported("labels on a scheduled reply");
|
|
1432
|
+
const { thread, channel } = await readableMessage(who, access, input.re, signal);
|
|
1433
|
+
need(access, "post", channel.name);
|
|
1434
|
+
target = { threadId: thread.id };
|
|
1435
|
+
}
|
|
1436
|
+
const ms = (value) => Math.round(duration(value));
|
|
1437
|
+
const firstAt = input.at !== void 0 ? Date.parse(input.at) : Date.now() + ms(input.in ?? input.every);
|
|
1438
|
+
const until = input.until !== void 0 ? Date.parse(input.until) : input.for !== void 0 ? firstAt + ms(input.for) : void 0;
|
|
1439
|
+
const { schedule } = await api(who, "POST", await onBoard(who, "/schedules"), {
|
|
1440
|
+
body: {
|
|
1441
|
+
operationId: operationId(),
|
|
1442
|
+
...target,
|
|
1443
|
+
text: input.text,
|
|
1444
|
+
...labels ? { labels } : {},
|
|
1445
|
+
firstAt,
|
|
1446
|
+
...input.every !== void 0 ? { every: ms(input.every) } : {},
|
|
1447
|
+
...until !== void 0 ? { until } : {},
|
|
1448
|
+
...input.times !== void 0 ? { times: input.times } : {}
|
|
1449
|
+
},
|
|
1450
|
+
signal
|
|
1451
|
+
});
|
|
1452
|
+
return { schedule: await scheduleView(who, schedule) };
|
|
1453
|
+
},
|
|
1454
|
+
async schedules(caller, query, signal) {
|
|
1455
|
+
const who = whoOf(caller);
|
|
1456
|
+
const access = accessOf(caller);
|
|
1457
|
+
const filter = { state: query.all ? void 0 : "pending" };
|
|
1458
|
+
if (query.re !== void 0) {
|
|
1459
|
+
const found = await readableMessage(who, access, query.re, signal).catch((error) => {
|
|
1460
|
+
if (error instanceof HttpError && error.status === 404) return null;
|
|
1461
|
+
throw error;
|
|
1462
|
+
});
|
|
1463
|
+
if (!found) return { schedules: [] };
|
|
1464
|
+
filter.threadId = found.thread.id;
|
|
1465
|
+
}
|
|
1466
|
+
if (query.channel !== void 0) {
|
|
1467
|
+
const channel = await channelNamed(who, query.channel);
|
|
1468
|
+
if (!channel) return { schedules: [] };
|
|
1469
|
+
filter.channelId = channel.id;
|
|
1470
|
+
}
|
|
1471
|
+
const me = query.by === "me" ? await actorOf(who) : void 0;
|
|
1472
|
+
const by = me ?? query.by;
|
|
1473
|
+
if (by?.startsWith("vercel:")) filter.createdBy = by;
|
|
1474
|
+
const created = (actor) => by === void 0 || (me ? actor.id === me : [
|
|
1475
|
+
actor.id,
|
|
1476
|
+
principalId(actor.principal),
|
|
1477
|
+
actor.profile?.name
|
|
1478
|
+
].includes(by));
|
|
1479
|
+
const listed = await all(who, await onBoard(who, "/schedules"), "schedules", filter, signal);
|
|
1480
|
+
return { schedules: (await Promise.all(listed.filter((schedule) => created(schedule.createdBy)).map((schedule) => scheduleView(who, schedule)))).filter((schedule) => access === null || access.readable(schedule.channel)) };
|
|
1481
|
+
},
|
|
1482
|
+
async cancelSchedule(caller, { id }, signal) {
|
|
1483
|
+
const who = whoOf(caller);
|
|
1484
|
+
await checkOwner("cancelSchedule", caller, who);
|
|
1485
|
+
const access = accessOf(caller);
|
|
1486
|
+
if (access) {
|
|
1487
|
+
const found = (await all(who, await onBoard(who, "/schedules"), "schedules", {}, signal)).find((schedule) => schedule.id === id);
|
|
1488
|
+
const channel = found && await channelById(who, found.channelId);
|
|
1489
|
+
if (!channel || !access.readable(channel.name)) throw notFound(`no schedule: ${id}`, "schedule_not_found");
|
|
1490
|
+
need(access, "post", channel.name);
|
|
1491
|
+
}
|
|
1492
|
+
const { schedule, canceled } = await api(who, "POST", await onBoard(who, `/schedules/${encodeURIComponent(id)}/cancel`), {
|
|
1493
|
+
body: { operationId: operationId() },
|
|
1494
|
+
signal
|
|
1495
|
+
});
|
|
1496
|
+
return {
|
|
1497
|
+
schedule: await scheduleView(who, schedule),
|
|
1498
|
+
canceled
|
|
1499
|
+
};
|
|
1500
|
+
},
|
|
1330
1501
|
async events(caller, query, signal) {
|
|
1331
1502
|
checkCaller("events", caller);
|
|
1332
1503
|
const who = whoOf(caller);
|
|
@@ -1399,6 +1570,7 @@ function createVercel(options, environment) {
|
|
|
1399
1570
|
}])),
|
|
1400
1571
|
routes: runner.routes,
|
|
1401
1572
|
keeps: false,
|
|
1573
|
+
sendsSchedulesHere: false,
|
|
1402
1574
|
bind(next) {
|
|
1403
1575
|
if (binding) throw new Error("vercel: this backend already serves a board: create one vercel() per board()");
|
|
1404
1576
|
if (Object.values(next.subscriptions).map((subscription) => subscription.kind).includes("sync")) throw new Error("vercel: Vercel's boards don't run sync yet: leave `sync` out");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { t as HttpError } from "./errors-
|
|
2
|
-
import { c as loginHanded, d as vercelProjectFile, i as environmentProfile, t as asYou, u as vercelLogin } from "./node-
|
|
3
|
-
import { t as createVercel } from "./backend-vercel-
|
|
1
|
+
import { t as HttpError } from "./errors-C_5rB8Iz.mjs";
|
|
2
|
+
import { c as loginHanded, d as vercelProjectFile, i as environmentProfile, t as asYou, u as vercelLogin } from "./node-D8Rtg1su.mjs";
|
|
3
|
+
import { t as createVercel } from "./backend-vercel-C4Kee2-K.mjs";
|
|
4
4
|
import { readFile } from "node:fs/promises";
|
|
5
5
|
import { decodeJwt } from "jose";
|
|
6
6
|
import { getVercelOidcToken } from "@vercel/oidc";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { t as Actor, x as Attachment } from "./folds-
|
|
2
|
-
import { A as InboxItem,
|
|
3
|
-
import { i as Caller, n as BackendRoute, r as BoardBinding } from "./backend-
|
|
1
|
+
import { t as Actor, x as Attachment } from "./folds-8wRRXjAt.mjs";
|
|
2
|
+
import { A as InboxItem, Ct as SyncCopiesView, D as IdentityView, Et as SyncFindView, H as MessageView, It as ThreadView, L as LinkedAccount, Lt as ThreadsPage, Mt as SyncThreadView, Pt as SyncedView, S as EventsPage, U as MessagesPage, Ut as UploadTicket, V as Me, b as Discovery, ft as SourceJoin, ht as SourceRead, k as InboxEntry, o as ProfileOption, q as PersonView, st as ScheduleView, tt as RegistrationView, v as ChannelView, xt as SyncCodeView, z as MatchView } from "./client-CjAatpV4.mjs";
|
|
3
|
+
import { i as Caller, n as BackendRoute, r as BoardBinding } from "./backend-n3hajfrD.mjs";
|
|
4
4
|
//#region src/server/backend-vercel.d.ts
|
|
5
5
|
type VercelOptions = {
|
|
6
6
|
/** The team whose board it is: its ID (`team_…`) or its slug. In Node, by default your deployment's, or `VERCEL_ORG_ID`. */
|
|
@@ -31,8 +31,8 @@ type VercelEnvironment = {
|
|
|
31
31
|
};
|
|
32
32
|
/**
|
|
33
33
|
* Vercel's board for your team, in Vercel's API: this deployment keeps nothing and reads and writes
|
|
34
|
-
* it as itself, its people as themselves. Messages, threads, reactions, labels,
|
|
35
|
-
* changes work; what the API keeps none of yet (
|
|
34
|
+
* it as itself, its people as themselves. Messages, threads, reactions, labels, a channel's
|
|
35
|
+
* changes, schedules, files, and watchers work; what the API keeps none of yet (sync) answers 501.
|
|
36
36
|
*/
|
|
37
37
|
declare function createVercel(options: VercelOptions, environment: VercelEnvironment | null): {
|
|
38
38
|
discovery: (caller: Caller, input: {
|
|
@@ -96,6 +96,7 @@ declare function createVercel(options: VercelOptions, environment: VercelEnviron
|
|
|
96
96
|
})[] | undefined;
|
|
97
97
|
id?: string | undefined;
|
|
98
98
|
attachments?: string[] | undefined;
|
|
99
|
+
after?: string | undefined;
|
|
99
100
|
}, signal: AbortSignal) => Promise<{
|
|
100
101
|
message: MessageView;
|
|
101
102
|
unknownMentions?: string[];
|
|
@@ -109,12 +110,15 @@ declare function createVercel(options: VercelOptions, environment: VercelEnviron
|
|
|
109
110
|
id: string;
|
|
110
111
|
} & {
|
|
111
112
|
text: string;
|
|
113
|
+
revision?: number | undefined;
|
|
112
114
|
}, signal: AbortSignal) => Promise<{
|
|
113
115
|
ok: true;
|
|
114
116
|
unknownMentions?: string[];
|
|
115
117
|
}>;
|
|
116
118
|
delete: (caller: Caller, input: {
|
|
117
119
|
id: string;
|
|
120
|
+
} & {
|
|
121
|
+
revision?: number | undefined;
|
|
118
122
|
}, signal: AbortSignal) => Promise<{
|
|
119
123
|
ok: true;
|
|
120
124
|
}>;
|
|
@@ -131,6 +135,7 @@ declare function createVercel(options: VercelOptions, environment: VercelEnviron
|
|
|
131
135
|
} & {
|
|
132
136
|
set?: Record<string, string> | undefined;
|
|
133
137
|
unset?: string[] | undefined;
|
|
138
|
+
if?: Record<string, string | null> | undefined;
|
|
134
139
|
}, signal: AbortSignal) => Promise<{
|
|
135
140
|
ok: true;
|
|
136
141
|
}>;
|
|
@@ -182,6 +187,7 @@ declare function createVercel(options: VercelOptions, environment: VercelEnviron
|
|
|
182
187
|
name?: string | null | undefined;
|
|
183
188
|
type?: string | null | undefined;
|
|
184
189
|
size: number;
|
|
190
|
+
sha256?: string | undefined;
|
|
185
191
|
}, signal: AbortSignal) => Promise<UploadTicket>;
|
|
186
192
|
uploadFinish: (caller: Caller, input: {
|
|
187
193
|
id: string;
|
|
@@ -315,6 +321,7 @@ declare function createVercel(options: VercelOptions, environment: VercelEnviron
|
|
|
315
321
|
message: string | null;
|
|
316
322
|
}[] | undefined;
|
|
317
323
|
id?: string | undefined;
|
|
324
|
+
after?: string | undefined;
|
|
318
325
|
} | {
|
|
319
326
|
author: {
|
|
320
327
|
id: string;
|
|
@@ -336,6 +343,7 @@ declare function createVercel(options: VercelOptions, environment: VercelEnviron
|
|
|
336
343
|
channel: string;
|
|
337
344
|
thread: string;
|
|
338
345
|
} | undefined;
|
|
346
|
+
revision?: number | undefined;
|
|
339
347
|
} | {
|
|
340
348
|
author: {
|
|
341
349
|
id: string;
|
|
@@ -351,6 +359,7 @@ declare function createVercel(options: VercelOptions, environment: VercelEnviron
|
|
|
351
359
|
} | undefined;
|
|
352
360
|
message?: string | undefined;
|
|
353
361
|
op: "delete";
|
|
362
|
+
revision?: number | undefined;
|
|
354
363
|
} | {
|
|
355
364
|
author: {
|
|
356
365
|
id: string;
|
|
@@ -385,6 +394,7 @@ declare function createVercel(options: VercelOptions, environment: VercelEnviron
|
|
|
385
394
|
op: "labels";
|
|
386
395
|
set?: Record<string, string> | undefined;
|
|
387
396
|
unset?: string[] | undefined;
|
|
397
|
+
if?: Record<string, string | null> | undefined;
|
|
388
398
|
} | {
|
|
389
399
|
author: {
|
|
390
400
|
id: string;
|
|
@@ -648,6 +658,7 @@ declare function createVercel(options: VercelOptions, environment: VercelEnviron
|
|
|
648
658
|
}>;
|
|
649
659
|
routes: BackendRoute[];
|
|
650
660
|
keeps: boolean;
|
|
661
|
+
sendsSchedulesHere: boolean;
|
|
651
662
|
bind(next: BoardBinding): void;
|
|
652
663
|
/** Registers this board's watchers with Vercel's API now, as `POST /watchers` does. */
|
|
653
664
|
registerWatchers: () => Promise<RegistrationView>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as VercelOptions, t as VercelBackend } from "./backend-vercel-
|
|
1
|
+
import { n as VercelOptions, t as VercelBackend } from "./backend-vercel-qznuDxnN.mjs";
|
|
2
2
|
//#region src/backend-vercel/index.default.d.ts
|
|
3
3
|
/**
|
|
4
4
|
* Your team's board, in Vercel's API. Outside Node there's no environment to find credentials or
|
package/dist/backend-vercel.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as createVercel } from "./backend-vercel-
|
|
1
|
+
import { t as createVercel } from "./backend-vercel-C4Kee2-K.mjs";
|
|
2
2
|
//#region src/backend-vercel/index.default.ts
|
|
3
3
|
/**
|
|
4
4
|
* Your team's board, in Vercel's API. Outside Node there's no environment to find credentials or
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as VercelOptions, t as VercelBackend } from "./backend-vercel-
|
|
1
|
+
import { n as VercelOptions, t as VercelBackend } from "./backend-vercel-qznuDxnN.mjs";
|
|
2
2
|
//#region src/backend-vercel/index.d.ts
|
|
3
3
|
/** Where `token` comes from, in words: what `vb whoami` says. */
|
|
4
4
|
export declare function credentialSource(): string;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as handTeam, r as vercel, t as credentialSource } from "./backend-vercel-
|
|
1
|
+
import { n as handTeam, r as vercel, t as credentialSource } from "./backend-vercel-Kd8nvW5A.mjs";
|
|
2
2
|
export { credentialSource, handTeam, vercel };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { n as DIRECT_UPLOAD_BYTES_MAX, t as ATTACHMENT_BYTES_MAX } from "./files-SniSmeEr.mjs";
|
|
2
2
|
import { i as Attachment } from "./schemas-DBmUO6pr.mjs";
|
|
3
|
-
import { r as badRequest, s as notFound, t as HttpError } from "./errors-
|
|
3
|
+
import { r as badRequest, s as notFound, t as HttpError } from "./errors-C_5rB8Iz.mjs";
|
|
4
4
|
import { randomBytes } from "node:crypto";
|
|
5
5
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
6
6
|
import { dirname, join } from "node:path";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { d as ExternalFile, f as ExternalLink, l as ExternalAuthor, t as Actor } from "./folds-
|
|
2
|
-
import {
|
|
3
|
-
import { M as SyncRoot, O as ProviderEvent, 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-
|
|
1
|
+
import { d as ExternalFile, f as ExternalLink, l as ExternalAuthor, t as Actor } from "./folds-8wRRXjAt.mjs";
|
|
2
|
+
import { ft as SourceJoin, ht as SourceRead } from "./client-CjAatpV4.mjs";
|
|
3
|
+
import { M as SyncRoot, O as ProviderEvent, 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-Bm46LAdp.mjs";
|
|
4
4
|
import { Adapter, Author, FileUpload, Message, ReactionEvent } from "chat";
|
|
5
5
|
//#region src/sync/types.d.ts
|
|
6
6
|
declare function externalAuthor(platform: string, author: Author): ExternalAuthor;
|
package/dist/cli-commands.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as OptionName, c as globalOptions, d as options, f as usage, i as CliOption, l as groups, n as CliCommand, o as commands, r as CliExample, s as filters, t as CliArgument, u as option } from "./commands-
|
|
1
|
+
import { a as OptionName, c as globalOptions, d as options, f as usage, i as CliOption, l as groups, n as CliCommand, o as commands, r as CliExample, s as filters, t as CliArgument, u as option } from "./commands-BtH69yqt.mjs";
|
|
2
2
|
export { CliArgument, CliCommand, CliExample, CliOption, OptionName, commands, filters, globalOptions, groups, option, options, usage };
|
package/dist/cli-commands.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as option, i as groups, n as filters, o as options, r as globalOptions, s as usage, t as commands } from "./commands-
|
|
1
|
+
import { a as option, i as groups, n as filters, o as options, r as globalOptions, s as usage, t as commands } from "./commands-B5DHjZKK.mjs";
|
|
2
2
|
export { commands, filters, globalOptions, groups, option, options, usage };
|
package/dist/cli-embedded.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { d as Board } from "./backend-
|
|
2
|
-
import "./index-
|
|
1
|
+
import { d as Board } from "./backend-n3hajfrD.mjs";
|
|
2
|
+
import "./index-BygAXP7t.mjs";
|
|
3
3
|
//#region src/cli/failure.d.ts
|
|
4
4
|
/**
|
|
5
5
|
* What kind of failure it is, which fixes the exit code: 2 for `usage` and `missing_input`, 130
|
package/dist/cli-embedded.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as commandLine, c as failureLines, i as mainWith, l as formatFailure, n as commandWord, o as exitCode, r as main, s as failureDocument, t as Failed } from "./main-
|
|
1
|
+
import { a as commandLine, c as failureLines, i as mainWith, l as formatFailure, n as commandWord, o as exitCode, r as main, s as failureDocument, t as Failed } from "./main-D2s-QBOK.mjs";
|
|
2
2
|
//#region src/cli/embedded.ts
|
|
3
3
|
/**
|
|
4
4
|
* Board's CLI as `appName` names it in help, usage, and errors (`vercel board`). With no board
|
package/dist/cli.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { t as ATTACHMENT_BYTES_MAX } from "./files-SniSmeEr.mjs";
|
|
3
3
|
import "./schemas-DBmUO6pr.mjs";
|
|
4
|
-
import { a as option } from "./commands-
|
|
5
|
-
import { l as projectDir } from "./node-
|
|
6
|
-
import { r as main, u as who } from "./main-
|
|
4
|
+
import { a as option } from "./commands-B5DHjZKK.mjs";
|
|
5
|
+
import { l as projectDir } from "./node-D8Rtg1su.mjs";
|
|
6
|
+
import { r as main, u as who } from "./main-D2s-QBOK.mjs";
|
|
7
7
|
import { randomBytes, timingSafeEqual } from "node:crypto";
|
|
8
8
|
import { appendFile, readFile } from "node:fs/promises";
|
|
9
9
|
import { join } from "node:path";
|
|
@@ -661,7 +661,7 @@ const local = {
|
|
|
661
661
|
if (args.length > 0) throw usage("serve takes no arguments: pass its port with --port, and its directory with --dir.");
|
|
662
662
|
const port = portFlag();
|
|
663
663
|
const root = projectDir();
|
|
664
|
-
const { localHandle, serveLocal } = await import("./serve-
|
|
664
|
+
const { localHandle, serveLocal } = await import("./serve-lPoBDEds.mjs");
|
|
665
665
|
const handle = flags.handle ?? process.env.BOARD_HANDLE;
|
|
666
666
|
const local = await serveLocal({
|
|
667
667
|
dir: flags.dir ?? join(root, ".board"),
|