@happyvertical/smrt-web 0.40.60 → 0.40.61

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.ts CHANGED
@@ -12,7 +12,8 @@ export declare function buildListQuery(params?: Record<string, unknown>): string
12
12
  * Build CRUD fetchers from a generated collection definition — the same URL
13
13
  * scheme and payload handling as the generated REST client
14
14
  * (`basePath + endpoint`), with one improvement: HTTP error statuses reject
15
- * with the server's `{ error }` body instead of resolving with it.
15
+ * instead of resolving with them. Typed/legacy 4xx detail is retained; 5xx
16
+ * failures stay opaque and payload-free.
16
17
  */
17
18
  export declare function createDefinitionFetchers(definition: SmrtWebCollectionDefinition<object>, basePath?: string, fetchFn?: typeof fetch): SmrtCrudFetchers;
18
19
 
@@ -699,6 +700,13 @@ export declare interface SmrtWebCollection<TData extends object> {
699
700
  export declare interface SmrtWebCollectionDefinition<TData extends object = object> {
700
701
  /** REST collection name (e.g. `products`). */
701
702
  name: string;
703
+ /**
704
+ * Canonical qualified model identity (e.g.
705
+ * `@happyvertical/smrt-products:Product`). Generated definitions always
706
+ * provide it; optional here for source compatibility with manual literals
707
+ * authored before policy-aware web collections.
708
+ */
709
+ objectRef?: string;
702
710
  /** Source class name (e.g. `Product`). */
703
711
  className: string;
704
712
  /** Path under the API base path (e.g. `/products`). */
@@ -907,11 +915,14 @@ export declare type SmrtWebRelationshipKind = 'foreignKey' | 'crossPackageRef' |
907
915
  * Raised when a generated-client call resolved with an error payload
908
916
  * (`{ error: string }` from the generated REST routes) or an unexpected shape.
909
917
  * Thrown inside a mutation handler, this triggers the automatic rollback of
910
- * optimistic state.
918
+ * optimistic state. HTTP 5xx failures are always opaque: their server payload
919
+ * is neither parsed nor retained because it may contain internal detail.
911
920
  */
912
921
  export declare class SmrtWebRequestError extends Error {
913
922
  readonly payload: unknown;
914
- constructor(message: string, payload?: unknown);
923
+ readonly status?: number;
924
+ readonly code?: string;
925
+ constructor(message: string, payload?: unknown, status?: number, code?: string);
915
926
  }
916
927
 
917
928
  /** A row as stored in the client collection: the DTO plus a required key. */
package/dist/index.js CHANGED
@@ -1529,12 +1529,32 @@ async function dispatch(fetchers, definition, action, args) {
1529
1529
  //#region src/index.ts
1530
1530
  var SmrtWebRequestError = class extends Error {
1531
1531
  payload;
1532
- constructor(message, payload) {
1532
+ status;
1533
+ code;
1534
+ constructor(message, payload, status, code) {
1533
1535
  super(message);
1534
1536
  this.name = "SmrtWebRequestError";
1535
1537
  this.payload = payload;
1538
+ if (status !== void 0) this.status = status;
1539
+ if (code !== void 0) this.code = code;
1536
1540
  }
1537
1541
  };
1542
+ function getWebErrorDetail(payload) {
1543
+ if (!payload || typeof payload !== "object") return {};
1544
+ const error = payload.error;
1545
+ if (typeof error === "string") return { message: error };
1546
+ if (!error || typeof error !== "object" || Array.isArray(error)) return {};
1547
+ const failure = error;
1548
+ return {
1549
+ message: typeof failure.message === "string" ? failure.message : void 0,
1550
+ code: typeof failure.code === "string" ? failure.code : void 0
1551
+ };
1552
+ }
1553
+ function createHttpRequestError(collectionName, status, payload) {
1554
+ if (status >= 500) return new SmrtWebRequestError(`[smrt-web] ${collectionName} request failed: server error`, void 0, status);
1555
+ const detail = getWebErrorDetail(payload);
1556
+ return new SmrtWebRequestError(`[smrt-web] ${collectionName} request failed: ${detail.message ?? `HTTP ${status}`}`, payload, status, detail.code);
1557
+ }
1538
1558
  function unwrapListResult(result, collectionName) {
1539
1559
  if (Array.isArray(result)) return result;
1540
1560
  if (result && typeof result === "object") {
@@ -1584,12 +1604,12 @@ function createDefinitionFetchers(definition, basePath = "/api/v1", fetchFn = (.
1584
1604
  const collectionUrl = `${basePath}${definition.endpoint}`;
1585
1605
  const headers = { "Content-Type": "application/json" };
1586
1606
  const parse = async (response) => {
1587
- const payload = await response.json().catch(() => null);
1588
1607
  if (!response.ok) {
1589
- const message = payload && typeof payload === "object" && typeof payload.error === "string" ? String(payload.error) : `HTTP ${response.status}`;
1590
- throw new SmrtWebRequestError(`[smrt-web] ${definition.name} request failed: ${message}`, payload);
1608
+ if (response.status >= 500) throw createHttpRequestError(definition.name, response.status);
1609
+ const payload = await response.json().catch(() => null);
1610
+ throw createHttpRequestError(definition.name, response.status, payload);
1591
1611
  }
1592
- return payload;
1612
+ return response.json().catch(() => null);
1593
1613
  };
1594
1614
  return {
1595
1615
  list: async (params) => parse(await fetchFn(`${collectionUrl}${buildListQuery(params)}`, { headers })),
@@ -1609,7 +1629,11 @@ function createDefinitionFetchers(definition, basePath = "/api/v1", fetchFn = (.
1609
1629
  method: "DELETE",
1610
1630
  headers
1611
1631
  });
1612
- if (!response.ok) throw new SmrtWebRequestError(`[smrt-web] delete(${definition.name}) failed: HTTP ${response.status}`);
1632
+ if (!response.ok) {
1633
+ if (response.status >= 500) throw createHttpRequestError(definition.name, response.status);
1634
+ const payload = await response.json().catch(() => null);
1635
+ throw createHttpRequestError(definition.name, response.status, payload);
1636
+ }
1613
1637
  return true;
1614
1638
  }
1615
1639
  };