@larc-iu/plaid-client 0.2.0-alpha.23 → 0.2.0-alpha.26

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/src/index.d.ts ADDED
@@ -0,0 +1,3814 @@
1
+ /**
2
+ * How long `admin.backup()` waits for the server to finish writing a backup:
3
+ * minutes on a large database, past the usual per-request timeout.
4
+ */
5
+ export const BACKUP_TIMEOUT_MS: number;
6
+ export default PlaidClient;
7
+ export { wasReplayed } from "./replayed.js";
8
+ export type TextEditOp = import("./textEdits.js").TextEditOp;
9
+ export type TextGap = import("./textEdits.js").TextGap;
10
+ export type MetadataOp = import("./metadataOps.js").MetadataOp;
11
+ export type LayerConstraint = import("./constraints.js").LayerConstraint;
12
+ export type ConstraintWriteOptions = import("./constraints.js").ConstraintWriteOptions;
13
+ export type ConstraintViolation = import("./constraints.js").ConstraintViolation;
14
+ export type Requester = import("./requester.js").Requester;
15
+ export type BatchRef = import("./batchRef.js").BatchRef;
16
+ export type ServiceParam = import("./serviceSchema.js").ServiceParam;
17
+ export type ServiceInfo = import("./serviceSchema.js").ServiceInfo;
18
+ export type DiscoveredService = import("./serviceSchema.js").DiscoveredService;
19
+ export type ResponseHelper = import("./services.js").ResponseHelper;
20
+ export type ServiceRegistration = import("./services.js").ServiceRegistration;
21
+ export type ServiceStatusEvent = import("./services.js").ServiceStatusEvent;
22
+ export type OperationGroupsBundle = PlaidClient["operationGroups"];
23
+ /**
24
+ * A single page of a cursor-paginated collection.
25
+ */
26
+ export type Page<T = any> = {
27
+ entries: T[];
28
+ nextCursor: string | null;
29
+ };
30
+ /**
31
+ * Client options.
32
+ */
33
+ export type PlaidClientOptions = {
34
+ /**
35
+ * Per-request timeout in ms (default
36
+ * 30000, 0 or null disables it).
37
+ */
38
+ timeout?: number | null;
39
+ /**
40
+ * Timeout for batch submissions in
41
+ * ms (default 180000, 0 or null disables it). Aborting a batch does NOT
42
+ * stop the server, which keeps running the transaction and holding the
43
+ * write lock. Defaults to `timeout` when that is given and this is not.
44
+ */
45
+ batchTimeout?: number | null;
46
+ /**
47
+ * Delays in ms before sending a keyed
48
+ * write again when its answer was lost (no response, 502 or 504). Default
49
+ * [1000, 3000, 9000].
50
+ */
51
+ retryDelaysMs?: number[];
52
+ /**
53
+ * Fired once when
54
+ * a request returns HTTP 401 (missing, expired or invalid token). 403 does
55
+ * NOT trigger it.
56
+ */
57
+ onAuthError?: ((error: Error) => void) | null;
58
+ };
59
+ /**
60
+ * What kind of operation a logical-operation group is (`?group-kind=`).
61
+ */
62
+ export type OperationKind = "assistant-plan" | "service-run" | "import" | "bulk-edit" | "guess-adoption" | "repair" | "review";
63
+ /**
64
+ * Idempotency-Key seed for an operation run more than once (`client.keySeed()`).
65
+ */
66
+ export type KeySeed = {
67
+ seed: string;
68
+ stamps: Map<number, number | null>;
69
+ };
70
+ /**
71
+ * A batch: the client's bundles, on which every write of project data queues
72
+ * until `submit()`. See `PlaidClient.batch()`. `submit()` resolves to one
73
+ * result per operation, in order. `ref(opIndex, index)` stands for the id a
74
+ * queued operation will create, in the body of a later write on this batch.
75
+ */
76
+ export type PlaidBatch = PlaidClient & {
77
+ readonly client: PlaidClient;
78
+ readonly operations: Array<{
79
+ path: string;
80
+ method: string;
81
+ body?: any;
82
+ }>;
83
+ submit(): Promise<any[]>;
84
+ abort(): void;
85
+ ref(opIndex?: number, index?: number): BatchRef;
86
+ };
87
+ /**
88
+ * Options for a single page of any audit log. `kinds` keeps only the entries
89
+ * of operations of these kinds, each whole. `order: "desc"` pages newest
90
+ * first, and a cursor belongs to the direction that made it. `opsLimit` keeps
91
+ * only each entry's oldest N operations in `ops` (1..1000), and every entry
92
+ * has `opCount`. `entryId` reads only that entry rather than a page.
93
+ */
94
+ export type AuditPageOptions = {
95
+ startTime?: string;
96
+ endTime?: string;
97
+ opTypes?: string[] | string;
98
+ kinds?: OperationKind[] | string;
99
+ order?: "asc" | "desc";
100
+ limit?: number;
101
+ cursor?: string;
102
+ opsLimit?: number;
103
+ entryId?: string;
104
+ };
105
+ /**
106
+ * What `vocabLayers.restoreItem` did, or with `dryRun` would do.
107
+ */
108
+ export type VocabItemRestoreSummary = {
109
+ /**
110
+ * The entry was gone and came back under its old id.
111
+ */
112
+ inserted: boolean;
113
+ /**
114
+ * A living entry's form was set back.
115
+ */
116
+ form: boolean;
117
+ /**
118
+ * A living entry's fields were set back.
119
+ */
120
+ metadata: boolean;
121
+ /**
122
+ * 0 when nothing changes.
123
+ */
124
+ total: number;
125
+ };
126
+ /**
127
+ * One private data entry. `version` is raised by one on every write of the
128
+ * entry, and a new entry is 1.
129
+ */
130
+ export type UserDataEntry = {
131
+ key: string;
132
+ updatedAt: string;
133
+ version: number;
134
+ value?: any;
135
+ };
136
+ export type AdminUserDataEntry = UserDataEntry & {
137
+ userId: string;
138
+ };
139
+ /**
140
+ * One user's activity over a scope and window (`audit.tally`).
141
+ */
142
+ export type ActivityTallyRow = {
143
+ user: {
144
+ id: string;
145
+ displayName?: string;
146
+ };
147
+ operations: number;
148
+ changes: number;
149
+ documents: number;
150
+ firstTs: string;
151
+ lastTs: string;
152
+ byDay?: Array<{
153
+ date: string;
154
+ changes: number;
155
+ }>;
156
+ };
157
+ /**
158
+ * What a constraint repair did in one document.
159
+ */
160
+ export type ConstraintRepair = {
161
+ document: string;
162
+ constraint: string;
163
+ deleted: number;
164
+ joined: number;
165
+ };
166
+ /**
167
+ * Entities that can carry a comment.
168
+ */
169
+ export type CommentableType = "document" | "text" | "token" | "span" | "relation" | "vocab-item";
170
+ /**
171
+ * One comment. `projectId` and `documentId` are null for a comment on a
172
+ * vocabulary entry, and `vocabLayerId` is set only for one. `anchorLabel` is
173
+ * what the comment is about, in words, captured when it was posted: a
174
+ * comment outlives its anchor. `edited` is true once the body has been
175
+ * rewritten since it was posted.
176
+ */
177
+ export type Comment = {
178
+ id: string;
179
+ projectId: string | null;
180
+ documentId: string | null;
181
+ vocabLayerId: string | null;
182
+ entityType: CommentableType;
183
+ entityId: string;
184
+ anchorLabel: string | null;
185
+ authorId: string;
186
+ body: string;
187
+ createdAt: string;
188
+ updatedAt: string;
189
+ edited: boolean;
190
+ };
191
+ /**
192
+ * One entry in a project's annotation manual. `body` is present on a single
193
+ * read and on a list made with `includeBodies`, `bodyChars` on a list made
194
+ * without. `pinned`: the assistant is given this one in full on every turn.
195
+ */
196
+ export type Guideline = {
197
+ id: string;
198
+ projectId: string;
199
+ title: string;
200
+ body?: string;
201
+ bodyChars?: number;
202
+ pinned: boolean;
203
+ createdAt: string;
204
+ updatedAt: string;
205
+ };
206
+ /**
207
+ * A research-telemetry event type.
208
+ */
209
+ export type ClientEventType = "suggestion.shown" | "suggestion.adopted" | "suggestion.dismissed" | "plan.opened";
210
+ /**
211
+ * One research-telemetry event as the server stores it.
212
+ */
213
+ export type ClientEvent = {
214
+ id: number;
215
+ projectId: string;
216
+ documentId: string | null;
217
+ userId: string;
218
+ type: ClientEventType;
219
+ targetId: string | null;
220
+ data: Record<string, any> | null;
221
+ clientTs: string | null;
222
+ ts: string;
223
+ };
224
+ /**
225
+ * An invite. `kind` is "signup" or "password-reset", `status` "active",
226
+ * "used", "expired", "revoked" or "inactive".
227
+ */
228
+ export type Invite = {
229
+ id: string;
230
+ kind: string;
231
+ status: string;
232
+ createdBy: string;
233
+ createdAt: string;
234
+ expiresAt: string;
235
+ maxUses: number;
236
+ uses: number;
237
+ revokedAt: string | null;
238
+ note: string | null;
239
+ targetUserId: string | null;
240
+ grantAdmin: boolean;
241
+ projectId: string | null;
242
+ projectRole: string | null;
243
+ };
244
+ /**
245
+ * Server limits, as reported by /api/v1/info. An unset limit is absent.
246
+ * `passwordMinLength` is the shortest password the server accepts on any
247
+ * path, `lockExpirationMs` how long a document lock is held before it lapses.
248
+ */
249
+ export type ServerLimits = {
250
+ mediaFileBytes?: number;
251
+ jsonBodyBytes?: number;
252
+ batchOperations?: number;
253
+ metadataDepth?: number;
254
+ metadataKeyCount?: number;
255
+ metadataStringLength?: number;
256
+ metadataTotalBytes?: number;
257
+ userDataValueBytes?: number;
258
+ guidelineTitleLength?: number;
259
+ guidelineBodyLength?: number;
260
+ passwordMinLength?: number;
261
+ lockExpirationMs?: number;
262
+ };
263
+ export type ServerHealth = {
264
+ ok: boolean;
265
+ version: string;
266
+ uptimeMs: number;
267
+ audit: {
268
+ dbSizeMb?: number;
269
+ auditRows?: number;
270
+ error?: string;
271
+ };
272
+ };
273
+ export type RateLimitBucket = {
274
+ ip: string;
275
+ userId?: string;
276
+ failures: number;
277
+ limit: number;
278
+ blocked: boolean;
279
+ };
280
+ export type RateLimitSnapshot = {
281
+ windowMs: number;
282
+ logins: RateLimitBucket[];
283
+ ips: RateLimitBucket[];
284
+ invites: RateLimitBucket[];
285
+ };
286
+ export type BackupStatus = {
287
+ enabled: boolean;
288
+ directory: string;
289
+ retention: number;
290
+ time: string;
291
+ backups: Array<{
292
+ name: string;
293
+ bytes: number;
294
+ modified: string;
295
+ }>;
296
+ ok?: boolean;
297
+ };
298
+ export type ServerReport = {
299
+ version: string;
300
+ jvm: {
301
+ uptimeMs: number;
302
+ startedAt: string;
303
+ java: string;
304
+ heapUsed: number;
305
+ heapMax: number;
306
+ };
307
+ database: {
308
+ path: string | null;
309
+ bytes: number | null;
310
+ walBytes: number | null;
311
+ slowQueryThresholdMs?: number;
312
+ journalMode?: string;
313
+ maxPoolSize?: number;
314
+ tables: Record<string, number | null>;
315
+ };
316
+ media: {
317
+ directory: string;
318
+ files: number;
319
+ bytes: number;
320
+ orphans: number;
321
+ orphanBytes: number;
322
+ };
323
+ backup: BackupStatus;
324
+ settings: Record<string, any>;
325
+ };
326
+ /**
327
+ * The live log. Requests and events are buffered separately, so a burst of
328
+ * requests cannot evict an error. In each, `matched` is how many passed the
329
+ * filters (which may exceed what `entries` holds) and `held` how many are
330
+ * buffered in total. `file` is the configured log file's absolute path, or
331
+ * null when logging to stdout.
332
+ */
333
+ export type LiveLog = {
334
+ requests: {
335
+ entries: object[];
336
+ matched: number;
337
+ held: number;
338
+ capacity: number;
339
+ stats: Record<string, number | null>;
340
+ };
341
+ events: {
342
+ entries: object[];
343
+ matched: number;
344
+ held: number;
345
+ capacity: number;
346
+ byLevel: Record<string, number>;
347
+ };
348
+ file: string | null;
349
+ };
350
+ /**
351
+ * An open server-sent-events stream. Once CLOSED, `error` says why: null when
352
+ * this side closed it. A refused stream's error carries the HTTP `status`,
353
+ * and one the server ended is named "StreamClosed".
354
+ */
355
+ export type SSEConnection = {
356
+ close: () => void;
357
+ getStats: () => any;
358
+ readyState: number;
359
+ error: (Error & {
360
+ status?: number;
361
+ }) | null;
362
+ };
363
+ export class PlaidClient {
364
+ /**
365
+ * Liveness, version and database size, with NO authentication and no client
366
+ * instance — for a launcher or status page checking whether a server is up
367
+ * before anyone logs in.
368
+ * @param {string} baseUrl - The API base URL
369
+ * @param {{timeout?: number | null}} [options]
370
+ * @returns {Promise<ServerHealth>}
371
+ */
372
+ static health(baseUrl: string, options?: {
373
+ timeout?: number | null;
374
+ }): Promise<ServerHealth>;
375
+ /**
376
+ * The limits this server enforces, with NO authentication and no client
377
+ * instance. See the instance method for the shape.
378
+ * @param {string} baseUrl - The API base URL
379
+ * @param {{timeout?: number | null}} [options]
380
+ * @returns {Promise<{limits: ServerLimits}>}
381
+ */
382
+ static info(baseUrl: string, options?: {
383
+ timeout?: number | null;
384
+ }): Promise<{
385
+ limits: ServerLimits;
386
+ }>;
387
+ /**
388
+ * Build the link to hand someone for an invite code. The server never sees
389
+ * an app URL, so the app that minted the invite is the one that names it.
390
+ * Both SPAs use HashRouter, so the code rides in the fragment — which also
391
+ * keeps it out of server access logs.
392
+ * @param {string} appUrl - Where the SPA lives, e.g. "https://plaid.example.org/igt/"
393
+ * @param {string} code - The code returned by invites.create()
394
+ * @returns {string}
395
+ */
396
+ static inviteUrl(appUrl: string, code: string): string;
397
+ /**
398
+ * Describe an invite code, with NO authentication — this is what a signup
399
+ * page calls before the redeemer has an account. Returns the kind of link
400
+ * ("signup" or "password-reset"), its status ("active", "used", "expired",
401
+ * "revoked", or "inactive" when its creator can no longer grant what it
402
+ * grants), and the project it grants access to, if any.
403
+ *
404
+ * Throws a 404-shaped error if the code is unknown. A known-but-dead code
405
+ * resolves normally with a non-"active" status, so the page can say why.
406
+ * @param {string} baseUrl - The API base URL
407
+ * @param {string} code - The invite code
408
+ * @param {object} [options]
409
+ * @returns {Promise<{kind: string, status: string, expiresAt: string, projectName?: string, projectRole?: string, email?: string, grantAdmin: boolean}>}
410
+ */
411
+ static lookupInvite(baseUrl: string, code: string, options?: object): Promise<{
412
+ kind: string;
413
+ status: string;
414
+ expiresAt: string;
415
+ projectName?: string;
416
+ projectRole?: string;
417
+ email?: string;
418
+ grantAdmin: boolean;
419
+ }>;
420
+ /**
421
+ * Redeem an invite code, with NO authentication.
422
+ *
423
+ * For a signup invite, pass `email` and `password` to create the account
424
+ * (and optionally `displayName`); the invite's grants are applied in the
425
+ * same transaction. For a password reset link, pass `password` only.
426
+ * Resolves to a logged-in client, exactly like login() — the redeemer just
427
+ * chose these credentials, so there is no reason to send them to a login
428
+ * form to retype them.
429
+ * @param {string} baseUrl - The API base URL
430
+ * @param {string} code - The invite code
431
+ * @param {object} credentials
432
+ * @param {string} [credentials.email] - The new account's email address,
433
+ * which becomes its id and login (signup only)
434
+ * @param {string} [credentials.displayName] - How the new user is shown in
435
+ * the UI; defaults to the local part of the email (signup only)
436
+ * @param {string} credentials.password - Desired password (min 8 characters)
437
+ * @param {object} [options]
438
+ * @returns {Promise<{client: PlaidClient, userId: string, kind: string}>}
439
+ */
440
+ static redeemInvite(baseUrl: string, code: string, { email, password, displayName }?: {
441
+ email?: string;
442
+ displayName?: string;
443
+ password: string;
444
+ }, options?: object): Promise<{
445
+ client: PlaidClient;
446
+ userId: string;
447
+ kind: string;
448
+ }>;
449
+ /**
450
+ * Authenticate and return a new client instance with token. This is the
451
+ * single auth entry point — there is no `client.login` resource.
452
+ * @param {string} baseUrl - The base URL for the API
453
+ * @param {string} userId - User ID for authentication
454
+ * @param {string} password - Password for authentication
455
+ * @param {object} [options] - Client options forwarded to the constructor (e.g. { timeout })
456
+ * @returns {Promise<PlaidClient>} - Authenticated client instance
457
+ */
458
+ static login(baseUrl: string, userId: string, password: string, options?: object): Promise<PlaidClient>;
459
+ /**
460
+ * Create a new PlaidClient instance
461
+ * @param {string} baseUrl - The base URL for the API
462
+ * @param {string} token - The authentication token
463
+ * @param {PlaidClientOptions} [options] - Client options
464
+ */
465
+ constructor(baseUrl: string, token: string, options?: PlaidClientOptions);
466
+ baseUrl: string;
467
+ token: string;
468
+ /** @type {number | null} */
469
+ timeout: number | null;
470
+ /** @type {number | null} */
471
+ batchTimeout: number | null;
472
+ /** @type {number[] | undefined} */
473
+ retryDelaysMs: number[] | undefined;
474
+ /**
475
+ * The latest version seen for each document written through this client,
476
+ * keyed by document id.
477
+ * @type {Record<string, number>}
478
+ */
479
+ documentVersions: Record<string, number>;
480
+ /**
481
+ * True once a response left its version list out
482
+ * (X-Document-Versions-Omitted, past fifty documents). Every version held
483
+ * was then forgotten, and the strict-mode document's is read again before
484
+ * the next write.
485
+ * @type {boolean | undefined}
486
+ */
487
+ documentVersionsOmitted: boolean | undefined;
488
+ /** @type {number | null} */
489
+ serverClockOffsetMs: number | null;
490
+ /**
491
+ * The document strict mode is entered for, or null.
492
+ * @type {string | null}
493
+ */
494
+ strictModeDocumentId: string | null;
495
+ /** @type {import("./documentLock.js").DocumentLockLost | null} */
496
+ documentLockLost: import("./documentLock.js").DocumentLockLost | null;
497
+ /**
498
+ * @type {{id: string, message: string | null, kind: OperationKind | null,
499
+ * ref: string | null, depth: number, written: boolean, refined: any,
500
+ * frames: object[]} | null}
501
+ */
502
+ operationGroup: {
503
+ id: string;
504
+ message: string | null;
505
+ kind: OperationKind | null;
506
+ ref: string | null;
507
+ depth: number;
508
+ written: boolean;
509
+ refined: any;
510
+ frames: object[];
511
+ } | null;
512
+ /** @type {((error: Error) => void) | null} */
513
+ onAuthError: ((error: Error) => void) | null;
514
+ /** @private */
515
+ private _authErrorFired;
516
+ /** @private */
517
+ private _retryListeners;
518
+ /** @private */
519
+ private _serverFacts;
520
+ /** @private @type {object | null} */
521
+ private _openedFrame;
522
+ /**
523
+ * A stream of this client ended without being closed here: the server may
524
+ * have restarted, with other limits.
525
+ * @private
526
+ */
527
+ private _noteStreamDropped;
528
+ /**
529
+ * A stream of this client is open. After a drop the limits are read again,
530
+ * once however many streams reopen.
531
+ * @private
532
+ */
533
+ private _noteStreamOpened;
534
+ /**
535
+ * Hear every time a request is sent again: after a 503 (the database was
536
+ * busy), or for a keyed write after its answer was lost (no response, 502,
537
+ * 504). The listener gets `{ attempt, retries, delay, error }` before the
538
+ * wait. A screen that writes through the client directly can say it is
539
+ * retrying while the server does not answer, though the browser is online.
540
+ * @param {(info: {attempt: number, retries: number, delay: number, error: Error}) => void} listener
541
+ * @returns {() => void} the unsubscribe
542
+ */
543
+ onRetry(listener: (info: {
544
+ attempt: number;
545
+ retries: number;
546
+ delay: number;
547
+ error: Error;
548
+ }) => void): () => void;
549
+ /**
550
+ * Tell every `onRetry` listener. A listener that throws is passed over.
551
+ * @private
552
+ */
553
+ private _noteRetry;
554
+ /**
555
+ * The server's time now, as its last response's Date header put it (to the
556
+ * second), else this machine's. Judge a time the server stamped, such as an
557
+ * audit entry's `ts`, against this rather than `Date.now()`: a browser
558
+ * clock can be minutes off.
559
+ * @returns {Date}
560
+ */
561
+ serverNow(): Date;
562
+ /**
563
+ * The API bundles (`client.documents`, `client.tokens`, ...). Installed on
564
+ * the client, and again on every batch it opens (see `batch()`): a batch is
565
+ * a view of the client with its own `_request`, so the same bundles built
566
+ * on it queue instead of sending.
567
+ * @private
568
+ */
569
+ private _installResources;
570
+ vocabLinks: {
571
+ /**
572
+ * Get a vocab link by ID
573
+ * @param {string} id - The resource ID
574
+ */
575
+ get: (id: string) => Promise<any>;
576
+ /**
577
+ * Delete a vocab link
578
+ * @param {string} id - The resource ID
579
+ * @param {string} [auditMessage] - Audit message for this write
580
+ */
581
+ delete: (id: string, auditMessage?: string) => Promise<any>;
582
+ /**
583
+ * Replace all metadata of an entity. Keys left out of the new map are removed.
584
+ * @param {string} id - The entity's ID
585
+ * @param {object} body - The new metadata map
586
+ * @param {string} [auditMessage] - Audit message for this write
587
+ */
588
+ setMetadata: (id: string, body: object, auditMessage?: string) => Promise<any>;
589
+ /**
590
+ * Remove all metadata from an entity.
591
+ * @param {string} id - The entity's ID
592
+ * @param {string} [auditMessage] - Audit message for this write
593
+ */
594
+ deleteMetadata: (id: string, auditMessage?: string) => Promise<any>;
595
+ /**
596
+ * Edit an entity's metadata with a list of ops applied in order, in one operation. `{op: 'set', path, value}` writes value at path, creating missing objects along it; `{op: 'delete', path}` removes the key at path (a no-op when absent). A path is a non-empty array of keys, the first a top-level key. A path through a non-object is refused (400). See metadataOps and applyMetadataOps.
597
+ * @param {string} id - The entity's ID
598
+ * @param {MetadataOp[]} body - The metadata ops
599
+ * @param {string} [auditMessage] - Audit message for this write
600
+ */
601
+ patchMetadata: (id: string, body: MetadataOp[], auditMessage?: string) => Promise<any>;
602
+ /**
603
+ * Create a new vocab link between tokens and a vocab item.
604
+ * @param {string} vocabItem - The vocab item to link
605
+ * @param {Array} tokens - The tokens to link
606
+ * @param {any} [metadata] - Metadata for the link. Omit to leave unset; pass null to send JSON null.
607
+ * @param {string} [auditMessage] - Audit message for this write
608
+ * @param {object} [opts]
609
+ * @param {string} [opts.id] - The new entity's id, minted by the caller (see uuidv7)
610
+ */
611
+ create: (vocabItem: string, tokens: any[], metadata?: any, auditMessage?: string, { id }?: {
612
+ id?: string;
613
+ }) => Promise<any>;
614
+ /**
615
+ * Create multiple vocab links in a single operation. Entries may
616
+ * reference different vocab items, but all tokens across the call must
617
+ * belong to one document.
618
+ * @param {Array<{vocabItem: string, tokens: string[], metadata?: any}>} body - The vocab links to create
619
+ * @param {string} [auditMessage] - Audit message for this write
620
+ * @returns {Promise<{ids: string[]}>} The created entity IDs, in input order. (bulkDelete resolves to no value.)
621
+ */
622
+ bulkCreate: (body: Array<{
623
+ vocabItem: string;
624
+ tokens: string[];
625
+ metadata?: any;
626
+ }>, auditMessage?: string) => Promise<{
627
+ ids: string[];
628
+ }>;
629
+ /**
630
+ * Delete multiple vocab links in a single operation. Provide an array of IDs.
631
+ * @param {string[]} body - The vocab link IDs to delete
632
+ * @param {string} [auditMessage] - Audit message for this write
633
+ * @returns {Promise<void>}
634
+ */
635
+ bulkDelete: (body: string[], auditMessage?: string) => Promise<void>;
636
+ };
637
+ vocabLayers: {
638
+ /**
639
+ * List all vocab layers accessible to user. Transparently follows
640
+ * pagination cursors and returns the full flat array.
641
+ */
642
+ list: () => Promise<any[]>;
643
+ /**
644
+ * Fetch a single page of vocab layers.
645
+ * @param {object} [opts]
646
+ * @param {number} [opts.limit] - Page size (1..1000; server default 100)
647
+ * @param {string} [opts.cursor] - Opaque cursor from a previous page
648
+ * @returns {Promise<{entries: Array, nextCursor: (string|null)}>}
649
+ */
650
+ listPage: ({ limit, cursor }?: {
651
+ limit?: number;
652
+ cursor?: string;
653
+ }) => Promise<{
654
+ entries: any[];
655
+ nextCursor: (string | null);
656
+ }>;
657
+ /**
658
+ * Async-iterate vocab layers page by page; yields each page's entries array.
659
+ * @param {object} [opts]
660
+ * @param {number} [opts.pageSize] - Per-request page size
661
+ * @returns {AsyncGenerator<Array>}
662
+ */
663
+ iterPages: ({ pageSize }?: {
664
+ pageSize?: number;
665
+ }) => AsyncGenerator<any[]>;
666
+ /**
667
+ * Create a new vocab layer. Note: this also registers the user as a maintainer.
668
+ * @param {string} name - The name
669
+ * @param {string} [auditMessage] - Audit message for this write
670
+ * @param {object} [opts]
671
+ * @param {string} [opts.id] - The new entity's id, minted by the caller (see uuidv7)
672
+ */
673
+ create: (name: string, auditMessage?: string, { id }?: {
674
+ id?: string;
675
+ }) => Promise<any>;
676
+ /**
677
+ * Assign a user as a maintainer for this vocab layer.
678
+ * @param {string} id - The resource ID
679
+ * @param {string} userId - The user ID
680
+ * @param {string} [auditMessage] - Audit message for this write
681
+ */
682
+ addMaintainer: (id: string, userId: string, auditMessage?: string) => Promise<any>;
683
+ /**
684
+ * Remove a user's maintainer privileges for this vocab layer.
685
+ * @param {string} id - The resource ID
686
+ * @param {string} userId - The user ID
687
+ * @param {string} [auditMessage] - Audit message for this write
688
+ */
689
+ removeMaintainer: (id: string, userId: string, auditMessage?: string) => Promise<any>;
690
+ /**
691
+ * Set a configuration value in an editor namespace.
692
+ * @param {string} id - The record's ID
693
+ * @param {string} namespace - The config namespace
694
+ * @param {string} configKey - The config key
695
+ * @param {any} configValue - Configuration value to set
696
+ * @param {string} [auditMessage] - Audit message for this write
697
+ * @param {{expected?: any}} [options] - `expected`: the value read for this key (null or undefined when it
698
+ * was absent). The write is then refused with a 409 when the stored value differs.
699
+ */
700
+ setConfig: (id: string, namespace: string, configKey: string, configValue: any, auditMessage?: string, options?: {
701
+ expected?: any;
702
+ }) => Promise<any>;
703
+ /**
704
+ * Remove a configuration value.
705
+ * @param {string} id - The record's ID
706
+ * @param {string} namespace - The config namespace
707
+ * @param {string} configKey - The config key
708
+ * @param {string} [auditMessage] - Audit message for this write
709
+ * @param {{expected?: any}} [options] - `expected`, as on setConfig.
710
+ */
711
+ deleteConfig: (id: string, namespace: string, configKey: string, auditMessage?: string, options?: {
712
+ expected?: any;
713
+ }) => Promise<any>;
714
+ /**
715
+ * Get a vocab layer by ID. With `asOf`, the vocabulary as it was at that
716
+ * instant, read from its history: the same shape as the live read, its
717
+ * entries with `includeItems`. A vocabulary that did not exist then is a
718
+ * 404, a malformed or pruned time a 400.
719
+ * @param {string} id - The resource ID
720
+ * @param {boolean} [includeItems] - Include vocab items
721
+ * @param {string} [asOf] - The moment to read at (ISO-8601 instant)
722
+ */
723
+ get: (id: string, includeItems?: boolean, asOf?: string) => Promise<any>;
724
+ /**
725
+ * One entry of the vocabulary as it was at `asOf`, also when it has
726
+ * been deleted since. The same shape as `vocabItems.get`. A 404 when
727
+ * the entry was not in this vocabulary at that time.
728
+ * @param {string} id - The vocabulary ID
729
+ * @param {string} itemId - The entry ID
730
+ * @param {string} asOf - The moment to read at (ISO-8601 instant)
731
+ */
732
+ getItemAt: (id: string, itemId: string, asOf: string) => Promise<any>;
733
+ /**
734
+ * Get the audit log of a vocabulary: every change to it or to its
735
+ * entries, folded into entries as the document log is. Links are not
736
+ * listed, they belong to the document they annotate. Transparently
737
+ * follows pagination cursors and returns the full flat array.
738
+ * @param {string} id - The vocabulary ID
739
+ * @param {string} [startTime] - Start of time range
740
+ * @param {string} [endTime] - End of time range
741
+ * @param {string[]|string} [opTypes] - Only return operations of these
742
+ * types, spelled as in an entry's `op/type` (e.g.
743
+ * `['vocab-item/delete', 'vocab-item/restore']`)
744
+ * @param {string} [itemId] - Only the changes that wrote this one entry,
745
+ * each with only its operations that did
746
+ * @param {string[]|string} [kinds] - Only the entries of operations of
747
+ * these kinds (e.g. `['review', 'guess-adoption']`), each whole
748
+ */
749
+ audit: (id: string, startTime?: string, endTime?: string, opTypes?: string[] | string, itemId?: string, kinds?: string[] | string) => Promise<any[]>;
750
+ /**
751
+ * One page of the same log, newest-first with `order: "desc"`. Use this
752
+ * rather than audit() wherever the caller wants the recent end of a log
753
+ * that may be long: audit() walks every page before it resolves.
754
+ * @param {string} id - The vocabulary ID
755
+ * @param {object} [opts]
756
+ * @param {string} [opts.startTime] - Only entries at or after this instant
757
+ * @param {string} [opts.endTime] - Only entries at or before this instant
758
+ * @param {string[]|string} [opts.opTypes] - Only these op types
759
+ * @param {OperationKind[]|string} [opts.kinds] - Only the entries of operations of these kinds, each whole
760
+ * @param {"asc"|"desc"} [opts.order] - "desc" pages newest-first
761
+ * @param {number} [opts.limit] - Page size (1..1000; server default 100)
762
+ * @param {string} [opts.cursor] - Opaque cursor from a previous page
763
+ * @param {number} [opts.opsLimit] - Keep only each entry's oldest N
764
+ * operations in `ops` (1..1000). `opCount` on every entry says how
765
+ * many it has
766
+ * @param {string} [opts.entryId] - Read only this entry, not a page
767
+ * @param {string} [opts.itemId] - Only the changes that wrote this one
768
+ * entry, each with only its operations that did
769
+ * @returns {Promise<{entries: Array, nextCursor: (string|null)}>}
770
+ */
771
+ auditPage: (id: string, { startTime, endTime, opTypes, kinds, order, limit, cursor, opsLimit, entryId, itemId }?: {
772
+ startTime?: string;
773
+ endTime?: string;
774
+ opTypes?: string[] | string;
775
+ kinds?: OperationKind[] | string;
776
+ order?: "asc" | "desc";
777
+ limit?: number;
778
+ cursor?: string;
779
+ opsLimit?: number;
780
+ entryId?: string;
781
+ itemId?: string;
782
+ }) => Promise<{
783
+ entries: any[];
784
+ nextCursor: (string | null);
785
+ }>;
786
+ /**
787
+ * Put one entry of the vocabulary back as it was at `asOf`, as one
788
+ * operation. A deleted entry comes back under its original id with its
789
+ * form and fields, and a living one has its form and fields set back.
790
+ * Links are not part of an entry: a deleted entry's links come back
791
+ * through each document's own `documents.restore`. Resolves to
792
+ * `{inserted, form, metadata, total}`, `total` 0 when nothing changes.
793
+ * A form set back bumps every linking document, and the new versions
794
+ * come back in X-Document-Versions (or, past fifty documents,
795
+ * X-Document-Versions-Omitted), which the client takes up as on any
796
+ * write. A time when the entry did not exist is a 400. Maintainers of
797
+ * the vocabulary only.
798
+ * @param {string} id - The vocabulary ID
799
+ * @param {string} itemId - The entry ID
800
+ * @param {string} asOf - The moment to go back to (ISO-8601 instant),
801
+ * typically a history entry's `endTime`
802
+ * @param {{dryRun?: boolean}} [options] - `{ dryRun }`: with `dryRun` true nothing
803
+ * is written and the summary says what would change
804
+ * @param {string} [auditMessage] - Custom audit message for this operation
805
+ * @returns {Promise<VocabItemRestoreSummary>}
806
+ */
807
+ restoreItem: (id: string, itemId: string, asOf: string, { dryRun }?: {
808
+ dryRun?: boolean;
809
+ }, auditMessage?: string) => Promise<VocabItemRestoreSummary>;
810
+ /**
811
+ * Delete a vocab layer.
812
+ * @param {string} id - The resource ID
813
+ * @param {string} [auditMessage] - Audit message for this write
814
+ */
815
+ delete: (id: string, auditMessage?: string) => Promise<any>;
816
+ /**
817
+ * Update a vocab layer's name.
818
+ * @param {string} id - The resource ID
819
+ * @param {string} name - The name
820
+ * @param {string} [auditMessage] - Audit message for this write
821
+ */
822
+ update: (id: string, name: string, auditMessage?: string) => Promise<any>;
823
+ };
824
+ relations: {
825
+ /**
826
+ * Update the target span of a relation.
827
+ * @param {string} relationId - The relation ID
828
+ * @param {string} spanId - The span ID
829
+ * @param {string} [auditMessage] - Audit message for this write
830
+ */
831
+ setTarget: (relationId: string, spanId: string, auditMessage?: string) => Promise<any>;
832
+ /**
833
+ * Get a relation by ID.
834
+ * @param {string} relationId - The relation ID
835
+ */
836
+ get: (relationId: string) => Promise<any>;
837
+ /**
838
+ * Delete a relation.
839
+ * @param {string} relationId - The relation ID
840
+ * @param {string} [auditMessage] - Audit message for this write
841
+ */
842
+ delete: (relationId: string, auditMessage?: string) => Promise<any>;
843
+ /**
844
+ * Update a relation's value.
845
+ * @param {string} relationId - The relation ID
846
+ * @param {any} value - The value
847
+ * @param {string} [auditMessage] - Audit message for this write
848
+ */
849
+ update: (relationId: string, value: any, auditMessage?: string) => Promise<any>;
850
+ /**
851
+ * Update the source span of a relation.
852
+ * @param {string} relationId - The relation ID
853
+ * @param {string} spanId - The span ID
854
+ * @param {string} [auditMessage] - Audit message for this write
855
+ */
856
+ setSource: (relationId: string, spanId: string, auditMessage?: string) => Promise<any>;
857
+ /**
858
+ * Create a new relation. A relation is a directed edge between two spans
859
+ * with a value, useful for expressing phenomena such as syntactic or
860
+ * semantic relations.
861
+ * @param {string} layerId - The relation layer ID
862
+ * @param {string} sourceId - The source span ID
863
+ * @param {string} targetId - The target span ID
864
+ * @param {any} value - The value
865
+ * @param {any} [metadata] - Metadata map. Omit to leave unset; pass null to send JSON null.
866
+ * @param {string} [auditMessage] - Audit message for this write
867
+ * @param {object} [opts]
868
+ * @param {string} [opts.id] - The new entity's id, minted by the caller (see uuidv7)
869
+ */
870
+ create: (layerId: string, sourceId: string, targetId: string, value: any, metadata?: any, auditMessage?: string, { id }?: {
871
+ id?: string;
872
+ }) => Promise<any>;
873
+ /**
874
+ * Create multiple relations in a single operation.
875
+ * @param {Array} body - The request body
876
+ * @param {string} [auditMessage] - Audit message for this write
877
+ * @returns {Promise<{ids: string[]}>} The created entity IDs, in input order. (bulkDelete resolves to no value.)
878
+ */
879
+ bulkCreate: (body: any[], auditMessage?: string) => Promise<{
880
+ ids: string[];
881
+ }>;
882
+ /**
883
+ * Delete multiple relations in a single operation. Provide an array of IDs.
884
+ * @param {Array} body - The request body
885
+ * @param {string} [auditMessage] - Audit message for this write
886
+ * @returns {Promise<void>}
887
+ */
888
+ bulkDelete: (body: any[], auditMessage?: string) => Promise<void>;
889
+ /**
890
+ * Update many relations in a single operation: set values and/or patch metadata.
891
+ * @param {Array} body - Objects of the shape `{id, value?, metadata?}`. `value` is set only when the key is present (null sends JSON null); `metadata` is a list of metadata ops, as for patchMetadata. The relations may lie in several documents of one project; every document touched has its version bumped and every new version comes back in `X-Document-Versions` (past fifty documents, only their number, in `X-Document-Versions-Omitted`). A `document-version` precondition is accepted only when every entry lies in one document. An unknown id refuses the whole update.
892
+ * @param {string} [auditMessage] - Audit message for this write
893
+ * @returns {Promise<{count: number}>} How many relations were updated.
894
+ */
895
+ bulkUpdate: (body: any[], auditMessage?: string) => Promise<{
896
+ count: number;
897
+ }>;
898
+ /**
899
+ * Replace all metadata of an entity. Keys left out of the new map are removed.
900
+ * @param {string} id - The entity's ID
901
+ * @param {object} body - The new metadata map
902
+ * @param {string} [auditMessage] - Audit message for this write
903
+ */
904
+ setMetadata: (id: string, body: object, auditMessage?: string) => Promise<any>;
905
+ /**
906
+ * Remove all metadata from an entity.
907
+ * @param {string} id - The entity's ID
908
+ * @param {string} [auditMessage] - Audit message for this write
909
+ */
910
+ deleteMetadata: (id: string, auditMessage?: string) => Promise<any>;
911
+ /**
912
+ * Edit an entity's metadata with a list of ops applied in order, in one operation. `{op: 'set', path, value}` writes value at path, creating missing objects along it; `{op: 'delete', path}` removes the key at path (a no-op when absent). A path is a non-empty array of keys, the first a top-level key. A path through a non-object is refused (400). See metadataOps and applyMetadataOps.
913
+ * @param {string} id - The entity's ID
914
+ * @param {MetadataOp[]} body - The metadata ops
915
+ * @param {string} [auditMessage] - Audit message for this write
916
+ */
917
+ patchMetadata: (id: string, body: MetadataOp[], auditMessage?: string) => Promise<any>;
918
+ };
919
+ spanLayers: {
920
+ /**
921
+ * Create a new span layer.
922
+ * @param {string} tokenLayerId - The token layer ID
923
+ * @param {string} name - The name
924
+ * @param {string} [auditMessage] - Audit message for this write
925
+ * @param {object} [opts]
926
+ * @param {string} [opts.id] - The new entity's id, minted by the caller (see uuidv7)
927
+ */
928
+ create: (tokenLayerId: string, name: string, auditMessage?: string, { id }?: {
929
+ id?: string;
930
+ }) => Promise<any>;
931
+ /**
932
+ * Get a layer by ID.
933
+ * @param {string} layerId - The layer ID
934
+ */
935
+ get: (layerId: string) => Promise<any>;
936
+ /**
937
+ * Delete a layer.
938
+ * @param {string} layerId - The layer ID
939
+ * @param {string} [auditMessage] - Audit message for this write
940
+ */
941
+ delete: (layerId: string, auditMessage?: string) => Promise<any>;
942
+ /**
943
+ * Rename a layer.
944
+ * @param {string} layerId - The layer ID
945
+ * @param {string} name - The new name
946
+ * @param {string} [auditMessage] - Audit message for this write
947
+ */
948
+ update: (layerId: string, name: string, auditMessage?: string) => Promise<any>;
949
+ /**
950
+ * Move a layer one place in its display order.
951
+ * @param {string} layerId - The layer ID
952
+ * @param {string} direction - The direction ("up" or "down")
953
+ * @param {string} [auditMessage] - Audit message for this write
954
+ */
955
+ shift: (layerId: string, direction: string, auditMessage?: string) => Promise<any>;
956
+ /**
957
+ * Declare an app namespace's constraints on this layer, replacing that
958
+ * namespace's list. Refused with 422 and the violations when the layer's
959
+ * stored data breaks them (see violationsOf).
960
+ * @param {string} layerId - The layer ID
961
+ * @param {string} namespace - The declaring app's namespace, e.g. "igt"
962
+ * @param {LayerConstraint[]} constraints - e.g. [{type: "single-span"}, {type: "value-set", values: ["N"]}]
963
+ * @param {string} [auditMessage] - Audit message for this write
964
+ * @param {{expected?: Array<object>|null}} [options] - `expected`: the list read for this
965
+ * namespace (null when it was absent). The write is then refused with a 409 when the stored
966
+ * list differs.
967
+ * @returns {Promise<{constraints: Record<string, LayerConstraint[]>}>} the layer's whole constraint map
968
+ */
969
+ setConstraints: (layerId: string, namespace: string, constraints: LayerConstraint[], auditMessage?: string, options?: {
970
+ expected?: Array<object> | null;
971
+ }) => Promise<{
972
+ constraints: Record<string, LayerConstraint[]>;
973
+ }>;
974
+ /**
975
+ * Remove an app namespace's constraints from this layer.
976
+ * @param {string} layerId - The layer ID
977
+ * @param {string} namespace - The declaring app's namespace
978
+ * @param {string} [auditMessage] - Audit message for this write
979
+ * @param {{expected?: Array<object>|null}} [options] - `expected`, as on setConstraints.
980
+ */
981
+ deleteConstraints: (layerId: string, namespace: string, auditMessage?: string, options?: {
982
+ expected?: Array<object> | null;
983
+ }) => Promise<any>;
984
+ /**
985
+ * The violations the given constraints would meet in this layer's stored
986
+ * data. Writes nothing.
987
+ * @param {string} layerId - The layer ID
988
+ * @param {LayerConstraint[]} constraints - The list to check
989
+ * @returns {Promise<{violations: ConstraintViolation[], violationCount: number}>}
990
+ */
991
+ checkConstraints: (layerId: string, constraints: LayerConstraint[]) => Promise<{
992
+ violations: ConstraintViolation[];
993
+ violationCount: number;
994
+ }>;
995
+ /**
996
+ * Apply the remedies of the given constraints' remediable types
997
+ * (coextensive, single-span, single-link, same-ancestor) to every
998
+ * violation in this layer's stored data, one operation per document.
999
+ * With `document`, only that document is repaired, and a writer may
1000
+ * ask. A document another user holds the lock on is left as it is and
1001
+ * listed under `locked`.
1002
+ * @param {string} layerId - The layer ID
1003
+ * @param {LayerConstraint[]} constraints - The list to repair for
1004
+ * @param {string} [auditMessage] - Audit message for this write
1005
+ * @param {{document?: string}} [options]
1006
+ * @returns {Promise<{repaired: ConstraintRepair[], locked: Array<{document: string, lockedBy: string}>, violations: ConstraintViolation[], violationCount: number}>}
1007
+ */
1008
+ repairConstraints: (layerId: string, constraints: LayerConstraint[], auditMessage?: string, options?: {
1009
+ document?: string;
1010
+ }) => Promise<{
1011
+ repaired: ConstraintRepair[];
1012
+ locked: Array<{
1013
+ document: string;
1014
+ lockedBy: string;
1015
+ }>;
1016
+ violations: ConstraintViolation[];
1017
+ violationCount: number;
1018
+ }>;
1019
+ /**
1020
+ * Set a configuration value in an editor namespace.
1021
+ * @param {string} id - The record's ID
1022
+ * @param {string} namespace - The config namespace
1023
+ * @param {string} configKey - The config key
1024
+ * @param {any} configValue - Configuration value to set
1025
+ * @param {string} [auditMessage] - Audit message for this write
1026
+ * @param {{expected?: any}} [options] - `expected`: the value read for this key (null or undefined when it
1027
+ * was absent). The write is then refused with a 409 when the stored value differs.
1028
+ */
1029
+ setConfig: (id: string, namespace: string, configKey: string, configValue: any, auditMessage?: string, options?: {
1030
+ expected?: any;
1031
+ }) => Promise<any>;
1032
+ /**
1033
+ * Remove a configuration value.
1034
+ * @param {string} id - The record's ID
1035
+ * @param {string} namespace - The config namespace
1036
+ * @param {string} configKey - The config key
1037
+ * @param {string} [auditMessage] - Audit message for this write
1038
+ * @param {{expected?: any}} [options] - `expected`, as on setConfig.
1039
+ */
1040
+ deleteConfig: (id: string, namespace: string, configKey: string, auditMessage?: string, options?: {
1041
+ expected?: any;
1042
+ }) => Promise<any>;
1043
+ };
1044
+ spans: {
1045
+ /**
1046
+ * Replace all metadata of an entity. Keys left out of the new map are removed.
1047
+ * @param {string} id - The entity's ID
1048
+ * @param {object} body - The new metadata map
1049
+ * @param {string} [auditMessage] - Audit message for this write
1050
+ */
1051
+ setMetadata: (id: string, body: object, auditMessage?: string) => Promise<any>;
1052
+ /**
1053
+ * Remove all metadata from an entity.
1054
+ * @param {string} id - The entity's ID
1055
+ * @param {string} [auditMessage] - Audit message for this write
1056
+ */
1057
+ deleteMetadata: (id: string, auditMessage?: string) => Promise<any>;
1058
+ /**
1059
+ * Edit an entity's metadata with a list of ops applied in order, in one operation. `{op: 'set', path, value}` writes value at path, creating missing objects along it; `{op: 'delete', path}` removes the key at path (a no-op when absent). A path is a non-empty array of keys, the first a top-level key. A path through a non-object is refused (400). See metadataOps and applyMetadataOps.
1060
+ * @param {string} id - The entity's ID
1061
+ * @param {MetadataOp[]} body - The metadata ops
1062
+ * @param {string} [auditMessage] - Audit message for this write
1063
+ */
1064
+ patchMetadata: (id: string, body: MetadataOp[], auditMessage?: string) => Promise<any>;
1065
+ /**
1066
+ * Replace tokens for a span.
1067
+ * @param {string} spanId - The span ID
1068
+ * @param {Array} tokens - The tokens
1069
+ * @param {string} [auditMessage] - Audit message for this write
1070
+ */
1071
+ setTokens: (spanId: string, tokens: any[], auditMessage?: string) => Promise<any>;
1072
+ /**
1073
+ * Create a new span. A span holds a primary atomic value and optional
1074
+ * metadata, and must at all times be associated with one or more tokens.
1075
+ * @param {string} spanLayerId - The span layer ID
1076
+ * @param {Array} tokens - The tokens
1077
+ * @param {any} value - The value
1078
+ * @param {any} [metadata] - Metadata map. Omit to leave unset; pass null to send JSON null.
1079
+ * @param {string} [auditMessage] - Audit message for this write
1080
+ * @param {object} [opts]
1081
+ * @param {string} [opts.id] - The new entity's id, minted by the caller (see uuidv7)
1082
+ */
1083
+ create: (spanLayerId: string, tokens: any[], value: any, metadata?: any, auditMessage?: string, { id }?: {
1084
+ id?: string;
1085
+ }) => Promise<any>;
1086
+ /**
1087
+ * Get a span by ID.
1088
+ * @param {string} spanId - The span ID
1089
+ */
1090
+ get: (spanId: string) => Promise<any>;
1091
+ /**
1092
+ * Delete a span.
1093
+ * @param {string} spanId - The span ID
1094
+ * @param {string} [auditMessage] - Audit message for this write
1095
+ */
1096
+ delete: (spanId: string, auditMessage?: string) => Promise<any>;
1097
+ /**
1098
+ * Update a span's value.
1099
+ * @param {string} spanId - The span ID
1100
+ * @param {any} value - The value
1101
+ * @param {string} [auditMessage] - Audit message for this write
1102
+ */
1103
+ update: (spanId: string, value: any, auditMessage?: string) => Promise<any>;
1104
+ /**
1105
+ * Create multiple spans in a single operation.
1106
+ * @param {Array} body - The request body
1107
+ * @param {string} [auditMessage] - Audit message for this write
1108
+ * @returns {Promise<{ids: string[]}>} The created entity IDs, in input order. (bulkDelete resolves to no value.)
1109
+ */
1110
+ bulkCreate: (body: any[], auditMessage?: string) => Promise<{
1111
+ ids: string[];
1112
+ }>;
1113
+ /**
1114
+ * Delete multiple spans in a single operation. Provide an array of IDs.
1115
+ * @param {Array} body - The request body
1116
+ * @param {string} [auditMessage] - Audit message for this write
1117
+ * @returns {Promise<void>}
1118
+ */
1119
+ bulkDelete: (body: any[], auditMessage?: string) => Promise<void>;
1120
+ /**
1121
+ * Update many spans in a single operation: set values and/or patch metadata.
1122
+ * @param {Array} body - Objects of the shape `{id, value?, metadata?}`. `value` is set only when the key is present (null sends JSON null); `metadata` is a list of metadata ops, as for patchMetadata. The spans may lie in several documents of one project; every document touched has its version bumped and every new version comes back in `X-Document-Versions` (past fifty documents, only their number, in `X-Document-Versions-Omitted`). A `document-version` precondition is accepted only when every entry lies in one document. An unknown id refuses the whole update.
1123
+ * @param {string} [auditMessage] - Audit message for this write
1124
+ * @returns {Promise<{count: number}>} How many spans were updated.
1125
+ */
1126
+ bulkUpdate: (body: any[], auditMessage?: string) => Promise<{
1127
+ count: number;
1128
+ }>;
1129
+ };
1130
+ server: {
1131
+ /**
1132
+ * This server's version and the limits it enforces, e.g.
1133
+ * `{ limits: { mediaFileBytes, jsonBodyBytes, batchOperations, … } }`.
1134
+ * Sizes are in bytes. Unauthenticated.
1135
+ * @returns {Promise<{limits: ServerLimits}>}
1136
+ */
1137
+ info: () => Promise<{
1138
+ limits: ServerLimits;
1139
+ }>;
1140
+ /**
1141
+ * Read `GET /info` again and resolve to it. Until it answers, a reader
1142
+ * waits for it. The facts known before are kept when the server does
1143
+ * not answer, and the error is thrown.
1144
+ * @returns {Promise<{limits: ServerLimits}>}
1145
+ */
1146
+ refresh: () => Promise<{
1147
+ limits: ServerLimits;
1148
+ }>;
1149
+ /**
1150
+ * Just the limits, which is what a caller almost always wants.
1151
+ * @returns {Promise<ServerLimits>}
1152
+ */
1153
+ limits: () => Promise<ServerLimits>;
1154
+ /**
1155
+ * Liveness, version and database size. Unauthenticated, and served
1156
+ * outside the REST router at /health, so it answers even while the API
1157
+ * is refusing requests. Never cached — the point is that it is current.
1158
+ * @returns {Promise<ServerHealth>}
1159
+ */
1160
+ health: () => Promise<ServerHealth>;
1161
+ };
1162
+ auth: {
1163
+ /**
1164
+ * End every sign-in of this user on every device: each browser tab,
1165
+ * script and service holding one of the user's sign-in tokens is
1166
+ * refused from now on, this client included. Named API tokens are not
1167
+ * affected (revoke one with `apiTokens.revoke`). To sign out of one tab
1168
+ * only, discard its token instead. A signal rather than project data:
1169
+ * made on a batch it still goes out at once, and it never joins an
1170
+ * operation.
1171
+ * @returns {Promise<void>}
1172
+ */
1173
+ logoutEverywhere: () => Promise<void>;
1174
+ };
1175
+ texts: {
1176
+ /**
1177
+ * Create a new text in a document's text layer. A text is a container for
1178
+ * one long string in `body` for a given layer.
1179
+ * @param {string} textLayerId - The text layer ID
1180
+ * @param {string} documentId - The document ID
1181
+ * @param {string} body - The request body
1182
+ * @param {any} [metadata] - Metadata map. Omit to leave unset; pass null to send JSON null.
1183
+ * @param {string} [auditMessage]
1184
+ * @param {{id?: string, tokenEdges?: number[]}} [options] - `id`: the new text's id, a UUIDv7
1185
+ * this client minted. `tokenEdges`: the code-point offsets where the tokens made next on
1186
+ * this text begin and end. The body is stored composed, except a character one of them
1187
+ * falls inside, which stays as sent (see composeText).
1188
+ */
1189
+ create: (textLayerId: string, documentId: string, body: string, metadata?: any, auditMessage?: string, { id, tokenEdges }?: {
1190
+ id?: string;
1191
+ tokenEdges?: number[];
1192
+ }) => Promise<any>;
1193
+ /**
1194
+ * Get a text.
1195
+ * @param {string} textId - The text ID
1196
+ */
1197
+ get: (textId: string) => Promise<any>;
1198
+ /**
1199
+ * Delete a text and all dependent data.
1200
+ * @param {string} textId - The text ID
1201
+ * @param {string} [auditMessage] - Audit message for this write
1202
+ */
1203
+ delete: (textId: string, auditMessage?: string) => Promise<any>;
1204
+ /**
1205
+ * Update a text's body. A diff is computed and token indices are updated
1206
+ * so that tokens remain intact. Alternatively, `body` can be a list of
1207
+ * edit directives (code-point indices, applied in order):
1208
+ * {type: 'delete', index, value: count}
1209
+ * {type: 'insert', index, value: string}
1210
+ * {type: 'replace', index, length, value: string} — unlike
1211
+ * delete+insert, a token covering the whole range is resized to keep
1212
+ * it (respell a word in place without losing its annotations).
1213
+ * A list is applied exactly as sent. With `base` (the `digest` of the
1214
+ * body the update was made on, as every read of a text gives it) the
1215
+ * update applies only to that body, and is refused with 409 and
1216
+ * `text-changed` otherwise. Strict mode then does not stamp it, unless
1217
+ * `versioned` is true (a batch whose later writes are stamped needs its
1218
+ * first write stamped too).
1219
+ * @param {string} textId - The text ID
1220
+ * @param {any} body - The request body
1221
+ * @param {string} [auditMessage]
1222
+ * @param {{base?: string, versioned?: boolean}} [options]
1223
+ */
1224
+ update: (textId: string, body: any, auditMessage?: string, { base, versioned }?: {
1225
+ base?: string;
1226
+ versioned?: boolean;
1227
+ }) => Promise<any>;
1228
+ /**
1229
+ * Change a text's body by the edits made at the caret: a list of edit
1230
+ * directives as `update` takes them (code-point indices, applied in
1231
+ * order, each index in the body the ones before it left). Only their
1232
+ * net change counts. An insert or a delete stays where it was made, and
1233
+ * a stretch deleted and typed over is read as a whole new body is. The
1234
+ * answer is the text with its new `digest` and `reshape` (the tokens
1235
+ * moved, the spans and vocab links trimmed, the rows deleted). With
1236
+ * `base`, the digest of the body the edits were made on, the edit
1237
+ * applies only to that body and is refused with 409 and `text-changed`
1238
+ * otherwise, and strict mode does not stamp it unless `versioned` is
1239
+ * true. See composeTextEdits and gapsToOps.
1240
+ * @param {string} textId - The text ID
1241
+ * @param {Array<object>} edits - The edit directives
1242
+ * @param {string} [auditMessage]
1243
+ * @param {{base?: string, versioned?: boolean}} [options]
1244
+ */
1245
+ edit: (textId: string, edits: Array<object>, auditMessage?: string, { base, versioned }?: {
1246
+ base?: string;
1247
+ versioned?: boolean;
1248
+ }) => Promise<any>;
1249
+ /**
1250
+ * Replace all metadata of an entity. Keys left out of the new map are removed.
1251
+ * @param {string} id - The entity's ID
1252
+ * @param {object} body - The new metadata map
1253
+ * @param {string} [auditMessage] - Audit message for this write
1254
+ */
1255
+ setMetadata: (id: string, body: object, auditMessage?: string) => Promise<any>;
1256
+ /**
1257
+ * Remove all metadata from an entity.
1258
+ * @param {string} id - The entity's ID
1259
+ * @param {string} [auditMessage] - Audit message for this write
1260
+ */
1261
+ deleteMetadata: (id: string, auditMessage?: string) => Promise<any>;
1262
+ /**
1263
+ * Edit an entity's metadata with a list of ops applied in order, in one operation. `{op: 'set', path, value}` writes value at path, creating missing objects along it; `{op: 'delete', path}` removes the key at path (a no-op when absent). A path is a non-empty array of keys, the first a top-level key. A path through a non-object is refused (400). See metadataOps and applyMetadataOps.
1264
+ * @param {string} id - The entity's ID
1265
+ * @param {MetadataOp[]} body - The metadata ops
1266
+ * @param {string} [auditMessage] - Audit message for this write
1267
+ */
1268
+ patchMetadata: (id: string, body: MetadataOp[], auditMessage?: string) => Promise<any>;
1269
+ };
1270
+ users: {
1271
+ /**
1272
+ * List (or search) users. Transparently follows pagination cursors and
1273
+ * returns the full flat array. Admin-or-maintainer only.
1274
+ * @param {object} [opts]
1275
+ * @param {string} [opts.q] - Filter to users whose display name contains this text, or whose email starts with it (contains it, when the text holds an at sign), case-insensitive
1276
+ */
1277
+ list: ({ q }?: {
1278
+ q?: string;
1279
+ }) => Promise<any[]>;
1280
+ /**
1281
+ * Fetch a single page of users (optionally filtered by `q`).
1282
+ * @param {object} [opts]
1283
+ * @param {string} [opts.q] - Filter to users whose display name contains this text, or whose email starts with it (contains it, when the text holds an at sign), case-insensitive
1284
+ * @param {number} [opts.limit] - Page size (1..1000; server default 100)
1285
+ * @param {string} [opts.cursor] - Opaque cursor from a previous page
1286
+ * @returns {Promise<{entries: Array, nextCursor: (string|null)}>}
1287
+ */
1288
+ listPage: ({ q, limit, cursor }?: {
1289
+ q?: string;
1290
+ limit?: number;
1291
+ cursor?: string;
1292
+ }) => Promise<{
1293
+ entries: any[];
1294
+ nextCursor: (string | null);
1295
+ }>;
1296
+ /**
1297
+ * Async-iterate users page by page; yields each page's entries array.
1298
+ * @param {object} [opts]
1299
+ * @param {string} [opts.q] - Filter to users whose display name contains this text, or whose email starts with it (contains it, when the text holds an at sign), case-insensitive
1300
+ * @param {number} [opts.pageSize] - Per-request page size
1301
+ * @returns {AsyncGenerator<Array>}
1302
+ */
1303
+ iterPages: ({ q, pageSize }?: {
1304
+ q?: string;
1305
+ pageSize?: number;
1306
+ }) => AsyncGenerator<any[]>;
1307
+ /**
1308
+ * Create a new user. Admin only, and not with a named API token (403):
1309
+ * it needs a sign-in token.
1310
+ * @param {string} email - The account's email address. It becomes the
1311
+ * user's id and is what they log in with; it can never be changed.
1312
+ * @param {string} password - The password
1313
+ * @param {boolean} isAdmin - Whether the user is an admin
1314
+ * @param {string} [displayName] - How the user is shown in the UI.
1315
+ * Defaults to the local part of the email.
1316
+ * @param {string} [auditMessage] - Audit message for this write
1317
+ */
1318
+ create: (email: string, password: string, isAdmin: boolean, displayName?: string, auditMessage?: string) => Promise<any>;
1319
+ /**
1320
+ * Get audit log for a user's actions. Transparently follows pagination
1321
+ * cursors and returns the full flat array.
1322
+ * @param {string} userId - The user ID
1323
+ * @param {string} [startTime] - Start of time range
1324
+ * @param {string} [endTime] - End of time range
1325
+ * @param {string[]|string} [opTypes] - Only return operations of these
1326
+ * types, spelled as in an entry's `op/type` (e.g.
1327
+ * `['span-layer/create', 'span-layer/delete']`). An entry appears when
1328
+ * one of its operations matches, carrying only the ones that did.
1329
+ * @param {string[]|string} [kinds] - Only the entries of operations of
1330
+ * these kinds (e.g. `['review', 'guess-adoption']`), each whole
1331
+ */
1332
+ audit: (userId: string, startTime?: string, endTime?: string, opTypes?: string[] | string, kinds?: string[] | string) => Promise<any[]>;
1333
+ /**
1334
+ * One page of the same log, newest-first with `order: "desc"`. Use this
1335
+ * rather than audit() wherever the caller wants the recent end of a log
1336
+ * that may be long: audit() walks every page before it resolves.
1337
+ * @param {string} userId - The user ID
1338
+ * @param {object} [opts]
1339
+ * @param {string} [opts.startTime] - Only entries at or after this instant
1340
+ * @param {string} [opts.endTime] - Only entries at or before this instant
1341
+ * @param {string[]|string} [opts.opTypes] - Only these op types
1342
+ * @param {OperationKind[]|string} [opts.kinds] - Only the entries of operations of these kinds, each whole
1343
+ * @param {"asc"|"desc"} [opts.order] - "desc" pages newest-first
1344
+ * @param {number} [opts.limit] - Page size (1..1000; server default 100)
1345
+ * @param {string} [opts.cursor] - Opaque cursor from a previous page
1346
+ * @param {number} [opts.opsLimit] - Keep only each entry's oldest N
1347
+ * operations in `ops` (1..1000). `opCount` on every entry says how
1348
+ * many it has
1349
+ * @param {string} [opts.entryId] - Read only this entry, not a page
1350
+ * @returns {Promise<{entries: Array, nextCursor: (string|null)}>}
1351
+ */
1352
+ auditPage: (userId: string, { startTime, endTime, opTypes, kinds, order, limit, cursor, opsLimit, entryId }?: {
1353
+ startTime?: string;
1354
+ endTime?: string;
1355
+ opTypes?: string[] | string;
1356
+ kinds?: OperationKind[] | string;
1357
+ order?: "asc" | "desc";
1358
+ limit?: number;
1359
+ cursor?: string;
1360
+ opsLimit?: number;
1361
+ entryId?: string;
1362
+ }) => Promise<{
1363
+ entries: any[];
1364
+ nextCursor: (string | null);
1365
+ }>;
1366
+ /**
1367
+ * Get a user by ID
1368
+ * @param {string} id - The resource ID
1369
+ */
1370
+ get: (id: string) => Promise<any>;
1371
+ /**
1372
+ * Deactivate a user. Users are never hard-deleted: deactivation
1373
+ * rejects their logins and tokens, strips their project memberships
1374
+ * and vocab maintainerships, and revokes their API tokens. The user
1375
+ * stays visible in listings with a deactivated-at timestamp.
1376
+ * Reversible via activate(), which restores login only.
1377
+ * @param {string} id - The resource ID
1378
+ * @param {string} [auditMessage] - Audit message for this write
1379
+ */
1380
+ delete: (id: string, auditMessage?: string) => Promise<any>;
1381
+ /**
1382
+ * Reactivate a deactivated user, restoring their ability to log in.
1383
+ * Project memberships, vocab maintainerships, and API tokens removed
1384
+ * at deactivation are NOT restored — re-grant them deliberately.
1385
+ * @param {string} id - The resource ID
1386
+ * @param {string} [auditMessage] - Audit message for this write
1387
+ */
1388
+ activate: (id: string, auditMessage?: string) => Promise<any>;
1389
+ /**
1390
+ * Modify a user. Admins may change the display name, password, and admin
1391
+ * status of any user. All other users may only modify their own display
1392
+ * name or password. A password change cannot be made with a named API
1393
+ * token (403): it needs a sign-in token.
1394
+ *
1395
+ * A user's id is their email address and is fixed for the life of the
1396
+ * account — it is what they log in with, so nothing can change it.
1397
+ * @param {string} id - The resource ID (the user's email address)
1398
+ * @param {string} [password] - New password
1399
+ * @param {string} [displayName] - New display name
1400
+ * @param {boolean} [isAdmin] - New admin status
1401
+ * @param {string} [auditMessage] - Audit message for this write
1402
+ */
1403
+ update: (id: string, password?: string, displayName?: string, isAdmin?: boolean, auditMessage?: string) => Promise<any>;
1404
+ /**
1405
+ * A token that shows any user's profile picture without an
1406
+ * Authorization header, for an `<img>`, which cannot send one. Resolves
1407
+ * to `{ token, expiresAt }` (`expiresAt` an ISO-8601 instant, a day on by
1408
+ * default). The server refuses it on every route but the picture, and
1409
+ * it stops working when the user signs out or changes password.
1410
+ *
1411
+ * One token serves the whole client: it is kept and handed out again
1412
+ * until under ten minutes of it remain (half its life, for one minted
1413
+ * near the end of a login), calls made while one is being minted share
1414
+ * that request, and it is dropped when the client's token changes.
1415
+ * avatarUrl() uses it.
1416
+ * @param {{renew?: boolean}} [options] - `renew`: mint a new one
1417
+ * whatever is kept, unless one was minted in the last few seconds
1418
+ * (or is being minted), which is shared
1419
+ * @returns {Promise<{token: string, expiresAt: string}>}
1420
+ */
1421
+ avatarToken: ({ renew }?: {
1422
+ renew?: boolean;
1423
+ }) => Promise<{
1424
+ token: string;
1425
+ expiresAt: string;
1426
+ }>;
1427
+ /**
1428
+ * Build a URL for a user's profile picture, for an `<img>` src. The
1429
+ * URL carries the client's avatar token (see avatarToken()), never the
1430
+ * login token.
1431
+ *
1432
+ * Pass the user record's `avatarHash` as the second argument whenever you
1433
+ * have it: the URL then addresses that exact picture, so the browser can
1434
+ * cache it indefinitely and still pick up a replacement the moment the
1435
+ * user changes it. Resolves to null when `avatarHash` is null (the user
1436
+ * has no picture), so callers can fall back to initials without a
1437
+ * wasted request.
1438
+ * @param {string} id - The user ID
1439
+ * @param {string|null} [avatarHash] - The user record's `avatarHash`
1440
+ * @param {{renew?: boolean}} [options] - `renew`: mint a new avatar
1441
+ * token first, for a picture its URL failed to load (the token
1442
+ * stops working when the login it was minted under ends)
1443
+ * @returns {Promise<string|null>}
1444
+ */
1445
+ avatarUrl: (id: string, avatarHash?: string | null, { renew }?: {
1446
+ renew?: boolean;
1447
+ }) => Promise<string | null>;
1448
+ /**
1449
+ * Fetch a user's profile picture as raw bytes. Most callers want
1450
+ * avatarUrl() instead. This one is for non-browser consumers.
1451
+ * @param {string} id - The user ID
1452
+ */
1453
+ getAvatar: (id: string) => Promise<any>;
1454
+ /**
1455
+ * Upload a profile picture. Your own, or anyone's if you are an admin.
1456
+ * The server center-crops to a square, scales to the configured edge
1457
+ * length, and re-encodes, so no client-side resizing is needed. Accepts
1458
+ * PNG, JPEG, WebP, and GIF. Resolves to the updated user record.
1459
+ * @param {string} id - The user ID
1460
+ * @param {File} file - The image to upload
1461
+ * @param {string} [auditMessage] - Audit message for this write
1462
+ */
1463
+ setAvatar: (id: string, file: File, auditMessage?: string) => Promise<any>;
1464
+ /**
1465
+ * Remove a profile picture. Your own, or anyone's if you are an admin.
1466
+ * @param {string} id - The user ID
1467
+ * @param {string} [auditMessage] - Audit message for this write
1468
+ */
1469
+ deleteAvatar: (id: string, auditMessage?: string) => Promise<any>;
1470
+ };
1471
+ userData: {
1472
+ /**
1473
+ * List a user's private data entries ({key, updatedAt}, plus value when
1474
+ * includeValues), ordered by key. Owner or admin only. Transparently
1475
+ * follows pagination cursors and returns the full flat array.
1476
+ *
1477
+ * Narrow with `prefix` (the literal head of a key) and/or `pattern`, a
1478
+ * GLOB over the whole key (`*` any run, `?` one character) — the way to
1479
+ * ask for a key convention identified by a segment in the middle, e.g.
1480
+ * `igt:assistant:*:meta:*` for every conversation's sidebar entry across
1481
+ * every project without dragging down the transcripts beside them.
1482
+ *
1483
+ * `pageSize` is exposed here, and defaults lower than elsewhere, because
1484
+ * one value runs to megabytes (`userDataValueBytes` in
1485
+ * `server.limits()`): a page of them with `includeValues` is the
1486
+ * largest response this API can be asked for. Raise it when the listing
1487
+ * is keys, or the values are known to be small.
1488
+ * @param {string} userId
1489
+ * @param {object} [opts]
1490
+ * @param {string} [opts.prefix] - Only keys starting with this prefix
1491
+ * @param {string} [opts.pattern] - Only keys matching this GLOB
1492
+ * @param {boolean} [opts.includeValues] - Also return each entry's value
1493
+ * @param {number} [opts.pageSize=100] - Entries per request (1..1000)
1494
+ * @returns {Promise<UserDataEntry[]>}
1495
+ */
1496
+ list: (userId: string, { prefix, pattern, includeValues, pageSize }?: {
1497
+ prefix?: string;
1498
+ pattern?: string;
1499
+ includeValues?: boolean;
1500
+ pageSize?: number;
1501
+ }) => Promise<UserDataEntry[]>;
1502
+ /**
1503
+ * One page of a user's private data entries, ordered by key.
1504
+ * @param {string} userId
1505
+ * @param {object} [opts]
1506
+ * @param {string} [opts.prefix] - Only keys starting with this prefix
1507
+ * @param {string} [opts.pattern] - Only keys matching this GLOB
1508
+ * @param {boolean} [opts.includeValues] - Also return each entry's value
1509
+ * @param {number} [opts.limit] - Page size (1..1000; server default 100)
1510
+ * @param {string} [opts.cursor] - Opaque cursor from a previous page
1511
+ * @returns {Promise<Page<UserDataEntry>>}
1512
+ */
1513
+ listPage: (userId: string, { prefix, pattern, includeValues, limit, cursor }?: {
1514
+ prefix?: string;
1515
+ pattern?: string;
1516
+ includeValues?: boolean;
1517
+ limit?: number;
1518
+ cursor?: string;
1519
+ }) => Promise<Page<UserDataEntry>>;
1520
+ /**
1521
+ * Async generator over a user's private data entries, one page at a time.
1522
+ * @param {string} userId
1523
+ * @param {object} [opts]
1524
+ * @param {string} [opts.prefix] - Only keys starting with this prefix
1525
+ * @param {string} [opts.pattern] - Only keys matching this GLOB
1526
+ * @param {boolean} [opts.includeValues] - Also return each entry's value
1527
+ * @param {number} [opts.pageSize=100] - Entries per request (1..1000)
1528
+ * @returns {AsyncGenerator<UserDataEntry[]>}
1529
+ */
1530
+ iterPages: (userId: string, { prefix, pattern, includeValues, pageSize }?: {
1531
+ prefix?: string;
1532
+ pattern?: string;
1533
+ includeValues?: boolean;
1534
+ pageSize?: number;
1535
+ }) => AsyncGenerator<UserDataEntry[]>;
1536
+ /**
1537
+ * Read one private data entry ({key, updatedAt, version, value}); 404 if absent.
1538
+ * @param {string} userId
1539
+ * @param {string} key
1540
+ * @returns {Promise<UserDataEntry & {value: any}>}
1541
+ */
1542
+ get: (userId: string, key: string) => Promise<UserDataEntry & {
1543
+ value: any;
1544
+ }>;
1545
+ /**
1546
+ * Create or replace one private data entry. `value` is any JSON, up to
1547
+ * the server's `userDataValueBytes` (`server.limits()`, 5 MB by
1548
+ * default), and is refused with 413 over it, after which
1549
+ * `server.limits()` answers the figure the server has now. Not audited,
1550
+ * not batchable.
1551
+ *
1552
+ * The server stores it verbatim, but this client recases object keys on
1553
+ * the way out and back like any other body (`myKey` <-> `my-key`), so a
1554
+ * value whose keys are camelCase round-trips unchanged while one keyed
1555
+ * by arbitrary strings does not. Put such a map under a `metadata` key,
1556
+ * which both clients pass through untouched.
1557
+ *
1558
+ * Every write raises the entry's `version` by one, and reads answer it.
1559
+ * With `version`, the write lands only when the entry is still at that
1560
+ * version (0: only when there is no entry), and is otherwise refused with
1561
+ * 409, `error: "version-mismatch"`, and the stored `version` and
1562
+ * `updatedAt` on the error's `responseData`: read it again and make the
1563
+ * change on what is there.
1564
+ * @param {string} userId
1565
+ * @param {string} key
1566
+ * @param {*} value
1567
+ * @param {object} [opts]
1568
+ * @param {number} [opts.version] - The version this write was made from
1569
+ * @returns {Promise<{key: string, updatedAt: string, version: number}>}
1570
+ */
1571
+ put: (userId: string, key: string, value: any, { version }?: {
1572
+ version?: number;
1573
+ }) => Promise<{
1574
+ key: string;
1575
+ updatedAt: string;
1576
+ version: number;
1577
+ }>;
1578
+ /**
1579
+ * Delete one private data entry; 404 if absent.
1580
+ * @param {string} userId
1581
+ * @param {string} key
1582
+ */
1583
+ delete: (userId: string, key: string) => Promise<any>;
1584
+ };
1585
+ apiTokens: {
1586
+ /**
1587
+ * List a user's named API tokens. Never includes the signed token
1588
+ * string itself — that is only returned once, by create().
1589
+ * Transparently follows pagination cursors and returns the full flat array.
1590
+ * @param {string} userId - The user ID who owns the tokens
1591
+ */
1592
+ list: (userId: string) => Promise<any[]>;
1593
+ /**
1594
+ * Fetch a single page of a user's named API tokens.
1595
+ * @param {string} userId - The user ID who owns the tokens
1596
+ * @param {object} [opts]
1597
+ * @param {number} [opts.limit] - Page size (1..1000; server default 100)
1598
+ * @param {string} [opts.cursor] - Opaque cursor from a previous page
1599
+ * @returns {Promise<{entries: Array, nextCursor: (string|null)}>}
1600
+ */
1601
+ listPage: (userId: string, { limit, cursor }?: {
1602
+ limit?: number;
1603
+ cursor?: string;
1604
+ }) => Promise<{
1605
+ entries: any[];
1606
+ nextCursor: (string | null);
1607
+ }>;
1608
+ /**
1609
+ * Async-iterate a user's named API tokens page by page; yields each
1610
+ * page's entries array.
1611
+ * @param {string} userId - The user ID who owns the tokens
1612
+ * @param {object} [opts]
1613
+ * @param {number} [opts.pageSize] - Per-request page size
1614
+ * @returns {AsyncGenerator<Array>}
1615
+ */
1616
+ iterPages: (userId: string, { pageSize }?: {
1617
+ pageSize?: number;
1618
+ }) => AsyncGenerator<any[]>;
1619
+ /**
1620
+ * Mint a named API token for a user. The returned `token` is the signed
1621
+ * credential and is shown ONLY here — store it immediately. API tokens
1622
+ * do not expire and survive password changes / logout; revoke to kill.
1623
+ * A client signed in with a named API token cannot do this (403): it
1624
+ * needs a sign-in token.
1625
+ * @param {string} userId - The user ID who will own the token
1626
+ * @param {string} name - A human label, e.g. "Stanza parser"
1627
+ * @param {string} [auditMessage] - Audit message for this write
1628
+ * @returns {Promise<{id: string, name: string, token: string}>}
1629
+ */
1630
+ create: (userId: string, name: string, auditMessage?: string) => Promise<{
1631
+ id: string;
1632
+ name: string;
1633
+ token: string;
1634
+ }>;
1635
+ /**
1636
+ * Revoke a named API token (soft-revoke; idempotent).
1637
+ * A client signed in with a named API token cannot do this (403): it
1638
+ * needs a sign-in token.
1639
+ * @param {string} userId - The user ID who owns the token
1640
+ * @param {string} tokenId - The token ID to revoke
1641
+ * @param {string} [auditMessage] - Audit message for this write
1642
+ */
1643
+ revoke: (userId: string, tokenId: string, auditMessage?: string) => Promise<any>;
1644
+ };
1645
+ invites: {
1646
+ /**
1647
+ * List invites you minted, oldest first. With `projectId`, lists that
1648
+ * project's invites instead (including co-maintainers'), which requires
1649
+ * maintainer or admin on it. Never includes invite codes — the code is
1650
+ * returned once, by create(), and is not recoverable afterward.
1651
+ * Transparently follows pagination cursors and returns the full flat array.
1652
+ * @param {object} [opts]
1653
+ * @param {string} [opts.projectId] - List this project's invites instead of your own
1654
+ * @param {boolean} [opts.all] - List every invite on the server (admin only)
1655
+ * @returns {Promise<Invite[]>}
1656
+ */
1657
+ list: ({ projectId, all }?: {
1658
+ projectId?: string;
1659
+ all?: boolean;
1660
+ }) => Promise<Invite[]>;
1661
+ /**
1662
+ * Fetch a single page of invites.
1663
+ * @param {object} [opts]
1664
+ * @param {string} [opts.projectId] - List this project's invites instead of your own
1665
+ * @param {boolean} [opts.all] - List every invite on the server (admin only)
1666
+ * @param {number} [opts.limit] - Page size (1..1000; server default 100)
1667
+ * @param {string} [opts.cursor] - Opaque cursor from a previous page
1668
+ * @returns {Promise<Page<Invite>>}
1669
+ */
1670
+ listPage: ({ projectId, all, limit, cursor }?: {
1671
+ projectId?: string;
1672
+ all?: boolean;
1673
+ limit?: number;
1674
+ cursor?: string;
1675
+ }) => Promise<Page<Invite>>;
1676
+ /**
1677
+ * Async-iterate invites page by page; yields each page's entries array.
1678
+ * @param {object} [opts]
1679
+ * @param {string} [opts.projectId] - List this project's invites instead of your own
1680
+ * @param {boolean} [opts.all] - List every invite on the server (admin only)
1681
+ * @param {number} [opts.pageSize] - Per-request page size
1682
+ * @returns {AsyncGenerator<Invite[]>}
1683
+ */
1684
+ iterPages: ({ projectId, all, pageSize }?: {
1685
+ projectId?: string;
1686
+ all?: boolean;
1687
+ pageSize?: number;
1688
+ }) => AsyncGenerator<Invite[]>;
1689
+ /**
1690
+ * Mint an invite. The returned `code` is shown ONLY here — it is never
1691
+ * stored and cannot be recovered, so build and hand off the link now.
1692
+ * Use PlaidClient.inviteUrl() to turn it into one.
1693
+ *
1694
+ * Admins may mint anything. A project maintainer may mint role grants on
1695
+ * projects they maintain, and nothing else: no admin grant, no grantless
1696
+ * invite, no password resets — so for a non-admin, projectId/projectRole
1697
+ * are required in practice (403 without them).
1698
+ *
1699
+ * Needs a signed-in session: a client signed in with a named API token
1700
+ * cannot mint any invite (403).
1701
+ *
1702
+ * EVERY option is optional; `create()` with no arguments mints a
1703
+ * single-use signup link granting nothing but an account. Two pairing
1704
+ * rules the server enforces with a 400: projectId and projectRole must be
1705
+ * given TOGETHER, and targetUserId may not be combined with projectId,
1706
+ * grantAdmin, or a maxUses above 1.
1707
+ * @param {object} [opts]
1708
+ * @param {string} [opts.projectId] - Project the redeemer joins (requires projectRole)
1709
+ * @param {string} [opts.projectRole] - "reader" | "writer" | "maintainer" (requires projectId)
1710
+ * @param {boolean} [opts.grantAdmin] - Make the new account a global admin (admin only)
1711
+ * @param {string} [opts.targetUserId] - Password reset for that user instead of a signup; admin only, single-use, grants nothing
1712
+ * @param {number} [opts.maxUses] - How many accounts this link may create (default 1)
1713
+ * @param {number} [opts.ttlDays] - Days until it expires (default 14, max 365)
1714
+ * @param {string} [opts.note] - Human label shown in your invite list
1715
+ * @param {string} [auditMessage] - Audit message for this write
1716
+ * @returns {Promise<Invite & {code: string}>}
1717
+ */
1718
+ create: ({ projectId, projectRole, grantAdmin, targetUserId, maxUses, ttlDays, note, }?: {
1719
+ projectId?: string;
1720
+ projectRole?: string;
1721
+ grantAdmin?: boolean;
1722
+ targetUserId?: string;
1723
+ maxUses?: number;
1724
+ ttlDays?: number;
1725
+ note?: string;
1726
+ }, auditMessage?: string) => Promise<Invite & {
1727
+ code: string;
1728
+ }>;
1729
+ /**
1730
+ * Revoke an invite, killing the link immediately. Idempotent. Allowed for
1731
+ * the creator, an admin, or a maintainer of the invite's project.
1732
+ * @param {string} id - The invite ID
1733
+ * @param {string} [auditMessage] - Audit message for this write
1734
+ */
1735
+ revoke: (id: string, auditMessage?: string) => Promise<any>;
1736
+ };
1737
+ admin: {
1738
+ /**
1739
+ * Everything about the server in one read: version and JVM uptime,
1740
+ * database size and per-table row counts, media directory usage, backup
1741
+ * configuration and the backups on disk, and the settings an operator
1742
+ * gets asked to confirm. Carries no secrets. Runs a count per table and
1743
+ * walks the media directory, so open it, do not poll it. Admin only.
1744
+ * @returns {Promise<ServerReport>}
1745
+ */
1746
+ server: () => Promise<ServerReport>;
1747
+ /**
1748
+ * Take a database backup right now, outside the nightly schedule.
1749
+ * Resolves to the backup block with `ok` reporting whether the snapshot
1750
+ * succeeded. Uses VACUUM INTO, which only reads, so it is safe while
1751
+ * people are working. Admin only.
1752
+ *
1753
+ * The server answers once the backup is written, which takes minutes on
1754
+ * a large database, so this waits up to `BACKUP_TIMEOUT_MS` (30 minutes)
1755
+ * rather than the client's usual timeout. A proxy in front of the server
1756
+ * may still give up first (a 504): the backup goes on, and its file
1757
+ * shows in `server().backup.backups` once it is written.
1758
+ * @returns {Promise<BackupStatus>}
1759
+ *
1760
+ * outOfBand, as every admin action on the server itself is: none of them
1761
+ * writes project data (see the note at the top of http.js).
1762
+ */
1763
+ backup: () => Promise<BackupStatus>;
1764
+ /**
1765
+ * Documents currently held by an editing lock, with who holds each and
1766
+ * when it expires on its own. Admin only.
1767
+ * @returns {Promise<{entries: Array<{documentId: string, userId: string, expiresAt: number}>}>}
1768
+ */
1769
+ locks: () => Promise<{
1770
+ entries: Array<{
1771
+ documentId: string;
1772
+ userId: string;
1773
+ expiresAt: number;
1774
+ }>;
1775
+ }>;
1776
+ /**
1777
+ * Drop the lock on a document whoever holds it. Idempotent. For a client
1778
+ * that went away without releasing one. Admin only.
1779
+ * @param {string} documentId - The document ID
1780
+ * @returns {Promise<{result: string}>}
1781
+ */
1782
+ releaseLock: (documentId: string) => Promise<{
1783
+ result: string;
1784
+ }>;
1785
+ /**
1786
+ * Live login and invite rate-limit buckets: the address, the account
1787
+ * where there is one, failures inside the window, the limit, and whether
1788
+ * it is currently blocking. Admin only.
1789
+ * @returns {Promise<RateLimitSnapshot>}
1790
+ */
1791
+ rateLimits: () => Promise<RateLimitSnapshot>;
1792
+ /**
1793
+ * Forget recorded rate-limit failures. With `ip`, clears that address,
1794
+ * narrowed to one account with `userId`. With neither, clears every
1795
+ * bucket. Only ever unblocks. Admin only.
1796
+ * @param {object} [opts]
1797
+ * @param {string} [opts.ip] - Clear only this address
1798
+ * @param {string} [opts.userId] - Narrow to one account on that address
1799
+ * @returns {Promise<{result: string}>}
1800
+ */
1801
+ clearRateLimits: ({ ip, userId }?: {
1802
+ ip?: string;
1803
+ userId?: string;
1804
+ }) => Promise<{
1805
+ result: string;
1806
+ }>;
1807
+ /**
1808
+ * What the server has logged, structured and filtered, from an in-memory
1809
+ * buffer kept whether or not a log file is configured. `requests` is one
1810
+ * entry per HTTP request (method, path, status, duration, and who made
1811
+ * it), `events` is everything else, with a stack trace where there was
1812
+ * one. They are buffered separately so a burst of requests cannot evict
1813
+ * an error. Both come newest first, `matched` counts what passed the
1814
+ * filters, and request `stats` describe the filtered set. Covers Plaid's
1815
+ * own log stream since the last restart: for library messages and older
1816
+ * history, see `logFile`. Admin only.
1817
+ * @param {object} [opts]
1818
+ * @param {number} [opts.limit] - Max entries per kind (default 200, max 2000)
1819
+ * @param {string} [opts.q] - Substring of any field, case-insensitive
1820
+ * @param {string} [opts.level] - Minimum level for events, e.g. "warn"
1821
+ * @param {string} [opts.status] - "2xx".."5xx", an exact code, or "failures"
1822
+ * @param {string} [opts.user] - Only requests made by this account
1823
+ * @param {string} [opts.method] - Only requests with this HTTP method
1824
+ * @returns {Promise<LiveLog>}
1825
+ */
1826
+ logs: ({ limit, q, level, status, user, method }?: {
1827
+ limit?: number;
1828
+ q?: string;
1829
+ level?: string;
1830
+ status?: string;
1831
+ user?: string;
1832
+ method?: string;
1833
+ }) => Promise<LiveLog>;
1834
+ /**
1835
+ * The tail of the configured log file, as text lines. The only place
1836
+ * third-party library messages and anything from before the last restart
1837
+ * can be read. Resolves with an `error` string instead of lines when no
1838
+ * log file is configured or it does not exist yet. Admin only.
1839
+ * @param {object} [opts]
1840
+ * @param {number} [opts.lines] - How many lines (default 200, max 2000)
1841
+ * @returns {Promise<{file: (string|null), lines: string[], error?: string}>}
1842
+ */
1843
+ logFile: ({ lines }?: {
1844
+ lines?: number;
1845
+ }) => Promise<{
1846
+ file: (string | null);
1847
+ lines: string[];
1848
+ error?: string;
1849
+ }>;
1850
+ /**
1851
+ * Private user-data entries across every account, each carrying its
1852
+ * `userId`. `/users/:userId/data` has always been owner-or-admin; this
1853
+ * is the same reach across accounts at once. Transparently follows
1854
+ * pagination cursors and returns the full flat array. Admin only.
1855
+ *
1856
+ * Narrow with `prefix` (the literal head of a key) and/or `pattern`, a
1857
+ * GLOB over the whole key (`*` any run, `?` one character) — the way to
1858
+ * ask for a key convention identified by a segment in the middle, e.g.
1859
+ * `igt:assistant:*:meta:*`. Values come only with `includeValues`, and
1860
+ * are recased like any other body (see `userData.put`).
1861
+ * @param {object} [opts]
1862
+ * @param {string} [opts.prefix] - Only keys starting with this
1863
+ * @param {string} [opts.pattern] - Only keys matching this GLOB
1864
+ * @param {boolean} [opts.includeValues] - Also return each entry's value
1865
+ * @returns {Promise<AdminUserDataEntry[]>}
1866
+ */
1867
+ userData: ({ prefix, pattern, includeValues }?: {
1868
+ prefix?: string;
1869
+ pattern?: string;
1870
+ includeValues?: boolean;
1871
+ }) => Promise<AdminUserDataEntry[]>;
1872
+ /**
1873
+ * One page of private user-data entries across accounts, ordered by
1874
+ * (user, key). Admin only.
1875
+ * @param {object} [opts]
1876
+ * @param {string} [opts.prefix] - Only keys starting with this
1877
+ * @param {string} [opts.pattern] - Only keys matching this GLOB
1878
+ * @param {boolean} [opts.includeValues] - Also return each entry's value
1879
+ * @param {number} [opts.limit] - Page size (1..1000; server default 100)
1880
+ * @param {string} [opts.cursor] - Opaque cursor from a previous page
1881
+ * @returns {Promise<Page<AdminUserDataEntry>>}
1882
+ */
1883
+ userDataPage: ({ prefix, pattern, includeValues, limit, cursor }?: {
1884
+ prefix?: string;
1885
+ pattern?: string;
1886
+ includeValues?: boolean;
1887
+ limit?: number;
1888
+ cursor?: string;
1889
+ }) => Promise<Page<AdminUserDataEntry>>;
1890
+ };
1891
+ audit: {
1892
+ /**
1893
+ * The audit log across every project, oldest first. Same fold, window
1894
+ * and op-type filter as the per-project read, with the entity scope
1895
+ * dropped. Admin only. Transparently follows pagination cursors and
1896
+ * returns the full flat array.
1897
+ * @param {object} [opts]
1898
+ * @param {string} [opts.startTime] - Only operations at or after this instant
1899
+ * @param {string} [opts.endTime] - Only operations at or before this instant
1900
+ * @param {string[]|string} [opts.opTypes] - Only these op types (e.g.
1901
+ * `['span-layer/create']`). An entry appears when one of its operations
1902
+ * matches, carrying only the ones that did.
1903
+ * @param {string[]|string} [opts.kinds] - Only the entries of operations
1904
+ * of these kinds (e.g. `['review']`), each whole
1905
+ */
1906
+ list: ({ startTime, endTime, opTypes, kinds }?: {
1907
+ startTime?: string;
1908
+ endTime?: string;
1909
+ opTypes?: string[] | string;
1910
+ kinds?: string[] | string;
1911
+ }) => Promise<any[]>;
1912
+ /**
1913
+ * Fetch a single page of the instance-wide audit log. Admin only.
1914
+ * @param {object} [opts]
1915
+ * @param {string} [opts.startTime] - Only entries at or after this instant
1916
+ * @param {string} [opts.endTime] - Only entries at or before this instant
1917
+ * @param {string[]|string} [opts.opTypes] - Only these op types
1918
+ * @param {OperationKind[]|string} [opts.kinds] - Only the entries of operations of these kinds, each whole
1919
+ * @param {"asc"|"desc"} [opts.order] - "desc" pages newest-first, which
1920
+ * is what a feed wants. A cursor belongs to the direction that made it.
1921
+ * @param {number} [opts.limit] - Page size (1..1000; server default 100)
1922
+ * @param {string} [opts.cursor] - Opaque cursor from a previous page
1923
+ * @param {number} [opts.opsLimit] - Keep only each entry's oldest N
1924
+ * operations in `ops` (1..1000). `opCount` on every entry says how
1925
+ * many it has
1926
+ * @param {string} [opts.entryId] - Read only this entry, not a page
1927
+ * @returns {Promise<{entries: Array, nextCursor: (string|null)}>}
1928
+ */
1929
+ listPage: ({ startTime, endTime, opTypes, kinds, order, limit, cursor, opsLimit, entryId }?: {
1930
+ startTime?: string;
1931
+ endTime?: string;
1932
+ opTypes?: string[] | string;
1933
+ kinds?: OperationKind[] | string;
1934
+ order?: "asc" | "desc";
1935
+ limit?: number;
1936
+ cursor?: string;
1937
+ opsLimit?: number;
1938
+ entryId?: string;
1939
+ }) => Promise<{
1940
+ entries: any[];
1941
+ nextCursor: (string | null);
1942
+ }>;
1943
+ /**
1944
+ * Async-iterate the instance-wide audit log page by page. Admin only.
1945
+ * @param {object} [opts]
1946
+ * @param {string} [opts.startTime] - Only entries at or after this instant
1947
+ * @param {string} [opts.endTime] - Only entries at or before this instant
1948
+ * @param {string[]|string} [opts.opTypes] - Only these op types
1949
+ * @param {OperationKind[]|string} [opts.kinds] - Only the entries of operations of these kinds, each whole
1950
+ * @param {number} [opts.pageSize] - Per-request page size
1951
+ * @returns {AsyncGenerator<Array>}
1952
+ */
1953
+ iterPages: ({ startTime, endTime, opTypes, kinds, pageSize }?: {
1954
+ startTime?: string;
1955
+ endTime?: string;
1956
+ opTypes?: string[] | string;
1957
+ kinds?: OperationKind[] | string;
1958
+ pageSize?: number;
1959
+ }) => AsyncGenerator<any[]>;
1960
+ /**
1961
+ * Per-user activity counts. `changes` is the number of logical actions,
1962
+ * folded the way the audit feed folds them, so one "Confirm word
1963
+ * analysis" counts once however many rows it wrote; `operations` is the
1964
+ * unfolded row count. Only users who did something appear — subtract
1965
+ * from the roster you already hold to find the ones who did not.
1966
+ *
1967
+ * With `projectId`, scoped to that project and open to its maintainers.
1968
+ * Without one, instance-wide and admin only.
1969
+ * @param {object} [opts]
1970
+ * @param {string} [opts.projectId] - Scope to one project
1971
+ * @param {string} [opts.startTime] - Only count at or after this instant
1972
+ * @param {string} [opts.endTime] - Only count at or before this instant
1973
+ * @param {boolean} [opts.daily] - Also return `byDay`, a list of
1974
+ * `{date, changes}` per user, oldest first, at the cost of a second
1975
+ * grouped scan
1976
+ * @returns {Promise<ActivityTallyRow[]>}
1977
+ */
1978
+ tally: ({ projectId, startTime, endTime, daily }?: {
1979
+ projectId?: string;
1980
+ startTime?: string;
1981
+ endTime?: string;
1982
+ daily?: boolean;
1983
+ }) => Promise<ActivityTallyRow[]>;
1984
+ };
1985
+ tokenLayers: {
1986
+ /**
1987
+ * Declare an app namespace's constraints on this layer, replacing that
1988
+ * namespace's list. Refused with 422 and the violations when the layer's
1989
+ * stored data breaks them (see violationsOf).
1990
+ * @param {string} layerId - The layer ID
1991
+ * @param {string} namespace - The declaring app's namespace, e.g. "igt"
1992
+ * @param {LayerConstraint[]} constraints - e.g. [{type: "single-span"}, {type: "value-set", values: ["N"]}]
1993
+ * @param {string} [auditMessage] - Audit message for this write
1994
+ * @param {{expected?: Array<object>|null}} [options] - `expected`: the list read for this
1995
+ * namespace (null when it was absent). The write is then refused with a 409 when the stored
1996
+ * list differs.
1997
+ * @returns {Promise<{constraints: Record<string, LayerConstraint[]>}>} the layer's whole constraint map
1998
+ */
1999
+ setConstraints: (layerId: string, namespace: string, constraints: LayerConstraint[], auditMessage?: string, options?: {
2000
+ expected?: Array<object> | null;
2001
+ }) => Promise<{
2002
+ constraints: Record<string, LayerConstraint[]>;
2003
+ }>;
2004
+ /**
2005
+ * Remove an app namespace's constraints from this layer.
2006
+ * @param {string} layerId - The layer ID
2007
+ * @param {string} namespace - The declaring app's namespace
2008
+ * @param {string} [auditMessage] - Audit message for this write
2009
+ * @param {{expected?: Array<object>|null}} [options] - `expected`, as on setConstraints.
2010
+ */
2011
+ deleteConstraints: (layerId: string, namespace: string, auditMessage?: string, options?: {
2012
+ expected?: Array<object> | null;
2013
+ }) => Promise<any>;
2014
+ /**
2015
+ * The violations the given constraints would meet in this layer's stored
2016
+ * data. Writes nothing.
2017
+ * @param {string} layerId - The layer ID
2018
+ * @param {LayerConstraint[]} constraints - The list to check
2019
+ * @returns {Promise<{violations: ConstraintViolation[], violationCount: number}>}
2020
+ */
2021
+ checkConstraints: (layerId: string, constraints: LayerConstraint[]) => Promise<{
2022
+ violations: ConstraintViolation[];
2023
+ violationCount: number;
2024
+ }>;
2025
+ /**
2026
+ * Apply the remedies of the given constraints' remediable types
2027
+ * (coextensive, single-span, single-link, same-ancestor) to every
2028
+ * violation in this layer's stored data, one operation per document.
2029
+ * With `document`, only that document is repaired, and a writer may
2030
+ * ask. A document another user holds the lock on is left as it is and
2031
+ * listed under `locked`.
2032
+ * @param {string} layerId - The layer ID
2033
+ * @param {LayerConstraint[]} constraints - The list to repair for
2034
+ * @param {string} [auditMessage] - Audit message for this write
2035
+ * @param {{document?: string}} [options]
2036
+ * @returns {Promise<{repaired: ConstraintRepair[], locked: Array<{document: string, lockedBy: string}>, violations: ConstraintViolation[], violationCount: number}>}
2037
+ */
2038
+ repairConstraints: (layerId: string, constraints: LayerConstraint[], auditMessage?: string, options?: {
2039
+ document?: string;
2040
+ }) => Promise<{
2041
+ repaired: ConstraintRepair[];
2042
+ locked: Array<{
2043
+ document: string;
2044
+ lockedBy: string;
2045
+ }>;
2046
+ violations: ConstraintViolation[];
2047
+ violationCount: number;
2048
+ }>;
2049
+ /**
2050
+ * Set a configuration value in an editor namespace.
2051
+ * @param {string} id - The record's ID
2052
+ * @param {string} namespace - The config namespace
2053
+ * @param {string} configKey - The config key
2054
+ * @param {any} configValue - Configuration value to set
2055
+ * @param {string} [auditMessage] - Audit message for this write
2056
+ * @param {{expected?: any}} [options] - `expected`: the value read for this key (null or undefined when it
2057
+ * was absent). The write is then refused with a 409 when the stored value differs.
2058
+ */
2059
+ setConfig: (id: string, namespace: string, configKey: string, configValue: any, auditMessage?: string, options?: {
2060
+ expected?: any;
2061
+ }) => Promise<any>;
2062
+ /**
2063
+ * Remove a configuration value.
2064
+ * @param {string} id - The record's ID
2065
+ * @param {string} namespace - The config namespace
2066
+ * @param {string} configKey - The config key
2067
+ * @param {string} [auditMessage] - Audit message for this write
2068
+ * @param {{expected?: any}} [options] - `expected`, as on setConfig.
2069
+ */
2070
+ deleteConfig: (id: string, namespace: string, configKey: string, auditMessage?: string, options?: {
2071
+ expected?: any;
2072
+ }) => Promise<any>;
2073
+ /**
2074
+ * Create a new token layer.
2075
+ * @param {string} textLayerId - The text layer ID
2076
+ * @param {string} name - The name
2077
+ * @param {string} [overlapMode] - Per-layer, immutable token invariant: "any" (default), "non-overlapping", or "partitioning". On partitioning layers, single token create/update/delete are rejected; use bulkCreate plus split/merge/shift.
2078
+ * @param {string} [parentTokenLayerId] - Optional immutable parent token layer. Tokens in this layer must nest within a parent-layer token; the parent layer must be in the same text layer and be "non-overlapping" or "partitioning" (an "any" parent is rejected). A nested layer may be "any" or "non-overlapping" but not "partitioning" (partitioning is only for root layers), e.g. words (non-overlapping, parent=sentences) within sentences (partitioning).
2079
+ * @param {string} [auditMessage] - Audit message for this write
2080
+ * @param {object} [opts]
2081
+ * @param {string} [opts.id] - The new entity's id, minted by the caller (see uuidv7)
2082
+ */
2083
+ create: (textLayerId: string, name: string, overlapMode?: string, parentTokenLayerId?: string, auditMessage?: string, { id }?: {
2084
+ id?: string;
2085
+ }) => Promise<any>;
2086
+ /**
2087
+ * Get a layer by ID.
2088
+ * @param {string} layerId - The layer ID
2089
+ */
2090
+ get: (layerId: string) => Promise<any>;
2091
+ /**
2092
+ * Delete a layer.
2093
+ * @param {string} layerId - The layer ID
2094
+ * @param {string} [auditMessage] - Audit message for this write
2095
+ */
2096
+ delete: (layerId: string, auditMessage?: string) => Promise<any>;
2097
+ /**
2098
+ * Rename a layer.
2099
+ * @param {string} layerId - The layer ID
2100
+ * @param {string} name - The new name
2101
+ * @param {string} [auditMessage] - Audit message for this write
2102
+ */
2103
+ update: (layerId: string, name: string, auditMessage?: string) => Promise<any>;
2104
+ /**
2105
+ * Move a layer one place in its display order.
2106
+ * @param {string} layerId - The layer ID
2107
+ * @param {string} direction - The direction ("up" or "down")
2108
+ * @param {string} [auditMessage] - Audit message for this write
2109
+ */
2110
+ shift: (layerId: string, direction: string, auditMessage?: string) => Promise<any>;
2111
+ };
2112
+ documents: {
2113
+ /**
2114
+ * Get audit log for a document. Transparently follows pagination cursors
2115
+ * and returns the full flat array. Each entry, and each of its `ops`,
2116
+ * says what kind of credential made it as `credential`: `login`,
2117
+ * `named-token` or `delegated` (absent on older operations, `service`
2118
+ * on some from 2026-10-06 to 2026-10-08),
2119
+ * beside `apiToken` (the named token's id and name) when there was one.
2120
+ * @param {string} documentId - The document ID
2121
+ * @param {string} [startTime] - Start of time range
2122
+ * @param {string} [endTime] - End of time range
2123
+ * @param {string[]|string} [opTypes] - Only return operations of these
2124
+ * types, spelled as in an entry's `op/type` (e.g.
2125
+ * `['span-layer/create', 'span-layer/delete']`). An entry appears when
2126
+ * one of its operations matches, carrying only the ones that did.
2127
+ * @param {string[]|string} [kinds] - Only the entries of operations of
2128
+ * these kinds (e.g. `['review', 'guess-adoption']`), each whole
2129
+ */
2130
+ audit: (documentId: string, startTime?: string, endTime?: string, opTypes?: string[] | string, kinds?: string[] | string) => Promise<any[]>;
2131
+ /**
2132
+ * One page of the same log, newest-first with `order: "desc"`. Use this
2133
+ * rather than audit() wherever the caller wants the recent end of a log
2134
+ * that may be long: audit() walks every page before it resolves.
2135
+ * @param {string} documentId - The document ID
2136
+ * @param {object} [opts]
2137
+ * @param {string} [opts.startTime] - Only entries at or after this instant
2138
+ * @param {string} [opts.endTime] - Only entries at or before this instant
2139
+ * @param {string[]|string} [opts.opTypes] - Only these op types
2140
+ * @param {OperationKind[]|string} [opts.kinds] - Only the entries of operations of these kinds, each whole
2141
+ * @param {"asc"|"desc"} [opts.order] - "desc" pages newest-first
2142
+ * @param {number} [opts.limit] - Page size (1..1000; server default 100)
2143
+ * @param {string} [opts.cursor] - Opaque cursor from a previous page
2144
+ * @param {number} [opts.opsLimit] - Keep only each entry's oldest N
2145
+ * operations in `ops` (1..1000). `opCount` on every entry says how
2146
+ * many it has
2147
+ * @param {string} [opts.entryId] - Read only this entry, not a page
2148
+ * @returns {Promise<{entries: Array, nextCursor: (string|null)}>}
2149
+ */
2150
+ auditPage: (documentId: string, { startTime, endTime, opTypes, kinds, order, limit, cursor, opsLimit, entryId }?: {
2151
+ startTime?: string;
2152
+ endTime?: string;
2153
+ opTypes?: string[] | string;
2154
+ kinds?: OperationKind[] | string;
2155
+ order?: "asc" | "desc";
2156
+ limit?: number;
2157
+ cursor?: string;
2158
+ opsLimit?: number;
2159
+ entryId?: string;
2160
+ }) => Promise<{
2161
+ entries: any[];
2162
+ nextCursor: (string | null);
2163
+ }>;
2164
+ /**
2165
+ * Restore a document to its state at an earlier time, as one
2166
+ * operation: what was deleted since then comes back under its original
2167
+ * id, what was added since is removed, and what changed is set back,
2168
+ * across every layer. A layer deleted since then, or a vocabulary entry
2169
+ * that no longer exists, is skipped and reported under `skipped`.
2170
+ * Resolves to a summary of the changes. Maintainers only.
2171
+ * @param {string} documentId - The document ID
2172
+ * @param {string} asOf - The moment to go back to (ISO-8601 instant),
2173
+ * typically a history entry's `endTime`
2174
+ * @param {{dryRun?: boolean}} [options] - `{ dryRun }`: with `dryRun` true nothing
2175
+ * is written and the summary says what would change
2176
+ * @param {string} [auditMessage] - Custom audit message for this operation
2177
+ */
2178
+ restore: (documentId: string, asOf: string, { dryRun }?: {
2179
+ dryRun?: boolean;
2180
+ }, auditMessage?: string) => Promise<any>;
2181
+ /**
2182
+ * Get a document. Set `includeBody` to true to include all data.
2183
+ *
2184
+ * `layers` narrows a body read to the layers you name (ids of any kind:
2185
+ * text, token, span, or relation). A layer comes back when it is named
2186
+ * or is an ancestor of a named layer, and carries its own
2187
+ * texts/tokens/spans/relations/vocabs only when it is itself named — so
2188
+ * name the text layer too if you also want the text body. An id that is
2189
+ * not a layer of this document's project is an error, not a quietly
2190
+ * smaller response. Requires `includeBody`.
2191
+ * @param {string} documentId - The document ID
2192
+ * @param {boolean} [includeBody] - Include document body data
2193
+ * @param {string} [asOf] - Temporal query timestamp
2194
+ * @param {string[]|string} [layers] - Layer ids to restrict a body read to
2195
+ */
2196
+ get: (documentId: string, includeBody?: boolean, asOf?: string, layers?: string[] | string) => Promise<any>;
2197
+ /**
2198
+ * Delete a document and all data contained.
2199
+ * @param {string} documentId - The document ID
2200
+ * @param {string} [auditMessage] - Audit message for this write
2201
+ */
2202
+ delete: (documentId: string, auditMessage?: string) => Promise<any>;
2203
+ /**
2204
+ * Update a document's name.
2205
+ * @param {string} documentId - The document ID
2206
+ * @param {string} name - The name
2207
+ * @param {string} [auditMessage] - Audit message for this write
2208
+ */
2209
+ update: (documentId: string, name: string, auditMessage?: string) => Promise<any>;
2210
+ /**
2211
+ * Create a new document in a project.
2212
+ * @param {string} projectId - The project ID
2213
+ * @param {string} name - The name
2214
+ * @param {any} [metadata] - Metadata map. Omit to leave unset; pass null to send JSON null.
2215
+ * @param {string} [auditMessage] - Audit message for this write
2216
+ * @param {object} [opts]
2217
+ * @param {string} [opts.id] - The new entity's id, minted by the caller (see uuidv7)
2218
+ */
2219
+ create: (projectId: string, name: string, metadata?: any, auditMessage?: string, { id }?: {
2220
+ id?: string;
2221
+ }) => Promise<any>;
2222
+ /**
2223
+ * Copy a document and everything in it into a new document of the same
2224
+ * project, as one operation. The copy shares the source's layers and
2225
+ * the vocabulary entries its links name, and holds the source's texts,
2226
+ * tokens, spans, relations and vocab links under fresh ids, with their
2227
+ * metadata. Comments do not travel. The media file does, unless
2228
+ * `includeMedia` is false. Resolves to `{ id }`, plus `mediaError` when
2229
+ * the source had media the copy could not take with it.
2230
+ * @param {string} documentId - The document to copy
2231
+ * @param {string} name - The new document's name
2232
+ * @param {{includeMedia?: boolean, id?: string}} [options] - `{ includeMedia }`: false leaves the media
2233
+ * file behind
2234
+ * @param {string} [auditMessage] - Custom audit message for this operation
2235
+ * @returns {Promise<{id: string, mediaError?: string}>}
2236
+ */
2237
+ copy: (documentId: string, name: string, { includeMedia, id }?: {
2238
+ includeMedia?: boolean;
2239
+ id?: string;
2240
+ }, auditMessage?: string) => Promise<{
2241
+ id: string;
2242
+ mediaError?: string;
2243
+ }>;
2244
+ /**
2245
+ * Replace all metadata of an entity. Keys left out of the new map are removed.
2246
+ * @param {string} id - The entity's ID
2247
+ * @param {object} body - The new metadata map
2248
+ * @param {string} [auditMessage] - Audit message for this write
2249
+ */
2250
+ setMetadata: (id: string, body: object, auditMessage?: string) => Promise<any>;
2251
+ /**
2252
+ * Remove all metadata from an entity.
2253
+ * @param {string} id - The entity's ID
2254
+ * @param {string} [auditMessage] - Audit message for this write
2255
+ */
2256
+ deleteMetadata: (id: string, auditMessage?: string) => Promise<any>;
2257
+ /**
2258
+ * Edit an entity's metadata with a list of ops applied in order, in one operation. `{op: 'set', path, value}` writes value at path, creating missing objects along it; `{op: 'delete', path}` removes the key at path (a no-op when absent). A path is a non-empty array of keys, the first a top-level key. A path through a non-object is refused (400). See metadataOps and applyMetadataOps.
2259
+ * @param {string} id - The entity's ID
2260
+ * @param {MetadataOp[]} body - The metadata ops
2261
+ * @param {string} [auditMessage] - Audit message for this write
2262
+ */
2263
+ patchMetadata: (id: string, body: MetadataOp[], auditMessage?: string) => Promise<any>;
2264
+ /**
2265
+ * Check the lock status of a document.
2266
+ * @param {string} documentId - The document ID
2267
+ */
2268
+ checkLock: (documentId: string) => Promise<any>;
2269
+ /**
2270
+ * Acquire a document lock as a new holder.
2271
+ *
2272
+ * The answer's `lockId` names the holder: `renewLock` and `releaseLock`
2273
+ * take it. While the lock is held, a second acquire is refused with
2274
+ * HTTP 423, whoever makes it, this user included.
2275
+ *
2276
+ * `newLockId` names the holder from the client's side (a fresh UUID). An
2277
+ * acquire whose answer never arrived can then be sent again, which
2278
+ * answers 200 while that holder has the lock, or released. Without it
2279
+ * the server mints the id, and a lost answer leaves a lock nobody can
2280
+ * release until it expires.
2281
+ *
2282
+ * outOfBand: the lock is a signal, not project data (see the note at
2283
+ * the top of http.js). Queued on a batch it would be taken only at
2284
+ * submit, after every write it was meant to guard, and until then answer
2285
+ * success to a caller that does not hold it and cannot see the 423
2286
+ * saying somebody else does.
2287
+ * @param {string} documentId - The document ID
2288
+ * @param {string} [auditMessage]
2289
+ * @param {string} [newLockId] - A holder id this client minted
2290
+ */
2291
+ acquireLock: (documentId: string, auditMessage?: string, newLockId?: string) => Promise<any>;
2292
+ /**
2293
+ * Renew the lock `lockId` holds while it is live. HTTP 423 if another
2294
+ * holder has it, and also once it has expired or been dropped, even when
2295
+ * nobody holds the document now: a renewal never takes a free document.
2296
+ * outOfBand, for the same reason as acquireLock.
2297
+ * @param {string} documentId - The document ID
2298
+ * @param {string} lockId - The `lockId` acquireLock answered with
2299
+ * @param {string} [auditMessage] - Audit message for this write
2300
+ */
2301
+ renewLock: (documentId: string, lockId: string, auditMessage?: string) => Promise<any>;
2302
+ /**
2303
+ * Release the lock `lockId` holds. Idempotent: a lock that holder no
2304
+ * longer has is left alone. outOfBand, for the same reason as
2305
+ * acquireLock: queued, the lock would be held until the batch submits,
2306
+ * and not released at all if it aborts.
2307
+ * @param {string} documentId - The document ID
2308
+ * @param {string} lockId - The `lockId` acquireLock answered with
2309
+ * @param {string} [auditMessage] - Audit message for this write
2310
+ */
2311
+ releaseLock: (documentId: string, lockId: string, auditMessage?: string) => Promise<any>;
2312
+ /**
2313
+ * Hold this document's server-enforced lock for the length of `fn`,
2314
+ * releasing it on the way out (including on error). Resolves to what
2315
+ * `fn` returned.
2316
+ *
2317
+ * await client.documents.locked(docId, async () => {
2318
+ * // delete + recreate tokens
2319
+ * });
2320
+ *
2321
+ * Wrap any multi-step, server-side mutation of a document that must not
2322
+ * interleave with a human editor or another service, e.g. a parser or
2323
+ * tokenizer that deletes and recreates a document's tokens, spans and
2324
+ * relations. A single atomic call does not need it. While the lock is
2325
+ * held, writes to the document by ANOTHER user are refused with HTTP
2326
+ * 423; the holder's own writes pass and renew it. If anyone already
2327
+ * holds it, another block of this same user included, this rejects with
2328
+ * a readable 423 and `fn` does not run.
2329
+ *
2330
+ * The lock is renewed for as long as `fn` runs, so work that computes
2331
+ * for minutes before it writes holds the lock the whole time rather than
2332
+ * only for its first minute. If a renewal fails the lock is gone: every
2333
+ * later write from this client throws `DocumentLockLost`, and a block
2334
+ * that got to the end anyway ends with that error rather than reporting
2335
+ * success. `fn` receives a lock handle and may read `lock.lost` (or call
2336
+ * `lock.raiseIfLost()`) to give up sooner.
2337
+ *
2338
+ * The lock is per HOLDER: each block is its own, named by
2339
+ * `lock.lockId`, and only that id renews or releases it. NOT
2340
+ * re-entrant: a nested `locked()` block on one document is a second
2341
+ * holder and gets the 423. Lock at exactly one level per call path.
2342
+ * The block mints its holder id and sends it with the acquire, so an
2343
+ * acquire whose answer was lost is sent again (up to three tries) and,
2344
+ * if none is answered, released rather than left to expire. A
2345
+ * lost lock is recorded on the CLIENT, like strict mode, so it stops
2346
+ * every write the client makes (on any batch of it too) and not only the
2347
+ * ones this block makes.
2348
+ * @template T
2349
+ * @param {string} documentId - The document ID
2350
+ * @param {(lock: import("./documentLock.js").DocumentLock) => T | Promise<T>} fn - The work to run while holding it
2351
+ * @param {{keepAlive?: boolean}} [options] - `{ keepAlive }`: renew on a timer (default true)
2352
+ * @returns {Promise<T>}
2353
+ */
2354
+ locked: <T>(documentId: string, fn: (lock: import("./documentLock.js").DocumentLock) => T | Promise<T>, options?: {
2355
+ keepAlive?: boolean;
2356
+ }) => Promise<T>;
2357
+ /**
2358
+ * Get the media file for a document. Media is not versioned, so there is
2359
+ * no as-of form: the route refuses the parameter. Prefer the document's
2360
+ * own `mediaUrl`, which carries the file's version for caching.
2361
+ * @param {string} documentId - The document ID
2362
+ * @returns {Promise<ArrayBuffer>}
2363
+ */
2364
+ getMedia: (documentId: string) => Promise<ArrayBuffer>;
2365
+ /**
2366
+ * Get a link that plays the document's recording without an
2367
+ * Authorization header, for an audio or video element's `src`, which
2368
+ * cannot send one. `url` is the document's media URL with a
2369
+ * `media-token` added, resolved against the client's base URL. The token
2370
+ * opens only this recording, for this user, and the server refuses it on
2371
+ * every other route. It expires at `expiresAt` (an ISO-8601 instant, six
2372
+ * hours on by default), and sooner when the user signs out, changes
2373
+ * password or loses access to the project: ask for a new link then. A
2374
+ * document with no recording is a 404. Writes nothing, so it takes no
2375
+ * Idempotency-Key and goes over the wire when made on a batch.
2376
+ * @param {string} documentId - The document ID
2377
+ * @returns {Promise<{url: string, expiresAt: string}>}
2378
+ */
2379
+ mediaLink: (documentId: string) => Promise<{
2380
+ url: string;
2381
+ expiresAt: string;
2382
+ }>;
2383
+ /**
2384
+ * Upload a media file for a document. Uses Apache Tika for content validation.
2385
+ * A document that already has a recording refuses it with a 409
2386
+ * (`media-exists`, and the current `media-url`): delete that one first.
2387
+ * A WAV whose samples are not PCM, 32-bit float, A-law or mu-law (IMA or
2388
+ * MS ADPCM, GSM, 64-bit float and the rest), which browsers cannot play,
2389
+ * is refused with a 415 whose `error` names its coding.
2390
+ * @param {string} documentId - The document ID
2391
+ * @param {File} file - The file to upload
2392
+ * @param {string} [auditMessage] - Custom audit-log message for this write
2393
+ * @param {{onProgress?: (progress: {loaded: number, total: number | null}) => void}} [options] - `{ onProgress }`: called with `{ loaded, total }` (bytes) as the file goes up. In a browser the upload then travels by XMLHttpRequest, and the request timeout only fires when the upload stalls, not on total time.
2394
+ */
2395
+ uploadMedia: (documentId: string, file: File, auditMessage?: string, { onProgress }?: {
2396
+ onProgress?: (progress: {
2397
+ loaded: number;
2398
+ total: number | null;
2399
+ }) => void;
2400
+ }) => Promise<any>;
2401
+ /**
2402
+ * Delete media file for a document
2403
+ * @param {string} documentId - The document ID
2404
+ * @param {string} [auditMessage] - Audit message for this write
2405
+ * @param {{mediaVersion?: string}} [options] - `mediaVersion`: the
2406
+ * recording meant, the `?v=` of the document's `mediaUrl`. The delete
2407
+ * is refused with a 409 (`media-changed`, and the current `media-url`)
2408
+ * when the stored recording is another one.
2409
+ */
2410
+ deleteMedia: (documentId: string, auditMessage?: string, { mediaVersion }?: {
2411
+ mediaVersion?: string;
2412
+ }) => Promise<any>;
2413
+ };
2414
+ projects: {
2415
+ /**
2416
+ * Assign a user as a maintainer for this project.
2417
+ * @param {string} id - The resource ID
2418
+ * @param {string} userId - The user ID
2419
+ * @param {string} [auditMessage] - Audit message for this write
2420
+ */
2421
+ addMaintainer: (id: string, userId: string, auditMessage?: string) => Promise<any>;
2422
+ /**
2423
+ * Remove a user's maintainer privileges for this project.
2424
+ * @param {string} id - The resource ID
2425
+ * @param {string} userId - The user ID
2426
+ * @param {string} [auditMessage] - Audit message for this write
2427
+ */
2428
+ removeMaintainer: (id: string, userId: string, auditMessage?: string) => Promise<any>;
2429
+ /**
2430
+ * Get audit log for a project. Transparently follows pagination cursors
2431
+ * and returns the full flat array. Each entry, and each of its `ops`,
2432
+ * says what kind of credential made it as `credential`: `login`,
2433
+ * `named-token` or `delegated` (absent on older operations, `service`
2434
+ * on some from 2026-10-06 to 2026-10-08),
2435
+ * beside `apiToken` (the named token's id and name) when there was one.
2436
+ * @param {string} projectId - The project ID
2437
+ * @param {string} [startTime] - Start of time range
2438
+ * @param {string} [endTime] - End of time range
2439
+ * @param {string[]|string} [opTypes] - Only return operations of these
2440
+ * types, spelled as in an entry's `op/type` (e.g.
2441
+ * `['span-layer/create', 'span-layer/delete']`). An entry appears when
2442
+ * one of its operations matches, carrying only the ones that did.
2443
+ * @param {string[]|string} [kinds] - Only the entries of operations of
2444
+ * these kinds (e.g. `['review', 'guess-adoption']`), each whole
2445
+ */
2446
+ audit: (projectId: string, startTime?: string, endTime?: string, opTypes?: string[] | string, kinds?: string[] | string) => Promise<any[]>;
2447
+ /**
2448
+ * One page of the same log, newest-first with `order: "desc"`. Use this
2449
+ * rather than audit() wherever the caller wants the recent end of a log
2450
+ * that may be long: audit() walks every page before it resolves.
2451
+ * @param {string} projectId - The project ID
2452
+ * @param {object} [opts]
2453
+ * @param {string} [opts.startTime] - Only entries at or after this instant
2454
+ * @param {string} [opts.endTime] - Only entries at or before this instant
2455
+ * @param {string[]|string} [opts.opTypes] - Only these op types
2456
+ * @param {OperationKind[]|string} [opts.kinds] - Only the entries of operations of these kinds, each whole
2457
+ * @param {"asc"|"desc"} [opts.order] - "desc" pages newest-first
2458
+ * @param {number} [opts.limit] - Page size (1..1000; server default 100)
2459
+ * @param {string} [opts.cursor] - Opaque cursor from a previous page
2460
+ * @param {number} [opts.opsLimit] - Keep only each entry's oldest N
2461
+ * operations in `ops` (1..1000). `opCount` on every entry says how
2462
+ * many it has
2463
+ * @param {string} [opts.entryId] - Read only this entry, not a page
2464
+ * @returns {Promise<{entries: Array, nextCursor: (string|null)}>}
2465
+ */
2466
+ auditPage: (projectId: string, { startTime, endTime, opTypes, kinds, order, limit, cursor, opsLimit, entryId }?: {
2467
+ startTime?: string;
2468
+ endTime?: string;
2469
+ opTypes?: string[] | string;
2470
+ kinds?: OperationKind[] | string;
2471
+ order?: "asc" | "desc";
2472
+ limit?: number;
2473
+ cursor?: string;
2474
+ opsLimit?: number;
2475
+ entryId?: string;
2476
+ }) => Promise<{
2477
+ entries: any[];
2478
+ nextCursor: (string | null);
2479
+ }>;
2480
+ /**
2481
+ * When the calling user last wrote to each document in a project, as a
2482
+ * `{documentId: timestamp}` map. Documents they have never written to
2483
+ * are absent. One request covers a whole document list.
2484
+ *
2485
+ * The response is NOT key-transformed: its keys are document ids, and
2486
+ * camelCasing would mangle the hyphens in a UUID.
2487
+ * @param {string} projectId - The project ID
2488
+ * @returns {Promise<Object<string, string>>}
2489
+ */
2490
+ myLastEdits: (projectId: string) => Promise<{
2491
+ [x: string]: string;
2492
+ }>;
2493
+ /**
2494
+ * Link a vocabulary to a project.
2495
+ * @param {string} id - The resource ID
2496
+ * @param {string} vocabId - The vocab layer ID
2497
+ * @param {string} [auditMessage] - Audit message for this write
2498
+ */
2499
+ linkVocab: (id: string, vocabId: string, auditMessage?: string) => Promise<any>;
2500
+ /**
2501
+ * Unlink a vocabulary from a project.
2502
+ * @param {string} id - The resource ID
2503
+ * @param {string} vocabId - The vocab layer ID
2504
+ * @param {string} [auditMessage] - Audit message for this write
2505
+ */
2506
+ unlinkVocab: (id: string, vocabId: string, auditMessage?: string) => Promise<any>;
2507
+ /**
2508
+ * Get a project by ID. To fetch the project's documents, use
2509
+ * listDocuments(id) — the include-documents flag has been removed.
2510
+ * @param {string} id - The resource ID
2511
+ */
2512
+ get: (id: string) => Promise<any>;
2513
+ /**
2514
+ * List all documents in a project. Transparently follows pagination
2515
+ * cursors and returns the full flat array.
2516
+ *
2517
+ * Note: this endpoint does not support temporal (`as-of`) queries; the
2518
+ * server rejects `?as-of=` on the documents-list route with a 400.
2519
+ * @param {string} id - The project ID
2520
+ */
2521
+ listDocuments: (id: string) => Promise<any[]>;
2522
+ /**
2523
+ * Fetch a single page of a project's documents.
2524
+ *
2525
+ * Note: this endpoint does not support temporal (`as-of`) queries; the
2526
+ * server rejects `?as-of=` on the documents-list route with a 400.
2527
+ * @param {string} id - The project ID
2528
+ * @param {object} [opts]
2529
+ * @param {number} [opts.limit] - Page size (1..1000; server default 100)
2530
+ * @param {string} [opts.cursor] - Opaque cursor from a previous page
2531
+ * @returns {Promise<{entries: Array, nextCursor: (string|null)}>}
2532
+ */
2533
+ listDocumentsPage: (id: string, { limit, cursor }?: {
2534
+ limit?: number;
2535
+ cursor?: string;
2536
+ }) => Promise<{
2537
+ entries: any[];
2538
+ nextCursor: (string | null);
2539
+ }>;
2540
+ /**
2541
+ * Async-iterate a project's documents page by page; yields each page's
2542
+ * entries array.
2543
+ *
2544
+ * Note: this endpoint does not support temporal (`as-of`) queries; the
2545
+ * server rejects `?as-of=` on the documents-list route with a 400.
2546
+ * @param {string} id - The project ID
2547
+ * @param {object} [opts]
2548
+ * @param {number} [opts.pageSize] - Per-request page size
2549
+ * @returns {AsyncGenerator<Array>}
2550
+ */
2551
+ iterDocuments: (id: string, { pageSize }?: {
2552
+ pageSize?: number;
2553
+ }) => AsyncGenerator<any[]>;
2554
+ /**
2555
+ * Delete a project and everything in it. This is irrecoverable. The
2556
+ * project is gone when this returns, and what it holds is removed on
2557
+ * the server afterwards.
2558
+ * @param {string} id - The resource ID
2559
+ * @param {string} [auditMessage] - Custom audit-log message
2560
+ * @param {object} [options]
2561
+ * @param {number} [options.timeout] - Per-request timeout in ms, the client's own by default (0/null disables)
2562
+ */
2563
+ delete: (id: string, auditMessage?: string, { timeout }?: {
2564
+ timeout?: number;
2565
+ }) => Promise<any>;
2566
+ /**
2567
+ * Update a project's name.
2568
+ * @param {string} id - The resource ID
2569
+ * @param {string} name - The name
2570
+ * @param {string} [auditMessage] - Audit message for this write
2571
+ */
2572
+ update: (id: string, name: string, auditMessage?: string) => Promise<any>;
2573
+ /**
2574
+ * List all projects accessible to user. Transparently follows pagination
2575
+ * cursors and returns the full flat array.
2576
+ */
2577
+ list: () => Promise<any[]>;
2578
+ /**
2579
+ * Fetch a single page of projects.
2580
+ * @param {object} [opts]
2581
+ * @param {number} [opts.limit] - Page size (1..1000; server default 100)
2582
+ * @param {string} [opts.cursor] - Opaque cursor from a previous page
2583
+ * @returns {Promise<{entries: Array, nextCursor: (string|null)}>}
2584
+ */
2585
+ listPage: ({ limit, cursor }?: {
2586
+ limit?: number;
2587
+ cursor?: string;
2588
+ }) => Promise<{
2589
+ entries: any[];
2590
+ nextCursor: (string | null);
2591
+ }>;
2592
+ /**
2593
+ * Async-iterate projects page by page; yields each page's entries array.
2594
+ * @param {object} [opts]
2595
+ * @param {number} [opts.pageSize] - Per-request page size
2596
+ * @returns {AsyncGenerator<Array>}
2597
+ */
2598
+ iterPages: ({ pageSize }?: {
2599
+ pageSize?: number;
2600
+ }) => AsyncGenerator<any[]>;
2601
+ /**
2602
+ * Create a new project. Note: this also registers the user as a maintainer.
2603
+ * @param {string} name - The name
2604
+ * @param {string} [auditMessage] - Audit message for this write
2605
+ * @param {object} [opts]
2606
+ * @param {string} [opts.id] - The new entity's id, minted by the caller (see uuidv7)
2607
+ */
2608
+ create: (name: string, auditMessage?: string, { id }?: {
2609
+ id?: string;
2610
+ }) => Promise<any>;
2611
+ /**
2612
+ * Set a configuration value in an editor namespace.
2613
+ * @param {string} id - The record's ID
2614
+ * @param {string} namespace - The config namespace
2615
+ * @param {string} configKey - The config key
2616
+ * @param {any} configValue - Configuration value to set
2617
+ * @param {string} [auditMessage] - Audit message for this write
2618
+ * @param {{expected?: any}} [options] - `expected`: the value read for this key (null or undefined when it
2619
+ * was absent). The write is then refused with a 409 when the stored value differs.
2620
+ */
2621
+ setConfig: (id: string, namespace: string, configKey: string, configValue: any, auditMessage?: string, options?: {
2622
+ expected?: any;
2623
+ }) => Promise<any>;
2624
+ /**
2625
+ * Remove a configuration value.
2626
+ * @param {string} id - The record's ID
2627
+ * @param {string} namespace - The config namespace
2628
+ * @param {string} configKey - The config key
2629
+ * @param {string} [auditMessage] - Audit message for this write
2630
+ * @param {{expected?: any}} [options] - `expected`, as on setConfig.
2631
+ */
2632
+ deleteConfig: (id: string, namespace: string, configKey: string, auditMessage?: string, options?: {
2633
+ expected?: any;
2634
+ }) => Promise<any>;
2635
+ /**
2636
+ * Set a user's access level to read and write for this project.
2637
+ * @param {string} id - The resource ID
2638
+ * @param {string} userId - The user ID
2639
+ * @param {string} [auditMessage] - Audit message for this write
2640
+ */
2641
+ addWriter: (id: string, userId: string, auditMessage?: string) => Promise<any>;
2642
+ /**
2643
+ * Remove a user's writer privileges for this project.
2644
+ * @param {string} id - The resource ID
2645
+ * @param {string} userId - The user ID
2646
+ * @param {string} [auditMessage] - Audit message for this write
2647
+ */
2648
+ removeWriter: (id: string, userId: string, auditMessage?: string) => Promise<any>;
2649
+ /**
2650
+ * Set a user's access level to read-only for this project.
2651
+ * @param {string} id - The resource ID
2652
+ * @param {string} userId - The user ID
2653
+ * @param {string} [auditMessage] - Audit message for this write
2654
+ */
2655
+ addReader: (id: string, userId: string, auditMessage?: string) => Promise<any>;
2656
+ /**
2657
+ * Remove a user's reader privileges for this project.
2658
+ * @param {string} id - The resource ID
2659
+ * @param {string} userId - The user ID
2660
+ * @param {string} [auditMessage] - Audit message for this write
2661
+ */
2662
+ removeReader: (id: string, userId: string, auditMessage?: string) => Promise<any>;
2663
+ };
2664
+ textLayers: {
2665
+ /**
2666
+ * Create a new text layer for a project.
2667
+ * @param {string} projectId - The project ID
2668
+ * @param {string} name - The name
2669
+ * @param {string} [auditMessage] - Audit message for this write
2670
+ * @param {object} [opts]
2671
+ * @param {string} [opts.id] - The new entity's id, minted by the caller (see uuidv7)
2672
+ */
2673
+ create: (projectId: string, name: string, auditMessage?: string, { id }?: {
2674
+ id?: string;
2675
+ }) => Promise<any>;
2676
+ /**
2677
+ * Get a layer by ID.
2678
+ * @param {string} layerId - The layer ID
2679
+ */
2680
+ get: (layerId: string) => Promise<any>;
2681
+ /**
2682
+ * Delete a layer.
2683
+ * @param {string} layerId - The layer ID
2684
+ * @param {string} [auditMessage] - Audit message for this write
2685
+ */
2686
+ delete: (layerId: string, auditMessage?: string) => Promise<any>;
2687
+ /**
2688
+ * Rename a layer.
2689
+ * @param {string} layerId - The layer ID
2690
+ * @param {string} name - The new name
2691
+ * @param {string} [auditMessage] - Audit message for this write
2692
+ */
2693
+ update: (layerId: string, name: string, auditMessage?: string) => Promise<any>;
2694
+ /**
2695
+ * Move a layer one place in its display order.
2696
+ * @param {string} layerId - The layer ID
2697
+ * @param {string} direction - The direction ("up" or "down")
2698
+ * @param {string} [auditMessage] - Audit message for this write
2699
+ */
2700
+ shift: (layerId: string, direction: string, auditMessage?: string) => Promise<any>;
2701
+ /**
2702
+ * Set a configuration value in an editor namespace.
2703
+ * @param {string} id - The record's ID
2704
+ * @param {string} namespace - The config namespace
2705
+ * @param {string} configKey - The config key
2706
+ * @param {any} configValue - Configuration value to set
2707
+ * @param {string} [auditMessage] - Audit message for this write
2708
+ * @param {{expected?: any}} [options] - `expected`: the value read for this key (null or undefined when it
2709
+ * was absent). The write is then refused with a 409 when the stored value differs.
2710
+ */
2711
+ setConfig: (id: string, namespace: string, configKey: string, configValue: any, auditMessage?: string, options?: {
2712
+ expected?: any;
2713
+ }) => Promise<any>;
2714
+ /**
2715
+ * Remove a configuration value.
2716
+ * @param {string} id - The record's ID
2717
+ * @param {string} namespace - The config namespace
2718
+ * @param {string} configKey - The config key
2719
+ * @param {string} [auditMessage] - Audit message for this write
2720
+ * @param {{expected?: any}} [options] - `expected`, as on setConfig.
2721
+ */
2722
+ deleteConfig: (id: string, namespace: string, configKey: string, auditMessage?: string, options?: {
2723
+ expected?: any;
2724
+ }) => Promise<any>;
2725
+ };
2726
+ vocabItems: {
2727
+ /**
2728
+ * Create a new vocab item
2729
+ * @param {string} vocabLayerId - The vocab layer ID
2730
+ * @param {string} form - The vocab item form
2731
+ * @param {any} [metadata] - Metadata map. Omit to leave unset; pass null to send JSON null.
2732
+ * @param {string} [auditMessage] - Audit message for this write
2733
+ * @param {object} [opts]
2734
+ * @param {string} [opts.id] - The new entity's id, minted by the caller (see uuidv7)
2735
+ */
2736
+ create: (vocabLayerId: string, form: string, metadata?: any, auditMessage?: string, { id }?: {
2737
+ id?: string;
2738
+ }) => Promise<any>;
2739
+ /**
2740
+ * Create multiple vocab items in a single operation. Entries may target
2741
+ * different vocab layers; the user must have write access to each.
2742
+ * @param {Array<{vocabLayerId: string, form: string, metadata?: any}>} body - The vocab items to create
2743
+ * @param {string} [auditMessage] - Audit message for this write
2744
+ * @returns {Promise<{ids: string[]}>}
2745
+ */
2746
+ bulkCreate: (body: Array<{
2747
+ vocabLayerId: string;
2748
+ form: string;
2749
+ metadata?: any;
2750
+ }>, auditMessage?: string) => Promise<{
2751
+ ids: string[];
2752
+ }>;
2753
+ /**
2754
+ * Update many vocab items in a single operation: set forms and/or patch
2755
+ * metadata.
2756
+ * @param {Array<{id: string, form?: string, metadata?: Array<object>}>} body - `form` is set only when the key is present; `metadata` is a list of metadata ops, as for patchMetadata. The entries may lie in several vocab layers; the user must have write access to each. An unknown id refuses the whole update, and an id may appear only once. Only an entry whose form really changes restates the documents linking it, and a strict-mode client picks up their new versions from the response.
2757
+ * @param {string} [auditMessage] - Audit message for this write
2758
+ * @returns {Promise<{count: number}>} How many vocab items were updated.
2759
+ */
2760
+ bulkUpdate: (body: Array<{
2761
+ id: string;
2762
+ form?: string;
2763
+ metadata?: Array<object>;
2764
+ }>, auditMessage?: string) => Promise<{
2765
+ count: number;
2766
+ }>;
2767
+ /**
2768
+ * Delete multiple vocab items in a single operation. Each item's
2769
+ * descendant vocab links are deleted too. Provide an array of IDs.
2770
+ *
2771
+ * Every document holding one of those links has its version bumped, and
2772
+ * a strict-mode client picks up their new versions from the response.
2773
+ * @param {string[]} body - The vocab item IDs to delete
2774
+ * @param {string} [auditMessage] - Audit message for this write
2775
+ * @returns {Promise<void>}
2776
+ */
2777
+ bulkDelete: (body: string[], auditMessage?: string) => Promise<void>;
2778
+ /**
2779
+ * Get a vocab item by ID
2780
+ * @param {string} id - The resource ID
2781
+ */
2782
+ get: (id: string) => Promise<any>;
2783
+ /**
2784
+ * Delete a vocab item, and every link to it. Every document holding one
2785
+ * of those links has its version bumped, and a strict-mode client picks
2786
+ * up their new versions from the response.
2787
+ * @param {string} id - The resource ID
2788
+ * @param {string} [auditMessage] - Audit message for this write
2789
+ * @param {{expectedLinkCount?: number}} [options] - `expectedLinkCount`: the
2790
+ * number of links the caller showed. The delete is refused with a 409 when
2791
+ * the entry has any other number of links by then.
2792
+ */
2793
+ delete: (id: string, auditMessage?: string, { expectedLinkCount }?: {
2794
+ expectedLinkCount?: number;
2795
+ }) => Promise<any>;
2796
+ /**
2797
+ * Merge entries into this one, in one operation. Every link to a loser
2798
+ * moves to the survivor (keeping its id and metadata), except a link on
2799
+ * words the survivor is already linked to, which is deleted, and then the
2800
+ * losers are deleted. Links are read when the merge runs, so one made
2801
+ * after the caller looked moves too. Every loser must be in the
2802
+ * survivor's vocabulary, and a loser that is already gone is skipped, so
2803
+ * a repeated merge changes nothing. Metadata naming a loser by its id,
2804
+ * in the vocabulary's other entries and in the documents of every
2805
+ * project it is linked to, is rewritten to name the survivor. A
2806
+ * reference to a loser in the survivor's own metadata is the caller's to
2807
+ * rewrite, in the same batch.
2808
+ * Needs maintainer rights on the vocabulary.
2809
+ * @param {string} survivorId - The entry that stays
2810
+ * @param {string[]} loserIds - The entries merged into it
2811
+ * @param {string} [auditMessage] - Audit message for this write
2812
+ * @returns {Promise<{moved: number, duplicates: number, removed: string[]}>}
2813
+ */
2814
+ merge: (survivorId: string, loserIds: string[], auditMessage?: string) => Promise<{
2815
+ moved: number;
2816
+ duplicates: number;
2817
+ removed: string[];
2818
+ }>;
2819
+ /**
2820
+ * Update a vocab item's form. A document read carries the entry's form on
2821
+ * every link to it, so a rename restates those documents: each has its
2822
+ * version bumped, and a strict-mode client picks up their new versions
2823
+ * from the response.
2824
+ * @param {string} id - The resource ID
2825
+ * @param {string} form - The vocab item form
2826
+ * @param {string} [auditMessage] - Audit message for this write
2827
+ */
2828
+ update: (id: string, form: string, auditMessage?: string) => Promise<any>;
2829
+ /**
2830
+ * Replace all metadata of an entity. Keys left out of the new map are removed.
2831
+ * @param {string} id - The entity's ID
2832
+ * @param {object} body - The new metadata map
2833
+ * @param {string} [auditMessage] - Audit message for this write
2834
+ */
2835
+ setMetadata: (id: string, body: object, auditMessage?: string) => Promise<any>;
2836
+ /**
2837
+ * Remove all metadata from an entity.
2838
+ * @param {string} id - The entity's ID
2839
+ * @param {string} [auditMessage] - Audit message for this write
2840
+ */
2841
+ deleteMetadata: (id: string, auditMessage?: string) => Promise<any>;
2842
+ /**
2843
+ * Edit an entity's metadata with a list of ops applied in order, in one operation. `{op: 'set', path, value}` writes value at path, creating missing objects along it; `{op: 'delete', path}` removes the key at path (a no-op when absent). A path is a non-empty array of keys, the first a top-level key. A path through a non-object is refused (400). See metadataOps and applyMetadataOps.
2844
+ * @param {string} id - The entity's ID
2845
+ * @param {MetadataOp[]} body - The metadata ops
2846
+ * @param {string} [auditMessage] - Audit message for this write
2847
+ */
2848
+ patchMetadata: (id: string, body: MetadataOp[], auditMessage?: string) => Promise<any>;
2849
+ };
2850
+ relationLayers: {
2851
+ /**
2852
+ * Declare an app namespace's constraints on this layer, replacing that
2853
+ * namespace's list. Refused with 422 and the violations when the layer's
2854
+ * stored data breaks them (see violationsOf).
2855
+ * @param {string} layerId - The layer ID
2856
+ * @param {string} namespace - The declaring app's namespace, e.g. "igt"
2857
+ * @param {LayerConstraint[]} constraints - e.g. [{type: "single-span"}, {type: "value-set", values: ["N"]}]
2858
+ * @param {string} [auditMessage] - Audit message for this write
2859
+ * @param {{expected?: Array<object>|null}} [options] - `expected`: the list read for this
2860
+ * namespace (null when it was absent). The write is then refused with a 409 when the stored
2861
+ * list differs.
2862
+ * @returns {Promise<{constraints: Record<string, LayerConstraint[]>}>} the layer's whole constraint map
2863
+ */
2864
+ setConstraints: (layerId: string, namespace: string, constraints: LayerConstraint[], auditMessage?: string, options?: {
2865
+ expected?: Array<object> | null;
2866
+ }) => Promise<{
2867
+ constraints: Record<string, LayerConstraint[]>;
2868
+ }>;
2869
+ /**
2870
+ * Remove an app namespace's constraints from this layer.
2871
+ * @param {string} layerId - The layer ID
2872
+ * @param {string} namespace - The declaring app's namespace
2873
+ * @param {string} [auditMessage] - Audit message for this write
2874
+ * @param {{expected?: Array<object>|null}} [options] - `expected`, as on setConstraints.
2875
+ */
2876
+ deleteConstraints: (layerId: string, namespace: string, auditMessage?: string, options?: {
2877
+ expected?: Array<object> | null;
2878
+ }) => Promise<any>;
2879
+ /**
2880
+ * The violations the given constraints would meet in this layer's stored
2881
+ * data. Writes nothing.
2882
+ * @param {string} layerId - The layer ID
2883
+ * @param {LayerConstraint[]} constraints - The list to check
2884
+ * @returns {Promise<{violations: ConstraintViolation[], violationCount: number}>}
2885
+ */
2886
+ checkConstraints: (layerId: string, constraints: LayerConstraint[]) => Promise<{
2887
+ violations: ConstraintViolation[];
2888
+ violationCount: number;
2889
+ }>;
2890
+ /**
2891
+ * Apply the remedies of the given constraints' remediable types
2892
+ * (coextensive, single-span, single-link, same-ancestor) to every
2893
+ * violation in this layer's stored data, one operation per document.
2894
+ * With `document`, only that document is repaired, and a writer may
2895
+ * ask. A document another user holds the lock on is left as it is and
2896
+ * listed under `locked`.
2897
+ * @param {string} layerId - The layer ID
2898
+ * @param {LayerConstraint[]} constraints - The list to repair for
2899
+ * @param {string} [auditMessage] - Audit message for this write
2900
+ * @param {{document?: string}} [options]
2901
+ * @returns {Promise<{repaired: ConstraintRepair[], locked: Array<{document: string, lockedBy: string}>, violations: ConstraintViolation[], violationCount: number}>}
2902
+ */
2903
+ repairConstraints: (layerId: string, constraints: LayerConstraint[], auditMessage?: string, options?: {
2904
+ document?: string;
2905
+ }) => Promise<{
2906
+ repaired: ConstraintRepair[];
2907
+ locked: Array<{
2908
+ document: string;
2909
+ lockedBy: string;
2910
+ }>;
2911
+ violations: ConstraintViolation[];
2912
+ violationCount: number;
2913
+ }>;
2914
+ /**
2915
+ * Set a configuration value in an editor namespace.
2916
+ * @param {string} id - The record's ID
2917
+ * @param {string} namespace - The config namespace
2918
+ * @param {string} configKey - The config key
2919
+ * @param {any} configValue - Configuration value to set
2920
+ * @param {string} [auditMessage] - Audit message for this write
2921
+ * @param {{expected?: any}} [options] - `expected`: the value read for this key (null or undefined when it
2922
+ * was absent). The write is then refused with a 409 when the stored value differs.
2923
+ */
2924
+ setConfig: (id: string, namespace: string, configKey: string, configValue: any, auditMessage?: string, options?: {
2925
+ expected?: any;
2926
+ }) => Promise<any>;
2927
+ /**
2928
+ * Remove a configuration value.
2929
+ * @param {string} id - The record's ID
2930
+ * @param {string} namespace - The config namespace
2931
+ * @param {string} configKey - The config key
2932
+ * @param {string} [auditMessage] - Audit message for this write
2933
+ * @param {{expected?: any}} [options] - `expected`, as on setConfig.
2934
+ */
2935
+ deleteConfig: (id: string, namespace: string, configKey: string, auditMessage?: string, options?: {
2936
+ expected?: any;
2937
+ }) => Promise<any>;
2938
+ /**
2939
+ * Create a new relation layer.
2940
+ * @param {string} spanLayerId - The span layer ID
2941
+ * @param {string} name - The name
2942
+ * @param {string} [auditMessage] - Audit message for this write
2943
+ * @param {object} [opts]
2944
+ * @param {string} [opts.id] - The new entity's id, minted by the caller (see uuidv7)
2945
+ */
2946
+ create: (spanLayerId: string, name: string, auditMessage?: string, { id }?: {
2947
+ id?: string;
2948
+ }) => Promise<any>;
2949
+ /**
2950
+ * Get a layer by ID.
2951
+ * @param {string} layerId - The layer ID
2952
+ */
2953
+ get: (layerId: string) => Promise<any>;
2954
+ /**
2955
+ * Delete a layer.
2956
+ * @param {string} layerId - The layer ID
2957
+ * @param {string} [auditMessage] - Audit message for this write
2958
+ */
2959
+ delete: (layerId: string, auditMessage?: string) => Promise<any>;
2960
+ /**
2961
+ * Rename a layer.
2962
+ * @param {string} layerId - The layer ID
2963
+ * @param {string} name - The new name
2964
+ * @param {string} [auditMessage] - Audit message for this write
2965
+ */
2966
+ update: (layerId: string, name: string, auditMessage?: string) => Promise<any>;
2967
+ /**
2968
+ * Move a layer one place in its display order.
2969
+ * @param {string} layerId - The layer ID
2970
+ * @param {string} direction - The direction ("up" or "down")
2971
+ * @param {string} [auditMessage] - Audit message for this write
2972
+ */
2973
+ shift: (layerId: string, direction: string, auditMessage?: string) => Promise<any>;
2974
+ };
2975
+ tokens: {
2976
+ /**
2977
+ * Replace all metadata of an entity. Keys left out of the new map are removed.
2978
+ * @param {string} id - The entity's ID
2979
+ * @param {object} body - The new metadata map
2980
+ * @param {string} [auditMessage] - Audit message for this write
2981
+ */
2982
+ setMetadata: (id: string, body: object, auditMessage?: string) => Promise<any>;
2983
+ /**
2984
+ * Remove all metadata from an entity.
2985
+ * @param {string} id - The entity's ID
2986
+ * @param {string} [auditMessage] - Audit message for this write
2987
+ */
2988
+ deleteMetadata: (id: string, auditMessage?: string) => Promise<any>;
2989
+ /**
2990
+ * Edit an entity's metadata with a list of ops applied in order, in one operation. `{op: 'set', path, value}` writes value at path, creating missing objects along it; `{op: 'delete', path}` removes the key at path (a no-op when absent). A path is a non-empty array of keys, the first a top-level key. A path through a non-object is refused (400). See metadataOps and applyMetadataOps.
2991
+ * @param {string} id - The entity's ID
2992
+ * @param {MetadataOp[]} body - The metadata ops
2993
+ * @param {string} [auditMessage] - Audit message for this write
2994
+ */
2995
+ patchMetadata: (id: string, body: MetadataOp[], auditMessage?: string) => Promise<any>;
2996
+ /**
2997
+ * Create a new token in a token layer. Tokens define text substrings
2998
+ * using begin and end offsets. Tokens may be zero-width and may overlap.
2999
+ * For tokens sharing the same begin, precedence controls the linear
3000
+ * ordering.
3001
+ *
3002
+ * Offsets are 0-based indices in Unicode CODE POINTS (not UTF-16 code
3003
+ * units): a supplementary-plane character (emoji, SMP script) is one
3004
+ * position. JS strings are UTF-16, so do NOT use `str.length` /
3005
+ * `str.substring` to compute offsets — count code points instead
3006
+ * (e.g. `[...str].length`, or iterate with `codePointAt`).
3007
+ * @param {string} tokenLayerId - The token layer ID
3008
+ * @param {string} text - The text ID
3009
+ * @param {number} begin - Start offset, inclusive (Unicode code points)
3010
+ * @param {number} end - End offset, exclusive (Unicode code points)
3011
+ * @param {number} [precedence] - Ordering precedence
3012
+ * @param {any} [metadata] - Metadata map. Omit to leave unset; pass null to send JSON null.
3013
+ * @param {string} [auditMessage] - Audit message for this write
3014
+ * @param {object} [opts]
3015
+ * @param {string} [opts.id] - The new entity's id, minted by the caller (see uuidv7)
3016
+ */
3017
+ create: (tokenLayerId: string, text: string, begin: number, end: number, precedence?: number, metadata?: any, auditMessage?: string, { id }?: {
3018
+ id?: string;
3019
+ }) => Promise<any>;
3020
+ /**
3021
+ * Get a token.
3022
+ * @param {string} tokenId - The token ID
3023
+ */
3024
+ get: (tokenId: string) => Promise<any>;
3025
+ /**
3026
+ * Delete a token and remove it from any spans. If this causes a span to
3027
+ * have no remaining tokens, the span will also be deleted.
3028
+ * @param {string} tokenId - The token ID
3029
+ * @param {string} [auditMessage] - Audit message for this write
3030
+ */
3031
+ delete: (tokenId: string, auditMessage?: string) => Promise<any>;
3032
+ /**
3033
+ * Update a token.
3034
+ * @param {string} tokenId - The token ID
3035
+ * @param {number} [begin] - New start offset, inclusive (Unicode code points)
3036
+ * @param {number} [end] - New end offset, exclusive (Unicode code points)
3037
+ * @param {?number} [precedence] - Ordering precedence. Omit (undefined)
3038
+ * to leave unchanged; pass a number to set; pass null explicitly to
3039
+ * CLEAR it (revert to no explicit ordering). bodyOf keeps null but
3040
+ * drops undefined, so the three cases map correctly to the server.
3041
+ * @param {string} [auditMessage] - Audit message for this write
3042
+ */
3043
+ update: (tokenId: string, begin?: number, end?: number, precedence?: number | null, auditMessage?: string) => Promise<any>;
3044
+ /**
3045
+ * Create multiple tokens in a single operation.
3046
+ * @param {Array} body - The request body
3047
+ * @param {string} [auditMessage] - Audit message for this write
3048
+ * @returns {Promise<{ids: string[]}>} The created entity IDs, in input order. (bulkDelete resolves to no value.)
3049
+ */
3050
+ bulkCreate: (body: any[], auditMessage?: string) => Promise<{
3051
+ ids: string[];
3052
+ }>;
3053
+ /**
3054
+ * Delete multiple tokens in a single operation. Provide an array of IDs.
3055
+ * @param {Array} body - The request body
3056
+ * @param {string} [auditMessage] - Audit message for this write
3057
+ * @returns {Promise<void>}
3058
+ */
3059
+ bulkDelete: (body: any[], auditMessage?: string) => Promise<void>;
3060
+ /**
3061
+ * Update many tokens in a single operation: patch metadata.
3062
+ * @param {Array} body - Objects of the shape `{id, metadata}`. `metadata` is a list of metadata ops, as for patchMetadata. The tokens may lie in several documents of one project; every document touched has its version bumped and every new version comes back in `X-Document-Versions` (past fifty documents, only their number, in `X-Document-Versions-Omitted`). A `document-version` precondition is accepted only when every entry lies in one document. An unknown id refuses the whole update.
3063
+ * @param {string} [auditMessage] - Audit message for this write
3064
+ * @returns {Promise<{count: number}>} How many tokens were updated.
3065
+ */
3066
+ bulkUpdate: (body: any[], auditMessage?: string) => Promise<{
3067
+ count: number;
3068
+ }>;
3069
+ /**
3070
+ * Split a token at a Unicode code-point offset. The original token becomes the
3071
+ * left half (keeps its ID, spans, vocab-links); the new right token's ID is returned.
3072
+ * @param {string} tokenId - The token ID
3073
+ * @param {number} position - Code-point offset to split at (strictly between begin and end)
3074
+ * @param {string} [auditMessage] - Audit message for this write
3075
+ * @param {{id?: string, keep?: "left"|"right"}} [options] - `id`: the new
3076
+ * token's id, a UUIDv7 this client minted. `keep`: the half the original token
3077
+ * (its id, spans, vocab-links, comments and metadata) stays on, `"left"` by
3078
+ * default. With `"right"` the new token, whose id is answered, is the left
3079
+ * half. A relation layer whose relations must stay inside one token
3080
+ * of this layer declares a same-ancestor constraint, and the server deletes
3081
+ * the relations the split leaves crossing in the same transaction.
3082
+ */
3083
+ split: (tokenId: string, position: number, auditMessage?: string, { id, keep }?: {
3084
+ id?: string;
3085
+ keep?: "left" | "right";
3086
+ }) => Promise<any>;
3087
+ /**
3088
+ * Merge two tokens. The left token (smaller begin) survives with the combined
3089
+ * extent; the right is deleted and its spans/vocab-links are reparented to the left.
3090
+ * On partitioning layers the tokens must be adjacent; on non-overlapping layers the
3091
+ * merged extent must not engulf a third token.
3092
+ * @param {string} tokenId - The anchor token ID
3093
+ * @param {string} otherTokenId - The other token to merge in
3094
+ * @param {string} [auditMessage] - Audit message for this write
3095
+ */
3096
+ merge: (tokenId: string, otherTokenId: string, auditMessage?: string) => Promise<any>;
3097
+ /**
3098
+ * Shift a token's boundary. On partitioning layers the adjacent token is
3099
+ * auto-adjusted to preserve the partition; on non-overlapping layers a shift that
3100
+ * would create an overlap is rejected.
3101
+ * @param {string} tokenId - The token ID
3102
+ * @param {number} [begin] - New start offset, inclusive (Unicode code points)
3103
+ * @param {number} [end] - New end offset, exclusive (Unicode code points)
3104
+ * @param {string} [auditMessage] - Audit message for this write
3105
+ */
3106
+ shift: (tokenId: string, begin?: number, end?: number, auditMessage?: string) => Promise<any>;
3107
+ };
3108
+ messages: {
3109
+ /**
3110
+ * Open a Server-Sent Events stream for a project.
3111
+ * @param {string} projectId - The UUID of the project to listen to
3112
+ * @param {(eventType: string, data: any) => void | boolean} onEvent - Callback function that receives (eventType, data). If it returns true, listening will stop.
3113
+ * @param {string} [path] - Stream path under baseUrl (defaults to the project /listen bus; service channels pass their own).
3114
+ * @returns {SSEConnection} SSE connection object with .close() and .getStats() methods
3115
+ */
3116
+ listen: (projectId: string, onEvent: (eventType: string, data: any) => void | boolean, path?: string) => SSEConnection;
3117
+ /**
3118
+ * Send a message to project listeners.
3119
+ *
3120
+ * `data` may be any JSON value and is sent VERBATIM (`rawBody`): a
3121
+ * message payload is opaque application data, like `metadata` and
3122
+ * `config`, so its keys must not be re-cased on the way out. Without
3123
+ * this a key such as `case-marker` would reach listeners as
3124
+ * `caseMarker` in JS and `case_marker` in Python. `listen` restores it
3125
+ * verbatim on the way in.
3126
+ *
3127
+ * A message is not saved and writes nothing to History, so it never
3128
+ * joins an open operation (`withOperation`). Made on a batch it still
3129
+ * queues, so a message queued after the writes goes out after them.
3130
+ * @param {string} projectId - The UUID of the project to send to
3131
+ * @param {any} data - The message data to send
3132
+ * @returns {Promise<any>} Response from the send operation
3133
+ */
3134
+ sendMessage: (projectId: string, data: any) => Promise<any>;
3135
+ /**
3136
+ * Discover the services seen on a project (synchronous GET). Currently
3137
+ * connected services carry `online: true`; previously-seen offline ones
3138
+ * carry `online: false` plus a `lastSeenAt` stamp.
3139
+ * @param {string} projectId - The UUID of the project to query
3140
+ * @returns {Promise<DiscoveredService[]>} Array of discovered service information
3141
+ */
3142
+ discoverServices: (projectId: string) => Promise<DiscoveredService[]>;
3143
+ /**
3144
+ * Forget a previously-seen (offline) service. Maintainer-only; 409 if
3145
+ * the service is currently connected.
3146
+ * @param {string} projectId - The UUID of the project
3147
+ * @param {string} serviceId - The ID of the service to forget
3148
+ * @returns {Promise<void>}
3149
+ */
3150
+ discardService: (projectId: string, serviceId: string) => Promise<void>;
3151
+ /**
3152
+ * Register as a service and handle incoming work requests.
3153
+ *
3154
+ * The registration reopens its channel whenever it drops, so a server
3155
+ * restart needs no service restart.
3156
+ * @param {string} projectId - The UUID of the project to serve
3157
+ * @param {ServiceInfo} serviceInfo - Service information {serviceId, serviceName, description}
3158
+ * @param {(data: any, responseHelper: ResponseHelper) => void} onServiceRequest - Callback (data, responseHelper)
3159
+ * @param {Object} [extras] - Optional additional service metadata
3160
+ * @param {(event: ServiceStatusEvent, projectId: string, detail?: string) => void} [onStatus] - Optional callback (event, projectId, detail) for
3161
+ * connection transitions: 'registered', 'reconnected', 'disconnected',
3162
+ * and 'stopped' when the server refuses the channel for good, which
3163
+ * ends the registration
3164
+ * @returns {ServiceRegistration} Service registration with .stop(), .isRunning(), .isConnected()
3165
+ */
3166
+ serve: (projectId: string, serviceInfo: ServiceInfo, onServiceRequest: (data: any, responseHelper: ResponseHelper) => void, extras?: any, onStatus?: (event: ServiceStatusEvent, projectId: string, detail?: string) => void) => ServiceRegistration;
3167
+ /**
3168
+ * Request a service to perform work and await its result.
3169
+ *
3170
+ * The request outlives this call: after a timeout, an abort, or a
3171
+ * dropped connection the service goes on, and `attachServiceRequest`
3172
+ * collects the result given the request id, which `opts.onAccepted`
3173
+ * receives as soon as the server has taken the request. Pass
3174
+ * `opts.requestId` (a UUID you mint) to know the id before submitting;
3175
+ * submitting an id that names a request you already made rejoins it
3176
+ * instead of starting another.
3177
+ * @param {string} projectId - The UUID of the project
3178
+ * @param {string} serviceId - The ID of the service to request
3179
+ * @param {any} data - The request data
3180
+ * @param {number} [timeout=10000] - Timeout in ms
3181
+ * @param {function} [onProgress] - Called with each progress payload {percent, message}
3182
+ * @param {AbortSignal} [signal] - Abort to stop waiting; rejects with an AbortError
3183
+ * @param {{requestId?: string, onAccepted?: (requestId: string) => void, projectIds?: string[], noOperation?: boolean}} [opts] - {requestId, onAccepted, projectIds, noOperation}
3184
+ * @returns {Promise<any>} The service's result
3185
+ */
3186
+ requestService: (projectId: string, serviceId: string, data: any, timeout?: number, onProgress?: Function, signal?: AbortSignal, opts?: {
3187
+ requestId?: string;
3188
+ onAccepted?: (requestId: string) => void;
3189
+ projectIds?: string[];
3190
+ noOperation?: boolean;
3191
+ }) => Promise<any>;
3192
+ /**
3193
+ * Rejoin a service request made earlier and await its result: the
3194
+ * latest progress is replayed, then the result comes, or at once if the
3195
+ * request already finished. Only the user who submitted it (or an
3196
+ * admin). Rejects with an error whose `status` is 404 when the request
3197
+ * is unknown or expired (a finished request's result is kept for a
3198
+ * while, not forever).
3199
+ * @param {string} projectId - The UUID of the project
3200
+ * @param {string} requestId - The request id
3201
+ * @param {number} [timeout=10000] - Timeout in ms
3202
+ * @param {function} [onProgress] - Called with each progress payload
3203
+ * @param {AbortSignal} [signal] - Abort to stop waiting
3204
+ * @returns {Promise<any>} The service's result
3205
+ */
3206
+ attachServiceRequest: (projectId: string, requestId: string, timeout?: number, onProgress?: Function, signal?: AbortSignal) => Promise<any>;
3207
+ /**
3208
+ * Ask the service to stop a request made earlier. The request still
3209
+ * ends with whatever the service then reports, on the stream of whoever
3210
+ * is awaiting it. Rejects with 404 if unknown or expired, 409 once
3211
+ * finished.
3212
+ * @param {string} projectId - The UUID of the project
3213
+ * @param {string} requestId - The request id
3214
+ * @returns {Promise<void>}
3215
+ */
3216
+ cancelServiceRequest: (projectId: string, requestId: string) => Promise<void>;
3217
+ };
3218
+ /**
3219
+ * Run a query over every project you can read.
3220
+ *
3221
+ * `body` is the query AST. Its keys follow the usual client convention
3222
+ * (camelCase, e.g. `scope.projectIds`) and are converted to the wire
3223
+ * format automatically; clause heads and variables are plain strings you
3224
+ * write literally (e.g. `'span'`, `'?s1'`, `'vocab-link'`). Example:
3225
+ *
3226
+ * await client.query({
3227
+ * find: ['?s1', '?s2'],
3228
+ * where: [
3229
+ * ['span', '?s1', { layer: posLayerId, value: 'NOUN' }],
3230
+ * ['span', '?s2', { layer: posLayerId, value: 'VERB' }],
3231
+ * ['covers', '?s1', '?t1'], ['covers', '?s2', '?t2'],
3232
+ * ['precedes', '?t1', '?t2'],
3233
+ * ],
3234
+ * return: 'entities', // 'ids' (default) | 'entities' | 'count'
3235
+ * limit: 100,
3236
+ * });
3237
+ *
3238
+ * A `layer` is referenced by its id (its UUID) only — not by name or
3239
+ * path. To match a layer by name, bind it with a `*-layer` clause (e.g.
3240
+ * `['span-layer', '?sl', { name: 'pos' }]`) and use the variable.
3241
+ *
3242
+ * Optional keys: `scope` (restrict to projects by id, `{projectIds}`), `orderBy`
3243
+ * (sort rows), and `bindings` (substitute `?name` placeholders with literals).
3244
+ * `return` may also be an aggregate spec `{group, aggregates}`. See the query
3245
+ * language reference.
3246
+ *
3247
+ * @param {Object} body - The query AST ({find, where, scope?, limit?, orderBy?,
3248
+ * return?, bindings?}).
3249
+ * @returns {Promise<Object>} For 'ids'/'entities': {columns, results, count, truncated}.
3250
+ * For 'count': {return: 'count', count, truncated}, where `truncated` says
3251
+ * the count stopped at the server's cap. Entity cells are full entity
3252
+ * objects (same shape as the GET endpoints).
3253
+ */
3254
+ query: (body: any) => Promise<any>;
3255
+ operationGroups: {
3256
+ /**
3257
+ * Get a logical-operation group (its label + creator).
3258
+ * @param {string} id - The group id
3259
+ */
3260
+ get: (id: string) => Promise<any>;
3261
+ /**
3262
+ * Relabel a logical-operation group after the fact. Owner or admin only.
3263
+ * @param {string} id - The group id
3264
+ * @param {string|null} message - The new label
3265
+ */
3266
+ update: (id: string, message: string | null) => Promise<any>;
3267
+ };
3268
+ comments: {
3269
+ /**
3270
+ * Post a comment on an entity. Requires write access to the entity's
3271
+ * project, or to the vocabulary for a vocab-item; the author is the
3272
+ * authenticated caller. Comments are not audited and do not bump the
3273
+ * document version.
3274
+ *
3275
+ * A comment outlives its anchor: deleting the entity does not delete
3276
+ * the comment. `anchorLabel` is the caption shown once that happens
3277
+ * ("Gloss of ktab, sentence 4"), so pass what the comment is about.
3278
+ * @param {CommentableType} entityType - What kind of thing is being commented on
3279
+ * @param {string} entityId - The commented entity's id
3280
+ * @param {string} body - The comment text (1..10000 characters)
3281
+ * @param {object} [opts]
3282
+ * @param {string} [opts.anchorLabel] - What the comment is about, in words (at most 200 characters)
3283
+ * @param {string} [opts.id] - The new comment's id, minted by the caller (see uuidv7)
3284
+ * @returns {Promise<Comment>}
3285
+ */
3286
+ create: (entityType: CommentableType, entityId: string, body: string, { anchorLabel, id }?: {
3287
+ anchorLabel?: string;
3288
+ id?: string;
3289
+ }) => Promise<Comment>;
3290
+ /**
3291
+ * Read one comment.
3292
+ * @param {string} id - The comment id
3293
+ * @returns {Promise<Comment>}
3294
+ */
3295
+ get: (id: string) => Promise<Comment>;
3296
+ /**
3297
+ * Edit a comment's body. Only the comment's AUTHOR may do this - not
3298
+ * maintainers, not admins. Sets `edited` on the comment.
3299
+ * @param {string} id - The comment id
3300
+ * @param {string} body - The replacement text
3301
+ * @returns {Promise<Comment>}
3302
+ */
3303
+ update: (id: string, body: string) => Promise<Comment>;
3304
+ /**
3305
+ * Delete a comment. The author may delete their own; a project
3306
+ * maintainer (or admin) may delete any.
3307
+ * @param {string} id - The comment id
3308
+ */
3309
+ delete: (id: string) => Promise<any>;
3310
+ /**
3311
+ * List comments in a project, oldest first. Transparently follows
3312
+ * pagination cursors and returns the full flat array.
3313
+ * @param {string} projectId - The project to read
3314
+ * @param {object} [filters] - Narrow the scope
3315
+ * @param {string} [filters.documentId] - Every comment anywhere in one document
3316
+ * @param {string} [filters.entityType] - With entityId, one entity's thread
3317
+ * @param {string} [filters.entityId] - With entityType, one entity's thread
3318
+ * @returns {Promise<Comment[]>}
3319
+ */
3320
+ list: (projectId: string, { documentId, entityType, entityId }?: {
3321
+ documentId?: string;
3322
+ entityType?: string;
3323
+ entityId?: string;
3324
+ }) => Promise<Comment[]>;
3325
+ /**
3326
+ * Fetch a single page of a project's comments.
3327
+ * @param {string} projectId - The project to read
3328
+ * @param {object} [opts]
3329
+ * @param {number} [opts.limit] - Page size (1..1000; server default 100)
3330
+ * @param {string} [opts.cursor] - Opaque cursor from a previous page
3331
+ * @param {string} [opts.documentId] - Every comment anywhere in one document
3332
+ * @param {string} [opts.entityType] - With entityId, one entity's thread
3333
+ * @param {string} [opts.entityId] - With entityType, one entity's thread
3334
+ * @returns {Promise<Page<Comment>>}
3335
+ */
3336
+ listPage: (projectId: string, { limit, cursor, documentId, entityType, entityId }?: {
3337
+ limit?: number;
3338
+ cursor?: string;
3339
+ documentId?: string;
3340
+ entityType?: string;
3341
+ entityId?: string;
3342
+ }) => Promise<Page<Comment>>;
3343
+ /**
3344
+ * Async-iterate a project's comments page by page; yields each page's entries array.
3345
+ * @param {string} projectId - The project to read
3346
+ * @param {object} [opts]
3347
+ * @param {number} [opts.pageSize] - Per-request page size
3348
+ * @param {string} [opts.documentId] - Every comment anywhere in one document
3349
+ * @param {string} [opts.entityType] - With entityId, one entity's thread
3350
+ * @param {string} [opts.entityId] - With entityType, one entity's thread
3351
+ * @returns {AsyncGenerator<Comment[]>}
3352
+ */
3353
+ iterPages: (projectId: string, { pageSize, documentId, entityType, entityId }?: {
3354
+ pageSize?: number;
3355
+ documentId?: string;
3356
+ entityType?: string;
3357
+ entityId?: string;
3358
+ }) => AsyncGenerator<Comment[]>;
3359
+ /**
3360
+ * Comment counts per entity, as an `{entityId: n}` map, over the same
3361
+ * scope and filters as `list`. One cheap request paints a comment
3362
+ * indicator on every annotated item in a document without paging
3363
+ * through the bodies.
3364
+ *
3365
+ * The response is NOT key-transformed: its keys are entity ids, and
3366
+ * camelCasing would mangle the hyphens in a UUID.
3367
+ * @param {string} projectId - The project to read
3368
+ * @param {{documentId?: string, entityType?: CommentableType, entityId?: string}} [filters] - Same filters as list()
3369
+ * @returns {Promise<Object<string, number>>}
3370
+ */
3371
+ counts: (projectId: string, { documentId, entityType, entityId }?: {
3372
+ documentId?: string;
3373
+ entityType?: CommentableType;
3374
+ entityId?: string;
3375
+ }) => Promise<{
3376
+ [x: string]: number;
3377
+ }>;
3378
+ /**
3379
+ * List the comments on a vocabulary's entries, oldest first. Requires
3380
+ * read access to the vocabulary. Transparently follows pagination
3381
+ * cursors and returns the full flat array.
3382
+ * @param {string} vocabId - The vocab layer to read
3383
+ * @param {object} [filters]
3384
+ * @param {string} [filters.entityId] - One entry's thread
3385
+ * @returns {Promise<Comment[]>}
3386
+ */
3387
+ listInVocab: (vocabId: string, { entityId }?: {
3388
+ entityId?: string;
3389
+ }) => Promise<Comment[]>;
3390
+ /**
3391
+ * Fetch a single page of a vocabulary's comments.
3392
+ * @param {string} vocabId - The vocab layer to read
3393
+ * @param {object} [opts]
3394
+ * @param {number} [opts.limit] - Page size (1..1000; server default 100)
3395
+ * @param {string} [opts.cursor] - Opaque cursor from a previous page
3396
+ * @param {string} [opts.entityId] - One entry's thread
3397
+ * @returns {Promise<Page<Comment>>}
3398
+ */
3399
+ listInVocabPage: (vocabId: string, { limit, cursor, entityId }?: {
3400
+ limit?: number;
3401
+ cursor?: string;
3402
+ entityId?: string;
3403
+ }) => Promise<Page<Comment>>;
3404
+ /**
3405
+ * Async-iterate a vocabulary's comments page by page, oldest first;
3406
+ * yields each page's entries array.
3407
+ * @param {string} vocabId - The vocab layer to read
3408
+ * @param {object} [opts]
3409
+ * @param {string} [opts.entityId] - One entry's thread
3410
+ * @param {number} [opts.pageSize] - Per-request page size
3411
+ * @returns {AsyncGenerator<Comment[]>}
3412
+ */
3413
+ iterInVocabPages: (vocabId: string, { entityId, pageSize }?: {
3414
+ entityId?: string;
3415
+ pageSize?: number;
3416
+ }) => AsyncGenerator<Comment[]>;
3417
+ /**
3418
+ * Comment counts per entry of a vocabulary, as an `{entityId: n}` map.
3419
+ * The response is NOT key-transformed: its keys are entry ids.
3420
+ * @param {string} vocabId - The vocab layer to read
3421
+ * @param {object} [filters]
3422
+ * @param {string} [filters.entityId] - One entry only
3423
+ * @returns {Promise<Object<string, number>>}
3424
+ */
3425
+ countsInVocab: (vocabId: string, { entityId }?: {
3426
+ entityId?: string;
3427
+ }) => Promise<{
3428
+ [x: string]: number;
3429
+ }>;
3430
+ };
3431
+ events: {
3432
+ /**
3433
+ * Record one research-telemetry event (plaid-core sql/client_event.clj).
3434
+ * Fire and forget: the event is buffered and sent with
3435
+ * others every ten seconds, at fifty events, and when the page is
3436
+ * hidden. A batch that fails is dropped, nothing is retried, and
3437
+ * nothing is ever thrown. Sends nothing for a project whose switch
3438
+ * (`config.plaid.research.telemetry`) is off, which it reads from the
3439
+ * project itself. `suggestion.shown` is recorded once per target,
3440
+ * field and value in a page session.
3441
+ * @param {ClientEventType} type - The event type
3442
+ * @param {object} fields
3443
+ * @param {string} fields.projectId - The project it happened in
3444
+ * @param {string} [fields.documentId] - The document it happened in
3445
+ * @param {string} [fields.targetId] - What it is about: a token, a plan
3446
+ * @param {object} [fields.data] - Its details, keyed by single lowercase words (`value`, `source`, `field`, `written`, `conversation`)
3447
+ * @returns {boolean} Whether the event was buffered
3448
+ */
3449
+ record: (type: ClientEventType, fields: {
3450
+ projectId: string;
3451
+ documentId?: string;
3452
+ targetId?: string;
3453
+ data?: object;
3454
+ }) => boolean;
3455
+ /**
3456
+ * Send what the recorder holds now, rather than at its next interval.
3457
+ * @returns {void}
3458
+ */
3459
+ flush: () => void;
3460
+ /**
3461
+ * Tell the recorder a project's switch at once, e.g. right after a
3462
+ * maintainer changed it. Turning it off drops what is buffered.
3463
+ * @param {string} projectId - The project
3464
+ * @param {boolean} on - Whether telemetry is on
3465
+ * @returns {void}
3466
+ */
3467
+ setEnabled: (projectId: string, on: boolean) => void;
3468
+ /**
3469
+ * Record events directly, with no buffering. Requires write access, and
3470
+ * the server refuses with a 403 while the project's switch is off. All
3471
+ * or nothing: one bad event refuses the request with a 400 naming it.
3472
+ * @param {string} projectId - The project the events happened in
3473
+ * @param {Array<{type: string, documentId?: string, targetId?: string, data?: object, clientTs?: string}>} events - At most 500 events
3474
+ * @returns {Promise<{count: number}>}
3475
+ */
3476
+ create: (projectId: string, events: Array<{
3477
+ type: string;
3478
+ documentId?: string;
3479
+ targetId?: string;
3480
+ data?: object;
3481
+ clientTs?: string;
3482
+ }>) => Promise<{
3483
+ count: number;
3484
+ }>;
3485
+ /**
3486
+ * A project's events in arrival order. Maintainer or admin only.
3487
+ * Transparently follows pagination cursors and returns the full flat
3488
+ * array.
3489
+ * @param {string} projectId - The project to read
3490
+ * @param {object} [filters]
3491
+ * @param {string|string[]} [filters.types] - Only these types
3492
+ * @param {string} [filters.startTime] - Only events the server stamped at or after this instant
3493
+ * @param {string} [filters.endTime] - Only events the server stamped at or before this instant
3494
+ * @returns {Promise<ClientEvent[]>}
3495
+ */
3496
+ list: (projectId: string, { types, startTime, endTime }?: {
3497
+ types?: string | string[];
3498
+ startTime?: string;
3499
+ endTime?: string;
3500
+ }) => Promise<ClientEvent[]>;
3501
+ /**
3502
+ * One page of a project's events. Maintainer or admin only.
3503
+ * @param {string} projectId - The project to read
3504
+ * @param {object} [opts]
3505
+ * @param {number} [opts.limit] - Page size (1..1000; server default 100)
3506
+ * @param {string} [opts.cursor] - Opaque cursor from a previous page
3507
+ * @param {string|string[]} [opts.types] - Only these types
3508
+ * @param {string} [opts.startTime] - Only events at or after this instant
3509
+ * @param {string} [opts.endTime] - Only events at or before this instant
3510
+ * @returns {Promise<Page<ClientEvent>>}
3511
+ */
3512
+ listPage: (projectId: string, { limit, cursor, types, startTime, endTime }?: {
3513
+ limit?: number;
3514
+ cursor?: string;
3515
+ types?: string | string[];
3516
+ startTime?: string;
3517
+ endTime?: string;
3518
+ }) => Promise<Page<ClientEvent>>;
3519
+ /**
3520
+ * Async-iterate a project's events page by page; yields each page's entries array.
3521
+ * @param {string} projectId - The project to read
3522
+ * @param {object} [opts]
3523
+ * @param {number} [opts.pageSize] - Per-request page size
3524
+ * @param {string|string[]} [opts.types] - Only these types
3525
+ * @param {string} [opts.startTime] - Only events at or after this instant
3526
+ * @param {string} [opts.endTime] - Only events at or before this instant
3527
+ * @returns {AsyncGenerator<ClientEvent[]>}
3528
+ */
3529
+ iterPages: (projectId: string, { pageSize, types, startTime, endTime }?: {
3530
+ pageSize?: number;
3531
+ types?: string | string[];
3532
+ startTime?: string;
3533
+ endTime?: string;
3534
+ }) => AsyncGenerator<ClientEvent[]>;
3535
+ };
3536
+ guidelines: {
3537
+ /**
3538
+ * Create a guideline in a project. `title` is the handle an assistant
3539
+ * asks for one by, and the only thing a person has to keep current. It is
3540
+ * NOT required to be unique, so a title already in use is written like
3541
+ * any other: warn about it, do not refuse it. A `pinned` guideline is one
3542
+ * the assistant is given in full on every turn.
3543
+ * @param {string} projectId - The project the guideline belongs to
3544
+ * @param {string} title - The handle an assistant asks for one by (1..100 characters)
3545
+ * @param {object} [opts]
3546
+ * @param {string} [opts.body] - The Markdown text (up to 20000 characters; may be empty)
3547
+ * @param {boolean} [opts.pinned] - Send this one to the assistant in full on every turn
3548
+ * @param {string} [opts.id] - The new guideline's id, minted by the caller (see uuidv7)
3549
+ * @param {string} [auditMessage] - Audit message for this write
3550
+ * @returns {Promise<{id: string}>}
3551
+ */
3552
+ create: (projectId: string, title: string, { body, pinned, id }?: {
3553
+ body?: string;
3554
+ pinned?: boolean;
3555
+ id?: string;
3556
+ }, auditMessage?: string) => Promise<{
3557
+ id: string;
3558
+ }>;
3559
+ /**
3560
+ * Read one guideline, Markdown body included.
3561
+ * @param {string} id - The guideline id
3562
+ * @returns {Promise<Guideline>}
3563
+ */
3564
+ get: (id: string) => Promise<Guideline>;
3565
+ /**
3566
+ * Update a guideline. Every field is optional and an omitted one is
3567
+ * left alone, so an edit to the body need not restate the title.
3568
+ *
3569
+ * Pass `expectedUpdatedAt` (the `updatedAt` you last read) when a person
3570
+ * has been editing prose: the write then fails with 409 rather than
3571
+ * overwriting somebody who saved in between. Leave it off for a pin
3572
+ * toggle or a script, which have nothing of anyone's to lose.
3573
+ * @param {string} id - The guideline id
3574
+ * @param {object} [changes]
3575
+ * @param {string} [changes.title] - The new handle
3576
+ * @param {string} [changes.body] - The new Markdown text
3577
+ * @param {boolean} [changes.pinned] - Whether the assistant always gets it in full
3578
+ * @param {string} [changes.expectedUpdatedAt] - Write only if this is still the stored updatedAt
3579
+ * @param {string} [auditMessage] - Audit message for this write
3580
+ * @returns {Promise<Guideline>}
3581
+ */
3582
+ update: (id: string, { title, body, pinned, expectedUpdatedAt }?: {
3583
+ title?: string;
3584
+ body?: string;
3585
+ pinned?: boolean;
3586
+ expectedUpdatedAt?: string;
3587
+ }, auditMessage?: string) => Promise<Guideline>;
3588
+ /**
3589
+ * Delete a guideline.
3590
+ * @param {string} id - The guideline id
3591
+ * @param {string} [auditMessage] - Audit message for this write
3592
+ */
3593
+ delete: (id: string, auditMessage?: string) => Promise<any>;
3594
+ /**
3595
+ * List a project's guidelines, by title. Transparently follows
3596
+ * pagination cursors and returns the full flat array.
3597
+ *
3598
+ * Without `includeBodies` each entry carries `bodyChars`, the length of
3599
+ * its body, so a caller can budget before fetching any. Pinned
3600
+ * guidelines are NOT sorted first: `pinned` is on every entry and
3601
+ * grouping is the caller's.
3602
+ * @param {string} projectId - The project to read
3603
+ * @param {object} [opts]
3604
+ * @param {boolean} [opts.includeBodies] - Return each body instead of its length
3605
+ * @returns {Promise<Guideline[]>}
3606
+ */
3607
+ list: (projectId: string, { includeBodies }?: {
3608
+ includeBodies?: boolean;
3609
+ }) => Promise<Guideline[]>;
3610
+ /**
3611
+ * Fetch a single page of a project's guidelines.
3612
+ * @param {string} projectId - The project to read
3613
+ * @param {object} [opts]
3614
+ * @param {number} [opts.limit] - Page size (1..1000; server default 100)
3615
+ * @param {string} [opts.cursor] - Opaque cursor from a previous page
3616
+ * @param {boolean} [opts.includeBodies] - Return each body instead of its length
3617
+ * @returns {Promise<Page<Guideline>>}
3618
+ */
3619
+ listPage: (projectId: string, { limit, cursor, includeBodies }?: {
3620
+ limit?: number;
3621
+ cursor?: string;
3622
+ includeBodies?: boolean;
3623
+ }) => Promise<Page<Guideline>>;
3624
+ /**
3625
+ * Async-iterate a project's guidelines page by page; yields each page's entries array.
3626
+ * @param {string} projectId - The project to read
3627
+ * @param {object} [opts]
3628
+ * @param {number} [opts.pageSize] - Per-request page size
3629
+ * @param {boolean} [opts.includeBodies] - Return each body instead of its length
3630
+ * @returns {AsyncGenerator<Guideline[]>}
3631
+ */
3632
+ iterPages: (projectId: string, { pageSize, includeBodies }?: {
3633
+ pageSize?: number;
3634
+ includeBodies?: boolean;
3635
+ }) => AsyncGenerator<Guideline[]>;
3636
+ };
3637
+ /** @private */
3638
+ private _request;
3639
+ /**
3640
+ * Enter strict mode for a specific document, requiring document version
3641
+ * headers so that conflicting concurrent writes are rejected.
3642
+ * @param {string} documentId - The ID of the document to track versions for
3643
+ */
3644
+ enterStrictMode(documentId: string): void;
3645
+ /** Exit strict mode and stop tracking document versions for writes. */
3646
+ exitStrictMode(): void;
3647
+ /**
3648
+ * Begin a LOGICAL OPERATION: a user-meaningful action ("Merge morphemes",
3649
+ * "Re-transcribe") implemented as many low-level writes, possibly across
3650
+ * several batches and even a service round-trip. Until `endOperation()`,
3651
+ * every write is stamped with a client-minted `?group-id=` (and the message)
3652
+ * so the audit log shows the whole run as ONE expandable entry labeled
3653
+ * `message`, with each write's own description underneath.
3654
+ *
3655
+ * Grouping is orthogonal to batches: a batch is a transaction boundary, an
3656
+ * operation is an intent boundary. An operation is NOT atomic — if write 3
3657
+ * of 5 fails, writes 1–2 stay committed (and logged under the group). Use a
3658
+ * batch inside the operation for any step that must be all-or-nothing.
3659
+ *
3660
+ * Nesting flattens: a `beginOperation` while one is open is a no-op that
3661
+ * joins the outer operation (the outer label wins), and the matching
3662
+ * `endOperation` is likewise a no-op. The label is recorded on the FIRST
3663
+ * write, so an operation that is never ended (crash, closed tab) is still
3664
+ * labeled in the log.
3665
+ *
3666
+ * "Every write" is the writes of project data. Reads never join, and neither
3667
+ * do the out-of-band signals shaped like a write (a document lock taken or
3668
+ * renewed, a stopped service request, a service reporting itself, an admin
3669
+ * control), and neither does a broadcast message (`messages.sendMessage`):
3670
+ * none of them is audited, so there would be nothing under the label.
3671
+ *
3672
+ * `kind` says what kind of operation this is, for a program reading the
3673
+ * log: one of `assistant-plan`, `service-run`, `import`, `bulk-edit`,
3674
+ * `guess-adoption`, `repair` or `review` (the server refuses any other).
3675
+ * Any other kind throws here, before anything is written.
3676
+ * `ref` is a short string naming what the operation came from, in the
3677
+ * shape its kind documents (the core manual, "Kinds of operation"). Both
3678
+ * are recorded from the first write like the label, and a nested operation
3679
+ * keeps the outer one's.
3680
+ *
3681
+ * `keys` (from `keySeed()`) makes a run of the operation send the same
3682
+ * requests as an earlier run with the same keys: the nth keyed request that
3683
+ * joins it takes the Idempotency-Key `<seed>.<n>` and the document-version
3684
+ * its first run claimed, so a request that landed is answered from its
3685
+ * first send and writes nothing again. The count starts at 0 at each
3686
+ * outermost begin. A nested operation joins the outer one's keys, unless it
3687
+ * brings its own: then it numbers from 0 under its own seed until its
3688
+ * matching end, and the outer numbering resumes after it.
3689
+ *
3690
+ * @param {string} message - Human label for the operation.
3691
+ * @param {{groupId?: string, kind?: OperationKind, ref?: string, keys?: KeySeed, minted?: Iterable<string>}} [opts] - Optional `{ groupId, kind, ref, keys, minted }`. `groupId` adopts an existing group id instead of minting one (a service joining the requester's operation; `requestService` propagates an open operation to the service automatically). Python's is `group_id`. `kind`, `ref` and `keys` are described above. `minted` is the ids the operation mints for what it creates: a create refused 409 id-taken for one of them was made by an earlier send of the operation, and answers as made.
3692
+ * @returns {string} The operation's group id.
3693
+ */
3694
+ beginOperation(message: string, { groupId, kind, ref, keys, minted }?: {
3695
+ groupId?: string;
3696
+ kind?: OperationKind;
3697
+ ref?: string;
3698
+ keys?: KeySeed;
3699
+ minted?: Iterable<string>;
3700
+ }): string;
3701
+ /**
3702
+ * A seed for the Idempotency-Keys of a logical operation that may be run
3703
+ * again from the top (see beginOperation's `keys`). Keep it with the work
3704
+ * it belongs to and pass it to every run.
3705
+ * @returns {KeySeed}
3706
+ */
3707
+ keySeed(): KeySeed;
3708
+ /**
3709
+ * End the current logical operation. With no argument this is purely local
3710
+ * (no request). Pass a refined `message` to relabel the group now that the
3711
+ * outcome is known (e.g. `endOperation('Merged 3 morphemes')`) — that sends
3712
+ * one PATCH, skipped if the operation never wrote anything. A refine from a
3713
+ * nested (flattened) `endOperation` is ignored; the outer label wins.
3714
+ * @param {string} [message] - Optional refined label.
3715
+ * @returns {Promise<void>}
3716
+ */
3717
+ endOperation(message?: string): Promise<void>;
3718
+ /**
3719
+ * Run `fn` as one logical operation (see beginOperation), ending it when
3720
+ * `fn` settles — including on throw. `fn` receives a `setMessage(msg)`
3721
+ * callback to refine the label once the outcome is known.
3722
+ *
3723
+ * await client.withOperation('Merge morphemes', async (setMessage) => {
3724
+ * await client.batched(async (b) => { ... });
3725
+ * setMessage(`Merged ${n} morphemes`);
3726
+ * });
3727
+ *
3728
+ * The kind and reference (see beginOperation) come after `fn`:
3729
+ *
3730
+ * await client.withOperation('Import ELAN corpus', run, { kind: 'import', ref: 'format:elan' });
3731
+ *
3732
+ * @template T
3733
+ * @param {string} message - Human label for the operation.
3734
+ * @param {(setMessage: (msg: string) => void) => T | Promise<T>} fn - The work to run; receives `setMessage(msg)` to refine the label once the outcome is known.
3735
+ * @param {{kind?: OperationKind, ref?: string, groupId?: string, keys?: KeySeed, minted?: Iterable<string>}} [opts] - Optional `{ kind, ref, groupId, keys, minted }`, as for beginOperation. `kind` is one of `assistant-plan`, `service-run`, `import`, `bulk-edit`, `guess-adoption`, `repair` or `review`, and any other throws before `fn` runs.
3736
+ * @returns {Promise<T>} Whatever `fn` resolves to.
3737
+ */
3738
+ withOperation<T>(message: string, fn: (setMessage: (msg: string) => void) => T | Promise<T>, { kind, ref, groupId, keys, minted }?: {
3739
+ kind?: OperationKind;
3740
+ ref?: string;
3741
+ groupId?: string;
3742
+ keys?: KeySeed;
3743
+ minted?: Iterable<string>;
3744
+ }): Promise<T>;
3745
+ /**
3746
+ * Open a batch: a view of this client with the same bundles, on which every
3747
+ * write of project data queues instead of going out. `submit()` sends the
3748
+ * queued operations as ONE atomic request (larger than the server's cap,
3749
+ * as consecutive requests with the results concatenated in queue order,
3750
+ * each atomic on its own, so a failure in a later one leaves the earlier
3751
+ * ones committed, and the error it throws carries `committed`, the count
3752
+ * saved, and `committedResults`, their results) and
3753
+ * resolves to one result per operation; `abort()` drops them. A call made
3754
+ * on the client itself is never touched by an open batch, and a read or an
3755
+ * out-of-band signal made on the batch goes over the wire now (see the note
3756
+ * at the top of `http.js`).
3757
+ *
3758
+ * const b = client.batch();
3759
+ * b.tokens.bulkCreate(sentenceOps);
3760
+ * b.tokens.bulkCreate(wordOps);
3761
+ * const [sentRes, wordRes] = await b.submit();
3762
+ *
3763
+ * Server-side a batch runs sequentially in one transaction: a child op sees
3764
+ * parents created earlier in the same batch, and any op's failure rolls the
3765
+ * whole batch back. A batch is not nestable. Prefer `batched()`, which
3766
+ * submits or aborts for you.
3767
+ * @returns {PlaidBatch} the batch view
3768
+ */
3769
+ batch(): PlaidBatch;
3770
+ /**
3771
+ * POST one batch request (at most MAX_BATCH_OPS operations). Resolves to
3772
+ * one `{ status, headers, body }` per operation, with only the body
3773
+ * recased: the headers keep the server's spelling. `key` is the request's
3774
+ * Idempotency-Key: a batch whose answer is lost (no response, 502, 504) is
3775
+ * sent again under it, and answered from the first send if that landed.
3776
+ * @private
3777
+ */
3778
+ private _postBatch;
3779
+ /**
3780
+ * Run `fn` with a batch, then submit all queued ops as `submit()` does (ONE
3781
+ * atomic request up to MAX_BATCH_OPS operations, consecutive requests past
3782
+ * it), or abort the batch if `fn` throws. `fn` receives the batch and makes its
3783
+ * writes on it; it must NOT call `submit()` itself. Resolves to the batch
3784
+ * results array (`[]` if `fn` queued nothing).
3785
+ *
3786
+ * const [sentRes, wordRes] = await client.batched(async (b) => {
3787
+ * b.tokens.bulkCreate(sentenceOps);
3788
+ * b.tokens.bulkCreate(wordOps);
3789
+ * });
3790
+ *
3791
+ * A write made on `client` inside `fn` is not part of the batch: it goes
3792
+ * over the wire at once, as it would anywhere else. See `batch()`.
3793
+ * @param {(batch: PlaidBatch) => (void | Promise<void>)} fn
3794
+ * @returns {Promise<any[]>}
3795
+ */
3796
+ batched(fn: (batch: PlaidBatch) => (void | Promise<void>)): Promise<any[]>;
3797
+ }
3798
+ /**
3799
+ * The server's cap on operations per batch request (plaid.rest-api.v1.batch).
3800
+ * A batch queued past it is submitted as consecutive requests.
3801
+ */
3802
+ export const MAX_BATCH_OPS: 1000;
3803
+ export { valueSetAllows, violationsOf } from "./constraints.js";
3804
+ export { cpLength, cpSlice, cpSlicer, utf16ToCp, cpIndexOf, composeText } from "./codepoint.js";
3805
+ export { composeTextEdits, gapsToOps, applyTextOps } from "./textEdits.js";
3806
+ export { PLAID_NAMESPACE, ROLE_KEY, PRESERVE_ON_SPLIT_KEY, SPLIT_ON_SPACE_KEY, ROLES, readRole, findByRole } from "./roles.js";
3807
+ export { TASKS, servesTask, filterServicesByTask, getParamSchema, getServiceSummary, buildDefaultValues, coerceParamValues } from "./serviceSchema.js";
3808
+ export { ServiceCancelled, createCancelScope } from "./services.js";
3809
+ export { REQUESTED_BY, makeRequester, requesterOf } from "./requester.js";
3810
+ export { DocumentLock, DocumentLockLost } from "./documentLock.js";
3811
+ export { PROV, PROV_STATES, PROVENANCE_KEYS, stampInferred, confirmedInferred, stampContributed, provState, provOrigin, isMachine, isProtected, needsReview, contributeOnEdit, serviceSource, REVIEW_KEY, readReview, projectRole, isReviewed, withReviewedUser, writerPolicy } from "./provenance.js";
3812
+ export { metadataOps, applyMetadataOps, mergeMetadata, isReservedMetadataKey } from "./metadataOps.js";
3813
+ export { createdId, createdIds } from "./created.js";
3814
+ export { uuidv4, uuidv7, normalizeUserId } from "./ids.js";