@mx-space/byline-api-client 0.3.1 → 0.3.2

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 CHANGED
@@ -34,7 +34,9 @@ resolves to `{ data, meta? }`, mirroring the server envelope. Responses are conv
34
34
  from the snake_case wire format to camelCase, except free-form subtrees (post `meta`,
35
35
  dynamic component `propsSchema`). Pass `camelCase: false` to keep the wire keys.
36
36
  Failures throw `BylineApiError` with the server's `status`, `code`, `message` and
37
- `details`; use `isBylineApiError(error)` to narrow.
37
+ `details`; use `isBylineApiError(error)` to narrow. A successful response labelled JSON
38
+ whose body is empty or not JSON throws code `INVALID_RESPONSE`; an error while
39
+ reading the body (for example a connection cut off mid-stream) is rethrown as is.
38
40
 
39
41
  | Option | Purpose |
40
42
  | ----------- | --------------------------------------------------------------- |
package/dist/index.cjs CHANGED
@@ -105,7 +105,7 @@ var HttpCore = class {
105
105
  signal: options.signal
106
106
  });
107
107
  if (response.status === 204) return { data: void 0 };
108
- const payload = (response.headers.get("content-type") ?? "").includes("json") ? await response.json().catch(() => null) : await response.text();
108
+ const payload = (response.headers.get("content-type") ?? "").includes("json") ? await this.readJson(response, path) : await response.text();
109
109
  if (!response.ok) throw this.toError(response.status, path, payload);
110
110
  if (!isEnvelope(payload)) return { data: this.transform(payload, options.preserve) };
111
111
  return {
@@ -113,6 +113,15 @@ var HttpCore = class {
113
113
  ...payload.meta === void 0 ? {} : { meta: this.transform(payload.meta) }
114
114
  };
115
115
  }
116
+ async readJson(response, path) {
117
+ try {
118
+ return await response.json();
119
+ } catch (error) {
120
+ if (!response.ok) return null;
121
+ if (!(error instanceof SyntaxError)) throw error;
122
+ throw new BylineApiError(response.status, "INVALID_RESPONSE", `Response body is not valid JSON: ${error.message}`, path);
123
+ }
124
+ }
116
125
  transform(value, preserve) {
117
126
  if (this.options.camelCase === false) return value;
118
127
  return camelcaseKeys(value, preserve);
package/dist/index.d.cts CHANGED
@@ -462,6 +462,7 @@ export declare class HttpCore {
462
462
  get lang(): string | undefined;
463
463
  buildUrl(path: string, query?: Record<string, QueryValue>): string;
464
464
  request<T, M = Record<string, unknown>>(method: HttpMethod, path: string, options?: RequestOptions): Promise<ApiResponse<T, M>>;
465
+ private readJson;
465
466
  private transform;
466
467
  private toError;
467
468
  }
package/dist/index.d.ts CHANGED
@@ -462,6 +462,7 @@ export declare class HttpCore {
462
462
  get lang(): string | undefined;
463
463
  buildUrl(path: string, query?: Record<string, QueryValue>): string;
464
464
  request<T, M = Record<string, unknown>>(method: HttpMethod, path: string, options?: RequestOptions): Promise<ApiResponse<T, M>>;
465
+ private readJson;
465
466
  private transform;
466
467
  private toError;
467
468
  }
package/dist/index.js CHANGED
@@ -104,7 +104,7 @@ var HttpCore = class {
104
104
  signal: options.signal
105
105
  });
106
106
  if (response.status === 204) return { data: void 0 };
107
- const payload = (response.headers.get("content-type") ?? "").includes("json") ? await response.json().catch(() => null) : await response.text();
107
+ const payload = (response.headers.get("content-type") ?? "").includes("json") ? await this.readJson(response, path) : await response.text();
108
108
  if (!response.ok) throw this.toError(response.status, path, payload);
109
109
  if (!isEnvelope(payload)) return { data: this.transform(payload, options.preserve) };
110
110
  return {
@@ -112,6 +112,15 @@ var HttpCore = class {
112
112
  ...payload.meta === void 0 ? {} : { meta: this.transform(payload.meta) }
113
113
  };
114
114
  }
115
+ async readJson(response, path) {
116
+ try {
117
+ return await response.json();
118
+ } catch (error) {
119
+ if (!response.ok) return null;
120
+ if (!(error instanceof SyntaxError)) throw error;
121
+ throw new BylineApiError(response.status, "INVALID_RESPONSE", `Response body is not valid JSON: ${error.message}`, path);
122
+ }
123
+ }
115
124
  transform(value, preserve) {
116
125
  if (this.options.camelCase === false) return value;
117
126
  return camelcaseKeys(value, preserve);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mx-space/byline-api-client",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "Typed fetch client for the Byline headless CMS API",
5
5
  "keywords": [
6
6
  "byline",