@object-ui/data-objectstack 5.0.1 → 5.0.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/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # @object-ui/data-objectstack
2
2
 
3
+ ## 5.0.2
4
+
5
+ ### Patch Changes
6
+
7
+ - @object-ui/types@5.0.2
8
+ - @object-ui/core@5.0.2
9
+
3
10
  ## 5.0.1
4
11
 
5
12
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -2126,6 +2126,63 @@ var ObjectStackAdapter = class {
2126
2126
  }
2127
2127
  return response.json();
2128
2128
  }
2129
+ /**
2130
+ * Cancel (recall) the active pending approval request for a given record.
2131
+ *
2132
+ * Looks up the most recent `sys_approval_request` for the (object, record)
2133
+ * pair whose status is `pending` or `in_approval`, then issues a POST to
2134
+ * `/api/v1/approvals/requests/:id/recall`. The submitter is the only role
2135
+ * permitted to recall on the server — non-submitters will receive a 403.
2136
+ *
2137
+ * On success, the backend mirrors `approval_status = 'recalled'` onto the
2138
+ * source record so the lock badge disappears on next fetch.
2139
+ */
2140
+ async cancelPendingApproval(objectName, recordId) {
2141
+ await this.connect();
2142
+ const listUrl = `${this.baseUrl}/api/v1/approvals/requests?recordId=${encodeURIComponent(recordId)}&object=${encodeURIComponent(objectName)}`;
2143
+ const listRes = await this.fetchImpl(listUrl, {
2144
+ method: "GET",
2145
+ headers: { "Content-Type": "application/json", ...this.getAuthHeaders() }
2146
+ });
2147
+ if (!listRes.ok) {
2148
+ throw new ObjectStackError(
2149
+ `Failed to look up approval requests (status ${listRes.status})`,
2150
+ "APPROVAL_LOOKUP_FAILED",
2151
+ listRes.status
2152
+ );
2153
+ }
2154
+ const listBody = await listRes.json().catch(() => ({}));
2155
+ const rows = Array.isArray(listBody) ? listBody : listBody?.data ?? [];
2156
+ const pending = rows.find(
2157
+ (r) => r?.status === "pending" || r?.status === "in_approval"
2158
+ );
2159
+ if (!pending?.id) {
2160
+ throw new ObjectStackError(
2161
+ "No pending approval request found for this record",
2162
+ "NO_PENDING_REQUEST",
2163
+ 404
2164
+ );
2165
+ }
2166
+ const url = `${this.baseUrl}/api/v1/approvals/requests/${encodeURIComponent(pending.id)}/recall`;
2167
+ const response = await this.fetchImpl(url, {
2168
+ method: "POST",
2169
+ headers: {
2170
+ "Content-Type": "application/json",
2171
+ ...this.getAuthHeaders()
2172
+ },
2173
+ body: JSON.stringify({})
2174
+ });
2175
+ if (!response.ok) {
2176
+ const err = await response.json().catch(() => ({}));
2177
+ throw new ObjectStackError(
2178
+ err?.error || err?.message || `Recall failed with status ${response.status}`,
2179
+ err?.code || "APPROVAL_RECALL_FAILED",
2180
+ response.status
2181
+ );
2182
+ }
2183
+ const body = await response.json().catch(() => ({}));
2184
+ return { requestId: pending.id, status: body?.data?.request?.status ?? "recalled" };
2185
+ }
2129
2186
  /**
2130
2187
  * Get authorization headers from the adapter config.
2131
2188
  */
package/dist/index.d.cts CHANGED
@@ -1104,6 +1104,21 @@ declare class ObjectStackAdapter<T = unknown> implements DataSource<T> {
1104
1104
  metadata?: Record<string, unknown>;
1105
1105
  onProgress?: (percent: number) => void;
1106
1106
  }): Promise<FileUploadResult[]>;
1107
+ /**
1108
+ * Cancel (recall) the active pending approval request for a given record.
1109
+ *
1110
+ * Looks up the most recent `sys_approval_request` for the (object, record)
1111
+ * pair whose status is `pending` or `in_approval`, then issues a POST to
1112
+ * `/api/v1/approvals/requests/:id/recall`. The submitter is the only role
1113
+ * permitted to recall on the server — non-submitters will receive a 403.
1114
+ *
1115
+ * On success, the backend mirrors `approval_status = 'recalled'` onto the
1116
+ * source record so the lock badge disappears on next fetch.
1117
+ */
1118
+ cancelPendingApproval(objectName: string, recordId: string): Promise<{
1119
+ requestId: string;
1120
+ status: string;
1121
+ }>;
1107
1122
  /**
1108
1123
  * Get authorization headers from the adapter config.
1109
1124
  */
package/dist/index.d.ts CHANGED
@@ -1104,6 +1104,21 @@ declare class ObjectStackAdapter<T = unknown> implements DataSource<T> {
1104
1104
  metadata?: Record<string, unknown>;
1105
1105
  onProgress?: (percent: number) => void;
1106
1106
  }): Promise<FileUploadResult[]>;
1107
+ /**
1108
+ * Cancel (recall) the active pending approval request for a given record.
1109
+ *
1110
+ * Looks up the most recent `sys_approval_request` for the (object, record)
1111
+ * pair whose status is `pending` or `in_approval`, then issues a POST to
1112
+ * `/api/v1/approvals/requests/:id/recall`. The submitter is the only role
1113
+ * permitted to recall on the server — non-submitters will receive a 403.
1114
+ *
1115
+ * On success, the backend mirrors `approval_status = 'recalled'` onto the
1116
+ * source record so the lock badge disappears on next fetch.
1117
+ */
1118
+ cancelPendingApproval(objectName: string, recordId: string): Promise<{
1119
+ requestId: string;
1120
+ status: string;
1121
+ }>;
1107
1122
  /**
1108
1123
  * Get authorization headers from the adapter config.
1109
1124
  */
package/dist/index.js CHANGED
@@ -2082,6 +2082,63 @@ var ObjectStackAdapter = class {
2082
2082
  }
2083
2083
  return response.json();
2084
2084
  }
2085
+ /**
2086
+ * Cancel (recall) the active pending approval request for a given record.
2087
+ *
2088
+ * Looks up the most recent `sys_approval_request` for the (object, record)
2089
+ * pair whose status is `pending` or `in_approval`, then issues a POST to
2090
+ * `/api/v1/approvals/requests/:id/recall`. The submitter is the only role
2091
+ * permitted to recall on the server — non-submitters will receive a 403.
2092
+ *
2093
+ * On success, the backend mirrors `approval_status = 'recalled'` onto the
2094
+ * source record so the lock badge disappears on next fetch.
2095
+ */
2096
+ async cancelPendingApproval(objectName, recordId) {
2097
+ await this.connect();
2098
+ const listUrl = `${this.baseUrl}/api/v1/approvals/requests?recordId=${encodeURIComponent(recordId)}&object=${encodeURIComponent(objectName)}`;
2099
+ const listRes = await this.fetchImpl(listUrl, {
2100
+ method: "GET",
2101
+ headers: { "Content-Type": "application/json", ...this.getAuthHeaders() }
2102
+ });
2103
+ if (!listRes.ok) {
2104
+ throw new ObjectStackError(
2105
+ `Failed to look up approval requests (status ${listRes.status})`,
2106
+ "APPROVAL_LOOKUP_FAILED",
2107
+ listRes.status
2108
+ );
2109
+ }
2110
+ const listBody = await listRes.json().catch(() => ({}));
2111
+ const rows = Array.isArray(listBody) ? listBody : listBody?.data ?? [];
2112
+ const pending = rows.find(
2113
+ (r) => r?.status === "pending" || r?.status === "in_approval"
2114
+ );
2115
+ if (!pending?.id) {
2116
+ throw new ObjectStackError(
2117
+ "No pending approval request found for this record",
2118
+ "NO_PENDING_REQUEST",
2119
+ 404
2120
+ );
2121
+ }
2122
+ const url = `${this.baseUrl}/api/v1/approvals/requests/${encodeURIComponent(pending.id)}/recall`;
2123
+ const response = await this.fetchImpl(url, {
2124
+ method: "POST",
2125
+ headers: {
2126
+ "Content-Type": "application/json",
2127
+ ...this.getAuthHeaders()
2128
+ },
2129
+ body: JSON.stringify({})
2130
+ });
2131
+ if (!response.ok) {
2132
+ const err = await response.json().catch(() => ({}));
2133
+ throw new ObjectStackError(
2134
+ err?.error || err?.message || `Recall failed with status ${response.status}`,
2135
+ err?.code || "APPROVAL_RECALL_FAILED",
2136
+ response.status
2137
+ );
2138
+ }
2139
+ const body = await response.json().catch(() => ({}));
2140
+ return { requestId: pending.id, status: body?.data?.request?.status ?? "recalled" };
2141
+ }
2085
2142
  /**
2086
2143
  * Get authorization headers from the adapter config.
2087
2144
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@object-ui/data-objectstack",
3
- "version": "5.0.1",
3
+ "version": "5.0.2",
4
4
  "description": "ObjectStack Data Adapter for Object UI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -22,9 +22,9 @@
22
22
  "LICENSE"
23
23
  ],
24
24
  "dependencies": {
25
- "@objectstack/client": "^4.0.5",
26
- "@object-ui/core": "5.0.1",
27
- "@object-ui/types": "5.0.1"
25
+ "@objectstack/client": "^4.1.1",
26
+ "@object-ui/core": "5.0.2",
27
+ "@object-ui/types": "5.0.2"
28
28
  },
29
29
  "devDependencies": {
30
30
  "tsup": "^8.5.1",
package/src/index.ts CHANGED
@@ -1728,6 +1728,75 @@ export class ObjectStackAdapter<T = unknown> implements DataSource<T> {
1728
1728
  return response.json();
1729
1729
  }
1730
1730
 
1731
+ /**
1732
+ * Cancel (recall) the active pending approval request for a given record.
1733
+ *
1734
+ * Looks up the most recent `sys_approval_request` for the (object, record)
1735
+ * pair whose status is `pending` or `in_approval`, then issues a POST to
1736
+ * `/api/v1/approvals/requests/:id/recall`. The submitter is the only role
1737
+ * permitted to recall on the server — non-submitters will receive a 403.
1738
+ *
1739
+ * On success, the backend mirrors `approval_status = 'recalled'` onto the
1740
+ * source record so the lock badge disappears on next fetch.
1741
+ */
1742
+ async cancelPendingApproval(
1743
+ objectName: string,
1744
+ recordId: string,
1745
+ ): Promise<{ requestId: string; status: string }> {
1746
+ await this.connect();
1747
+
1748
+ // Use the approvals service REST endpoint directly. The generic
1749
+ // `/api/v1/data/sys_approval_request` route applies record-sharing
1750
+ // ACLs that the approvals collection isn't always registered for,
1751
+ // so prefer the cross-cutting `/approvals/requests` endpoint which
1752
+ // is owned by the approvals service itself.
1753
+ const listUrl = `${this.baseUrl}/api/v1/approvals/requests?recordId=${encodeURIComponent(recordId)}&object=${encodeURIComponent(objectName)}`;
1754
+ const listRes = await this.fetchImpl(listUrl, {
1755
+ method: 'GET',
1756
+ headers: { 'Content-Type': 'application/json', ...this.getAuthHeaders() },
1757
+ });
1758
+ if (!listRes.ok) {
1759
+ throw new ObjectStackError(
1760
+ `Failed to look up approval requests (status ${listRes.status})`,
1761
+ 'APPROVAL_LOOKUP_FAILED',
1762
+ listRes.status,
1763
+ );
1764
+ }
1765
+ const listBody: any = await listRes.json().catch(() => ({}));
1766
+ const rows: any[] = Array.isArray(listBody) ? listBody : (listBody?.data ?? []);
1767
+ const pending = rows.find(
1768
+ (r) => r?.status === 'pending' || r?.status === 'in_approval',
1769
+ );
1770
+ if (!pending?.id) {
1771
+ throw new ObjectStackError(
1772
+ 'No pending approval request found for this record',
1773
+ 'NO_PENDING_REQUEST',
1774
+ 404,
1775
+ );
1776
+ }
1777
+
1778
+ const url = `${this.baseUrl}/api/v1/approvals/requests/${encodeURIComponent(pending.id)}/recall`;
1779
+ const response = await this.fetchImpl(url, {
1780
+ method: 'POST',
1781
+ headers: {
1782
+ 'Content-Type': 'application/json',
1783
+ ...this.getAuthHeaders(),
1784
+ },
1785
+ body: JSON.stringify({}),
1786
+ });
1787
+
1788
+ if (!response.ok) {
1789
+ const err: any = await response.json().catch(() => ({}));
1790
+ throw new ObjectStackError(
1791
+ err?.error || err?.message || `Recall failed with status ${response.status}`,
1792
+ err?.code || 'APPROVAL_RECALL_FAILED',
1793
+ response.status,
1794
+ );
1795
+ }
1796
+ const body: any = await response.json().catch(() => ({}));
1797
+ return { requestId: pending.id, status: body?.data?.request?.status ?? 'recalled' };
1798
+ }
1799
+
1731
1800
  /**
1732
1801
  * Get authorization headers from the adapter config.
1733
1802
  */