@unofficialbox/box-open-sdk 0.7.1 → 0.9.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/dist/cjs/buildinfo.js +2 -2
- package/dist/cjs/client.js +11 -2
- package/dist/cjs/errors.js +3 -2
- package/dist/cjs/managers/authorization.js +15 -0
- package/dist/cjs/managers/events.js +27 -1
- package/dist/cjs/managers/web_links.js +26 -2
- package/dist/cjs/models/schemas/ai.js +1 -1
- package/dist/cjs/models/schemas/ai_studio.js +1 -1
- package/dist/cjs/models/schemas/app_item_associations.js +1 -1
- package/dist/cjs/models/schemas/archives.js +1 -1
- package/dist/cjs/models/schemas/authorization.js +1 -1
- package/dist/cjs/models/schemas/automate_workflows.js +1 -1
- package/dist/cjs/models/schemas/avatars.js +1 -1
- package/dist/cjs/models/schemas/chunked_uploads.js +1 -1
- package/dist/cjs/models/schemas/classifications.js +1 -1
- package/dist/cjs/models/schemas/collaboration_allowlist_entries.js +1 -1
- package/dist/cjs/models/schemas/collaboration_allowlist_exempt_targets.js +1 -1
- package/dist/cjs/models/schemas/collections.js +1 -1
- package/dist/cjs/models/schemas/comments.js +1 -1
- package/dist/cjs/models/schemas/device_pinners.js +1 -1
- package/dist/cjs/models/schemas/docgen.js +1 -1
- package/dist/cjs/models/schemas/docgen_template.js +1 -1
- package/dist/cjs/models/schemas/document_split.js +1 -1
- package/dist/cjs/models/schemas/email_aliases.js +1 -1
- package/dist/cjs/models/schemas/enterprise_configurations.js +1 -1
- package/dist/cjs/models/schemas/events.js +1 -1
- package/dist/cjs/models/schemas/external_users.js +1 -1
- package/dist/cjs/models/schemas/file_requests.js +1 -1
- package/dist/cjs/models/schemas/file_version_legal_holds.js +1 -1
- package/dist/cjs/models/schemas/file_version_retentions.js +1 -1
- package/dist/cjs/models/schemas/file_versions.js +1 -1
- package/dist/cjs/models/schemas/files.js +1 -1
- package/dist/cjs/models/schemas/folder_locks.js +1 -1
- package/dist/cjs/models/schemas/folders.js +1 -1
- package/dist/cjs/models/schemas/groups.js +1 -1
- package/dist/cjs/models/schemas/hub_collaborations.js +1 -1
- package/dist/cjs/models/schemas/hub_document.js +1 -1
- package/dist/cjs/models/schemas/hub_items.js +1 -1
- package/dist/cjs/models/schemas/hubs.js +1 -1
- package/dist/cjs/models/schemas/integration_mappings.js +1 -1
- package/dist/cjs/models/schemas/invites.js +1 -1
- package/dist/cjs/models/schemas/legal_hold_policies.js +1 -1
- package/dist/cjs/models/schemas/legal_hold_policy_assignments.js +1 -1
- package/dist/cjs/models/schemas/list_collaborations.js +1 -1
- package/dist/cjs/models/schemas/memberships.js +1 -1
- package/dist/cjs/models/schemas/metadata_cascade_policies.js +1 -1
- package/dist/cjs/models/schemas/metadata_taxonomies.js +1 -1
- package/dist/cjs/models/schemas/metadata_templates.js +1 -1
- package/dist/cjs/models/schemas/notes.js +1 -1
- package/dist/cjs/models/schemas/query.js +1 -1
- package/dist/cjs/models/schemas/recent_items.js +1 -1
- package/dist/cjs/models/schemas/retention_policies.js +1 -1
- package/dist/cjs/models/schemas/retention_policy_assignments.js +1 -1
- package/dist/cjs/models/schemas/search.js +1 -1
- package/dist/cjs/models/schemas/session_termination.js +1 -1
- package/dist/cjs/models/schemas/shared_links_folders.js +1 -1
- package/dist/cjs/models/schemas/shield_information_barrier_reports.js +1 -1
- package/dist/cjs/models/schemas/shield_information_barrier_segment_members.js +1 -1
- package/dist/cjs/models/schemas/shield_information_barrier_segment_restrictions.js +1 -1
- package/dist/cjs/models/schemas/shield_information_barrier_segments.js +1 -1
- package/dist/cjs/models/schemas/shield_information_barriers.js +1 -1
- package/dist/cjs/models/schemas/shield_lists.js +1 -1
- package/dist/cjs/models/schemas/shuttle.js +1 -1
- package/dist/cjs/models/schemas/sign_requests.js +1 -1
- package/dist/cjs/models/schemas/sign_templates.js +1 -1
- package/dist/cjs/models/schemas/skills.js +1 -1
- package/dist/cjs/models/schemas/storage_policies.js +1 -1
- package/dist/cjs/models/schemas/storage_policy_assignments.js +1 -1
- package/dist/cjs/models/schemas/task_assignments.js +1 -1
- package/dist/cjs/models/schemas/tasks.js +1 -1
- package/dist/cjs/models/schemas/terms_of_service_user_statuses.js +1 -1
- package/dist/cjs/models/schemas/terms_of_services.js +1 -1
- package/dist/cjs/models/schemas/transfer.js +1 -1
- package/dist/cjs/models/schemas/trashed_files.js +1 -1
- package/dist/cjs/models/schemas/trashed_folders.js +1 -1
- package/dist/cjs/models/schemas/trashed_items.js +1 -1
- package/dist/cjs/models/schemas/trashed_web_links.js +1 -1
- package/dist/cjs/models/schemas/uploads.js +1 -1
- package/dist/cjs/models/schemas/user_collaborations.js +1 -1
- package/dist/cjs/models/schemas/users.js +1 -1
- package/dist/cjs/models/schemas/web_links.js +1 -1
- package/dist/cjs/models/schemas/webhooks.js +1 -1
- package/dist/cjs/models/schemas/workflows.js +1 -1
- package/dist/cjs/models/schemas/zip_downloads.js +1 -1
- package/dist/cjs/models/schemas.js +1 -1
- package/dist/cjs/runtime.js +127 -0
- package/dist/cjs/webhooks.js +113 -0
- package/dist/esm/buildinfo.js +2 -2
- package/dist/esm/client.js +11 -2
- package/dist/esm/errors.js +3 -2
- package/dist/esm/managers/authorization.js +15 -0
- package/dist/esm/managers/events.js +27 -1
- package/dist/esm/managers/web_links.js +26 -2
- package/dist/esm/models/schemas/ai.js +1 -1
- package/dist/esm/models/schemas/ai_studio.js +1 -1
- package/dist/esm/models/schemas/app_item_associations.js +1 -1
- package/dist/esm/models/schemas/archives.js +1 -1
- package/dist/esm/models/schemas/authorization.js +1 -1
- package/dist/esm/models/schemas/automate_workflows.js +1 -1
- package/dist/esm/models/schemas/avatars.js +1 -1
- package/dist/esm/models/schemas/chunked_uploads.js +1 -1
- package/dist/esm/models/schemas/classifications.js +1 -1
- package/dist/esm/models/schemas/collaboration_allowlist_entries.js +1 -1
- package/dist/esm/models/schemas/collaboration_allowlist_exempt_targets.js +1 -1
- package/dist/esm/models/schemas/collections.js +1 -1
- package/dist/esm/models/schemas/comments.js +1 -1
- package/dist/esm/models/schemas/device_pinners.js +1 -1
- package/dist/esm/models/schemas/docgen.js +1 -1
- package/dist/esm/models/schemas/docgen_template.js +1 -1
- package/dist/esm/models/schemas/document_split.js +1 -1
- package/dist/esm/models/schemas/email_aliases.js +1 -1
- package/dist/esm/models/schemas/enterprise_configurations.js +1 -1
- package/dist/esm/models/schemas/events.js +1 -1
- package/dist/esm/models/schemas/external_users.js +1 -1
- package/dist/esm/models/schemas/file_requests.js +1 -1
- package/dist/esm/models/schemas/file_version_legal_holds.js +1 -1
- package/dist/esm/models/schemas/file_version_retentions.js +1 -1
- package/dist/esm/models/schemas/file_versions.js +1 -1
- package/dist/esm/models/schemas/files.js +1 -1
- package/dist/esm/models/schemas/folder_locks.js +1 -1
- package/dist/esm/models/schemas/folders.js +1 -1
- package/dist/esm/models/schemas/groups.js +1 -1
- package/dist/esm/models/schemas/hub_collaborations.js +1 -1
- package/dist/esm/models/schemas/hub_document.js +1 -1
- package/dist/esm/models/schemas/hub_items.js +1 -1
- package/dist/esm/models/schemas/hubs.js +1 -1
- package/dist/esm/models/schemas/integration_mappings.js +1 -1
- package/dist/esm/models/schemas/invites.js +1 -1
- package/dist/esm/models/schemas/legal_hold_policies.js +1 -1
- package/dist/esm/models/schemas/legal_hold_policy_assignments.js +1 -1
- package/dist/esm/models/schemas/list_collaborations.js +1 -1
- package/dist/esm/models/schemas/memberships.js +1 -1
- package/dist/esm/models/schemas/metadata_cascade_policies.js +1 -1
- package/dist/esm/models/schemas/metadata_taxonomies.js +1 -1
- package/dist/esm/models/schemas/metadata_templates.js +1 -1
- package/dist/esm/models/schemas/notes.js +1 -1
- package/dist/esm/models/schemas/query.js +1 -1
- package/dist/esm/models/schemas/recent_items.js +1 -1
- package/dist/esm/models/schemas/retention_policies.js +1 -1
- package/dist/esm/models/schemas/retention_policy_assignments.js +1 -1
- package/dist/esm/models/schemas/search.js +1 -1
- package/dist/esm/models/schemas/session_termination.js +1 -1
- package/dist/esm/models/schemas/shared_links_folders.js +1 -1
- package/dist/esm/models/schemas/shield_information_barrier_reports.js +1 -1
- package/dist/esm/models/schemas/shield_information_barrier_segment_members.js +1 -1
- package/dist/esm/models/schemas/shield_information_barrier_segment_restrictions.js +1 -1
- package/dist/esm/models/schemas/shield_information_barrier_segments.js +1 -1
- package/dist/esm/models/schemas/shield_information_barriers.js +1 -1
- package/dist/esm/models/schemas/shield_lists.js +1 -1
- package/dist/esm/models/schemas/shuttle.js +1 -1
- package/dist/esm/models/schemas/sign_requests.js +1 -1
- package/dist/esm/models/schemas/sign_templates.js +1 -1
- package/dist/esm/models/schemas/skills.js +1 -1
- package/dist/esm/models/schemas/storage_policies.js +1 -1
- package/dist/esm/models/schemas/storage_policy_assignments.js +1 -1
- package/dist/esm/models/schemas/task_assignments.js +1 -1
- package/dist/esm/models/schemas/tasks.js +1 -1
- package/dist/esm/models/schemas/terms_of_service_user_statuses.js +1 -1
- package/dist/esm/models/schemas/terms_of_services.js +1 -1
- package/dist/esm/models/schemas/transfer.js +1 -1
- package/dist/esm/models/schemas/trashed_files.js +1 -1
- package/dist/esm/models/schemas/trashed_folders.js +1 -1
- package/dist/esm/models/schemas/trashed_items.js +1 -1
- package/dist/esm/models/schemas/trashed_web_links.js +1 -1
- package/dist/esm/models/schemas/uploads.js +1 -1
- package/dist/esm/models/schemas/user_collaborations.js +1 -1
- package/dist/esm/models/schemas/users.js +1 -1
- package/dist/esm/models/schemas/web_links.js +1 -1
- package/dist/esm/models/schemas/webhooks.js +1 -1
- package/dist/esm/models/schemas/workflows.js +1 -1
- package/dist/esm/models/schemas/zip_downloads.js +1 -1
- package/dist/esm/models/schemas.js +1 -1
- package/dist/esm/runtime.js +124 -0
- package/dist/esm/webhooks.js +109 -0
- package/dist/types/buildinfo.d.ts +1 -1
- package/dist/types/client.d.ts +9 -3
- package/dist/types/managers/authorization.d.ts +6 -0
- package/dist/types/managers/events.d.ts +4 -0
- package/dist/types/managers/web_links.d.ts +14 -2
- package/dist/types/runtime.d.ts +41 -0
- package/dist/types/webhooks.d.ts +24 -0
- package/docs/README.md +1 -0
- package/docs/auth.md +35 -8
- package/docs/errors.md +2 -2
- package/docs/managers/web_links.md +3 -0
- package/docs/pagination.md +17 -1
- package/docs/webhooks.md +34 -0
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// Code generated by box-gantry 0.1.0 (spec
|
|
2
|
+
// Code generated by box-gantry 0.1.0 (spec 21e020ceb5dcf964) for Box API 2024.0. DO NOT EDIT.
|
|
3
3
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
4
|
if (k2 === undefined) k2 = k;
|
|
5
5
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
package/dist/cjs/runtime.js
CHANGED
|
@@ -26,11 +26,15 @@ exports.responseBytes = responseBytes;
|
|
|
26
26
|
exports.responseStream = responseStream;
|
|
27
27
|
exports.responseHeader = responseHeader;
|
|
28
28
|
exports.statusCode = statusCode;
|
|
29
|
+
exports.eventStream = eventStream;
|
|
30
|
+
exports.streamPosition = streamPosition;
|
|
31
|
+
exports.parseJsonExact = parseJsonExact;
|
|
29
32
|
const errors_js_1 = require("./errors.js");
|
|
30
33
|
var errors_js_2 = require("./errors.js");
|
|
31
34
|
Object.defineProperty(exports, "BoxApiError", { enumerable: true, get: function () { return errors_js_2.BoxApiError; } });
|
|
32
35
|
Object.defineProperty(exports, "isPreconditionFailed", { enumerable: true, get: function () { return errors_js_2.isPreconditionFailed; } });
|
|
33
36
|
__exportStar(require("./auth.js"), exports);
|
|
37
|
+
__exportStar(require("./webhooks.js"), exports);
|
|
34
38
|
/** The default base URLs for the D-106 URL classes. */
|
|
35
39
|
const DEFAULT_BASE_URLS = {
|
|
36
40
|
api: 'https://api.box.com/2.0',
|
|
@@ -100,6 +104,20 @@ class Client {
|
|
|
100
104
|
this.fetchImpl = options.fetch ?? fetch;
|
|
101
105
|
this.defaultHeaders = { ...(options.headers ?? {}) };
|
|
102
106
|
}
|
|
107
|
+
/** A new client that sends `As-User: userId` with every API request, so Box
|
|
108
|
+
* acts as that user (an admin, or a service account whose app may "make API
|
|
109
|
+
* calls using the as-user header"). It shares this client's auth flow and
|
|
110
|
+
* token cache, `fetch`, base URLs, and retry policy; this client is
|
|
111
|
+
* unchanged. Token requests never carry the header. */
|
|
112
|
+
withAsUserHeader(userId) {
|
|
113
|
+
const headers = Object.fromEntries(Object.entries(this.defaultHeaders).filter(([name]) => name.toLowerCase() !== 'as-user'));
|
|
114
|
+
return new Client(this.auth, {
|
|
115
|
+
maxRetries: this.maxRetries,
|
|
116
|
+
baseUrls: this.baseUrls,
|
|
117
|
+
fetch: this.fetchImpl,
|
|
118
|
+
headers: { ...headers, 'As-User': userId },
|
|
119
|
+
});
|
|
120
|
+
}
|
|
103
121
|
/** The configured base URL for a D-106 class, without a trailing slash. */
|
|
104
122
|
baseUrl(name) {
|
|
105
123
|
return this.baseUrls[name] ?? '';
|
|
@@ -317,3 +335,112 @@ function responseHeader(response, name) {
|
|
|
317
335
|
function statusCode(response) {
|
|
318
336
|
return response.status;
|
|
319
337
|
}
|
|
338
|
+
const DEFAULT_LONG_POLL_RETRIES = 10;
|
|
339
|
+
const DEFAULT_LONG_POLL_TIMEOUT_SECONDS = 610;
|
|
340
|
+
/** Box may deliver an event twice; this many recent event ids are kept to drop
|
|
341
|
+
* the repeats (the bound Box's own SDKs use). */
|
|
342
|
+
const MAX_SEEN_EVENTS = 1000;
|
|
343
|
+
/**
|
|
344
|
+
* Follow Box's long-poll protocol from `position` (`'now'` for events from
|
|
345
|
+
* here on): yield the events after it, each once, then wait on a real-time
|
|
346
|
+
* server until Box reports a change and yield those. A `reconnect` answer, or
|
|
347
|
+
* exhausting the server's retries, lists a fresh server. A long poll that times
|
|
348
|
+
* out or fails in transit is retried; an error response from Box ends the
|
|
349
|
+
* stream by throwing it, and aborting `signal` throws the abort.
|
|
350
|
+
*/
|
|
351
|
+
async function* eventStream(client, position, source, signal) {
|
|
352
|
+
let seen = new Set();
|
|
353
|
+
let server;
|
|
354
|
+
let retries = 0;
|
|
355
|
+
for (;;) {
|
|
356
|
+
const { events, next } = await source.page(position);
|
|
357
|
+
for (const event of events) {
|
|
358
|
+
const id = source.id(event);
|
|
359
|
+
if (id !== undefined) {
|
|
360
|
+
if (seen.has(id)) {
|
|
361
|
+
continue;
|
|
362
|
+
}
|
|
363
|
+
seen.add(id);
|
|
364
|
+
}
|
|
365
|
+
yield event;
|
|
366
|
+
}
|
|
367
|
+
if (seen.size >= MAX_SEEN_EVENTS) {
|
|
368
|
+
// Repeats arrive close together: keep only this page's ids.
|
|
369
|
+
seen = new Set();
|
|
370
|
+
for (const event of events) {
|
|
371
|
+
const id = source.id(event);
|
|
372
|
+
if (id !== undefined) {
|
|
373
|
+
seen.add(id);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
if (next !== undefined && next !== '') {
|
|
378
|
+
position = next;
|
|
379
|
+
}
|
|
380
|
+
// Wait for Box to report a change after `position`.
|
|
381
|
+
for (let changed = false; !changed;) {
|
|
382
|
+
if (server === undefined || retries >= server.maxRetries) {
|
|
383
|
+
const listed = await source.server();
|
|
384
|
+
server = {
|
|
385
|
+
url: listed.url,
|
|
386
|
+
maxRetries: positiveOr(listed.maxRetries, DEFAULT_LONG_POLL_RETRIES),
|
|
387
|
+
retryTimeoutSeconds: positiveOr(listed.retryTimeoutSeconds, DEFAULT_LONG_POLL_TIMEOUT_SECONDS),
|
|
388
|
+
};
|
|
389
|
+
retries = 0;
|
|
390
|
+
}
|
|
391
|
+
retries++;
|
|
392
|
+
let message;
|
|
393
|
+
try {
|
|
394
|
+
message = await longPoll(client, server, position, signal);
|
|
395
|
+
}
|
|
396
|
+
catch (err) {
|
|
397
|
+
if (signal?.aborted || (err instanceof errors_js_1.BoxApiError && err.status !== undefined)) {
|
|
398
|
+
throw err;
|
|
399
|
+
}
|
|
400
|
+
// Timed out or failed in transit: poll again.
|
|
401
|
+
continue;
|
|
402
|
+
}
|
|
403
|
+
if (message === 'new_change') {
|
|
404
|
+
changed = true;
|
|
405
|
+
}
|
|
406
|
+
else if (message === 'reconnect' || message === 'max_retries') {
|
|
407
|
+
server = undefined;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
function positiveOr(value, fallback) {
|
|
413
|
+
return value !== undefined && value > 0 ? value : fallback;
|
|
414
|
+
}
|
|
415
|
+
/** Wait on a real-time server for Box's next message about the stream after
|
|
416
|
+
* `position`: `new_change`, `reconnect`, or `max_retries`. */
|
|
417
|
+
async function longPoll(client, server, position, signal) {
|
|
418
|
+
const separator = server.url.includes('?') ? '&' : '?';
|
|
419
|
+
const url = `${server.url}${separator}stream_position=${encodeURIComponent(position)}`;
|
|
420
|
+
const timeout = AbortSignal.timeout(server.retryTimeoutSeconds * 1000);
|
|
421
|
+
const response = await client.fetch(client.newRequest('GET', url), signal === undefined ? timeout : AbortSignal.any([signal, timeout]));
|
|
422
|
+
const answer = JSON.parse(new TextDecoder().decode(response.bodyBytes));
|
|
423
|
+
if (typeof answer === 'object' && answer !== null && 'message' in answer) {
|
|
424
|
+
return typeof answer.message === 'string' ? answer.message : undefined;
|
|
425
|
+
}
|
|
426
|
+
return undefined;
|
|
427
|
+
}
|
|
428
|
+
/** A stream position Box sent as a JSON string or number, as the string to
|
|
429
|
+
* send back. */
|
|
430
|
+
function streamPosition(value) {
|
|
431
|
+
if (typeof value === 'string') {
|
|
432
|
+
return value;
|
|
433
|
+
}
|
|
434
|
+
return typeof value === 'number' || typeof value === 'bigint' ? String(value) : undefined;
|
|
435
|
+
}
|
|
436
|
+
/** `JSON.parse`, except an integer too large for a `number` keeps its exact
|
|
437
|
+
* digits as a string — a stream position must round-trip unchanged. */
|
|
438
|
+
function parseJsonExact(text) {
|
|
439
|
+
const reviver = (_key, value, context) => typeof value === 'number' &&
|
|
440
|
+
!Number.isSafeInteger(value) &&
|
|
441
|
+
context?.source !== undefined &&
|
|
442
|
+
/^-?\d+$/.test(context.source)
|
|
443
|
+
? context.source
|
|
444
|
+
: value;
|
|
445
|
+
return JSON.parse(text, reviver);
|
|
446
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Code generated by box-gantry (vendored from runtimes/typescript/gantryruntime/src/webhooks.ts). DO NOT EDIT.
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.DEFAULT_WEBHOOK_MAX_AGE_SECONDS = void 0;
|
|
5
|
+
exports.verifyWebhook = verifyWebhook;
|
|
6
|
+
// Box webhook signature verification (Box's v2 scheme). Each
|
|
7
|
+
// `BOX-SIGNATURE-*` header of a delivery is the base64 HMAC-SHA256, under that
|
|
8
|
+
// signature key, of the body followed by the `BOX-DELIVERY-TIMESTAMP` header.
|
|
9
|
+
// Built on WebCrypto (`crypto.subtle`), so it runs in Node and browsers alike
|
|
10
|
+
// and needs no `node:crypto`; `subtle.verify` compares in constant time.
|
|
11
|
+
/** How old a delivery may be, in seconds, before it's rejected as a possible
|
|
12
|
+
* replay: Box's ten minutes. */
|
|
13
|
+
exports.DEFAULT_WEBHOOK_MAX_AGE_SECONDS = 600;
|
|
14
|
+
/**
|
|
15
|
+
* Whether `body` and `headers` are a genuine, recent delivery from Box. Pass
|
|
16
|
+
* the body exactly as received; header names match in any case. Resolves
|
|
17
|
+
* `false` for an unknown signature version or algorithm, a delivery older than
|
|
18
|
+
* the maximum age or timestamped in the future, and a signature no configured
|
|
19
|
+
* key produces.
|
|
20
|
+
*/
|
|
21
|
+
async function verifyWebhook(body, headers, keys) {
|
|
22
|
+
const header = (name) => {
|
|
23
|
+
if (headers instanceof Headers) {
|
|
24
|
+
return headers.get(name) ?? undefined;
|
|
25
|
+
}
|
|
26
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
27
|
+
if (key.toLowerCase() === name) {
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return undefined;
|
|
32
|
+
};
|
|
33
|
+
if (header('box-signature-version') !== '1' || header('box-signature-algorithm') !== 'HmacSHA256') {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
const timestamp = header('box-delivery-timestamp');
|
|
37
|
+
const sentMs = timestamp === undefined ? NaN : Date.parse(timestamp);
|
|
38
|
+
if (Number.isNaN(sentMs)) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
// Whole seconds, as Box's own SDKs compare them.
|
|
42
|
+
const sent = Math.floor(sentMs / 1000);
|
|
43
|
+
const at = Math.floor((keys.now ?? new Date()).getTime() / 1000);
|
|
44
|
+
if (sent > at || at - sent > (keys.maxAgeSeconds ?? exports.DEFAULT_WEBHOOK_MAX_AGE_SECONDS)) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
const encoder = new TextEncoder();
|
|
48
|
+
const raw = typeof body === 'string' ? encoder.encode(body) : Uint8Array.from(body);
|
|
49
|
+
const bodies = [raw];
|
|
50
|
+
const escaped = escapeNonAscii(raw);
|
|
51
|
+
if (escaped !== undefined) {
|
|
52
|
+
bodies.push(encoder.encode(escaped));
|
|
53
|
+
}
|
|
54
|
+
const stamp = encoder.encode(timestamp);
|
|
55
|
+
const signed = [
|
|
56
|
+
[keys.primaryKey, 'box-signature-primary'],
|
|
57
|
+
[keys.secondaryKey, 'box-signature-secondary'],
|
|
58
|
+
];
|
|
59
|
+
for (const [key, name] of signed) {
|
|
60
|
+
const received = decodeBase64(header(name));
|
|
61
|
+
if (key === undefined || key === '' || received === undefined) {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
const hmac = await crypto.subtle.importKey('raw', encoder.encode(key), { name: 'HMAC', hash: 'SHA-256' }, false, ['verify']);
|
|
65
|
+
for (const candidate of bodies) {
|
|
66
|
+
const message = new Uint8Array(candidate.length + stamp.length);
|
|
67
|
+
message.set(candidate);
|
|
68
|
+
message.set(stamp, candidate.length);
|
|
69
|
+
if (await crypto.subtle.verify('HMAC', hmac, received, message)) {
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
/** Standard base64 to bytes; `undefined` when absent, empty, or malformed. */
|
|
77
|
+
function decodeBase64(value) {
|
|
78
|
+
if (value === undefined || value === '') {
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
return Uint8Array.from(atob(value), (c) => c.charCodeAt(0));
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
return undefined;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/** `body` with every character from U+007F up written as a JSON `\uXXXX`
|
|
89
|
+
* escape (UTF-16, lowercase hex) — the form Box signs. A body re-encoded as
|
|
90
|
+
* raw UTF-8 on its way to the caller verifies through it. `undefined` when
|
|
91
|
+
* `body` is already all ASCII, or is not UTF-8. */
|
|
92
|
+
function escapeNonAscii(body) {
|
|
93
|
+
let text;
|
|
94
|
+
try {
|
|
95
|
+
text = new TextDecoder('utf-8', { fatal: true }).decode(body);
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return undefined;
|
|
99
|
+
}
|
|
100
|
+
let out = '';
|
|
101
|
+
let escaped = false;
|
|
102
|
+
for (let i = 0; i < text.length; i++) {
|
|
103
|
+
const unit = text.charCodeAt(i);
|
|
104
|
+
if (unit < 0x7f) {
|
|
105
|
+
out += text[i];
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
escaped = true;
|
|
109
|
+
out += `\\u${unit.toString(16).padStart(4, '0')}`;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return escaped ? out : undefined;
|
|
113
|
+
}
|
package/dist/esm/buildinfo.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
// Code generated by box-gantry 0.1.0 (spec
|
|
1
|
+
// Code generated by box-gantry 0.1.0 (spec 21e020ceb5dcf964). DO NOT EDIT.
|
|
2
2
|
/** The box-gantry engine version that generated this SDK. */
|
|
3
3
|
export const ENGINE = "0.1.0";
|
|
4
4
|
/** Fingerprint of the input spec set. */
|
|
5
|
-
export const SPEC_FINGERPRINT = "
|
|
5
|
+
export const SPEC_FINGERPRINT = "21e020ceb5dcf964";
|
|
6
6
|
/** The target language key (FR-4). */
|
|
7
7
|
export const TARGET = "typescript";
|
package/dist/esm/client.js
CHANGED
|
@@ -178,10 +178,13 @@ export class Client {
|
|
|
178
178
|
webhooks;
|
|
179
179
|
workflows;
|
|
180
180
|
zipDownloads;
|
|
181
|
+
#session;
|
|
181
182
|
/** Build a client for an authentication flow; `options` configures the
|
|
182
|
-
* runtime session (retries, `fetch`, default headers, base URLs).
|
|
183
|
+
* runtime session (retries, `fetch`, default headers, base URLs). An
|
|
184
|
+
* already configured runtime session is used as is. */
|
|
183
185
|
constructor(auth, options = {}) {
|
|
184
|
-
const session = new Session(auth, options);
|
|
186
|
+
const session = auth instanceof Session ? auth : new Session(auth, options);
|
|
187
|
+
this.#session = session;
|
|
185
188
|
this.ai = new AiManager(session);
|
|
186
189
|
this.aiStudio = new AiStudioManager(session);
|
|
187
190
|
this.appItemAssociations = new AppItemAssociationsManager(session);
|
|
@@ -271,4 +274,10 @@ export class Client {
|
|
|
271
274
|
this.workflows = new WorkflowsManager(session);
|
|
272
275
|
this.zipDownloads = new ZipDownloadsManager(session);
|
|
273
276
|
}
|
|
277
|
+
/** A new client whose every API call acts as the user `userId` (Box's
|
|
278
|
+
* `As-User` header). It shares this client's auth and configuration;
|
|
279
|
+
* this client is unchanged. */
|
|
280
|
+
withAsUserHeader(userId) {
|
|
281
|
+
return new Client(this.#session.withAsUserHeader(userId));
|
|
282
|
+
}
|
|
274
283
|
}
|
package/dist/esm/errors.js
CHANGED
|
@@ -51,8 +51,9 @@ export function apiErrorFromResponse(status, body) {
|
|
|
51
51
|
const value = payload[key];
|
|
52
52
|
return typeof value === 'string' ? value : undefined;
|
|
53
53
|
};
|
|
54
|
-
|
|
55
|
-
const
|
|
54
|
+
// A Box error object, or from the token endpoint an OAuth 2.0 error.
|
|
55
|
+
const code = field('code') ?? field('error');
|
|
56
|
+
const boxMessage = field('message') ?? field('error_description');
|
|
56
57
|
const requestId = field('request_id');
|
|
57
58
|
let message = `box: status ${status}`;
|
|
58
59
|
if (code !== undefined) {
|
|
@@ -109,4 +109,19 @@ export class AuthorizationManager {
|
|
|
109
109
|
req = runtime.withFormBody(req, new TextEncoder().encode(formEncode(form)));
|
|
110
110
|
await this.session.fetch(req);
|
|
111
111
|
}
|
|
112
|
+
/** Exchange the session's current access token for one limited to `scopes`
|
|
113
|
+
* and, when given, to one item (`resource`: its API URL, e.g.
|
|
114
|
+
* `https://api.box.com/2.0/files/123`) or a shared link. The result is a plain
|
|
115
|
+
* access token with no refresh token: build a client from it with
|
|
116
|
+
* `auth.developerToken`. */
|
|
117
|
+
async downscopeToken(scopes, resource, sharedLink) {
|
|
118
|
+
return this.createOauth2Token({
|
|
119
|
+
grant_type: "urn:ietf:params:oauth:grant-type:token-exchange",
|
|
120
|
+
subject_token: await this.session.accessToken(),
|
|
121
|
+
subject_token_type: "urn:ietf:params:oauth:token-type:access_token",
|
|
122
|
+
scope: scopes.join(' '),
|
|
123
|
+
...(resource === undefined ? {} : { resource: resource }),
|
|
124
|
+
...(sharedLink === undefined ? {} : { box_shared_link: sharedLink }),
|
|
125
|
+
});
|
|
126
|
+
}
|
|
112
127
|
}
|
|
@@ -32,7 +32,7 @@ export class EventsManager {
|
|
|
32
32
|
}
|
|
33
33
|
const resp = await this.session.fetch(req);
|
|
34
34
|
const data = runtime.responseBytes(resp);
|
|
35
|
-
return
|
|
35
|
+
return runtime.parseJsonExact(new TextDecoder().decode(data));
|
|
36
36
|
}
|
|
37
37
|
async options() {
|
|
38
38
|
let url = this.session.baseUrl("api");
|
|
@@ -42,4 +42,30 @@ export class EventsManager {
|
|
|
42
42
|
const data = runtime.responseBytes(resp);
|
|
43
43
|
return JSON.parse(new TextDecoder().decode(data));
|
|
44
44
|
}
|
|
45
|
+
/** Box's long-poll event stream from `opts.stream_position` (`'now'` when
|
|
46
|
+
* unset): yields each event once, then waits on a real-time server for the
|
|
47
|
+
* next change. It rejects when a call fails; aborting `signal` stops it. */
|
|
48
|
+
stream(opts, signal) {
|
|
49
|
+
const options = { ...opts };
|
|
50
|
+
return runtime.eventStream(this.session, options.stream_position ?? 'now', {
|
|
51
|
+
server: async () => {
|
|
52
|
+
const listed = await this.options();
|
|
53
|
+
for (const s of listed.entries ?? []) {
|
|
54
|
+
if (s.url !== undefined) {
|
|
55
|
+
return {
|
|
56
|
+
url: s.url,
|
|
57
|
+
maxRetries: s.max_retries === undefined ? undefined : Number(s.max_retries),
|
|
58
|
+
retryTimeoutSeconds: s.retry_timeout,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
throw new runtime.BoxApiError('box: no real-time server to long-poll');
|
|
63
|
+
},
|
|
64
|
+
page: async (position) => {
|
|
65
|
+
const page = await this.list({ ...options, stream_position: position });
|
|
66
|
+
return { events: page.entries ?? [], next: runtime.streamPosition(page.next_stream_position) };
|
|
67
|
+
},
|
|
68
|
+
id: (event) => event.event_id,
|
|
69
|
+
}, signal);
|
|
70
|
+
}
|
|
45
71
|
}
|
|
@@ -26,26 +26,50 @@ export class WebLinksManager {
|
|
|
26
26
|
if (options.boxapi !== undefined) {
|
|
27
27
|
req = runtime.withHeader(req, "boxapi", options.boxapi);
|
|
28
28
|
}
|
|
29
|
+
if (options["if-none-match"] !== undefined) {
|
|
30
|
+
req = runtime.withHeader(req, "if-none-match", options["if-none-match"]);
|
|
31
|
+
}
|
|
29
32
|
const resp = await this.session.fetch(req);
|
|
30
33
|
const data = runtime.responseBytes(resp);
|
|
31
34
|
return JSON.parse(new TextDecoder().decode(data));
|
|
32
35
|
}
|
|
33
|
-
|
|
36
|
+
/** `get` with `If-None-Match` set to `etag`: resolves `undefined` when
|
|
37
|
+
* the item is unchanged since `etag` (Box answers 304 Not Modified). */
|
|
38
|
+
async getIfModified(webLinkId, etag, opts) {
|
|
39
|
+
try {
|
|
40
|
+
return await this.get(webLinkId, { ...opts, "if-none-match": etag });
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
if (err instanceof runtime.BoxApiError && err.status === 304) {
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
throw err;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
async update(webLinkId, body, opts) {
|
|
34
50
|
let url = this.session.baseUrl("api");
|
|
35
51
|
url += "/web_links";
|
|
36
52
|
url += '/' + pathEscape(webLinkId);
|
|
37
53
|
let req = this.session.newRequest("PUT", url);
|
|
54
|
+
const options = opts ?? {};
|
|
55
|
+
if (options["if-match"] !== undefined) {
|
|
56
|
+
req = runtime.withHeader(req, "if-match", options["if-match"]);
|
|
57
|
+
}
|
|
38
58
|
const payload = new TextEncoder().encode(JSON.stringify(body));
|
|
39
59
|
req = runtime.withJsonBody(req, payload);
|
|
40
60
|
const resp = await this.session.fetch(req);
|
|
41
61
|
const data = runtime.responseBytes(resp);
|
|
42
62
|
return JSON.parse(new TextDecoder().decode(data));
|
|
43
63
|
}
|
|
44
|
-
async delete_(webLinkId) {
|
|
64
|
+
async delete_(webLinkId, opts) {
|
|
45
65
|
let url = this.session.baseUrl("api");
|
|
46
66
|
url += "/web_links";
|
|
47
67
|
url += '/' + pathEscape(webLinkId);
|
|
48
68
|
let req = this.session.newRequest("DELETE", url);
|
|
69
|
+
const options = opts ?? {};
|
|
70
|
+
if (options["if-match"] !== undefined) {
|
|
71
|
+
req = runtime.withHeader(req, "if-match", options["if-match"]);
|
|
72
|
+
}
|
|
49
73
|
await this.session.fetch(req);
|
|
50
74
|
}
|
|
51
75
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// Code generated by box-gantry 0.1.0 (spec
|
|
1
|
+
// Code generated by box-gantry 0.1.0 (spec 21e020ceb5dcf964) for Box API 2024.0. DO NOT EDIT.
|
|
2
2
|
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// Code generated by box-gantry 0.1.0 (spec
|
|
1
|
+
// Code generated by box-gantry 0.1.0 (spec 21e020ceb5dcf964) for Box API 2024.0. DO NOT EDIT.
|
|
2
2
|
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// Code generated by box-gantry 0.1.0 (spec
|
|
1
|
+
// Code generated by box-gantry 0.1.0 (spec 21e020ceb5dcf964) for Box API 2024.0. DO NOT EDIT.
|
|
2
2
|
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// Code generated by box-gantry 0.1.0 (spec
|
|
1
|
+
// Code generated by box-gantry 0.1.0 (spec 21e020ceb5dcf964) for Box API 2024.0. DO NOT EDIT.
|
|
2
2
|
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// Code generated by box-gantry 0.1.0 (spec
|
|
1
|
+
// Code generated by box-gantry 0.1.0 (spec 21e020ceb5dcf964) for Box API 2024.0. DO NOT EDIT.
|
|
2
2
|
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// Code generated by box-gantry 0.1.0 (spec
|
|
1
|
+
// Code generated by box-gantry 0.1.0 (spec 21e020ceb5dcf964) for Box API 2024.0. DO NOT EDIT.
|
|
2
2
|
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// Code generated by box-gantry 0.1.0 (spec
|
|
1
|
+
// Code generated by box-gantry 0.1.0 (spec 21e020ceb5dcf964) for Box API 2024.0. DO NOT EDIT.
|
|
2
2
|
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// Code generated by box-gantry 0.1.0 (spec
|
|
1
|
+
// Code generated by box-gantry 0.1.0 (spec 21e020ceb5dcf964) for Box API 2024.0. DO NOT EDIT.
|
|
2
2
|
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// Code generated by box-gantry 0.1.0 (spec
|
|
1
|
+
// Code generated by box-gantry 0.1.0 (spec 21e020ceb5dcf964) for Box API 2024.0. DO NOT EDIT.
|
|
2
2
|
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// Code generated by box-gantry 0.1.0 (spec
|
|
1
|
+
// Code generated by box-gantry 0.1.0 (spec 21e020ceb5dcf964) for Box API 2024.0. DO NOT EDIT.
|
|
2
2
|
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// Code generated by box-gantry 0.1.0 (spec
|
|
1
|
+
// Code generated by box-gantry 0.1.0 (spec 21e020ceb5dcf964) for Box API 2024.0. DO NOT EDIT.
|
|
2
2
|
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// Code generated by box-gantry 0.1.0 (spec
|
|
1
|
+
// Code generated by box-gantry 0.1.0 (spec 21e020ceb5dcf964) for Box API 2024.0. DO NOT EDIT.
|
|
2
2
|
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// Code generated by box-gantry 0.1.0 (spec
|
|
1
|
+
// Code generated by box-gantry 0.1.0 (spec 21e020ceb5dcf964) for Box API 2024.0. DO NOT EDIT.
|
|
2
2
|
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// Code generated by box-gantry 0.1.0 (spec
|
|
1
|
+
// Code generated by box-gantry 0.1.0 (spec 21e020ceb5dcf964) for Box API 2024.0. DO NOT EDIT.
|
|
2
2
|
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// Code generated by box-gantry 0.1.0 (spec
|
|
1
|
+
// Code generated by box-gantry 0.1.0 (spec 21e020ceb5dcf964) for Box API 2024.0. DO NOT EDIT.
|
|
2
2
|
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// Code generated by box-gantry 0.1.0 (spec
|
|
1
|
+
// Code generated by box-gantry 0.1.0 (spec 21e020ceb5dcf964) for Box API 2024.0. DO NOT EDIT.
|
|
2
2
|
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// Code generated by box-gantry 0.1.0 (spec
|
|
1
|
+
// Code generated by box-gantry 0.1.0 (spec 21e020ceb5dcf964) for Box API 2024.0. DO NOT EDIT.
|
|
2
2
|
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// Code generated by box-gantry 0.1.0 (spec
|
|
1
|
+
// Code generated by box-gantry 0.1.0 (spec 21e020ceb5dcf964) for Box API 2024.0. DO NOT EDIT.
|
|
2
2
|
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// Code generated by box-gantry 0.1.0 (spec
|
|
1
|
+
// Code generated by box-gantry 0.1.0 (spec 21e020ceb5dcf964) for Box API 2024.0. DO NOT EDIT.
|
|
2
2
|
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// Code generated by box-gantry 0.1.0 (spec
|
|
1
|
+
// Code generated by box-gantry 0.1.0 (spec 21e020ceb5dcf964) for Box API 2024.0. DO NOT EDIT.
|
|
2
2
|
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// Code generated by box-gantry 0.1.0 (spec
|
|
1
|
+
// Code generated by box-gantry 0.1.0 (spec 21e020ceb5dcf964) for Box API 2024.0. DO NOT EDIT.
|
|
2
2
|
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// Code generated by box-gantry 0.1.0 (spec
|
|
1
|
+
// Code generated by box-gantry 0.1.0 (spec 21e020ceb5dcf964) for Box API 2024.0. DO NOT EDIT.
|
|
2
2
|
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// Code generated by box-gantry 0.1.0 (spec
|
|
1
|
+
// Code generated by box-gantry 0.1.0 (spec 21e020ceb5dcf964) for Box API 2024.0. DO NOT EDIT.
|
|
2
2
|
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// Code generated by box-gantry 0.1.0 (spec
|
|
1
|
+
// Code generated by box-gantry 0.1.0 (spec 21e020ceb5dcf964) for Box API 2024.0. DO NOT EDIT.
|
|
2
2
|
export {};
|