@vercel/board 0.19.0 → 0.20.1
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-C1obi0Qb.mjs → a2-QtmN9EhW.mjs} +36 -6
- package/dist/access.mjs +3 -3
- package/dist/{actors-BOamkEuz.mjs → actors-rPnEQLZu.mjs} +2 -2
- package/dist/{auth-Drg9FiC2.mjs → auth-5nLsx9qB.mjs} +1 -1
- package/dist/{backend-B5GCP1oK.d.mts → backend-CWmd4UH-.d.mts} +8 -1
- package/dist/backend-a2.d.mts +22 -4
- package/dist/backend-a2.mjs +1 -1
- package/dist/{backend-http-Ca6b0FPA.d.mts → backend-http-BfWQfvqB.d.mts} +22 -4
- package/dist/{backend-http-BMVDbtD_.mjs → backend-http-CbcjkHEn.mjs} +7 -3
- package/dist/{backend-http-DMpQ750P.mjs → backend-http-maHy-JW3.mjs} +19 -6
- 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-B5uCc0an.d.mts → chat-provider-D0k3y8zY.d.mts} +4 -1
- package/dist/{chat-provider-YHy-WbrB.mjs → chat-provider-DnHibqnM.mjs} +4 -1
- package/dist/cli-embedded.d.mts +47 -0
- package/dist/cli-embedded.mjs +64 -0
- package/dist/cli.mjs +73 -1661
- package/dist/{client-BA-J7usH.mjs → client-ClznIBMg.mjs} +2 -0
- package/dist/{conformance-D0Z4dXC_.mjs → conformance-DQ9qVzWP.mjs} +1 -1
- package/dist/conformance.d.mts +1 -1
- package/dist/conformance.mjs +1 -1
- package/dist/{engine-D0oBUBEK.mjs → engine-kHfSOXnQ.mjs} +15 -4
- package/dist/{errors-DX3hpwWt.mjs → errors-CQ-fwxM3.mjs} +13 -1
- package/dist/{exports-CUGshfRF.mjs → exports-Dd8YdgO-.mjs} +15 -6
- package/dist/exports-ggfE9jNv.d.mts +4 -0
- package/dist/index-DsMPCv_K.d.mts +11 -0
- package/dist/index.d.mts +4 -4
- package/dist/{index.default-Cm6GsLdj.mjs → index.default-BqstUHvz.mjs} +1 -1
- package/dist/index.mjs +6 -6
- package/dist/index.node.d.mts +4 -12
- package/dist/index.node.mjs +4 -4
- package/dist/inspect/app.js +93 -92
- package/dist/inspect/engine.js +4 -4
- package/dist/main-CRLa7i3I.mjs +1745 -0
- package/dist/{middleware-CqaCwucP.mjs → middleware-DUjyQP_a.mjs} +1 -1
- package/dist/{provider-B1Z3Ok86.d.mts → provider-D11Dfda0.d.mts} +86 -32
- package/dist/{provider-B3DpYSDq.mjs → provider-poIkXapd.mjs} +4 -0
- package/dist/{serve-DB9ijyQ7.mjs → serve-1kBFSHe_.mjs} +4 -4
- package/dist/{server-BujqWBP5.mjs → server-CuqhG9E6.mjs} +4 -4
- package/dist/{serving-CNkgUPW1.mjs → serving-B307gppu.mjs} +1 -1
- package/dist/sync-github.d.mts +2 -2
- package/dist/sync-github.mjs +2 -2
- package/dist/sync-kapso.d.mts +2 -2
- package/dist/sync-kapso.mjs +2 -2
- package/dist/sync-linear.d.mts +2 -2
- package/dist/sync-linear.mjs +2 -2
- package/dist/sync-slack.d.mts +11 -2
- package/dist/sync-slack.mjs +57 -17
- package/dist/sync.chat.d.mts +1 -1
- package/dist/sync.chat.mjs +1 -1
- package/dist/sync.d.mts +1 -1
- package/dist/sync.mjs +1 -1
- package/dist/{tokens-DhuzKzAl.mjs → tokens-DUXaXwOj.mjs} +2 -2
- package/dist/{watchers-hash-B2TevhFZ.mjs → watchers-hash-Cd6ZLo9m.mjs} +38 -25
- package/docs/02-sync/03-slack.md +14 -1
- package/docs/02-sync/06-providers.md +1 -0
- package/docs/04-reference/01-cli.md +53 -2
- package/docs/04-reference/02-board.md +8 -3
- package/docs/04-reference/03-http.md +4 -3
- package/package.json +5 -1
- package/dist/exports-B3AFzT_f.d.mts +0 -4
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { m as MESSAGE_TEXT_MAX, p as Labels } from "./schemas-Be08nyfW.mjs";
|
|
2
|
-
import { t as HttpError } from "./errors-
|
|
2
|
+
import { t as HttpError } from "./errors-CQ-fwxM3.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
//#region src/server/middleware.ts
|
|
5
5
|
/** A write the middleware didn't let through: the API answers 422 with what it responded. */
|
|
@@ -115,11 +115,27 @@ declare const InboxQuery: z.ZodObject<{
|
|
|
115
115
|
}, z.core.$strip>;
|
|
116
116
|
/** How many watchers one registration holds: the board matches every event against every tail. */
|
|
117
117
|
declare const REGISTERED_WATCHERS_MAX = 32;
|
|
118
|
-
/**
|
|
119
|
-
|
|
118
|
+
/**
|
|
119
|
+
* What a board on `http()` registers with the board it uses: its watchers, and where to wake it,
|
|
120
|
+
* at a URL or at a path on its own project, never both.
|
|
121
|
+
*/
|
|
122
|
+
declare const RegisterBody: z.ZodUnion<readonly [z.ZodObject<{
|
|
123
|
+
watch: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
124
|
+
tail: z.ZodString;
|
|
125
|
+
when: z.ZodDefault<z.ZodEnum<{
|
|
126
|
+
enters: "enters";
|
|
127
|
+
matches: "matches";
|
|
128
|
+
}>>;
|
|
129
|
+
}, z.core.$strip>>;
|
|
130
|
+
sync: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
131
|
+
key: z.ZodString;
|
|
132
|
+
platform: z.ZodString;
|
|
133
|
+
signIn: z.ZodDefault<z.ZodBoolean>;
|
|
134
|
+
}, z.core.$strip>>>;
|
|
120
135
|
url: z.ZodOptional<z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>>;
|
|
121
|
-
path: z.ZodOptional<z.
|
|
122
|
-
branch: z.ZodOptional<z.
|
|
136
|
+
path: z.ZodOptional<z.ZodNull>;
|
|
137
|
+
branch: z.ZodOptional<z.ZodNull>;
|
|
138
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
123
139
|
watch: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
124
140
|
tail: z.ZodString;
|
|
125
141
|
when: z.ZodDefault<z.ZodEnum<{
|
|
@@ -132,7 +148,12 @@ declare const RegisterBody: z.ZodObject<{
|
|
|
132
148
|
platform: z.ZodString;
|
|
133
149
|
signIn: z.ZodDefault<z.ZodBoolean>;
|
|
134
150
|
}, z.core.$strip>>>;
|
|
135
|
-
|
|
151
|
+
url: z.ZodOptional<z.ZodNull>;
|
|
152
|
+
path: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
153
|
+
branch: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
154
|
+
}, z.core.$strip>]>;
|
|
155
|
+
/** A registration as a board on `http()` sends it: `{ url?, watch, sync? }` or `{ path, branch?, watch, sync? }`. */
|
|
156
|
+
type RegisterInput = z.input<typeof RegisterBody>;
|
|
136
157
|
/** A pull of the caller's matches: at most `limit`, waiting up to `wait` seconds for one. */
|
|
137
158
|
declare const MatchesQuery: z.ZodObject<{
|
|
138
159
|
limit: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
@@ -152,6 +173,10 @@ declare const SourceReadQuery: z.ZodObject<{
|
|
|
152
173
|
target: z.ZodString;
|
|
153
174
|
limit: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
154
175
|
}, z.core.$strip>;
|
|
176
|
+
/** A channel to add the board's app to, so it can be read on demand: `#name`, an ID, or a link into it. */
|
|
177
|
+
declare const SourceJoinBody: z.ZodObject<{
|
|
178
|
+
target: z.ZodString;
|
|
179
|
+
}, z.core.$strip>;
|
|
155
180
|
/** A platform's link to a message or thread, such as a Slack permalink or a GitHub comment's URL. */
|
|
156
181
|
declare const LinkedQuery: z.ZodObject<{
|
|
157
182
|
url: z.ZodString;
|
|
@@ -688,16 +713,13 @@ type Discovery = {
|
|
|
688
713
|
*/
|
|
689
714
|
wake_by_path?: boolean;
|
|
690
715
|
};
|
|
691
|
-
/**
|
|
716
|
+
/**
|
|
717
|
+
* Watchers a board on `http()` registered here: one registration per principal, woken at a URL
|
|
718
|
+
* or at a path on its own project, never both.
|
|
719
|
+
*/
|
|
692
720
|
type RegistrationView = {
|
|
693
721
|
/** The principal that registered. Its watchers write as it, with their IDs as profiles. */
|
|
694
722
|
owner: string;
|
|
695
|
-
/** Where it's woken: `<url>/wake`. `null` when it pulls on its own, or is woken by `path`. */
|
|
696
|
-
url: string | null;
|
|
697
|
-
/** Where it's woken on its own Vercel project, on a board with `wake_by_path`. */
|
|
698
|
-
path?: string | null;
|
|
699
|
-
/** The branch whose latest ready preview a preview's `path` wakes. */
|
|
700
|
-
branch?: string | null;
|
|
701
723
|
watch: Record<string, {
|
|
702
724
|
tail: string;
|
|
703
725
|
when: 'matches' | 'enters';
|
|
@@ -710,7 +732,18 @@ type RegistrationView = {
|
|
|
710
732
|
}[];
|
|
711
733
|
/** Every wake-up carries it, so the board can tell its registration is stale. */
|
|
712
734
|
hash: string;
|
|
713
|
-
}
|
|
735
|
+
} & ({
|
|
736
|
+
/** Where it's woken: `<url>/wake`. `null` when it pulls on its own. */
|
|
737
|
+
url: string | null;
|
|
738
|
+
path?: undefined;
|
|
739
|
+
branch?: undefined;
|
|
740
|
+
} | {
|
|
741
|
+
url: null;
|
|
742
|
+
/** Where it's woken on its own Vercel project, on a board with `wake_by_path`. */
|
|
743
|
+
path: string;
|
|
744
|
+
/** The branch whose latest ready preview a preview's `path` wakes. */
|
|
745
|
+
branch?: string;
|
|
746
|
+
});
|
|
714
747
|
/** One match, leased to the registrant that pulled it. */
|
|
715
748
|
type MatchView = {
|
|
716
749
|
/** The match's ID, which its watcher's writes derive their IDs from. */
|
|
@@ -880,6 +913,12 @@ type SourceRead = {
|
|
|
880
913
|
/** The platform has more than `limit`: older messages in a channel, later replies in a thread. */
|
|
881
914
|
more: boolean;
|
|
882
915
|
};
|
|
916
|
+
/** A channel the board's app joined, or was already in (`joined: false`). */
|
|
917
|
+
type SourceJoin = {
|
|
918
|
+
channel: string;
|
|
919
|
+
name: string | null;
|
|
920
|
+
joined: boolean;
|
|
921
|
+
};
|
|
883
922
|
type ApiError = {
|
|
884
923
|
error: {
|
|
885
924
|
code: string;
|
|
@@ -1497,6 +1536,14 @@ declare const routes: {
|
|
|
1497
1536
|
limit: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
1498
1537
|
}, z.core.$strip>;
|
|
1499
1538
|
};
|
|
1539
|
+
/** Adds the app to a public channel so it can be read, where that sync runs and opted in with `join`. Full access only. */
|
|
1540
|
+
readonly joinSource: {
|
|
1541
|
+
readonly method: 'POST';
|
|
1542
|
+
readonly path: '/sources/:key/join';
|
|
1543
|
+
readonly body: z.ZodObject<{
|
|
1544
|
+
target: z.ZodString;
|
|
1545
|
+
}, z.core.$strip>;
|
|
1546
|
+
};
|
|
1500
1547
|
readonly webhook: {
|
|
1501
1548
|
readonly method: 'POST';
|
|
1502
1549
|
readonly path: '/webhooks/:key';
|
|
@@ -1588,10 +1635,23 @@ declare const routes: {
|
|
|
1588
1635
|
readonly register: {
|
|
1589
1636
|
readonly method: 'POST';
|
|
1590
1637
|
readonly path: '/watchers';
|
|
1591
|
-
readonly body: z.ZodObject<{
|
|
1638
|
+
readonly body: z.ZodUnion<readonly [z.ZodObject<{
|
|
1639
|
+
watch: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
1640
|
+
tail: z.ZodString;
|
|
1641
|
+
when: z.ZodDefault<z.ZodEnum<{
|
|
1642
|
+
enters: "enters";
|
|
1643
|
+
matches: "matches";
|
|
1644
|
+
}>>;
|
|
1645
|
+
}, z.core.$strip>>;
|
|
1646
|
+
sync: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
1647
|
+
key: z.ZodString;
|
|
1648
|
+
platform: z.ZodString;
|
|
1649
|
+
signIn: z.ZodDefault<z.ZodBoolean>;
|
|
1650
|
+
}, z.core.$strip>>>;
|
|
1592
1651
|
url: z.ZodOptional<z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>>;
|
|
1593
|
-
path: z.ZodOptional<z.
|
|
1594
|
-
branch: z.ZodOptional<z.
|
|
1652
|
+
path: z.ZodOptional<z.ZodNull>;
|
|
1653
|
+
branch: z.ZodOptional<z.ZodNull>;
|
|
1654
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
1595
1655
|
watch: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
1596
1656
|
tail: z.ZodString;
|
|
1597
1657
|
when: z.ZodDefault<z.ZodEnum<{
|
|
@@ -1604,7 +1664,10 @@ declare const routes: {
|
|
|
1604
1664
|
platform: z.ZodString;
|
|
1605
1665
|
signIn: z.ZodDefault<z.ZodBoolean>;
|
|
1606
1666
|
}, z.core.$strip>>>;
|
|
1607
|
-
|
|
1667
|
+
url: z.ZodOptional<z.ZodNull>;
|
|
1668
|
+
path: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
1669
|
+
branch: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
1670
|
+
}, z.core.$strip>]>;
|
|
1608
1671
|
};
|
|
1609
1672
|
/** The caller's matches it can run now, each leased to it until it acks. */
|
|
1610
1673
|
readonly matches: {
|
|
@@ -1827,20 +1890,7 @@ declare function createBoardClient(options: ClientOptions): {
|
|
|
1827
1890
|
limit?: number;
|
|
1828
1891
|
}) => Promise<InboxEntry[]>;
|
|
1829
1892
|
/** Registers the caller's watchers, replacing its last registration: what a board on `http()` does. */
|
|
1830
|
-
register: (input:
|
|
1831
|
-
url?: string | null;
|
|
1832
|
-
path?: string | null;
|
|
1833
|
-
branch?: string | null;
|
|
1834
|
-
watch: Record<string, {
|
|
1835
|
-
tail: string;
|
|
1836
|
-
when?: 'matches' | 'enters';
|
|
1837
|
-
}>;
|
|
1838
|
-
sync?: {
|
|
1839
|
-
key: string;
|
|
1840
|
-
platform: string;
|
|
1841
|
-
signIn?: boolean;
|
|
1842
|
-
}[];
|
|
1843
|
-
}) => Promise<RegistrationView>;
|
|
1893
|
+
register: (input: RegisterInput) => Promise<RegistrationView>;
|
|
1844
1894
|
/** Registered watchers: every one to `manage` everywhere, the caller's own to anyone else. */
|
|
1845
1895
|
watchers: () => Promise<RegistrationView[]>;
|
|
1846
1896
|
/** The caller's matches it can run now, each leased to it until it acks. `wait` holds the request up to that many seconds for one. */
|
|
@@ -1864,6 +1914,8 @@ declare function createBoardClient(options: ClientOptions): {
|
|
|
1864
1914
|
readSource: (key: string, target: string, opts?: {
|
|
1865
1915
|
limit?: number;
|
|
1866
1916
|
}) => Promise<SourceRead>;
|
|
1917
|
+
/** Adds the app to a public channel so `readSource` can read it, where the sync opted in with `join`. Full access only. */
|
|
1918
|
+
joinSource: (key: string, target: string) => Promise<SourceJoin>;
|
|
1867
1919
|
poll: (query?: Filters & {
|
|
1868
1920
|
after?: string;
|
|
1869
1921
|
wait?: number;
|
|
@@ -2595,6 +2647,8 @@ declare abstract class SyncProvider<E extends ProviderEvent = ProviderEvent> {
|
|
|
2595
2647
|
read(_target: string, _options: {
|
|
2596
2648
|
limit: number;
|
|
2597
2649
|
}): Promise<SourceRead>;
|
|
2650
|
+
/** Adds the board's app to a channel so `read` can read it, where the board opted in. Throws `UnreadableError` otherwise. */
|
|
2651
|
+
join(_target: string): Promise<SourceJoin>;
|
|
2598
2652
|
edit(_thread: string, _message: string, _body: ProviderPost): Promise<void>;
|
|
2599
2653
|
delete(_thread: string, _message: string): Promise<void>;
|
|
2600
2654
|
react(_thread: string, _message: string, _emoji: string, _added: boolean): Promise<void>;
|
|
@@ -2615,4 +2669,4 @@ declare abstract class SyncProvider<E extends ProviderEvent = ProviderEvent> {
|
|
|
2615
2669
|
render(input: RenderInput): string;
|
|
2616
2670
|
}
|
|
2617
2671
|
//#endregion
|
|
2618
|
-
export { Discovery as $,
|
|
2672
|
+
export { Discovery as $, SyncCodeView as $t, SyncOverrides as A, Ref as At, ReplyOptions as B, SchedulesQuery as Bt, channels as C, MessagesQueryInput as Ct, EventBase as D, PostInput as Dt, render as E, PostBody as Et, BoardClient as F, RouteName as Ft, Written as G, SourceJoinBody as Gt, ScheduleTiming as H, SchedulesQueryOutput as Ht, BoardError as I, ScheduleBody as It, ActorView as J, SourceReadQuery as Jt, duration as K, SourceMessage as Kt, Filters as L, ScheduleBodyOutput as Lt, SyncRoot as M, RegisterInput as Mt, envelope as N, RegistrationView as Nt, ProviderEvent as O, REGISTERED_WATCHERS_MAX as Ot, eventSchema as P, ResolvedSyncTarget as Pt, DeleteBody as Q, SyncCodeBody as Qt, PostOptions as R, ScheduleInput as Rt, SyncUnit as S, routes as Sn, MessagesQuery as St, mirror as T, PersonView as Tt, UploadInput as U, SignInQuery as Ut, ScheduleOptions as V, SchedulesQueryInput as Vt, WaitOptions as W, SourceJoin as Wt, BoardEventView as X, SyncAccountInput as Xt, ApiError as Y, SyncAccountBody as Yt, ChannelView as Z, SyncBody as Zt, withUserTokens as _, ThreadsQueryInput as _n, MatchView as _t, ProviderOptions as a, SyncImportBody as an, IdentityUnlinkBody as at, SyncIn as b, UploadStartBody as bn, MessageView as bt, ReceivedEvent as c, SyncReceiptInput as cn, InboxEntry as ct, ResolvedTarget as d, SyncUnlinkBody as dn, InboxPushBody as dt, SyncCopiesQuery as en, EditBody as et, SyncContext as f, SyncedView as fn, InboxQuery as ft, connectUserTokens as g, ThreadsQuery as gn, LinkedQuery as gt, UserTokens as h, ThreadsPage as hn, LinkedAccount as ht, ProviderFile as i, SyncFindView as in, FiltersInput as it, SyncResult as j, RegisterBody as jt, RootOverride as k, ReactBody as kt, RenderInput as l, SyncRootsQuery as ln, InboxItem as lt, UnreadableError as m, ThreadView as mn, LinkView as mt, FileDelivery as n, SyncFindInput as nn, EventsQuery as nt, ProviderPost as o, SyncImportInput as on, IdentityView as ot, SyncProvider as p, ThreadSummaryView as pn, LabelBody as pt, AckBody as q, SourceRead as qt, ProviderDelivery as r, SyncFindQuery as rn, EventsQueryInput as rt, Receive as s, SyncReceiptBody as sn, InboxAckBody as st, FetchedLink as t, SyncCopiesView as tn, EventsPage as tt, Renderer as u, SyncThreadView as un, InboxNextQuery as ut, Sync as v, TypingBody as vn, MatchesQuery as vt, into as w, ParsedFilters as wt, SyncOut as x, UploadTicket as xn, MessagesPage as xt, SyncFn as y, TypingResult as yn, Me as yt, ProfileOption as z, ScheduleView as zt };
|
|
@@ -188,6 +188,10 @@ var SyncProvider = class {
|
|
|
188
188
|
async read(_target, _options) {
|
|
189
189
|
throw new UnreadableError("unsupported", `${this.platform} can't be read on demand`);
|
|
190
190
|
}
|
|
191
|
+
/** Adds the board's app to a channel so `read` can read it, where the board opted in. Throws `UnreadableError` otherwise. */
|
|
192
|
+
async join(_target) {
|
|
193
|
+
throw new UnreadableError("unsupported", `${this.platform} can't join channels on demand`);
|
|
194
|
+
}
|
|
191
195
|
async edit(_thread, _message, _body) {}
|
|
192
196
|
async delete(_thread, _message) {}
|
|
193
197
|
async react(_thread, _message, _emoji, _added) {}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { o as localTokenFile } from "./backend-http-
|
|
2
|
-
import { t as board } from "./server-
|
|
3
|
-
import { t as oidcTokens } from "./tokens-
|
|
4
|
-
import { n as fsBlob, t as a2 } from "./a2-
|
|
1
|
+
import { o as localTokenFile } from "./backend-http-maHy-JW3.mjs";
|
|
2
|
+
import { t as board } from "./server-CuqhG9E6.mjs";
|
|
3
|
+
import { t as oidcTokens } from "./tokens-DUXaXwOj.mjs";
|
|
4
|
+
import { n as fsBlob, t as a2 } from "./a2-QtmN9EhW.mjs";
|
|
5
5
|
import { t as localScheduler } from "./local-DhkrAqPP.mjs";
|
|
6
6
|
import { mkdir, rm, writeFile } from "node:fs/promises";
|
|
7
7
|
import { userInfo } from "node:os";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as createBoard } from "./exports-
|
|
2
|
-
import { t as http } from "./backend-http-
|
|
1
|
+
import { t as createBoard } from "./exports-Dd8YdgO-.mjs";
|
|
2
|
+
import { t as http } from "./backend-http-maHy-JW3.mjs";
|
|
3
3
|
//#region src/server/index.ts
|
|
4
4
|
/**
|
|
5
5
|
* The handle on a board. With a `backend`, the board lives there: `a2()` keeps it in this
|
|
@@ -9,8 +9,8 @@ import { t as http } from "./backend-http-DMpQ750P.mjs";
|
|
|
9
9
|
function board(options = {}) {
|
|
10
10
|
return createBoard(options, {
|
|
11
11
|
http: () => http(),
|
|
12
|
-
sync: () => import("./engine-
|
|
13
|
-
serving: () => import("./serving-
|
|
12
|
+
sync: () => import("./engine-kHfSOXnQ.mjs"),
|
|
13
|
+
serving: () => import("./serving-B307gppu.mjs")
|
|
14
14
|
});
|
|
15
15
|
}
|
|
16
16
|
//#endregion
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as ownTeamId, n as discoveryIdentity, r as ownProjectId, t as oidcTokens } from "./tokens-
|
|
1
|
+
import { i as ownTeamId, n as discoveryIdentity, r as ownProjectId, t as oidcTokens } from "./tokens-DUXaXwOj.mjs";
|
|
2
2
|
export { discoveryIdentity, oidcTokens, ownProjectId, ownTeamId };
|
package/dist/sync-github.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as SyncUnit, _ as withUserTokens, d as ResolvedTarget, f as SyncContext, h as UserTokens, o as ProviderPost, r as ProviderDelivery, y as SyncFn } from "./provider-
|
|
2
|
-
import { n as ChatSyncProvider } from "./chat-provider-
|
|
1
|
+
import { S as SyncUnit, _ as withUserTokens, d as ResolvedTarget, f as SyncContext, h as UserTokens, o as ProviderPost, r as ProviderDelivery, y as SyncFn } from "./provider-D11Dfda0.mjs";
|
|
2
|
+
import { n as ChatSyncProvider } from "./chat-provider-D0k3y8zY.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { Adapter } from "chat";
|
|
5
5
|
//#region src/sync/github.d.ts
|
package/dist/sync-github.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { c as into, d as withRoutes } from "./provider-
|
|
1
|
+
import { c as into, d as withRoutes } from "./provider-poIkXapd.mjs";
|
|
2
2
|
import { i as eventSchema, r as envelope } from "./events-CewD4kw7.mjs";
|
|
3
3
|
import { r as withUserTokens, t as connectUserTokens } from "./users-yryHKFMo.mjs";
|
|
4
|
-
import { r as markdownOf, t as ChatSyncProvider } from "./chat-provider-
|
|
4
|
+
import { r as markdownOf, t as ChatSyncProvider } from "./chat-provider-DnHibqnM.mjs";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
import { connectGitHubAdapter } from "@vercel/connect/chat";
|
|
7
7
|
import { createGitHubAdapter } from "@chat-adapter/github";
|
package/dist/sync-kapso.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as SyncUnit, f as SyncContext, y as SyncFn } from "./provider-
|
|
2
|
-
import { n as ChatSyncProvider, t as ChatInput } from "./chat-provider-
|
|
1
|
+
import { S as SyncUnit, f as SyncContext, y as SyncFn } from "./provider-D11Dfda0.mjs";
|
|
2
|
+
import { n as ChatSyncProvider, t as ChatInput } from "./chat-provider-D0k3y8zY.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { Adapter } from "chat";
|
|
5
5
|
//#region src/sync/kapso.d.ts
|
package/dist/sync-kapso.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { s as channels } from "./provider-
|
|
1
|
+
import { s as channels } from "./provider-poIkXapd.mjs";
|
|
2
2
|
import { i as eventSchema, r as envelope } from "./events-CewD4kw7.mjs";
|
|
3
|
-
import { r as markdownOf, t as ChatSyncProvider } from "./chat-provider-
|
|
3
|
+
import { r as markdownOf, t as ChatSyncProvider } from "./chat-provider-DnHibqnM.mjs";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
//#region src/sync/kapso.ts
|
|
6
6
|
const decode = (id) => id.split(":").map((part) => Buffer.from(part, "base64url").toString("utf8")).join(":");
|
package/dist/sync-linear.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as SyncUnit, c as ReceivedEvent, d as ResolvedTarget, f as SyncContext, o as ProviderPost, r as ProviderDelivery, y as SyncFn } from "./provider-
|
|
2
|
-
import { n as ChatSyncProvider, t as ChatInput } from "./chat-provider-
|
|
1
|
+
import { S as SyncUnit, c as ReceivedEvent, d as ResolvedTarget, f as SyncContext, o as ProviderPost, r as ProviderDelivery, y as SyncFn } from "./provider-D11Dfda0.mjs";
|
|
2
|
+
import { n as ChatSyncProvider, t as ChatInput } from "./chat-provider-D0k3y8zY.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { Adapter } from "chat";
|
|
5
5
|
//#region src/sync/linear.d.ts
|
package/dist/sync-linear.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { i as UnreadableError, s as channels } from "./provider-
|
|
1
|
+
import { i as UnreadableError, s as channels } from "./provider-poIkXapd.mjs";
|
|
2
2
|
import { i as eventSchema, r as envelope } from "./events-CewD4kw7.mjs";
|
|
3
|
-
import { r as markdownOf, t as ChatSyncProvider } from "./chat-provider-
|
|
3
|
+
import { r as markdownOf, t as ChatSyncProvider } from "./chat-provider-DnHibqnM.mjs";
|
|
4
4
|
import "zod";
|
|
5
5
|
import { connectLinearAdapter } from "@vercel/connect/chat";
|
|
6
6
|
import { createLinearAdapter } from "@chat-adapter/linear";
|
package/dist/sync-slack.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { f as ExternalLink } from "./folds-CRYY14kc.mjs";
|
|
2
|
-
import { C as channels, _ as withUserTokens, d as ResolvedTarget, f as SyncContext, h as UserTokens, o as ProviderPost, r as ProviderDelivery, y as SyncFn } from "./provider-
|
|
3
|
-
import { n as ChatSyncProvider, t as ChatInput } from "./chat-provider-
|
|
2
|
+
import { C as channels, _ as withUserTokens, d as ResolvedTarget, f as SyncContext, h as UserTokens, o as ProviderPost, r as ProviderDelivery, y as SyncFn } from "./provider-D11Dfda0.mjs";
|
|
3
|
+
import { n as ChatSyncProvider, t as ChatInput } from "./chat-provider-D0k3y8zY.mjs";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
import { Adapter } from "chat";
|
|
6
6
|
//#region src/sync/slack.d.ts
|
|
@@ -46,6 +46,10 @@ export type SlackClient = {
|
|
|
46
46
|
messages?: SlackMessage[];
|
|
47
47
|
has_more?: boolean;
|
|
48
48
|
}>;
|
|
49
|
+
/** Adds the app to a public channel, for `vb sources <key> join`; needs `channels:join`. */
|
|
50
|
+
join?(args: {
|
|
51
|
+
channel: string;
|
|
52
|
+
}): Promise<unknown>;
|
|
49
53
|
};
|
|
50
54
|
users?: {
|
|
51
55
|
info(args: {
|
|
@@ -320,6 +324,11 @@ export type SlackOptions = {
|
|
|
320
324
|
adapter: Adapter | string;
|
|
321
325
|
/** Not needed with a connector. */
|
|
322
326
|
client?: () => Promise<SlackClient>;
|
|
327
|
+
/**
|
|
328
|
+
* Lets `vb sources <key> join` add the app to a public channel, so it can be read on demand
|
|
329
|
+
* without syncing it. Off by default; the app needs `channels:join`.
|
|
330
|
+
*/
|
|
331
|
+
join?: boolean;
|
|
323
332
|
};
|
|
324
333
|
/**
|
|
325
334
|
* Syncs a Slack workspace with the board: `app` is a Vercel Connect connector
|
package/dist/sync-slack.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { m as MESSAGE_TEXT_MAX } from "./schemas-Be08nyfW.mjs";
|
|
2
2
|
import "./external-BV_cUncs.mjs";
|
|
3
|
-
import { i as UnreadableError, s as channels } from "./provider-
|
|
3
|
+
import { i as UnreadableError, s as channels } from "./provider-poIkXapd.mjs";
|
|
4
4
|
import { i as eventSchema, r as envelope } from "./events-CewD4kw7.mjs";
|
|
5
5
|
import { r as withUserTokens, t as connectUserTokens } from "./users-yryHKFMo.mjs";
|
|
6
|
-
import { r as markdownOf, t as ChatSyncProvider } from "./chat-provider-
|
|
6
|
+
import { r as markdownOf, t as ChatSyncProvider } from "./chat-provider-DnHibqnM.mjs";
|
|
7
7
|
import { z } from "zod";
|
|
8
8
|
import { stringifyMarkdown } from "chat";
|
|
9
9
|
import { createSlackAdapter } from "@chat-adapter/slack";
|
|
@@ -318,6 +318,26 @@ var SlackProvider = class extends ChatSyncProvider {
|
|
|
318
318
|
if (!found) throw new UnreadableError("channel_not_found", publicOnly ? `no public Slack channel named #${name} (the app lacks groups:read, so a private channel needs its ID)` : `no Slack channel named #${name} (a private channel shows up once the app is invited)`);
|
|
319
319
|
return found;
|
|
320
320
|
}
|
|
321
|
+
async function targetOf(web, target) {
|
|
322
|
+
const link = new RegExp(PERMALINK.source).exec(target);
|
|
323
|
+
if (link) {
|
|
324
|
+
const [, id, seconds, micros, query] = link;
|
|
325
|
+
return {
|
|
326
|
+
channel: id,
|
|
327
|
+
thread: /[?&]thread_ts=(\d+\.\d+)/.exec(query?.replaceAll("&", "&") ?? "")?.[1] ?? `${seconds}.${micros}`
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
if (target.startsWith("#")) return {
|
|
331
|
+
channel: (await find(web, target.slice(1))).id,
|
|
332
|
+
thread: null
|
|
333
|
+
};
|
|
334
|
+
const parsed = /^([A-Z0-9]+)(?::(\d+\.\d+))?$/.exec(target);
|
|
335
|
+
if (!parsed) throw new UnreadableError("invalid_target", `not a Slack channel, thread, or message link: ${target} (try #name, C0123, C0123:1727000000.123456, or a permalink)`);
|
|
336
|
+
return {
|
|
337
|
+
channel: parsed[1],
|
|
338
|
+
thread: parsed[2] ?? null
|
|
339
|
+
};
|
|
340
|
+
}
|
|
321
341
|
const avatars = /* @__PURE__ */ new Map();
|
|
322
342
|
function avatarOf(user) {
|
|
323
343
|
let promise = avatars.get(user);
|
|
@@ -488,20 +508,9 @@ var SlackProvider = class extends ChatSyncProvider {
|
|
|
488
508
|
async read(target, { limit }) {
|
|
489
509
|
const web = await client();
|
|
490
510
|
if (!web) throw new UnreadableError("no_client", "no Slack client to read it with");
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
if (link) {
|
|
495
|
-
const [, id, seconds, micros, query] = link;
|
|
496
|
-
channel = id;
|
|
497
|
-
thread = /[?&]thread_ts=(\d+\.\d+)/.exec(query?.replaceAll("&", "&") ?? "")?.[1] ?? `${seconds}.${micros}`;
|
|
498
|
-
} else if (target.startsWith("#")) channel = (await find(web, target.slice(1))).id;
|
|
499
|
-
else {
|
|
500
|
-
const parsed = /^([A-Z0-9]+)(?::(\d+\.\d+))?$/.exec(target);
|
|
501
|
-
if (!parsed) throw new UnreadableError("invalid_target", `not a Slack channel, thread, or message link: ${target} (try #name, C0123, C0123:1727000000.123456, or a permalink)`);
|
|
502
|
-
channel = parsed[1];
|
|
503
|
-
thread = parsed[2] ?? null;
|
|
504
|
-
}
|
|
511
|
+
const parsed = await targetOf(web, target);
|
|
512
|
+
const channel = parsed.channel;
|
|
513
|
+
let thread = parsed.thread;
|
|
505
514
|
let found;
|
|
506
515
|
let more = false;
|
|
507
516
|
let name = null;
|
|
@@ -512,7 +521,7 @@ var SlackProvider = class extends ChatSyncProvider {
|
|
|
512
521
|
const label = name ? `#${name}` : channel;
|
|
513
522
|
if (info.is_private || info.is_im || info.is_mpim) throw new UnreadableError("private_channel", `${label} is private: the board only reads public channels on demand`);
|
|
514
523
|
if (info.is_ext_shared) throw new UnreadableError("shared_channel", `${label} is shared with another organization: the board doesn't read those on demand`);
|
|
515
|
-
if (!info.is_member) throw new UnreadableError("not_in_channel", `the app isn't in ${label}: someone needs to add it (it won't join on its own)`);
|
|
524
|
+
if (!info.is_member) throw new UnreadableError("not_in_channel", options.join ? `the app isn't in ${label}: join it first with \`vb sources <key> join ${label}\`, which adds the app there` : `the app isn't in ${label}: someone needs to add it (it won't join on its own)`);
|
|
516
525
|
if (thread) {
|
|
517
526
|
const replies = web.conversations.replies;
|
|
518
527
|
if (!replies) throw new UnreadableError("no_client", "this Slack client can't read threads");
|
|
@@ -562,6 +571,37 @@ var SlackProvider = class extends ChatSyncProvider {
|
|
|
562
571
|
more: more || found.length > limit
|
|
563
572
|
};
|
|
564
573
|
},
|
|
574
|
+
async join(target) {
|
|
575
|
+
if (!options.join) throw new UnreadableError("join_disabled", "this board doesn't join Slack channels: it needs `join: true` on slack()");
|
|
576
|
+
const web = await client();
|
|
577
|
+
if (!web) throw new UnreadableError("no_client", "no Slack client to join with");
|
|
578
|
+
const { channel } = await targetOf(web, target);
|
|
579
|
+
try {
|
|
580
|
+
const info = (await web.conversations.info({ channel })).channel;
|
|
581
|
+
if (!info) throw new UnreadableError("channel_not_found", `no Slack channel ${channel}`);
|
|
582
|
+
const name = info.name ?? null;
|
|
583
|
+
const label = name ? `#${name}` : channel;
|
|
584
|
+
if (info.is_private || info.is_im || info.is_mpim) throw new UnreadableError("private_channel", `${label} is private: the app can only be invited there`);
|
|
585
|
+
if (info.is_ext_shared) throw new UnreadableError("shared_channel", `${label} is shared with another organization: the board doesn't join those`);
|
|
586
|
+
if (info.is_member) return {
|
|
587
|
+
channel,
|
|
588
|
+
name,
|
|
589
|
+
joined: false
|
|
590
|
+
};
|
|
591
|
+
if (!web.conversations.join) throw new UnreadableError("no_client", "this Slack client can't join channels");
|
|
592
|
+
await web.conversations.join({ channel });
|
|
593
|
+
return {
|
|
594
|
+
channel,
|
|
595
|
+
name,
|
|
596
|
+
joined: true
|
|
597
|
+
};
|
|
598
|
+
} catch (error) {
|
|
599
|
+
if (error instanceof UnreadableError) throw error;
|
|
600
|
+
const code = slackError(error).split(",")[0];
|
|
601
|
+
if (code === "missing_scope") throw new UnreadableError(code, "the Slack app can't join channels: it needs the channels:join scope");
|
|
602
|
+
throw new UnreadableError(code, `Slack refused to join ${target}: ${slackError(error)}`);
|
|
603
|
+
}
|
|
604
|
+
},
|
|
565
605
|
intercept(key, _headers, body) {
|
|
566
606
|
let event;
|
|
567
607
|
try {
|
package/dist/sync.chat.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as externalAuthor, n as ChatSyncProvider, r as ChatTransport, t as ChatInput } from "./chat-provider-
|
|
1
|
+
import { i as externalAuthor, n as ChatSyncProvider, r as ChatTransport, t as ChatInput } from "./chat-provider-D0k3y8zY.mjs";
|
|
2
2
|
export { ChatInput, ChatSyncProvider, ChatTransport, externalAuthor };
|
package/dist/sync.chat.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as externalAuthor, t as ChatSyncProvider } from "./chat-provider-
|
|
1
|
+
import { n as externalAuthor, t as ChatSyncProvider } from "./chat-provider-DnHibqnM.mjs";
|
|
2
2
|
export { ChatSyncProvider, externalAuthor };
|
package/dist/sync.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { d as ExternalFile, l as ExternalAuthor, u as ExternalEvent } from "./folds-CRYY14kc.mjs";
|
|
2
|
-
import { A as SyncOverrides, C as channels, D as EventBase, E as render, M as SyncRoot, N as envelope, O as ProviderEvent, P as eventSchema, S as SyncUnit, T as mirror, _ as withUserTokens, a as ProviderOptions, b as SyncIn, c as ReceivedEvent, d as ResolvedTarget, f as SyncContext, g as connectUserTokens, h as UserTokens, i as ProviderFile, j as SyncResult, k as RootOverride, l as RenderInput, m as UnreadableError, n as FileDelivery, o as ProviderPost, p as SyncProvider, r as ProviderDelivery, s as Receive, u as Renderer, v as Sync, w as into, x as SyncOut, y as SyncFn } from "./provider-
|
|
2
|
+
import { A as SyncOverrides, C as channels, D as EventBase, E as render, M as SyncRoot, N as envelope, O as ProviderEvent, P as eventSchema, S as SyncUnit, T as mirror, _ as withUserTokens, a as ProviderOptions, b as SyncIn, c as ReceivedEvent, d as ResolvedTarget, f as SyncContext, g as connectUserTokens, h as UserTokens, i as ProviderFile, j as SyncResult, k as RootOverride, l as RenderInput, m as UnreadableError, n as FileDelivery, o as ProviderPost, p as SyncProvider, r as ProviderDelivery, s as Receive, u as Renderer, v as Sync, w as into, x as SyncOut, y as SyncFn } from "./provider-D11Dfda0.mjs";
|
|
3
3
|
export { EventBase, type ExternalAuthor, ExternalEvent, type ExternalFile, type FileDelivery, type ProviderDelivery, type ProviderEvent, type ProviderFile, type ProviderOptions, type ProviderPost, type Receive, ReceivedEvent, type RenderInput, type Renderer, ResolvedTarget, type RootOverride, type Sync, type SyncContext, type SyncFn, type SyncIn, type SyncOut, SyncOverrides, SyncProvider, type SyncResult, type SyncRoot, type SyncUnit, UnreadableError, type UserTokens, channels, connectUserTokens, envelope, eventSchema, into, mirror, render, withUserTokens };
|
package/dist/sync.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as ExternalEvent } from "./external-BV_cUncs.mjs";
|
|
2
|
-
import { c as into, i as UnreadableError, l as mirror, n as ResolvedTarget, r as SyncProvider, s as channels, t as ReceivedEvent, u as render } from "./provider-
|
|
2
|
+
import { c as into, i as UnreadableError, l as mirror, n as ResolvedTarget, r as SyncProvider, s as channels, t as ReceivedEvent, u as render } from "./provider-poIkXapd.mjs";
|
|
3
3
|
import { i as eventSchema, n as SyncOverrides, r as envelope, t as EventBase } from "./events-CewD4kw7.mjs";
|
|
4
4
|
import { r as withUserTokens, t as connectUserTokens } from "./users-yryHKFMo.mjs";
|
|
5
5
|
export { EventBase, ExternalEvent, ReceivedEvent, ResolvedTarget, SyncOverrides, SyncProvider, UnreadableError, channels, connectUserTokens, envelope, eventSchema, into, mirror, render, withUserTokens };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { l as unauthorized } from "./errors-
|
|
2
|
-
import { f as markVerified, m as trustedIssuers, n as TOKENS, r as VERCEL_ISSUER, u as issuerName } from "./auth-
|
|
1
|
+
import { l as unauthorized } from "./errors-CQ-fwxM3.mjs";
|
|
2
|
+
import { f as markVerified, m as trustedIssuers, n as TOKENS, r as VERCEL_ISSUER, u as issuerName } from "./auth-5nLsx9qB.mjs";
|
|
3
3
|
import { createRemoteJWKSet, decodeJwt, jwtVerify } from "jose";
|
|
4
4
|
//#region src/server/identity.ts
|
|
5
5
|
let fromDisk;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { n as DIRECT_UPLOAD_BYTES_MAX, t as ATTACHMENT_BYTES_MAX } from "./files-SniSmeEr.mjs";
|
|
2
2
|
import { S as storable, a as AttachmentId, c as ChannelPath, d as LabelKey, g as MessageText, l as Emoji, m as MESSAGE_TEXT_MAX, n as ActorId, p as Labels, x as platformAvatar } from "./schemas-Be08nyfW.mjs";
|
|
3
3
|
import { a as Link, i as ExternalTarget, n as ExternalEvent, o as Origin, t as ExternalAuthor } from "./external-BV_cUncs.mjs";
|
|
4
|
-
import { r as badRequest, t as HttpError } from "./errors-
|
|
4
|
+
import { r as badRequest, t as HttpError } from "./errors-CQ-fwxM3.mjs";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
//#region src/api/routes.ts
|
|
7
7
|
/**
|
|
@@ -114,22 +114,8 @@ const InboxQuery = z.object({
|
|
|
114
114
|
channel: z.string().optional(),
|
|
115
115
|
limit: z.coerce.number().int().min(1).max(500).optional()
|
|
116
116
|
});
|
|
117
|
-
/** What
|
|
118
|
-
const
|
|
119
|
-
/** Without one, or a `path`, the board pulls on its own instead of being woken. */
|
|
120
|
-
url: z.string().url().max(500).refine((url) => /^https:\/\//.test(url), "wake-ups go over https").transform((url) => url.replace(/\/+$/, "")).nullable().optional(),
|
|
121
|
-
/**
|
|
122
|
-
* Where to wake the caller on its own Vercel project, on a board whose discovery says
|
|
123
|
-
* `wake_by_path`. The board takes the project and environment from the caller's token and
|
|
124
|
-
* finds the deployment, so a project can only register itself, and anyone else gets 403
|
|
125
|
-
* `not_a_project`.
|
|
126
|
-
*/
|
|
127
|
-
path: z.string().max(300).regex(/^\/[^?#]*$/, "a path starts with / and has no query or fragment").transform((path) => path.replace(/(.)\/+$/, "$1")).nullable().optional(),
|
|
128
|
-
/**
|
|
129
|
-
* With a `path`, from a preview: the branch whose latest ready preview is woken, since a
|
|
130
|
-
* token says which project and environment called but not which deployment. Production names none.
|
|
131
|
-
*/
|
|
132
|
-
branch: z.string().min(1).max(255).nullable().optional(),
|
|
117
|
+
/** What every registration carries: its watchers' tails, and its sync entries. */
|
|
118
|
+
const Registering = z.object({
|
|
133
119
|
watch: z.record(z.string().max(100), z.object({
|
|
134
120
|
tail: z.string().max(1e3),
|
|
135
121
|
when: z.enum(["matches", "enters"]).default("matches")
|
|
@@ -143,13 +129,31 @@ const RegisterBody = z.object({
|
|
|
143
129
|
platform: z.string().min(1).max(64),
|
|
144
130
|
signIn: z.boolean().default(false)
|
|
145
131
|
})).max(32).optional()
|
|
146
|
-
}).refine((body) => !(body.url && body.path), {
|
|
147
|
-
message: "register a url or a path, not both",
|
|
148
|
-
path: ["path"]
|
|
149
|
-
}).refine((body) => !body.branch || body.path, {
|
|
150
|
-
message: "a branch goes with a path",
|
|
151
|
-
path: ["branch"]
|
|
152
132
|
});
|
|
133
|
+
/**
|
|
134
|
+
* What a board on `http()` registers with the board it uses: its watchers, and where to wake it,
|
|
135
|
+
* at a URL or at a path on its own project, never both.
|
|
136
|
+
*/
|
|
137
|
+
const RegisterBody = z.union([Registering.extend({
|
|
138
|
+
/** Without one, the board pulls on its own instead of being woken. */
|
|
139
|
+
url: z.string().url().max(500).refine((url) => /^https:\/\//.test(url), "wake-ups go over https").transform((url) => url.replace(/\/+$/, "")).nullable().optional(),
|
|
140
|
+
path: z.null({ error: "register a url or a path, not both" }).optional(),
|
|
141
|
+
branch: z.null({ error: "a branch goes with a path" }).optional()
|
|
142
|
+
}), Registering.extend({
|
|
143
|
+
url: z.null({ error: "register a url or a path, not both" }).optional(),
|
|
144
|
+
/**
|
|
145
|
+
* Where to wake the caller on its own Vercel project, on a board whose discovery says
|
|
146
|
+
* `wake_by_path`. The board takes the project and environment from the caller's token and
|
|
147
|
+
* finds the deployment, so a project can only register itself, and anyone else gets 403
|
|
148
|
+
* `not_a_project`.
|
|
149
|
+
*/
|
|
150
|
+
path: z.string().max(300).regex(/^\/[^?#]*$/, "a path starts with / and has no query or fragment").transform((path) => path.replace(/(.)\/+$/, "$1")),
|
|
151
|
+
/**
|
|
152
|
+
* From a preview: the branch whose latest ready preview is woken, since a token says which
|
|
153
|
+
* project and environment called but not which deployment. Production names none.
|
|
154
|
+
*/
|
|
155
|
+
branch: z.string().min(1).max(255).nullable().optional()
|
|
156
|
+
})]);
|
|
153
157
|
/** A pull of the caller's matches: at most `limit`, waiting up to `wait` seconds for one. */
|
|
154
158
|
const MatchesQuery = z.object({
|
|
155
159
|
limit: z.coerce.number().int().min(1).max(50).optional(),
|
|
@@ -169,6 +173,8 @@ const SourceReadQuery = z.object({
|
|
|
169
173
|
target: z.string().min(1).max(4e3),
|
|
170
174
|
limit: z.coerce.number().int().min(1).max(200).optional()
|
|
171
175
|
});
|
|
176
|
+
/** A channel to add the board's app to, so it can be read on demand: `#name`, an ID, or a link into it. */
|
|
177
|
+
const SourceJoinBody = z.object({ target: z.string().min(1).max(4e3) });
|
|
172
178
|
/** A platform's link to a message or thread, such as a Slack permalink or a GitHub comment's URL. */
|
|
173
179
|
const LinkedQuery = z.object({ url: z.string().url().max(4e3) });
|
|
174
180
|
const IdentityUnlinkBody = z.object({ actor: z.string().min(1).max(256) });
|
|
@@ -556,6 +562,12 @@ const routes = {
|
|
|
556
562
|
path: "/sources/:key/read",
|
|
557
563
|
query: SourceReadQuery
|
|
558
564
|
},
|
|
565
|
+
/** Adds the app to a public channel so it can be read, where that sync runs and opted in with `join`. Full access only. */
|
|
566
|
+
joinSource: {
|
|
567
|
+
method: "POST",
|
|
568
|
+
path: "/sources/:key/join",
|
|
569
|
+
body: SourceJoinBody
|
|
570
|
+
},
|
|
559
571
|
webhook: {
|
|
560
572
|
method: "POST",
|
|
561
573
|
path: "/webhooks/:key"
|
|
@@ -649,7 +661,7 @@ const routes = {
|
|
|
649
661
|
const SYNC = "@sync";
|
|
650
662
|
//#endregion
|
|
651
663
|
//#region src/version.ts
|
|
652
|
-
const VERSION = "0.
|
|
664
|
+
const VERSION = "0.20.1";
|
|
653
665
|
//#endregion
|
|
654
666
|
//#region src/server/routing.ts
|
|
655
667
|
/** board()'s own routes: the files it serves, and sync's, which run where board() does. */
|
|
@@ -705,6 +717,7 @@ const METHODS = [
|
|
|
705
717
|
"syncUnlink",
|
|
706
718
|
"typing",
|
|
707
719
|
"readSource",
|
|
720
|
+
"joinSource",
|
|
708
721
|
"synced",
|
|
709
722
|
"linked"
|
|
710
723
|
];
|
|
@@ -1007,4 +1020,4 @@ function canonicalWatchers(watch, sync = []) {
|
|
|
1007
1020
|
return JSON.stringify(canonical);
|
|
1008
1021
|
}
|
|
1009
1022
|
//#endregion
|
|
1010
|
-
export { ScheduleBody as A,
|
|
1023
|
+
export { ScheduleBody as A, SyncImportBody as B, LinkedQuery as C, ReactBody as D, PostBody as E, SyncAccountBody as F, TypingBody as G, SyncRootsQuery as H, SyncBody as I, UploadStartBody as K, SyncCodeBody as L, SignInQuery as M, SourceJoinBody as N, Ref as O, SourceReadQuery as P, SyncCopiesQuery as R, LabelBody as S, MessagesQuery as T, SyncUnlinkBody as U, SyncReceiptBody as V, ThreadsQuery as W, IdentityUnlinkBody as _, withMentions as a, InboxPushBody as b, openapi as c, readJson as d, VERSION as f, EventsQuery as g, EditBody as h, FILTER_FLAGS as i, SchedulesQuery as j, RegisterBody as k, queryObject as l, AckBody as m, compileWatcher as n, METHODS as o, SYNC as p, routes as q, hasCriteria as r, createRouter as s, canonicalWatchers as t, readCapped as u, InboxAckBody as v, MatchesQuery as w, InboxQuery as x, InboxNextQuery as y, SyncFindQuery as z };
|