@atscript/db-client 0.1.128 → 0.1.129

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.cjs CHANGED
@@ -56,6 +56,24 @@ var VersionMismatchError = class extends ClientError {
56
56
  return this.body.currentVersion;
57
57
  }
58
58
  };
59
+ /**
60
+ * Thrown by `Client` when NO server verdict was obtained: `fetch` itself
61
+ * rejected (network down, DNS, CORS, `AbortError`, …) or a 2xx response
62
+ * carried a body that is not JSON. Unlike {@link ClientError} — where the
63
+ * server answered and rejected — the request's outcome is unknown: a write
64
+ * may have committed. Reload before retrying a non-idempotent write.
65
+ * The underlying error is the standard `cause`.
66
+ */
67
+ var TransportError = class extends Error {
68
+ method;
69
+ url;
70
+ name = "TransportError";
71
+ constructor(method, url, detail, cause) {
72
+ super(`${method} ${url}: ${detail}`, { cause });
73
+ this.method = method;
74
+ this.url = url;
75
+ }
76
+ };
59
77
  /** Thrown by `Client.action()` when the action name is not present in `/meta`. */
60
78
  var ActionNotFoundError = class extends Error {
61
79
  action;
@@ -430,14 +448,20 @@ var Client = class {
430
448
  return init;
431
449
  }
432
450
  async _send(url, init, allowEmpty) {
433
- const res = await this._fetch(url, init);
451
+ const method = init.method ?? "GET";
452
+ let res;
453
+ try {
454
+ res = await this._fetch(url, init);
455
+ } catch (cause) {
456
+ throw new TransportError(method, url, describeCause(cause), cause);
457
+ }
434
458
  if (!res.ok) {
435
459
  let errorBody;
436
460
  try {
437
461
  errorBody = await res.json();
438
462
  } catch {
439
463
  errorBody = {
440
- message: res.statusText,
464
+ message: res.statusText || `HTTP ${res.status}`,
441
465
  statusCode: res.status
442
466
  };
443
467
  }
@@ -445,7 +469,11 @@ var Client = class {
445
469
  if (errorBody.kind === "version_mismatch") throw new VersionMismatchError(res.status, errorBody);
446
470
  throw new ClientError(res.status, errorBody);
447
471
  }
448
- if (!allowEmpty) return res.json();
472
+ if (!allowEmpty) try {
473
+ return await res.json();
474
+ } catch (cause) {
475
+ throw new TransportError(method, url, `HTTP ${res.status} body is not JSON (${describeCause(cause)})`, cause);
476
+ }
449
477
  if (res.status === 204 || res.headers.get("content-length") === "0") return void 0;
450
478
  try {
451
479
  return await res.json();
@@ -454,6 +482,11 @@ var Client = class {
454
482
  }
455
483
  }
456
484
  };
485
+ /** One-line rendering of a thrown value for a `TransportError` message. */
486
+ function describeCause(cause) {
487
+ if (cause instanceof Error) return cause.message || cause.name;
488
+ return String(cause);
489
+ }
457
490
  /**
458
491
  * Render a single identifier field for substitution into a navigate-URL
459
492
  * template or human-readable string. `null` / `undefined` collapse to `""`
@@ -495,6 +528,7 @@ exports.ActionNotFoundError = ActionNotFoundError;
495
528
  exports.ActionUnsupportedError = ActionUnsupportedError;
496
529
  exports.Client = Client;
497
530
  exports.ClientError = ClientError;
531
+ exports.TransportError = TransportError;
498
532
  exports.VersionMismatchError = VersionMismatchError;
499
533
  exports.encodeNavigateId = encodeNavigateId;
500
534
  exports.formatIdentifier = formatIdentifier;
package/dist/index.d.cts CHANGED
@@ -295,6 +295,28 @@ declare class VersionMismatchError extends ClientError {
295
295
  /** Row's current server-side version — clients refresh + retry against it. */
296
296
  get currentVersion(): number;
297
297
  }
298
+ /**
299
+ * Thrown by `Client` when NO server verdict was obtained: `fetch` itself
300
+ * rejected (network down, DNS, CORS, `AbortError`, …) or a 2xx response
301
+ * carried a body that is not JSON. Unlike {@link ClientError} — where the
302
+ * server answered and rejected — the request's outcome is unknown: a write
303
+ * may have committed. Reload before retrying a non-idempotent write.
304
+ * The underlying error is the standard `cause`.
305
+ */
306
+ declare class TransportError extends Error {
307
+ /** HTTP method of the failed request. */
308
+ readonly method: string;
309
+ /** Full request URL. */
310
+ readonly url: string;
311
+ name: string;
312
+ constructor(/** HTTP method of the failed request. */
313
+
314
+ method: string, /** Full request URL. */
315
+
316
+ url: string, /** What went wrong; the message is `<method> <url>: <detail>`. */
317
+
318
+ detail: string, cause?: unknown);
319
+ }
298
320
  /** Thrown by `Client.action()` when the action name is not present in `/meta`. */
299
321
  declare class ActionNotFoundError extends Error {
300
322
  readonly action: string;
@@ -314,4 +336,4 @@ declare class ActionUnsupportedError extends Error {
314
336
  constructor(action: string, processor: string, message: string);
315
337
  }
316
338
  //#endregion
317
- export { ActionDisabledError, type ActionDisabledErrorBody, ActionNotFoundError, ActionUnsupportedError, type AggregateQuery, type AggregateResult, type AtscriptClientShape, Client, ClientError, type ClientOptions, type ClientResponse, type ClientValidationError, type ClientValidator, type ClientValidatorOptions, type DataOf, type DbPatch, type DbRow, type FieldMeta, type FilterExpr, type IdOf, type MetaResponse, type NavOf, type OwnOf, type PageResult, type PatchOf, type RelationInfo, type RowOf, type SearchIndexInfo, type ServerError, type TCrudOp, type TCrudPermissions, type TDbActionInfo, type TDbActionIntent, type TDbActionLevel, type TDbActionProcessor, type TDbDeleteResult, type TDbInsertManyResult, type TDbInsertResult, type TDbUpdateResult, type TSerializedAnnotatedType, type TypedWithRelation, type Uniquery, type UniqueryControls, type ValidatorMode, VersionMismatchError, type VersionMismatchErrorBody, encodeNavigateId, formatIdentifier, formatIdentifierField };
339
+ export { ActionDisabledError, type ActionDisabledErrorBody, ActionNotFoundError, ActionUnsupportedError, type AggregateQuery, type AggregateResult, type AtscriptClientShape, Client, ClientError, type ClientOptions, type ClientResponse, type ClientValidationError, type ClientValidator, type ClientValidatorOptions, type DataOf, type DbPatch, type DbRow, type FieldMeta, type FilterExpr, type IdOf, type MetaResponse, type NavOf, type OwnOf, type PageResult, type PatchOf, type RelationInfo, type RowOf, type SearchIndexInfo, type ServerError, type TCrudOp, type TCrudPermissions, type TDbActionInfo, type TDbActionIntent, type TDbActionLevel, type TDbActionProcessor, type TDbDeleteResult, type TDbInsertManyResult, type TDbInsertResult, type TDbUpdateResult, type TSerializedAnnotatedType, TransportError, type TypedWithRelation, type Uniquery, type UniqueryControls, type ValidatorMode, VersionMismatchError, type VersionMismatchErrorBody, encodeNavigateId, formatIdentifier, formatIdentifierField };
package/dist/index.d.mts CHANGED
@@ -295,6 +295,28 @@ declare class VersionMismatchError extends ClientError {
295
295
  /** Row's current server-side version — clients refresh + retry against it. */
296
296
  get currentVersion(): number;
297
297
  }
298
+ /**
299
+ * Thrown by `Client` when NO server verdict was obtained: `fetch` itself
300
+ * rejected (network down, DNS, CORS, `AbortError`, …) or a 2xx response
301
+ * carried a body that is not JSON. Unlike {@link ClientError} — where the
302
+ * server answered and rejected — the request's outcome is unknown: a write
303
+ * may have committed. Reload before retrying a non-idempotent write.
304
+ * The underlying error is the standard `cause`.
305
+ */
306
+ declare class TransportError extends Error {
307
+ /** HTTP method of the failed request. */
308
+ readonly method: string;
309
+ /** Full request URL. */
310
+ readonly url: string;
311
+ name: string;
312
+ constructor(/** HTTP method of the failed request. */
313
+
314
+ method: string, /** Full request URL. */
315
+
316
+ url: string, /** What went wrong; the message is `<method> <url>: <detail>`. */
317
+
318
+ detail: string, cause?: unknown);
319
+ }
298
320
  /** Thrown by `Client.action()` when the action name is not present in `/meta`. */
299
321
  declare class ActionNotFoundError extends Error {
300
322
  readonly action: string;
@@ -314,4 +336,4 @@ declare class ActionUnsupportedError extends Error {
314
336
  constructor(action: string, processor: string, message: string);
315
337
  }
316
338
  //#endregion
317
- export { ActionDisabledError, type ActionDisabledErrorBody, ActionNotFoundError, ActionUnsupportedError, type AggregateQuery, type AggregateResult, type AtscriptClientShape, Client, ClientError, type ClientOptions, type ClientResponse, type ClientValidationError, type ClientValidator, type ClientValidatorOptions, type DataOf, type DbPatch, type DbRow, type FieldMeta, type FilterExpr, type IdOf, type MetaResponse, type NavOf, type OwnOf, type PageResult, type PatchOf, type RelationInfo, type RowOf, type SearchIndexInfo, type ServerError, type TCrudOp, type TCrudPermissions, type TDbActionInfo, type TDbActionIntent, type TDbActionLevel, type TDbActionProcessor, type TDbDeleteResult, type TDbInsertManyResult, type TDbInsertResult, type TDbUpdateResult, type TSerializedAnnotatedType, type TypedWithRelation, type Uniquery, type UniqueryControls, type ValidatorMode, VersionMismatchError, type VersionMismatchErrorBody, encodeNavigateId, formatIdentifier, formatIdentifierField };
339
+ export { ActionDisabledError, type ActionDisabledErrorBody, ActionNotFoundError, ActionUnsupportedError, type AggregateQuery, type AggregateResult, type AtscriptClientShape, Client, ClientError, type ClientOptions, type ClientResponse, type ClientValidationError, type ClientValidator, type ClientValidatorOptions, type DataOf, type DbPatch, type DbRow, type FieldMeta, type FilterExpr, type IdOf, type MetaResponse, type NavOf, type OwnOf, type PageResult, type PatchOf, type RelationInfo, type RowOf, type SearchIndexInfo, type ServerError, type TCrudOp, type TCrudPermissions, type TDbActionInfo, type TDbActionIntent, type TDbActionLevel, type TDbActionProcessor, type TDbDeleteResult, type TDbInsertManyResult, type TDbInsertResult, type TDbUpdateResult, type TSerializedAnnotatedType, TransportError, type TypedWithRelation, type Uniquery, type UniqueryControls, type ValidatorMode, VersionMismatchError, type VersionMismatchErrorBody, encodeNavigateId, formatIdentifier, formatIdentifierField };
package/dist/index.mjs CHANGED
@@ -55,6 +55,24 @@ var VersionMismatchError = class extends ClientError {
55
55
  return this.body.currentVersion;
56
56
  }
57
57
  };
58
+ /**
59
+ * Thrown by `Client` when NO server verdict was obtained: `fetch` itself
60
+ * rejected (network down, DNS, CORS, `AbortError`, …) or a 2xx response
61
+ * carried a body that is not JSON. Unlike {@link ClientError} — where the
62
+ * server answered and rejected — the request's outcome is unknown: a write
63
+ * may have committed. Reload before retrying a non-idempotent write.
64
+ * The underlying error is the standard `cause`.
65
+ */
66
+ var TransportError = class extends Error {
67
+ method;
68
+ url;
69
+ name = "TransportError";
70
+ constructor(method, url, detail, cause) {
71
+ super(`${method} ${url}: ${detail}`, { cause });
72
+ this.method = method;
73
+ this.url = url;
74
+ }
75
+ };
58
76
  /** Thrown by `Client.action()` when the action name is not present in `/meta`. */
59
77
  var ActionNotFoundError = class extends Error {
60
78
  action;
@@ -429,14 +447,20 @@ var Client = class {
429
447
  return init;
430
448
  }
431
449
  async _send(url, init, allowEmpty) {
432
- const res = await this._fetch(url, init);
450
+ const method = init.method ?? "GET";
451
+ let res;
452
+ try {
453
+ res = await this._fetch(url, init);
454
+ } catch (cause) {
455
+ throw new TransportError(method, url, describeCause(cause), cause);
456
+ }
433
457
  if (!res.ok) {
434
458
  let errorBody;
435
459
  try {
436
460
  errorBody = await res.json();
437
461
  } catch {
438
462
  errorBody = {
439
- message: res.statusText,
463
+ message: res.statusText || `HTTP ${res.status}`,
440
464
  statusCode: res.status
441
465
  };
442
466
  }
@@ -444,7 +468,11 @@ var Client = class {
444
468
  if (errorBody.kind === "version_mismatch") throw new VersionMismatchError(res.status, errorBody);
445
469
  throw new ClientError(res.status, errorBody);
446
470
  }
447
- if (!allowEmpty) return res.json();
471
+ if (!allowEmpty) try {
472
+ return await res.json();
473
+ } catch (cause) {
474
+ throw new TransportError(method, url, `HTTP ${res.status} body is not JSON (${describeCause(cause)})`, cause);
475
+ }
448
476
  if (res.status === 204 || res.headers.get("content-length") === "0") return void 0;
449
477
  try {
450
478
  return await res.json();
@@ -453,6 +481,11 @@ var Client = class {
453
481
  }
454
482
  }
455
483
  };
484
+ /** One-line rendering of a thrown value for a `TransportError` message. */
485
+ function describeCause(cause) {
486
+ if (cause instanceof Error) return cause.message || cause.name;
487
+ return String(cause);
488
+ }
456
489
  /**
457
490
  * Render a single identifier field for substitution into a navigate-URL
458
491
  * template or human-readable string. `null` / `undefined` collapse to `""`
@@ -489,4 +522,4 @@ function describeShape(value) {
489
522
  return typeof value;
490
523
  }
491
524
  //#endregion
492
- export { ActionDisabledError, ActionNotFoundError, ActionUnsupportedError, Client, ClientError, VersionMismatchError, encodeNavigateId, formatIdentifier, formatIdentifierField };
525
+ export { ActionDisabledError, ActionNotFoundError, ActionUnsupportedError, Client, ClientError, TransportError, VersionMismatchError, encodeNavigateId, formatIdentifier, formatIdentifierField };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atscript/db-client",
3
- "version": "0.1.128",
3
+ "version": "0.1.129",
4
4
  "description": "Browser-compatible HTTP client for @atscript/moost-db REST endpoints.",
5
5
  "keywords": [
6
6
  "atscript",
@@ -50,7 +50,7 @@
50
50
  "@atscript/typescript": "^0.1.92",
51
51
  "@uniqu/core": "^0.1.8",
52
52
  "unplugin-atscript": "^0.1.92",
53
- "@atscript/db": "0.1.128"
53
+ "@atscript/db": "0.1.129"
54
54
  },
55
55
  "peerDependencies": {
56
56
  "@atscript/db": "^0.1.44",