@unofficialbox/box-open-sdk 0.7.0 → 0.7.1

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.
@@ -2,6 +2,7 @@
2
2
  // Code generated by box-gantry (vendored from runtimes/typescript/gantryruntime/src/errors.ts). DO NOT EDIT.
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.BoxApiError = void 0;
5
+ exports.isPreconditionFailed = isPreconditionFailed;
5
6
  exports.apiErrorFromResponse = apiErrorFromResponse;
6
7
  /**
7
8
  * A runtime error: a failed request, auth acquisition, or body decode. The
@@ -31,6 +32,12 @@ class BoxApiError extends Error {
31
32
  }
32
33
  }
33
34
  exports.BoxApiError = BoxApiError;
35
+ /** Whether `err` is Box's 412 Precondition Failed: an `If-Match` write whose
36
+ * etag no longer matches, because the item changed since it was read. Re-read
37
+ * the item and retry with its new etag. */
38
+ function isPreconditionFailed(err) {
39
+ return err instanceof BoxApiError && err.status === 412;
40
+ }
34
41
  /** The error for a non-2xx response: `Client.fetch` throws it once the retry
35
42
  * budget and the single 401 refresh are spent, so a caller never mistakes an
36
43
  * error body for a result. Box's error fields are read from the body when it
@@ -15,7 +15,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
16
16
  };
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.Client = exports.Stream = exports.Response = exports.Request = exports.BoxApiError = void 0;
18
+ exports.Client = exports.Stream = exports.Response = exports.Request = exports.isPreconditionFailed = exports.BoxApiError = void 0;
19
19
  exports.withHeader = withHeader;
20
20
  exports.withQuery = withQuery;
21
21
  exports.withJsonBody = withJsonBody;
@@ -29,6 +29,7 @@ exports.statusCode = statusCode;
29
29
  const errors_js_1 = require("./errors.js");
30
30
  var errors_js_2 = require("./errors.js");
31
31
  Object.defineProperty(exports, "BoxApiError", { enumerable: true, get: function () { return errors_js_2.BoxApiError; } });
32
+ Object.defineProperty(exports, "isPreconditionFailed", { enumerable: true, get: function () { return errors_js_2.isPreconditionFailed; } });
32
33
  __exportStar(require("./auth.js"), exports);
33
34
  /** The default base URLs for the D-106 URL classes. */
34
35
  const DEFAULT_BASE_URLS = {
@@ -26,6 +26,12 @@ export class BoxApiError extends Error {
26
26
  this.body = options.body;
27
27
  }
28
28
  }
29
+ /** Whether `err` is Box's 412 Precondition Failed: an `If-Match` write whose
30
+ * etag no longer matches, because the item changed since it was read. Re-read
31
+ * the item and retry with its new etag. */
32
+ export function isPreconditionFailed(err) {
33
+ return err instanceof BoxApiError && err.status === 412;
34
+ }
29
35
  /** The error for a non-2xx response: `Client.fetch` throws it once the retry
30
36
  * budget and the single 401 refresh are spent, so a caller never mistakes an
31
37
  * error body for a result. Box's error fields are read from the body when it
@@ -1,6 +1,6 @@
1
1
  // Code generated by box-gantry (vendored from runtimes/typescript/gantryruntime/src/runtime.ts). DO NOT EDIT.
2
2
  import { BoxApiError, apiErrorFromResponse } from './errors.js';
3
- export { BoxApiError } from './errors.js';
3
+ export { BoxApiError, isPreconditionFailed } from './errors.js';
4
4
  export * from './auth.js';
5
5
  /** The default base URLs for the D-106 URL classes. */
6
6
  const DEFAULT_BASE_URLS = {
@@ -33,6 +33,10 @@ export declare class BoxApiError extends Error {
33
33
  readonly body?: Uint8Array;
34
34
  constructor(message: string, options?: BoxApiErrorOptions);
35
35
  }
36
+ /** Whether `err` is Box's 412 Precondition Failed: an `If-Match` write whose
37
+ * etag no longer matches, because the item changed since it was read. Re-read
38
+ * the item and retry with its new etag. */
39
+ export declare function isPreconditionFailed(err: unknown): err is BoxApiError;
36
40
  /** The error for a non-2xx response: `Client.fetch` throws it once the retry
37
41
  * budget and the single 401 refresh are spent, so a caller never mistakes an
38
42
  * error body for a result. Box's error fields are read from the body when it
@@ -1,5 +1,5 @@
1
1
  import type { Auth } from './auth.js';
2
- export { BoxApiError } from './errors.js';
2
+ export { BoxApiError, isPreconditionFailed } from './errors.js';
3
3
  export * from './auth.js';
4
4
  /** The runtime-owned HTTP request envelope, assembled by the `with*` builders
5
5
  * before `fetch` executes it. */
package/docs/errors.md CHANGED
@@ -34,18 +34,24 @@ guide):
34
34
  - **Writes** — pass the etag as `'if-match'` on a file or folder update or
35
35
  delete, or a new file version upload. Box answers `412 Precondition
36
36
  Failed` (code `precondition_failed`) when the item changed since you read
37
- it: read it again, reapply your change, retry. `If-Match` can't block a move.
37
+ it, and `runtime.isPreconditionFailed(err)` reports it: read it again,
38
+ reapply your change, retry. `If-Match` can't block a move.
38
39
 
39
40
  ```ts
40
41
  const file = await client.files.getIfModified(fileId, etag);
41
42
  if (file === undefined) {
42
43
  // unchanged since etag
43
44
  }
44
- try {
45
- await client.files.update(fileId, body, { 'if-match': etag });
46
- } catch (err) {
47
- if (err instanceof runtime.BoxApiError && err.status === 412) {
48
- // changed since etag: re-read and retry
45
+
46
+ // Re-read and retry: the update lands only on the version it was made from.
47
+ for (let attempt = 1; ; attempt++) {
48
+ try {
49
+ await client.files.update(fileId, body, { 'if-match': etag });
50
+ break;
51
+ } catch (err) {
52
+ if (!runtime.isPreconditionFailed(err) || attempt === 3) throw err;
53
+ const current = await client.files.get(fileId);
54
+ etag = current.etag ?? undefined; // reapply your change to current here
49
55
  }
50
56
  }
51
57
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unofficialbox/box-open-sdk",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "description": "Box API client for TypeScript (open source, community, punk rock) — typed models, async managers, and a fetch runtime with retry, backoff, and token refresh.",
5
5
  "keywords": ["box", "box-api", "sdk", "api-client", "typescript", "unofficial"],
6
6
  "license": "MIT",