@larc-iu/plaid-client 0.2.0-alpha.3 → 0.2.0-alpha.32
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/README.md +39 -0
- package/package.json +13 -6
- package/src/apiAnnotations.d.ts +508 -0
- package/src/apiAnnotations.js +543 -0
- package/src/apiDocuments.d.ts +569 -0
- package/src/apiDocuments.js +551 -0
- package/src/apiLayers.d.ts +369 -0
- package/src/apiLayers.js +222 -0
- package/src/apiMessages.d.ts +293 -0
- package/src/apiMessages.js +265 -0
- package/src/apiPeople.d.ts +626 -0
- package/src/apiPeople.js +698 -0
- package/src/apiProject.d.ts +761 -0
- package/src/apiProject.js +774 -0
- package/src/apiServer.d.ts +457 -0
- package/src/apiServer.js +424 -0
- package/src/apiVocab.d.ts +456 -0
- package/src/apiVocab.js +425 -0
- package/src/batch.d.ts +54 -0
- package/src/batch.js +323 -0
- package/src/batchRef.d.ts +30 -0
- package/src/batchRef.js +128 -0
- package/src/client.d.ts +1321 -0
- package/src/client.js +743 -0
- package/src/codepoint.d.ts +94 -0
- package/src/codepoint.js +131 -1
- package/src/constraints.d.ts +85 -0
- package/src/constraints.js +112 -0
- package/src/created.d.ts +2 -0
- package/src/created.js +29 -0
- package/src/documentLock.d.ts +172 -0
- package/src/documentLock.js +384 -0
- package/src/entryForms.d.ts +68 -0
- package/src/entryForms.js +164 -0
- package/src/events.d.ts +60 -0
- package/src/events.js +271 -0
- package/src/families.d.ts +349 -0
- package/src/families.js +396 -0
- package/src/http.d.ts +233 -0
- package/src/http.js +809 -93
- package/src/ids.d.ts +26 -0
- package/src/ids.js +96 -0
- package/src/index.d.ts +101 -0
- package/src/index.js +183 -2105
- package/src/metadataOps.d.ts +15 -0
- package/src/metadataOps.js +124 -0
- package/src/operations.d.ts +36 -0
- package/src/operations.js +164 -0
- package/src/pagination.d.ts +49 -0
- package/src/pagination.js +20 -53
- package/src/provenance.d.ts +243 -0
- package/src/provenance.js +458 -36
- package/src/replayed.d.ts +3 -0
- package/src/replayed.js +31 -0
- package/src/requester.d.ts +60 -0
- package/src/requester.js +74 -0
- package/src/roles.d.ts +104 -0
- package/src/roles.js +64 -2
- package/src/serviceSchema.d.ts +337 -0
- package/src/serviceSchema.js +177 -60
- package/src/services.d.ts +319 -0
- package/src/services.js +742 -58
- package/src/sse.d.ts +30 -0
- package/src/sse.js +80 -3
- package/src/testing.d.ts +128 -0
- package/src/testing.js +379 -0
- package/src/textEdits.d.ts +59 -0
- package/src/textEdits.js +234 -0
- package/src/transforms.d.ts +25 -0
- package/src/transforms.js +11 -1
- package/src/types.d.ts +867 -0
- package/src/types.js +663 -0
- package/index.d.ts +0 -532
package/src/apiServer.js
ADDED
|
@@ -0,0 +1,424 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The server bundles: the server's facts and health, the instance admin
|
|
3
|
+
* controls and the instance-wide audit log, each a factory of the client
|
|
4
|
+
* (client.js installs them).
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { auditQuery } from "./families.js";
|
|
8
|
+
import { iterPages, listAll, listPage } from "./pagination.js";
|
|
9
|
+
import { PlaidClient } from "./client.js";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* How long `admin.backup()` waits for the server to finish writing a backup:
|
|
13
|
+
* minutes on a large database, past the usual per-request timeout.
|
|
14
|
+
*/
|
|
15
|
+
export const BACKUP_TIMEOUT_MS = 30 * 60 * 1000;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @typedef {import("./types.js").TextEditOp} TextEditOp
|
|
19
|
+
* @typedef {import("./types.js").TextGap} TextGap
|
|
20
|
+
* @typedef {import("./types.js").MetadataOp} MetadataOp
|
|
21
|
+
* @typedef {import("./types.js").LayerConstraint} LayerConstraint
|
|
22
|
+
* @typedef {import("./types.js").ConstraintWriteOptions} ConstraintWriteOptions
|
|
23
|
+
* @typedef {import("./types.js").ConstraintViolation} ConstraintViolation
|
|
24
|
+
* @typedef {import("./types.js").Requester} Requester
|
|
25
|
+
* @typedef {import("./types.js").BatchRef} BatchRef
|
|
26
|
+
* @typedef {import("./types.js").ServiceParam} ServiceParam
|
|
27
|
+
* @typedef {import("./types.js").ServiceInfo} ServiceInfo
|
|
28
|
+
* @typedef {import("./types.js").DiscoveredService} DiscoveredService
|
|
29
|
+
* @typedef {import("./types.js").ResponseHelper} ResponseHelper
|
|
30
|
+
* @typedef {import("./types.js").ServiceRegistration} ServiceRegistration
|
|
31
|
+
* @typedef {import("./types.js").ServiceStatusEvent} ServiceStatusEvent
|
|
32
|
+
* @typedef {import("./types.js").OperationGroupsBundle} OperationGroupsBundle
|
|
33
|
+
* @typedef {import("./types.js").PlaidClientOptions} PlaidClientOptions
|
|
34
|
+
* @typedef {import("./types.js").OperationKind} OperationKind
|
|
35
|
+
* @typedef {import("./types.js").KeySeed} KeySeed
|
|
36
|
+
* @typedef {import("./types.js").PlaidBatch} PlaidBatch
|
|
37
|
+
* @typedef {import("./types.js").AuditPageOptions} AuditPageOptions
|
|
38
|
+
* @typedef {import("./types.js").VocabItemRestoreSummary} VocabItemRestoreSummary
|
|
39
|
+
* @typedef {import("./types.js").UserDataEntry} UserDataEntry
|
|
40
|
+
* @typedef {import("./types.js").AdminUserDataEntry} AdminUserDataEntry
|
|
41
|
+
* @typedef {import("./types.js").ActivityTallyRow} ActivityTallyRow
|
|
42
|
+
* @typedef {import("./types.js").ConstraintRepair} ConstraintRepair
|
|
43
|
+
* @typedef {import("./types.js").ValueSetRule} ValueSetRule
|
|
44
|
+
* @typedef {import("./types.js").RefusedValues} RefusedValues
|
|
45
|
+
* @typedef {import("./types.js").CommentableType} CommentableType
|
|
46
|
+
* @typedef {import("./types.js").Comment} Comment
|
|
47
|
+
* @typedef {import("./types.js").Guideline} Guideline
|
|
48
|
+
* @typedef {import("./types.js").ClientEventType} ClientEventType
|
|
49
|
+
* @typedef {import("./types.js").ClientEvent} ClientEvent
|
|
50
|
+
* @typedef {import("./types.js").Invite} Invite
|
|
51
|
+
* @typedef {import("./types.js").ServerLimits} ServerLimits
|
|
52
|
+
* @typedef {import("./types.js").ServerHealth} ServerHealth
|
|
53
|
+
* @typedef {import("./types.js").RateLimitBucket} RateLimitBucket
|
|
54
|
+
* @typedef {import("./types.js").RateLimitSnapshot} RateLimitSnapshot
|
|
55
|
+
* @typedef {import("./types.js").BackupStatus} BackupStatus
|
|
56
|
+
* @typedef {import("./types.js").ServerReport} ServerReport
|
|
57
|
+
* @typedef {import("./types.js").LiveLog} LiveLog
|
|
58
|
+
* @typedef {import("./types.js").SSEConnection} SSEConnection
|
|
59
|
+
* @typedef {import("./types.js").SSEStats} SSEStats
|
|
60
|
+
* @typedef {import("./types.js").AtomicValue} AtomicValue
|
|
61
|
+
* @typedef {import("./types.js").Created} Created
|
|
62
|
+
* @typedef {import("./types.js").Project} Project
|
|
63
|
+
* @typedef {import("./types.js").ProjectTextLayer} ProjectTextLayer
|
|
64
|
+
* @typedef {import("./types.js").ProjectTokenLayer} ProjectTokenLayer
|
|
65
|
+
* @typedef {import("./types.js").ProjectSpanLayer} ProjectSpanLayer
|
|
66
|
+
* @typedef {import("./types.js").ProjectRelationLayer} ProjectRelationLayer
|
|
67
|
+
* @typedef {import("./types.js").ProjectVocab} ProjectVocab
|
|
68
|
+
* @typedef {import("./types.js").PlaidDocument} PlaidDocument
|
|
69
|
+
* @typedef {import("./types.js").DocumentTextLayer} DocumentTextLayer
|
|
70
|
+
* @typedef {import("./types.js").DocumentTokenLayer} DocumentTokenLayer
|
|
71
|
+
* @typedef {import("./types.js").DocumentSpanLayer} DocumentSpanLayer
|
|
72
|
+
* @typedef {import("./types.js").PlaidText} PlaidText
|
|
73
|
+
* @typedef {import("./types.js").TextReshape} TextReshape
|
|
74
|
+
* @typedef {import("./types.js").Token} Token
|
|
75
|
+
* @typedef {import("./types.js").Span} Span
|
|
76
|
+
* @typedef {import("./types.js").Relation} Relation
|
|
77
|
+
* @typedef {import("./types.js").VocabItem} VocabItem
|
|
78
|
+
* @typedef {import("./types.js").VocabLink} VocabLink
|
|
79
|
+
* @typedef {import("./types.js").VocabLayer} VocabLayer
|
|
80
|
+
* @typedef {import("./types.js").TextLayer} TextLayer
|
|
81
|
+
* @typedef {import("./types.js").TokenLayer} TokenLayer
|
|
82
|
+
* @typedef {import("./types.js").SpanLayer} SpanLayer
|
|
83
|
+
* @typedef {import("./types.js").RelationLayer} RelationLayer
|
|
84
|
+
* @typedef {import("./types.js").MetadataRecords} MetadataRecords
|
|
85
|
+
* @typedef {import("./types.js").LayerRecords} LayerRecords
|
|
86
|
+
* @typedef {import("./types.js").User} User
|
|
87
|
+
* @typedef {import("./types.js").ProjectListEntry} ProjectListEntry
|
|
88
|
+
* @typedef {import("./types.js").DocumentListEntry} DocumentListEntry
|
|
89
|
+
* @typedef {import("./types.js").ApiToken} ApiToken
|
|
90
|
+
* @typedef {import("./types.js").AuditUser} AuditUser
|
|
91
|
+
* @typedef {import("./types.js").AuditTarget} AuditTarget
|
|
92
|
+
* @typedef {import("./types.js").AuditOp} AuditOp
|
|
93
|
+
* @typedef {import("./types.js").AuditEntry} AuditEntry
|
|
94
|
+
* @typedef {import("./types.js").LockGrant} LockGrant
|
|
95
|
+
* @typedef {import("./types.js").DocumentRestoreSummary} DocumentRestoreSummary
|
|
96
|
+
* @typedef {import("./types.js").RestoreCounts} RestoreCounts
|
|
97
|
+
* @typedef {import("./types.js").OperationGroup} OperationGroup
|
|
98
|
+
* @typedef {import("./types.js").QueryResult} QueryResult
|
|
99
|
+
*/
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* @template [T=any]
|
|
103
|
+
* @typedef {import("./types.js").Page<T>} Page
|
|
104
|
+
*/
|
|
105
|
+
|
|
106
|
+
// Server-level facts. Read once, and again only when they may have
|
|
107
|
+
// changed: after this client's connection to the server was lost and came
|
|
108
|
+
// back (a restart, the only way the limits change, always drops it), or
|
|
109
|
+
// after the server refused a private data write as too large. A caller
|
|
110
|
+
// asking "will this file be accepted" does not pay a round trip to find
|
|
111
|
+
// out. The facts live on the client (`_serverFacts`), so a batch opened
|
|
112
|
+
// on it reads the same.
|
|
113
|
+
/** @param {import("./client.js").PlaidClient} client */
|
|
114
|
+
export function serverApi(client) {
|
|
115
|
+
return {
|
|
116
|
+
/**
|
|
117
|
+
* This server's version and the limits it enforces, e.g.
|
|
118
|
+
* `{ limits: { mediaFileBytes, jsonBodyBytes, batchOperations, … } }`.
|
|
119
|
+
* Sizes are in bytes. Unauthenticated.
|
|
120
|
+
* @returns {Promise<{limits: ServerLimits}>}
|
|
121
|
+
*/
|
|
122
|
+
info: () => {
|
|
123
|
+
const facts = client._serverFacts;
|
|
124
|
+
if (!facts.info) {
|
|
125
|
+
const asked = client._request("GET", "/api/v1/info").catch((err) => {
|
|
126
|
+
// A failure must not be kept: a client that starts before the
|
|
127
|
+
// server is up would never see the limits at all.
|
|
128
|
+
if (facts.info === asked) facts.info = null;
|
|
129
|
+
throw err;
|
|
130
|
+
});
|
|
131
|
+
facts.info = asked;
|
|
132
|
+
}
|
|
133
|
+
return facts.info;
|
|
134
|
+
},
|
|
135
|
+
/**
|
|
136
|
+
* Read `GET /info` again and resolve to it. Until it answers, a reader
|
|
137
|
+
* waits for it. The facts known before are kept when the server does
|
|
138
|
+
* not answer, and the error is thrown.
|
|
139
|
+
* @returns {Promise<{limits: ServerLimits}>}
|
|
140
|
+
*/
|
|
141
|
+
refresh: () => {
|
|
142
|
+
const facts = client._serverFacts;
|
|
143
|
+
const before = facts.info;
|
|
144
|
+
facts.stale = false;
|
|
145
|
+
const fresh = client._request("GET", "/api/v1/info");
|
|
146
|
+
const held = fresh.catch((err) => {
|
|
147
|
+
if (facts.info === held) facts.info = before;
|
|
148
|
+
if (before) return before;
|
|
149
|
+
throw err;
|
|
150
|
+
});
|
|
151
|
+
held.catch(() => {});
|
|
152
|
+
facts.info = held;
|
|
153
|
+
return fresh;
|
|
154
|
+
},
|
|
155
|
+
/**
|
|
156
|
+
* Just the limits, which is what a caller almost always wants.
|
|
157
|
+
* @returns {Promise<ServerLimits>}
|
|
158
|
+
*/
|
|
159
|
+
limits: async () => {
|
|
160
|
+
// Through `self`: tsc types a bundle that names itself as
|
|
161
|
+
// `this.server` in its own methods `any` in the declarations.
|
|
162
|
+
const self = client;
|
|
163
|
+
return (await self.server.info()).limits;
|
|
164
|
+
},
|
|
165
|
+
/**
|
|
166
|
+
* Liveness, version and database size. Unauthenticated, and served
|
|
167
|
+
* outside the REST router at /health, so it answers even while the API
|
|
168
|
+
* is refusing requests. Never cached — the point is that it is current.
|
|
169
|
+
* @returns {Promise<ServerHealth>}
|
|
170
|
+
*/
|
|
171
|
+
health: () => PlaidClient.health(client.baseUrl, { timeout: client.timeout }),
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/** @param {import("./client.js").PlaidClient} client */
|
|
176
|
+
export function adminApi(client) {
|
|
177
|
+
return {
|
|
178
|
+
/**
|
|
179
|
+
* Everything about the server in one read: version and JVM uptime,
|
|
180
|
+
* database size and per-table row counts, media directory usage, backup
|
|
181
|
+
* configuration and the backups on disk, and the settings an operator
|
|
182
|
+
* gets asked to confirm. Carries no secrets. Runs a count per table and
|
|
183
|
+
* walks the media directory, so open it, do not poll it. Admin only.
|
|
184
|
+
* @returns {Promise<ServerReport>}
|
|
185
|
+
*/
|
|
186
|
+
server: () => client._request("GET", "/api/v1/admin/server"),
|
|
187
|
+
/**
|
|
188
|
+
* Take a database backup right now, outside the nightly schedule.
|
|
189
|
+
* Resolves to the backup block, with `ok` true, once the backup is
|
|
190
|
+
* written. A backup the server could not write rejects with status 500,
|
|
191
|
+
* and the error's `responseData` is the backup block with `ok` false (the
|
|
192
|
+
* reason is in the server log). Uses VACUUM INTO, which only reads, so it
|
|
193
|
+
* is safe while people are working. Admin only.
|
|
194
|
+
*
|
|
195
|
+
* The server answers once the backup is written, which takes minutes on
|
|
196
|
+
* a large database, so this waits up to `BACKUP_TIMEOUT_MS` (30 minutes)
|
|
197
|
+
* rather than the client's usual timeout. A proxy in front of the server
|
|
198
|
+
* may still give up first (a 504): the backup goes on, and its file
|
|
199
|
+
* shows in `server().backup.backups` once it is written.
|
|
200
|
+
* @returns {Promise<BackupStatus>}
|
|
201
|
+
*
|
|
202
|
+
* outOfBand, as every admin action on the server itself is: none of them
|
|
203
|
+
* writes project data (see the note at the top of http.js).
|
|
204
|
+
*/
|
|
205
|
+
backup: () =>
|
|
206
|
+
client._request("POST", "/api/v1/admin/backup", {
|
|
207
|
+
outOfBand: true,
|
|
208
|
+
timeout: BACKUP_TIMEOUT_MS,
|
|
209
|
+
}),
|
|
210
|
+
/**
|
|
211
|
+
* Documents currently held by an editing lock, with who holds each and
|
|
212
|
+
* when it expires on its own. Admin only.
|
|
213
|
+
* @returns {Promise<{entries: Array<{documentId: string, userId: string, expiresAt: number}>}>}
|
|
214
|
+
*/
|
|
215
|
+
locks: () => client._request("GET", "/api/v1/admin/locks"),
|
|
216
|
+
/**
|
|
217
|
+
* Drop the lock on a document whoever holds it. Idempotent. For a client
|
|
218
|
+
* that went away without releasing one. Admin only.
|
|
219
|
+
* @param {string} documentId - The document ID
|
|
220
|
+
* @returns {Promise<{result: string}>}
|
|
221
|
+
*/
|
|
222
|
+
releaseLock: (documentId) =>
|
|
223
|
+
client._request("DELETE", `/api/v1/admin/locks/${documentId}`, {
|
|
224
|
+
outOfBand: true,
|
|
225
|
+
}),
|
|
226
|
+
/**
|
|
227
|
+
* Live login and invite rate-limit buckets: the address, the account
|
|
228
|
+
* where there is one, failures inside the window, the limit, and whether
|
|
229
|
+
* it is currently blocking. Admin only.
|
|
230
|
+
* @returns {Promise<RateLimitSnapshot>}
|
|
231
|
+
*/
|
|
232
|
+
rateLimits: () => client._request("GET", "/api/v1/admin/rate-limits"),
|
|
233
|
+
/**
|
|
234
|
+
* Forget recorded rate-limit failures. With `ip`, clears that address,
|
|
235
|
+
* narrowed to one account with `userId`. With neither, clears every
|
|
236
|
+
* bucket. Only ever unblocks. Admin only.
|
|
237
|
+
* @param {object} [opts]
|
|
238
|
+
* @param {string} [opts.ip] - Clear only this address
|
|
239
|
+
* @param {string} [opts.userId] - Narrow to one account on that address
|
|
240
|
+
* @returns {Promise<{result: string}>}
|
|
241
|
+
*/
|
|
242
|
+
clearRateLimits: ({ ip, userId } = {}) =>
|
|
243
|
+
client._request("DELETE", "/api/v1/admin/rate-limits", {
|
|
244
|
+
outOfBand: true,
|
|
245
|
+
queryParams: { ip, "user-id": userId },
|
|
246
|
+
}),
|
|
247
|
+
/**
|
|
248
|
+
* What the server has logged, structured and filtered, from an in-memory
|
|
249
|
+
* buffer kept whether or not a log file is configured. `requests` is one
|
|
250
|
+
* entry per HTTP request (method, path, status, duration, and who made
|
|
251
|
+
* it), `events` is everything else, with a stack trace where there was
|
|
252
|
+
* one. They are buffered separately so a burst of requests cannot evict
|
|
253
|
+
* an error. Both come newest first, `matched` counts what passed the
|
|
254
|
+
* filters, and request `stats` describe the filtered set. Covers Plaid's
|
|
255
|
+
* own log stream since the last restart: for library messages and older
|
|
256
|
+
* history, see `logFile`. Admin only.
|
|
257
|
+
* @param {object} [opts]
|
|
258
|
+
* @param {number} [opts.limit] - Max entries per kind (default 200, max 2000)
|
|
259
|
+
* @param {string} [opts.q] - Substring of any field, case-insensitive
|
|
260
|
+
* @param {string} [opts.level] - Minimum level for events, e.g. "warn"
|
|
261
|
+
* @param {string} [opts.status] - "2xx".."5xx", an exact code, or "failures"
|
|
262
|
+
* @param {string} [opts.user] - Only requests made by this account
|
|
263
|
+
* @param {string} [opts.method] - Only requests with this HTTP method
|
|
264
|
+
* @returns {Promise<LiveLog>}
|
|
265
|
+
*/
|
|
266
|
+
logs: ({ limit, q, level, status, user, method } = {}) =>
|
|
267
|
+
client._request("GET", "/api/v1/admin/logs", {
|
|
268
|
+
queryParams: { limit, q, level, status, user, method },
|
|
269
|
+
}),
|
|
270
|
+
/**
|
|
271
|
+
* The tail of the configured log file, as text lines. The only place
|
|
272
|
+
* third-party library messages and anything from before the last restart
|
|
273
|
+
* can be read. Resolves with an `error` string instead of lines when no
|
|
274
|
+
* log file is configured or it does not exist yet. Admin only.
|
|
275
|
+
* @param {object} [opts]
|
|
276
|
+
* @param {number} [opts.lines] - How many lines (default 200, max 2000)
|
|
277
|
+
* @returns {Promise<{file: (string|null), lines: string[], error?: string}>}
|
|
278
|
+
*/
|
|
279
|
+
logFile: ({ lines } = {}) =>
|
|
280
|
+
client._request("GET", "/api/v1/admin/logs/file", {
|
|
281
|
+
queryParams: { lines },
|
|
282
|
+
}),
|
|
283
|
+
/**
|
|
284
|
+
* Private user-data entries across every account, each carrying its
|
|
285
|
+
* `userId`. `/users/:userId/data` has always been owner-or-admin; this
|
|
286
|
+
* is the same reach across accounts at once. Transparently follows
|
|
287
|
+
* pagination cursors and returns the full flat array. Admin only.
|
|
288
|
+
*
|
|
289
|
+
* Narrow with `prefix` (the literal head of a key) and/or `pattern`, a
|
|
290
|
+
* GLOB over the whole key (`*` any run, `?` one character) — the way to
|
|
291
|
+
* ask for a key convention identified by a segment in the middle, e.g.
|
|
292
|
+
* `igt:assistant:*:meta:*`. Values come only with `includeValues`, and
|
|
293
|
+
* are recased like any other body (see `userData.put`).
|
|
294
|
+
* @param {object} [opts]
|
|
295
|
+
* @param {string} [opts.prefix] - Only keys starting with this
|
|
296
|
+
* @param {string} [opts.pattern] - Only keys matching this GLOB
|
|
297
|
+
* @param {boolean} [opts.includeValues] - Also return each entry's value
|
|
298
|
+
* @returns {Promise<AdminUserDataEntry[]>}
|
|
299
|
+
*/
|
|
300
|
+
userData: ({ prefix, pattern, includeValues } = {}) =>
|
|
301
|
+
listAll(client, "/api/v1/admin/user-data", {
|
|
302
|
+
query: {
|
|
303
|
+
prefix,
|
|
304
|
+
pattern,
|
|
305
|
+
"include-values": includeValues,
|
|
306
|
+
},
|
|
307
|
+
}),
|
|
308
|
+
/**
|
|
309
|
+
* One page of private user-data entries across accounts, ordered by
|
|
310
|
+
* (user, key). Admin only.
|
|
311
|
+
* @param {object} [opts]
|
|
312
|
+
* @param {string} [opts.prefix] - Only keys starting with this
|
|
313
|
+
* @param {string} [opts.pattern] - Only keys matching this GLOB
|
|
314
|
+
* @param {boolean} [opts.includeValues] - Also return each entry's value
|
|
315
|
+
* @param {number} [opts.limit] - Page size (1..1000; server default 100)
|
|
316
|
+
* @param {string} [opts.cursor] - Opaque cursor from a previous page
|
|
317
|
+
* @returns {Promise<Page<AdminUserDataEntry>>}
|
|
318
|
+
*/
|
|
319
|
+
userDataPage: ({ prefix, pattern, includeValues, limit, cursor } = {}) =>
|
|
320
|
+
listPage(client, "/api/v1/admin/user-data", {
|
|
321
|
+
limit,
|
|
322
|
+
cursor,
|
|
323
|
+
query: {
|
|
324
|
+
prefix,
|
|
325
|
+
pattern,
|
|
326
|
+
"include-values": includeValues,
|
|
327
|
+
},
|
|
328
|
+
}),
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/** @param {import("./client.js").PlaidClient} client */
|
|
333
|
+
export function auditApi(client) {
|
|
334
|
+
return {
|
|
335
|
+
/**
|
|
336
|
+
* The audit log across every project, oldest first. Same fold, window
|
|
337
|
+
* and op-type filter as the per-project read, with the entity scope
|
|
338
|
+
* dropped. Admin only. Transparently follows pagination cursors and
|
|
339
|
+
* returns the full flat array.
|
|
340
|
+
* @param {object} [opts]
|
|
341
|
+
* @param {string} [opts.startTime] - Only operations at or after this instant
|
|
342
|
+
* @param {string} [opts.endTime] - Only operations at or before this instant
|
|
343
|
+
* @param {string[]|string} [opts.opTypes] - Only these op types (e.g.
|
|
344
|
+
* `['span-layer/create']`). An entry appears when one of its operations
|
|
345
|
+
* matches, carrying only the ones that did.
|
|
346
|
+
* @param {string[]|string} [opts.kinds] - Only the entries of operations
|
|
347
|
+
* of these kinds (e.g. `['review']`), each whole
|
|
348
|
+
* @returns {Promise<AuditEntry[]>}
|
|
349
|
+
*/
|
|
350
|
+
list: ({ startTime, endTime, opTypes, kinds } = {}) =>
|
|
351
|
+
listAll(client, "/api/v1/audit", {
|
|
352
|
+
query: auditQuery({ startTime, endTime, opTypes, kinds }),
|
|
353
|
+
}),
|
|
354
|
+
/**
|
|
355
|
+
* Fetch a single page of the instance-wide audit log. Admin only.
|
|
356
|
+
* @param {object} [opts]
|
|
357
|
+
* @param {string} [opts.startTime] - Only entries at or after this instant
|
|
358
|
+
* @param {string} [opts.endTime] - Only entries at or before this instant
|
|
359
|
+
* @param {string[]|string} [opts.opTypes] - Only these op types
|
|
360
|
+
* @param {OperationKind[]|string} [opts.kinds] - Only the entries of operations of these kinds, each whole
|
|
361
|
+
* @param {"asc"|"desc"} [opts.order] - "desc" pages newest-first, which
|
|
362
|
+
* is what a feed wants. A cursor belongs to the direction that made it.
|
|
363
|
+
* @param {number} [opts.limit] - Page size (1..1000; server default 100)
|
|
364
|
+
* @param {string} [opts.cursor] - Opaque cursor from a previous page
|
|
365
|
+
* @param {number} [opts.opsLimit] - Keep only each entry's oldest N
|
|
366
|
+
* operations in `ops` (1..1000). `opCount` on every entry says how
|
|
367
|
+
* many it has
|
|
368
|
+
* @param {string} [opts.entryId] - Read only this entry, not a page
|
|
369
|
+
* @returns {Promise<Page<AuditEntry>>}
|
|
370
|
+
*/
|
|
371
|
+
listPage: ({ startTime, endTime, opTypes, kinds, order, limit, cursor, opsLimit, entryId } = {}) =>
|
|
372
|
+
listPage(client, "/api/v1/audit", {
|
|
373
|
+
limit,
|
|
374
|
+
cursor,
|
|
375
|
+
query: auditQuery({ startTime, endTime, opTypes, kinds, order, opsLimit, entryId }),
|
|
376
|
+
}),
|
|
377
|
+
/**
|
|
378
|
+
* Async-iterate the instance-wide audit log page by page. Admin only.
|
|
379
|
+
* @param {object} [opts]
|
|
380
|
+
* @param {string} [opts.startTime] - Only entries at or after this instant
|
|
381
|
+
* @param {string} [opts.endTime] - Only entries at or before this instant
|
|
382
|
+
* @param {string[]|string} [opts.opTypes] - Only these op types
|
|
383
|
+
* @param {OperationKind[]|string} [opts.kinds] - Only the entries of operations of these kinds, each whole
|
|
384
|
+
* @param {number} [opts.pageSize] - Per-request page size
|
|
385
|
+
* @returns {AsyncGenerator<AuditEntry[]>}
|
|
386
|
+
*/
|
|
387
|
+
iterPages: ({ startTime, endTime, opTypes, kinds, pageSize } = {}) =>
|
|
388
|
+
iterPages(client, "/api/v1/audit", {
|
|
389
|
+
pageSize,
|
|
390
|
+
query: auditQuery({ startTime, endTime, opTypes, kinds }),
|
|
391
|
+
}),
|
|
392
|
+
/**
|
|
393
|
+
* Per-user activity counts. `changes` is the number of logical actions,
|
|
394
|
+
* folded the way the audit feed folds them, so one "Confirm word
|
|
395
|
+
* analysis" counts once however many rows it wrote; `operations` is the
|
|
396
|
+
* unfolded row count. Only users who did something appear — subtract
|
|
397
|
+
* from the roster you already hold to find the ones who did not.
|
|
398
|
+
*
|
|
399
|
+
* With `projectId`, scoped to that project and open to its maintainers.
|
|
400
|
+
* Without one, instance-wide and admin only.
|
|
401
|
+
* @param {object} [opts]
|
|
402
|
+
* @param {string} [opts.projectId] - Scope to one project
|
|
403
|
+
* @param {string} [opts.startTime] - Only count at or after this instant
|
|
404
|
+
* @param {string} [opts.endTime] - Only count at or before this instant
|
|
405
|
+
* @param {boolean} [opts.daily] - Also return `byDay`, a list of
|
|
406
|
+
* `{date, changes}` per user, oldest first, at the cost of a second
|
|
407
|
+
* grouped scan
|
|
408
|
+
* @returns {Promise<ActivityTallyRow[]>}
|
|
409
|
+
*/
|
|
410
|
+
tally: async ({ projectId, startTime, endTime, daily } = {}) => {
|
|
411
|
+
const path = projectId
|
|
412
|
+
? `/api/v1/projects/${projectId}/audit/tally`
|
|
413
|
+
: "/api/v1/audit/tally";
|
|
414
|
+
const result = await client._request("GET", path, {
|
|
415
|
+
queryParams: {
|
|
416
|
+
"start-time": startTime,
|
|
417
|
+
"end-time": endTime,
|
|
418
|
+
daily,
|
|
419
|
+
},
|
|
420
|
+
});
|
|
421
|
+
return result.entries;
|
|
422
|
+
},
|
|
423
|
+
};
|
|
424
|
+
}
|