@bettercms-ai/sdk 1.8.0 → 1.8.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.
package/dist/index.d.cts CHANGED
@@ -404,18 +404,28 @@ declare class BetterCMSError extends Error {
404
404
  * shares a status with others (e.g. 409 slug-conflict vs 409 project-deleted).
405
405
  */
406
406
  readonly bodyCode?: string;
407
- constructor(message: string, status: number, code: BetterCMSErrorCode, bodyCode?: string);
407
+ /**
408
+ * Per-field validation messages from a 400 `{ errors: { field: message } }` body.
409
+ * The backend returns validation failures in this shape (not `message`/`error`), so
410
+ * without this the SDK collapsed every validation 400 to a bare "Bad Request" with no
411
+ * hint which field or rule failed (FLO-474). Mirrors the forms client's `fieldErrors`.
412
+ */
413
+ readonly fieldErrors?: Record<string, string>;
414
+ constructor(message: string, status: number, code: BetterCMSErrorCode, bodyCode?: string, fieldErrors?: Record<string, string>);
408
415
  toJSON(): {
409
416
  name: string;
410
417
  message: string;
411
418
  status: number;
412
419
  code: BetterCMSErrorCode;
413
420
  bodyCode: string | undefined;
421
+ fieldErrors: Record<string, string> | undefined;
414
422
  };
415
423
  /**
416
- * Factory — creates a BetterCMSError from a failed fetch Response. Reads the
417
- * body's `message` (or `error`) for the human message and `code` for a
418
- * machine-readable condition the SDK surfaces as `bodyCode`.
424
+ * Factory — creates a BetterCMSError from a failed fetch Response. Reads the body's
425
+ * `message` (or `error`) for the human message and `code` for a machine-readable
426
+ * condition surfaced as `bodyCode`. Validation failures arrive as `{ errors: {...} }`
427
+ * (no `message`/`error`), so fall back to the first field error for the message and
428
+ * expose the full map as `fieldErrors` (FLO-474).
419
429
  */
420
430
  static from(res: Response): Promise<BetterCMSError>;
421
431
  }
package/dist/index.d.ts CHANGED
@@ -404,18 +404,28 @@ declare class BetterCMSError extends Error {
404
404
  * shares a status with others (e.g. 409 slug-conflict vs 409 project-deleted).
405
405
  */
406
406
  readonly bodyCode?: string;
407
- constructor(message: string, status: number, code: BetterCMSErrorCode, bodyCode?: string);
407
+ /**
408
+ * Per-field validation messages from a 400 `{ errors: { field: message } }` body.
409
+ * The backend returns validation failures in this shape (not `message`/`error`), so
410
+ * without this the SDK collapsed every validation 400 to a bare "Bad Request" with no
411
+ * hint which field or rule failed (FLO-474). Mirrors the forms client's `fieldErrors`.
412
+ */
413
+ readonly fieldErrors?: Record<string, string>;
414
+ constructor(message: string, status: number, code: BetterCMSErrorCode, bodyCode?: string, fieldErrors?: Record<string, string>);
408
415
  toJSON(): {
409
416
  name: string;
410
417
  message: string;
411
418
  status: number;
412
419
  code: BetterCMSErrorCode;
413
420
  bodyCode: string | undefined;
421
+ fieldErrors: Record<string, string> | undefined;
414
422
  };
415
423
  /**
416
- * Factory — creates a BetterCMSError from a failed fetch Response. Reads the
417
- * body's `message` (or `error`) for the human message and `code` for a
418
- * machine-readable condition the SDK surfaces as `bodyCode`.
424
+ * Factory — creates a BetterCMSError from a failed fetch Response. Reads the body's
425
+ * `message` (or `error`) for the human message and `code` for a machine-readable
426
+ * condition surfaced as `bodyCode`. Validation failures arrive as `{ errors: {...} }`
427
+ * (no `message`/`error`), so fall back to the first field error for the message and
428
+ * expose the full map as `fieldErrors` (FLO-474).
419
429
  */
420
430
  static from(res: Response): Promise<BetterCMSError>;
421
431
  }
package/dist/index.js CHANGED
@@ -28,12 +28,20 @@ var BetterCMSError = class _BetterCMSError extends Error {
28
28
  * shares a status with others (e.g. 409 slug-conflict vs 409 project-deleted).
29
29
  */
30
30
  bodyCode;
31
- constructor(message, status, code, bodyCode) {
31
+ /**
32
+ * Per-field validation messages from a 400 `{ errors: { field: message } }` body.
33
+ * The backend returns validation failures in this shape (not `message`/`error`), so
34
+ * without this the SDK collapsed every validation 400 to a bare "Bad Request" with no
35
+ * hint which field or rule failed (FLO-474). Mirrors the forms client's `fieldErrors`.
36
+ */
37
+ fieldErrors;
38
+ constructor(message, status, code, bodyCode, fieldErrors) {
32
39
  super(message);
33
40
  this.name = "BetterCMSError";
34
41
  this.status = status;
35
42
  this.code = code;
36
43
  this.bodyCode = bodyCode;
44
+ this.fieldErrors = fieldErrors;
37
45
  if (Error.captureStackTrace) {
38
46
  Error.captureStackTrace(this, _BetterCMSError);
39
47
  }
@@ -44,25 +52,40 @@ var BetterCMSError = class _BetterCMSError extends Error {
44
52
  message: this.message,
45
53
  status: this.status,
46
54
  code: this.code,
47
- bodyCode: this.bodyCode
55
+ bodyCode: this.bodyCode,
56
+ fieldErrors: this.fieldErrors
48
57
  };
49
58
  }
50
59
  /**
51
- * Factory — creates a BetterCMSError from a failed fetch Response. Reads the
52
- * body's `message` (or `error`) for the human message and `code` for a
53
- * machine-readable condition the SDK surfaces as `bodyCode`.
60
+ * Factory — creates a BetterCMSError from a failed fetch Response. Reads the body's
61
+ * `message` (or `error`) for the human message and `code` for a machine-readable
62
+ * condition surfaced as `bodyCode`. Validation failures arrive as `{ errors: {...} }`
63
+ * (no `message`/`error`), so fall back to the first field error for the message and
64
+ * expose the full map as `fieldErrors` (FLO-474).
54
65
  */
55
66
  static async from(res) {
56
67
  let message = res.statusText || "An error occurred";
57
68
  let bodyCode;
69
+ let fieldErrors;
70
+ let code = statusToCode(res.status);
58
71
  try {
59
72
  const body = await res.json();
73
+ if (body?.errors && typeof body.errors === "object") {
74
+ fieldErrors = body.errors;
75
+ code = ErrorCodes.VALIDATION_ERROR;
76
+ }
60
77
  if (body?.message) message = body.message;
61
78
  else if (body?.error) message = body.error;
79
+ else if (fieldErrors) {
80
+ const [field, detail] = Object.entries(fieldErrors).find(
81
+ ([, v]) => typeof v === "string" && v.length > 0
82
+ ) ?? [];
83
+ if (field) message = `${field}: ${detail}`;
84
+ }
62
85
  if (body?.code) bodyCode = body.code;
63
86
  } catch {
64
87
  }
65
- return new _BetterCMSError(message, res.status, statusToCode(res.status), bodyCode);
88
+ return new _BetterCMSError(message, res.status, code, bodyCode, fieldErrors);
66
89
  }
67
90
  };
68
91