@softr/sdk 0.0.45-alpha.1 → 0.0.45-alpha.3
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/boot-error.js
CHANGED
|
@@ -69,16 +69,21 @@ function errorPage(error) {
|
|
|
69
69
|
setOpen(toggle.getAttribute('aria-expanded') === 'false')
|
|
70
70
|
})
|
|
71
71
|
|
|
72
|
-
|
|
73
|
-
const button = event.currentTarget
|
|
72
|
+
const copyStack = async () => {
|
|
74
73
|
try {
|
|
75
74
|
await navigator.clipboard.writeText(stack.textContent)
|
|
76
|
-
|
|
77
|
-
setTimeout(() => delete button.dataset.copied, 1500)
|
|
75
|
+
return true
|
|
78
76
|
} catch {
|
|
79
|
-
// Denied clipboard permission. Select it so Ctrl/Cmd+C works.
|
|
80
77
|
getSelection().selectAllChildren(stack)
|
|
78
|
+
return document.execCommand('copy')
|
|
81
79
|
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
document.getElementById('copy').addEventListener('click', async (event) => {
|
|
83
|
+
const button = event.currentTarget
|
|
84
|
+
if (!(await copyStack())) return
|
|
85
|
+
button.dataset.copied = ''
|
|
86
|
+
setTimeout(() => delete button.dataset.copied, 1500)
|
|
82
87
|
})
|
|
83
88
|
<\/script>` : ""
|
|
84
89
|
});
|
package/dist/datasource/chart.js
CHANGED
|
@@ -4,7 +4,7 @@ import { readUserTimezone } from "../cookies.js";
|
|
|
4
4
|
import { readSessionToken } from "../auth/session.js";
|
|
5
5
|
import { INTERNAL_KIND, buildFilterCriteria, buildOrderBy, dealiasFilterCriteria } from "./filter.js";
|
|
6
6
|
import { andAll, makeFieldSet, makeSortSet } from "./fields.js";
|
|
7
|
-
import { dsUrl, resolveTarget } from "./record.js";
|
|
7
|
+
import { describeFailure, dsUrl, resolveTarget } from "./record.js";
|
|
8
8
|
|
|
9
9
|
//#region src/datasource/chart.ts
|
|
10
10
|
const COUNT_CNT = "COUNT_CNT";
|
|
@@ -202,7 +202,7 @@ async function executeChart(query, state) {
|
|
|
202
202
|
},
|
|
203
203
|
body: JSON.stringify(body)
|
|
204
204
|
});
|
|
205
|
-
if (!res.ok) throw new Error(`
|
|
205
|
+
if (!res.ok) throw new Error(`datasource chart failed for action "${actionId}": ${await describeFailure(res)}`);
|
|
206
206
|
const payload = await res.json();
|
|
207
207
|
return {
|
|
208
208
|
data: mapChartRows(columns, payload.data),
|
|
@@ -275,7 +275,7 @@ async function executeMetric(query, handle, filters) {
|
|
|
275
275
|
},
|
|
276
276
|
body: JSON.stringify(body)
|
|
277
277
|
});
|
|
278
|
-
if (!res.ok) throw new Error(`
|
|
278
|
+
if (!res.ok) throw new Error(`datasource metric failed for action "${actionId}": ${await describeFailure(res)}`);
|
|
279
279
|
const payload = await res.json();
|
|
280
280
|
return {
|
|
281
281
|
value: readMetricValue(responseKey, payload.data),
|
|
@@ -15,6 +15,11 @@ const dsUrl = (actionId) => {
|
|
|
15
15
|
if (!applicationId) panic("SOFTR_APPLICATION_ID is not set.");
|
|
16
16
|
return `${withoutTrailingSlash(datasourceApiUrl)}/v1/datasource/vibe/applications/${applicationId}/actions/${actionId}`;
|
|
17
17
|
};
|
|
18
|
+
async function describeFailure(res) {
|
|
19
|
+
const body = await res.json().catch(() => null);
|
|
20
|
+
const message = typeof body === "object" && body !== null && "message" in body ? body.message : null;
|
|
21
|
+
return typeof message === "string" && message.length > 0 ? `${res.status} ${message}` : `${res.status}`;
|
|
22
|
+
}
|
|
18
23
|
/**
|
|
19
24
|
* Queries a list of records from the datasource.
|
|
20
25
|
*
|
|
@@ -87,7 +92,7 @@ async function executeList(query, args) {
|
|
|
87
92
|
}
|
|
88
93
|
})
|
|
89
94
|
});
|
|
90
|
-
if (!res.ok) throw new Error(`
|
|
95
|
+
if (!res.ok) throw new Error(`datasource list failed for "${actionId}": ${await describeFailure(res)}`);
|
|
91
96
|
const payload = await res.json();
|
|
92
97
|
const nextOffset = payload.offset < payload.total ? payload.offset : null;
|
|
93
98
|
return {
|
|
@@ -153,7 +158,7 @@ async function executeGet(query, id, filters) {
|
|
|
153
158
|
filterCriteria
|
|
154
159
|
})
|
|
155
160
|
});
|
|
156
|
-
if (!res.ok) throw new Error(`
|
|
161
|
+
if (!res.ok) throw new Error(`datasource get failed for action "${actionId}": ${await describeFailure(res)}`);
|
|
157
162
|
const contentLength = res.headers.get("Content-Length");
|
|
158
163
|
if (contentLength && parseInt(contentLength, 10) === 0) return null;
|
|
159
164
|
const record = await res.json();
|
|
@@ -182,7 +187,7 @@ async function createRecord(action, options) {
|
|
|
182
187
|
},
|
|
183
188
|
body: JSON.stringify({ fields: rawFields })
|
|
184
189
|
});
|
|
185
|
-
if (!res.ok) throw new Error(`
|
|
190
|
+
if (!res.ok) throw new Error(`datasource create failed for action "${actionId}": ${await describeFailure(res)}`);
|
|
186
191
|
const record = await res.json();
|
|
187
192
|
return {
|
|
188
193
|
id: record.id,
|
|
@@ -199,7 +204,7 @@ async function createRecord(action, options) {
|
|
|
199
204
|
* })
|
|
200
205
|
*/
|
|
201
206
|
async function updateRecord(action, options) {
|
|
202
|
-
if (!options.id) throw new Error(`
|
|
207
|
+
if (!options.id) throw new Error(`datasource update: id must not be empty`);
|
|
203
208
|
const { actionId, select } = resolveTarget(action, "update");
|
|
204
209
|
const data = options.data;
|
|
205
210
|
const rawFields = dealiasData(data, select);
|
|
@@ -211,7 +216,7 @@ async function updateRecord(action, options) {
|
|
|
211
216
|
},
|
|
212
217
|
body: JSON.stringify({ fields: rawFields })
|
|
213
218
|
});
|
|
214
|
-
if (!res.ok) throw new Error(`
|
|
219
|
+
if (!res.ok) throw new Error(`datasource update failed for action "${actionId}": ${await describeFailure(res)}`);
|
|
215
220
|
const record = await res.json();
|
|
216
221
|
return {
|
|
217
222
|
id: record.id,
|
|
@@ -230,7 +235,7 @@ async function deleteRecord(action, options) {
|
|
|
230
235
|
method: "DELETE",
|
|
231
236
|
headers: { Authorization: `Bearer ${readSessionToken()}` }
|
|
232
237
|
});
|
|
233
|
-
if (!res.ok) throw new Error(`
|
|
238
|
+
if (!res.ok) throw new Error(`datasource delete failed for action "${actionId}": ${await describeFailure(res)}`);
|
|
234
239
|
}
|
|
235
240
|
function resolveTarget(subject, operation) {
|
|
236
241
|
const declaredBy = operation === "read" ? "defineQuery" : "defineMutation";
|
|
@@ -244,7 +249,7 @@ function resolveTarget(subject, operation) {
|
|
|
244
249
|
}
|
|
245
250
|
function aliasFields(fields, aliases) {
|
|
246
251
|
const result = {};
|
|
247
|
-
for (const [alias, fieldId] of Object.entries(aliases)) result[alias] = fields[fieldId];
|
|
252
|
+
for (const [alias, fieldId] of Object.entries(aliases)) result[alias] = fields[fieldId] ?? null;
|
|
248
253
|
return result;
|
|
249
254
|
}
|
|
250
255
|
function dealiasData(data, select) {
|
|
@@ -257,4 +262,4 @@ function withoutTrailingSlash(url) {
|
|
|
257
262
|
}
|
|
258
263
|
|
|
259
264
|
//#endregion
|
|
260
|
-
export { createRecord, deleteRecord, dsUrl, getRecord, listRecords, resolveTarget, updateRecord };
|
|
265
|
+
export { createRecord, deleteRecord, describeFailure, dsUrl, getRecord, listRecords, resolveTarget, updateRecord };
|
|
@@ -65,15 +65,20 @@ function StackTrace({ stack }) {
|
|
|
65
65
|
const [copied, setCopied] = useState(false);
|
|
66
66
|
const ref = useRef(null);
|
|
67
67
|
if (!cleaned) return null;
|
|
68
|
-
async function
|
|
68
|
+
async function copyStack() {
|
|
69
69
|
try {
|
|
70
70
|
await navigator.clipboard.writeText(cleaned);
|
|
71
|
-
|
|
72
|
-
setTimeout(() => setCopied(false), 1500);
|
|
71
|
+
return true;
|
|
73
72
|
} catch {
|
|
74
73
|
if (ref.current) getSelection()?.selectAllChildren(ref.current);
|
|
74
|
+
return document.execCommand("copy");
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
|
+
async function copy() {
|
|
78
|
+
if (!await copyStack()) return;
|
|
79
|
+
setCopied(true);
|
|
80
|
+
setTimeout(() => setCopied(false), 1500);
|
|
81
|
+
}
|
|
77
82
|
return /* @__PURE__ */ jsxs("div", {
|
|
78
83
|
style: {
|
|
79
84
|
display: "flex",
|
package/dist/package.js
CHANGED
package/package.json
CHANGED
|
@@ -1,37 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@softr/sdk",
|
|
3
|
-
"version": "0.0.45-alpha.
|
|
3
|
+
"version": "0.0.45-alpha.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
|
-
".": {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
"./server": {
|
|
15
|
-
"types": "./dist/server.d.ts",
|
|
16
|
-
"import": "./dist/server.js"
|
|
17
|
-
},
|
|
18
|
-
"./vite": {
|
|
19
|
-
"types": "./dist/vite.d.ts",
|
|
20
|
-
"import": "./dist/vite.js"
|
|
21
|
-
}
|
|
22
|
-
},
|
|
23
|
-
"bin": {
|
|
24
|
-
"softr-sdk": "./dist/cli.js"
|
|
25
|
-
},
|
|
26
|
-
"files": [
|
|
27
|
-
"dist",
|
|
28
|
-
"schema",
|
|
29
|
-
"skills",
|
|
30
|
-
"!skills/_artifacts"
|
|
31
|
-
],
|
|
32
|
-
"publishConfig": {
|
|
33
|
-
"access": "public"
|
|
34
|
-
},
|
|
6
|
+
".": { "types": "./dist/index.d.ts", "import": "./dist/index.js" },
|
|
7
|
+
"./client": { "types": "./dist/client.d.ts", "import": "./dist/client.js" },
|
|
8
|
+
"./server": { "types": "./dist/server.d.ts", "import": "./dist/server.js" },
|
|
9
|
+
"./vite": { "types": "./dist/vite.d.ts", "import": "./dist/vite.js" }
|
|
10
|
+
},
|
|
11
|
+
"bin": { "softr-sdk": "./dist/cli.js" },
|
|
12
|
+
"files": ["dist", "schema", "skills", "!skills/_artifacts"],
|
|
13
|
+
"publishConfig": { "access": "public" },
|
|
35
14
|
"scripts": {
|
|
36
15
|
"build": "tsdown",
|
|
37
16
|
"test": "node --import ./src/test-utils/setup.ts --test",
|
|
@@ -63,9 +42,7 @@
|
|
|
63
42
|
"optional": true
|
|
64
43
|
}
|
|
65
44
|
},
|
|
66
|
-
"keywords": [
|
|
67
|
-
"tanstack-intent"
|
|
68
|
-
],
|
|
45
|
+
"keywords": ["tanstack-intent"],
|
|
69
46
|
"intent": {
|
|
70
47
|
"version": 1,
|
|
71
48
|
"repo": "@softr/sdk",
|
|
@@ -179,7 +179,7 @@ ds.list(products).where((q) => q.status.is(selectedStatusId))
|
|
|
179
179
|
|
|
180
180
|
Skip this request when the options are predefined and fixed — hardcode them instead.
|
|
181
181
|
|
|
182
|
-
A read the datasource turns down throws rather than coming back empty, and it throws a plain `Error` carrying the status. There is no typed predicate to narrow it with. Handle it where you would handle any other failed fetch: an `errorComponent` on the route, or a check in the handler.
|
|
182
|
+
A read the datasource turns down throws rather than coming back empty, and it throws a plain `Error` carrying the status, followed by the reason the datasource gives when it sends one. There is no typed predicate to narrow it with. Handle it where you would handle any other failed fetch: an `errorComponent` on the route, or a check in the handler.
|
|
183
183
|
|
|
184
184
|
## Typing
|
|
185
185
|
|