@larc-iu/plaid-client 0.2.0-alpha.16 → 0.2.0-alpha.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +285 -60
- package/package.json +1 -1
- package/src/created.js +29 -0
- package/src/http.js +153 -56
- package/src/index.js +323 -195
- package/src/metadataOps.js +117 -0
- package/src/provenance.js +2 -16
- package/src/services.js +42 -5
- package/src/sse.js +29 -3
- package/src/transforms.js +7 -1
package/src/index.js
CHANGED
|
@@ -6,6 +6,7 @@ import { transformRequest, transformResponse } from "./transforms.js";
|
|
|
6
6
|
import {
|
|
7
7
|
makeRequest,
|
|
8
8
|
queueRequest,
|
|
9
|
+
restampDocumentVersion,
|
|
9
10
|
extractDocumentVersions,
|
|
10
11
|
parseErrorBody,
|
|
11
12
|
makeHttpError,
|
|
@@ -128,6 +129,9 @@ function openBatch(client) {
|
|
|
128
129
|
const batch = Object.create(client);
|
|
129
130
|
batch.client = client;
|
|
130
131
|
batch.operations = [];
|
|
132
|
+
// The document each queued op's strict-mode stamp is for (null for none),
|
|
133
|
+
// index for index with `operations`.
|
|
134
|
+
batch.stampedDocuments = [];
|
|
131
135
|
batch.open = true;
|
|
132
136
|
batch._request = (method, path, options = {}) =>
|
|
133
137
|
queueRequest(batch, method, path, options);
|
|
@@ -138,6 +142,7 @@ function openBatch(client) {
|
|
|
138
142
|
batch.submit = () => submitBatch(batch);
|
|
139
143
|
batch.abort = () => {
|
|
140
144
|
batch.operations = [];
|
|
145
|
+
batch.stampedDocuments = [];
|
|
141
146
|
batch.open = false;
|
|
142
147
|
};
|
|
143
148
|
batch._installResources();
|
|
@@ -150,23 +155,57 @@ async function submitBatch(batch) {
|
|
|
150
155
|
}
|
|
151
156
|
batch.open = false;
|
|
152
157
|
const ops = batch.operations;
|
|
158
|
+
const stamps = batch.stampedDocuments;
|
|
153
159
|
batch.operations = [];
|
|
160
|
+
batch.stampedDocuments = [];
|
|
154
161
|
if (ops.length === 0) return [];
|
|
155
|
-
const
|
|
162
|
+
const client = batch.client;
|
|
163
|
+
const url = `${client.baseUrl}/api/v1/batch`;
|
|
156
164
|
// The server caps a batch at MAX_BATCH_OPS so one transaction cannot hold
|
|
157
165
|
// the write lock without bound. A larger batch goes as consecutive
|
|
158
166
|
// requests, results concatenated in queue order: it could not have been one
|
|
159
167
|
// transaction anyway, and a repair or bulk edit over a big document must
|
|
160
|
-
// not fail on its size alone.
|
|
168
|
+
// not fail on its size alone. Past the first request, a strict-mode stamp
|
|
169
|
+
// claims the version the requests before it left (learned from their
|
|
170
|
+
// results), not the one the document had when the op was queued, which the
|
|
171
|
+
// first request has already moved on.
|
|
172
|
+
//
|
|
173
|
+
// Each request is atomic, the whole is not: a failure leaves the requests
|
|
174
|
+
// before it saved. The error says so, as `committed` (how many operations
|
|
175
|
+
// were saved) and `committedResults` (their results, in queue order), so a
|
|
176
|
+
// caller can tell a partial write from a batch that saved nothing. The
|
|
177
|
+
// failed request itself counts as unsaved, even when its answer was lost.
|
|
161
178
|
const results = [];
|
|
162
|
-
|
|
163
|
-
results
|
|
164
|
-
|
|
165
|
-
)
|
|
179
|
+
try {
|
|
180
|
+
await sendChunks(client, url, ops, stamps, results);
|
|
181
|
+
} catch (error) {
|
|
182
|
+
if (error && typeof error === "object") {
|
|
183
|
+
error.committed = results.length;
|
|
184
|
+
error.committedResults = results;
|
|
185
|
+
}
|
|
186
|
+
throw error;
|
|
166
187
|
}
|
|
167
188
|
return results;
|
|
168
189
|
}
|
|
169
190
|
|
|
191
|
+
async function sendChunks(client, url, ops, stamps, results) {
|
|
192
|
+
for (let i = 0; i < ops.length; i += MAX_BATCH_OPS) {
|
|
193
|
+
let chunk = ops.slice(i, i + MAX_BATCH_OPS);
|
|
194
|
+
if (i > 0) {
|
|
195
|
+
chunk = chunk.map((op, j) => {
|
|
196
|
+
const docId = stamps[i + j];
|
|
197
|
+
if (!docId) return op;
|
|
198
|
+
const path = restampDocumentVersion(
|
|
199
|
+
op.path,
|
|
200
|
+
client.documentVersions[docId],
|
|
201
|
+
);
|
|
202
|
+
return { ...op, path };
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
results.push(...(await client._postBatch(url, chunk)));
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
170
209
|
class PlaidClient {
|
|
171
210
|
/**
|
|
172
211
|
* Create a new PlaidClient instance
|
|
@@ -261,7 +300,6 @@ class PlaidClient {
|
|
|
261
300
|
this._request("PUT", `/api/v1/vocab-links/${id}/metadata`, {
|
|
262
301
|
auditMessage,
|
|
263
302
|
rawBody: body,
|
|
264
|
-
skipResponseTransform: true,
|
|
265
303
|
}),
|
|
266
304
|
/**
|
|
267
305
|
* Remove all metadata from a vocab link.
|
|
@@ -270,28 +308,23 @@ class PlaidClient {
|
|
|
270
308
|
deleteMetadata: (id, auditMessage) =>
|
|
271
309
|
this._request("DELETE", `/api/v1/vocab-links/${id}/metadata`, {
|
|
272
310
|
auditMessage,
|
|
273
|
-
skipResponseTransform: true,
|
|
274
311
|
}),
|
|
275
312
|
/**
|
|
276
|
-
*
|
|
313
|
+
* Edit metadata for a vocab link 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.
|
|
277
314
|
* @param {string} id - The resource ID
|
|
278
|
-
* @param {any} body - The metadata
|
|
315
|
+
* @param {Array<{op: string, path: string[], value?: any}>} body - The metadata ops
|
|
279
316
|
*/
|
|
280
317
|
patchMetadata: (id, body, auditMessage) =>
|
|
281
318
|
this._request("PATCH", `/api/v1/vocab-links/${id}/metadata`, {
|
|
282
319
|
auditMessage,
|
|
283
320
|
rawBody: body,
|
|
284
|
-
skipResponseTransform: true,
|
|
285
321
|
}),
|
|
286
322
|
/**
|
|
287
323
|
* Get a vocab link by ID
|
|
288
324
|
* @param {string} id - The resource ID
|
|
289
|
-
* @param {string} [asOf] - Temporal query timestamp
|
|
290
325
|
*/
|
|
291
|
-
get: (id
|
|
292
|
-
this._request("GET", `/api/v1/vocab-links/${id}
|
|
293
|
-
queryParams: { "as-of": asOf },
|
|
294
|
-
}),
|
|
326
|
+
get: (id) =>
|
|
327
|
+
this._request("GET", `/api/v1/vocab-links/${id}`),
|
|
295
328
|
/**
|
|
296
329
|
* Delete a vocab link
|
|
297
330
|
* @param {string} id - The resource ID
|
|
@@ -302,15 +335,113 @@ class PlaidClient {
|
|
|
302
335
|
|
|
303
336
|
this.vocabLayers = {
|
|
304
337
|
/**
|
|
305
|
-
* Get a vocab layer by ID
|
|
338
|
+
* Get a vocab layer by ID. With `asOf`, the vocabulary as it was at that
|
|
339
|
+
* instant, read from its history: the same shape as the live read, its
|
|
340
|
+
* entries with `includeItems`. A vocabulary that did not exist then is a
|
|
341
|
+
* 404, a malformed or pruned time a 400.
|
|
306
342
|
* @param {string} id - The resource ID
|
|
307
343
|
* @param {boolean} [includeItems] - Include vocab items
|
|
308
|
-
* @param {string} [asOf] -
|
|
344
|
+
* @param {string} [asOf] - The moment to read at (ISO-8601 instant)
|
|
309
345
|
*/
|
|
310
346
|
get: (id, includeItems, asOf) =>
|
|
311
347
|
this._request("GET", `/api/v1/vocab-layers/${id}`, {
|
|
312
348
|
queryParams: { "include-items": includeItems, "as-of": asOf },
|
|
313
349
|
}),
|
|
350
|
+
/**
|
|
351
|
+
* One entry of the vocabulary as it was at `asOf`, also when it has
|
|
352
|
+
* been deleted since. The same shape as `vocabItems.get`. A 404 when
|
|
353
|
+
* the entry was not in this vocabulary at that time.
|
|
354
|
+
* @param {string} id - The vocabulary ID
|
|
355
|
+
* @param {string} itemId - The entry ID
|
|
356
|
+
* @param {string} asOf - The moment to read at (ISO-8601 instant)
|
|
357
|
+
*/
|
|
358
|
+
getItemAt: (id, itemId, asOf) =>
|
|
359
|
+
this._request("GET", `/api/v1/vocab-layers/${id}/items/${itemId}`, {
|
|
360
|
+
queryParams: { "as-of": asOf },
|
|
361
|
+
}),
|
|
362
|
+
/**
|
|
363
|
+
* Get the audit log of a vocabulary: every change to it or to its
|
|
364
|
+
* entries, folded into entries as the document log is. Links are not
|
|
365
|
+
* listed, they belong to the document they annotate. Transparently
|
|
366
|
+
* follows pagination cursors and returns the full flat array.
|
|
367
|
+
* @param {string} id - The vocabulary ID
|
|
368
|
+
* @param {string} [startTime] - Start of time range
|
|
369
|
+
* @param {string} [endTime] - End of time range
|
|
370
|
+
* @param {string[]|string} [opTypes] - Only return operations of these
|
|
371
|
+
* types, spelled as in an entry's `op/type` (e.g.
|
|
372
|
+
* `['vocab-item/delete', 'vocab-item/restore']`)
|
|
373
|
+
* @param {string} [itemId] - Only the changes that wrote this one entry,
|
|
374
|
+
* each with only its operations that did
|
|
375
|
+
*/
|
|
376
|
+
audit: (id, startTime, endTime, opTypes, itemId) =>
|
|
377
|
+
listAll(this, `/api/v1/vocab-layers/${id}/audit`, {
|
|
378
|
+
query: {
|
|
379
|
+
"start-time": startTime,
|
|
380
|
+
"end-time": endTime,
|
|
381
|
+
"op-types": opTypesParam(opTypes),
|
|
382
|
+
"item-id": itemId,
|
|
383
|
+
},
|
|
384
|
+
}),
|
|
385
|
+
/**
|
|
386
|
+
* One page of the same log, newest-first with `order: "desc"`. Use this
|
|
387
|
+
* rather than audit() wherever the caller wants the recent end of a log
|
|
388
|
+
* that may be long: audit() walks every page before it resolves.
|
|
389
|
+
* @param {string} id - The vocabulary ID
|
|
390
|
+
* @param {object} [opts]
|
|
391
|
+
* @param {"asc"|"desc"} [opts.order] - "desc" pages newest-first
|
|
392
|
+
* @param {number} [opts.limit] - Page size (1..1000; server default 100)
|
|
393
|
+
* @param {string} [opts.cursor] - Opaque cursor from a previous page
|
|
394
|
+
* @param {string} [opts.itemId] - Only the changes that wrote this one
|
|
395
|
+
* entry, each with only its operations that did
|
|
396
|
+
* @returns {Promise<{entries: Array, nextCursor: (string|null)}>}
|
|
397
|
+
*/
|
|
398
|
+
auditPage: (
|
|
399
|
+
id,
|
|
400
|
+
{ startTime, endTime, opTypes, order, limit, cursor, itemId } = {},
|
|
401
|
+
) =>
|
|
402
|
+
listPage(this, `/api/v1/vocab-layers/${id}/audit`, {
|
|
403
|
+
limit,
|
|
404
|
+
cursor,
|
|
405
|
+
query: {
|
|
406
|
+
"start-time": startTime,
|
|
407
|
+
"end-time": endTime,
|
|
408
|
+
"op-types": opTypesParam(opTypes),
|
|
409
|
+
order,
|
|
410
|
+
"item-id": itemId,
|
|
411
|
+
},
|
|
412
|
+
}),
|
|
413
|
+
/**
|
|
414
|
+
* Put one entry of the vocabulary back as it was at `asOf`, as one
|
|
415
|
+
* operation. A deleted entry comes back under its original id with its
|
|
416
|
+
* form and fields, and a living one has its form and fields set back.
|
|
417
|
+
* Links are not part of an entry: a deleted entry's links come back
|
|
418
|
+
* through each document's own `documents.restore`. Resolves to
|
|
419
|
+
* `{inserted, form, metadata, total}`, `total` 0 when nothing changes.
|
|
420
|
+
* A form set back bumps every linking document, and the new versions
|
|
421
|
+
* come back in X-Document-Versions (or, past fifty documents,
|
|
422
|
+
* X-Document-Versions-Omitted), which the client takes up as on any
|
|
423
|
+
* write. A time when the entry did not exist is a 400. Maintainers of
|
|
424
|
+
* the vocabulary only.
|
|
425
|
+
* @param {string} id - The vocabulary ID
|
|
426
|
+
* @param {string} itemId - The entry ID
|
|
427
|
+
* @param {string} asOf - The moment to go back to (ISO-8601 instant),
|
|
428
|
+
* typically a history entry's `endTime`
|
|
429
|
+
* @param {object} [options] - `{ dryRun }`: with `dryRun` true nothing
|
|
430
|
+
* is written and the summary says what would change
|
|
431
|
+
* @param {string} [auditMessage] - Custom audit message for this operation
|
|
432
|
+
*/
|
|
433
|
+
restoreItem: (id, itemId, asOf, { dryRun } = {}, auditMessage) =>
|
|
434
|
+
this._request(
|
|
435
|
+
"POST",
|
|
436
|
+
`/api/v1/vocab-layers/${id}/items/${itemId}/restore`,
|
|
437
|
+
{
|
|
438
|
+
queryParams: {
|
|
439
|
+
"as-of": asOf,
|
|
440
|
+
"dry-run": dryRun ? "true" : undefined,
|
|
441
|
+
},
|
|
442
|
+
auditMessage,
|
|
443
|
+
},
|
|
444
|
+
),
|
|
314
445
|
/**
|
|
315
446
|
* Delete a vocab layer.
|
|
316
447
|
* @param {string} id - The resource ID
|
|
@@ -355,35 +486,29 @@ class PlaidClient {
|
|
|
355
486
|
/**
|
|
356
487
|
* List all vocab layers accessible to user. Transparently follows
|
|
357
488
|
* pagination cursors and returns the full flat array.
|
|
358
|
-
* @param {string} [asOf] - Temporal query timestamp
|
|
359
489
|
*/
|
|
360
|
-
list: (
|
|
361
|
-
listAll(this, "/api/v1/vocab-layers", { query: { "as-of": asOf } }),
|
|
490
|
+
list: () => listAll(this, "/api/v1/vocab-layers"),
|
|
362
491
|
/**
|
|
363
492
|
* Fetch a single page of vocab layers.
|
|
364
493
|
* @param {object} [opts]
|
|
365
494
|
* @param {number} [opts.limit] - Page size (1..1000; server default 100)
|
|
366
495
|
* @param {string} [opts.cursor] - Opaque cursor from a previous page
|
|
367
|
-
* @param {string} [opts.asOf] - Temporal query timestamp
|
|
368
496
|
* @returns {Promise<{entries: Array, nextCursor: (string|null)}>}
|
|
369
497
|
*/
|
|
370
|
-
listPage: ({ limit, cursor
|
|
498
|
+
listPage: ({ limit, cursor } = {}) =>
|
|
371
499
|
listPage(this, "/api/v1/vocab-layers", {
|
|
372
500
|
limit,
|
|
373
501
|
cursor,
|
|
374
|
-
query: { "as-of": asOf },
|
|
375
502
|
}),
|
|
376
503
|
/**
|
|
377
504
|
* Async-iterate vocab layers page by page; yields each page's entries array.
|
|
378
505
|
* @param {object} [opts]
|
|
379
506
|
* @param {number} [opts.pageSize] - Per-request page size
|
|
380
|
-
* @param {string} [opts.asOf] - Temporal query timestamp
|
|
381
507
|
* @returns {AsyncGenerator<Array>}
|
|
382
508
|
*/
|
|
383
|
-
iterPages: ({ pageSize
|
|
509
|
+
iterPages: ({ pageSize } = {}) =>
|
|
384
510
|
iterPages(this, "/api/v1/vocab-layers", {
|
|
385
511
|
pageSize,
|
|
386
|
-
query: { "as-of": asOf },
|
|
387
512
|
}),
|
|
388
513
|
/**
|
|
389
514
|
* Create a new vocab layer. Note: this also registers the user as a maintainer.
|
|
@@ -428,7 +553,6 @@ class PlaidClient {
|
|
|
428
553
|
this._request("PUT", `/api/v1/relations/${relationId}/metadata`, {
|
|
429
554
|
auditMessage,
|
|
430
555
|
rawBody: body,
|
|
431
|
-
skipResponseTransform: true,
|
|
432
556
|
}),
|
|
433
557
|
/**
|
|
434
558
|
* Remove all metadata from a relation.
|
|
@@ -437,18 +561,16 @@ class PlaidClient {
|
|
|
437
561
|
deleteMetadata: (relationId, auditMessage) =>
|
|
438
562
|
this._request("DELETE", `/api/v1/relations/${relationId}/metadata`, {
|
|
439
563
|
auditMessage,
|
|
440
|
-
skipResponseTransform: true,
|
|
441
564
|
}),
|
|
442
565
|
/**
|
|
443
|
-
*
|
|
566
|
+
* Edit metadata for a relation 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.
|
|
444
567
|
* @param {string} relationId - The relation ID
|
|
445
|
-
* @param {any} body - The metadata
|
|
568
|
+
* @param {Array<{op: string, path: string[], value?: any}>} body - The metadata ops
|
|
446
569
|
*/
|
|
447
570
|
patchMetadata: (relationId, body, auditMessage) =>
|
|
448
571
|
this._request("PATCH", `/api/v1/relations/${relationId}/metadata`, {
|
|
449
572
|
auditMessage,
|
|
450
573
|
rawBody: body,
|
|
451
|
-
skipResponseTransform: true,
|
|
452
574
|
}),
|
|
453
575
|
/**
|
|
454
576
|
* Update the target span of a relation.
|
|
@@ -463,12 +585,9 @@ class PlaidClient {
|
|
|
463
585
|
/**
|
|
464
586
|
* Get a relation by ID.
|
|
465
587
|
* @param {string} relationId - The relation ID
|
|
466
|
-
* @param {string} [asOf] - Temporal query timestamp
|
|
467
588
|
*/
|
|
468
|
-
get: (relationId
|
|
469
|
-
this._request("GET", `/api/v1/relations/${relationId}
|
|
470
|
-
queryParams: { "as-of": asOf },
|
|
471
|
-
}),
|
|
589
|
+
get: (relationId) =>
|
|
590
|
+
this._request("GET", `/api/v1/relations/${relationId}`),
|
|
472
591
|
/**
|
|
473
592
|
* Delete a relation.
|
|
474
593
|
* @param {string} relationId - The relation ID
|
|
@@ -536,7 +655,7 @@ class PlaidClient {
|
|
|
536
655
|
}),
|
|
537
656
|
/**
|
|
538
657
|
* Update many relations in a single operation: set values and/or patch metadata.
|
|
539
|
-
* @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
|
|
658
|
+
* @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.
|
|
540
659
|
* @returns {Promise<{count: number}>} How many relations were updated.
|
|
541
660
|
*/
|
|
542
661
|
bulkUpdate: (body, auditMessage) =>
|
|
@@ -581,12 +700,9 @@ class PlaidClient {
|
|
|
581
700
|
/**
|
|
582
701
|
* Get a span layer by ID.
|
|
583
702
|
* @param {string} spanLayerId - The span layer ID
|
|
584
|
-
* @param {string} [asOf] - Temporal query timestamp
|
|
585
703
|
*/
|
|
586
|
-
get: (spanLayerId
|
|
587
|
-
this._request("GET", `/api/v1/span-layers/${spanLayerId}
|
|
588
|
-
queryParams: { "as-of": asOf },
|
|
589
|
-
}),
|
|
704
|
+
get: (spanLayerId) =>
|
|
705
|
+
this._request("GET", `/api/v1/span-layers/${spanLayerId}`),
|
|
590
706
|
/**
|
|
591
707
|
* Delete a span layer.
|
|
592
708
|
* @param {string} spanLayerId - The span layer ID
|
|
@@ -659,12 +775,9 @@ class PlaidClient {
|
|
|
659
775
|
/**
|
|
660
776
|
* Get a span by ID.
|
|
661
777
|
* @param {string} spanId - The span ID
|
|
662
|
-
* @param {string} [asOf] - Temporal query timestamp
|
|
663
778
|
*/
|
|
664
|
-
get: (spanId
|
|
665
|
-
this._request("GET", `/api/v1/spans/${spanId}
|
|
666
|
-
queryParams: { "as-of": asOf },
|
|
667
|
-
}),
|
|
779
|
+
get: (spanId) =>
|
|
780
|
+
this._request("GET", `/api/v1/spans/${spanId}`),
|
|
668
781
|
/**
|
|
669
782
|
* Delete a span.
|
|
670
783
|
* @param {string} spanId - The span ID
|
|
@@ -696,7 +809,7 @@ class PlaidClient {
|
|
|
696
809
|
this._request("DELETE", "/api/v1/spans/bulk", { auditMessage, body }),
|
|
697
810
|
/**
|
|
698
811
|
* Update many spans in a single operation: set values and/or patch metadata.
|
|
699
|
-
* @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
|
|
812
|
+
* @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.
|
|
700
813
|
* @returns {Promise<{count: number}>} How many spans were updated.
|
|
701
814
|
*/
|
|
702
815
|
bulkUpdate: (body, auditMessage) =>
|
|
@@ -713,7 +826,6 @@ class PlaidClient {
|
|
|
713
826
|
this._request("PUT", `/api/v1/spans/${spanId}/metadata`, {
|
|
714
827
|
auditMessage,
|
|
715
828
|
rawBody: body,
|
|
716
|
-
skipResponseTransform: true,
|
|
717
829
|
}),
|
|
718
830
|
/**
|
|
719
831
|
* Remove all metadata from a span.
|
|
@@ -722,18 +834,16 @@ class PlaidClient {
|
|
|
722
834
|
deleteMetadata: (spanId, auditMessage) =>
|
|
723
835
|
this._request("DELETE", `/api/v1/spans/${spanId}/metadata`, {
|
|
724
836
|
auditMessage,
|
|
725
|
-
skipResponseTransform: true,
|
|
726
837
|
}),
|
|
727
838
|
/**
|
|
728
|
-
*
|
|
839
|
+
* Edit metadata for a span 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.
|
|
729
840
|
* @param {string} spanId - The span ID
|
|
730
|
-
* @param {any} body - The metadata
|
|
841
|
+
* @param {Array<{op: string, path: string[], value?: any}>} body - The metadata ops
|
|
731
842
|
*/
|
|
732
843
|
patchMetadata: (spanId, body, auditMessage) =>
|
|
733
844
|
this._request("PATCH", `/api/v1/spans/${spanId}/metadata`, {
|
|
734
845
|
auditMessage,
|
|
735
846
|
rawBody: body,
|
|
736
|
-
skipResponseTransform: true,
|
|
737
847
|
}),
|
|
738
848
|
};
|
|
739
849
|
|
|
@@ -769,6 +879,24 @@ class PlaidClient {
|
|
|
769
879
|
health: () => PlaidClient.health(this.baseUrl, { timeout: this.timeout }),
|
|
770
880
|
};
|
|
771
881
|
|
|
882
|
+
// The signed-in user's sign-ins. Signing in is `PlaidClient.login`, which
|
|
883
|
+
// makes the client.
|
|
884
|
+
this.auth = {
|
|
885
|
+
/**
|
|
886
|
+
* End every sign-in of this user on every device: each browser tab,
|
|
887
|
+
* script and service holding one of the user's sign-in tokens is
|
|
888
|
+
* refused from now on, this client included. Named API tokens are not
|
|
889
|
+
* affected (revoke one with `apiTokens.revoke`). To sign out of one tab
|
|
890
|
+
* only, discard its token instead. A signal rather than project data:
|
|
891
|
+
* made on a batch it still goes out at once, and it never joins an
|
|
892
|
+
* operation.
|
|
893
|
+
* @returns {Promise<void>}
|
|
894
|
+
*/
|
|
895
|
+
logoutEverywhere: async () => {
|
|
896
|
+
await this._request("POST", "/api/v1/logout", { outOfBand: true });
|
|
897
|
+
},
|
|
898
|
+
};
|
|
899
|
+
|
|
772
900
|
this.texts = {
|
|
773
901
|
/**
|
|
774
902
|
* Replace all metadata for a text.
|
|
@@ -779,7 +907,6 @@ class PlaidClient {
|
|
|
779
907
|
this._request("PUT", `/api/v1/texts/${textId}/metadata`, {
|
|
780
908
|
auditMessage,
|
|
781
909
|
rawBody: body,
|
|
782
|
-
skipResponseTransform: true,
|
|
783
910
|
}),
|
|
784
911
|
/**
|
|
785
912
|
* Remove all metadata from a text.
|
|
@@ -788,18 +915,16 @@ class PlaidClient {
|
|
|
788
915
|
deleteMetadata: (textId, auditMessage) =>
|
|
789
916
|
this._request("DELETE", `/api/v1/texts/${textId}/metadata`, {
|
|
790
917
|
auditMessage,
|
|
791
|
-
skipResponseTransform: true,
|
|
792
918
|
}),
|
|
793
919
|
/**
|
|
794
|
-
*
|
|
920
|
+
* Edit metadata for a text 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.
|
|
795
921
|
* @param {string} textId - The text ID
|
|
796
|
-
* @param {any} body - The metadata
|
|
922
|
+
* @param {Array<{op: string, path: string[], value?: any}>} body - The metadata ops
|
|
797
923
|
*/
|
|
798
924
|
patchMetadata: (textId, body, auditMessage) =>
|
|
799
925
|
this._request("PATCH", `/api/v1/texts/${textId}/metadata`, {
|
|
800
926
|
auditMessage,
|
|
801
927
|
rawBody: body,
|
|
802
|
-
skipResponseTransform: true,
|
|
803
928
|
}),
|
|
804
929
|
/**
|
|
805
930
|
* Create a new text in a document's text layer. A text is a container for
|
|
@@ -822,12 +947,9 @@ class PlaidClient {
|
|
|
822
947
|
/**
|
|
823
948
|
* Get a text.
|
|
824
949
|
* @param {string} textId - The text ID
|
|
825
|
-
* @param {string} [asOf] - Temporal query timestamp
|
|
826
950
|
*/
|
|
827
|
-
get: (textId
|
|
828
|
-
this._request("GET", `/api/v1/texts/${textId}
|
|
829
|
-
queryParams: { "as-of": asOf },
|
|
830
|
-
}),
|
|
951
|
+
get: (textId) =>
|
|
952
|
+
this._request("GET", `/api/v1/texts/${textId}`),
|
|
831
953
|
/**
|
|
832
954
|
* Delete a text and all dependent data.
|
|
833
955
|
* @param {string} textId - The text ID
|
|
@@ -859,37 +981,34 @@ class PlaidClient {
|
|
|
859
981
|
* returns the full flat array. Admin-or-maintainer only.
|
|
860
982
|
* @param {object} [opts]
|
|
861
983
|
* @param {string} [opts.q] - Filter to users whose display name or email contains this text (case-insensitive)
|
|
862
|
-
* @param {string} [opts.asOf] - Temporal query timestamp
|
|
863
984
|
*/
|
|
864
|
-
list: ({ q
|
|
865
|
-
listAll(this, "/api/v1/users", { query: { q
|
|
985
|
+
list: ({ q } = {}) =>
|
|
986
|
+
listAll(this, "/api/v1/users", { query: { q } }),
|
|
866
987
|
/**
|
|
867
988
|
* Fetch a single page of users (optionally filtered by `q`).
|
|
868
989
|
* @param {object} [opts]
|
|
869
990
|
* @param {string} [opts.q] - Filter to users whose display name or email contains this text (case-insensitive)
|
|
870
991
|
* @param {number} [opts.limit] - Page size (1..1000; server default 100)
|
|
871
992
|
* @param {string} [opts.cursor] - Opaque cursor from a previous page
|
|
872
|
-
* @param {string} [opts.asOf] - Temporal query timestamp
|
|
873
993
|
* @returns {Promise<{entries: Array, nextCursor: (string|null)}>}
|
|
874
994
|
*/
|
|
875
|
-
listPage: ({ q, limit, cursor
|
|
995
|
+
listPage: ({ q, limit, cursor } = {}) =>
|
|
876
996
|
listPage(this, "/api/v1/users", {
|
|
877
997
|
limit,
|
|
878
998
|
cursor,
|
|
879
|
-
query: { q
|
|
999
|
+
query: { q },
|
|
880
1000
|
}),
|
|
881
1001
|
/**
|
|
882
1002
|
* Async-iterate users page by page; yields each page's entries array.
|
|
883
1003
|
* @param {object} [opts]
|
|
884
1004
|
* @param {string} [opts.q] - Filter to users whose display name or email contains this text (case-insensitive)
|
|
885
1005
|
* @param {number} [opts.pageSize] - Per-request page size
|
|
886
|
-
* @param {string} [opts.asOf] - Temporal query timestamp
|
|
887
1006
|
* @returns {AsyncGenerator<Array>}
|
|
888
1007
|
*/
|
|
889
|
-
iterPages: ({ q, pageSize
|
|
1008
|
+
iterPages: ({ q, pageSize } = {}) =>
|
|
890
1009
|
iterPages(this, "/api/v1/users", {
|
|
891
1010
|
pageSize,
|
|
892
|
-
query: { q
|
|
1011
|
+
query: { q },
|
|
893
1012
|
}),
|
|
894
1013
|
/**
|
|
895
1014
|
* Create a new user.
|
|
@@ -907,7 +1026,9 @@ class PlaidClient {
|
|
|
907
1026
|
email,
|
|
908
1027
|
password,
|
|
909
1028
|
"is-admin": isAdmin,
|
|
910
|
-
|
|
1029
|
+
// Left out when not given (null too), so core gives the user the
|
|
1030
|
+
// local part of the email. Core refuses a null display name.
|
|
1031
|
+
"display-name": displayName ?? undefined,
|
|
911
1032
|
}),
|
|
912
1033
|
}),
|
|
913
1034
|
/**
|
|
@@ -916,18 +1037,16 @@ class PlaidClient {
|
|
|
916
1037
|
* @param {string} userId - The user ID
|
|
917
1038
|
* @param {string} [startTime] - Start of time range
|
|
918
1039
|
* @param {string} [endTime] - End of time range
|
|
919
|
-
* @param {string} [asOf] - Temporal query timestamp
|
|
920
1040
|
* @param {string[]|string} [opTypes] - Only return operations of these
|
|
921
1041
|
* types, spelled as in an entry's `op/type` (e.g.
|
|
922
1042
|
* `['span-layer/create', 'span-layer/delete']`). An entry appears when
|
|
923
1043
|
* one of its operations matches, carrying only the ones that did.
|
|
924
1044
|
*/
|
|
925
|
-
audit: (userId, startTime, endTime,
|
|
1045
|
+
audit: (userId, startTime, endTime, opTypes) =>
|
|
926
1046
|
listAll(this, `/api/v1/users/${userId}/audit`, {
|
|
927
1047
|
query: {
|
|
928
1048
|
"start-time": startTime,
|
|
929
1049
|
"end-time": endTime,
|
|
930
|
-
"as-of": asOf,
|
|
931
1050
|
"op-types": opTypesParam(opTypes),
|
|
932
1051
|
},
|
|
933
1052
|
}),
|
|
@@ -935,6 +1054,7 @@ class PlaidClient {
|
|
|
935
1054
|
* One page of the same log, newest-first with `order: "desc"`. Use this
|
|
936
1055
|
* rather than audit() wherever the caller wants the recent end of a log
|
|
937
1056
|
* that may be long: audit() walks every page before it resolves.
|
|
1057
|
+
* @param {string} userId - The user ID
|
|
938
1058
|
* @param {object} [opts]
|
|
939
1059
|
* @param {"asc"|"desc"} [opts.order] - "desc" pages newest-first
|
|
940
1060
|
* @param {number} [opts.limit] - Page size (1..1000; server default 100)
|
|
@@ -943,7 +1063,7 @@ class PlaidClient {
|
|
|
943
1063
|
*/
|
|
944
1064
|
auditPage: (
|
|
945
1065
|
userId,
|
|
946
|
-
{ startTime, endTime,
|
|
1066
|
+
{ startTime, endTime, opTypes, order, limit, cursor } = {},
|
|
947
1067
|
) =>
|
|
948
1068
|
listPage(this, `/api/v1/users/${userId}/audit`, {
|
|
949
1069
|
limit,
|
|
@@ -951,7 +1071,6 @@ class PlaidClient {
|
|
|
951
1071
|
query: {
|
|
952
1072
|
"start-time": startTime,
|
|
953
1073
|
"end-time": endTime,
|
|
954
|
-
"as-of": asOf,
|
|
955
1074
|
"op-types": opTypesParam(opTypes),
|
|
956
1075
|
order,
|
|
957
1076
|
},
|
|
@@ -959,12 +1078,9 @@ class PlaidClient {
|
|
|
959
1078
|
/**
|
|
960
1079
|
* Get a user by ID
|
|
961
1080
|
* @param {string} id - The resource ID
|
|
962
|
-
* @param {string} [asOf] - Temporal query timestamp
|
|
963
1081
|
*/
|
|
964
|
-
get: (id
|
|
965
|
-
this._request("GET", `/api/v1/users/${id}
|
|
966
|
-
queryParams: { "as-of": asOf },
|
|
967
|
-
}),
|
|
1082
|
+
get: (id) =>
|
|
1083
|
+
this._request("GET", `/api/v1/users/${id}`),
|
|
968
1084
|
/**
|
|
969
1085
|
* Deactivate a user. Users are never hard-deleted: deactivation
|
|
970
1086
|
* rejects their logins and tokens, strips their project memberships
|
|
@@ -1142,7 +1258,7 @@ class PlaidClient {
|
|
|
1142
1258
|
),
|
|
1143
1259
|
/**
|
|
1144
1260
|
* Create or replace one private data entry. `value` is any JSON (up to
|
|
1145
|
-
* 1 MB)
|
|
1261
|
+
* 1 MB). Not audited, not batchable.
|
|
1146
1262
|
*
|
|
1147
1263
|
* The server stores it verbatim, but this client recases object keys on
|
|
1148
1264
|
* the way out and back like any other body (`myKey` <-> `my-key`), so a
|
|
@@ -1210,7 +1326,7 @@ class PlaidClient {
|
|
|
1210
1326
|
* credential and is shown ONLY here — store it immediately. API tokens
|
|
1211
1327
|
* do not expire and survive password changes / logout; revoke to kill.
|
|
1212
1328
|
* @param {string} userId - The user ID who will own the token
|
|
1213
|
-
* @param {string} name - A human label, e.g. "Stanza
|
|
1329
|
+
* @param {string} name - A human label, e.g. "Stanza parser"
|
|
1214
1330
|
* @returns {Promise<{id: string, name: string, token: string}>}
|
|
1215
1331
|
*/
|
|
1216
1332
|
create: (userId, name, auditMessage) =>
|
|
@@ -1626,12 +1742,9 @@ class PlaidClient {
|
|
|
1626
1742
|
/**
|
|
1627
1743
|
* Get a token layer by ID.
|
|
1628
1744
|
* @param {string} tokenLayerId - The token layer ID
|
|
1629
|
-
* @param {string} [asOf] - Temporal query timestamp
|
|
1630
1745
|
*/
|
|
1631
|
-
get: (tokenLayerId
|
|
1632
|
-
this._request("GET", `/api/v1/token-layers/${tokenLayerId}
|
|
1633
|
-
queryParams: { "as-of": asOf },
|
|
1634
|
-
}),
|
|
1746
|
+
get: (tokenLayerId) =>
|
|
1747
|
+
this._request("GET", `/api/v1/token-layers/${tokenLayerId}`),
|
|
1635
1748
|
/**
|
|
1636
1749
|
* Delete a token layer.
|
|
1637
1750
|
* @param {string} tokenLayerId - The token layer ID
|
|
@@ -1656,12 +1769,9 @@ class PlaidClient {
|
|
|
1656
1769
|
/**
|
|
1657
1770
|
* Check the lock status of a document.
|
|
1658
1771
|
* @param {string} documentId - The document ID
|
|
1659
|
-
* @param {string} [asOf] - Temporal query timestamp
|
|
1660
1772
|
*/
|
|
1661
|
-
checkLock: (documentId
|
|
1662
|
-
this._request("GET", `/api/v1/documents/${documentId}/lock
|
|
1663
|
-
queryParams: { "as-of": asOf },
|
|
1664
|
-
}),
|
|
1773
|
+
checkLock: (documentId) =>
|
|
1774
|
+
this._request("GET", `/api/v1/documents/${documentId}/lock`),
|
|
1665
1775
|
/**
|
|
1666
1776
|
* Acquire or refresh a document lock.
|
|
1667
1777
|
*
|
|
@@ -1717,8 +1827,8 @@ class PlaidClient {
|
|
|
1717
1827
|
* NOT re-entrant: nesting two `locked()` blocks on one document would
|
|
1718
1828
|
* release on the inner exit and leave the outer unprotected. Lock at
|
|
1719
1829
|
* exactly one level per call path. A lost lock is recorded on the
|
|
1720
|
-
* CLIENT, like
|
|
1721
|
-
*
|
|
1830
|
+
* CLIENT, like strict mode, so it stops every write the client makes
|
|
1831
|
+
* (on any batch of it too) and not only the ones this block makes.
|
|
1722
1832
|
* @param {string} documentId - The document ID
|
|
1723
1833
|
* @param {(lock: DocumentLock) => any} fn - The work to run while holding it
|
|
1724
1834
|
* @param {object} [options] - `{ keepAlive }`: renew on a timer (default true)
|
|
@@ -1775,7 +1885,6 @@ class PlaidClient {
|
|
|
1775
1885
|
this._request("PUT", `/api/v1/documents/${documentId}/metadata`, {
|
|
1776
1886
|
auditMessage,
|
|
1777
1887
|
rawBody: body,
|
|
1778
|
-
skipResponseTransform: true,
|
|
1779
1888
|
}),
|
|
1780
1889
|
/**
|
|
1781
1890
|
* Remove all metadata from a document.
|
|
@@ -1784,18 +1893,16 @@ class PlaidClient {
|
|
|
1784
1893
|
deleteMetadata: (documentId, auditMessage) =>
|
|
1785
1894
|
this._request("DELETE", `/api/v1/documents/${documentId}/metadata`, {
|
|
1786
1895
|
auditMessage,
|
|
1787
|
-
skipResponseTransform: true,
|
|
1788
1896
|
}),
|
|
1789
1897
|
/**
|
|
1790
|
-
*
|
|
1898
|
+
* Edit metadata for a document 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.
|
|
1791
1899
|
* @param {string} documentId - The document ID
|
|
1792
|
-
* @param {any} body - The metadata
|
|
1900
|
+
* @param {Array<{op: string, path: string[], value?: any}>} body - The metadata ops
|
|
1793
1901
|
*/
|
|
1794
1902
|
patchMetadata: (documentId, body, auditMessage) =>
|
|
1795
1903
|
this._request("PATCH", `/api/v1/documents/${documentId}/metadata`, {
|
|
1796
1904
|
auditMessage,
|
|
1797
1905
|
rawBody: body,
|
|
1798
|
-
skipResponseTransform: true,
|
|
1799
1906
|
}),
|
|
1800
1907
|
/**
|
|
1801
1908
|
* Get audit log for a document. Transparently follows pagination cursors
|
|
@@ -1803,18 +1910,16 @@ class PlaidClient {
|
|
|
1803
1910
|
* @param {string} documentId - The document ID
|
|
1804
1911
|
* @param {string} [startTime] - Start of time range
|
|
1805
1912
|
* @param {string} [endTime] - End of time range
|
|
1806
|
-
* @param {string} [asOf] - Temporal query timestamp
|
|
1807
1913
|
* @param {string[]|string} [opTypes] - Only return operations of these
|
|
1808
1914
|
* types, spelled as in an entry's `op/type` (e.g.
|
|
1809
1915
|
* `['span-layer/create', 'span-layer/delete']`). An entry appears when
|
|
1810
1916
|
* one of its operations matches, carrying only the ones that did.
|
|
1811
1917
|
*/
|
|
1812
|
-
audit: (documentId, startTime, endTime,
|
|
1918
|
+
audit: (documentId, startTime, endTime, opTypes) =>
|
|
1813
1919
|
listAll(this, `/api/v1/documents/${documentId}/audit`, {
|
|
1814
1920
|
query: {
|
|
1815
1921
|
"start-time": startTime,
|
|
1816
1922
|
"end-time": endTime,
|
|
1817
|
-
"as-of": asOf,
|
|
1818
1923
|
"op-types": opTypesParam(opTypes),
|
|
1819
1924
|
},
|
|
1820
1925
|
}),
|
|
@@ -1822,6 +1927,7 @@ class PlaidClient {
|
|
|
1822
1927
|
* One page of the same log, newest-first with `order: "desc"`. Use this
|
|
1823
1928
|
* rather than audit() wherever the caller wants the recent end of a log
|
|
1824
1929
|
* that may be long: audit() walks every page before it resolves.
|
|
1930
|
+
* @param {string} documentId - The document ID
|
|
1825
1931
|
* @param {object} [opts]
|
|
1826
1932
|
* @param {"asc"|"desc"} [opts.order] - "desc" pages newest-first
|
|
1827
1933
|
* @param {number} [opts.limit] - Page size (1..1000; server default 100)
|
|
@@ -1830,7 +1936,7 @@ class PlaidClient {
|
|
|
1830
1936
|
*/
|
|
1831
1937
|
auditPage: (
|
|
1832
1938
|
documentId,
|
|
1833
|
-
{ startTime, endTime,
|
|
1939
|
+
{ startTime, endTime, opTypes, order, limit, cursor } = {},
|
|
1834
1940
|
) =>
|
|
1835
1941
|
listPage(this, `/api/v1/documents/${documentId}/audit`, {
|
|
1836
1942
|
limit,
|
|
@@ -1838,7 +1944,6 @@ class PlaidClient {
|
|
|
1838
1944
|
query: {
|
|
1839
1945
|
"start-time": startTime,
|
|
1840
1946
|
"end-time": endTime,
|
|
1841
|
-
"as-of": asOf,
|
|
1842
1947
|
"op-types": opTypesParam(opTypes),
|
|
1843
1948
|
order,
|
|
1844
1949
|
},
|
|
@@ -2026,18 +2131,16 @@ class PlaidClient {
|
|
|
2026
2131
|
* @param {string} projectId - The project ID
|
|
2027
2132
|
* @param {string} [startTime] - Start of time range
|
|
2028
2133
|
* @param {string} [endTime] - End of time range
|
|
2029
|
-
* @param {string} [asOf] - Temporal query timestamp
|
|
2030
2134
|
* @param {string[]|string} [opTypes] - Only return operations of these
|
|
2031
2135
|
* types, spelled as in an entry's `op/type` (e.g.
|
|
2032
2136
|
* `['span-layer/create', 'span-layer/delete']`). An entry appears when
|
|
2033
2137
|
* one of its operations matches, carrying only the ones that did.
|
|
2034
2138
|
*/
|
|
2035
|
-
audit: (projectId, startTime, endTime,
|
|
2139
|
+
audit: (projectId, startTime, endTime, opTypes) =>
|
|
2036
2140
|
listAll(this, `/api/v1/projects/${projectId}/audit`, {
|
|
2037
2141
|
query: {
|
|
2038
2142
|
"start-time": startTime,
|
|
2039
2143
|
"end-time": endTime,
|
|
2040
|
-
"as-of": asOf,
|
|
2041
2144
|
"op-types": opTypesParam(opTypes),
|
|
2042
2145
|
},
|
|
2043
2146
|
}),
|
|
@@ -2045,6 +2148,7 @@ class PlaidClient {
|
|
|
2045
2148
|
* One page of the same log, newest-first with `order: "desc"`. Use this
|
|
2046
2149
|
* rather than audit() wherever the caller wants the recent end of a log
|
|
2047
2150
|
* that may be long: audit() walks every page before it resolves.
|
|
2151
|
+
* @param {string} projectId - The project ID
|
|
2048
2152
|
* @param {object} [opts]
|
|
2049
2153
|
* @param {"asc"|"desc"} [opts.order] - "desc" pages newest-first
|
|
2050
2154
|
* @param {number} [opts.limit] - Page size (1..1000; server default 100)
|
|
@@ -2053,7 +2157,7 @@ class PlaidClient {
|
|
|
2053
2157
|
*/
|
|
2054
2158
|
auditPage: (
|
|
2055
2159
|
projectId,
|
|
2056
|
-
{ startTime, endTime,
|
|
2160
|
+
{ startTime, endTime, opTypes, order, limit, cursor } = {},
|
|
2057
2161
|
) =>
|
|
2058
2162
|
listPage(this, `/api/v1/projects/${projectId}/audit`, {
|
|
2059
2163
|
limit,
|
|
@@ -2061,7 +2165,6 @@ class PlaidClient {
|
|
|
2061
2165
|
query: {
|
|
2062
2166
|
"start-time": startTime,
|
|
2063
2167
|
"end-time": endTime,
|
|
2064
|
-
"as-of": asOf,
|
|
2065
2168
|
"op-types": opTypesParam(opTypes),
|
|
2066
2169
|
order,
|
|
2067
2170
|
},
|
|
@@ -2102,12 +2205,9 @@ class PlaidClient {
|
|
|
2102
2205
|
* Get a project by ID. To fetch the project's documents, use
|
|
2103
2206
|
* listDocuments(id) — the include-documents flag has been removed.
|
|
2104
2207
|
* @param {string} id - The resource ID
|
|
2105
|
-
* @param {string} [asOf] - Temporal query timestamp
|
|
2106
2208
|
*/
|
|
2107
|
-
get: (id
|
|
2108
|
-
this._request("GET", `/api/v1/projects/${id}
|
|
2109
|
-
queryParams: { "as-of": asOf },
|
|
2110
|
-
}),
|
|
2209
|
+
get: (id) =>
|
|
2210
|
+
this._request("GET", `/api/v1/projects/${id}`),
|
|
2111
2211
|
/**
|
|
2112
2212
|
* List all documents in a project. Transparently follows pagination
|
|
2113
2213
|
* cursors and returns the full flat array.
|
|
@@ -2144,17 +2244,15 @@ class PlaidClient {
|
|
|
2144
2244
|
iterDocuments: (id, { pageSize } = {}) =>
|
|
2145
2245
|
iterPages(this, `/api/v1/projects/${id}/documents`, { pageSize }),
|
|
2146
2246
|
/**
|
|
2147
|
-
* Delete a project and everything in it. This is irrecoverable.
|
|
2148
|
-
*
|
|
2149
|
-
*
|
|
2150
|
-
* per-request timeout is DISABLED by default. Pass `{ timeout }` to
|
|
2151
|
-
* impose a finite bound.
|
|
2247
|
+
* Delete a project and everything in it. This is irrecoverable. The
|
|
2248
|
+
* project is gone when this returns, and what it holds is removed on
|
|
2249
|
+
* the server afterwards.
|
|
2152
2250
|
* @param {string} id - The resource ID
|
|
2153
2251
|
* @param {string} [auditMessage] - Custom audit-log message
|
|
2154
2252
|
* @param {object} [options]
|
|
2155
|
-
* @param {number} [options.timeout
|
|
2253
|
+
* @param {number} [options.timeout] - Per-request timeout in ms, the client's own by default (0/null disables)
|
|
2156
2254
|
*/
|
|
2157
|
-
delete: (id, auditMessage, { timeout
|
|
2255
|
+
delete: (id, auditMessage, { timeout } = {}) =>
|
|
2158
2256
|
this._request("DELETE", `/api/v1/projects/${id}`, {
|
|
2159
2257
|
auditMessage,
|
|
2160
2258
|
timeout,
|
|
@@ -2172,35 +2270,29 @@ class PlaidClient {
|
|
|
2172
2270
|
/**
|
|
2173
2271
|
* List all projects accessible to user. Transparently follows pagination
|
|
2174
2272
|
* cursors and returns the full flat array.
|
|
2175
|
-
* @param {string} [asOf] - Temporal query timestamp
|
|
2176
2273
|
*/
|
|
2177
|
-
list: (
|
|
2178
|
-
listAll(this, "/api/v1/projects", { query: { "as-of": asOf } }),
|
|
2274
|
+
list: () => listAll(this, "/api/v1/projects"),
|
|
2179
2275
|
/**
|
|
2180
2276
|
* Fetch a single page of projects.
|
|
2181
2277
|
* @param {object} [opts]
|
|
2182
2278
|
* @param {number} [opts.limit] - Page size (1..1000; server default 100)
|
|
2183
2279
|
* @param {string} [opts.cursor] - Opaque cursor from a previous page
|
|
2184
|
-
* @param {string} [opts.asOf] - Temporal query timestamp
|
|
2185
2280
|
* @returns {Promise<{entries: Array, nextCursor: (string|null)}>}
|
|
2186
2281
|
*/
|
|
2187
|
-
listPage: ({ limit, cursor
|
|
2282
|
+
listPage: ({ limit, cursor } = {}) =>
|
|
2188
2283
|
listPage(this, "/api/v1/projects", {
|
|
2189
2284
|
limit,
|
|
2190
2285
|
cursor,
|
|
2191
|
-
query: { "as-of": asOf },
|
|
2192
2286
|
}),
|
|
2193
2287
|
/**
|
|
2194
2288
|
* Async-iterate projects page by page; yields each page's entries array.
|
|
2195
2289
|
* @param {object} [opts]
|
|
2196
2290
|
* @param {number} [opts.pageSize] - Per-request page size
|
|
2197
|
-
* @param {string} [opts.asOf] - Temporal query timestamp
|
|
2198
2291
|
* @returns {AsyncGenerator<Array>}
|
|
2199
2292
|
*/
|
|
2200
|
-
iterPages: ({ pageSize
|
|
2293
|
+
iterPages: ({ pageSize } = {}) =>
|
|
2201
2294
|
iterPages(this, "/api/v1/projects", {
|
|
2202
2295
|
pageSize,
|
|
2203
|
-
query: { "as-of": asOf },
|
|
2204
2296
|
}),
|
|
2205
2297
|
/**
|
|
2206
2298
|
* Create a new project. Note: this also registers the user as a maintainer.
|
|
@@ -2248,12 +2340,9 @@ class PlaidClient {
|
|
|
2248
2340
|
/**
|
|
2249
2341
|
* Get a text layer by ID.
|
|
2250
2342
|
* @param {string} textLayerId - The text layer ID
|
|
2251
|
-
* @param {string} [asOf] - Temporal query timestamp
|
|
2252
2343
|
*/
|
|
2253
|
-
get: (textLayerId
|
|
2254
|
-
this._request("GET", `/api/v1/text-layers/${textLayerId}
|
|
2255
|
-
queryParams: { "as-of": asOf },
|
|
2256
|
-
}),
|
|
2344
|
+
get: (textLayerId) =>
|
|
2345
|
+
this._request("GET", `/api/v1/text-layers/${textLayerId}`),
|
|
2257
2346
|
/**
|
|
2258
2347
|
* Delete a text layer.
|
|
2259
2348
|
* @param {string} textLayerId - The text layer ID
|
|
@@ -2304,7 +2393,6 @@ class PlaidClient {
|
|
|
2304
2393
|
this._request("PUT", `/api/v1/vocab-items/${id}/metadata`, {
|
|
2305
2394
|
auditMessage,
|
|
2306
2395
|
rawBody: body,
|
|
2307
|
-
skipResponseTransform: true,
|
|
2308
2396
|
}),
|
|
2309
2397
|
/**
|
|
2310
2398
|
* Remove all metadata from a vocab item.
|
|
@@ -2313,18 +2401,16 @@ class PlaidClient {
|
|
|
2313
2401
|
deleteMetadata: (id, auditMessage) =>
|
|
2314
2402
|
this._request("DELETE", `/api/v1/vocab-items/${id}/metadata`, {
|
|
2315
2403
|
auditMessage,
|
|
2316
|
-
skipResponseTransform: true,
|
|
2317
2404
|
}),
|
|
2318
2405
|
/**
|
|
2319
|
-
*
|
|
2406
|
+
* Edit metadata for a vocab item 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.
|
|
2320
2407
|
* @param {string} id - The resource ID
|
|
2321
|
-
* @param {any} body - The metadata
|
|
2408
|
+
* @param {Array<{op: string, path: string[], value?: any}>} body - The metadata ops
|
|
2322
2409
|
*/
|
|
2323
2410
|
patchMetadata: (id, body, auditMessage) =>
|
|
2324
2411
|
this._request("PATCH", `/api/v1/vocab-items/${id}/metadata`, {
|
|
2325
2412
|
auditMessage,
|
|
2326
2413
|
rawBody: body,
|
|
2327
|
-
skipResponseTransform: true,
|
|
2328
2414
|
}),
|
|
2329
2415
|
/**
|
|
2330
2416
|
* Create a new vocab item
|
|
@@ -2350,7 +2436,7 @@ class PlaidClient {
|
|
|
2350
2436
|
/**
|
|
2351
2437
|
* Update many vocab items in a single operation: set forms and/or patch
|
|
2352
2438
|
* metadata.
|
|
2353
|
-
* @param {Array<{id: string, form?: string, metadata?:
|
|
2439
|
+
* @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.
|
|
2354
2440
|
* @returns {Promise<{count: number}>} How many vocab items were updated.
|
|
2355
2441
|
*/
|
|
2356
2442
|
bulkUpdate: (body, auditMessage) =>
|
|
@@ -2374,12 +2460,9 @@ class PlaidClient {
|
|
|
2374
2460
|
/**
|
|
2375
2461
|
* Get a vocab item by ID
|
|
2376
2462
|
* @param {string} id - The resource ID
|
|
2377
|
-
* @param {string} [asOf] - Temporal query timestamp
|
|
2378
2463
|
*/
|
|
2379
|
-
get: (id
|
|
2380
|
-
this._request("GET", `/api/v1/vocab-items/${id}
|
|
2381
|
-
queryParams: { "as-of": asOf },
|
|
2382
|
-
}),
|
|
2464
|
+
get: (id) =>
|
|
2465
|
+
this._request("GET", `/api/v1/vocab-items/${id}`),
|
|
2383
2466
|
/**
|
|
2384
2467
|
* Delete a vocab item, and every link to it. Every document holding one
|
|
2385
2468
|
* of those links has its version bumped, and a strict-mode client picks
|
|
@@ -2459,12 +2542,9 @@ class PlaidClient {
|
|
|
2459
2542
|
/**
|
|
2460
2543
|
* Get a relation layer by ID.
|
|
2461
2544
|
* @param {string} relationLayerId - The relation layer ID
|
|
2462
|
-
* @param {string} [asOf] - Temporal query timestamp
|
|
2463
2545
|
*/
|
|
2464
|
-
get: (relationLayerId
|
|
2465
|
-
this._request("GET", `/api/v1/relation-layers/${relationLayerId}
|
|
2466
|
-
queryParams: { "as-of": asOf },
|
|
2467
|
-
}),
|
|
2546
|
+
get: (relationLayerId) =>
|
|
2547
|
+
this._request("GET", `/api/v1/relation-layers/${relationLayerId}`),
|
|
2468
2548
|
/**
|
|
2469
2549
|
* Delete a relation layer.
|
|
2470
2550
|
* @param {string} relationLayerId - The relation layer ID
|
|
@@ -2527,12 +2607,9 @@ class PlaidClient {
|
|
|
2527
2607
|
/**
|
|
2528
2608
|
* Get a token.
|
|
2529
2609
|
* @param {string} tokenId - The token ID
|
|
2530
|
-
* @param {string} [asOf] - Temporal query timestamp
|
|
2531
2610
|
*/
|
|
2532
|
-
get: (tokenId
|
|
2533
|
-
this._request("GET", `/api/v1/tokens/${tokenId}
|
|
2534
|
-
queryParams: { "as-of": asOf },
|
|
2535
|
-
}),
|
|
2611
|
+
get: (tokenId) =>
|
|
2612
|
+
this._request("GET", `/api/v1/tokens/${tokenId}`),
|
|
2536
2613
|
/**
|
|
2537
2614
|
* Delete a token and remove it from any spans. If this causes a span to
|
|
2538
2615
|
* have no remaining tokens, the span will also be deleted.
|
|
@@ -2570,7 +2647,7 @@ class PlaidClient {
|
|
|
2570
2647
|
this._request("DELETE", "/api/v1/tokens/bulk", { auditMessage, body }),
|
|
2571
2648
|
/**
|
|
2572
2649
|
* Update many tokens in a single operation: patch metadata.
|
|
2573
|
-
* @param {Array} body - Objects of the shape `{id, metadata}`. `metadata` is a
|
|
2650
|
+
* @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.
|
|
2574
2651
|
* @returns {Promise<{count: number}>} How many tokens were updated.
|
|
2575
2652
|
*/
|
|
2576
2653
|
bulkUpdate: (body, auditMessage) =>
|
|
@@ -2624,7 +2701,6 @@ class PlaidClient {
|
|
|
2624
2701
|
this._request("PUT", `/api/v1/tokens/${tokenId}/metadata`, {
|
|
2625
2702
|
auditMessage,
|
|
2626
2703
|
rawBody: body,
|
|
2627
|
-
skipResponseTransform: true,
|
|
2628
2704
|
}),
|
|
2629
2705
|
/**
|
|
2630
2706
|
* Remove all metadata from a token.
|
|
@@ -2633,18 +2709,16 @@ class PlaidClient {
|
|
|
2633
2709
|
deleteMetadata: (tokenId, auditMessage) =>
|
|
2634
2710
|
this._request("DELETE", `/api/v1/tokens/${tokenId}/metadata`, {
|
|
2635
2711
|
auditMessage,
|
|
2636
|
-
skipResponseTransform: true,
|
|
2637
2712
|
}),
|
|
2638
2713
|
/**
|
|
2639
|
-
*
|
|
2714
|
+
* Edit metadata for a token 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.
|
|
2640
2715
|
* @param {string} tokenId - The token ID
|
|
2641
|
-
* @param {any} body - The metadata
|
|
2716
|
+
* @param {Array<{op: string, path: string[], value?: any}>} body - The metadata ops
|
|
2642
2717
|
*/
|
|
2643
2718
|
patchMetadata: (tokenId, body, auditMessage) =>
|
|
2644
2719
|
this._request("PATCH", `/api/v1/tokens/${tokenId}/metadata`, {
|
|
2645
2720
|
auditMessage,
|
|
2646
2721
|
rawBody: body,
|
|
2647
|
-
skipResponseTransform: true,
|
|
2648
2722
|
}),
|
|
2649
2723
|
};
|
|
2650
2724
|
|
|
@@ -2668,13 +2742,17 @@ class PlaidClient {
|
|
|
2668
2742
|
* this a key such as `case-marker` would reach listeners as
|
|
2669
2743
|
* `caseMarker` in JS and `case_marker` in Python. `listen` restores it
|
|
2670
2744
|
* verbatim on the way in.
|
|
2745
|
+
*
|
|
2746
|
+
* A message is not saved and writes nothing to History, so it never
|
|
2747
|
+
* joins an open operation (`withOperation`). Made on a batch it still
|
|
2748
|
+
* queues, so a message queued after the writes goes out after them.
|
|
2671
2749
|
* @param {string} projectId - The UUID of the project to send to
|
|
2672
2750
|
* @param {any} data - The message data to send
|
|
2673
2751
|
* @returns {Promise<any>} Response from the send operation
|
|
2674
2752
|
*/
|
|
2675
|
-
sendMessage: (projectId, data
|
|
2753
|
+
sendMessage: (projectId, data) =>
|
|
2676
2754
|
this._request("POST", `/api/v1/projects/${projectId}/message`, {
|
|
2677
|
-
|
|
2755
|
+
noOperation: true,
|
|
2678
2756
|
rawBody: { body: data },
|
|
2679
2757
|
}),
|
|
2680
2758
|
|
|
@@ -2707,7 +2785,9 @@ class PlaidClient {
|
|
|
2707
2785
|
* @param {function} onServiceRequest - Callback (data, responseHelper)
|
|
2708
2786
|
* @param {Object} [extras] - Optional additional service metadata
|
|
2709
2787
|
* @param {function} [onStatus] - Optional callback (event, projectId, detail) for
|
|
2710
|
-
* connection transitions: 'registered', 'reconnected', 'disconnected'
|
|
2788
|
+
* connection transitions: 'registered', 'reconnected', 'disconnected',
|
|
2789
|
+
* and 'stopped' when the server refuses the channel for good, which
|
|
2790
|
+
* ends the registration
|
|
2711
2791
|
* @returns {Object} Service registration with .stop(), .isRunning(), .isConnected()
|
|
2712
2792
|
*/
|
|
2713
2793
|
serve: (projectId, serviceInfo, onServiceRequest, extras, onStatus) =>
|
|
@@ -2729,7 +2809,7 @@ class PlaidClient {
|
|
|
2729
2809
|
* @param {number} [timeout=10000] - Timeout in ms
|
|
2730
2810
|
* @param {function} [onProgress] - Called with each progress payload {percent, message}
|
|
2731
2811
|
* @param {AbortSignal} [signal] - Abort to stop waiting; rejects with an AbortError
|
|
2732
|
-
* @param {Object} [opts] - {requestId, onAccepted}
|
|
2812
|
+
* @param {Object} [opts] - {requestId, onAccepted, projectIds}
|
|
2733
2813
|
* @returns {Promise<any>} The service's result
|
|
2734
2814
|
*/
|
|
2735
2815
|
requestService: (
|
|
@@ -2827,18 +2907,15 @@ class PlaidClient {
|
|
|
2827
2907
|
* @param {Object} body - The query AST ({find, where, scope?, limit?, orderBy?,
|
|
2828
2908
|
* return?, bindings?}).
|
|
2829
2909
|
* @returns {Promise<Object>} For 'ids'/'entities': {columns, results, count, truncated}.
|
|
2830
|
-
* For 'count': {return: 'count', count}
|
|
2831
|
-
*
|
|
2910
|
+
* For 'count': {return: 'count', count, truncated}, where `truncated` says
|
|
2911
|
+
* the count stopped at the server's cap. Entity cells are full entity
|
|
2912
|
+
* objects (same shape as the GET endpoints).
|
|
2832
2913
|
*/
|
|
2833
2914
|
// outOfBand: a query is a read that travels as a POST (see the note at
|
|
2834
2915
|
// the top of http.js). Made on a batch it goes over the wire like any
|
|
2835
2916
|
// read, and it never joins a logical operation.
|
|
2836
|
-
this.query = (body
|
|
2837
|
-
this._request("POST", "/api/v1/query", {
|
|
2838
|
-
auditMessage,
|
|
2839
|
-
body,
|
|
2840
|
-
outOfBand: true,
|
|
2841
|
-
});
|
|
2917
|
+
this.query = (body) =>
|
|
2918
|
+
this._request("POST", "/api/v1/query", { body, outOfBand: true });
|
|
2842
2919
|
|
|
2843
2920
|
// Logical-operation groups (audit-log grouping). There is no create: a
|
|
2844
2921
|
// group row is made lazily by the first write carrying `?group-id=`
|
|
@@ -3015,6 +3092,20 @@ class PlaidClient {
|
|
|
3015
3092
|
cursor,
|
|
3016
3093
|
query: { "entity-id": entityId },
|
|
3017
3094
|
}),
|
|
3095
|
+
/**
|
|
3096
|
+
* Async-iterate a vocabulary's comments page by page, oldest first;
|
|
3097
|
+
* yields each page's entries array.
|
|
3098
|
+
* @param {string} vocabId - The vocab layer to read
|
|
3099
|
+
* @param {object} [opts]
|
|
3100
|
+
* @param {string} [opts.entityId] - One entry's thread
|
|
3101
|
+
* @param {number} [opts.pageSize] - Per-request page size
|
|
3102
|
+
* @returns {AsyncGenerator<Array>}
|
|
3103
|
+
*/
|
|
3104
|
+
iterInVocabPages: (vocabId, { entityId, pageSize } = {}) =>
|
|
3105
|
+
iterPages(this, `/api/v1/vocab-layers/${vocabId}/comments`, {
|
|
3106
|
+
pageSize,
|
|
3107
|
+
query: { "entity-id": entityId },
|
|
3108
|
+
}),
|
|
3018
3109
|
/**
|
|
3019
3110
|
* Comment counts per entry of a vocabulary, as an `{entityId: n}` map.
|
|
3020
3111
|
* The response is NOT key-transformed: its keys are entry ids.
|
|
@@ -3177,8 +3268,8 @@ class PlaidClient {
|
|
|
3177
3268
|
* "Every write" is the writes of project data. Reads never join, and neither
|
|
3178
3269
|
* do the out-of-band signals shaped like a write (a document lock taken or
|
|
3179
3270
|
* renewed, a stopped service request, a service reporting itself, an admin
|
|
3180
|
-
* control)
|
|
3181
|
-
* label.
|
|
3271
|
+
* control), and neither does a broadcast message (`messages.sendMessage`):
|
|
3272
|
+
* none of them is audited, so there would be nothing under the label.
|
|
3182
3273
|
*
|
|
3183
3274
|
* @param {string} message - Human label for the operation.
|
|
3184
3275
|
* @param {object} [opts] - Optional `{ id }`: adopt an existing group id instead of minting one (a service joining the requester's operation; `requestService` propagates an open operation to the service automatically).
|
|
@@ -3259,7 +3350,10 @@ class PlaidClient {
|
|
|
3259
3350
|
* Open a batch: a view of this client with the same bundles, on which every
|
|
3260
3351
|
* write of project data queues instead of going out. `submit()` sends the
|
|
3261
3352
|
* queued operations as ONE atomic request (larger than the server's cap,
|
|
3262
|
-
* as consecutive requests with the results concatenated in queue order
|
|
3353
|
+
* as consecutive requests with the results concatenated in queue order,
|
|
3354
|
+
* each atomic on its own, so a failure in a later one leaves the earlier
|
|
3355
|
+
* ones committed, and the error it throws carries `committed`, the count
|
|
3356
|
+
* saved, and `committedResults`, their results) and
|
|
3263
3357
|
* resolves to one result per operation; `abort()` drops them. A call made
|
|
3264
3358
|
* on the client itself is never touched by an open batch, and a read or an
|
|
3265
3359
|
* out-of-band signal made on the batch goes over the wire now (see the note
|
|
@@ -3280,7 +3374,11 @@ class PlaidClient {
|
|
|
3280
3374
|
return openBatch(this);
|
|
3281
3375
|
}
|
|
3282
3376
|
|
|
3283
|
-
/**
|
|
3377
|
+
/**
|
|
3378
|
+
* POST one batch request (at most MAX_BATCH_OPS operations). Resolves to
|
|
3379
|
+
* one `{ status, headers, body }` per operation, with only the body
|
|
3380
|
+
* recased: the headers keep the server's spelling.
|
|
3381
|
+
*/
|
|
3284
3382
|
async _postBatch(url, body) {
|
|
3285
3383
|
const fetchOptions = {
|
|
3286
3384
|
method: "POST",
|
|
@@ -3305,6 +3403,22 @@ class PlaidClient {
|
|
|
3305
3403
|
throw makeHttpError(res, await parseErrorBody(res), url, "POST");
|
|
3306
3404
|
}
|
|
3307
3405
|
return res;
|
|
3406
|
+
}).catch((error) => {
|
|
3407
|
+
// 401 means the token is missing, expired or invalid: fire the app's
|
|
3408
|
+
// auth-error handler once, exactly as makeRequest does.
|
|
3409
|
+
if (
|
|
3410
|
+
error?.status === 401 &&
|
|
3411
|
+
typeof this.onAuthError === "function" &&
|
|
3412
|
+
!this._authErrorFired
|
|
3413
|
+
) {
|
|
3414
|
+
this._authErrorFired = true;
|
|
3415
|
+
try {
|
|
3416
|
+
this.onAuthError(error);
|
|
3417
|
+
} catch (_) {
|
|
3418
|
+
/* handler must not mask the original error */
|
|
3419
|
+
}
|
|
3420
|
+
}
|
|
3421
|
+
throw error;
|
|
3308
3422
|
});
|
|
3309
3423
|
|
|
3310
3424
|
const results = await response.json();
|
|
@@ -3332,7 +3446,10 @@ class PlaidClient {
|
|
|
3332
3446
|
}
|
|
3333
3447
|
}
|
|
3334
3448
|
|
|
3335
|
-
return results.map((result) =>
|
|
3449
|
+
return results.map((result) => ({
|
|
3450
|
+
...result,
|
|
3451
|
+
body: transformResponse(result.body),
|
|
3452
|
+
}));
|
|
3336
3453
|
} catch (error) {
|
|
3337
3454
|
if (error.status) throw error;
|
|
3338
3455
|
throw makeNetworkError(error, url, "POST");
|
|
@@ -3340,8 +3457,9 @@ class PlaidClient {
|
|
|
3340
3457
|
}
|
|
3341
3458
|
|
|
3342
3459
|
/**
|
|
3343
|
-
* Run `fn` with a batch, then submit all queued ops as
|
|
3344
|
-
*
|
|
3460
|
+
* Run `fn` with a batch, then submit all queued ops as `submit()` does (ONE
|
|
3461
|
+
* atomic request up to MAX_BATCH_OPS operations, consecutive requests past
|
|
3462
|
+
* it), or abort the batch if `fn` throws. `fn` receives the batch and makes its
|
|
3345
3463
|
* writes on it; it must NOT call `submit()` itself. Resolves to the batch
|
|
3346
3464
|
* results array (`[]` if `fn` queued nothing).
|
|
3347
3465
|
*
|
|
@@ -3366,15 +3484,6 @@ class PlaidClient {
|
|
|
3366
3484
|
return batch.submit();
|
|
3367
3485
|
}
|
|
3368
3486
|
|
|
3369
|
-
/**
|
|
3370
|
-
* Authenticate and return a new client instance with token. This is the
|
|
3371
|
-
* single auth entry point — there is no `client.login` resource.
|
|
3372
|
-
* @param {string} baseUrl - The base URL for the API
|
|
3373
|
-
* @param {string} userId - User ID for authentication
|
|
3374
|
-
* @param {string} password - Password for authentication
|
|
3375
|
-
* @param {object} [options] - Client options forwarded to the constructor (e.g. { timeout })
|
|
3376
|
-
* @returns {Promise<PlaidClient>} - Authenticated client instance
|
|
3377
|
-
*/
|
|
3378
3487
|
/**
|
|
3379
3488
|
* Liveness, version and database size, with NO authentication and no client
|
|
3380
3489
|
* instance — for a launcher or status page checking whether a server is up
|
|
@@ -3469,6 +3578,15 @@ class PlaidClient {
|
|
|
3469
3578
|
};
|
|
3470
3579
|
}
|
|
3471
3580
|
|
|
3581
|
+
/**
|
|
3582
|
+
* Authenticate and return a new client instance with token. This is the
|
|
3583
|
+
* single auth entry point — there is no `client.login` resource.
|
|
3584
|
+
* @param {string} baseUrl - The base URL for the API
|
|
3585
|
+
* @param {string} userId - User ID for authentication
|
|
3586
|
+
* @param {string} password - Password for authentication
|
|
3587
|
+
* @param {object} [options] - Client options forwarded to the constructor (e.g. { timeout })
|
|
3588
|
+
* @returns {Promise<PlaidClient>} - Authenticated client instance
|
|
3589
|
+
*/
|
|
3472
3590
|
static async login(baseUrl, userId, password, options = {}) {
|
|
3473
3591
|
baseUrl = baseUrl.replace(/\/$/, "");
|
|
3474
3592
|
const url = `${baseUrl}/api/v1/login`;
|
|
@@ -3568,7 +3686,6 @@ export {
|
|
|
3568
3686
|
needsReview,
|
|
3569
3687
|
verifyOnEdit,
|
|
3570
3688
|
contributeOnEdit,
|
|
3571
|
-
mergeMetadata,
|
|
3572
3689
|
serviceSource,
|
|
3573
3690
|
userSource,
|
|
3574
3691
|
REVIEW_KEY,
|
|
@@ -3579,4 +3696,15 @@ export {
|
|
|
3579
3696
|
withReviewedUser,
|
|
3580
3697
|
writerPolicy,
|
|
3581
3698
|
} from "./provenance.js";
|
|
3699
|
+
// Metadata ops: the body of a metadata PATCH and of a bulk update entry's
|
|
3700
|
+
// `metadata`. See ./metadataOps.js.
|
|
3701
|
+
export {
|
|
3702
|
+
metadataOps,
|
|
3703
|
+
applyMetadataOps,
|
|
3704
|
+
mergeMetadata,
|
|
3705
|
+
isReservedMetadataKey,
|
|
3706
|
+
} from "./metadataOps.js";
|
|
3707
|
+
// The ids a create or bulk create answered with, off the call or its batch
|
|
3708
|
+
// result. See ./created.js.
|
|
3709
|
+
export { createdId, createdIds } from "./created.js";
|
|
3582
3710
|
export { MAX_BATCH_OPS };
|