@happyvertical/smrt-web 0.40.59 → 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 +16 -3
- package/dist/index.js +30 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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
|
-
*
|
|
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`). */
|
|
@@ -828,6 +836,8 @@ export declare interface SmrtWebEventSubscriberConfig {
|
|
|
828
836
|
export declare interface SmrtWebFieldDefinition {
|
|
829
837
|
type: SmrtWebFieldType;
|
|
830
838
|
required?: boolean;
|
|
839
|
+
/** Whether the public field contract explicitly permits `null`. */
|
|
840
|
+
nullable?: boolean;
|
|
831
841
|
default?: unknown;
|
|
832
842
|
/** Developer-authored `@field({ description })` (#2046) — end-user help seed. */
|
|
833
843
|
description?: string;
|
|
@@ -905,11 +915,14 @@ export declare type SmrtWebRelationshipKind = 'foreignKey' | 'crossPackageRef' |
|
|
|
905
915
|
* Raised when a generated-client call resolved with an error payload
|
|
906
916
|
* (`{ error: string }` from the generated REST routes) or an unexpected shape.
|
|
907
917
|
* Thrown inside a mutation handler, this triggers the automatic rollback of
|
|
908
|
-
* 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.
|
|
909
920
|
*/
|
|
910
921
|
export declare class SmrtWebRequestError extends Error {
|
|
911
922
|
readonly payload: unknown;
|
|
912
|
-
|
|
923
|
+
readonly status?: number;
|
|
924
|
+
readonly code?: string;
|
|
925
|
+
constructor(message: string, payload?: unknown, status?: number, code?: string);
|
|
913
926
|
}
|
|
914
927
|
|
|
915
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
|
-
|
|
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
|
-
|
|
1590
|
-
|
|
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
|
|
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)
|
|
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
|
};
|