arangojs 8.4.1 → 8.6.0

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/database.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Database = exports.isArangoDatabase = void 0;
3
+ exports.Database = exports.LogLevel = exports.isArangoDatabase = void 0;
4
4
  const analyzer_1 = require("./analyzer");
5
5
  const aql_1 = require("./aql");
6
6
  const collection_1 = require("./collection");
@@ -8,6 +8,7 @@ const connection_1 = require("./connection");
8
8
  const cursor_1 = require("./cursor");
9
9
  const error_1 = require("./error");
10
10
  const graph_1 = require("./graph");
11
+ const job_1 = require("./job");
11
12
  const codes_1 = require("./lib/codes");
12
13
  const multipart_1 = require("./lib/multipart");
13
14
  const route_1 = require("./route");
@@ -58,6 +59,17 @@ function coerceTransactionCollections(collections) {
58
59
  }
59
60
  return cols;
60
61
  }
62
+ /**
63
+ * Numeric representation of the logging level of a log entry.
64
+ */
65
+ var LogLevel;
66
+ (function (LogLevel) {
67
+ LogLevel[LogLevel["FATAL"] = 0] = "FATAL";
68
+ LogLevel[LogLevel["ERROR"] = 1] = "ERROR";
69
+ LogLevel[LogLevel["WARNING"] = 2] = "WARNING";
70
+ LogLevel[LogLevel["INFO"] = 3] = "INFO";
71
+ LogLevel[LogLevel["DEBUG"] = 4] = "DEBUG";
72
+ })(LogLevel = exports.LogLevel || (exports.LogLevel = {}));
61
73
  /**
62
74
  * An object representing a single ArangoDB database. All arangojs collections,
63
75
  * cursors, analyzers and so on are linked to a `Database` object.
@@ -124,6 +136,15 @@ class Database {
124
136
  qs: { details },
125
137
  });
126
138
  }
139
+ /**
140
+ * Retrives the server's current system time in milliseconds with microsecond
141
+ * precision.
142
+ */
143
+ time() {
144
+ return this.request({
145
+ path: "/_admin/time",
146
+ }, (res) => res.body.time * 1000);
147
+ }
127
148
  /**
128
149
  * Returns a new {@link route.Route} instance for the given path (relative to the
129
150
  * database) that can be used to perform arbitrary HTTP requests.
@@ -149,10 +170,78 @@ class Database {
149
170
  route(path, headers) {
150
171
  return new route_1.Route(this, path, headers);
151
172
  }
152
- request({ absolutePath = false, basePath, ...opts }, transform = (res) => res.body) {
173
+ /**
174
+ * Creates an async job by executing the given callback function. The first
175
+ * database request performed by the callback will be marked for asynchronous
176
+ * execution and its result will be made available as an async job.
177
+ *
178
+ * Returns a {@link Job} instance that can be used to retrieve the result
179
+ * of the callback function once the request has been executed.
180
+ *
181
+ * @param callback - Callback function to execute as an async job.
182
+ *
183
+ * @example
184
+ * ```js
185
+ * const db = new Database();
186
+ * const job = await db.createJob(() => db.collections());
187
+ * while (!job.isLoaded) {
188
+ * await timeout(1000);
189
+ * await job.load();
190
+ * }
191
+ * // job.result is a list of Collection instances
192
+ * ```
193
+ */
194
+ async createJob(callback) {
195
+ const trap = new Promise((resolveTrap) => {
196
+ this._trapRequest = (trapped) => resolveTrap(trapped);
197
+ });
198
+ const eventualResult = callback();
199
+ const trapped = await trap;
200
+ if (trapped.error)
201
+ return eventualResult;
202
+ const { jobId, onResolve, onReject } = trapped;
203
+ return new job_1.Job(this, jobId, (res) => {
204
+ onResolve(res);
205
+ return eventualResult;
206
+ }, (e) => {
207
+ onReject(e);
208
+ return eventualResult;
209
+ });
210
+ }
211
+ async request({ absolutePath = false, basePath, ...opts }, transform = (res) => res.body) {
153
212
  if (!absolutePath) {
154
213
  basePath = `/_db/${encodeURIComponent(this._name)}${basePath || ""}`;
155
214
  }
215
+ if (this._trapRequest) {
216
+ const trap = this._trapRequest;
217
+ this._trapRequest = undefined;
218
+ return new Promise(async (resolveRequest, rejectRequest) => {
219
+ const options = { ...opts };
220
+ options.headers = { ...options.headers, "x-arango-async": "store" };
221
+ let jobRes;
222
+ try {
223
+ jobRes = await this._connection.request({ basePath, ...options });
224
+ }
225
+ catch (e) {
226
+ trap({ error: true });
227
+ rejectRequest(e);
228
+ return;
229
+ }
230
+ const jobId = jobRes.headers["x-arango-async-id"];
231
+ trap({
232
+ jobId,
233
+ onResolve: (res) => {
234
+ const result = transform ? transform(res) : res;
235
+ resolveRequest(result);
236
+ return result;
237
+ },
238
+ onReject: (err) => {
239
+ rejectRequest(err);
240
+ throw err;
241
+ },
242
+ });
243
+ });
244
+ }
156
245
  return this._connection.request({ basePath, ...opts }, transform || undefined);
157
246
  }
158
247
  /**
@@ -218,6 +307,15 @@ class Database {
218
307
  close() {
219
308
  this._connection.close();
220
309
  }
310
+ /**
311
+ * Attempts to initiate a clean shutdown of the server.
312
+ */
313
+ shutdown() {
314
+ return this.request({
315
+ method: "DELETE",
316
+ path: "/_admin/shutdown",
317
+ }, () => undefined);
318
+ }
221
319
  async waitForPropagation({ basePath, ...request }, timeout) {
222
320
  await this._connection.waitForPropagation({
223
321
  ...request,
@@ -974,7 +1072,6 @@ class Database {
974
1072
  return analyzers.map((data) => this.analyzer(data.name));
975
1073
  }
976
1074
  //#endregion
977
- //#region users
978
1075
  /**
979
1076
  * Fetches all ArangoDB users visible to the authenticated user and returns
980
1077
  * an array of user objects.
@@ -2107,6 +2204,241 @@ class Database {
2107
2204
  qs: { replace },
2108
2205
  }, () => undefined);
2109
2206
  }
2207
+ //#endregion
2208
+ //#region hot backups
2209
+ /**
2210
+ * (Enterprise Edition only.) Creates a hot backup of the entire ArangoDB
2211
+ * deployment including all databases, collections, etc.
2212
+ *
2213
+ * Returns an object describing the backup result.
2214
+ *
2215
+ * @param options - Options for creating the backup.
2216
+ *
2217
+ * @example
2218
+ * ```js
2219
+ * const info = await db.createHotBackup();
2220
+ * // a hot backup has been created
2221
+ * ```
2222
+ */
2223
+ createHotBackup(options = {}) {
2224
+ return this.request({
2225
+ method: "POST",
2226
+ path: "/_admin/backup/create",
2227
+ body: options,
2228
+ }, (res) => res.body.result);
2229
+ }
2230
+ /**
2231
+ * (Enterprise Edition only.) Retrieves a list of all locally found hot
2232
+ * backups.
2233
+ *
2234
+ * @param id - If specified, only the backup with the given ID will be
2235
+ * returned.
2236
+ *
2237
+ * @example
2238
+ * ```js
2239
+ * const backups = await db.listHotBackups();
2240
+ * for (const backup of backups) {
2241
+ * console.log(backup.id);
2242
+ * }
2243
+ * ```
2244
+ */
2245
+ listHotBackups(id) {
2246
+ return this.request({
2247
+ method: "POST",
2248
+ path: "/_admin/backup/list",
2249
+ body: id ? { id } : undefined,
2250
+ }, (res) => res.body.result);
2251
+ }
2252
+ /**
2253
+ * (Enteprise Edition only.) Restores a consistent local hot backup.
2254
+ *
2255
+ * Returns the directory path of the restored backup.
2256
+ *
2257
+ * @param id - The ID of the backup to restore.
2258
+ *
2259
+ * @example
2260
+ * ```js
2261
+ * await db.restoreHotBackup("2023-09-19T15.38.21Z_example");
2262
+ * // the backup has been restored
2263
+ * ```
2264
+ */
2265
+ restoreHotBackup(id) {
2266
+ return this.request({
2267
+ method: "POST",
2268
+ path: "/_admin/backup/restore",
2269
+ body: { id },
2270
+ }, (res) => res.body.result.previous);
2271
+ }
2272
+ /**
2273
+ * (Enterprise Edition only.) Deletes a local hot backup.
2274
+ *
2275
+ * @param id - The ID of the backup to delete.
2276
+ *
2277
+ * @example
2278
+ * ```js
2279
+ * await db.deleteHotBackup("2023-09-19T15.38.21Z_example");
2280
+ * // the backup has been deleted
2281
+ * ```
2282
+ */
2283
+ deleteHotBackup(id) {
2284
+ return this.request({
2285
+ method: "POST",
2286
+ path: "/_admin/backup/delete",
2287
+ body: { id },
2288
+ }, () => undefined);
2289
+ }
2290
+ //#endregion
2291
+ //#region logs
2292
+ /**
2293
+ * Retrieves the log messages from the server's global log.
2294
+ *
2295
+ * @param options - Options for retrieving the log entries.
2296
+ *
2297
+ * @example
2298
+ * ```js
2299
+ * const log = await db.getLogEntries();
2300
+ * for (let i = 0; i < log.totalAmount; i++) {
2301
+ * console.log(`${
2302
+ * new Date(log.timestamp[i] * 1000).toISOString()
2303
+ * } - [${LogLevel[log.level[i]]}] ${log.text[i]} (#${log.lid[i]})`);
2304
+ * }
2305
+ * ```
2306
+ */
2307
+ getLogEntries(options) {
2308
+ return this.request({
2309
+ path: "/_admin/log",
2310
+ qs: options,
2311
+ }, (res) => res.body);
2312
+ }
2313
+ /**
2314
+ * Retrieves the log messages from the server's global log.
2315
+ *
2316
+ * @param options - Options for retrieving the log entries.
2317
+ *
2318
+ * @example
2319
+ * ```js
2320
+ * const messages = await db.getLogMessages();
2321
+ * for (const m of messages) {
2322
+ * console.log(`${m.date} - [${m.level}] ${m.message} (#${m.id})`);
2323
+ * }
2324
+ * ```
2325
+ */
2326
+ getLogMessages(options) {
2327
+ return this.request({
2328
+ path: "/_admin/log",
2329
+ qs: options,
2330
+ }, (res) => res.body.messages);
2331
+ }
2332
+ /**
2333
+ * Retrieves the server's current log level for each topic.
2334
+ *
2335
+ * @example
2336
+ * ```js
2337
+ * const levels = await db.getLogLevel();
2338
+ * console.log(levels.request); // log level for incoming requests
2339
+ * ```
2340
+ */
2341
+ getLogLevel() {
2342
+ return this.request({
2343
+ path: "/_admin/log/level",
2344
+ });
2345
+ }
2346
+ /**
2347
+ * Sets the server's log level for each of the given topics to the given level.
2348
+ *
2349
+ * Any omitted topics will be left unchanged.
2350
+ *
2351
+ * @param levels - An object mapping topic names to log levels.
2352
+ *
2353
+ * @example
2354
+ * ```js
2355
+ * await db.setLogLevel({ request: "debug" });
2356
+ * // Debug information will now be logged for each request
2357
+ * ```
2358
+ */
2359
+ setLogLevel(levels) {
2360
+ return this.request({
2361
+ method: "PUT",
2362
+ path: "/_admin/log/level",
2363
+ body: levels,
2364
+ });
2365
+ }
2366
+ //#endregion
2367
+ //#region async jobs
2368
+ /**
2369
+ * Returns a {@link job.Job} instance for the given `jobId`.
2370
+ *
2371
+ * @param jobId - ID of the async job.
2372
+ *
2373
+ * @example
2374
+ * ```js
2375
+ * const db = new Database();
2376
+ * const job = db.job("12345");
2377
+ * ```
2378
+ */
2379
+ job(jobId) {
2380
+ return new job_1.Job(this, jobId);
2381
+ }
2382
+ /**
2383
+ * Returns a list of the IDs of all currently pending async jobs.
2384
+ *
2385
+ * @example
2386
+ * ```js
2387
+ * const db = new Database();
2388
+ * const pendingJobs = await db.listPendingJobs();
2389
+ * console.log(pendingJobs); // e.g. ["12345", "67890"]
2390
+ * ```
2391
+ */
2392
+ listPendingJobs() {
2393
+ return this.request({
2394
+ path: "/_api/job/pending",
2395
+ }, (res) => res.body);
2396
+ }
2397
+ /**
2398
+ * Returns a list of the IDs of all currently available completed async jobs.
2399
+ *
2400
+ * @example
2401
+ * ```js
2402
+ * const db = new Database();
2403
+ * const completedJobs = await db.listCompletedJobs();
2404
+ * console.log(completedJobs); // e.g. ["12345", "67890"]
2405
+ * ```
2406
+ */
2407
+ listCompletedJobs() {
2408
+ return this.request({
2409
+ path: "/_api/job/done",
2410
+ }, (res) => res.body);
2411
+ }
2412
+ /**
2413
+ * Deletes the results of all completed async jobs created before the given
2414
+ * threshold.
2415
+ *
2416
+ * @param threshold - The expiration timestamp in milliseconds.
2417
+ *
2418
+ * @example
2419
+ * ```js
2420
+ * const db = new Database();
2421
+ * const ONE_WEEK = 7 * 24 * 60 * 60 * 1000;
2422
+ * await db.deleteExpiredJobResults(Date.now() - ONE_WEEK);
2423
+ * // all job results older than a week have been deleted
2424
+ * ```
2425
+ */
2426
+ deleteExpiredJobResults(threshold) {
2427
+ return this.request({
2428
+ method: "DELETE",
2429
+ path: `/_api/job/expired`,
2430
+ qs: { stamp: threshold / 1000 },
2431
+ }, () => undefined);
2432
+ }
2433
+ /**
2434
+ * Deletes the results of all completed async jobs.
2435
+ */
2436
+ deleteAllJobResults() {
2437
+ return this.request({
2438
+ method: "DELETE",
2439
+ path: `/_api/job/all`,
2440
+ }, () => undefined);
2441
+ }
2110
2442
  }
2111
2443
  exports.Database = Database;
2112
2444
  //# sourceMappingURL=database.js.map