grist-widget-sdk 0.3.26 → 0.4.0
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 +53 -0
- package/README.md +1 -1
- package/dist/app.cjs +1139 -4336
- package/dist/app.cjs.map +1 -1
- package/dist/app.d.cts +1 -3
- package/dist/app.d.ts +1 -3
- package/dist/app.js +9 -517
- package/dist/app.js.map +1 -1
- package/dist/chunk-4ZGVKGDF.js +204 -0
- package/dist/chunk-4ZGVKGDF.js.map +1 -0
- package/dist/{chunk-YQNMIL33.js → chunk-B5ZZNLVS.js} +528 -181
- package/dist/chunk-B5ZZNLVS.js.map +1 -0
- package/dist/chunk-O7NY46QY.js +1830 -0
- package/dist/chunk-O7NY46QY.js.map +1 -0
- package/dist/chunk-P6VTEKWO.js +618 -0
- package/dist/chunk-P6VTEKWO.js.map +1 -0
- package/dist/emulator/testing.cjs +2084 -391
- package/dist/emulator/testing.cjs.map +1 -1
- package/dist/emulator/testing.d.cts +55 -7
- package/dist/emulator/testing.d.ts +55 -7
- package/dist/emulator/testing.js +144 -19
- package/dist/emulator/testing.js.map +1 -1
- package/dist/emulator.cjs +59 -249
- package/dist/emulator.cjs.map +1 -1
- package/dist/emulator.d.cts +3 -5
- package/dist/emulator.d.ts +3 -5
- package/dist/emulator.js +5 -11
- package/dist/index.cjs +1373 -4859
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +81 -260
- package/dist/index.d.ts +81 -260
- package/dist/index.js +8 -161
- package/dist/{inline-C7DkvuET.d.cts → templates-CGmRIQBV.d.cts} +89 -35
- package/dist/{inline-DpcT8tV9.d.ts → templates-Cq94qOcf.d.ts} +89 -35
- package/dist/{types-D3JxUCfL.d.cts → types-DBStn0Dk.d.cts} +2 -26
- package/dist/{types-D3JxUCfL.d.ts → types-DBStn0Dk.d.ts} +2 -26
- package/dist/use-grist-BK0eke9K.d.cts +358 -0
- package/dist/use-grist-C5DMZ3wU.d.ts +358 -0
- package/package.json +8 -37
- package/dist/advanced.cjs +0 -2799
- package/dist/advanced.cjs.map +0 -1
- package/dist/advanced.d.cts +0 -822
- package/dist/advanced.d.ts +0 -822
- package/dist/advanced.js +0 -875
- package/dist/advanced.js.map +0 -1
- package/dist/chunk-22U7WAY3.js +0 -463
- package/dist/chunk-22U7WAY3.js.map +0 -1
- package/dist/chunk-64SVRWW7.js +0 -758
- package/dist/chunk-64SVRWW7.js.map +0 -1
- package/dist/chunk-ELGVOHFD.js +0 -32
- package/dist/chunk-ELGVOHFD.js.map +0 -1
- package/dist/chunk-EPEBKXVN.js +0 -470
- package/dist/chunk-EPEBKXVN.js.map +0 -1
- package/dist/chunk-GTTD5HPO.js +0 -36
- package/dist/chunk-GTTD5HPO.js.map +0 -1
- package/dist/chunk-JASMM2YC.js +0 -243
- package/dist/chunk-JASMM2YC.js.map +0 -1
- package/dist/chunk-N3X46JW2.js +0 -37
- package/dist/chunk-N3X46JW2.js.map +0 -1
- package/dist/chunk-PDGEZ24B.js +0 -2366
- package/dist/chunk-PDGEZ24B.js.map +0 -1
- package/dist/chunk-PM3B4WYV.js +0 -12
- package/dist/chunk-PM3B4WYV.js.map +0 -1
- package/dist/chunk-REV5AUXD.js +0 -25
- package/dist/chunk-REV5AUXD.js.map +0 -1
- package/dist/chunk-TZB3OZA6.js +0 -1630
- package/dist/chunk-TZB3OZA6.js.map +0 -1
- package/dist/chunk-YQNMIL33.js.map +0 -1
- package/dist/create-grist-emulator-BCqp1BF9.d.ts +0 -81
- package/dist/create-grist-emulator-DBM8OSIR.d.cts +0 -81
- package/dist/emulator/devtools.cjs +0 -1404
- package/dist/emulator/devtools.cjs.map +0 -1
- package/dist/emulator/devtools.d.cts +0 -48
- package/dist/emulator/devtools.d.ts +0 -48
- package/dist/emulator/devtools.js +0 -508
- package/dist/emulator/devtools.js.map +0 -1
- package/dist/emulator/transports.cjs +0 -1132
- package/dist/emulator/transports.cjs.map +0 -1
- package/dist/emulator/transports.d.cts +0 -38
- package/dist/emulator/transports.d.ts +0 -38
- package/dist/emulator/transports.js +0 -12
- package/dist/emulator/transports.js.map +0 -1
- package/dist/templates-8k2LKoO-.d.cts +0 -24
- package/dist/templates-DIwi_mvI.d.ts +0 -24
- package/dist/use-grist-reads-DUMvJgV7.d.ts +0 -480
- package/dist/use-grist-reads-DpjVuI0H.d.cts +0 -480
- package/dist/use-grist-types-DdOLEJXN.d.cts +0 -499
- package/dist/use-grist-types-kwxoFeub.d.ts +0 -499
- package/dist/use-grist-widget-options-from-context-CGOlQ5Vc.d.cts +0 -43
- package/dist/use-grist-widget-options-from-context-CGOlQ5Vc.d.ts +0 -43
package/dist/chunk-64SVRWW7.js
DELETED
|
@@ -1,758 +0,0 @@
|
|
|
1
|
-
// src/sdk/helpers/grist-value-codec.ts
|
|
2
|
-
var MARSHALLED_TAGS = /* @__PURE__ */ new Set(["E", "L", "D", "d", "R", "r", "P"]);
|
|
3
|
-
function isMarshalledTuple(value) {
|
|
4
|
-
return Array.isArray(value) && typeof value[0] === "string" && value[0].length <= 2 && MARSHALLED_TAGS.has(value[0]);
|
|
5
|
-
}
|
|
6
|
-
function coerceGristDocApiRefRowId(value) {
|
|
7
|
-
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
8
|
-
if (!Array.isArray(value) || value.length < 2) return void 0;
|
|
9
|
-
const tag = value[0];
|
|
10
|
-
if (tag === "R" && typeof value[2] === "number" && Number.isFinite(value[2])) return value[2];
|
|
11
|
-
if (tag === "r" && typeof value[1] === "number" && Number.isFinite(value[1])) return value[1];
|
|
12
|
-
return void 0;
|
|
13
|
-
}
|
|
14
|
-
function looksLikeAttachmentColumn(column) {
|
|
15
|
-
return column?.type === "Attachments";
|
|
16
|
-
}
|
|
17
|
-
function looksLikeChoiceListColumn(column) {
|
|
18
|
-
return column?.type === "ChoiceList";
|
|
19
|
-
}
|
|
20
|
-
function looksLikeRefListColumn(column) {
|
|
21
|
-
return typeof column?.type === "string" && column.type.startsWith("RefList:");
|
|
22
|
-
}
|
|
23
|
-
function looksLikeRefColumn(column) {
|
|
24
|
-
return typeof column?.type === "string" && column.type.startsWith("Ref:");
|
|
25
|
-
}
|
|
26
|
-
function looksLikeDateColumn(column) {
|
|
27
|
-
return column?.type === "Date";
|
|
28
|
-
}
|
|
29
|
-
function looksLikeDateTimeColumn(column) {
|
|
30
|
-
return typeof column?.type === "string" && column.type.startsWith("DateTime");
|
|
31
|
-
}
|
|
32
|
-
function decodeGristValue(value, column) {
|
|
33
|
-
if (value === null || value === void 0) return null;
|
|
34
|
-
if (isMarshalledTuple(value)) {
|
|
35
|
-
const tag = value[0];
|
|
36
|
-
switch (tag) {
|
|
37
|
-
case "E":
|
|
38
|
-
return {
|
|
39
|
-
__error: true,
|
|
40
|
-
type: typeof value[1] === "string" ? value[1] : "Error",
|
|
41
|
-
message: typeof value[2] === "string" ? value[2] : void 0,
|
|
42
|
-
traceback: typeof value[3] === "string" ? value[3] : void 0
|
|
43
|
-
};
|
|
44
|
-
case "L":
|
|
45
|
-
return value.slice(1).map((v) => decodeGristValue(v, void 0));
|
|
46
|
-
case "D":
|
|
47
|
-
if (typeof value[1] === "number") return new Date(value[1] * 1e3);
|
|
48
|
-
return null;
|
|
49
|
-
case "d":
|
|
50
|
-
if (typeof value[1] === "number") return new Date(value[1] * 1e3);
|
|
51
|
-
return null;
|
|
52
|
-
case "R":
|
|
53
|
-
return {
|
|
54
|
-
__ref: true,
|
|
55
|
-
tableId: typeof value[1] === "string" ? value[1] : void 0,
|
|
56
|
-
rowId: typeof value[2] === "number" ? value[2] : 0
|
|
57
|
-
};
|
|
58
|
-
case "r":
|
|
59
|
-
return { __ref: true, rowId: typeof value[1] === "number" ? value[1] : 0 };
|
|
60
|
-
case "P":
|
|
61
|
-
return null;
|
|
62
|
-
default:
|
|
63
|
-
return null;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
if (looksLikeDateColumn(column) || looksLikeDateTimeColumn(column)) {
|
|
67
|
-
if (typeof value === "number" && Number.isFinite(value)) return new Date(value * 1e3);
|
|
68
|
-
}
|
|
69
|
-
if (looksLikeRefColumn(column) && typeof value === "number") {
|
|
70
|
-
return { __ref: true, rowId: value };
|
|
71
|
-
}
|
|
72
|
-
if ((looksLikeRefListColumn(column) || looksLikeChoiceListColumn(column) || looksLikeAttachmentColumn(column)) && Array.isArray(value)) {
|
|
73
|
-
return value.map((v) => decodeGristValue(v, void 0));
|
|
74
|
-
}
|
|
75
|
-
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return value;
|
|
76
|
-
if (Array.isArray(value)) return value.map((v) => decodeGristValue(v, void 0));
|
|
77
|
-
return null;
|
|
78
|
-
}
|
|
79
|
-
function isGristCellError(value) {
|
|
80
|
-
return Array.isArray(value) && value[0] === "E";
|
|
81
|
-
}
|
|
82
|
-
function encodeGristValue(value, column) {
|
|
83
|
-
if (value === null || value === void 0) return null;
|
|
84
|
-
if (looksLikeDateColumn(column) || looksLikeDateTimeColumn(column)) {
|
|
85
|
-
if (value instanceof Date) return Math.floor(value.getTime() / 1e3);
|
|
86
|
-
if (typeof value === "string") {
|
|
87
|
-
const parsed = Date.parse(value);
|
|
88
|
-
if (!Number.isNaN(parsed)) return Math.floor(parsed / 1e3);
|
|
89
|
-
}
|
|
90
|
-
if (typeof value === "number") return Math.floor(value);
|
|
91
|
-
}
|
|
92
|
-
if (looksLikeRefColumn(column)) {
|
|
93
|
-
if (typeof value === "number") return value;
|
|
94
|
-
if (value && typeof value === "object" && "rowId" in value) {
|
|
95
|
-
return value.rowId;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
if (looksLikeRefListColumn(column) || looksLikeChoiceListColumn(column) || looksLikeAttachmentColumn(column)) {
|
|
99
|
-
if (Array.isArray(value)) {
|
|
100
|
-
const items = value.map((v) => {
|
|
101
|
-
if (v && typeof v === "object" && "rowId" in v) return v.rowId;
|
|
102
|
-
return v;
|
|
103
|
-
});
|
|
104
|
-
return ["L", ...items];
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
return value;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// src/sdk/helpers/grist-widget-options.ts
|
|
111
|
-
function parseGristWidgetOptionsCell(raw) {
|
|
112
|
-
if (raw == null || raw === "") return void 0;
|
|
113
|
-
if (typeof raw === "string") {
|
|
114
|
-
try {
|
|
115
|
-
const parsed = JSON.parse(raw);
|
|
116
|
-
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
117
|
-
return parsed;
|
|
118
|
-
}
|
|
119
|
-
} catch {
|
|
120
|
-
return void 0;
|
|
121
|
-
}
|
|
122
|
-
return void 0;
|
|
123
|
-
}
|
|
124
|
-
if (typeof raw === "object" && !Array.isArray(raw)) {
|
|
125
|
-
return raw;
|
|
126
|
-
}
|
|
127
|
-
return void 0;
|
|
128
|
-
}
|
|
129
|
-
function readStyleColor(style, key) {
|
|
130
|
-
const v = style[key];
|
|
131
|
-
return typeof v === "string" ? v : void 0;
|
|
132
|
-
}
|
|
133
|
-
function normalizeGristChoiceListEntries(widgetOptions) {
|
|
134
|
-
if (!widgetOptions) return [];
|
|
135
|
-
const rawChoices = widgetOptions.choices;
|
|
136
|
-
if (!Array.isArray(rawChoices)) return [];
|
|
137
|
-
const choiceOptionsRaw = widgetOptions.choiceOptions;
|
|
138
|
-
const choiceOptions = choiceOptionsRaw && typeof choiceOptionsRaw === "object" && !Array.isArray(choiceOptionsRaw) ? choiceOptionsRaw : {};
|
|
139
|
-
const out = [];
|
|
140
|
-
for (const c of rawChoices) {
|
|
141
|
-
const value = typeof c === "string" ? c : c != null ? String(c) : "";
|
|
142
|
-
if (!value) continue;
|
|
143
|
-
const style = choiceOptions[value] ?? {};
|
|
144
|
-
out.push({
|
|
145
|
-
value,
|
|
146
|
-
label: value,
|
|
147
|
-
fillColor: readStyleColor(style, "fillColor"),
|
|
148
|
-
textColor: readStyleColor(style, "textColor")
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
return out;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
// src/sdk/helpers/grist-safe-parse.ts
|
|
155
|
-
import { z } from "zod";
|
|
156
|
-
var gristSafeRefValueSchema = z.object({
|
|
157
|
-
rowId: z.number(),
|
|
158
|
-
display: z.string().nullable().optional()
|
|
159
|
-
});
|
|
160
|
-
var gristSafeRefListValueSchema = z.object({
|
|
161
|
-
rowIds: z.array(z.number()),
|
|
162
|
-
displays: z.array(z.string()).optional()
|
|
163
|
-
});
|
|
164
|
-
var gristCellValueSchema = z.union([
|
|
165
|
-
z.null(),
|
|
166
|
-
z.string(),
|
|
167
|
-
z.number(),
|
|
168
|
-
z.boolean(),
|
|
169
|
-
z.date(),
|
|
170
|
-
z.array(z.unknown()),
|
|
171
|
-
gristSafeRefValueSchema,
|
|
172
|
-
gristSafeRefListValueSchema
|
|
173
|
-
]);
|
|
174
|
-
function inferDisplayHelpersByRef(columns) {
|
|
175
|
-
const out = {};
|
|
176
|
-
const helperColumns = Object.entries(columns).filter(
|
|
177
|
-
([colId]) => colId.startsWith("gristHelper_")
|
|
178
|
-
);
|
|
179
|
-
const usedHelpers = /* @__PURE__ */ new Set();
|
|
180
|
-
const colRefToColId = /* @__PURE__ */ new Map();
|
|
181
|
-
for (const [colId, col] of Object.entries(columns)) {
|
|
182
|
-
if (typeof col?.colRef === "number" && Number.isFinite(col.colRef)) {
|
|
183
|
-
colRefToColId.set(col.colRef, colId);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
for (const [colId, col] of Object.entries(columns)) {
|
|
187
|
-
const type = col?.type;
|
|
188
|
-
if (typeof type !== "string" || !type.startsWith("Ref:") && !type.startsWith("RefList:")) {
|
|
189
|
-
continue;
|
|
190
|
-
}
|
|
191
|
-
if (typeof col.displayColRef === "number" && Number.isFinite(col.displayColRef)) {
|
|
192
|
-
const helperColId = colRefToColId.get(col.displayColRef);
|
|
193
|
-
if (helperColId) {
|
|
194
|
-
out[colId] = helperColId;
|
|
195
|
-
usedHelpers.add(helperColId);
|
|
196
|
-
continue;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
const match = helperColumns.find(([, helper]) => {
|
|
200
|
-
const formula = helper?.formula;
|
|
201
|
-
return typeof formula === "string" && (formula.includes(`$${colId}.`) || formula.includes(`$${colId}`));
|
|
202
|
-
});
|
|
203
|
-
if (match) {
|
|
204
|
-
out[colId] = match[0];
|
|
205
|
-
usedHelpers.add(match[0]);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
const unresolvedRefs = Object.entries(columns).filter(([colId, col]) => {
|
|
209
|
-
const type = col?.type;
|
|
210
|
-
return !out[colId] && typeof type === "string" && (type.startsWith("Ref:") || type.startsWith("RefList:"));
|
|
211
|
-
}).sort((a, b) => (a[1]?.parentPos ?? Number.MAX_SAFE_INTEGER) - (b[1]?.parentPos ?? Number.MAX_SAFE_INTEGER));
|
|
212
|
-
const helperByPos = helperColumns.filter(([helperId]) => !usedHelpers.has(helperId)).sort((a, b) => (a[1]?.parentPos ?? Number.MAX_SAFE_INTEGER) - (b[1]?.parentPos ?? Number.MAX_SAFE_INTEGER));
|
|
213
|
-
for (const [refId, refCol] of unresolvedRefs) {
|
|
214
|
-
const refPos = refCol?.parentPos ?? Number.MAX_SAFE_INTEGER;
|
|
215
|
-
const candidate = helperByPos.find(([, helperCol]) => {
|
|
216
|
-
const helperPos = helperCol?.parentPos ?? Number.MAX_SAFE_INTEGER;
|
|
217
|
-
return helperPos > refPos;
|
|
218
|
-
});
|
|
219
|
-
if (!candidate) continue;
|
|
220
|
-
out[refId] = candidate[0];
|
|
221
|
-
usedHelpers.add(candidate[0]);
|
|
222
|
-
}
|
|
223
|
-
for (const [refId] of unresolvedRefs) {
|
|
224
|
-
if (out[refId]) continue;
|
|
225
|
-
const candidate = helperByPos.find(([helperId]) => !usedHelpers.has(helperId));
|
|
226
|
-
if (!candidate) continue;
|
|
227
|
-
out[refId] = candidate[0];
|
|
228
|
-
usedHelpers.add(candidate[0]);
|
|
229
|
-
}
|
|
230
|
-
return out;
|
|
231
|
-
}
|
|
232
|
-
function computeRowCount(data) {
|
|
233
|
-
const idCol = data.id;
|
|
234
|
-
if (Array.isArray(idCol)) return idCol.length;
|
|
235
|
-
for (const key of Object.keys(data)) {
|
|
236
|
-
const col = data[key];
|
|
237
|
-
if (Array.isArray(col)) return col.length;
|
|
238
|
-
}
|
|
239
|
-
return 0;
|
|
240
|
-
}
|
|
241
|
-
function manualSortKey(row) {
|
|
242
|
-
const v = row.manualSort;
|
|
243
|
-
if (typeof v === "number" && !Number.isNaN(v)) return v;
|
|
244
|
-
if (typeof v === "string" && v.trim() !== "") {
|
|
245
|
-
const n = Number(v);
|
|
246
|
-
if (!Number.isNaN(n)) return n;
|
|
247
|
-
}
|
|
248
|
-
return null;
|
|
249
|
-
}
|
|
250
|
-
function sortRowsByGristOrder(rows) {
|
|
251
|
-
const hasManual = rows.some((r) => manualSortKey(r) !== null);
|
|
252
|
-
if (!hasManual) {
|
|
253
|
-
return [...rows].sort((a, b) => {
|
|
254
|
-
const ida = typeof a.id === "number" ? a.id : 0;
|
|
255
|
-
const idb = typeof b.id === "number" ? b.id : 0;
|
|
256
|
-
return ida - idb;
|
|
257
|
-
});
|
|
258
|
-
}
|
|
259
|
-
return [...rows].sort((a, b) => {
|
|
260
|
-
const ma = manualSortKey(a);
|
|
261
|
-
const mb = manualSortKey(b);
|
|
262
|
-
if (ma !== null && mb !== null && ma !== mb) return ma - mb;
|
|
263
|
-
if (ma !== null && mb === null) return -1;
|
|
264
|
-
if (ma === null && mb !== null) return 1;
|
|
265
|
-
const ida = typeof a.id === "number" ? a.id : 0;
|
|
266
|
-
const idb = typeof b.id === "number" ? b.id : 0;
|
|
267
|
-
return ida - idb;
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
function columnKind(column) {
|
|
271
|
-
const type = column?.type;
|
|
272
|
-
if (!type) return "unknown";
|
|
273
|
-
if (type === "Text") return "text";
|
|
274
|
-
if (type === "Numeric") return "numeric";
|
|
275
|
-
if (type === "Int") return "int";
|
|
276
|
-
if (type === "Bool") return "bool";
|
|
277
|
-
if (type === "Date") return "date";
|
|
278
|
-
if (type === "DateTime" || type.startsWith("DateTime:")) return "datetime";
|
|
279
|
-
if (type === "Choice") return "choice";
|
|
280
|
-
if (type === "ChoiceList") return "choiceList";
|
|
281
|
-
if (type.startsWith("Ref:")) return "ref";
|
|
282
|
-
if (type.startsWith("RefList:")) return "refList";
|
|
283
|
-
if (type === "Attachments") return "attachments";
|
|
284
|
-
if (type === "Any") return "any";
|
|
285
|
-
return "unknown";
|
|
286
|
-
}
|
|
287
|
-
function primitiveToString(value) {
|
|
288
|
-
if (value === null || value === void 0) return null;
|
|
289
|
-
if (typeof value === "string") return value;
|
|
290
|
-
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
|
|
291
|
-
return String(value);
|
|
292
|
-
}
|
|
293
|
-
return null;
|
|
294
|
-
}
|
|
295
|
-
function normalizeRefDisplay(value) {
|
|
296
|
-
if (value === null || value === void 0) return { value: null };
|
|
297
|
-
if (typeof value === "string") return { value };
|
|
298
|
-
if (typeof value === "number" || typeof value === "boolean") return { value: String(value) };
|
|
299
|
-
return {
|
|
300
|
-
issue: {
|
|
301
|
-
code: "helper_mismatch",
|
|
302
|
-
message: "Ref display helper value should be a scalar value."
|
|
303
|
-
}
|
|
304
|
-
};
|
|
305
|
-
}
|
|
306
|
-
function normalizeRefListDisplays(value) {
|
|
307
|
-
if (value === null || value === void 0) return { values: [] };
|
|
308
|
-
if (typeof value === "string") {
|
|
309
|
-
const s = value.trim();
|
|
310
|
-
if (s === "") return { values: [] };
|
|
311
|
-
if (s.startsWith("[")) {
|
|
312
|
-
try {
|
|
313
|
-
const parsed = JSON.parse(s);
|
|
314
|
-
if (Array.isArray(parsed)) {
|
|
315
|
-
return normalizeRefListDisplays(parsed);
|
|
316
|
-
}
|
|
317
|
-
} catch {
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
if (!Array.isArray(value)) {
|
|
322
|
-
return {
|
|
323
|
-
issue: {
|
|
324
|
-
code: "helper_mismatch",
|
|
325
|
-
message: "RefList display helper value should be an array."
|
|
326
|
-
}
|
|
327
|
-
};
|
|
328
|
-
}
|
|
329
|
-
const items = value.length > 0 && value[0] === "L" ? value.slice(1) : value;
|
|
330
|
-
const out = [];
|
|
331
|
-
for (const item of items) {
|
|
332
|
-
const s = primitiveToString(item);
|
|
333
|
-
if (s === null) {
|
|
334
|
-
return {
|
|
335
|
-
issue: {
|
|
336
|
-
code: "helper_mismatch",
|
|
337
|
-
message: "RefList helper items should be scalar values."
|
|
338
|
-
}
|
|
339
|
-
};
|
|
340
|
-
}
|
|
341
|
-
out.push(s);
|
|
342
|
-
}
|
|
343
|
-
return { values: out };
|
|
344
|
-
}
|
|
345
|
-
function normalizeRefValue(decoded, helperValue, refMode) {
|
|
346
|
-
const issues = [];
|
|
347
|
-
if (decoded === null) return { value: null, issues };
|
|
348
|
-
const rowId = typeof decoded === "number" && Number.isFinite(decoded) ? decoded : decoded && typeof decoded === "object" && "__ref" in decoded ? decoded.rowId : null;
|
|
349
|
-
if (rowId === 0) return { value: null, issues };
|
|
350
|
-
if (rowId === null || !Number.isFinite(rowId)) {
|
|
351
|
-
issues.push({
|
|
352
|
-
code: "type_mismatch",
|
|
353
|
-
message: "Expected a Ref row id."
|
|
354
|
-
});
|
|
355
|
-
return { value: null, issues };
|
|
356
|
-
}
|
|
357
|
-
if (refMode === "id") return { value: rowId, issues };
|
|
358
|
-
const helper = normalizeRefDisplay(helperValue);
|
|
359
|
-
if (helper.issue) issues.push(helper.issue);
|
|
360
|
-
return {
|
|
361
|
-
value: { rowId, display: helper.value },
|
|
362
|
-
issues
|
|
363
|
-
};
|
|
364
|
-
}
|
|
365
|
-
function normalizeRefListValue(decoded, helperValue, refMode) {
|
|
366
|
-
const issues = [];
|
|
367
|
-
if (decoded === null) return { value: null, issues };
|
|
368
|
-
if (!Array.isArray(decoded)) {
|
|
369
|
-
issues.push({
|
|
370
|
-
code: "type_mismatch",
|
|
371
|
-
message: "Expected an array for RefList."
|
|
372
|
-
});
|
|
373
|
-
return { value: null, issues };
|
|
374
|
-
}
|
|
375
|
-
const rowIds = [];
|
|
376
|
-
for (const item of decoded) {
|
|
377
|
-
if (typeof item === "number" && Number.isFinite(item) && item !== 0) {
|
|
378
|
-
rowIds.push(item);
|
|
379
|
-
continue;
|
|
380
|
-
}
|
|
381
|
-
if (item && typeof item === "object" && "__ref" in item) {
|
|
382
|
-
const rowId = item.rowId;
|
|
383
|
-
if (typeof rowId === "number" && Number.isFinite(rowId) && rowId !== 0) {
|
|
384
|
-
rowIds.push(rowId);
|
|
385
|
-
continue;
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
issues.push({
|
|
389
|
-
code: "type_mismatch",
|
|
390
|
-
message: "RefList items should be row ids."
|
|
391
|
-
});
|
|
392
|
-
return { value: null, issues };
|
|
393
|
-
}
|
|
394
|
-
if (refMode === "id") return { value: rowIds, issues };
|
|
395
|
-
const helper = normalizeRefListDisplays(helperValue);
|
|
396
|
-
if (helper.issue) {
|
|
397
|
-
issues.push(helper.issue);
|
|
398
|
-
} else if (helper.values && helper.values.length > 0 && helper.values.length !== rowIds.length) {
|
|
399
|
-
issues.push({
|
|
400
|
-
code: "helper_mismatch",
|
|
401
|
-
message: "RefList helper labels count does not match row ids count."
|
|
402
|
-
});
|
|
403
|
-
}
|
|
404
|
-
return {
|
|
405
|
-
value: { rowIds, displays: helper.values },
|
|
406
|
-
issues
|
|
407
|
-
};
|
|
408
|
-
}
|
|
409
|
-
function normalizeByColumnKind(decoded, kind, helperValue, fallbackUntypedToString, refMode) {
|
|
410
|
-
const issues = [];
|
|
411
|
-
if (decoded && typeof decoded === "object" && "__error" in decoded) {
|
|
412
|
-
issues.push({
|
|
413
|
-
code: "grist_error",
|
|
414
|
-
message: decoded.message ?? "Grist returned a cell error."
|
|
415
|
-
});
|
|
416
|
-
return { value: null, issues };
|
|
417
|
-
}
|
|
418
|
-
switch (kind) {
|
|
419
|
-
case "ref":
|
|
420
|
-
return normalizeRefValue(decoded, helperValue, refMode);
|
|
421
|
-
case "refList":
|
|
422
|
-
return normalizeRefListValue(decoded, helperValue, refMode);
|
|
423
|
-
case "date":
|
|
424
|
-
case "datetime":
|
|
425
|
-
if (decoded === null || decoded instanceof Date) return { value: decoded, issues };
|
|
426
|
-
issues.push({ code: "type_mismatch", message: "Expected a Date value." });
|
|
427
|
-
return { value: null, issues };
|
|
428
|
-
case "bool":
|
|
429
|
-
if (decoded === null || typeof decoded === "boolean") return { value: decoded, issues };
|
|
430
|
-
issues.push({ code: "type_mismatch", message: "Expected a boolean value." });
|
|
431
|
-
return { value: null, issues };
|
|
432
|
-
case "numeric":
|
|
433
|
-
if (decoded === null || typeof decoded === "number" && Number.isFinite(decoded)) {
|
|
434
|
-
return { value: decoded, issues };
|
|
435
|
-
}
|
|
436
|
-
issues.push({ code: "type_mismatch", message: "Expected a numeric value." });
|
|
437
|
-
return {
|
|
438
|
-
value: typeof decoded === "string" || typeof decoded === "number" || typeof decoded === "boolean" ? decoded : null,
|
|
439
|
-
issues
|
|
440
|
-
};
|
|
441
|
-
case "int":
|
|
442
|
-
if (decoded === null || typeof decoded === "number" && Number.isInteger(decoded)) {
|
|
443
|
-
return { value: decoded, issues };
|
|
444
|
-
}
|
|
445
|
-
issues.push({ code: "type_mismatch", message: "Expected an integer value." });
|
|
446
|
-
return {
|
|
447
|
-
value: typeof decoded === "string" || typeof decoded === "number" || typeof decoded === "boolean" ? decoded : null,
|
|
448
|
-
issues
|
|
449
|
-
};
|
|
450
|
-
case "choice":
|
|
451
|
-
case "text":
|
|
452
|
-
if (decoded === null || typeof decoded === "string") return { value: decoded, issues };
|
|
453
|
-
issues.push({ code: "type_mismatch", message: "Expected a string value." });
|
|
454
|
-
return { value: null, issues };
|
|
455
|
-
case "choiceList":
|
|
456
|
-
case "attachments":
|
|
457
|
-
if (decoded === null || Array.isArray(decoded)) return { value: decoded, issues };
|
|
458
|
-
issues.push({ code: "type_mismatch", message: "Expected a list value." });
|
|
459
|
-
return { value: null, issues };
|
|
460
|
-
case "any":
|
|
461
|
-
case "unknown":
|
|
462
|
-
if (helperValue !== void 0) {
|
|
463
|
-
if (typeof decoded === "number" || decoded && typeof decoded === "object" && "__ref" in decoded) {
|
|
464
|
-
return normalizeRefValue(decoded, helperValue, refMode);
|
|
465
|
-
}
|
|
466
|
-
if (Array.isArray(decoded)) {
|
|
467
|
-
return normalizeRefListValue(decoded, helperValue, refMode);
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
if (!fallbackUntypedToString) return { value: decoded, issues };
|
|
471
|
-
if (decoded === null) return { value: null, issues };
|
|
472
|
-
if (typeof decoded === "string") return { value: decoded, issues };
|
|
473
|
-
if (typeof decoded === "number" || typeof decoded === "boolean" || decoded instanceof Date) {
|
|
474
|
-
return {
|
|
475
|
-
value: decoded instanceof Date ? decoded.toISOString() : String(decoded),
|
|
476
|
-
issues
|
|
477
|
-
};
|
|
478
|
-
}
|
|
479
|
-
if (Array.isArray(decoded)) {
|
|
480
|
-
try {
|
|
481
|
-
return { value: JSON.stringify(decoded), issues };
|
|
482
|
-
} catch {
|
|
483
|
-
issues.push({
|
|
484
|
-
code: "invalid_format",
|
|
485
|
-
message: "Unable to stringify list value."
|
|
486
|
-
});
|
|
487
|
-
return { value: null, issues };
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
issues.push({
|
|
491
|
-
code: "type_mismatch",
|
|
492
|
-
message: "Untyped value could not be represented as a string."
|
|
493
|
-
});
|
|
494
|
-
return { value: null, issues };
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
function buildChoiceTokens(col, value) {
|
|
498
|
-
const type = col?.type;
|
|
499
|
-
if (type !== "Choice" && type !== "ChoiceList") return void 0;
|
|
500
|
-
const entries = normalizeGristChoiceListEntries(col?.widgetOptions);
|
|
501
|
-
const byValue = new Map(entries.map((entry) => [entry.value, entry]));
|
|
502
|
-
if (type === "Choice") {
|
|
503
|
-
if (value == null || typeof value !== "string" || value.trim() === "") return [];
|
|
504
|
-
const meta = byValue.get(value);
|
|
505
|
-
if (!meta) return [{ value, label: value, valid: false }];
|
|
506
|
-
return [
|
|
507
|
-
{
|
|
508
|
-
value,
|
|
509
|
-
label: meta.label,
|
|
510
|
-
fillColor: meta.fillColor,
|
|
511
|
-
textColor: meta.textColor,
|
|
512
|
-
valid: true
|
|
513
|
-
}
|
|
514
|
-
];
|
|
515
|
-
}
|
|
516
|
-
if (!Array.isArray(value)) return [];
|
|
517
|
-
const out = [];
|
|
518
|
-
for (const item of value) {
|
|
519
|
-
const v = typeof item === "string" ? item : String(item);
|
|
520
|
-
const meta = byValue.get(v);
|
|
521
|
-
if (!meta) {
|
|
522
|
-
out.push({ value: v, label: v, valid: false });
|
|
523
|
-
continue;
|
|
524
|
-
}
|
|
525
|
-
out.push({
|
|
526
|
-
value: v,
|
|
527
|
-
label: meta.label,
|
|
528
|
-
fillColor: meta.fillColor,
|
|
529
|
-
textColor: meta.textColor,
|
|
530
|
-
valid: true
|
|
531
|
-
});
|
|
532
|
-
}
|
|
533
|
-
return out;
|
|
534
|
-
}
|
|
535
|
-
function safeParseGristValues(options) {
|
|
536
|
-
const fallbackUntypedToString = options.fallbackUntypedToString ?? true;
|
|
537
|
-
const refMode = options.refMode ?? "id";
|
|
538
|
-
const kind = columnKind(options.column);
|
|
539
|
-
return options.values.map((raw, index) => {
|
|
540
|
-
const decoded = decodeGristValue(raw, options.column);
|
|
541
|
-
const helperValue = options.helperValues?.[index];
|
|
542
|
-
const normalized = normalizeByColumnKind(
|
|
543
|
-
decoded,
|
|
544
|
-
kind,
|
|
545
|
-
helperValue,
|
|
546
|
-
fallbackUntypedToString,
|
|
547
|
-
refMode
|
|
548
|
-
);
|
|
549
|
-
const issues = [...normalized.issues];
|
|
550
|
-
if (options.schema) {
|
|
551
|
-
const result = options.schema.safeParse(normalized.value);
|
|
552
|
-
if (!result.success) {
|
|
553
|
-
issues.push({
|
|
554
|
-
code: "zod_error",
|
|
555
|
-
message: result.error.issues.map((issue) => issue.message).join("; ")
|
|
556
|
-
});
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
return {
|
|
560
|
-
ok: issues.length === 0,
|
|
561
|
-
typedValue: normalized.value,
|
|
562
|
-
displayValue: normalized.value,
|
|
563
|
-
raw,
|
|
564
|
-
issues
|
|
565
|
-
};
|
|
566
|
-
});
|
|
567
|
-
}
|
|
568
|
-
function safeParseGristTableData(data, options) {
|
|
569
|
-
const columns = options?.columns ?? {};
|
|
570
|
-
const inferredDisplayHelpersByRef = inferDisplayHelpersByRef(columns);
|
|
571
|
-
const displayHelpersByRef = {
|
|
572
|
-
...inferredDisplayHelpersByRef,
|
|
573
|
-
...options?.displayHelpersByRef ?? {}
|
|
574
|
-
};
|
|
575
|
-
for (const [colId, col] of Object.entries(columns)) {
|
|
576
|
-
const type = col?.type;
|
|
577
|
-
if (typeof type !== "string" || !type.startsWith("Ref:") && !type.startsWith("RefList:")) {
|
|
578
|
-
continue;
|
|
579
|
-
}
|
|
580
|
-
if (displayHelpersByRef[colId]) continue;
|
|
581
|
-
const byName = `gristHelper_${colId}`;
|
|
582
|
-
if (Array.isArray(data[byName])) {
|
|
583
|
-
displayHelpersByRef[colId] = byName;
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
const fallbackUntypedToString = options?.fallbackUntypedToString ?? true;
|
|
587
|
-
const refMode = options?.refMode ?? "id";
|
|
588
|
-
const colIds = Object.keys(data);
|
|
589
|
-
const parsedByColumn = {};
|
|
590
|
-
for (const colId of colIds) {
|
|
591
|
-
const rawValues = Array.isArray(data[colId]) ? data[colId] : [];
|
|
592
|
-
const helperColId = displayHelpersByRef[colId];
|
|
593
|
-
const helperValues = helperColId && Array.isArray(data[helperColId]) ? data[helperColId] : void 0;
|
|
594
|
-
parsedByColumn[colId] = colId === "id" ? rawValues.map((raw) => ({
|
|
595
|
-
ok: typeof raw === "number" && Number.isFinite(raw),
|
|
596
|
-
typedValue: typeof raw === "number" && Number.isFinite(raw) ? raw : null,
|
|
597
|
-
displayValue: raw,
|
|
598
|
-
raw,
|
|
599
|
-
issues: typeof raw === "number" && Number.isFinite(raw) ? [] : [{ code: "type_mismatch", message: "Row id should be numeric." }]
|
|
600
|
-
})) : safeParseGristValues({
|
|
601
|
-
values: rawValues,
|
|
602
|
-
column: columns[colId],
|
|
603
|
-
helperValues,
|
|
604
|
-
fallbackUntypedToString,
|
|
605
|
-
refMode
|
|
606
|
-
});
|
|
607
|
-
}
|
|
608
|
-
const rowCount = computeRowCount(data);
|
|
609
|
-
const rows = [];
|
|
610
|
-
const cellIssues = [];
|
|
611
|
-
const cellMeta = [];
|
|
612
|
-
for (let rowIndex = 0; rowIndex < rowCount; rowIndex++) {
|
|
613
|
-
const row = {};
|
|
614
|
-
for (const colId of colIds) {
|
|
615
|
-
const parsed = parsedByColumn[colId]?.[rowIndex];
|
|
616
|
-
row[colId] = parsed?.typedValue ?? null;
|
|
617
|
-
const choiceTokens = buildChoiceTokens(columns[colId], parsed?.displayValue);
|
|
618
|
-
if (parsed) {
|
|
619
|
-
if (parsed.issues.length > 0 || choiceTokens && choiceTokens.length > 0) {
|
|
620
|
-
cellMeta.push({
|
|
621
|
-
rowIndex,
|
|
622
|
-
colId,
|
|
623
|
-
ok: parsed.ok,
|
|
624
|
-
issues: parsed.issues,
|
|
625
|
-
choiceTokens
|
|
626
|
-
});
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
|
-
if (!parsed || parsed.issues.length === 0) continue;
|
|
630
|
-
for (const issue of parsed.issues) {
|
|
631
|
-
cellIssues.push({ ...issue, rowIndex, colId });
|
|
632
|
-
}
|
|
633
|
-
}
|
|
634
|
-
rows.push(row);
|
|
635
|
-
}
|
|
636
|
-
const cellMetaByKey = {};
|
|
637
|
-
for (const meta of cellMeta) {
|
|
638
|
-
const rowId = rows[meta.rowIndex]?.id;
|
|
639
|
-
if (typeof rowId !== "number") continue;
|
|
640
|
-
cellMetaByKey[`${rowId}:${meta.colId}`] = meta;
|
|
641
|
-
}
|
|
642
|
-
const order = options?.order ?? "grist";
|
|
643
|
-
if (order === "none") {
|
|
644
|
-
return { rows, cellIssues, cellMeta, cellMetaByKey, cellResultsByColumn: parsedByColumn };
|
|
645
|
-
}
|
|
646
|
-
if (order === "id") {
|
|
647
|
-
return {
|
|
648
|
-
rows: [...rows].sort((a, b) => {
|
|
649
|
-
const ida = typeof a.id === "number" ? a.id : 0;
|
|
650
|
-
const idb = typeof b.id === "number" ? b.id : 0;
|
|
651
|
-
return ida - idb;
|
|
652
|
-
}),
|
|
653
|
-
cellIssues,
|
|
654
|
-
cellMeta,
|
|
655
|
-
cellMetaByKey,
|
|
656
|
-
cellResultsByColumn: parsedByColumn
|
|
657
|
-
};
|
|
658
|
-
}
|
|
659
|
-
return {
|
|
660
|
-
rows: sortRowsByGristOrder(rows),
|
|
661
|
-
cellIssues,
|
|
662
|
-
cellMeta,
|
|
663
|
-
cellMetaByKey,
|
|
664
|
-
cellResultsByColumn: parsedByColumn
|
|
665
|
-
};
|
|
666
|
-
}
|
|
667
|
-
|
|
668
|
-
// src/sdk/helpers/grist-user-actions.ts
|
|
669
|
-
function gristUpdateRecordAction(tableId, rowId, patch) {
|
|
670
|
-
return ["UpdateRecord", tableId, rowId, patch];
|
|
671
|
-
}
|
|
672
|
-
function gristAddRecordAction(tableId, values) {
|
|
673
|
-
return ["AddRecord", tableId, null, values];
|
|
674
|
-
}
|
|
675
|
-
function gristRemoveRecordAction(tableId, rowId) {
|
|
676
|
-
return ["RemoveRecord", tableId, rowId];
|
|
677
|
-
}
|
|
678
|
-
function gristBulkUpdateRecordAction(tableId, rowIds, columnarPatch) {
|
|
679
|
-
return ["BulkUpdateRecord", tableId, rowIds, columnarPatch];
|
|
680
|
-
}
|
|
681
|
-
function gristBulkAddRecordAction(tableId, values, rowIds) {
|
|
682
|
-
const length = inferBulkLength(values);
|
|
683
|
-
const ids = rowIds ?? new Array(length).fill(null);
|
|
684
|
-
return ["BulkAddRecord", tableId, ids, values];
|
|
685
|
-
}
|
|
686
|
-
function gristBulkRemoveRecordAction(tableId, rowIds) {
|
|
687
|
-
return ["BulkRemoveRecord", tableId, rowIds];
|
|
688
|
-
}
|
|
689
|
-
function gristAddColumnAction(tableId, colId, colInfo) {
|
|
690
|
-
return ["AddColumn", tableId, colId, colInfo];
|
|
691
|
-
}
|
|
692
|
-
function gristAddVisibleColumnAction(tableId, colId, colInfo) {
|
|
693
|
-
return ["AddVisibleColumn", tableId, colId, colInfo];
|
|
694
|
-
}
|
|
695
|
-
function gristRenameColumnAction(tableId, colId, newColId) {
|
|
696
|
-
return ["RenameColumn", tableId, colId, newColId];
|
|
697
|
-
}
|
|
698
|
-
function gristModifyColumnAction(tableId, colId, colInfo) {
|
|
699
|
-
return ["ModifyColumn", tableId, colId, colInfo];
|
|
700
|
-
}
|
|
701
|
-
function gristRemoveColumnAction(tableId, colId) {
|
|
702
|
-
return ["RemoveColumn", tableId, colId];
|
|
703
|
-
}
|
|
704
|
-
function gristAddTableAction(tableId, tableInfo) {
|
|
705
|
-
return ["AddTable", tableId, tableInfo];
|
|
706
|
-
}
|
|
707
|
-
function gristRenameTableAction(tableId, newTableId) {
|
|
708
|
-
return ["RenameTable", tableId, newTableId];
|
|
709
|
-
}
|
|
710
|
-
function gristRemoveTableAction(tableId) {
|
|
711
|
-
return ["RemoveTable", tableId];
|
|
712
|
-
}
|
|
713
|
-
function gristDuplicateTableAction(tableId, newTableId, options) {
|
|
714
|
-
return options ? ["DuplicateTable", tableId, newTableId, options] : ["DuplicateTable", tableId, newTableId];
|
|
715
|
-
}
|
|
716
|
-
function gristReplaceTableDataAction(tableId, rowIds, columnarData) {
|
|
717
|
-
return ["ReplaceTableData", tableId, rowIds, columnarData];
|
|
718
|
-
}
|
|
719
|
-
function gristSetDocumentInfoAction(info) {
|
|
720
|
-
return ["SetDocumentInfo", info];
|
|
721
|
-
}
|
|
722
|
-
function inferBulkLength(values) {
|
|
723
|
-
for (const arr of Object.values(values)) if (Array.isArray(arr)) return arr.length;
|
|
724
|
-
return 0;
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
export {
|
|
728
|
-
coerceGristDocApiRefRowId,
|
|
729
|
-
decodeGristValue,
|
|
730
|
-
isGristCellError,
|
|
731
|
-
encodeGristValue,
|
|
732
|
-
parseGristWidgetOptionsCell,
|
|
733
|
-
normalizeGristChoiceListEntries,
|
|
734
|
-
gristSafeRefValueSchema,
|
|
735
|
-
gristSafeRefListValueSchema,
|
|
736
|
-
gristCellValueSchema,
|
|
737
|
-
inferDisplayHelpersByRef,
|
|
738
|
-
safeParseGristValues,
|
|
739
|
-
safeParseGristTableData,
|
|
740
|
-
gristUpdateRecordAction,
|
|
741
|
-
gristAddRecordAction,
|
|
742
|
-
gristRemoveRecordAction,
|
|
743
|
-
gristBulkUpdateRecordAction,
|
|
744
|
-
gristBulkAddRecordAction,
|
|
745
|
-
gristBulkRemoveRecordAction,
|
|
746
|
-
gristAddColumnAction,
|
|
747
|
-
gristAddVisibleColumnAction,
|
|
748
|
-
gristRenameColumnAction,
|
|
749
|
-
gristModifyColumnAction,
|
|
750
|
-
gristRemoveColumnAction,
|
|
751
|
-
gristAddTableAction,
|
|
752
|
-
gristRenameTableAction,
|
|
753
|
-
gristRemoveTableAction,
|
|
754
|
-
gristDuplicateTableAction,
|
|
755
|
-
gristReplaceTableDataAction,
|
|
756
|
-
gristSetDocumentInfoAction
|
|
757
|
-
};
|
|
758
|
-
//# sourceMappingURL=chunk-64SVRWW7.js.map
|