@shipstatic/types 0.9.5 → 0.9.6

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
@@ -43,7 +43,8 @@ if (isShipError(error)) {
43
43
  }
44
44
 
45
45
  if (error.isClientError()) { /* Business | Config | File | Validation */ }
46
- if (error.isAuthError()) { /* handle auth */ }
46
+ if (error.isAuthError()) { /* handle auth */ }
47
+ if (error.type === ErrorType.Validation) { /* specific-type checks */ }
47
48
  ```
48
49
 
49
50
  **HTTP client integration.** Both producer and consumer sides of the wire have first-class helpers, so every HTTP client across the platform reconstructs the same `ShipError` shape:
@@ -54,6 +55,8 @@ return c.json(error.toResponse(), error.status ?? 500);
54
55
 
55
56
  // Consumer side — two symmetric helpers cover both HTTP error modes:
56
57
 
58
+ // Both helpers take an optional operationName for context-aware fallback messages.
59
+
57
60
  // 1. Server returned a non-OK response
58
61
  if (!response.ok) {
59
62
  throw await ShipError.fromHttpResponse(response, 'Get account');
package/dist/index.d.ts CHANGED
@@ -354,8 +354,8 @@ export declare class ShipError extends Error {
354
354
  * Construct a `ShipError` from an HTTP error response.
355
355
  *
356
356
  * Best-effort body parse for `{ message, error?, details? }`. Message
357
- * resolution: `body.message` → `body.error` → `fallbackMessage`
358
- * `Request failed with status N`.
357
+ * resolution: `body.message` → `body.error` → `"<operationName> failed with
358
+ * status <N>"`.
359
359
  *
360
360
  * Type resolution: trusts `body.error` when it's a known `ErrorType`
361
361
  * (preserves the wire's intent — server's `ShipError.validation(...)`
@@ -363,10 +363,13 @@ export declare class ShipError extends Error {
363
363
  * status-derived (401 → Authentication, 429 → RateLimit, else → Api) for
364
364
  * non-API responses (CDN errors, intermediaries) or malformed bodies.
365
365
  *
366
+ * `operationName` (e.g. `"Get account"`) is used to compose the fallback
367
+ * message. Defaults to `"Request"`. Same convention as `fromFetchError`.
368
+ *
366
369
  * Async because it reads the response body. Returns rather than throws so
367
370
  * callers can compose; most will `throw await ShipError.fromHttpResponse(...)`.
368
371
  */
369
- static fromHttpResponse(response: Response, fallbackMessage?: string): Promise<ShipError>;
372
+ static fromHttpResponse(response: Response, operationName?: string): Promise<ShipError>;
370
373
  /**
371
374
  * Construct a `ShipError` from an error caught around a `fetch()` call.
372
375
  *
@@ -391,18 +394,14 @@ export declare class ShipError extends Error {
391
394
  static rateLimit(message?: string): ShipError;
392
395
  static authentication(message?: string, details?: any): ShipError;
393
396
  static business(message: string, status?: number): ShipError;
394
- static network(message: string, cause?: Error): ShipError;
397
+ static network(message: string, details?: any): ShipError;
395
398
  static cancelled(message: string): ShipError;
396
- static file(message: string, filePath?: string): ShipError;
399
+ static file(message: string, details?: any): ShipError;
397
400
  static config(message: string, details?: any): ShipError;
398
401
  static api(message: string, status?: number): ShipError;
399
- get filePath(): string | undefined;
400
402
  isClientError(): boolean;
401
403
  isNetworkError(): boolean;
402
404
  isAuthError(): boolean;
403
- isValidationError(): boolean;
404
- isFileError(): boolean;
405
- isConfigError(): boolean;
406
405
  isType(errorType: ErrorType): boolean;
407
406
  }
408
407
  /**
package/dist/index.js CHANGED
@@ -132,8 +132,8 @@ export class ShipError extends Error {
132
132
  * Construct a `ShipError` from an HTTP error response.
133
133
  *
134
134
  * Best-effort body parse for `{ message, error?, details? }`. Message
135
- * resolution: `body.message` → `body.error` → `fallbackMessage`
136
- * `Request failed with status N`.
135
+ * resolution: `body.message` → `body.error` → `"<operationName> failed with
136
+ * status <N>"`.
137
137
  *
138
138
  * Type resolution: trusts `body.error` when it's a known `ErrorType`
139
139
  * (preserves the wire's intent — server's `ShipError.validation(...)`
@@ -141,10 +141,13 @@ export class ShipError extends Error {
141
141
  * status-derived (401 → Authentication, 429 → RateLimit, else → Api) for
142
142
  * non-API responses (CDN errors, intermediaries) or malformed bodies.
143
143
  *
144
+ * `operationName` (e.g. `"Get account"`) is used to compose the fallback
145
+ * message. Defaults to `"Request"`. Same convention as `fromFetchError`.
146
+ *
144
147
  * Async because it reads the response body. Returns rather than throws so
145
148
  * callers can compose; most will `throw await ShipError.fromHttpResponse(...)`.
146
149
  */
147
- static async fromHttpResponse(response, fallbackMessage) {
150
+ static async fromHttpResponse(response, operationName) {
148
151
  let message;
149
152
  let details;
150
153
  let bodyType;
@@ -171,9 +174,9 @@ export class ShipError extends Error {
171
174
  }
172
175
  }
173
176
  catch {
174
- // Body unreadable; fall through to fallback.
177
+ // Body unreadable; fall through to operationName-derived message.
175
178
  }
176
- message = message || fallbackMessage || `Request failed with status ${response.status}`;
179
+ message = message || `${operationName || 'Request'} failed with status ${response.status}`;
177
180
  const type = bodyType ?? (response.status === 401 ? ErrorType.Authentication :
178
181
  response.status === 429 ? ErrorType.RateLimit :
179
182
  ErrorType.Api);
@@ -206,7 +209,7 @@ export class ShipError extends Error {
206
209
  return ShipError.cancelled(`${op} was cancelled`);
207
210
  }
208
211
  if (cause instanceof TypeError && cause.message.includes('fetch')) {
209
- return ShipError.network(`${op} failed: ${cause.message}`, cause);
212
+ return ShipError.network(`${op} failed: ${cause.message}`, { cause });
210
213
  }
211
214
  return new ShipError(ErrorType.Api, `${op} failed: ${cause.message}`);
212
215
  }
@@ -229,14 +232,14 @@ export class ShipError extends Error {
229
232
  static business(message, status = 400) {
230
233
  return new ShipError(ErrorType.Business, message, status);
231
234
  }
232
- static network(message, cause) {
233
- return new ShipError(ErrorType.Network, message, undefined, { cause });
235
+ static network(message, details) {
236
+ return new ShipError(ErrorType.Network, message, undefined, details);
234
237
  }
235
238
  static cancelled(message) {
236
239
  return new ShipError(ErrorType.Cancelled, message);
237
240
  }
238
- static file(message, filePath) {
239
- return new ShipError(ErrorType.File, message, undefined, { filePath });
241
+ static file(message, details) {
242
+ return new ShipError(ErrorType.File, message, undefined, details);
240
243
  }
241
244
  static config(message, details) {
242
245
  return new ShipError(ErrorType.Config, message, undefined, details);
@@ -244,11 +247,8 @@ export class ShipError extends Error {
244
247
  static api(message, status = 500) {
245
248
  return new ShipError(ErrorType.Api, message, status);
246
249
  }
247
- // Helper getter for accessing file path from details
248
- get filePath() {
249
- return this.details?.filePath;
250
- }
251
- // Helper methods for error type checking using categorization
250
+ // Semantic-category type guards. For specific-type checks, use
251
+ // `error.type === ErrorType.X` directly or the generic `isType(t)`.
252
252
  isClientError() {
253
253
  return ERROR_CATEGORIES.client.has(this.type);
254
254
  }
@@ -258,16 +258,6 @@ export class ShipError extends Error {
258
258
  isAuthError() {
259
259
  return ERROR_CATEGORIES.auth.has(this.type);
260
260
  }
261
- isValidationError() {
262
- return this.type === ErrorType.Validation;
263
- }
264
- isFileError() {
265
- return this.type === ErrorType.File;
266
- }
267
- isConfigError() {
268
- return this.type === ErrorType.Config;
269
- }
270
- // Generic type checker
271
261
  isType(errorType) {
272
262
  return this.type === errorType;
273
263
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shipstatic/types",
3
- "version": "0.9.5",
3
+ "version": "0.9.6",
4
4
  "description": "Shared types for ShipStatic platform",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
package/src/index.ts CHANGED
@@ -448,8 +448,8 @@ export class ShipError extends Error {
448
448
  * Construct a `ShipError` from an HTTP error response.
449
449
  *
450
450
  * Best-effort body parse for `{ message, error?, details? }`. Message
451
- * resolution: `body.message` → `body.error` → `fallbackMessage`
452
- * `Request failed with status N`.
451
+ * resolution: `body.message` → `body.error` → `"<operationName> failed with
452
+ * status <N>"`.
453
453
  *
454
454
  * Type resolution: trusts `body.error` when it's a known `ErrorType`
455
455
  * (preserves the wire's intent — server's `ShipError.validation(...)`
@@ -457,12 +457,15 @@ export class ShipError extends Error {
457
457
  * status-derived (401 → Authentication, 429 → RateLimit, else → Api) for
458
458
  * non-API responses (CDN errors, intermediaries) or malformed bodies.
459
459
  *
460
+ * `operationName` (e.g. `"Get account"`) is used to compose the fallback
461
+ * message. Defaults to `"Request"`. Same convention as `fromFetchError`.
462
+ *
460
463
  * Async because it reads the response body. Returns rather than throws so
461
464
  * callers can compose; most will `throw await ShipError.fromHttpResponse(...)`.
462
465
  */
463
466
  static async fromHttpResponse(
464
467
  response: Response,
465
- fallbackMessage?: string,
468
+ operationName?: string,
466
469
  ): Promise<ShipError> {
467
470
  let message: string | undefined;
468
471
  let details: unknown;
@@ -486,10 +489,10 @@ export class ShipError extends Error {
486
489
  if (text) message = text;
487
490
  }
488
491
  } catch {
489
- // Body unreadable; fall through to fallback.
492
+ // Body unreadable; fall through to operationName-derived message.
490
493
  }
491
494
 
492
- message = message || fallbackMessage || `Request failed with status ${response.status}`;
495
+ message = message || `${operationName || 'Request'} failed with status ${response.status}`;
493
496
 
494
497
  const type = bodyType ?? (
495
498
  response.status === 401 ? ErrorType.Authentication :
@@ -528,7 +531,7 @@ export class ShipError extends Error {
528
531
  return ShipError.cancelled(`${op} was cancelled`);
529
532
  }
530
533
  if (cause instanceof TypeError && cause.message.includes('fetch')) {
531
- return ShipError.network(`${op} failed: ${cause.message}`, cause);
534
+ return ShipError.network(`${op} failed: ${cause.message}`, { cause });
532
535
  }
533
536
  return new ShipError(ErrorType.Api, `${op} failed: ${cause.message}`);
534
537
  }
@@ -558,16 +561,16 @@ export class ShipError extends Error {
558
561
  return new ShipError(ErrorType.Business, message, status);
559
562
  }
560
563
 
561
- static network(message: string, cause?: Error): ShipError {
562
- return new ShipError(ErrorType.Network, message, undefined, { cause });
564
+ static network(message: string, details?: any): ShipError {
565
+ return new ShipError(ErrorType.Network, message, undefined, details);
563
566
  }
564
567
 
565
568
  static cancelled(message: string): ShipError {
566
569
  return new ShipError(ErrorType.Cancelled, message);
567
570
  }
568
571
 
569
- static file(message: string, filePath?: string): ShipError {
570
- return new ShipError(ErrorType.File, message, undefined, { filePath });
572
+ static file(message: string, details?: any): ShipError {
573
+ return new ShipError(ErrorType.File, message, undefined, details);
571
574
  }
572
575
 
573
576
  static config(message: string, details?: any): ShipError {
@@ -578,12 +581,8 @@ export class ShipError extends Error {
578
581
  return new ShipError(ErrorType.Api, message, status);
579
582
  }
580
583
 
581
- // Helper getter for accessing file path from details
582
- get filePath(): string | undefined {
583
- return this.details?.filePath;
584
- }
585
-
586
- // Helper methods for error type checking using categorization
584
+ // Semantic-category type guards. For specific-type checks, use
585
+ // `error.type === ErrorType.X` directly or the generic `isType(t)`.
587
586
  isClientError(): boolean {
588
587
  return ERROR_CATEGORIES.client.has(this.type);
589
588
  }
@@ -596,19 +595,6 @@ export class ShipError extends Error {
596
595
  return ERROR_CATEGORIES.auth.has(this.type);
597
596
  }
598
597
 
599
- isValidationError(): boolean {
600
- return this.type === ErrorType.Validation;
601
- }
602
-
603
- isFileError(): boolean {
604
- return this.type === ErrorType.File;
605
- }
606
-
607
- isConfigError(): boolean {
608
- return this.type === ErrorType.Config;
609
- }
610
-
611
- // Generic type checker
612
598
  isType(errorType: ErrorType): boolean {
613
599
  return this.type === errorType;
614
600
  }