@larc-iu/plaid-client 0.2.0-alpha.3 → 0.2.0-alpha.5
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 +542 -105
- package/package.json +1 -1
- package/src/http.js +70 -5
- package/src/index.js +920 -341
- package/src/provenance.js +11 -0
- package/src/serviceSchema.js +49 -31
- package/src/services.js +60 -8
- package/src/sse.js +31 -0
package/src/index.js
CHANGED
|
@@ -2,26 +2,33 @@
|
|
|
2
2
|
* plaid-client - JavaScript client for the Plaid annotation API
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { transformRequest, transformResponse } from
|
|
5
|
+
import { transformRequest, transformResponse } from "./transforms.js";
|
|
6
6
|
import {
|
|
7
|
-
makeRequest,
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
makeRequest,
|
|
8
|
+
extractDocumentVersions,
|
|
9
|
+
parseErrorBody,
|
|
10
|
+
makeHttpError,
|
|
11
|
+
makeNetworkError,
|
|
12
|
+
timeoutSignal,
|
|
13
|
+
retryWhileBusy,
|
|
14
|
+
DEFAULT_TIMEOUT_MS,
|
|
15
|
+
DEFAULT_BATCH_TIMEOUT_MS,
|
|
16
|
+
} from "./http.js";
|
|
17
|
+
import { listAll, listPage, iterPages } from "./pagination.js";
|
|
18
|
+
import { createSSEConnection } from "./sse.js";
|
|
12
19
|
import {
|
|
13
20
|
discoverServices,
|
|
14
21
|
discardService,
|
|
15
22
|
serve,
|
|
16
23
|
requestService,
|
|
17
|
-
} from
|
|
24
|
+
} from "./services.js";
|
|
18
25
|
|
|
19
26
|
// Helper: normalize a document-read `layers` filter to the wire's
|
|
20
27
|
// comma-separated form. Accepts an array of layer ids or a ready-made string;
|
|
21
28
|
// anything empty becomes undefined so no `?layers=` is sent at all.
|
|
22
29
|
function layersParam(layers) {
|
|
23
30
|
if (layers === undefined || layers === null) return undefined;
|
|
24
|
-
const joined = Array.isArray(layers) ? layers.join(
|
|
31
|
+
const joined = Array.isArray(layers) ? layers.join(",") : String(layers);
|
|
25
32
|
return joined.length > 0 ? joined : undefined;
|
|
26
33
|
}
|
|
27
34
|
|
|
@@ -30,7 +37,7 @@ function layersParam(layers) {
|
|
|
30
37
|
// becomes undefined so no `?op-types=` is sent at all.
|
|
31
38
|
function opTypesParam(opTypes) {
|
|
32
39
|
if (opTypes === undefined || opTypes === null) return undefined;
|
|
33
|
-
const joined = Array.isArray(opTypes) ? opTypes.join(
|
|
40
|
+
const joined = Array.isArray(opTypes) ? opTypes.join(",") : String(opTypes);
|
|
34
41
|
return joined.length > 0 ? joined : undefined;
|
|
35
42
|
}
|
|
36
43
|
|
|
@@ -47,25 +54,32 @@ function bodyOf(obj) {
|
|
|
47
54
|
// and redemption). Deliberately does not go through PlaidClient._request: these
|
|
48
55
|
// are called before any client exists, which is the whole point.
|
|
49
56
|
async function anonymousPost(baseUrl, path, body, options = {}) {
|
|
50
|
-
const base = baseUrl.replace(/\/$/,
|
|
57
|
+
const base = baseUrl.replace(/\/$/, "");
|
|
51
58
|
const url = `${base}${path}`;
|
|
52
59
|
try {
|
|
53
60
|
const fetchOptions = {
|
|
54
|
-
method:
|
|
55
|
-
headers: {
|
|
61
|
+
method: "POST",
|
|
62
|
+
headers: { "Content-Type": "application/json" },
|
|
56
63
|
body: JSON.stringify(body),
|
|
57
64
|
};
|
|
58
|
-
const signal = timeoutSignal(
|
|
65
|
+
const signal = timeoutSignal(
|
|
66
|
+
options.timeout !== undefined ? options.timeout : DEFAULT_TIMEOUT_MS,
|
|
67
|
+
);
|
|
59
68
|
if (signal) fetchOptions.signal = signal;
|
|
60
69
|
|
|
61
70
|
const response = await fetch(url, fetchOptions);
|
|
62
71
|
if (!response.ok) {
|
|
63
|
-
throw makeHttpError(
|
|
72
|
+
throw makeHttpError(
|
|
73
|
+
response,
|
|
74
|
+
await parseErrorBody(response),
|
|
75
|
+
url,
|
|
76
|
+
"POST",
|
|
77
|
+
);
|
|
64
78
|
}
|
|
65
79
|
return transformResponse(await response.json());
|
|
66
80
|
} catch (error) {
|
|
67
81
|
if (error.status) throw error;
|
|
68
|
-
throw makeNetworkError(error, url,
|
|
82
|
+
throw makeNetworkError(error, url, "POST");
|
|
69
83
|
}
|
|
70
84
|
}
|
|
71
85
|
|
|
@@ -76,11 +90,24 @@ class PlaidClient {
|
|
|
76
90
|
* @param {string} token - The authentication token
|
|
77
91
|
* @param {object} [options] - Client options
|
|
78
92
|
* @param {number} [options.timeout=30000] - Per-request timeout in ms (0 or null disables it)
|
|
93
|
+
* @param {number} [options.batchTimeout=180000] - Timeout for batch submissions in ms (0 or null disables it)
|
|
79
94
|
*/
|
|
80
95
|
constructor(baseUrl, token, options = {}) {
|
|
81
|
-
this.baseUrl = baseUrl.replace(/\/$/,
|
|
96
|
+
this.baseUrl = baseUrl.replace(/\/$/, "");
|
|
82
97
|
this.token = token;
|
|
83
|
-
this.timeout =
|
|
98
|
+
this.timeout =
|
|
99
|
+
options.timeout !== undefined ? options.timeout : DEFAULT_TIMEOUT_MS;
|
|
100
|
+
// Batch submissions get a longer budget than a single request. Aborting a
|
|
101
|
+
// batch does NOT stop the server: it keeps running the transaction and
|
|
102
|
+
// holding the single SQLite write lock, so a client that gives up early
|
|
103
|
+
// just adds a retry on top of a write that is still in progress. Falls
|
|
104
|
+
// back to an explicit `timeout` when one was given.
|
|
105
|
+
this.batchTimeout =
|
|
106
|
+
options.batchTimeout !== undefined
|
|
107
|
+
? options.batchTimeout
|
|
108
|
+
: options.timeout !== undefined
|
|
109
|
+
? options.timeout
|
|
110
|
+
: DEFAULT_BATCH_TIMEOUT_MS;
|
|
84
111
|
this.isBatching = false;
|
|
85
112
|
this.batchOperations = [];
|
|
86
113
|
this.documentVersions = {};
|
|
@@ -106,8 +133,9 @@ class PlaidClient {
|
|
|
106
133
|
* @param {any} [metadata] - Metadata for the link. Omit to leave unset; pass null to send JSON null.
|
|
107
134
|
*/
|
|
108
135
|
create: (vocabItem, tokens, metadata, auditMessage) =>
|
|
109
|
-
this._request(
|
|
110
|
-
|
|
136
|
+
this._request("POST", "/api/v1/vocab-links", {
|
|
137
|
+
auditMessage,
|
|
138
|
+
body: bodyOf({ "vocab-item": vocabItem, tokens, metadata }),
|
|
111
139
|
}),
|
|
112
140
|
/**
|
|
113
141
|
* Create multiple vocab links in a single operation. Entries may
|
|
@@ -117,28 +145,37 @@ class PlaidClient {
|
|
|
117
145
|
* @returns {Promise<{ids: string[]}>} The created entity IDs, in input order. (bulkDelete resolves to no value.)
|
|
118
146
|
*/
|
|
119
147
|
bulkCreate: (body, auditMessage) =>
|
|
120
|
-
this._request(
|
|
148
|
+
this._request("POST", "/api/v1/vocab-links/bulk", {
|
|
149
|
+
auditMessage,
|
|
150
|
+
body,
|
|
151
|
+
}),
|
|
121
152
|
/**
|
|
122
153
|
* Delete multiple vocab links in a single operation. Provide an array of IDs.
|
|
123
154
|
* @param {string[]} body - The vocab link IDs to delete
|
|
124
155
|
*/
|
|
125
156
|
bulkDelete: (body, auditMessage) =>
|
|
126
|
-
this._request(
|
|
157
|
+
this._request("DELETE", "/api/v1/vocab-links/bulk", {
|
|
158
|
+
auditMessage,
|
|
159
|
+
body,
|
|
160
|
+
}),
|
|
127
161
|
/**
|
|
128
162
|
* Replace all metadata for a vocab link. The entire metadata map is replaced - existing metadata keys not included in the request will be removed.
|
|
129
163
|
* @param {string} id - The resource ID
|
|
130
164
|
* @param {any} body - The request body
|
|
131
165
|
*/
|
|
132
166
|
setMetadata: (id, body, auditMessage) =>
|
|
133
|
-
this._request(
|
|
134
|
-
|
|
167
|
+
this._request("PUT", `/api/v1/vocab-links/${id}/metadata`, {
|
|
168
|
+
auditMessage,
|
|
169
|
+
rawBody: body,
|
|
170
|
+
skipResponseTransform: true,
|
|
135
171
|
}),
|
|
136
172
|
/**
|
|
137
173
|
* Remove all metadata from a vocab link.
|
|
138
174
|
* @param {string} id - The resource ID
|
|
139
175
|
*/
|
|
140
176
|
deleteMetadata: (id, auditMessage) =>
|
|
141
|
-
this._request(
|
|
177
|
+
this._request("DELETE", `/api/v1/vocab-links/${id}/metadata`, {
|
|
178
|
+
auditMessage,
|
|
142
179
|
skipResponseTransform: true,
|
|
143
180
|
}),
|
|
144
181
|
/**
|
|
@@ -147,8 +184,10 @@ class PlaidClient {
|
|
|
147
184
|
* @param {any} body - The metadata patch
|
|
148
185
|
*/
|
|
149
186
|
patchMetadata: (id, body, auditMessage) =>
|
|
150
|
-
this._request(
|
|
151
|
-
|
|
187
|
+
this._request("PATCH", `/api/v1/vocab-links/${id}/metadata`, {
|
|
188
|
+
auditMessage,
|
|
189
|
+
rawBody: body,
|
|
190
|
+
skipResponseTransform: true,
|
|
152
191
|
}),
|
|
153
192
|
/**
|
|
154
193
|
* Get a vocab link by ID
|
|
@@ -156,15 +195,15 @@ class PlaidClient {
|
|
|
156
195
|
* @param {string} [asOf] - Temporal query timestamp
|
|
157
196
|
*/
|
|
158
197
|
get: (id, asOf) =>
|
|
159
|
-
this._request(
|
|
160
|
-
queryParams: {
|
|
198
|
+
this._request("GET", `/api/v1/vocab-links/${id}`, {
|
|
199
|
+
queryParams: { "as-of": asOf },
|
|
161
200
|
}),
|
|
162
201
|
/**
|
|
163
202
|
* Delete a vocab link
|
|
164
203
|
* @param {string} id - The resource ID
|
|
165
204
|
*/
|
|
166
205
|
delete: (id, auditMessage) =>
|
|
167
|
-
this._request(
|
|
206
|
+
this._request("DELETE", `/api/v1/vocab-links/${id}`, { auditMessage }),
|
|
168
207
|
};
|
|
169
208
|
|
|
170
209
|
this.vocabLayers = {
|
|
@@ -175,22 +214,23 @@ class PlaidClient {
|
|
|
175
214
|
* @param {string} [asOf] - Temporal query timestamp
|
|
176
215
|
*/
|
|
177
216
|
get: (id, includeItems, asOf) =>
|
|
178
|
-
this._request(
|
|
179
|
-
queryParams: {
|
|
217
|
+
this._request("GET", `/api/v1/vocab-layers/${id}`, {
|
|
218
|
+
queryParams: { "include-items": includeItems, "as-of": asOf },
|
|
180
219
|
}),
|
|
181
220
|
/**
|
|
182
221
|
* Delete a vocab layer.
|
|
183
222
|
* @param {string} id - The resource ID
|
|
184
223
|
*/
|
|
185
224
|
delete: (id, auditMessage) =>
|
|
186
|
-
this._request(
|
|
225
|
+
this._request("DELETE", `/api/v1/vocab-layers/${id}`, { auditMessage }),
|
|
187
226
|
/**
|
|
188
227
|
* Update a vocab layer's name.
|
|
189
228
|
* @param {string} id - The resource ID
|
|
190
229
|
* @param {string} name - The name
|
|
191
230
|
*/
|
|
192
231
|
update: (id, name, auditMessage) =>
|
|
193
|
-
this._request(
|
|
232
|
+
this._request("PATCH", `/api/v1/vocab-layers/${id}`, {
|
|
233
|
+
auditMessage,
|
|
194
234
|
body: bodyOf({ name }),
|
|
195
235
|
}),
|
|
196
236
|
/**
|
|
@@ -201,9 +241,11 @@ class PlaidClient {
|
|
|
201
241
|
* @param {any} configValue - Configuration value to set
|
|
202
242
|
*/
|
|
203
243
|
setConfig: (id, namespace, configKey, configValue, auditMessage) =>
|
|
204
|
-
this._request(
|
|
205
|
-
|
|
206
|
-
|
|
244
|
+
this._request(
|
|
245
|
+
"PUT",
|
|
246
|
+
`/api/v1/vocab-layers/${id}/config/${namespace}/${configKey}`,
|
|
247
|
+
{ auditMessage, rawBody: configValue, skipResponseTransform: true },
|
|
248
|
+
),
|
|
207
249
|
/**
|
|
208
250
|
* Remove a configuration value for a layer.
|
|
209
251
|
* @param {string} id - The resource ID
|
|
@@ -211,9 +253,11 @@ class PlaidClient {
|
|
|
211
253
|
* @param {string} configKey - The config key
|
|
212
254
|
*/
|
|
213
255
|
deleteConfig: (id, namespace, configKey, auditMessage) =>
|
|
214
|
-
this._request(
|
|
215
|
-
|
|
216
|
-
|
|
256
|
+
this._request(
|
|
257
|
+
"DELETE",
|
|
258
|
+
`/api/v1/vocab-layers/${id}/config/${namespace}/${configKey}`,
|
|
259
|
+
{ auditMessage, skipResponseTransform: true },
|
|
260
|
+
),
|
|
217
261
|
/**
|
|
218
262
|
* List all vocab layers accessible to user. Transparently follows
|
|
219
263
|
* pagination cursors and returns the full flat array.
|
|
@@ -221,7 +265,7 @@ class PlaidClient {
|
|
|
221
265
|
* @param {string} [asOf] - Temporal query timestamp
|
|
222
266
|
*/
|
|
223
267
|
list: (asOf) =>
|
|
224
|
-
listAll(this,
|
|
268
|
+
listAll(this, "/api/v1/vocab-layers", { query: { "as-of": asOf } }),
|
|
225
269
|
/**
|
|
226
270
|
* Fetch a single page of vocab layers.
|
|
227
271
|
* @param {object} [opts]
|
|
@@ -231,7 +275,11 @@ class PlaidClient {
|
|
|
231
275
|
* @returns {Promise<{entries: Array, nextCursor: (string|null)}>}
|
|
232
276
|
*/
|
|
233
277
|
listPage: ({ limit, cursor, asOf } = {}) =>
|
|
234
|
-
listPage(this,
|
|
278
|
+
listPage(this, "/api/v1/vocab-layers", {
|
|
279
|
+
limit,
|
|
280
|
+
cursor,
|
|
281
|
+
query: { "as-of": asOf },
|
|
282
|
+
}),
|
|
235
283
|
/**
|
|
236
284
|
* Async-iterate vocab layers page by page; yields each page's entries array.
|
|
237
285
|
* @param {object} [opts]
|
|
@@ -241,13 +289,17 @@ class PlaidClient {
|
|
|
241
289
|
* @returns {AsyncGenerator<Array>}
|
|
242
290
|
*/
|
|
243
291
|
iterPages: ({ pageSize, asOf } = {}) =>
|
|
244
|
-
iterPages(this,
|
|
292
|
+
iterPages(this, "/api/v1/vocab-layers", {
|
|
293
|
+
pageSize,
|
|
294
|
+
query: { "as-of": asOf },
|
|
295
|
+
}),
|
|
245
296
|
/**
|
|
246
297
|
* Create a new vocab layer. Note: this also registers the user as a maintainer.
|
|
247
298
|
* @param {string} name - The name
|
|
248
299
|
*/
|
|
249
300
|
create: (name, auditMessage) =>
|
|
250
|
-
this._request(
|
|
301
|
+
this._request("POST", "/api/v1/vocab-layers", {
|
|
302
|
+
auditMessage,
|
|
251
303
|
body: bodyOf({ name }),
|
|
252
304
|
}),
|
|
253
305
|
/**
|
|
@@ -256,14 +308,22 @@ class PlaidClient {
|
|
|
256
308
|
* @param {string} userId - The user ID
|
|
257
309
|
*/
|
|
258
310
|
addMaintainer: (id, userId, auditMessage) =>
|
|
259
|
-
this._request(
|
|
311
|
+
this._request(
|
|
312
|
+
"POST",
|
|
313
|
+
`/api/v1/vocab-layers/${id}/maintainers/${userId}`,
|
|
314
|
+
{ auditMessage },
|
|
315
|
+
),
|
|
260
316
|
/**
|
|
261
317
|
* Remove a user's maintainer privileges for this vocab layer.
|
|
262
318
|
* @param {string} id - The resource ID
|
|
263
319
|
* @param {string} userId - The user ID
|
|
264
320
|
*/
|
|
265
321
|
removeMaintainer: (id, userId, auditMessage) =>
|
|
266
|
-
this._request(
|
|
322
|
+
this._request(
|
|
323
|
+
"DELETE",
|
|
324
|
+
`/api/v1/vocab-layers/${id}/maintainers/${userId}`,
|
|
325
|
+
{ auditMessage },
|
|
326
|
+
),
|
|
267
327
|
};
|
|
268
328
|
|
|
269
329
|
this.relations = {
|
|
@@ -273,15 +333,18 @@ class PlaidClient {
|
|
|
273
333
|
* @param {any} body - The request body
|
|
274
334
|
*/
|
|
275
335
|
setMetadata: (relationId, body, auditMessage) =>
|
|
276
|
-
this._request(
|
|
277
|
-
|
|
336
|
+
this._request("PUT", `/api/v1/relations/${relationId}/metadata`, {
|
|
337
|
+
auditMessage,
|
|
338
|
+
rawBody: body,
|
|
339
|
+
skipResponseTransform: true,
|
|
278
340
|
}),
|
|
279
341
|
/**
|
|
280
342
|
* Remove all metadata from a relation.
|
|
281
343
|
* @param {string} relationId - The relation ID
|
|
282
344
|
*/
|
|
283
345
|
deleteMetadata: (relationId, auditMessage) =>
|
|
284
|
-
this._request(
|
|
346
|
+
this._request("DELETE", `/api/v1/relations/${relationId}/metadata`, {
|
|
347
|
+
auditMessage,
|
|
285
348
|
skipResponseTransform: true,
|
|
286
349
|
}),
|
|
287
350
|
/**
|
|
@@ -290,8 +353,10 @@ class PlaidClient {
|
|
|
290
353
|
* @param {any} body - The metadata patch
|
|
291
354
|
*/
|
|
292
355
|
patchMetadata: (relationId, body, auditMessage) =>
|
|
293
|
-
this._request(
|
|
294
|
-
|
|
356
|
+
this._request("PATCH", `/api/v1/relations/${relationId}/metadata`, {
|
|
357
|
+
auditMessage,
|
|
358
|
+
rawBody: body,
|
|
359
|
+
skipResponseTransform: true,
|
|
295
360
|
}),
|
|
296
361
|
/**
|
|
297
362
|
* Update the target span of a relation.
|
|
@@ -299,8 +364,9 @@ class PlaidClient {
|
|
|
299
364
|
* @param {string} spanId - The span ID
|
|
300
365
|
*/
|
|
301
366
|
setTarget: (relationId, spanId, auditMessage) =>
|
|
302
|
-
this._request(
|
|
303
|
-
|
|
367
|
+
this._request("PUT", `/api/v1/relations/${relationId}/target`, {
|
|
368
|
+
auditMessage,
|
|
369
|
+
body: bodyOf({ "span-id": spanId }),
|
|
304
370
|
}),
|
|
305
371
|
/**
|
|
306
372
|
* Get a relation by ID.
|
|
@@ -308,22 +374,25 @@ class PlaidClient {
|
|
|
308
374
|
* @param {string} [asOf] - Temporal query timestamp
|
|
309
375
|
*/
|
|
310
376
|
get: (relationId, asOf) =>
|
|
311
|
-
this._request(
|
|
312
|
-
queryParams: {
|
|
377
|
+
this._request("GET", `/api/v1/relations/${relationId}`, {
|
|
378
|
+
queryParams: { "as-of": asOf },
|
|
313
379
|
}),
|
|
314
380
|
/**
|
|
315
381
|
* Delete a relation.
|
|
316
382
|
* @param {string} relationId - The relation ID
|
|
317
383
|
*/
|
|
318
384
|
delete: (relationId, auditMessage) =>
|
|
319
|
-
this._request(
|
|
385
|
+
this._request("DELETE", `/api/v1/relations/${relationId}`, {
|
|
386
|
+
auditMessage,
|
|
387
|
+
}),
|
|
320
388
|
/**
|
|
321
389
|
* Update a relation's value.
|
|
322
390
|
* @param {string} relationId - The relation ID
|
|
323
391
|
* @param {any} value - The value
|
|
324
392
|
*/
|
|
325
393
|
update: (relationId, value, auditMessage) =>
|
|
326
|
-
this._request(
|
|
394
|
+
this._request("PATCH", `/api/v1/relations/${relationId}`, {
|
|
395
|
+
auditMessage,
|
|
327
396
|
body: bodyOf({ value }),
|
|
328
397
|
}),
|
|
329
398
|
/**
|
|
@@ -332,8 +401,9 @@ class PlaidClient {
|
|
|
332
401
|
* @param {string} spanId - The span ID
|
|
333
402
|
*/
|
|
334
403
|
setSource: (relationId, spanId, auditMessage) =>
|
|
335
|
-
this._request(
|
|
336
|
-
|
|
404
|
+
this._request("PUT", `/api/v1/relations/${relationId}/source`, {
|
|
405
|
+
auditMessage,
|
|
406
|
+
body: bodyOf({ "span-id": spanId }),
|
|
337
407
|
}),
|
|
338
408
|
/**
|
|
339
409
|
* Create a new relation. A relation is a directed edge between two spans
|
|
@@ -346,8 +416,15 @@ class PlaidClient {
|
|
|
346
416
|
* @param {any} [metadata] - Metadata map. Omit to leave unset; pass null to send JSON null.
|
|
347
417
|
*/
|
|
348
418
|
create: (layerId, sourceId, targetId, value, metadata, auditMessage) =>
|
|
349
|
-
this._request(
|
|
350
|
-
|
|
419
|
+
this._request("POST", "/api/v1/relations", {
|
|
420
|
+
auditMessage,
|
|
421
|
+
body: bodyOf({
|
|
422
|
+
"layer-id": layerId,
|
|
423
|
+
"source-id": sourceId,
|
|
424
|
+
"target-id": targetId,
|
|
425
|
+
value,
|
|
426
|
+
metadata,
|
|
427
|
+
}),
|
|
351
428
|
}),
|
|
352
429
|
/**
|
|
353
430
|
* Create multiple relations in a single operation.
|
|
@@ -355,13 +432,16 @@ class PlaidClient {
|
|
|
355
432
|
* @returns {Promise<{ids: string[]}>} The created entity IDs, in input order. (bulkDelete resolves to no value.)
|
|
356
433
|
*/
|
|
357
434
|
bulkCreate: (body, auditMessage) =>
|
|
358
|
-
this._request(
|
|
435
|
+
this._request("POST", "/api/v1/relations/bulk", { auditMessage, body }),
|
|
359
436
|
/**
|
|
360
437
|
* Delete multiple relations in a single operation. Provide an array of IDs.
|
|
361
438
|
* @param {Array} body - The request body
|
|
362
439
|
*/
|
|
363
440
|
bulkDelete: (body, auditMessage) =>
|
|
364
|
-
this._request(
|
|
441
|
+
this._request("DELETE", "/api/v1/relations/bulk", {
|
|
442
|
+
auditMessage,
|
|
443
|
+
body,
|
|
444
|
+
}),
|
|
365
445
|
};
|
|
366
446
|
|
|
367
447
|
this.spanLayers = {
|
|
@@ -372,10 +452,18 @@ class PlaidClient {
|
|
|
372
452
|
* @param {string} configKey - The config key
|
|
373
453
|
* @param {any} configValue - Configuration value to set
|
|
374
454
|
*/
|
|
375
|
-
setConfig: (
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
455
|
+
setConfig: (
|
|
456
|
+
spanLayerId,
|
|
457
|
+
namespace,
|
|
458
|
+
configKey,
|
|
459
|
+
configValue,
|
|
460
|
+
auditMessage,
|
|
461
|
+
) =>
|
|
462
|
+
this._request(
|
|
463
|
+
"PUT",
|
|
464
|
+
`/api/v1/span-layers/${spanLayerId}/config/${namespace}/${configKey}`,
|
|
465
|
+
{ auditMessage, rawBody: configValue, skipResponseTransform: true },
|
|
466
|
+
),
|
|
379
467
|
/**
|
|
380
468
|
* Remove a configuration value for a layer.
|
|
381
469
|
* @param {string} spanLayerId - The span layer ID
|
|
@@ -383,31 +471,36 @@ class PlaidClient {
|
|
|
383
471
|
* @param {string} configKey - The config key
|
|
384
472
|
*/
|
|
385
473
|
deleteConfig: (spanLayerId, namespace, configKey, auditMessage) =>
|
|
386
|
-
this._request(
|
|
387
|
-
|
|
388
|
-
|
|
474
|
+
this._request(
|
|
475
|
+
"DELETE",
|
|
476
|
+
`/api/v1/span-layers/${spanLayerId}/config/${namespace}/${configKey}`,
|
|
477
|
+
{ auditMessage, skipResponseTransform: true },
|
|
478
|
+
),
|
|
389
479
|
/**
|
|
390
480
|
* Get a span layer by ID.
|
|
391
481
|
* @param {string} spanLayerId - The span layer ID
|
|
392
482
|
* @param {string} [asOf] - Temporal query timestamp
|
|
393
483
|
*/
|
|
394
484
|
get: (spanLayerId, asOf) =>
|
|
395
|
-
this._request(
|
|
396
|
-
queryParams: {
|
|
485
|
+
this._request("GET", `/api/v1/span-layers/${spanLayerId}`, {
|
|
486
|
+
queryParams: { "as-of": asOf },
|
|
397
487
|
}),
|
|
398
488
|
/**
|
|
399
489
|
* Delete a span layer.
|
|
400
490
|
* @param {string} spanLayerId - The span layer ID
|
|
401
491
|
*/
|
|
402
492
|
delete: (spanLayerId, auditMessage) =>
|
|
403
|
-
this._request(
|
|
493
|
+
this._request("DELETE", `/api/v1/span-layers/${spanLayerId}`, {
|
|
494
|
+
auditMessage,
|
|
495
|
+
}),
|
|
404
496
|
/**
|
|
405
497
|
* Update a span layer's name.
|
|
406
498
|
* @param {string} spanLayerId - The span layer ID
|
|
407
499
|
* @param {string} name - The name
|
|
408
500
|
*/
|
|
409
501
|
update: (spanLayerId, name, auditMessage) =>
|
|
410
|
-
this._request(
|
|
502
|
+
this._request("PATCH", `/api/v1/span-layers/${spanLayerId}`, {
|
|
503
|
+
auditMessage,
|
|
411
504
|
body: bodyOf({ name }),
|
|
412
505
|
}),
|
|
413
506
|
/**
|
|
@@ -416,8 +509,9 @@ class PlaidClient {
|
|
|
416
509
|
* @param {string} name - The name
|
|
417
510
|
*/
|
|
418
511
|
create: (tokenLayerId, name, auditMessage) =>
|
|
419
|
-
this._request(
|
|
420
|
-
|
|
512
|
+
this._request("POST", "/api/v1/span-layers", {
|
|
513
|
+
auditMessage,
|
|
514
|
+
body: bodyOf({ "token-layer-id": tokenLayerId, name }),
|
|
421
515
|
}),
|
|
422
516
|
/**
|
|
423
517
|
* Shift a span layer's display order.
|
|
@@ -425,7 +519,8 @@ class PlaidClient {
|
|
|
425
519
|
* @param {string} direction - The direction ("up" or "down")
|
|
426
520
|
*/
|
|
427
521
|
shift: (spanLayerId, direction, auditMessage) =>
|
|
428
|
-
this._request(
|
|
522
|
+
this._request("POST", `/api/v1/span-layers/${spanLayerId}/shift`, {
|
|
523
|
+
auditMessage,
|
|
429
524
|
body: bodyOf({ direction }),
|
|
430
525
|
}),
|
|
431
526
|
};
|
|
@@ -437,7 +532,8 @@ class PlaidClient {
|
|
|
437
532
|
* @param {Array} tokens - The tokens
|
|
438
533
|
*/
|
|
439
534
|
setTokens: (spanId, tokens, auditMessage) =>
|
|
440
|
-
this._request(
|
|
535
|
+
this._request("PUT", `/api/v1/spans/${spanId}/tokens`, {
|
|
536
|
+
auditMessage,
|
|
441
537
|
body: bodyOf({ tokens }),
|
|
442
538
|
}),
|
|
443
539
|
/**
|
|
@@ -449,8 +545,14 @@ class PlaidClient {
|
|
|
449
545
|
* @param {any} [metadata] - Metadata map. Omit to leave unset; pass null to send JSON null.
|
|
450
546
|
*/
|
|
451
547
|
create: (spanLayerId, tokens, value, metadata, auditMessage) =>
|
|
452
|
-
this._request(
|
|
453
|
-
|
|
548
|
+
this._request("POST", "/api/v1/spans", {
|
|
549
|
+
auditMessage,
|
|
550
|
+
body: bodyOf({
|
|
551
|
+
"span-layer-id": spanLayerId,
|
|
552
|
+
tokens,
|
|
553
|
+
value,
|
|
554
|
+
metadata,
|
|
555
|
+
}),
|
|
454
556
|
}),
|
|
455
557
|
/**
|
|
456
558
|
* Get a span by ID.
|
|
@@ -458,22 +560,23 @@ class PlaidClient {
|
|
|
458
560
|
* @param {string} [asOf] - Temporal query timestamp
|
|
459
561
|
*/
|
|
460
562
|
get: (spanId, asOf) =>
|
|
461
|
-
this._request(
|
|
462
|
-
queryParams: {
|
|
563
|
+
this._request("GET", `/api/v1/spans/${spanId}`, {
|
|
564
|
+
queryParams: { "as-of": asOf },
|
|
463
565
|
}),
|
|
464
566
|
/**
|
|
465
567
|
* Delete a span.
|
|
466
568
|
* @param {string} spanId - The span ID
|
|
467
569
|
*/
|
|
468
570
|
delete: (spanId, auditMessage) =>
|
|
469
|
-
this._request(
|
|
571
|
+
this._request("DELETE", `/api/v1/spans/${spanId}`, { auditMessage }),
|
|
470
572
|
/**
|
|
471
573
|
* Update a span's value.
|
|
472
574
|
* @param {string} spanId - The span ID
|
|
473
575
|
* @param {any} value - The value
|
|
474
576
|
*/
|
|
475
577
|
update: (spanId, value, auditMessage) =>
|
|
476
|
-
this._request(
|
|
578
|
+
this._request("PATCH", `/api/v1/spans/${spanId}`, {
|
|
579
|
+
auditMessage,
|
|
477
580
|
body: bodyOf({ value }),
|
|
478
581
|
}),
|
|
479
582
|
/**
|
|
@@ -482,28 +585,31 @@ class PlaidClient {
|
|
|
482
585
|
* @returns {Promise<{ids: string[]}>} The created entity IDs, in input order. (bulkDelete resolves to no value.)
|
|
483
586
|
*/
|
|
484
587
|
bulkCreate: (body, auditMessage) =>
|
|
485
|
-
this._request(
|
|
588
|
+
this._request("POST", "/api/v1/spans/bulk", { auditMessage, body }),
|
|
486
589
|
/**
|
|
487
590
|
* Delete multiple spans in a single operation. Provide an array of IDs.
|
|
488
591
|
* @param {Array} body - The request body
|
|
489
592
|
*/
|
|
490
593
|
bulkDelete: (body, auditMessage) =>
|
|
491
|
-
this._request(
|
|
594
|
+
this._request("DELETE", "/api/v1/spans/bulk", { auditMessage, body }),
|
|
492
595
|
/**
|
|
493
596
|
* Replace all metadata for a span.
|
|
494
597
|
* @param {string} spanId - The span ID
|
|
495
598
|
* @param {any} body - The request body
|
|
496
599
|
*/
|
|
497
600
|
setMetadata: (spanId, body, auditMessage) =>
|
|
498
|
-
this._request(
|
|
499
|
-
|
|
601
|
+
this._request("PUT", `/api/v1/spans/${spanId}/metadata`, {
|
|
602
|
+
auditMessage,
|
|
603
|
+
rawBody: body,
|
|
604
|
+
skipResponseTransform: true,
|
|
500
605
|
}),
|
|
501
606
|
/**
|
|
502
607
|
* Remove all metadata from a span.
|
|
503
608
|
* @param {string} spanId - The span ID
|
|
504
609
|
*/
|
|
505
610
|
deleteMetadata: (spanId, auditMessage) =>
|
|
506
|
-
this._request(
|
|
611
|
+
this._request("DELETE", `/api/v1/spans/${spanId}/metadata`, {
|
|
612
|
+
auditMessage,
|
|
507
613
|
skipResponseTransform: true,
|
|
508
614
|
}),
|
|
509
615
|
/**
|
|
@@ -512,8 +618,10 @@ class PlaidClient {
|
|
|
512
618
|
* @param {any} body - The metadata patch
|
|
513
619
|
*/
|
|
514
620
|
patchMetadata: (spanId, body, auditMessage) =>
|
|
515
|
-
this._request(
|
|
516
|
-
|
|
621
|
+
this._request("PATCH", `/api/v1/spans/${spanId}/metadata`, {
|
|
622
|
+
auditMessage,
|
|
623
|
+
rawBody: body,
|
|
624
|
+
skipResponseTransform: true,
|
|
517
625
|
}),
|
|
518
626
|
};
|
|
519
627
|
|
|
@@ -524,8 +632,10 @@ class PlaidClient {
|
|
|
524
632
|
* @param {Array} body - The request body
|
|
525
633
|
*/
|
|
526
634
|
submit: (body, auditMessage) =>
|
|
527
|
-
this._request(
|
|
528
|
-
|
|
635
|
+
this._request("POST", "/api/v1/batch", {
|
|
636
|
+
auditMessage,
|
|
637
|
+
body,
|
|
638
|
+
noBatch: true,
|
|
529
639
|
}),
|
|
530
640
|
};
|
|
531
641
|
|
|
@@ -536,15 +646,18 @@ class PlaidClient {
|
|
|
536
646
|
* @param {any} body - The request body
|
|
537
647
|
*/
|
|
538
648
|
setMetadata: (textId, body, auditMessage) =>
|
|
539
|
-
this._request(
|
|
540
|
-
|
|
649
|
+
this._request("PUT", `/api/v1/texts/${textId}/metadata`, {
|
|
650
|
+
auditMessage,
|
|
651
|
+
rawBody: body,
|
|
652
|
+
skipResponseTransform: true,
|
|
541
653
|
}),
|
|
542
654
|
/**
|
|
543
655
|
* Remove all metadata from a text.
|
|
544
656
|
* @param {string} textId - The text ID
|
|
545
657
|
*/
|
|
546
658
|
deleteMetadata: (textId, auditMessage) =>
|
|
547
|
-
this._request(
|
|
659
|
+
this._request("DELETE", `/api/v1/texts/${textId}/metadata`, {
|
|
660
|
+
auditMessage,
|
|
548
661
|
skipResponseTransform: true,
|
|
549
662
|
}),
|
|
550
663
|
/**
|
|
@@ -553,8 +666,10 @@ class PlaidClient {
|
|
|
553
666
|
* @param {any} body - The metadata patch
|
|
554
667
|
*/
|
|
555
668
|
patchMetadata: (textId, body, auditMessage) =>
|
|
556
|
-
this._request(
|
|
557
|
-
|
|
669
|
+
this._request("PATCH", `/api/v1/texts/${textId}/metadata`, {
|
|
670
|
+
auditMessage,
|
|
671
|
+
rawBody: body,
|
|
672
|
+
skipResponseTransform: true,
|
|
558
673
|
}),
|
|
559
674
|
/**
|
|
560
675
|
* Create a new text in a document's text layer. A text is a container for
|
|
@@ -565,8 +680,14 @@ class PlaidClient {
|
|
|
565
680
|
* @param {any} [metadata] - Metadata map. Omit to leave unset; pass null to send JSON null.
|
|
566
681
|
*/
|
|
567
682
|
create: (textLayerId, documentId, body, metadata, auditMessage) =>
|
|
568
|
-
this._request(
|
|
569
|
-
|
|
683
|
+
this._request("POST", "/api/v1/texts", {
|
|
684
|
+
auditMessage,
|
|
685
|
+
body: bodyOf({
|
|
686
|
+
"text-layer-id": textLayerId,
|
|
687
|
+
"document-id": documentId,
|
|
688
|
+
body,
|
|
689
|
+
metadata,
|
|
690
|
+
}),
|
|
570
691
|
}),
|
|
571
692
|
/**
|
|
572
693
|
* Get a text.
|
|
@@ -574,24 +695,30 @@ class PlaidClient {
|
|
|
574
695
|
* @param {string} [asOf] - Temporal query timestamp
|
|
575
696
|
*/
|
|
576
697
|
get: (textId, asOf) =>
|
|
577
|
-
this._request(
|
|
578
|
-
queryParams: {
|
|
698
|
+
this._request("GET", `/api/v1/texts/${textId}`, {
|
|
699
|
+
queryParams: { "as-of": asOf },
|
|
579
700
|
}),
|
|
580
701
|
/**
|
|
581
702
|
* Delete a text and all dependent data.
|
|
582
703
|
* @param {string} textId - The text ID
|
|
583
704
|
*/
|
|
584
705
|
delete: (textId, auditMessage) =>
|
|
585
|
-
this._request(
|
|
706
|
+
this._request("DELETE", `/api/v1/texts/${textId}`, { auditMessage }),
|
|
586
707
|
/**
|
|
587
708
|
* Update a text's body. A diff is computed and token indices are updated
|
|
588
709
|
* so that tokens remain intact. Alternatively, `body` can be a list of
|
|
589
|
-
* edit directives
|
|
710
|
+
* edit directives (code-point indices, applied in order):
|
|
711
|
+
* {type: 'delete', index, value: count}
|
|
712
|
+
* {type: 'insert', index, value: string}
|
|
713
|
+
* {type: 'replace', index, length, value: string} — unlike
|
|
714
|
+
* delete+insert, a token covering the whole range is resized to keep
|
|
715
|
+
* it (respell a word in place without losing its annotations).
|
|
590
716
|
* @param {string} textId - The text ID
|
|
591
717
|
* @param {any} body - The request body
|
|
592
718
|
*/
|
|
593
719
|
update: (textId, body, auditMessage) =>
|
|
594
|
-
this._request(
|
|
720
|
+
this._request("PATCH", `/api/v1/texts/${textId}`, {
|
|
721
|
+
auditMessage,
|
|
595
722
|
body: bodyOf({ body }),
|
|
596
723
|
}),
|
|
597
724
|
};
|
|
@@ -602,42 +729,58 @@ class PlaidClient {
|
|
|
602
729
|
* returns the full flat array. Admin-or-maintainer only.
|
|
603
730
|
* Cannot be used inside a batch (auto-paginates across requests); throws if called while batching — use listPage() for a single page in a batch.
|
|
604
731
|
* @param {object} [opts]
|
|
605
|
-
* @param {string} [opts.q] - Filter to
|
|
732
|
+
* @param {string} [opts.q] - Filter to users whose display name or email contains this text (case-insensitive)
|
|
606
733
|
* @param {string} [opts.asOf] - Temporal query timestamp
|
|
607
734
|
*/
|
|
608
735
|
list: ({ q, asOf } = {}) =>
|
|
609
|
-
listAll(this,
|
|
736
|
+
listAll(this, "/api/v1/users", { query: { q, "as-of": asOf } }),
|
|
610
737
|
/**
|
|
611
738
|
* Fetch a single page of users (optionally filtered by `q`).
|
|
612
739
|
* @param {object} [opts]
|
|
613
|
-
* @param {string} [opts.q] - Filter to
|
|
740
|
+
* @param {string} [opts.q] - Filter to users whose display name or email contains this text (case-insensitive)
|
|
614
741
|
* @param {number} [opts.limit] - Page size (1..1000; server default 100)
|
|
615
742
|
* @param {string} [opts.cursor] - Opaque cursor from a previous page
|
|
616
743
|
* @param {string} [opts.asOf] - Temporal query timestamp
|
|
617
744
|
* @returns {Promise<{entries: Array, nextCursor: (string|null)}>}
|
|
618
745
|
*/
|
|
619
746
|
listPage: ({ q, limit, cursor, asOf } = {}) =>
|
|
620
|
-
listPage(this,
|
|
747
|
+
listPage(this, "/api/v1/users", {
|
|
748
|
+
limit,
|
|
749
|
+
cursor,
|
|
750
|
+
query: { q, "as-of": asOf },
|
|
751
|
+
}),
|
|
621
752
|
/**
|
|
622
753
|
* Async-iterate users page by page; yields each page's entries array.
|
|
623
754
|
* @param {object} [opts]
|
|
624
|
-
* @param {string} [opts.q] - Filter to
|
|
755
|
+
* @param {string} [opts.q] - Filter to users whose display name or email contains this text (case-insensitive)
|
|
625
756
|
* @param {number} [opts.pageSize] - Per-request page size
|
|
626
757
|
* @param {string} [opts.asOf] - Temporal query timestamp
|
|
627
758
|
* Cannot be used inside a batch (auto-paginates across requests); throws on first iteration if called while batching — use listPage() for a single page in a batch.
|
|
628
759
|
* @returns {AsyncGenerator<Array>}
|
|
629
760
|
*/
|
|
630
761
|
iterPages: ({ q, pageSize, asOf } = {}) =>
|
|
631
|
-
iterPages(this,
|
|
762
|
+
iterPages(this, "/api/v1/users", {
|
|
763
|
+
pageSize,
|
|
764
|
+
query: { q, "as-of": asOf },
|
|
765
|
+
}),
|
|
632
766
|
/**
|
|
633
|
-
* Create a new user
|
|
634
|
-
* @param {string}
|
|
767
|
+
* Create a new user.
|
|
768
|
+
* @param {string} email - The account's email address. It becomes the
|
|
769
|
+
* user's id and is what they log in with; it can never be changed.
|
|
635
770
|
* @param {string} password - The password
|
|
636
771
|
* @param {boolean} isAdmin - Whether the user is an admin
|
|
772
|
+
* @param {string} [displayName] - How the user is shown in the UI.
|
|
773
|
+
* Defaults to the local part of the email.
|
|
637
774
|
*/
|
|
638
|
-
create: (
|
|
639
|
-
this._request(
|
|
640
|
-
|
|
775
|
+
create: (email, password, isAdmin, displayName, auditMessage) =>
|
|
776
|
+
this._request("POST", "/api/v1/users", {
|
|
777
|
+
auditMessage,
|
|
778
|
+
body: bodyOf({
|
|
779
|
+
email,
|
|
780
|
+
password,
|
|
781
|
+
"is-admin": isAdmin,
|
|
782
|
+
"display-name": displayName,
|
|
783
|
+
}),
|
|
641
784
|
}),
|
|
642
785
|
/**
|
|
643
786
|
* Get audit log for a user's actions. Transparently follows pagination
|
|
@@ -655,10 +798,10 @@ class PlaidClient {
|
|
|
655
798
|
audit: (userId, startTime, endTime, asOf, opTypes) =>
|
|
656
799
|
listAll(this, `/api/v1/users/${userId}/audit`, {
|
|
657
800
|
query: {
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
801
|
+
"start-time": startTime,
|
|
802
|
+
"end-time": endTime,
|
|
803
|
+
"as-of": asOf,
|
|
804
|
+
"op-types": opTypesParam(opTypes),
|
|
662
805
|
},
|
|
663
806
|
}),
|
|
664
807
|
/**
|
|
@@ -667,8 +810,8 @@ class PlaidClient {
|
|
|
667
810
|
* @param {string} [asOf] - Temporal query timestamp
|
|
668
811
|
*/
|
|
669
812
|
get: (id, asOf) =>
|
|
670
|
-
this._request(
|
|
671
|
-
queryParams: {
|
|
813
|
+
this._request("GET", `/api/v1/users/${id}`, {
|
|
814
|
+
queryParams: { "as-of": asOf },
|
|
672
815
|
}),
|
|
673
816
|
/**
|
|
674
817
|
* Deactivate a user. Users are never hard-deleted: deactivation
|
|
@@ -679,7 +822,7 @@ class PlaidClient {
|
|
|
679
822
|
* @param {string} id - The resource ID
|
|
680
823
|
*/
|
|
681
824
|
delete: (id, auditMessage) =>
|
|
682
|
-
this._request(
|
|
825
|
+
this._request("DELETE", `/api/v1/users/${id}`, { auditMessage }),
|
|
683
826
|
/**
|
|
684
827
|
* Reactivate a deactivated user, restoring their ability to log in.
|
|
685
828
|
* Project memberships, vocab maintainerships, and API tokens removed
|
|
@@ -687,19 +830,27 @@ class PlaidClient {
|
|
|
687
830
|
* @param {string} id - The resource ID
|
|
688
831
|
*/
|
|
689
832
|
activate: (id, auditMessage) =>
|
|
690
|
-
this._request(
|
|
833
|
+
this._request("POST", `/api/v1/users/${id}/activate`, { auditMessage }),
|
|
691
834
|
/**
|
|
692
|
-
* Modify a user. Admins may change the
|
|
693
|
-
* status of any user. All other users may only modify their own
|
|
694
|
-
* or password.
|
|
695
|
-
*
|
|
835
|
+
* Modify a user. Admins may change the display name, password, and admin
|
|
836
|
+
* status of any user. All other users may only modify their own display
|
|
837
|
+
* name or password.
|
|
838
|
+
*
|
|
839
|
+
* A user's id is their email address and is fixed for the life of the
|
|
840
|
+
* account — it is what they log in with, so nothing can change it.
|
|
841
|
+
* @param {string} id - The resource ID (the user's email address)
|
|
696
842
|
* @param {string} [password] - New password
|
|
697
|
-
* @param {string} [
|
|
843
|
+
* @param {string} [displayName] - New display name
|
|
698
844
|
* @param {boolean} [isAdmin] - New admin status
|
|
699
845
|
*/
|
|
700
|
-
update: (id, password,
|
|
701
|
-
this._request(
|
|
702
|
-
|
|
846
|
+
update: (id, password, displayName, isAdmin, auditMessage) =>
|
|
847
|
+
this._request("PATCH", `/api/v1/users/${id}`, {
|
|
848
|
+
auditMessage,
|
|
849
|
+
body: bodyOf({
|
|
850
|
+
password,
|
|
851
|
+
"display-name": displayName,
|
|
852
|
+
"is-admin": isAdmin,
|
|
853
|
+
}),
|
|
703
854
|
}),
|
|
704
855
|
/**
|
|
705
856
|
* Build a URL for a user's profile picture, suitable for use directly as
|
|
@@ -719,7 +870,7 @@ class PlaidClient {
|
|
|
719
870
|
avatarUrl: (id, avatarHash) => {
|
|
720
871
|
if (avatarHash === null) return null;
|
|
721
872
|
const params = new URLSearchParams({ token: this.token });
|
|
722
|
-
if (avatarHash) params.set(
|
|
873
|
+
if (avatarHash) params.set("v", avatarHash);
|
|
723
874
|
return `${this.baseUrl}/api/v1/users/${id}/avatar?${params}`;
|
|
724
875
|
},
|
|
725
876
|
/**
|
|
@@ -728,7 +879,7 @@ class PlaidClient {
|
|
|
728
879
|
* @param {string} id - The user ID
|
|
729
880
|
*/
|
|
730
881
|
getAvatar: (id) =>
|
|
731
|
-
this._request(
|
|
882
|
+
this._request("GET", `/api/v1/users/${id}/avatar`, {
|
|
732
883
|
noBatch: true,
|
|
733
884
|
binaryResponse: true,
|
|
734
885
|
}),
|
|
@@ -742,9 +893,12 @@ class PlaidClient {
|
|
|
742
893
|
*/
|
|
743
894
|
setAvatar: (id, file, auditMessage) => {
|
|
744
895
|
const fd = new FormData();
|
|
745
|
-
fd.append(
|
|
746
|
-
return this._request(
|
|
747
|
-
|
|
896
|
+
fd.append("file", file);
|
|
897
|
+
return this._request("PUT", `/api/v1/users/${id}/avatar`, {
|
|
898
|
+
auditMessage,
|
|
899
|
+
body: fd,
|
|
900
|
+
formData: true,
|
|
901
|
+
noBatch: true,
|
|
748
902
|
});
|
|
749
903
|
},
|
|
750
904
|
/**
|
|
@@ -752,11 +906,72 @@ class PlaidClient {
|
|
|
752
906
|
* @param {string} id - The user ID
|
|
753
907
|
*/
|
|
754
908
|
deleteAvatar: (id, auditMessage) =>
|
|
755
|
-
this._request(
|
|
909
|
+
this._request("DELETE", `/api/v1/users/${id}/avatar`, {
|
|
910
|
+
auditMessage,
|
|
756
911
|
noBatch: true,
|
|
757
912
|
}),
|
|
758
913
|
};
|
|
759
914
|
|
|
915
|
+
this.userData = {
|
|
916
|
+
/**
|
|
917
|
+
* List a user's private data entries ({key, updatedAt}, plus value when
|
|
918
|
+
* includeValues). Owner or admin only.
|
|
919
|
+
* @param {string} userId
|
|
920
|
+
* @param {object} [opts]
|
|
921
|
+
* @param {string} [opts.prefix] - Only keys starting with this prefix
|
|
922
|
+
* @param {boolean} [opts.includeValues] - Also return each entry's value
|
|
923
|
+
*/
|
|
924
|
+
list: (userId, { prefix, includeValues } = {}) =>
|
|
925
|
+
this._request("GET", `/api/v1/users/${userId}/data`, {
|
|
926
|
+
queryParams: { prefix, "include-values": includeValues },
|
|
927
|
+
}),
|
|
928
|
+
/**
|
|
929
|
+
* Read one private data entry ({key, updatedAt, value}); 404 if absent.
|
|
930
|
+
* @param {string} userId
|
|
931
|
+
* @param {string} key
|
|
932
|
+
*/
|
|
933
|
+
get: (userId, key) =>
|
|
934
|
+
this._request(
|
|
935
|
+
"GET",
|
|
936
|
+
`/api/v1/users/${userId}/data/${encodeURIComponent(key)}`,
|
|
937
|
+
),
|
|
938
|
+
/**
|
|
939
|
+
* Create or replace one private data entry. `value` is any JSON (up to
|
|
940
|
+
* 1 MB), stored as sent. Not audited, not batchable.
|
|
941
|
+
*
|
|
942
|
+
* The server stores it verbatim, but this client recases object keys on
|
|
943
|
+
* the way out and back like any other body (`myKey` <-> `my-key`), so a
|
|
944
|
+
* value whose keys are camelCase round-trips unchanged while one keyed
|
|
945
|
+
* by arbitrary strings does not. Put such a map under a `metadata` key,
|
|
946
|
+
* which both clients pass through untouched.
|
|
947
|
+
* @param {string} userId
|
|
948
|
+
* @param {string} key
|
|
949
|
+
* @param {*} value
|
|
950
|
+
*/
|
|
951
|
+
put: (userId, key, value) =>
|
|
952
|
+
this._request(
|
|
953
|
+
"PUT",
|
|
954
|
+
`/api/v1/users/${userId}/data/${encodeURIComponent(key)}`,
|
|
955
|
+
{
|
|
956
|
+
body: value,
|
|
957
|
+
noBatch: true,
|
|
958
|
+
},
|
|
959
|
+
),
|
|
960
|
+
/**
|
|
961
|
+
* Delete one private data entry; 404 if absent.
|
|
962
|
+
* @param {string} userId
|
|
963
|
+
* @param {string} key
|
|
964
|
+
*/
|
|
965
|
+
delete: (userId, key) =>
|
|
966
|
+
this._request(
|
|
967
|
+
"DELETE",
|
|
968
|
+
`/api/v1/users/${userId}/data/${encodeURIComponent(key)}`,
|
|
969
|
+
{
|
|
970
|
+
noBatch: true,
|
|
971
|
+
},
|
|
972
|
+
),
|
|
973
|
+
};
|
|
974
|
+
|
|
760
975
|
this.apiTokens = {
|
|
761
976
|
/**
|
|
762
977
|
* List a user's named API tokens. Never includes the signed token
|
|
@@ -765,8 +980,7 @@ class PlaidClient {
|
|
|
765
980
|
* Cannot be used inside a batch (auto-paginates across requests); throws if called while batching — use listPage() for a single page in a batch.
|
|
766
981
|
* @param {string} userId - The user ID who owns the tokens
|
|
767
982
|
*/
|
|
768
|
-
list: (userId) =>
|
|
769
|
-
listAll(this, `/api/v1/users/${userId}/tokens`),
|
|
983
|
+
list: (userId) => listAll(this, `/api/v1/users/${userId}/tokens`),
|
|
770
984
|
/**
|
|
771
985
|
* Fetch a single page of a user's named API tokens.
|
|
772
986
|
* @param {string} userId - The user ID who owns the tokens
|
|
@@ -797,7 +1011,8 @@ class PlaidClient {
|
|
|
797
1011
|
* @returns {Promise<{id: string, name: string, token: string}>}
|
|
798
1012
|
*/
|
|
799
1013
|
create: (userId, name, auditMessage) =>
|
|
800
|
-
this._request(
|
|
1014
|
+
this._request("POST", `/api/v1/users/${userId}/tokens`, {
|
|
1015
|
+
auditMessage,
|
|
801
1016
|
body: bodyOf({ name }),
|
|
802
1017
|
}),
|
|
803
1018
|
/**
|
|
@@ -806,7 +1021,9 @@ class PlaidClient {
|
|
|
806
1021
|
* @param {string} tokenId - The token ID to revoke
|
|
807
1022
|
*/
|
|
808
1023
|
revoke: (userId, tokenId, auditMessage) =>
|
|
809
|
-
this._request(
|
|
1024
|
+
this._request("DELETE", `/api/v1/users/${userId}/tokens/${tokenId}`, {
|
|
1025
|
+
auditMessage,
|
|
1026
|
+
}),
|
|
810
1027
|
};
|
|
811
1028
|
|
|
812
1029
|
this.invites = {
|
|
@@ -821,7 +1038,9 @@ class PlaidClient {
|
|
|
821
1038
|
* @param {string} [opts.projectId] - List this project's invites instead of your own
|
|
822
1039
|
*/
|
|
823
1040
|
list: ({ projectId } = {}) =>
|
|
824
|
-
listAll(this,
|
|
1041
|
+
listAll(this, "/api/v1/invites", {
|
|
1042
|
+
query: { "project-id": projectId },
|
|
1043
|
+
}),
|
|
825
1044
|
/**
|
|
826
1045
|
* Fetch a single page of invites.
|
|
827
1046
|
* @param {object} [opts]
|
|
@@ -831,7 +1050,11 @@ class PlaidClient {
|
|
|
831
1050
|
* @returns {Promise<{entries: Array, nextCursor: (string|null)}>}
|
|
832
1051
|
*/
|
|
833
1052
|
listPage: ({ projectId, limit, cursor } = {}) =>
|
|
834
|
-
listPage(this,
|
|
1053
|
+
listPage(this, "/api/v1/invites", {
|
|
1054
|
+
limit,
|
|
1055
|
+
cursor,
|
|
1056
|
+
query: { "project-id": projectId },
|
|
1057
|
+
}),
|
|
835
1058
|
/**
|
|
836
1059
|
* Async-iterate invites page by page; yields each page's entries array.
|
|
837
1060
|
* @param {object} [opts]
|
|
@@ -841,7 +1064,10 @@ class PlaidClient {
|
|
|
841
1064
|
* @returns {AsyncGenerator<Array>}
|
|
842
1065
|
*/
|
|
843
1066
|
iterPages: ({ projectId, pageSize } = {}) =>
|
|
844
|
-
iterPages(this,
|
|
1067
|
+
iterPages(this, "/api/v1/invites", {
|
|
1068
|
+
pageSize,
|
|
1069
|
+
query: { "project-id": projectId },
|
|
1070
|
+
}),
|
|
845
1071
|
/**
|
|
846
1072
|
* Mint an invite. The returned `code` is shown ONLY here — it is never
|
|
847
1073
|
* stored and cannot be recovered, so build and hand off the link now.
|
|
@@ -849,23 +1075,46 @@ class PlaidClient {
|
|
|
849
1075
|
*
|
|
850
1076
|
* Admins may mint anything. A project maintainer may mint role grants on
|
|
851
1077
|
* projects they maintain, and nothing else: no admin grant, no grantless
|
|
852
|
-
* invite, no password resets
|
|
853
|
-
*
|
|
854
|
-
*
|
|
855
|
-
*
|
|
1078
|
+
* invite, no password resets — so for a non-admin, projectId/projectRole
|
|
1079
|
+
* are required in practice (403 without them).
|
|
1080
|
+
*
|
|
1081
|
+
* EVERY option is optional; `create()` with no arguments mints a
|
|
1082
|
+
* single-use signup link granting nothing but an account. Two pairing
|
|
1083
|
+
* rules the server enforces with a 400: projectId and projectRole must be
|
|
1084
|
+
* given TOGETHER, and targetUserId may not be combined with projectId,
|
|
1085
|
+
* grantAdmin, or a maxUses above 1.
|
|
1086
|
+
* @param {object} [opts]
|
|
1087
|
+
* @param {string} [opts.projectId] - Project the redeemer joins (requires projectRole)
|
|
1088
|
+
* @param {string} [opts.projectRole] - "reader" | "writer" | "maintainer" (requires projectId)
|
|
856
1089
|
* @param {boolean} [opts.grantAdmin] - Make the new account a global admin (admin only)
|
|
857
|
-
* @param {string} [opts.targetUserId] -
|
|
1090
|
+
* @param {string} [opts.targetUserId] - Password reset for that user instead of a signup; admin only, single-use, grants nothing
|
|
858
1091
|
* @param {number} [opts.maxUses] - How many accounts this link may create (default 1)
|
|
859
1092
|
* @param {number} [opts.ttlDays] - Days until it expires (default 14, max 365)
|
|
860
1093
|
* @param {string} [opts.note] - Human label shown in your invite list
|
|
861
1094
|
* @returns {Promise<{id: string, code: string, kind: string, status: string}>}
|
|
862
1095
|
*/
|
|
863
|
-
create: (
|
|
864
|
-
|
|
1096
|
+
create: (
|
|
1097
|
+
{
|
|
1098
|
+
projectId,
|
|
1099
|
+
projectRole,
|
|
1100
|
+
grantAdmin,
|
|
1101
|
+
targetUserId,
|
|
1102
|
+
maxUses,
|
|
1103
|
+
ttlDays,
|
|
1104
|
+
note,
|
|
1105
|
+
} = {},
|
|
1106
|
+
auditMessage,
|
|
1107
|
+
) =>
|
|
1108
|
+
this._request("POST", "/api/v1/invites", {
|
|
1109
|
+
auditMessage,
|
|
865
1110
|
body: bodyOf({
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
1111
|
+
"project-id": projectId,
|
|
1112
|
+
"project-role": projectRole,
|
|
1113
|
+
"grant-admin": grantAdmin,
|
|
1114
|
+
"target-user-id": targetUserId,
|
|
1115
|
+
"max-uses": maxUses,
|
|
1116
|
+
"ttl-days": ttlDays,
|
|
1117
|
+
note,
|
|
869
1118
|
}),
|
|
870
1119
|
}),
|
|
871
1120
|
/**
|
|
@@ -874,7 +1123,7 @@ class PlaidClient {
|
|
|
874
1123
|
* @param {string} id - The invite ID
|
|
875
1124
|
*/
|
|
876
1125
|
revoke: (id, auditMessage) =>
|
|
877
|
-
this._request(
|
|
1126
|
+
this._request("DELETE", `/api/v1/invites/${id}`, { auditMessage }),
|
|
878
1127
|
};
|
|
879
1128
|
|
|
880
1129
|
this.tokenLayers = {
|
|
@@ -884,7 +1133,8 @@ class PlaidClient {
|
|
|
884
1133
|
* @param {string} direction - The direction ("up" or "down")
|
|
885
1134
|
*/
|
|
886
1135
|
shift: (tokenLayerId, direction, auditMessage) =>
|
|
887
|
-
this._request(
|
|
1136
|
+
this._request("POST", `/api/v1/token-layers/${tokenLayerId}/shift`, {
|
|
1137
|
+
auditMessage,
|
|
888
1138
|
body: bodyOf({ direction }),
|
|
889
1139
|
}),
|
|
890
1140
|
/**
|
|
@@ -894,9 +1144,21 @@ class PlaidClient {
|
|
|
894
1144
|
* @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.
|
|
895
1145
|
* @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).
|
|
896
1146
|
*/
|
|
897
|
-
create: (
|
|
898
|
-
|
|
899
|
-
|
|
1147
|
+
create: (
|
|
1148
|
+
textLayerId,
|
|
1149
|
+
name,
|
|
1150
|
+
overlapMode,
|
|
1151
|
+
parentTokenLayerId,
|
|
1152
|
+
auditMessage,
|
|
1153
|
+
) =>
|
|
1154
|
+
this._request("POST", "/api/v1/token-layers", {
|
|
1155
|
+
auditMessage,
|
|
1156
|
+
body: bodyOf({
|
|
1157
|
+
"text-layer-id": textLayerId,
|
|
1158
|
+
name,
|
|
1159
|
+
"overlap-mode": overlapMode,
|
|
1160
|
+
"parent-token-layer-id": parentTokenLayerId,
|
|
1161
|
+
}),
|
|
900
1162
|
}),
|
|
901
1163
|
/**
|
|
902
1164
|
* Set a configuration value for a layer in an editor namespace.
|
|
@@ -905,10 +1167,18 @@ class PlaidClient {
|
|
|
905
1167
|
* @param {string} configKey - The config key
|
|
906
1168
|
* @param {any} configValue - Configuration value to set
|
|
907
1169
|
*/
|
|
908
|
-
setConfig: (
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
1170
|
+
setConfig: (
|
|
1171
|
+
tokenLayerId,
|
|
1172
|
+
namespace,
|
|
1173
|
+
configKey,
|
|
1174
|
+
configValue,
|
|
1175
|
+
auditMessage,
|
|
1176
|
+
) =>
|
|
1177
|
+
this._request(
|
|
1178
|
+
"PUT",
|
|
1179
|
+
`/api/v1/token-layers/${tokenLayerId}/config/${namespace}/${configKey}`,
|
|
1180
|
+
{ auditMessage, rawBody: configValue, skipResponseTransform: true },
|
|
1181
|
+
),
|
|
912
1182
|
/**
|
|
913
1183
|
* Remove a configuration value for a layer.
|
|
914
1184
|
* @param {string} tokenLayerId - The token layer ID
|
|
@@ -916,31 +1186,36 @@ class PlaidClient {
|
|
|
916
1186
|
* @param {string} configKey - The config key
|
|
917
1187
|
*/
|
|
918
1188
|
deleteConfig: (tokenLayerId, namespace, configKey, auditMessage) =>
|
|
919
|
-
this._request(
|
|
920
|
-
|
|
921
|
-
|
|
1189
|
+
this._request(
|
|
1190
|
+
"DELETE",
|
|
1191
|
+
`/api/v1/token-layers/${tokenLayerId}/config/${namespace}/${configKey}`,
|
|
1192
|
+
{ auditMessage, skipResponseTransform: true },
|
|
1193
|
+
),
|
|
922
1194
|
/**
|
|
923
1195
|
* Get a token layer by ID.
|
|
924
1196
|
* @param {string} tokenLayerId - The token layer ID
|
|
925
1197
|
* @param {string} [asOf] - Temporal query timestamp
|
|
926
1198
|
*/
|
|
927
1199
|
get: (tokenLayerId, asOf) =>
|
|
928
|
-
this._request(
|
|
929
|
-
queryParams: {
|
|
1200
|
+
this._request("GET", `/api/v1/token-layers/${tokenLayerId}`, {
|
|
1201
|
+
queryParams: { "as-of": asOf },
|
|
930
1202
|
}),
|
|
931
1203
|
/**
|
|
932
1204
|
* Delete a token layer.
|
|
933
1205
|
* @param {string} tokenLayerId - The token layer ID
|
|
934
1206
|
*/
|
|
935
1207
|
delete: (tokenLayerId, auditMessage) =>
|
|
936
|
-
this._request(
|
|
1208
|
+
this._request("DELETE", `/api/v1/token-layers/${tokenLayerId}`, {
|
|
1209
|
+
auditMessage,
|
|
1210
|
+
}),
|
|
937
1211
|
/**
|
|
938
1212
|
* Update a token layer's name.
|
|
939
1213
|
* @param {string} tokenLayerId - The token layer ID
|
|
940
1214
|
* @param {string} name - The name
|
|
941
1215
|
*/
|
|
942
1216
|
update: (tokenLayerId, name, auditMessage) =>
|
|
943
|
-
this._request(
|
|
1217
|
+
this._request("PATCH", `/api/v1/token-layers/${tokenLayerId}`, {
|
|
1218
|
+
auditMessage,
|
|
944
1219
|
body: bodyOf({ name }),
|
|
945
1220
|
}),
|
|
946
1221
|
};
|
|
@@ -952,29 +1227,33 @@ class PlaidClient {
|
|
|
952
1227
|
* @param {string} [asOf] - Temporal query timestamp
|
|
953
1228
|
*/
|
|
954
1229
|
checkLock: (documentId, asOf) =>
|
|
955
|
-
this._request(
|
|
956
|
-
queryParams: {
|
|
1230
|
+
this._request("GET", `/api/v1/documents/${documentId}/lock`, {
|
|
1231
|
+
queryParams: { "as-of": asOf },
|
|
957
1232
|
}),
|
|
958
1233
|
/**
|
|
959
1234
|
* Acquire or refresh a document lock
|
|
960
1235
|
* @param {string} documentId - The document ID
|
|
961
1236
|
*/
|
|
962
1237
|
acquireLock: (documentId, auditMessage) =>
|
|
963
|
-
this._request(
|
|
1238
|
+
this._request("POST", `/api/v1/documents/${documentId}/lock`, {
|
|
1239
|
+
auditMessage,
|
|
1240
|
+
}),
|
|
964
1241
|
/**
|
|
965
1242
|
* Release a document lock
|
|
966
1243
|
* @param {string} documentId - The document ID
|
|
967
1244
|
*/
|
|
968
1245
|
releaseLock: (documentId, auditMessage) =>
|
|
969
|
-
this._request(
|
|
1246
|
+
this._request("DELETE", `/api/v1/documents/${documentId}/lock`, {
|
|
1247
|
+
auditMessage,
|
|
1248
|
+
}),
|
|
970
1249
|
/**
|
|
971
1250
|
* Get media file for a document
|
|
972
1251
|
* @param {string} documentId - The document ID
|
|
973
1252
|
* @param {string} [asOf] - Temporal query timestamp
|
|
974
1253
|
*/
|
|
975
1254
|
getMedia: (documentId, asOf) =>
|
|
976
|
-
this._request(
|
|
977
|
-
queryParams: {
|
|
1255
|
+
this._request("GET", `/api/v1/documents/${documentId}/media`, {
|
|
1256
|
+
queryParams: { "as-of": asOf },
|
|
978
1257
|
noBatch: true,
|
|
979
1258
|
binaryResponse: true,
|
|
980
1259
|
}),
|
|
@@ -985,9 +1264,12 @@ class PlaidClient {
|
|
|
985
1264
|
*/
|
|
986
1265
|
uploadMedia: (documentId, file, auditMessage) => {
|
|
987
1266
|
const fd = new FormData();
|
|
988
|
-
fd.append(
|
|
989
|
-
return this._request(
|
|
990
|
-
|
|
1267
|
+
fd.append("file", file);
|
|
1268
|
+
return this._request("PUT", `/api/v1/documents/${documentId}/media`, {
|
|
1269
|
+
auditMessage,
|
|
1270
|
+
body: fd,
|
|
1271
|
+
formData: true,
|
|
1272
|
+
noBatch: true,
|
|
991
1273
|
});
|
|
992
1274
|
},
|
|
993
1275
|
/**
|
|
@@ -995,7 +1277,8 @@ class PlaidClient {
|
|
|
995
1277
|
* @param {string} documentId - The document ID
|
|
996
1278
|
*/
|
|
997
1279
|
deleteMedia: (documentId, auditMessage) =>
|
|
998
|
-
this._request(
|
|
1280
|
+
this._request("DELETE", `/api/v1/documents/${documentId}/media`, {
|
|
1281
|
+
auditMessage,
|
|
999
1282
|
noBatch: true,
|
|
1000
1283
|
}),
|
|
1001
1284
|
/**
|
|
@@ -1004,15 +1287,18 @@ class PlaidClient {
|
|
|
1004
1287
|
* @param {any} body - The request body
|
|
1005
1288
|
*/
|
|
1006
1289
|
setMetadata: (documentId, body, auditMessage) =>
|
|
1007
|
-
this._request(
|
|
1008
|
-
|
|
1290
|
+
this._request("PUT", `/api/v1/documents/${documentId}/metadata`, {
|
|
1291
|
+
auditMessage,
|
|
1292
|
+
rawBody: body,
|
|
1293
|
+
skipResponseTransform: true,
|
|
1009
1294
|
}),
|
|
1010
1295
|
/**
|
|
1011
1296
|
* Remove all metadata from a document.
|
|
1012
1297
|
* @param {string} documentId - The document ID
|
|
1013
1298
|
*/
|
|
1014
1299
|
deleteMetadata: (documentId, auditMessage) =>
|
|
1015
|
-
this._request(
|
|
1300
|
+
this._request("DELETE", `/api/v1/documents/${documentId}/metadata`, {
|
|
1301
|
+
auditMessage,
|
|
1016
1302
|
skipResponseTransform: true,
|
|
1017
1303
|
}),
|
|
1018
1304
|
/**
|
|
@@ -1021,8 +1307,10 @@ class PlaidClient {
|
|
|
1021
1307
|
* @param {any} body - The metadata patch
|
|
1022
1308
|
*/
|
|
1023
1309
|
patchMetadata: (documentId, body, auditMessage) =>
|
|
1024
|
-
this._request(
|
|
1025
|
-
|
|
1310
|
+
this._request("PATCH", `/api/v1/documents/${documentId}/metadata`, {
|
|
1311
|
+
auditMessage,
|
|
1312
|
+
rawBody: body,
|
|
1313
|
+
skipResponseTransform: true,
|
|
1026
1314
|
}),
|
|
1027
1315
|
/**
|
|
1028
1316
|
* Get audit log for a document. Transparently follows pagination cursors
|
|
@@ -1040,10 +1328,10 @@ class PlaidClient {
|
|
|
1040
1328
|
audit: (documentId, startTime, endTime, asOf, opTypes) =>
|
|
1041
1329
|
listAll(this, `/api/v1/documents/${documentId}/audit`, {
|
|
1042
1330
|
query: {
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1331
|
+
"start-time": startTime,
|
|
1332
|
+
"end-time": endTime,
|
|
1333
|
+
"as-of": asOf,
|
|
1334
|
+
"op-types": opTypesParam(opTypes),
|
|
1047
1335
|
},
|
|
1048
1336
|
}),
|
|
1049
1337
|
/**
|
|
@@ -1062,10 +1350,10 @@ class PlaidClient {
|
|
|
1062
1350
|
* @param {string[]|string} [layers] - Layer ids to restrict a body read to
|
|
1063
1351
|
*/
|
|
1064
1352
|
get: (documentId, includeBody, asOf, layers) =>
|
|
1065
|
-
this._request(
|
|
1353
|
+
this._request("GET", `/api/v1/documents/${documentId}`, {
|
|
1066
1354
|
queryParams: {
|
|
1067
|
-
|
|
1068
|
-
|
|
1355
|
+
"include-body": includeBody,
|
|
1356
|
+
"as-of": asOf,
|
|
1069
1357
|
layers: layersParam(layers),
|
|
1070
1358
|
},
|
|
1071
1359
|
}),
|
|
@@ -1074,14 +1362,17 @@ class PlaidClient {
|
|
|
1074
1362
|
* @param {string} documentId - The document ID
|
|
1075
1363
|
*/
|
|
1076
1364
|
delete: (documentId, auditMessage) =>
|
|
1077
|
-
this._request(
|
|
1365
|
+
this._request("DELETE", `/api/v1/documents/${documentId}`, {
|
|
1366
|
+
auditMessage,
|
|
1367
|
+
}),
|
|
1078
1368
|
/**
|
|
1079
1369
|
* Update a document's name.
|
|
1080
1370
|
* @param {string} documentId - The document ID
|
|
1081
1371
|
* @param {string} name - The name
|
|
1082
1372
|
*/
|
|
1083
1373
|
update: (documentId, name, auditMessage) =>
|
|
1084
|
-
this._request(
|
|
1374
|
+
this._request("PATCH", `/api/v1/documents/${documentId}`, {
|
|
1375
|
+
auditMessage,
|
|
1085
1376
|
body: bodyOf({ name }),
|
|
1086
1377
|
}),
|
|
1087
1378
|
/**
|
|
@@ -1091,8 +1382,9 @@ class PlaidClient {
|
|
|
1091
1382
|
* @param {any} [metadata] - Metadata map. Omit to leave unset; pass null to send JSON null.
|
|
1092
1383
|
*/
|
|
1093
1384
|
create: (projectId, name, metadata, auditMessage) =>
|
|
1094
|
-
this._request(
|
|
1095
|
-
|
|
1385
|
+
this._request("POST", "/api/v1/documents", {
|
|
1386
|
+
auditMessage,
|
|
1387
|
+
body: bodyOf({ "project-id": projectId, name, metadata }),
|
|
1096
1388
|
}),
|
|
1097
1389
|
};
|
|
1098
1390
|
|
|
@@ -1103,28 +1395,36 @@ class PlaidClient {
|
|
|
1103
1395
|
* @param {string} userId - The user ID
|
|
1104
1396
|
*/
|
|
1105
1397
|
addWriter: (id, userId, auditMessage) =>
|
|
1106
|
-
this._request(
|
|
1398
|
+
this._request("POST", `/api/v1/projects/${id}/writers/${userId}`, {
|
|
1399
|
+
auditMessage,
|
|
1400
|
+
}),
|
|
1107
1401
|
/**
|
|
1108
1402
|
* Remove a user's writer privileges for this project.
|
|
1109
1403
|
* @param {string} id - The resource ID
|
|
1110
1404
|
* @param {string} userId - The user ID
|
|
1111
1405
|
*/
|
|
1112
1406
|
removeWriter: (id, userId, auditMessage) =>
|
|
1113
|
-
this._request(
|
|
1407
|
+
this._request("DELETE", `/api/v1/projects/${id}/writers/${userId}`, {
|
|
1408
|
+
auditMessage,
|
|
1409
|
+
}),
|
|
1114
1410
|
/**
|
|
1115
1411
|
* Set a user's access level to read-only for this project.
|
|
1116
1412
|
* @param {string} id - The resource ID
|
|
1117
1413
|
* @param {string} userId - The user ID
|
|
1118
1414
|
*/
|
|
1119
1415
|
addReader: (id, userId, auditMessage) =>
|
|
1120
|
-
this._request(
|
|
1416
|
+
this._request("POST", `/api/v1/projects/${id}/readers/${userId}`, {
|
|
1417
|
+
auditMessage,
|
|
1418
|
+
}),
|
|
1121
1419
|
/**
|
|
1122
1420
|
* Remove a user's reader privileges for this project.
|
|
1123
1421
|
* @param {string} id - The resource ID
|
|
1124
1422
|
* @param {string} userId - The user ID
|
|
1125
1423
|
*/
|
|
1126
1424
|
removeReader: (id, userId, auditMessage) =>
|
|
1127
|
-
this._request(
|
|
1425
|
+
this._request("DELETE", `/api/v1/projects/${id}/readers/${userId}`, {
|
|
1426
|
+
auditMessage,
|
|
1427
|
+
}),
|
|
1128
1428
|
/**
|
|
1129
1429
|
* Set a configuration value for a project in an editor namespace.
|
|
1130
1430
|
* @param {string} id - The resource ID
|
|
@@ -1133,9 +1433,11 @@ class PlaidClient {
|
|
|
1133
1433
|
* @param {any} configValue - Configuration value to set
|
|
1134
1434
|
*/
|
|
1135
1435
|
setConfig: (id, namespace, configKey, configValue, auditMessage) =>
|
|
1136
|
-
this._request(
|
|
1137
|
-
|
|
1138
|
-
|
|
1436
|
+
this._request(
|
|
1437
|
+
"PUT",
|
|
1438
|
+
`/api/v1/projects/${id}/config/${namespace}/${configKey}`,
|
|
1439
|
+
{ auditMessage, rawBody: configValue, skipResponseTransform: true },
|
|
1440
|
+
),
|
|
1139
1441
|
/**
|
|
1140
1442
|
* Remove a configuration value for a project.
|
|
1141
1443
|
* @param {string} id - The resource ID
|
|
@@ -1143,23 +1445,31 @@ class PlaidClient {
|
|
|
1143
1445
|
* @param {string} configKey - The config key
|
|
1144
1446
|
*/
|
|
1145
1447
|
deleteConfig: (id, namespace, configKey, auditMessage) =>
|
|
1146
|
-
this._request(
|
|
1147
|
-
|
|
1148
|
-
|
|
1448
|
+
this._request(
|
|
1449
|
+
"DELETE",
|
|
1450
|
+
`/api/v1/projects/${id}/config/${namespace}/${configKey}`,
|
|
1451
|
+
{ auditMessage, skipResponseTransform: true },
|
|
1452
|
+
),
|
|
1149
1453
|
/**
|
|
1150
1454
|
* Assign a user as a maintainer for this project.
|
|
1151
1455
|
* @param {string} id - The resource ID
|
|
1152
1456
|
* @param {string} userId - The user ID
|
|
1153
1457
|
*/
|
|
1154
1458
|
addMaintainer: (id, userId, auditMessage) =>
|
|
1155
|
-
this._request(
|
|
1459
|
+
this._request("POST", `/api/v1/projects/${id}/maintainers/${userId}`, {
|
|
1460
|
+
auditMessage,
|
|
1461
|
+
}),
|
|
1156
1462
|
/**
|
|
1157
1463
|
* Remove a user's maintainer privileges for this project.
|
|
1158
1464
|
* @param {string} id - The resource ID
|
|
1159
1465
|
* @param {string} userId - The user ID
|
|
1160
1466
|
*/
|
|
1161
1467
|
removeMaintainer: (id, userId, auditMessage) =>
|
|
1162
|
-
this._request(
|
|
1468
|
+
this._request(
|
|
1469
|
+
"DELETE",
|
|
1470
|
+
`/api/v1/projects/${id}/maintainers/${userId}`,
|
|
1471
|
+
{ auditMessage },
|
|
1472
|
+
),
|
|
1163
1473
|
/**
|
|
1164
1474
|
* Get audit log for a project. Transparently follows pagination cursors
|
|
1165
1475
|
* and returns the full flat array.
|
|
@@ -1176,10 +1486,10 @@ class PlaidClient {
|
|
|
1176
1486
|
audit: (projectId, startTime, endTime, asOf, opTypes) =>
|
|
1177
1487
|
listAll(this, `/api/v1/projects/${projectId}/audit`, {
|
|
1178
1488
|
query: {
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1489
|
+
"start-time": startTime,
|
|
1490
|
+
"end-time": endTime,
|
|
1491
|
+
"as-of": asOf,
|
|
1492
|
+
"op-types": opTypesParam(opTypes),
|
|
1183
1493
|
},
|
|
1184
1494
|
}),
|
|
1185
1495
|
/**
|
|
@@ -1188,14 +1498,18 @@ class PlaidClient {
|
|
|
1188
1498
|
* @param {string} vocabId - The vocab layer ID
|
|
1189
1499
|
*/
|
|
1190
1500
|
linkVocab: (id, vocabId, auditMessage) =>
|
|
1191
|
-
this._request(
|
|
1501
|
+
this._request("POST", `/api/v1/projects/${id}/vocabs/${vocabId}`, {
|
|
1502
|
+
auditMessage,
|
|
1503
|
+
}),
|
|
1192
1504
|
/**
|
|
1193
1505
|
* Unlink a vocabulary from a project.
|
|
1194
1506
|
* @param {string} id - The resource ID
|
|
1195
1507
|
* @param {string} vocabId - The vocab layer ID
|
|
1196
1508
|
*/
|
|
1197
1509
|
unlinkVocab: (id, vocabId, auditMessage) =>
|
|
1198
|
-
this._request(
|
|
1510
|
+
this._request("DELETE", `/api/v1/projects/${id}/vocabs/${vocabId}`, {
|
|
1511
|
+
auditMessage,
|
|
1512
|
+
}),
|
|
1199
1513
|
/**
|
|
1200
1514
|
* Get a project by ID. To fetch the project's documents, use
|
|
1201
1515
|
* listDocuments(id) — the include-documents flag has been removed.
|
|
@@ -1203,8 +1517,8 @@ class PlaidClient {
|
|
|
1203
1517
|
* @param {string} [asOf] - Temporal query timestamp
|
|
1204
1518
|
*/
|
|
1205
1519
|
get: (id, asOf) =>
|
|
1206
|
-
this._request(
|
|
1207
|
-
queryParams: {
|
|
1520
|
+
this._request("GET", `/api/v1/projects/${id}`, {
|
|
1521
|
+
queryParams: { "as-of": asOf },
|
|
1208
1522
|
}),
|
|
1209
1523
|
/**
|
|
1210
1524
|
* List all documents in a project. Transparently follows pagination
|
|
@@ -1215,8 +1529,7 @@ class PlaidClient {
|
|
|
1215
1529
|
* server rejects `?as-of=` on the documents-list route with a 400.
|
|
1216
1530
|
* @param {string} id - The project ID
|
|
1217
1531
|
*/
|
|
1218
|
-
listDocuments: (id) =>
|
|
1219
|
-
listAll(this, `/api/v1/projects/${id}/documents`),
|
|
1532
|
+
listDocuments: (id) => listAll(this, `/api/v1/projects/${id}/documents`),
|
|
1220
1533
|
/**
|
|
1221
1534
|
* Fetch a single page of a project's documents.
|
|
1222
1535
|
*
|
|
@@ -1256,14 +1569,18 @@ class PlaidClient {
|
|
|
1256
1569
|
* @param {number} [options.timeout=0] - Per-request timeout in ms (0/null disables)
|
|
1257
1570
|
*/
|
|
1258
1571
|
delete: (id, auditMessage, { timeout = 0 } = {}) =>
|
|
1259
|
-
this._request(
|
|
1572
|
+
this._request("DELETE", `/api/v1/projects/${id}`, {
|
|
1573
|
+
auditMessage,
|
|
1574
|
+
timeout,
|
|
1575
|
+
}),
|
|
1260
1576
|
/**
|
|
1261
1577
|
* Update a project's name.
|
|
1262
1578
|
* @param {string} id - The resource ID
|
|
1263
1579
|
* @param {string} name - The name
|
|
1264
1580
|
*/
|
|
1265
1581
|
update: (id, name, auditMessage) =>
|
|
1266
|
-
this._request(
|
|
1582
|
+
this._request("PATCH", `/api/v1/projects/${id}`, {
|
|
1583
|
+
auditMessage,
|
|
1267
1584
|
body: bodyOf({ name }),
|
|
1268
1585
|
}),
|
|
1269
1586
|
/**
|
|
@@ -1273,7 +1590,7 @@ class PlaidClient {
|
|
|
1273
1590
|
* @param {string} [asOf] - Temporal query timestamp
|
|
1274
1591
|
*/
|
|
1275
1592
|
list: (asOf) =>
|
|
1276
|
-
listAll(this,
|
|
1593
|
+
listAll(this, "/api/v1/projects", { query: { "as-of": asOf } }),
|
|
1277
1594
|
/**
|
|
1278
1595
|
* Fetch a single page of projects.
|
|
1279
1596
|
* @param {object} [opts]
|
|
@@ -1283,7 +1600,11 @@ class PlaidClient {
|
|
|
1283
1600
|
* @returns {Promise<{entries: Array, nextCursor: (string|null)}>}
|
|
1284
1601
|
*/
|
|
1285
1602
|
listPage: ({ limit, cursor, asOf } = {}) =>
|
|
1286
|
-
listPage(this,
|
|
1603
|
+
listPage(this, "/api/v1/projects", {
|
|
1604
|
+
limit,
|
|
1605
|
+
cursor,
|
|
1606
|
+
query: { "as-of": asOf },
|
|
1607
|
+
}),
|
|
1287
1608
|
/**
|
|
1288
1609
|
* Async-iterate projects page by page; yields each page's entries array.
|
|
1289
1610
|
* @param {object} [opts]
|
|
@@ -1293,13 +1614,17 @@ class PlaidClient {
|
|
|
1293
1614
|
* @returns {AsyncGenerator<Array>}
|
|
1294
1615
|
*/
|
|
1295
1616
|
iterPages: ({ pageSize, asOf } = {}) =>
|
|
1296
|
-
iterPages(this,
|
|
1617
|
+
iterPages(this, "/api/v1/projects", {
|
|
1618
|
+
pageSize,
|
|
1619
|
+
query: { "as-of": asOf },
|
|
1620
|
+
}),
|
|
1297
1621
|
/**
|
|
1298
1622
|
* Create a new project. Note: this also registers the user as a maintainer.
|
|
1299
1623
|
* @param {string} name - The name
|
|
1300
1624
|
*/
|
|
1301
1625
|
create: (name, auditMessage) =>
|
|
1302
|
-
this._request(
|
|
1626
|
+
this._request("POST", "/api/v1/projects", {
|
|
1627
|
+
auditMessage,
|
|
1303
1628
|
body: bodyOf({ name }),
|
|
1304
1629
|
}),
|
|
1305
1630
|
};
|
|
@@ -1312,10 +1637,18 @@ class PlaidClient {
|
|
|
1312
1637
|
* @param {string} configKey - The config key
|
|
1313
1638
|
* @param {any} configValue - Configuration value to set
|
|
1314
1639
|
*/
|
|
1315
|
-
setConfig: (
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1640
|
+
setConfig: (
|
|
1641
|
+
textLayerId,
|
|
1642
|
+
namespace,
|
|
1643
|
+
configKey,
|
|
1644
|
+
configValue,
|
|
1645
|
+
auditMessage,
|
|
1646
|
+
) =>
|
|
1647
|
+
this._request(
|
|
1648
|
+
"PUT",
|
|
1649
|
+
`/api/v1/text-layers/${textLayerId}/config/${namespace}/${configKey}`,
|
|
1650
|
+
{ auditMessage, rawBody: configValue, skipResponseTransform: true },
|
|
1651
|
+
),
|
|
1319
1652
|
/**
|
|
1320
1653
|
* Remove a configuration value for a layer.
|
|
1321
1654
|
* @param {string} textLayerId - The text layer ID
|
|
@@ -1323,31 +1656,36 @@ class PlaidClient {
|
|
|
1323
1656
|
* @param {string} configKey - The config key
|
|
1324
1657
|
*/
|
|
1325
1658
|
deleteConfig: (textLayerId, namespace, configKey, auditMessage) =>
|
|
1326
|
-
this._request(
|
|
1327
|
-
|
|
1328
|
-
|
|
1659
|
+
this._request(
|
|
1660
|
+
"DELETE",
|
|
1661
|
+
`/api/v1/text-layers/${textLayerId}/config/${namespace}/${configKey}`,
|
|
1662
|
+
{ auditMessage, skipResponseTransform: true },
|
|
1663
|
+
),
|
|
1329
1664
|
/**
|
|
1330
1665
|
* Get a text layer by ID.
|
|
1331
1666
|
* @param {string} textLayerId - The text layer ID
|
|
1332
1667
|
* @param {string} [asOf] - Temporal query timestamp
|
|
1333
1668
|
*/
|
|
1334
1669
|
get: (textLayerId, asOf) =>
|
|
1335
|
-
this._request(
|
|
1336
|
-
queryParams: {
|
|
1670
|
+
this._request("GET", `/api/v1/text-layers/${textLayerId}`, {
|
|
1671
|
+
queryParams: { "as-of": asOf },
|
|
1337
1672
|
}),
|
|
1338
1673
|
/**
|
|
1339
1674
|
* Delete a text layer.
|
|
1340
1675
|
* @param {string} textLayerId - The text layer ID
|
|
1341
1676
|
*/
|
|
1342
1677
|
delete: (textLayerId, auditMessage) =>
|
|
1343
|
-
this._request(
|
|
1678
|
+
this._request("DELETE", `/api/v1/text-layers/${textLayerId}`, {
|
|
1679
|
+
auditMessage,
|
|
1680
|
+
}),
|
|
1344
1681
|
/**
|
|
1345
1682
|
* Update a text layer's name.
|
|
1346
1683
|
* @param {string} textLayerId - The text layer ID
|
|
1347
1684
|
* @param {string} name - The name
|
|
1348
1685
|
*/
|
|
1349
1686
|
update: (textLayerId, name, auditMessage) =>
|
|
1350
|
-
this._request(
|
|
1687
|
+
this._request("PATCH", `/api/v1/text-layers/${textLayerId}`, {
|
|
1688
|
+
auditMessage,
|
|
1351
1689
|
body: bodyOf({ name }),
|
|
1352
1690
|
}),
|
|
1353
1691
|
/**
|
|
@@ -1356,7 +1694,8 @@ class PlaidClient {
|
|
|
1356
1694
|
* @param {string} direction - The direction ("up" or "down")
|
|
1357
1695
|
*/
|
|
1358
1696
|
shift: (textLayerId, direction, auditMessage) =>
|
|
1359
|
-
this._request(
|
|
1697
|
+
this._request("POST", `/api/v1/text-layers/${textLayerId}/shift`, {
|
|
1698
|
+
auditMessage,
|
|
1360
1699
|
body: bodyOf({ direction }),
|
|
1361
1700
|
}),
|
|
1362
1701
|
/**
|
|
@@ -1365,8 +1704,9 @@ class PlaidClient {
|
|
|
1365
1704
|
* @param {string} name - The name
|
|
1366
1705
|
*/
|
|
1367
1706
|
create: (projectId, name, auditMessage) =>
|
|
1368
|
-
this._request(
|
|
1369
|
-
|
|
1707
|
+
this._request("POST", "/api/v1/text-layers", {
|
|
1708
|
+
auditMessage,
|
|
1709
|
+
body: bodyOf({ "project-id": projectId, name }),
|
|
1370
1710
|
}),
|
|
1371
1711
|
};
|
|
1372
1712
|
|
|
@@ -1377,15 +1717,18 @@ class PlaidClient {
|
|
|
1377
1717
|
* @param {any} body - The request body
|
|
1378
1718
|
*/
|
|
1379
1719
|
setMetadata: (id, body, auditMessage) =>
|
|
1380
|
-
this._request(
|
|
1381
|
-
|
|
1720
|
+
this._request("PUT", `/api/v1/vocab-items/${id}/metadata`, {
|
|
1721
|
+
auditMessage,
|
|
1722
|
+
rawBody: body,
|
|
1723
|
+
skipResponseTransform: true,
|
|
1382
1724
|
}),
|
|
1383
1725
|
/**
|
|
1384
1726
|
* Remove all metadata from a vocab item.
|
|
1385
1727
|
* @param {string} id - The resource ID
|
|
1386
1728
|
*/
|
|
1387
1729
|
deleteMetadata: (id, auditMessage) =>
|
|
1388
|
-
this._request(
|
|
1730
|
+
this._request("DELETE", `/api/v1/vocab-items/${id}/metadata`, {
|
|
1731
|
+
auditMessage,
|
|
1389
1732
|
skipResponseTransform: true,
|
|
1390
1733
|
}),
|
|
1391
1734
|
/**
|
|
@@ -1394,8 +1737,10 @@ class PlaidClient {
|
|
|
1394
1737
|
* @param {any} body - The metadata patch
|
|
1395
1738
|
*/
|
|
1396
1739
|
patchMetadata: (id, body, auditMessage) =>
|
|
1397
|
-
this._request(
|
|
1398
|
-
|
|
1740
|
+
this._request("PATCH", `/api/v1/vocab-items/${id}/metadata`, {
|
|
1741
|
+
auditMessage,
|
|
1742
|
+
rawBody: body,
|
|
1743
|
+
skipResponseTransform: true,
|
|
1399
1744
|
}),
|
|
1400
1745
|
/**
|
|
1401
1746
|
* Create a new vocab item
|
|
@@ -1404,8 +1749,9 @@ class PlaidClient {
|
|
|
1404
1749
|
* @param {any} [metadata] - Metadata map. Omit to leave unset; pass null to send JSON null.
|
|
1405
1750
|
*/
|
|
1406
1751
|
create: (vocabLayerId, form, metadata, auditMessage) =>
|
|
1407
|
-
this._request(
|
|
1408
|
-
|
|
1752
|
+
this._request("POST", "/api/v1/vocab-items", {
|
|
1753
|
+
auditMessage,
|
|
1754
|
+
body: bodyOf({ "vocab-layer-id": vocabLayerId, form, metadata }),
|
|
1409
1755
|
}),
|
|
1410
1756
|
/**
|
|
1411
1757
|
* Create multiple vocab items in a single operation. Entries may target
|
|
@@ -1413,36 +1759,43 @@ class PlaidClient {
|
|
|
1413
1759
|
* @param {Array<{vocabLayerId: string, form: string, metadata?: any}>} body - The vocab items to create
|
|
1414
1760
|
*/
|
|
1415
1761
|
bulkCreate: (body, auditMessage) =>
|
|
1416
|
-
this._request(
|
|
1762
|
+
this._request("POST", "/api/v1/vocab-items/bulk", {
|
|
1763
|
+
auditMessage,
|
|
1764
|
+
body,
|
|
1765
|
+
}),
|
|
1417
1766
|
/**
|
|
1418
1767
|
* Delete multiple vocab items in a single operation. Each item's
|
|
1419
1768
|
* descendant vocab links are deleted too. Provide an array of IDs.
|
|
1420
1769
|
* @param {string[]} body - The vocab item IDs to delete
|
|
1421
1770
|
*/
|
|
1422
1771
|
bulkDelete: (body, auditMessage) =>
|
|
1423
|
-
this._request(
|
|
1772
|
+
this._request("DELETE", "/api/v1/vocab-items/bulk", {
|
|
1773
|
+
auditMessage,
|
|
1774
|
+
body,
|
|
1775
|
+
}),
|
|
1424
1776
|
/**
|
|
1425
1777
|
* Get a vocab item by ID
|
|
1426
1778
|
* @param {string} id - The resource ID
|
|
1427
1779
|
* @param {string} [asOf] - Temporal query timestamp
|
|
1428
1780
|
*/
|
|
1429
1781
|
get: (id, asOf) =>
|
|
1430
|
-
this._request(
|
|
1431
|
-
queryParams: {
|
|
1782
|
+
this._request("GET", `/api/v1/vocab-items/${id}`, {
|
|
1783
|
+
queryParams: { "as-of": asOf },
|
|
1432
1784
|
}),
|
|
1433
1785
|
/**
|
|
1434
1786
|
* Delete a vocab item
|
|
1435
1787
|
* @param {string} id - The resource ID
|
|
1436
1788
|
*/
|
|
1437
1789
|
delete: (id, auditMessage) =>
|
|
1438
|
-
this._request(
|
|
1790
|
+
this._request("DELETE", `/api/v1/vocab-items/${id}`, { auditMessage }),
|
|
1439
1791
|
/**
|
|
1440
1792
|
* Update a vocab item's form
|
|
1441
1793
|
* @param {string} id - The resource ID
|
|
1442
1794
|
* @param {string} form - The vocab item form
|
|
1443
1795
|
*/
|
|
1444
1796
|
update: (id, form, auditMessage) =>
|
|
1445
|
-
this._request(
|
|
1797
|
+
this._request("PATCH", `/api/v1/vocab-items/${id}`, {
|
|
1798
|
+
auditMessage,
|
|
1446
1799
|
body: bodyOf({ form }),
|
|
1447
1800
|
}),
|
|
1448
1801
|
};
|
|
@@ -1454,17 +1807,20 @@ class PlaidClient {
|
|
|
1454
1807
|
* @param {string} direction - The direction ("up" or "down")
|
|
1455
1808
|
*/
|
|
1456
1809
|
shift: (relationLayerId, direction, auditMessage) =>
|
|
1457
|
-
this._request(
|
|
1458
|
-
|
|
1459
|
-
|
|
1810
|
+
this._request(
|
|
1811
|
+
"POST",
|
|
1812
|
+
`/api/v1/relation-layers/${relationLayerId}/shift`,
|
|
1813
|
+
{ auditMessage, body: bodyOf({ direction }) },
|
|
1814
|
+
),
|
|
1460
1815
|
/**
|
|
1461
1816
|
* Create a new relation layer.
|
|
1462
1817
|
* @param {string} spanLayerId - The span layer ID
|
|
1463
1818
|
* @param {string} name - The name
|
|
1464
1819
|
*/
|
|
1465
1820
|
create: (spanLayerId, name, auditMessage) =>
|
|
1466
|
-
this._request(
|
|
1467
|
-
|
|
1821
|
+
this._request("POST", "/api/v1/relation-layers", {
|
|
1822
|
+
auditMessage,
|
|
1823
|
+
body: bodyOf({ "span-layer-id": spanLayerId, name }),
|
|
1468
1824
|
}),
|
|
1469
1825
|
/**
|
|
1470
1826
|
* Set a configuration value for a layer in an editor namespace.
|
|
@@ -1473,10 +1829,18 @@ class PlaidClient {
|
|
|
1473
1829
|
* @param {string} configKey - The config key
|
|
1474
1830
|
* @param {any} configValue - Configuration value to set
|
|
1475
1831
|
*/
|
|
1476
|
-
setConfig: (
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1832
|
+
setConfig: (
|
|
1833
|
+
relationLayerId,
|
|
1834
|
+
namespace,
|
|
1835
|
+
configKey,
|
|
1836
|
+
configValue,
|
|
1837
|
+
auditMessage,
|
|
1838
|
+
) =>
|
|
1839
|
+
this._request(
|
|
1840
|
+
"PUT",
|
|
1841
|
+
`/api/v1/relation-layers/${relationLayerId}/config/${namespace}/${configKey}`,
|
|
1842
|
+
{ auditMessage, rawBody: configValue, skipResponseTransform: true },
|
|
1843
|
+
),
|
|
1480
1844
|
/**
|
|
1481
1845
|
* Remove a configuration value for a layer.
|
|
1482
1846
|
* @param {string} relationLayerId - The relation layer ID
|
|
@@ -1484,31 +1848,36 @@ class PlaidClient {
|
|
|
1484
1848
|
* @param {string} configKey - The config key
|
|
1485
1849
|
*/
|
|
1486
1850
|
deleteConfig: (relationLayerId, namespace, configKey, auditMessage) =>
|
|
1487
|
-
this._request(
|
|
1488
|
-
|
|
1489
|
-
|
|
1851
|
+
this._request(
|
|
1852
|
+
"DELETE",
|
|
1853
|
+
`/api/v1/relation-layers/${relationLayerId}/config/${namespace}/${configKey}`,
|
|
1854
|
+
{ auditMessage, skipResponseTransform: true },
|
|
1855
|
+
),
|
|
1490
1856
|
/**
|
|
1491
1857
|
* Get a relation layer by ID.
|
|
1492
1858
|
* @param {string} relationLayerId - The relation layer ID
|
|
1493
1859
|
* @param {string} [asOf] - Temporal query timestamp
|
|
1494
1860
|
*/
|
|
1495
1861
|
get: (relationLayerId, asOf) =>
|
|
1496
|
-
this._request(
|
|
1497
|
-
queryParams: {
|
|
1862
|
+
this._request("GET", `/api/v1/relation-layers/${relationLayerId}`, {
|
|
1863
|
+
queryParams: { "as-of": asOf },
|
|
1498
1864
|
}),
|
|
1499
1865
|
/**
|
|
1500
1866
|
* Delete a relation layer.
|
|
1501
1867
|
* @param {string} relationLayerId - The relation layer ID
|
|
1502
1868
|
*/
|
|
1503
1869
|
delete: (relationLayerId, auditMessage) =>
|
|
1504
|
-
this._request(
|
|
1870
|
+
this._request("DELETE", `/api/v1/relation-layers/${relationLayerId}`, {
|
|
1871
|
+
auditMessage,
|
|
1872
|
+
}),
|
|
1505
1873
|
/**
|
|
1506
1874
|
* Update a relation layer's name.
|
|
1507
1875
|
* @param {string} relationLayerId - The relation layer ID
|
|
1508
1876
|
* @param {string} name - The name
|
|
1509
1877
|
*/
|
|
1510
1878
|
update: (relationLayerId, name, auditMessage) =>
|
|
1511
|
-
this._request(
|
|
1879
|
+
this._request("PATCH", `/api/v1/relation-layers/${relationLayerId}`, {
|
|
1880
|
+
auditMessage,
|
|
1512
1881
|
body: bodyOf({ name }),
|
|
1513
1882
|
}),
|
|
1514
1883
|
};
|
|
@@ -1532,9 +1901,25 @@ class PlaidClient {
|
|
|
1532
1901
|
* @param {number} [precedence] - Ordering precedence
|
|
1533
1902
|
* @param {any} [metadata] - Metadata map. Omit to leave unset; pass null to send JSON null.
|
|
1534
1903
|
*/
|
|
1535
|
-
create: (
|
|
1536
|
-
|
|
1537
|
-
|
|
1904
|
+
create: (
|
|
1905
|
+
tokenLayerId,
|
|
1906
|
+
text,
|
|
1907
|
+
begin,
|
|
1908
|
+
end,
|
|
1909
|
+
precedence,
|
|
1910
|
+
metadata,
|
|
1911
|
+
auditMessage,
|
|
1912
|
+
) =>
|
|
1913
|
+
this._request("POST", "/api/v1/tokens", {
|
|
1914
|
+
auditMessage,
|
|
1915
|
+
body: bodyOf({
|
|
1916
|
+
"token-layer-id": tokenLayerId,
|
|
1917
|
+
text,
|
|
1918
|
+
begin,
|
|
1919
|
+
end,
|
|
1920
|
+
precedence,
|
|
1921
|
+
metadata,
|
|
1922
|
+
}),
|
|
1538
1923
|
}),
|
|
1539
1924
|
/**
|
|
1540
1925
|
* Get a token.
|
|
@@ -1542,8 +1927,8 @@ class PlaidClient {
|
|
|
1542
1927
|
* @param {string} [asOf] - Temporal query timestamp
|
|
1543
1928
|
*/
|
|
1544
1929
|
get: (tokenId, asOf) =>
|
|
1545
|
-
this._request(
|
|
1546
|
-
queryParams: {
|
|
1930
|
+
this._request("GET", `/api/v1/tokens/${tokenId}`, {
|
|
1931
|
+
queryParams: { "as-of": asOf },
|
|
1547
1932
|
}),
|
|
1548
1933
|
/**
|
|
1549
1934
|
* Delete a token and remove it from any spans. If this causes a span to
|
|
@@ -1551,7 +1936,7 @@ class PlaidClient {
|
|
|
1551
1936
|
* @param {string} tokenId - The token ID
|
|
1552
1937
|
*/
|
|
1553
1938
|
delete: (tokenId, auditMessage) =>
|
|
1554
|
-
this._request(
|
|
1939
|
+
this._request("DELETE", `/api/v1/tokens/${tokenId}`, { auditMessage }),
|
|
1555
1940
|
/**
|
|
1556
1941
|
* Update a token.
|
|
1557
1942
|
* @param {string} tokenId - The token ID
|
|
@@ -1563,7 +1948,8 @@ class PlaidClient {
|
|
|
1563
1948
|
* drops undefined, so the three cases map correctly to the server.
|
|
1564
1949
|
*/
|
|
1565
1950
|
update: (tokenId, begin, end, precedence, auditMessage) =>
|
|
1566
|
-
this._request(
|
|
1951
|
+
this._request("PATCH", `/api/v1/tokens/${tokenId}`, {
|
|
1952
|
+
auditMessage,
|
|
1567
1953
|
body: bodyOf({ begin, end, precedence }),
|
|
1568
1954
|
}),
|
|
1569
1955
|
/**
|
|
@@ -1572,13 +1958,13 @@ class PlaidClient {
|
|
|
1572
1958
|
* @returns {Promise<{ids: string[]}>} The created entity IDs, in input order. (bulkDelete resolves to no value.)
|
|
1573
1959
|
*/
|
|
1574
1960
|
bulkCreate: (body, auditMessage) =>
|
|
1575
|
-
this._request(
|
|
1961
|
+
this._request("POST", "/api/v1/tokens/bulk", { auditMessage, body }),
|
|
1576
1962
|
/**
|
|
1577
1963
|
* Delete multiple tokens in a single operation. Provide an array of IDs.
|
|
1578
1964
|
* @param {Array} body - The request body
|
|
1579
1965
|
*/
|
|
1580
1966
|
bulkDelete: (body, auditMessage) =>
|
|
1581
|
-
this._request(
|
|
1967
|
+
this._request("DELETE", "/api/v1/tokens/bulk", { auditMessage, body }),
|
|
1582
1968
|
/**
|
|
1583
1969
|
* Split a token at a Unicode code-point offset. The original token becomes the
|
|
1584
1970
|
* left half (keeps its ID, spans, vocab-links); the new right token's ID is returned.
|
|
@@ -1586,7 +1972,8 @@ class PlaidClient {
|
|
|
1586
1972
|
* @param {number} position - Code-point offset to split at (strictly between begin and end)
|
|
1587
1973
|
*/
|
|
1588
1974
|
split: (tokenId, position, auditMessage) =>
|
|
1589
|
-
this._request(
|
|
1975
|
+
this._request("POST", `/api/v1/tokens/${tokenId}/split`, {
|
|
1976
|
+
auditMessage,
|
|
1590
1977
|
body: bodyOf({ position }),
|
|
1591
1978
|
}),
|
|
1592
1979
|
/**
|
|
@@ -1598,8 +1985,9 @@ class PlaidClient {
|
|
|
1598
1985
|
* @param {string} otherTokenId - The other token to merge in
|
|
1599
1986
|
*/
|
|
1600
1987
|
merge: (tokenId, otherTokenId, auditMessage) =>
|
|
1601
|
-
this._request(
|
|
1602
|
-
|
|
1988
|
+
this._request("POST", `/api/v1/tokens/${tokenId}/merge`, {
|
|
1989
|
+
auditMessage,
|
|
1990
|
+
body: bodyOf({ "other-token-id": otherTokenId }),
|
|
1603
1991
|
}),
|
|
1604
1992
|
/**
|
|
1605
1993
|
* Shift a token's boundary. On partitioning layers the adjacent token is
|
|
@@ -1610,7 +1998,8 @@ class PlaidClient {
|
|
|
1610
1998
|
* @param {number} [end] - New end offset, exclusive (Unicode code points)
|
|
1611
1999
|
*/
|
|
1612
2000
|
shift: (tokenId, begin, end, auditMessage) =>
|
|
1613
|
-
this._request(
|
|
2001
|
+
this._request("POST", `/api/v1/tokens/${tokenId}/shift`, {
|
|
2002
|
+
auditMessage,
|
|
1614
2003
|
body: bodyOf({ begin, end }),
|
|
1615
2004
|
}),
|
|
1616
2005
|
/**
|
|
@@ -1619,15 +2008,18 @@ class PlaidClient {
|
|
|
1619
2008
|
* @param {any} body - The request body
|
|
1620
2009
|
*/
|
|
1621
2010
|
setMetadata: (tokenId, body, auditMessage) =>
|
|
1622
|
-
this._request(
|
|
1623
|
-
|
|
2011
|
+
this._request("PUT", `/api/v1/tokens/${tokenId}/metadata`, {
|
|
2012
|
+
auditMessage,
|
|
2013
|
+
rawBody: body,
|
|
2014
|
+
skipResponseTransform: true,
|
|
1624
2015
|
}),
|
|
1625
2016
|
/**
|
|
1626
2017
|
* Remove all metadata from a token.
|
|
1627
2018
|
* @param {string} tokenId - The token ID
|
|
1628
2019
|
*/
|
|
1629
2020
|
deleteMetadata: (tokenId, auditMessage) =>
|
|
1630
|
-
this._request(
|
|
2021
|
+
this._request("DELETE", `/api/v1/tokens/${tokenId}/metadata`, {
|
|
2022
|
+
auditMessage,
|
|
1631
2023
|
skipResponseTransform: true,
|
|
1632
2024
|
}),
|
|
1633
2025
|
/**
|
|
@@ -1636,8 +2028,10 @@ class PlaidClient {
|
|
|
1636
2028
|
* @param {any} body - The metadata patch
|
|
1637
2029
|
*/
|
|
1638
2030
|
patchMetadata: (tokenId, body, auditMessage) =>
|
|
1639
|
-
this._request(
|
|
1640
|
-
|
|
2031
|
+
this._request("PATCH", `/api/v1/tokens/${tokenId}/metadata`, {
|
|
2032
|
+
auditMessage,
|
|
2033
|
+
rawBody: body,
|
|
2034
|
+
skipResponseTransform: true,
|
|
1641
2035
|
}),
|
|
1642
2036
|
};
|
|
1643
2037
|
|
|
@@ -1666,7 +2060,8 @@ class PlaidClient {
|
|
|
1666
2060
|
* @returns {Promise<any>} Response from the send operation
|
|
1667
2061
|
*/
|
|
1668
2062
|
sendMessage: (projectId, data, auditMessage) =>
|
|
1669
|
-
this._request(
|
|
2063
|
+
this._request("POST", `/api/v1/projects/${projectId}/message`, {
|
|
2064
|
+
auditMessage,
|
|
1670
2065
|
rawBody: { body: data },
|
|
1671
2066
|
}),
|
|
1672
2067
|
|
|
@@ -1677,8 +2072,7 @@ class PlaidClient {
|
|
|
1677
2072
|
* @param {string} projectId - The UUID of the project to query
|
|
1678
2073
|
* @returns {Promise<Array>} Array of discovered service information
|
|
1679
2074
|
*/
|
|
1680
|
-
discoverServices: (projectId) =>
|
|
1681
|
-
discoverServices(this, projectId),
|
|
2075
|
+
discoverServices: (projectId) => discoverServices(this, projectId),
|
|
1682
2076
|
|
|
1683
2077
|
/**
|
|
1684
2078
|
* Forget a previously-seen (offline) service. Maintainer-only; 409 if
|
|
@@ -1692,14 +2086,19 @@ class PlaidClient {
|
|
|
1692
2086
|
|
|
1693
2087
|
/**
|
|
1694
2088
|
* Register as a service and handle incoming work requests.
|
|
2089
|
+
*
|
|
2090
|
+
* The registration reopens its channel whenever it drops, so a server
|
|
2091
|
+
* restart needs no service restart.
|
|
1695
2092
|
* @param {string} projectId - The UUID of the project to serve
|
|
1696
2093
|
* @param {Object} serviceInfo - Service information {serviceId, serviceName, description}
|
|
1697
2094
|
* @param {function} onServiceRequest - Callback (data, responseHelper)
|
|
1698
2095
|
* @param {Object} [extras] - Optional additional service metadata
|
|
1699
|
-
* @
|
|
2096
|
+
* @param {function} [onStatus] - Optional callback (event, projectId, detail) for
|
|
2097
|
+
* connection transitions: 'registered', 'reconnected', 'disconnected'
|
|
2098
|
+
* @returns {Object} Service registration with .stop(), .isRunning(), .isConnected()
|
|
1700
2099
|
*/
|
|
1701
|
-
serve: (projectId, serviceInfo, onServiceRequest, extras) =>
|
|
1702
|
-
serve(this, projectId, serviceInfo, onServiceRequest, extras),
|
|
2100
|
+
serve: (projectId, serviceInfo, onServiceRequest, extras, onStatus) =>
|
|
2101
|
+
serve(this, projectId, serviceInfo, onServiceRequest, extras, onStatus),
|
|
1703
2102
|
|
|
1704
2103
|
/**
|
|
1705
2104
|
* Request a service to perform work and await its result.
|
|
@@ -1708,10 +2107,11 @@ class PlaidClient {
|
|
|
1708
2107
|
* @param {any} data - The request data
|
|
1709
2108
|
* @param {number} [timeout] - Timeout in milliseconds (default: 10000)
|
|
1710
2109
|
* @param {function} [onProgress] - Called with each progress payload {percent, message}
|
|
2110
|
+
* @param {AbortSignal} [signal] - Abort to stop waiting; rejects with an AbortError
|
|
1711
2111
|
* @returns {Promise<any>} Service response
|
|
1712
2112
|
*/
|
|
1713
|
-
requestService: (projectId, serviceId, data, timeout, onProgress) =>
|
|
1714
|
-
requestService(this, projectId, serviceId, data, timeout, onProgress),
|
|
2113
|
+
requestService: (projectId, serviceId, data, timeout, onProgress, signal) =>
|
|
2114
|
+
requestService(this, projectId, serviceId, data, timeout, onProgress, signal),
|
|
1715
2115
|
};
|
|
1716
2116
|
|
|
1717
2117
|
/**
|
|
@@ -1749,8 +2149,14 @@ class PlaidClient {
|
|
|
1749
2149
|
* For 'count': {return: 'count', count}. Entity cells are full entity objects
|
|
1750
2150
|
* (same shape as the GET endpoints).
|
|
1751
2151
|
*/
|
|
2152
|
+
// bypassBatch: a query is a read. `client.batched()` flips one flag on the
|
|
2153
|
+
// whole client, so a query issued by unrelated code while a batch is open
|
|
2154
|
+
// (the IGT island fetching precedent while a document reconciles) used to
|
|
2155
|
+
// be queued into it: the caller got `{batched: true}` instead of results,
|
|
2156
|
+
// and the server ran the query against the batch's tx Connection, which
|
|
2157
|
+
// 500s and rolls back every write in that batch.
|
|
1752
2158
|
this.query = (body, auditMessage) =>
|
|
1753
|
-
this._request(
|
|
2159
|
+
this._request("POST", "/api/v1/query", { auditMessage, body, bypassBatch: true });
|
|
1754
2160
|
|
|
1755
2161
|
// Logical-operation groups (audit-log grouping). There is no create: a
|
|
1756
2162
|
// group row is made lazily by the first write carrying `?group-id=`
|
|
@@ -1760,15 +2166,130 @@ class PlaidClient {
|
|
|
1760
2166
|
* Get a logical-operation group (its label + creator).
|
|
1761
2167
|
* @param {string} id - The group id
|
|
1762
2168
|
*/
|
|
1763
|
-
get: (id) =>
|
|
1764
|
-
this._request('GET', `/api/v1/operation-groups/${id}`),
|
|
2169
|
+
get: (id) => this._request("GET", `/api/v1/operation-groups/${id}`),
|
|
1765
2170
|
/**
|
|
1766
2171
|
* Relabel a logical-operation group after the fact. Owner or admin only.
|
|
1767
2172
|
* @param {string} id - The group id
|
|
1768
2173
|
* @param {string|null} message - The new label
|
|
1769
2174
|
*/
|
|
1770
2175
|
update: (id, message) =>
|
|
1771
|
-
this._request(
|
|
2176
|
+
this._request("PATCH", `/api/v1/operation-groups/${id}`, {
|
|
2177
|
+
body: { message },
|
|
2178
|
+
}),
|
|
2179
|
+
};
|
|
2180
|
+
|
|
2181
|
+
this.comments = {
|
|
2182
|
+
/**
|
|
2183
|
+
* Post a comment on an entity. Requires write access to the entity's
|
|
2184
|
+
* project; the author is the authenticated caller. Comments are not
|
|
2185
|
+
* audited and do not bump the document version.
|
|
2186
|
+
* @param {'document'|'text'|'token'|'span'|'relation'} entityType - What kind of thing is being commented on
|
|
2187
|
+
* @param {string} entityId - The commented entity's id
|
|
2188
|
+
* @param {string} body - The comment text (1..10000 characters)
|
|
2189
|
+
*/
|
|
2190
|
+
create: (entityType, entityId, body) =>
|
|
2191
|
+
this._request("POST", "/api/v1/comments", {
|
|
2192
|
+
body: bodyOf({ "entity-type": entityType, "entity-id": entityId, body }),
|
|
2193
|
+
}),
|
|
2194
|
+
/**
|
|
2195
|
+
* Read one comment.
|
|
2196
|
+
* @param {string} id - The comment id
|
|
2197
|
+
*/
|
|
2198
|
+
get: (id) => this._request("GET", `/api/v1/comments/${id}`),
|
|
2199
|
+
/**
|
|
2200
|
+
* Edit a comment's body. Only the comment's AUTHOR may do this - not
|
|
2201
|
+
* maintainers, not admins. Sets `edited` on the comment.
|
|
2202
|
+
* @param {string} id - The comment id
|
|
2203
|
+
* @param {string} body - The replacement text
|
|
2204
|
+
*/
|
|
2205
|
+
update: (id, body) =>
|
|
2206
|
+
this._request("PATCH", `/api/v1/comments/${id}`, { body: { body } }),
|
|
2207
|
+
/**
|
|
2208
|
+
* Delete a comment. The author may delete their own; a project
|
|
2209
|
+
* maintainer (or admin) may delete any.
|
|
2210
|
+
* @param {string} id - The comment id
|
|
2211
|
+
*/
|
|
2212
|
+
delete: (id) => this._request("DELETE", `/api/v1/comments/${id}`),
|
|
2213
|
+
/**
|
|
2214
|
+
* List comments in a project, oldest first. Transparently follows
|
|
2215
|
+
* pagination cursors and returns the full flat array.
|
|
2216
|
+
* Cannot be used inside a batch (auto-paginates across requests); throws if called while batching - use listPage() for a single page in a batch.
|
|
2217
|
+
* @param {string} projectId - The project to read
|
|
2218
|
+
* @param {object} [filters] - Narrow the scope
|
|
2219
|
+
* @param {string} [filters.documentId] - Every comment anywhere in one document
|
|
2220
|
+
* @param {string} [filters.entityType] - With entityId, one entity's thread
|
|
2221
|
+
* @param {string} [filters.entityId] - With entityType, one entity's thread
|
|
2222
|
+
*/
|
|
2223
|
+
list: (projectId, { documentId, entityType, entityId } = {}) =>
|
|
2224
|
+
listAll(this, `/api/v1/projects/${projectId}/comments`, {
|
|
2225
|
+
query: {
|
|
2226
|
+
"document-id": documentId,
|
|
2227
|
+
"entity-type": entityType,
|
|
2228
|
+
"entity-id": entityId,
|
|
2229
|
+
},
|
|
2230
|
+
}),
|
|
2231
|
+
/**
|
|
2232
|
+
* Fetch a single page of a project's comments.
|
|
2233
|
+
* @param {string} projectId - The project to read
|
|
2234
|
+
* @param {object} [opts]
|
|
2235
|
+
* @param {number} [opts.limit] - Page size (1..1000; server default 100)
|
|
2236
|
+
* @param {string} [opts.cursor] - Opaque cursor from a previous page
|
|
2237
|
+
* @param {string} [opts.documentId] - Every comment anywhere in one document
|
|
2238
|
+
* @param {string} [opts.entityType] - With entityId, one entity's thread
|
|
2239
|
+
* @param {string} [opts.entityId] - With entityType, one entity's thread
|
|
2240
|
+
* @returns {Promise<{entries: Array, nextCursor: (string|null)}>}
|
|
2241
|
+
*/
|
|
2242
|
+
listPage: (projectId, { limit, cursor, documentId, entityType, entityId } = {}) =>
|
|
2243
|
+
listPage(this, `/api/v1/projects/${projectId}/comments`, {
|
|
2244
|
+
limit,
|
|
2245
|
+
cursor,
|
|
2246
|
+
query: {
|
|
2247
|
+
"document-id": documentId,
|
|
2248
|
+
"entity-type": entityType,
|
|
2249
|
+
"entity-id": entityId,
|
|
2250
|
+
},
|
|
2251
|
+
}),
|
|
2252
|
+
/**
|
|
2253
|
+
* Async-iterate a project's comments page by page; yields each page's entries array.
|
|
2254
|
+
* Cannot be used inside a batch (auto-paginates across requests); throws on first iteration if called while batching - use listPage() for a single page in a batch.
|
|
2255
|
+
* @param {string} projectId - The project to read
|
|
2256
|
+
* @param {object} [opts]
|
|
2257
|
+
* @param {number} [opts.pageSize] - Per-request page size
|
|
2258
|
+
* @param {string} [opts.documentId] - Every comment anywhere in one document
|
|
2259
|
+
* @param {string} [opts.entityType] - With entityId, one entity's thread
|
|
2260
|
+
* @param {string} [opts.entityId] - With entityType, one entity's thread
|
|
2261
|
+
* @returns {AsyncGenerator<Array>}
|
|
2262
|
+
*/
|
|
2263
|
+
iterPages: (projectId, { pageSize, documentId, entityType, entityId } = {}) =>
|
|
2264
|
+
iterPages(this, `/api/v1/projects/${projectId}/comments`, {
|
|
2265
|
+
pageSize,
|
|
2266
|
+
query: {
|
|
2267
|
+
"document-id": documentId,
|
|
2268
|
+
"entity-type": entityType,
|
|
2269
|
+
"entity-id": entityId,
|
|
2270
|
+
},
|
|
2271
|
+
}),
|
|
2272
|
+
/**
|
|
2273
|
+
* Comment counts per entity, as an `{entityId: n}` map, over the same
|
|
2274
|
+
* scope and filters as `list`. One cheap request paints a comment
|
|
2275
|
+
* indicator on every annotated item in a document without paging
|
|
2276
|
+
* through the bodies.
|
|
2277
|
+
*
|
|
2278
|
+
* The response is NOT key-transformed: its keys are entity ids, and
|
|
2279
|
+
* camelCasing would mangle the hyphens in a UUID.
|
|
2280
|
+
* @param {string} projectId - The project to read
|
|
2281
|
+
* @param {object} [filters] - Same filters as list()
|
|
2282
|
+
* @returns {Promise<Object<string, number>>}
|
|
2283
|
+
*/
|
|
2284
|
+
counts: (projectId, { documentId, entityType, entityId } = {}) =>
|
|
2285
|
+
this._request("GET", `/api/v1/projects/${projectId}/comments/counts`, {
|
|
2286
|
+
queryParams: {
|
|
2287
|
+
"document-id": documentId,
|
|
2288
|
+
"entity-type": entityType,
|
|
2289
|
+
"entity-id": entityId,
|
|
2290
|
+
},
|
|
2291
|
+
skipResponseTransform: true,
|
|
2292
|
+
}),
|
|
1772
2293
|
};
|
|
1773
2294
|
}
|
|
1774
2295
|
|
|
@@ -1876,7 +2397,9 @@ class PlaidClient {
|
|
|
1876
2397
|
async withOperation(message, fn) {
|
|
1877
2398
|
this.beginOperation(message);
|
|
1878
2399
|
const group = this.operationGroup;
|
|
1879
|
-
const setMessage = (msg) => {
|
|
2400
|
+
const setMessage = (msg) => {
|
|
2401
|
+
if (group.depth === 1) group.refined = msg;
|
|
2402
|
+
};
|
|
1880
2403
|
try {
|
|
1881
2404
|
return await fn(setMessage);
|
|
1882
2405
|
} finally {
|
|
@@ -1900,7 +2423,7 @@ class PlaidClient {
|
|
|
1900
2423
|
*/
|
|
1901
2424
|
async submitBatch() {
|
|
1902
2425
|
if (!this.isBatching) {
|
|
1903
|
-
throw new Error(
|
|
2426
|
+
throw new Error("No active batch. Call beginBatch() first.");
|
|
1904
2427
|
}
|
|
1905
2428
|
|
|
1906
2429
|
if (this.batchOperations.length === 0) {
|
|
@@ -1910,50 +2433,66 @@ class PlaidClient {
|
|
|
1910
2433
|
|
|
1911
2434
|
try {
|
|
1912
2435
|
let url = `${this.baseUrl}/api/v1/batch`;
|
|
1913
|
-
const body = this.batchOperations.map(op => ({
|
|
2436
|
+
const body = this.batchOperations.map((op) => ({
|
|
1914
2437
|
path: op.path,
|
|
1915
2438
|
method: op.method.toUpperCase(),
|
|
1916
2439
|
...(op.body && { body: op.body }),
|
|
1917
2440
|
}));
|
|
1918
2441
|
|
|
1919
2442
|
const fetchOptions = {
|
|
1920
|
-
method:
|
|
2443
|
+
method: "POST",
|
|
1921
2444
|
headers: {
|
|
1922
|
-
|
|
1923
|
-
|
|
2445
|
+
Authorization: `Bearer ${this.token}`,
|
|
2446
|
+
"Content-Type": "application/json",
|
|
1924
2447
|
},
|
|
1925
2448
|
body: JSON.stringify(body),
|
|
1926
2449
|
};
|
|
1927
|
-
const signal = timeoutSignal(this.timeout);
|
|
1928
|
-
if (signal) fetchOptions.signal = signal;
|
|
1929
2450
|
|
|
1930
2451
|
try {
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
2452
|
+
// Retry a 503: the batch is atomic, so a refused one wrote nothing and
|
|
2453
|
+
// repeating it is safe. A fresh timeout signal per attempt — an
|
|
2454
|
+
// AbortSignal.timeout stays aborted once it fires.
|
|
2455
|
+
const response = await retryWhileBusy(async () => {
|
|
2456
|
+
const signal = timeoutSignal(this.batchTimeout);
|
|
2457
|
+
const res = await fetch(
|
|
2458
|
+
url,
|
|
2459
|
+
signal ? { ...fetchOptions, signal } : fetchOptions,
|
|
2460
|
+
);
|
|
2461
|
+
if (!res.ok) {
|
|
2462
|
+
throw makeHttpError(res, await parseErrorBody(res), url, "POST");
|
|
2463
|
+
}
|
|
2464
|
+
return res;
|
|
2465
|
+
});
|
|
1935
2466
|
|
|
1936
2467
|
const results = await response.json();
|
|
1937
2468
|
|
|
1938
2469
|
// Extract document versions from each batch response
|
|
1939
2470
|
for (const result of results) {
|
|
1940
|
-
if (result.headers && result.headers[
|
|
2471
|
+
if (result.headers && result.headers["X-Document-Versions"]) {
|
|
1941
2472
|
try {
|
|
1942
|
-
const versionsMap = JSON.parse(
|
|
1943
|
-
|
|
2473
|
+
const versionsMap = JSON.parse(
|
|
2474
|
+
result.headers["X-Document-Versions"],
|
|
2475
|
+
);
|
|
2476
|
+
if (typeof versionsMap === "object" && versionsMap !== null) {
|
|
1944
2477
|
// Clone once per response, then merge — not once per entry.
|
|
1945
|
-
this.documentVersions = {
|
|
2478
|
+
this.documentVersions = {
|
|
2479
|
+
...this.documentVersions,
|
|
2480
|
+
...versionsMap,
|
|
2481
|
+
};
|
|
1946
2482
|
}
|
|
1947
2483
|
} catch (e) {
|
|
1948
|
-
console.warn(
|
|
2484
|
+
console.warn(
|
|
2485
|
+
"Failed to parse document versions header from batch response:",
|
|
2486
|
+
e,
|
|
2487
|
+
);
|
|
1949
2488
|
}
|
|
1950
2489
|
}
|
|
1951
2490
|
}
|
|
1952
2491
|
|
|
1953
|
-
return results.map(result => transformResponse(result));
|
|
2492
|
+
return results.map((result) => transformResponse(result));
|
|
1954
2493
|
} catch (error) {
|
|
1955
2494
|
if (error.status) throw error;
|
|
1956
|
-
throw makeNetworkError(error, url,
|
|
2495
|
+
throw makeNetworkError(error, url, "POST");
|
|
1957
2496
|
}
|
|
1958
2497
|
} finally {
|
|
1959
2498
|
this.isBatching = false;
|
|
@@ -2026,7 +2565,7 @@ class PlaidClient {
|
|
|
2026
2565
|
* @returns {string}
|
|
2027
2566
|
*/
|
|
2028
2567
|
static inviteUrl(appUrl, code) {
|
|
2029
|
-
return `${appUrl.replace(/#.*$/,
|
|
2568
|
+
return `${appUrl.replace(/#.*$/, "").replace(/\/$/, "")}/#/invite/${encodeURIComponent(code)}`;
|
|
2030
2569
|
}
|
|
2031
2570
|
|
|
2032
2571
|
/**
|
|
@@ -2040,63 +2579,90 @@ class PlaidClient {
|
|
|
2040
2579
|
* @param {string} baseUrl - The API base URL
|
|
2041
2580
|
* @param {string} code - The invite code
|
|
2042
2581
|
* @param {object} [options]
|
|
2043
|
-
* @returns {Promise<{kind: string, status: string, expiresAt: string, projectName?: string, projectRole?: string,
|
|
2582
|
+
* @returns {Promise<{kind: string, status: string, expiresAt: string, projectName?: string, projectRole?: string, email?: string, grantAdmin: boolean}>}
|
|
2044
2583
|
*/
|
|
2045
2584
|
static async lookupInvite(baseUrl, code, options = {}) {
|
|
2046
|
-
return anonymousPost(
|
|
2585
|
+
return anonymousPost(
|
|
2586
|
+
baseUrl,
|
|
2587
|
+
"/api/v1/invite-codes/lookup",
|
|
2588
|
+
{ code },
|
|
2589
|
+
options,
|
|
2590
|
+
);
|
|
2047
2591
|
}
|
|
2048
2592
|
|
|
2049
2593
|
/**
|
|
2050
2594
|
* Redeem an invite code, with NO authentication.
|
|
2051
2595
|
*
|
|
2052
|
-
* For a signup invite, pass `
|
|
2053
|
-
* the invite's grants are applied in the
|
|
2054
|
-
* reset link, pass `password` only.
|
|
2055
|
-
* like login() — the redeemer just
|
|
2056
|
-
* reason to send them to a login
|
|
2596
|
+
* For a signup invite, pass `email` and `password` to create the account
|
|
2597
|
+
* (and optionally `displayName`); the invite's grants are applied in the
|
|
2598
|
+
* same transaction. For a password reset link, pass `password` only.
|
|
2599
|
+
* Resolves to a logged-in client, exactly like login() — the redeemer just
|
|
2600
|
+
* chose these credentials, so there is no reason to send them to a login
|
|
2601
|
+
* form to retype them.
|
|
2057
2602
|
* @param {string} baseUrl - The API base URL
|
|
2058
2603
|
* @param {string} code - The invite code
|
|
2059
2604
|
* @param {object} credentials
|
|
2060
|
-
* @param {string} [credentials.
|
|
2605
|
+
* @param {string} [credentials.email] - The new account's email address,
|
|
2606
|
+
* which becomes its id and login (signup only)
|
|
2607
|
+
* @param {string} [credentials.displayName] - How the new user is shown in
|
|
2608
|
+
* the UI; defaults to the local part of the email (signup only)
|
|
2061
2609
|
* @param {string} credentials.password - Desired password (min 8 characters)
|
|
2062
2610
|
* @param {object} [options]
|
|
2063
2611
|
* @returns {Promise<{client: PlaidClient, userId: string, kind: string}>}
|
|
2064
2612
|
*/
|
|
2065
|
-
static async redeemInvite(
|
|
2613
|
+
static async redeemInvite(
|
|
2614
|
+
baseUrl,
|
|
2615
|
+
code,
|
|
2616
|
+
{ email, password, displayName } = {},
|
|
2617
|
+
options = {},
|
|
2618
|
+
) {
|
|
2066
2619
|
const data = await anonymousPost(
|
|
2067
|
-
baseUrl,
|
|
2068
|
-
|
|
2620
|
+
baseUrl,
|
|
2621
|
+
"/api/v1/invite-codes/redeem",
|
|
2622
|
+
bodyOf({ code, email, password, "display-name": displayName }),
|
|
2623
|
+
options,
|
|
2069
2624
|
);
|
|
2070
2625
|
return {
|
|
2071
|
-
client: new PlaidClient(
|
|
2626
|
+
client: new PlaidClient(
|
|
2627
|
+
baseUrl.replace(/\/$/, ""),
|
|
2628
|
+
data.token || "",
|
|
2629
|
+
options,
|
|
2630
|
+
),
|
|
2072
2631
|
userId: data.userId,
|
|
2073
2632
|
kind: data.kind,
|
|
2074
2633
|
};
|
|
2075
2634
|
}
|
|
2076
2635
|
|
|
2077
2636
|
static async login(baseUrl, userId, password, options = {}) {
|
|
2078
|
-
baseUrl = baseUrl.replace(/\/$/,
|
|
2637
|
+
baseUrl = baseUrl.replace(/\/$/, "");
|
|
2079
2638
|
const url = `${baseUrl}/api/v1/login`;
|
|
2080
2639
|
try {
|
|
2081
2640
|
const fetchOptions = {
|
|
2082
|
-
method:
|
|
2083
|
-
headers: {
|
|
2084
|
-
body: JSON.stringify({
|
|
2641
|
+
method: "POST",
|
|
2642
|
+
headers: { "Content-Type": "application/json" },
|
|
2643
|
+
body: JSON.stringify({ "user-id": userId, password }),
|
|
2085
2644
|
};
|
|
2086
|
-
const signal = timeoutSignal(
|
|
2645
|
+
const signal = timeoutSignal(
|
|
2646
|
+
options.timeout !== undefined ? options.timeout : DEFAULT_TIMEOUT_MS,
|
|
2647
|
+
);
|
|
2087
2648
|
if (signal) fetchOptions.signal = signal;
|
|
2088
2649
|
|
|
2089
2650
|
const response = await fetch(url, fetchOptions);
|
|
2090
2651
|
if (!response.ok) {
|
|
2091
|
-
throw makeHttpError(
|
|
2652
|
+
throw makeHttpError(
|
|
2653
|
+
response,
|
|
2654
|
+
await parseErrorBody(response),
|
|
2655
|
+
url,
|
|
2656
|
+
"POST",
|
|
2657
|
+
);
|
|
2092
2658
|
}
|
|
2093
2659
|
|
|
2094
2660
|
const data = await response.json();
|
|
2095
|
-
const token = data.token ||
|
|
2661
|
+
const token = data.token || "";
|
|
2096
2662
|
return new PlaidClient(baseUrl, token, options);
|
|
2097
2663
|
} catch (error) {
|
|
2098
2664
|
if (error.status) throw error;
|
|
2099
|
-
throw makeNetworkError(error, url,
|
|
2665
|
+
throw makeNetworkError(error, url, "POST");
|
|
2100
2666
|
}
|
|
2101
2667
|
}
|
|
2102
2668
|
}
|
|
@@ -2106,8 +2672,21 @@ export { PlaidClient };
|
|
|
2106
2672
|
|
|
2107
2673
|
// Unicode code-point helpers for text offsets (token begin/end are code-point
|
|
2108
2674
|
// indices). See ./codepoint.js.
|
|
2109
|
-
export {
|
|
2110
|
-
|
|
2675
|
+
export {
|
|
2676
|
+
cpLength,
|
|
2677
|
+
cpSlice,
|
|
2678
|
+
cpSlicer,
|
|
2679
|
+
utf16ToCp,
|
|
2680
|
+
cpToUtf16,
|
|
2681
|
+
cpIndexOf,
|
|
2682
|
+
} from "./codepoint.js";
|
|
2683
|
+
export {
|
|
2684
|
+
PLAID_NAMESPACE,
|
|
2685
|
+
ROLE_KEY,
|
|
2686
|
+
ROLES,
|
|
2687
|
+
readRole,
|
|
2688
|
+
findByRole,
|
|
2689
|
+
} from "./roles.js";
|
|
2111
2690
|
// Service self-description helpers: filter discovered services by task, read a
|
|
2112
2691
|
// service's parameter schema/summary, and build/coerce form values. See
|
|
2113
2692
|
// ./serviceSchema.js.
|
|
@@ -2119,7 +2698,7 @@ export {
|
|
|
2119
2698
|
getServiceSummary,
|
|
2120
2699
|
buildDefaultValues,
|
|
2121
2700
|
coerceParamValues,
|
|
2122
|
-
} from
|
|
2701
|
+
} from "./serviceSchema.js";
|
|
2123
2702
|
// Provenance: the cross-app convention for machine-provided vs human-labeled
|
|
2124
2703
|
// information (flat prov/provSource/provConfirmed metadata; absence = human),
|
|
2125
2704
|
// plus the machine-writer contract. See ./provenance.js and the manual,
|
|
@@ -2135,4 +2714,4 @@ export {
|
|
|
2135
2714
|
isProtected,
|
|
2136
2715
|
verifyOnEdit,
|
|
2137
2716
|
serviceSource,
|
|
2138
|
-
} from
|
|
2717
|
+
} from "./provenance.js";
|