@larc-iu/plaid-client 0.2.0-alpha.16 → 0.2.0-alpha.18
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/index.d.ts +409 -65
- package/package.json +1 -1
- package/src/created.js +29 -0
- package/src/documentLock.js +14 -9
- package/src/events.js +256 -0
- package/src/http.js +168 -56
- package/src/index.js +495 -208
- package/src/metadataOps.js +117 -0
- package/src/provenance.js +7 -17
- package/src/requester.js +56 -0
- package/src/services.js +62 -7
- package/src/sse.js +29 -3
- package/src/transforms.js +7 -1
package/index.d.ts
CHANGED
|
@@ -77,7 +77,8 @@ interface ServiceRegistration {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
/** Connection-state transitions reported by a service registration. */
|
|
80
|
-
|
|
80
|
+
/** "stopped": the server refused the channel for a reason retrying cannot fix (a revoked token, no write access, no such project), which ends the registration. */
|
|
81
|
+
type ServiceStatusEvent = "registered" | "reconnected" | "disconnected" | "stopped";
|
|
81
82
|
|
|
82
83
|
interface ResponseHelper {
|
|
83
84
|
requestId: string;
|
|
@@ -105,6 +106,26 @@ export class ServiceCancelled extends Error {
|
|
|
105
106
|
constructor(message?: string);
|
|
106
107
|
}
|
|
107
108
|
|
|
109
|
+
/** The key a run's stored record names its requester under. */
|
|
110
|
+
export const REQUESTED_BY: "requestedBy";
|
|
111
|
+
|
|
112
|
+
/** The person who asked for one service run. Both fields are null when nobody asked. */
|
|
113
|
+
export interface Requester {
|
|
114
|
+
id: string | null;
|
|
115
|
+
name: string | null;
|
|
116
|
+
/** `"<text>, requested by <name>"`, or `text` when nobody asked. */
|
|
117
|
+
label(text: string): string;
|
|
118
|
+
/** `{ id, name }` for a stored report, or null when nobody asked. */
|
|
119
|
+
record(): { id: string; name: string | null } | null;
|
|
120
|
+
/** A machine stamp's `provDetail` with `requestedBy: <id>` added. */
|
|
121
|
+
detail(detail?: Record<string, any>): Record<string, any>;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export function makeRequester(id?: string | null, name?: string | null): Requester;
|
|
125
|
+
|
|
126
|
+
/** The requester of one request, from the `requesterId` in a `serve` handler's data, named by display name. */
|
|
127
|
+
export function requesterOf(client: { users: { get(id: string): Promise<any> } }, data: any): Promise<Requester>;
|
|
128
|
+
|
|
108
129
|
/** The cancellation half of a responseHelper, on its own. */
|
|
109
130
|
export function createCancelScope(isCancelled: () => boolean): {
|
|
110
131
|
readonly cancelled: boolean;
|
|
@@ -116,6 +137,11 @@ interface SSEConnection {
|
|
|
116
137
|
close(): void;
|
|
117
138
|
getStats(): any;
|
|
118
139
|
readyState: number;
|
|
140
|
+
/**
|
|
141
|
+
* Once CLOSED, why: null when this side closed it. A refused stream's error
|
|
142
|
+
* carries the HTTP `status`, and one the server ended is named "StreamClosed".
|
|
143
|
+
*/
|
|
144
|
+
error: (Error & { status?: number }) | null;
|
|
119
145
|
}
|
|
120
146
|
|
|
121
147
|
interface VocabLinksBundle {
|
|
@@ -129,13 +155,45 @@ interface VocabLinksBundle {
|
|
|
129
155
|
bulkDelete(body: any[], auditMessage?: string): Promise<void>;
|
|
130
156
|
setMetadata(id: string, body: any, auditMessage?: string): Promise<any>;
|
|
131
157
|
deleteMetadata(id: string, auditMessage?: string): Promise<any>;
|
|
132
|
-
patchMetadata(id: string, body:
|
|
133
|
-
get(id: string
|
|
158
|
+
patchMetadata(id: string, body: MetadataOp[], auditMessage?: string): Promise<any>;
|
|
159
|
+
get(id: string): Promise<any>;
|
|
134
160
|
delete(id: string, auditMessage?: string): Promise<any>;
|
|
135
161
|
}
|
|
136
162
|
|
|
163
|
+
/** What `vocabLayers.restoreItem` did, or with `dryRun` would do. */
|
|
164
|
+
interface VocabItemRestoreSummary {
|
|
165
|
+
/** The entry was gone and came back under its old id. */
|
|
166
|
+
inserted: boolean;
|
|
167
|
+
/** A living entry's form was set back. */
|
|
168
|
+
form: boolean;
|
|
169
|
+
/** A living entry's fields were set back. */
|
|
170
|
+
metadata: boolean;
|
|
171
|
+
/** 0 when nothing changes. */
|
|
172
|
+
total: number;
|
|
173
|
+
}
|
|
174
|
+
|
|
137
175
|
interface VocabLayersBundle {
|
|
176
|
+
/** `asOf` reads the vocabulary as it was at that instant. */
|
|
138
177
|
get(id: string, includeItems?: boolean, asOf?: string): Promise<any>;
|
|
178
|
+
/** One entry as it was at `asOf`, also when it has been deleted since. */
|
|
179
|
+
getItemAt(id: string, itemId: string, asOf: string): Promise<any>;
|
|
180
|
+
/** `itemId` keeps only the changes that wrote that one entry. */
|
|
181
|
+
audit(
|
|
182
|
+
id: string,
|
|
183
|
+
startTime?: string,
|
|
184
|
+
endTime?: string,
|
|
185
|
+
opTypes?: string[] | string,
|
|
186
|
+
itemId?: string,
|
|
187
|
+
): Promise<any[]>;
|
|
188
|
+
auditPage(id: string, opts?: AuditPageOptions & { itemId?: string }): Promise<Page>;
|
|
189
|
+
/** Put one entry back as it was at `asOf`. Maintainers of the vocabulary only. */
|
|
190
|
+
restoreItem(
|
|
191
|
+
id: string,
|
|
192
|
+
itemId: string,
|
|
193
|
+
asOf: string,
|
|
194
|
+
options?: { dryRun?: boolean },
|
|
195
|
+
auditMessage?: string,
|
|
196
|
+
): Promise<VocabItemRestoreSummary>;
|
|
139
197
|
delete(id: string, auditMessage?: string): Promise<any>;
|
|
140
198
|
update(id: string, name: string, auditMessage?: string): Promise<any>;
|
|
141
199
|
setConfig(
|
|
@@ -151,13 +209,9 @@ interface VocabLayersBundle {
|
|
|
151
209
|
configKey: string,
|
|
152
210
|
auditMessage?: string,
|
|
153
211
|
): Promise<any>;
|
|
154
|
-
list(
|
|
155
|
-
listPage(opts?: {
|
|
156
|
-
|
|
157
|
-
cursor?: string;
|
|
158
|
-
asOf?: string;
|
|
159
|
-
}): Promise<Page>;
|
|
160
|
-
iterPages(opts?: { pageSize?: number; asOf?: string }): AsyncGenerator<any[]>;
|
|
212
|
+
list(): Promise<any[]>;
|
|
213
|
+
listPage(opts?: { limit?: number; cursor?: string }): Promise<Page>;
|
|
214
|
+
iterPages(opts?: { pageSize?: number }): AsyncGenerator<any[]>;
|
|
161
215
|
create(name: string, auditMessage?: string): Promise<any>;
|
|
162
216
|
addMaintainer(
|
|
163
217
|
id: string,
|
|
@@ -180,7 +234,7 @@ interface RelationsBundle {
|
|
|
180
234
|
deleteMetadata(relationId: string, auditMessage?: string): Promise<any>;
|
|
181
235
|
patchMetadata(
|
|
182
236
|
relationId: string,
|
|
183
|
-
body:
|
|
237
|
+
body: MetadataOp[],
|
|
184
238
|
auditMessage?: string,
|
|
185
239
|
): Promise<any>;
|
|
186
240
|
setTarget(
|
|
@@ -188,7 +242,7 @@ interface RelationsBundle {
|
|
|
188
242
|
spanId: string,
|
|
189
243
|
auditMessage?: string,
|
|
190
244
|
): Promise<any>;
|
|
191
|
-
get(relationId: string
|
|
245
|
+
get(relationId: string): Promise<any>;
|
|
192
246
|
delete(relationId: string, auditMessage?: string): Promise<any>;
|
|
193
247
|
update(relationId: string, value: any, auditMessage?: string): Promise<any>;
|
|
194
248
|
setSource(
|
|
@@ -223,7 +277,7 @@ interface SpanLayersBundle {
|
|
|
223
277
|
configKey: string,
|
|
224
278
|
auditMessage?: string,
|
|
225
279
|
): Promise<any>;
|
|
226
|
-
get(spanLayerId: string
|
|
280
|
+
get(spanLayerId: string): Promise<any>;
|
|
227
281
|
delete(spanLayerId: string, auditMessage?: string): Promise<any>;
|
|
228
282
|
update(
|
|
229
283
|
spanLayerId: string,
|
|
@@ -251,7 +305,7 @@ interface SpansBundle {
|
|
|
251
305
|
metadata?: any,
|
|
252
306
|
auditMessage?: string,
|
|
253
307
|
): Promise<any>;
|
|
254
|
-
get(spanId: string
|
|
308
|
+
get(spanId: string): Promise<any>;
|
|
255
309
|
delete(spanId: string, auditMessage?: string): Promise<any>;
|
|
256
310
|
update(spanId: string, value: any, auditMessage?: string): Promise<any>;
|
|
257
311
|
bulkCreate(body: any[], auditMessage?: string): Promise<{ ids: string[] }>;
|
|
@@ -259,13 +313,13 @@ interface SpansBundle {
|
|
|
259
313
|
bulkUpdate(body: any[], auditMessage?: string): Promise<{ count: number }>;
|
|
260
314
|
setMetadata(spanId: string, body: any, auditMessage?: string): Promise<any>;
|
|
261
315
|
deleteMetadata(spanId: string, auditMessage?: string): Promise<any>;
|
|
262
|
-
patchMetadata(spanId: string, body:
|
|
316
|
+
patchMetadata(spanId: string, body: MetadataOp[], auditMessage?: string): Promise<any>;
|
|
263
317
|
}
|
|
264
318
|
|
|
265
319
|
interface TextsBundle {
|
|
266
320
|
setMetadata(textId: string, body: any, auditMessage?: string): Promise<any>;
|
|
267
321
|
deleteMetadata(textId: string, auditMessage?: string): Promise<any>;
|
|
268
|
-
patchMetadata(textId: string, body:
|
|
322
|
+
patchMetadata(textId: string, body: MetadataOp[], auditMessage?: string): Promise<any>;
|
|
269
323
|
create(
|
|
270
324
|
textLayerId: string,
|
|
271
325
|
documentId: string,
|
|
@@ -273,19 +327,16 @@ interface TextsBundle {
|
|
|
273
327
|
metadata?: any,
|
|
274
328
|
auditMessage?: string,
|
|
275
329
|
): Promise<any>;
|
|
276
|
-
get(textId: string
|
|
330
|
+
get(textId: string): Promise<any>;
|
|
277
331
|
delete(textId: string, auditMessage?: string): Promise<any>;
|
|
278
332
|
update(textId: string, body: any, auditMessage?: string): Promise<any>;
|
|
279
333
|
}
|
|
280
334
|
|
|
281
335
|
interface UsersBundle {
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
asOf?: string;
|
|
287
|
-
}): Promise<Page>;
|
|
288
|
-
iterPages(opts?: { pageSize?: number; asOf?: string }): AsyncGenerator<any[]>;
|
|
336
|
+
/** `q` narrows to users whose id or display name contains it (admin or maintainer). */
|
|
337
|
+
list(opts?: { q?: string }): Promise<any[]>;
|
|
338
|
+
listPage(opts?: { q?: string; limit?: number; cursor?: string }): Promise<Page>;
|
|
339
|
+
iterPages(opts?: { q?: string; pageSize?: number }): AsyncGenerator<any[]>;
|
|
289
340
|
create(
|
|
290
341
|
email: string,
|
|
291
342
|
password: string,
|
|
@@ -297,10 +348,10 @@ interface UsersBundle {
|
|
|
297
348
|
userId: string,
|
|
298
349
|
startTime?: string,
|
|
299
350
|
endTime?: string,
|
|
300
|
-
|
|
351
|
+
opTypes?: string[] | string,
|
|
301
352
|
): Promise<any[]>;
|
|
302
353
|
auditPage(userId: string, opts?: AuditPageOptions): Promise<Page>;
|
|
303
|
-
get(id: string
|
|
354
|
+
get(id: string): Promise<any>;
|
|
304
355
|
delete(id: string, auditMessage?: string): Promise<any>;
|
|
305
356
|
activate(id: string, auditMessage?: string): Promise<any>;
|
|
306
357
|
update(
|
|
@@ -440,6 +491,65 @@ interface Comment {
|
|
|
440
491
|
edited: boolean;
|
|
441
492
|
}
|
|
442
493
|
|
|
494
|
+
/** A research-telemetry event type (core manual, "Research telemetry"). */
|
|
495
|
+
type ClientEventType =
|
|
496
|
+
| "suggestion.shown"
|
|
497
|
+
| "suggestion.adopted"
|
|
498
|
+
| "suggestion.dismissed"
|
|
499
|
+
| "plan.opened";
|
|
500
|
+
|
|
501
|
+
interface ClientEventFields {
|
|
502
|
+
projectId: string;
|
|
503
|
+
documentId?: string;
|
|
504
|
+
targetId?: string;
|
|
505
|
+
/** Keyed by single lowercase words: value, source, field, written, conversation. */
|
|
506
|
+
data?: Record<string, any>;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
interface ClientEvent {
|
|
510
|
+
id: number;
|
|
511
|
+
projectId: string;
|
|
512
|
+
documentId: string | null;
|
|
513
|
+
userId: string;
|
|
514
|
+
type: ClientEventType;
|
|
515
|
+
targetId: string | null;
|
|
516
|
+
data: Record<string, any> | null;
|
|
517
|
+
clientTs: string | null;
|
|
518
|
+
ts: string;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
interface ClientEventFilters {
|
|
522
|
+
types?: ClientEventType | ClientEventType[] | string;
|
|
523
|
+
startTime?: string;
|
|
524
|
+
endTime?: string;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
interface EventsBundle {
|
|
528
|
+
/** Buffer one event; never throws. False when not recorded (switch off, a repeat shown). */
|
|
529
|
+
record(type: ClientEventType, fields: ClientEventFields): boolean;
|
|
530
|
+
flush(): void;
|
|
531
|
+
setEnabled(projectId: string, on: boolean): void;
|
|
532
|
+
create(
|
|
533
|
+
projectId: string,
|
|
534
|
+
events: Array<{
|
|
535
|
+
type: ClientEventType;
|
|
536
|
+
documentId?: string;
|
|
537
|
+
targetId?: string;
|
|
538
|
+
data?: Record<string, any>;
|
|
539
|
+
clientTs?: string;
|
|
540
|
+
}>,
|
|
541
|
+
): Promise<{ count: number }>;
|
|
542
|
+
list(projectId: string, filters?: ClientEventFilters): Promise<ClientEvent[]>;
|
|
543
|
+
listPage(
|
|
544
|
+
projectId: string,
|
|
545
|
+
opts?: ClientEventFilters & { limit?: number; cursor?: string },
|
|
546
|
+
): Promise<Page<ClientEvent>>;
|
|
547
|
+
iterPages(
|
|
548
|
+
projectId: string,
|
|
549
|
+
opts?: ClientEventFilters & { pageSize?: number },
|
|
550
|
+
): AsyncGenerator<ClientEvent[]>;
|
|
551
|
+
}
|
|
552
|
+
|
|
443
553
|
interface CommentsBundle {
|
|
444
554
|
create(
|
|
445
555
|
entityType: CommentableType,
|
|
@@ -473,6 +583,10 @@ interface CommentsBundle {
|
|
|
473
583
|
vocabId: string,
|
|
474
584
|
opts?: { entityId?: string; limit?: number; cursor?: string },
|
|
475
585
|
): Promise<Page<Comment>>;
|
|
586
|
+
iterInVocabPages(
|
|
587
|
+
vocabId: string,
|
|
588
|
+
opts?: { entityId?: string; pageSize?: number },
|
|
589
|
+
): AsyncGenerator<Comment[]>;
|
|
476
590
|
/** `{entryId: count}` over a vocabulary; keys are raw entry ids. */
|
|
477
591
|
countsInVocab(
|
|
478
592
|
vocabId: string,
|
|
@@ -552,6 +666,12 @@ interface ServerLimits {
|
|
|
552
666
|
metadataStringLength?: number;
|
|
553
667
|
metadataTotalBytes?: number;
|
|
554
668
|
userDataValueBytes?: number;
|
|
669
|
+
guidelineTitleLength?: number;
|
|
670
|
+
guidelineBodyLength?: number;
|
|
671
|
+
/** The shortest password the server accepts on any path. */
|
|
672
|
+
passwordMinLength?: number;
|
|
673
|
+
/** How long a document lock is held before it lapses. */
|
|
674
|
+
lockExpirationMs?: number;
|
|
555
675
|
}
|
|
556
676
|
|
|
557
677
|
interface ServerHealth {
|
|
@@ -561,7 +681,8 @@ interface ServerHealth {
|
|
|
561
681
|
audit: { dbSizeMb?: number; auditRows?: number; error?: string };
|
|
562
682
|
}
|
|
563
683
|
|
|
564
|
-
|
|
684
|
+
/** A document lock as the admin lock listing reports it. */
|
|
685
|
+
interface DocumentLockInfo {
|
|
565
686
|
documentId: string;
|
|
566
687
|
userId: string;
|
|
567
688
|
expiresAt: number;
|
|
@@ -620,6 +741,15 @@ interface ServerReport {
|
|
|
620
741
|
settings: Record<string, any>;
|
|
621
742
|
}
|
|
622
743
|
|
|
744
|
+
/** The signed-in user's sign-ins. Signing in is `PlaidClient.login`. */
|
|
745
|
+
interface AuthBundle {
|
|
746
|
+
/**
|
|
747
|
+
* End every sign-in of this user on every device, this client's included.
|
|
748
|
+
* Named API tokens are not affected. Goes out at once even on a batch.
|
|
749
|
+
*/
|
|
750
|
+
logoutEverywhere(): Promise<void>;
|
|
751
|
+
}
|
|
752
|
+
|
|
623
753
|
/** Server-level facts. `info` is fetched at most once per client. */
|
|
624
754
|
interface ServerBundle {
|
|
625
755
|
info(): Promise<{ limits: ServerLimits }>;
|
|
@@ -631,7 +761,7 @@ interface ServerBundle {
|
|
|
631
761
|
interface AdminBundle {
|
|
632
762
|
server(): Promise<ServerReport>;
|
|
633
763
|
backup(): Promise<BackupStatus>;
|
|
634
|
-
locks(): Promise<{ entries:
|
|
764
|
+
locks(): Promise<{ entries: DocumentLockInfo[] }>;
|
|
635
765
|
releaseLock(documentId: string): Promise<{ result: string }>;
|
|
636
766
|
rateLimits(): Promise<RateLimitSnapshot>;
|
|
637
767
|
clearRateLimits(opts?: {
|
|
@@ -735,7 +865,6 @@ type AdminUserDataEntry = UserDataEntry & { userId: string };
|
|
|
735
865
|
interface AuditPageOptions {
|
|
736
866
|
startTime?: string;
|
|
737
867
|
endTime?: string;
|
|
738
|
-
asOf?: string;
|
|
739
868
|
opTypes?: string[] | string;
|
|
740
869
|
/** "desc" pages newest-first; a cursor belongs to the direction that made it. */
|
|
741
870
|
order?: "asc" | "desc";
|
|
@@ -827,7 +956,7 @@ interface TokenLayersBundle {
|
|
|
827
956
|
configKey: string,
|
|
828
957
|
auditMessage?: string,
|
|
829
958
|
): Promise<any>;
|
|
830
|
-
get(tokenLayerId: string
|
|
959
|
+
get(tokenLayerId: string): Promise<any>;
|
|
831
960
|
delete(tokenLayerId: string, auditMessage?: string): Promise<any>;
|
|
832
961
|
update(
|
|
833
962
|
tokenLayerId: string,
|
|
@@ -839,6 +968,8 @@ interface TokenLayersBundle {
|
|
|
839
968
|
/** Handle passed to a `documents.locked()` block. */
|
|
840
969
|
export declare class DocumentLock {
|
|
841
970
|
readonly documentId: string;
|
|
971
|
+
/** The holder id the acquire answered with. */
|
|
972
|
+
readonly lockId: string | null;
|
|
842
973
|
/** The DocumentLockLost if the lock lapsed, else null. */
|
|
843
974
|
readonly lost: DocumentLockLost | null;
|
|
844
975
|
/** Throw if the lock lapsed; call it between steps that have not written. */
|
|
@@ -856,13 +987,24 @@ export declare class DocumentLockLost extends Error {
|
|
|
856
987
|
export const DOCUMENT_LOCK_TTL_MS: 60000;
|
|
857
988
|
|
|
858
989
|
interface DocumentsBundle {
|
|
859
|
-
checkLock(documentId: string
|
|
990
|
+
checkLock(documentId: string): Promise<any>;
|
|
991
|
+
/** Take the lock as a new holder. The answer's `lockId` names it. */
|
|
860
992
|
acquireLock(documentId: string, auditMessage?: string): Promise<any>;
|
|
861
|
-
|
|
993
|
+
/** Renew `lockId`'s lock while it is live. 423 once it has lapsed. */
|
|
994
|
+
renewLock(
|
|
995
|
+
documentId: string,
|
|
996
|
+
lockId: string,
|
|
997
|
+
auditMessage?: string,
|
|
998
|
+
): Promise<any>;
|
|
999
|
+
releaseLock(
|
|
1000
|
+
documentId: string,
|
|
1001
|
+
lockId: string,
|
|
1002
|
+
auditMessage?: string,
|
|
1003
|
+
): Promise<any>;
|
|
862
1004
|
/**
|
|
863
1005
|
* Hold the document's lock for the length of `fn`, renewing it while `fn`
|
|
864
|
-
* runs and releasing it on the way out. Rejects with a 423 if
|
|
865
|
-
*
|
|
1006
|
+
* runs and releasing it on the way out. Rejects with a 423 if it is already
|
|
1007
|
+
* held, and with DocumentLockLost if a renewal fails.
|
|
866
1008
|
*/
|
|
867
1009
|
locked<T>(
|
|
868
1010
|
documentId: string,
|
|
@@ -888,17 +1030,26 @@ interface DocumentsBundle {
|
|
|
888
1030
|
deleteMetadata(documentId: string, auditMessage?: string): Promise<any>;
|
|
889
1031
|
patchMetadata(
|
|
890
1032
|
documentId: string,
|
|
891
|
-
body:
|
|
1033
|
+
body: MetadataOp[],
|
|
892
1034
|
auditMessage?: string,
|
|
893
1035
|
): Promise<any>;
|
|
894
1036
|
audit(
|
|
895
1037
|
documentId: string,
|
|
896
1038
|
startTime?: string,
|
|
897
1039
|
endTime?: string,
|
|
898
|
-
|
|
1040
|
+
opTypes?: string[] | string,
|
|
899
1041
|
): Promise<any[]>;
|
|
900
1042
|
auditPage(documentId: string, opts?: AuditPageOptions): Promise<Page>;
|
|
901
|
-
|
|
1043
|
+
/**
|
|
1044
|
+
* `asOf` reads the document as it was at that instant. `layers` narrows a
|
|
1045
|
+
* body read to the named layers (ids of any kind), and needs `includeBody`.
|
|
1046
|
+
*/
|
|
1047
|
+
get(
|
|
1048
|
+
documentId: string,
|
|
1049
|
+
includeBody?: boolean,
|
|
1050
|
+
asOf?: string,
|
|
1051
|
+
layers?: string[] | string,
|
|
1052
|
+
): Promise<any>;
|
|
902
1053
|
delete(documentId: string, auditMessage?: string): Promise<any>;
|
|
903
1054
|
update(documentId: string, name: string, auditMessage?: string): Promise<any>;
|
|
904
1055
|
create(
|
|
@@ -923,11 +1074,8 @@ interface DocumentsBundle {
|
|
|
923
1074
|
}
|
|
924
1075
|
|
|
925
1076
|
interface MessagesBundle {
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
data: any,
|
|
929
|
-
auditMessage?: string,
|
|
930
|
-
): Promise<any>;
|
|
1077
|
+
/** Broadcast to the project's listeners. Never saved and never part of an operation. */
|
|
1078
|
+
sendMessage(projectId: string, data: any): Promise<any>;
|
|
931
1079
|
listen(
|
|
932
1080
|
projectId: string,
|
|
933
1081
|
onEvent: (eventType: string, data: any) => void | boolean,
|
|
@@ -964,7 +1112,35 @@ interface MessagesBundle {
|
|
|
964
1112
|
timeout?: number,
|
|
965
1113
|
onProgress?: (progress: any) => void,
|
|
966
1114
|
signal?: AbortSignal,
|
|
1115
|
+
opts?: {
|
|
1116
|
+
/** A request id you mint, so you know it before submitting; resubmitting one rejoins that request. */
|
|
1117
|
+
requestId?: string;
|
|
1118
|
+
/** Called with the request id as soon as the server has taken the request. */
|
|
1119
|
+
onAccepted?: (requestId: string) => void;
|
|
1120
|
+
/** Other projects the request is about. A delegating service's token reaches `projectId` and those of these the requester can read, nothing else. */
|
|
1121
|
+
projectIds?: string[];
|
|
1122
|
+
/** Carry no open operation: the service's writes are a group of their own, not part of whatever operation this client has open. */
|
|
1123
|
+
noOperation?: boolean;
|
|
1124
|
+
},
|
|
1125
|
+
): Promise<any>;
|
|
1126
|
+
/**
|
|
1127
|
+
* Rejoin a request made earlier: the latest progress is replayed, then the
|
|
1128
|
+
* result, or at once if it already finished. Only its submitter (or an
|
|
1129
|
+
* admin). Rejects with a 404 when the request is unknown or expired.
|
|
1130
|
+
*/
|
|
1131
|
+
attachServiceRequest(
|
|
1132
|
+
projectId: string,
|
|
1133
|
+
requestId: string,
|
|
1134
|
+
timeout?: number,
|
|
1135
|
+
onProgress?: (progress: any) => void,
|
|
1136
|
+
signal?: AbortSignal,
|
|
967
1137
|
): Promise<any>;
|
|
1138
|
+
/**
|
|
1139
|
+
* Ask the service to stop a request made earlier. The request still ends
|
|
1140
|
+
* with whatever the service then reports. 404 if unknown or expired, 409
|
|
1141
|
+
* once finished.
|
|
1142
|
+
*/
|
|
1143
|
+
cancelServiceRequest(projectId: string, requestId: string): Promise<void>;
|
|
968
1144
|
}
|
|
969
1145
|
|
|
970
1146
|
interface ProjectsBundle {
|
|
@@ -999,12 +1175,18 @@ interface ProjectsBundle {
|
|
|
999
1175
|
projectId: string,
|
|
1000
1176
|
startTime?: string,
|
|
1001
1177
|
endTime?: string,
|
|
1002
|
-
|
|
1178
|
+
opTypes?: string[] | string,
|
|
1003
1179
|
): Promise<any[]>;
|
|
1004
1180
|
auditPage(projectId: string, opts?: AuditPageOptions): Promise<Page>;
|
|
1181
|
+
/**
|
|
1182
|
+
* When the calling user last wrote to each document of the project, as a
|
|
1183
|
+
* `{documentId: timestamp}` map; documents they never wrote to are absent.
|
|
1184
|
+
* The keys are document ids, so the response is not key-transformed.
|
|
1185
|
+
*/
|
|
1186
|
+
myLastEdits(projectId: string): Promise<Record<string, string>>;
|
|
1005
1187
|
linkVocab(id: string, vocabId: string, auditMessage?: string): Promise<any>;
|
|
1006
1188
|
unlinkVocab(id: string, vocabId: string, auditMessage?: string): Promise<any>;
|
|
1007
|
-
get(id: string
|
|
1189
|
+
get(id: string): Promise<any>;
|
|
1008
1190
|
listDocuments(id: string): Promise<any[]>;
|
|
1009
1191
|
listDocumentsPage(
|
|
1010
1192
|
id: string,
|
|
@@ -1014,15 +1196,16 @@ interface ProjectsBundle {
|
|
|
1014
1196
|
id: string,
|
|
1015
1197
|
opts?: { pageSize?: number },
|
|
1016
1198
|
): AsyncGenerator<any[]>;
|
|
1017
|
-
delete(id: string, auditMessage?: string): Promise<any>;
|
|
1018
1199
|
update(id: string, name: string, auditMessage?: string): Promise<any>;
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1200
|
+
/** The project is gone when this returns, and what it holds is removed on the server afterwards. The timeout defaults to the client's. */
|
|
1201
|
+
delete(
|
|
1202
|
+
id: string,
|
|
1203
|
+
auditMessage?: string,
|
|
1204
|
+
options?: { timeout?: number | null },
|
|
1205
|
+
): Promise<any>;
|
|
1206
|
+
list(): Promise<any[]>;
|
|
1207
|
+
listPage(opts?: { limit?: number; cursor?: string }): Promise<Page>;
|
|
1208
|
+
iterPages(opts?: { pageSize?: number }): AsyncGenerator<any[]>;
|
|
1026
1209
|
create(name: string, auditMessage?: string): Promise<any>;
|
|
1027
1210
|
}
|
|
1028
1211
|
|
|
@@ -1040,7 +1223,7 @@ interface TextLayersBundle {
|
|
|
1040
1223
|
configKey: string,
|
|
1041
1224
|
auditMessage?: string,
|
|
1042
1225
|
): Promise<any>;
|
|
1043
|
-
get(textLayerId: string
|
|
1226
|
+
get(textLayerId: string): Promise<any>;
|
|
1044
1227
|
delete(textLayerId: string, auditMessage?: string): Promise<any>;
|
|
1045
1228
|
update(
|
|
1046
1229
|
textLayerId: string,
|
|
@@ -1058,7 +1241,7 @@ interface TextLayersBundle {
|
|
|
1058
1241
|
interface VocabItemsBundle {
|
|
1059
1242
|
setMetadata(id: string, body: any, auditMessage?: string): Promise<any>;
|
|
1060
1243
|
deleteMetadata(id: string, auditMessage?: string): Promise<any>;
|
|
1061
|
-
patchMetadata(id: string, body:
|
|
1244
|
+
patchMetadata(id: string, body: MetadataOp[], auditMessage?: string): Promise<any>;
|
|
1062
1245
|
create(
|
|
1063
1246
|
vocabLayerId: string,
|
|
1064
1247
|
form: string,
|
|
@@ -1068,7 +1251,7 @@ interface VocabItemsBundle {
|
|
|
1068
1251
|
bulkCreate(body: any[], auditMessage?: string): Promise<{ ids: string[] }>;
|
|
1069
1252
|
bulkDelete(body: any[], auditMessage?: string): Promise<void>;
|
|
1070
1253
|
bulkUpdate(body: any[], auditMessage?: string): Promise<{ count: number }>;
|
|
1071
|
-
get(id: string
|
|
1254
|
+
get(id: string): Promise<any>;
|
|
1072
1255
|
delete(id: string, auditMessage?: string): Promise<any>;
|
|
1073
1256
|
update(id: string, form: string, auditMessage?: string): Promise<any>;
|
|
1074
1257
|
}
|
|
@@ -1097,7 +1280,7 @@ interface RelationLayersBundle {
|
|
|
1097
1280
|
configKey: string,
|
|
1098
1281
|
auditMessage?: string,
|
|
1099
1282
|
): Promise<any>;
|
|
1100
|
-
get(relationLayerId: string
|
|
1283
|
+
get(relationLayerId: string): Promise<any>;
|
|
1101
1284
|
delete(relationLayerId: string, auditMessage?: string): Promise<any>;
|
|
1102
1285
|
update(
|
|
1103
1286
|
relationLayerId: string,
|
|
@@ -1116,7 +1299,7 @@ interface TokensBundle {
|
|
|
1116
1299
|
metadata?: any,
|
|
1117
1300
|
auditMessage?: string,
|
|
1118
1301
|
): Promise<any>;
|
|
1119
|
-
get(tokenId: string
|
|
1302
|
+
get(tokenId: string): Promise<any>;
|
|
1120
1303
|
delete(tokenId: string, auditMessage?: string): Promise<any>;
|
|
1121
1304
|
update(
|
|
1122
1305
|
tokenId: string,
|
|
@@ -1144,7 +1327,7 @@ interface TokensBundle {
|
|
|
1144
1327
|
deleteMetadata(tokenId: string, auditMessage?: string): Promise<any>;
|
|
1145
1328
|
patchMetadata(
|
|
1146
1329
|
tokenId: string,
|
|
1147
|
-
body:
|
|
1330
|
+
body: MetadataOp[],
|
|
1148
1331
|
auditMessage?: string,
|
|
1149
1332
|
): Promise<any>;
|
|
1150
1333
|
}
|
|
@@ -1167,6 +1350,15 @@ interface PlaidClientOptions {
|
|
|
1167
1350
|
onAuthError?: ((error: Error) => void) | null;
|
|
1168
1351
|
}
|
|
1169
1352
|
|
|
1353
|
+
/** What kind of operation a logical-operation group is (`?group-kind=`). */
|
|
1354
|
+
export type OperationKind =
|
|
1355
|
+
| 'assistant-plan'
|
|
1356
|
+
| 'service-run'
|
|
1357
|
+
| 'import'
|
|
1358
|
+
| 'bulk-edit'
|
|
1359
|
+
| 'guess-adoption'
|
|
1360
|
+
| 'repair';
|
|
1361
|
+
|
|
1170
1362
|
export interface OperationGroupsBundle {
|
|
1171
1363
|
get(id: string): Promise<any>;
|
|
1172
1364
|
update(id: string, message: string | null): Promise<any>;
|
|
@@ -1181,7 +1373,14 @@ export interface PlaidBatch extends PlaidClient {
|
|
|
1181
1373
|
readonly client: PlaidClient;
|
|
1182
1374
|
/** The queued operations, in order. */
|
|
1183
1375
|
readonly operations: Array<{ path: string; method: string; body?: any }>;
|
|
1184
|
-
/**
|
|
1376
|
+
/**
|
|
1377
|
+
* Send the queued operations and resolve to one result per operation, in
|
|
1378
|
+
* order. Up to MAX_BATCH_OPS operations go as one atomic request. A larger
|
|
1379
|
+
* batch goes as consecutive requests, each atomic on its own, so a failure
|
|
1380
|
+
* in a later one leaves the earlier ones committed. The error then carries
|
|
1381
|
+
* `committed`, how many operations were saved (0 when none were), and
|
|
1382
|
+
* `committedResults`, their results in queue order.
|
|
1383
|
+
*/
|
|
1185
1384
|
submit(): Promise<any[]>;
|
|
1186
1385
|
/** Drop the queued operations without sending them. */
|
|
1187
1386
|
abort(): void;
|
|
@@ -1189,6 +1388,16 @@ export interface PlaidBatch extends PlaidClient {
|
|
|
1189
1388
|
|
|
1190
1389
|
export declare class PlaidClient {
|
|
1191
1390
|
constructor(baseUrl: string, token: string, options?: PlaidClientOptions);
|
|
1391
|
+
/** Liveness, version and database size, with no authentication. */
|
|
1392
|
+
static health(
|
|
1393
|
+
baseUrl: string,
|
|
1394
|
+
options?: { timeout?: number | null },
|
|
1395
|
+
): Promise<ServerHealth>;
|
|
1396
|
+
/** The limits this server enforces, with no authentication. */
|
|
1397
|
+
static info(
|
|
1398
|
+
baseUrl: string,
|
|
1399
|
+
options?: { timeout?: number | null },
|
|
1400
|
+
): Promise<{ limits: ServerLimits }>;
|
|
1192
1401
|
static login(
|
|
1193
1402
|
baseUrl: string,
|
|
1194
1403
|
userId: string,
|
|
@@ -1210,10 +1419,26 @@ export declare class PlaidClient {
|
|
|
1210
1419
|
credentials: { email?: string; password: string; displayName?: string },
|
|
1211
1420
|
options?: PlaidClientOptions,
|
|
1212
1421
|
): Promise<{ client: PlaidClient; userId: string; kind: string }>;
|
|
1422
|
+
/** The server's base URL, without a trailing slash. */
|
|
1423
|
+
readonly baseUrl: string;
|
|
1424
|
+
/** The bearer token every request carries. */
|
|
1425
|
+
token: string;
|
|
1213
1426
|
timeout: number | null;
|
|
1214
1427
|
batchTimeout: number | null;
|
|
1428
|
+
/** The document strict mode is entered for, or null. */
|
|
1429
|
+
readonly strictModeDocumentId: string | null;
|
|
1430
|
+
/** The DocumentLockLost of the open `locked()` block whose lock lapsed, or null. Cleared when that block exits. */
|
|
1431
|
+
documentLockLost: DocumentLockLost | null;
|
|
1215
1432
|
/** Fired once on HTTP 401 (see PlaidClientOptions.onAuthError). */
|
|
1216
1433
|
onAuthError: ((error: Error) => void) | null;
|
|
1434
|
+
/** The latest version seen for each document written through this client, keyed by document id. */
|
|
1435
|
+
documentVersions: Record<string, number>;
|
|
1436
|
+
/** True once a response left its version list out (X-Document-Versions-Omitted, past fifty documents). Every version held was then forgotten, and the strict-mode document's is read again before the next write. */
|
|
1437
|
+
documentVersionsOmitted?: boolean;
|
|
1438
|
+
/** The server's clock minus this machine's, in ms, from the last response with a Date header, or null before one. */
|
|
1439
|
+
serverClockOffsetMs: number | null;
|
|
1440
|
+
/** The server's time now, from its last response's Date header (to the second), else this machine's. Judge a time the server stamped, such as an audit entry's `ts`, against this rather than `Date.now()`. */
|
|
1441
|
+
serverNow(): Date;
|
|
1217
1442
|
|
|
1218
1443
|
// Batches.
|
|
1219
1444
|
//
|
|
@@ -1225,9 +1450,9 @@ export declare class PlaidClient {
|
|
|
1225
1450
|
// reporting its progress, taking and dropping a document lock, the admin
|
|
1226
1451
|
// actions on the server itself), goes over the wire even when made on the
|
|
1227
1452
|
// batch.
|
|
1228
|
-
/** Open a batch. Queue writes on it, then `submit()` them
|
|
1453
|
+
/** Open a batch. Queue writes on it, then `submit()` them (one atomic request up to MAX_BATCH_OPS operations), or `abort()`. Not nestable. */
|
|
1229
1454
|
batch(): PlaidBatch;
|
|
1230
|
-
/** Run `fn` with a batch, then submit
|
|
1455
|
+
/** Run `fn` with a batch, then submit it as `submit()` does (or abort if `fn` throws). Resolves to the results array, one entry per queued write. */
|
|
1231
1456
|
batched(fn: (batch: PlaidBatch) => void | Promise<void>): Promise<any[]>;
|
|
1232
1457
|
|
|
1233
1458
|
// Strict mode methods
|
|
@@ -1237,17 +1462,28 @@ export declare class PlaidClient {
|
|
|
1237
1462
|
// Logical operations (audit-log grouping). While one is open every write is
|
|
1238
1463
|
// stamped with its group id so the audit log folds them into one entry.
|
|
1239
1464
|
// Not atomic; nesting flattens into the outer operation.
|
|
1240
|
-
|
|
1241
|
-
|
|
1465
|
+
// `kind` is one of OperationKind (the server refuses any other) and `ref`
|
|
1466
|
+
// names what the operation came from; nesting keeps the outer ones.
|
|
1467
|
+
operationGroup: {
|
|
1468
|
+
id: string;
|
|
1469
|
+
message: string | null;
|
|
1470
|
+
kind: OperationKind | null;
|
|
1471
|
+
ref: string | null;
|
|
1472
|
+
} | null;
|
|
1473
|
+
beginOperation(
|
|
1474
|
+
message: string,
|
|
1475
|
+
opts?: { id?: string; kind?: OperationKind; ref?: string },
|
|
1476
|
+
): string;
|
|
1242
1477
|
endOperation(message?: string): Promise<void>;
|
|
1243
1478
|
withOperation<T>(
|
|
1244
1479
|
message: string,
|
|
1245
1480
|
fn: (setMessage: (msg: string) => void) => Promise<T> | T,
|
|
1481
|
+
opts?: { kind?: OperationKind; ref?: string },
|
|
1246
1482
|
): Promise<T>;
|
|
1247
1483
|
operationGroups: OperationGroupsBundle;
|
|
1248
1484
|
|
|
1249
1485
|
// Query
|
|
1250
|
-
query(body: any
|
|
1486
|
+
query(body: any): Promise<any>;
|
|
1251
1487
|
|
|
1252
1488
|
vocabLinks: VocabLinksBundle;
|
|
1253
1489
|
vocabLayers: VocabLayersBundle;
|
|
@@ -1260,9 +1496,11 @@ export declare class PlaidClient {
|
|
|
1260
1496
|
userData: UserDataBundle;
|
|
1261
1497
|
invites: InvitesBundle;
|
|
1262
1498
|
server: ServerBundle;
|
|
1499
|
+
auth: AuthBundle;
|
|
1263
1500
|
admin: AdminBundle;
|
|
1264
1501
|
audit: AuditBundle;
|
|
1265
1502
|
comments: CommentsBundle;
|
|
1503
|
+
events: EventsBundle;
|
|
1266
1504
|
guidelines: GuidelinesBundle;
|
|
1267
1505
|
tokenLayers: TokenLayersBundle;
|
|
1268
1506
|
documents: DocumentsBundle;
|
|
@@ -1298,6 +1536,8 @@ export function cpIndexOf(s: string, sub: string, fromCp?: number): number;
|
|
|
1298
1536
|
export const PLAID_NAMESPACE: "plaid";
|
|
1299
1537
|
/** The config key, under `plaid`, holding a layer's role. */
|
|
1300
1538
|
export const ROLE_KEY: "role";
|
|
1539
|
+
/** Layer config key naming the metadata keys a token born of a SPLIT inherits. */
|
|
1540
|
+
export const PRESERVE_ON_SPLIT_KEY: "preserveOnSplit";
|
|
1301
1541
|
|
|
1302
1542
|
/** The server's cap on operations per batch request; a larger batch goes as consecutive requests. */
|
|
1303
1543
|
export const MAX_BATCH_OPS: 1000;
|
|
@@ -1330,6 +1570,7 @@ export const TASKS: {
|
|
|
1330
1570
|
readonly TRANSCRIBE: "transcribe";
|
|
1331
1571
|
readonly LINK_VOCAB: "link-vocab";
|
|
1332
1572
|
readonly ANALYZE: "analyze";
|
|
1573
|
+
readonly DRAFT_GRAPH: "draft-graph";
|
|
1333
1574
|
readonly TRANSLATE: "translate";
|
|
1334
1575
|
readonly ASSIST: "assist";
|
|
1335
1576
|
readonly DETECT_SPEECH: "detect-speech";
|
|
@@ -1362,7 +1603,7 @@ export function coerceParamValues(
|
|
|
1362
1603
|
// replace unverified machine material but must never touch human/verified
|
|
1363
1604
|
// material without an explicit overwrite opt-in; any human edit verifies.
|
|
1364
1605
|
// See the manual, "Provenance".
|
|
1365
|
-
type ProvState = "human" | "machine" | "verified";
|
|
1606
|
+
type ProvState = "human" | "machine" | "contributed" | "verified";
|
|
1366
1607
|
export const PROV: {
|
|
1367
1608
|
readonly key: "prov";
|
|
1368
1609
|
readonly sourceKey: "provSource";
|
|
@@ -1370,12 +1611,16 @@ export const PROV: {
|
|
|
1370
1611
|
readonly probKey: "provProb";
|
|
1371
1612
|
readonly detailKey: "provDetail";
|
|
1372
1613
|
readonly INFERRED: "inferred";
|
|
1614
|
+
readonly CONTRIBUTED: "contributed";
|
|
1373
1615
|
};
|
|
1374
1616
|
export const PROV_STATES: {
|
|
1375
1617
|
readonly HUMAN: "human";
|
|
1376
1618
|
readonly MACHINE: "machine";
|
|
1619
|
+
readonly CONTRIBUTED: "contributed";
|
|
1377
1620
|
readonly VERIFIED: "verified";
|
|
1378
1621
|
};
|
|
1622
|
+
/** The provenance keys Plaid itself owns — what a split carries and a reshape keeps. */
|
|
1623
|
+
export const PROVENANCE_KEYS: readonly string[];
|
|
1379
1624
|
/** Optional prediction extras: prob = a probability in [0,1] for the chosen value
|
|
1380
1625
|
* (flat + queryable; omit unless it honestly is one); detail = an open map of
|
|
1381
1626
|
* producer extras (top-k alternatives, model version, raw scores; keep it small).
|
|
@@ -1420,3 +1665,102 @@ export function verifyOnEdit(
|
|
|
1420
1665
|
): { readonly provConfirmed: true } | null;
|
|
1421
1666
|
/** Canonical provSource for a service: 'service:<serviceId>'. */
|
|
1422
1667
|
export function serviceSource(serviceId: string): string;
|
|
1668
|
+
/** Canonical provSource for a contributor: 'user:<userId>'. */
|
|
1669
|
+
export function userSource(userId: string): string;
|
|
1670
|
+
/** The metadata fragment a contributor's work carries. */
|
|
1671
|
+
export function stampContributed(userId: string): {
|
|
1672
|
+
prov: "contributed";
|
|
1673
|
+
provSource: string;
|
|
1674
|
+
};
|
|
1675
|
+
/** Where an entity came from, confirmed or not: what a verified entity's tooltip needs. */
|
|
1676
|
+
export function provOrigin(
|
|
1677
|
+
metadata: object | null | undefined,
|
|
1678
|
+
): null | "inferred" | "contributed";
|
|
1679
|
+
/** Whether a verifier still has to look at this entity: machine-made or contributed, unconfirmed. */
|
|
1680
|
+
export function needsReview(metadata: object | null | undefined): boolean;
|
|
1681
|
+
/** The fragment a CONTRIBUTOR's edit merges in: the contributed stamp, dropping any confirmation. */
|
|
1682
|
+
export function contributeOnEdit(
|
|
1683
|
+
metadata: object | null | undefined,
|
|
1684
|
+
userId: string,
|
|
1685
|
+
): { prov: "contributed"; provSource: string; provConfirmed: null };
|
|
1686
|
+
/** Merge a fragment into a local copy, a null value deleting the key: applyMetadataOps(metadata, metadataOps(fragment)), refused where the server would refuse it. Returns a new object. */
|
|
1687
|
+
export function mergeMetadata(
|
|
1688
|
+
metadata: object | null | undefined,
|
|
1689
|
+
fragment: object | null | undefined,
|
|
1690
|
+
): Record<string, any>;
|
|
1691
|
+
|
|
1692
|
+
// --- Create responses ---------------------------------------------------------
|
|
1693
|
+
/** The id a single create answered with, read off the call's response or its batch result (`{status, body}`). Undefined when it gave none. */
|
|
1694
|
+
export function createdId(result: any): string | undefined;
|
|
1695
|
+
/** The ids a bulk create answered with, in input order, read off the call's response or its batch result. Empty when it gave none. */
|
|
1696
|
+
export function createdIds(result: any): string[];
|
|
1697
|
+
|
|
1698
|
+
// --- Metadata ops -------------------------------------------------------------
|
|
1699
|
+
/** One metadata edit: the body of a metadata PATCH is a list of these. */
|
|
1700
|
+
export type MetadataOp =
|
|
1701
|
+
| { op: "set"; path: string[]; value: any }
|
|
1702
|
+
| { op: "delete"; path: string[] };
|
|
1703
|
+
/** The ops that set each top-level key of a fragment, a null value deleting it. */
|
|
1704
|
+
export function metadataOps(
|
|
1705
|
+
fragment: object | null | undefined,
|
|
1706
|
+
): MetadataOp[];
|
|
1707
|
+
/** Apply ops to a local copy the way the server does. Returns a new object; throws where the server would refuse. */
|
|
1708
|
+
export function applyMetadataOps(
|
|
1709
|
+
metadata: object | null | undefined,
|
|
1710
|
+
ops: MetadataOp[],
|
|
1711
|
+
): Record<string, any>;
|
|
1712
|
+
/** True for a top-level metadata key Plaid keeps for itself (`plaid` and the provenance keys), never a user's field. */
|
|
1713
|
+
export function isReservedMetadataKey(key: string): boolean;
|
|
1714
|
+
|
|
1715
|
+
// --- Review: whose work is reviewed (a project-config norm) -------------------
|
|
1716
|
+
/** The config key, under the `plaid` namespace, holding the review lists. */
|
|
1717
|
+
export const REVIEW_KEY: "review";
|
|
1718
|
+
/** The project roles a review list may name. */
|
|
1719
|
+
export const PROJECT_ROLES: readonly ["reader", "writer", "maintainer"];
|
|
1720
|
+
/** A project's review lists, normalized. */
|
|
1721
|
+
export function readReview(config?: object | null): {
|
|
1722
|
+
users: string[];
|
|
1723
|
+
roles: string[];
|
|
1724
|
+
};
|
|
1725
|
+
/** A person's role in a project from its ACL lists; an admin with no entry is a maintainer. */
|
|
1726
|
+
export function projectRole(
|
|
1727
|
+
project: object | null | undefined,
|
|
1728
|
+
userId: string | null | undefined,
|
|
1729
|
+
opts?: { isAdmin?: boolean },
|
|
1730
|
+
): "maintainer" | "writer" | "reader" | null;
|
|
1731
|
+
/** Whether this person's work is reviewed here: named in review.users, or holding a role in review.roles. */
|
|
1732
|
+
export function isReviewed(
|
|
1733
|
+
project: object | null | undefined,
|
|
1734
|
+
userId: string | null | undefined,
|
|
1735
|
+
opts?: { isAdmin?: boolean },
|
|
1736
|
+
): boolean;
|
|
1737
|
+
/** The review lists with one person added to or removed from `users`. Pure. */
|
|
1738
|
+
export function withReviewedUser(
|
|
1739
|
+
review: { users?: string[]; roles?: string[] } | null | undefined,
|
|
1740
|
+
userId: string,
|
|
1741
|
+
reviewed: boolean,
|
|
1742
|
+
): { users: string[]; roles: string[] };
|
|
1743
|
+
/** What one writer's writes carry and what their review gestures act on. */
|
|
1744
|
+
export function writerPolicy(contributorId?: string | null): {
|
|
1745
|
+
readonly contributorId: string | null;
|
|
1746
|
+
readonly isContributor: boolean;
|
|
1747
|
+
/** The metadata a NEW entity carries: null for a verifier. */
|
|
1748
|
+
readonly createStamp: Record<string, any> | null;
|
|
1749
|
+
/** The fragment an EDIT merges, or null when there is nothing to merge. */
|
|
1750
|
+
readonly editStamp: (
|
|
1751
|
+
metadata: object | null | undefined,
|
|
1752
|
+
) => Record<string, any> | null;
|
|
1753
|
+
/** The fragment an explicit confirm gesture merges, or null. */
|
|
1754
|
+
readonly confirmStamp: (
|
|
1755
|
+
metadata: object | null | undefined,
|
|
1756
|
+
) => Record<string, any> | null;
|
|
1757
|
+
/** What an adopted suggestion is written with. */
|
|
1758
|
+
readonly adoptStamp: (
|
|
1759
|
+
source: string,
|
|
1760
|
+
detail?: Record<string, any>,
|
|
1761
|
+
) => Record<string, any>;
|
|
1762
|
+
/** Whether this writer's review gesture acts on the entity. */
|
|
1763
|
+
readonly reviewable: (metadata: object | null | undefined) => boolean;
|
|
1764
|
+
/** The same test over a provState. */
|
|
1765
|
+
readonly reviewableState: (state: string) => boolean;
|
|
1766
|
+
};
|