agent-spreadsheet-sdk 0.12.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.
@@ -0,0 +1,393 @@
1
+ const { freezeCapabilities, WASM_CAPABILITIES } = require("./capabilities")
2
+ const {
3
+ requireCapability,
4
+ requiredString,
5
+ normalizeSheetPageResult,
6
+ normalizeGridExportResult,
7
+ normalizeTransformBatchResult,
8
+ normalizeDescribeWorkbookResult,
9
+ normalizeNamedRangesResult,
10
+ normalizeSheetOverviewResult,
11
+ normalizeFindValueResult,
12
+ normalizeReadTableResult
13
+ } = require("./backend")
14
+ const { SpreadsheetSdkError, normalizeBackendError } = require("./errors")
15
+
16
+ function normalizeSheetNames(items) {
17
+ return items.map((item) => {
18
+ if (typeof item === "string") {
19
+ return item
20
+ }
21
+ if (item && typeof item === "object" && typeof item.name === "string") {
22
+ return item.name
23
+ }
24
+ throw new SpreadsheetSdkError("invalid sheet summary in listSheets response", {
25
+ code: "INVALID_RESPONSE",
26
+ backend: "wasm",
27
+ operation: "listSheets"
28
+ })
29
+ })
30
+ }
31
+
32
+ function normalizeListSheetsResult(result) {
33
+ if (Array.isArray(result)) {
34
+ return normalizeSheetNames(result)
35
+ }
36
+ if (result && typeof result === "object") {
37
+ if (Array.isArray(result.sheets)) {
38
+ return normalizeSheetNames(result.sheets)
39
+ }
40
+ if (Array.isArray(result.sheet_names)) {
41
+ return normalizeSheetNames(result.sheet_names)
42
+ }
43
+ }
44
+ throw new SpreadsheetSdkError("invalid listSheets response", {
45
+ code: "INVALID_RESPONSE",
46
+ backend: "wasm",
47
+ operation: "listSheets"
48
+ })
49
+ }
50
+
51
+ function normalizeRangeValuesResult(result, fallbackSheetName) {
52
+ if (!result || typeof result !== "object") {
53
+ throw new SpreadsheetSdkError("invalid rangeValues response", {
54
+ code: "INVALID_RESPONSE",
55
+ backend: "wasm",
56
+ operation: "rangeValues"
57
+ })
58
+ }
59
+
60
+ const sheetName = typeof result.sheetName === "string"
61
+ ? result.sheetName
62
+ : typeof result.sheet_name === "string"
63
+ ? result.sheet_name
64
+ : fallbackSheetName
65
+
66
+ const values = Array.isArray(result.values) ? result.values : []
67
+ return { sheetName, values }
68
+ }
69
+
70
+ class WasmBackend {
71
+ /**
72
+ * @param {{
73
+ * bindings: Record<string, unknown>,
74
+ * capabilities?: import("./capabilities").BackendCapabilities
75
+ * }} params
76
+ */
77
+ constructor(params) {
78
+ if (!params || !params.bindings || typeof params.bindings !== "object") {
79
+ throw new SpreadsheetSdkError("WasmBackend requires bindings object", {
80
+ code: "INVALID_ARGUMENT",
81
+ backend: "wasm"
82
+ })
83
+ }
84
+
85
+ this.kind = "wasm"
86
+ this._bindings = params.bindings
87
+ this._capabilities = freezeCapabilities(params.capabilities || WASM_CAPABILITIES)
88
+ }
89
+
90
+ getCapabilities() {
91
+ return this._capabilities
92
+ }
93
+
94
+ async createSession(input = {}) {
95
+ requireCapability(this, "supportsSessionLifecycle", "createSession")
96
+ const workbookBytes = input.workbookBytes || input.bytes
97
+ if (!workbookBytes) {
98
+ throw new SpreadsheetSdkError("missing required field 'workbookBytes'", {
99
+ code: "INVALID_ARGUMENT",
100
+ backend: this.kind,
101
+ operation: "createSession"
102
+ })
103
+ }
104
+ return this._call("createSession", workbookBytes)
105
+ }
106
+
107
+ async describeWorkbook(input = {}) {
108
+ requireCapability(this, "supportsDescribeWorkbook", "describeWorkbook")
109
+ const sessionId = requiredString(input.sessionId || input.session_id || input.contextId, "sessionId")
110
+ const result = await this._call("describeWorkbook", sessionId)
111
+ return normalizeDescribeWorkbookResult(result, sessionId)
112
+ }
113
+
114
+ async namedRanges(input = {}) {
115
+ requireCapability(this, "supportsNamedRanges", "namedRanges")
116
+ const sessionId = requiredString(input.sessionId || input.session_id || input.contextId, "sessionId")
117
+ const result = await this._call("namedRanges", sessionId)
118
+ return normalizeNamedRangesResult(result, sessionId)
119
+ }
120
+
121
+ async verifyWorkbook(input = {}) {
122
+ requireCapability(this, "supportsVerification", "verifyWorkbook")
123
+ return input
124
+ }
125
+
126
+ async verifyTargets(input = {}) {
127
+ requireCapability(this, "supportsVerification", "verifyTargets")
128
+ return input
129
+ }
130
+
131
+ async verifyErrors(input = {}) {
132
+ requireCapability(this, "supportsVerification", "verifyErrors")
133
+ return input
134
+ }
135
+
136
+ async defineName(input = {}) {
137
+ requireCapability(this, "supportsNamedRangeMutations", "defineName")
138
+ const sessionId = requiredString(input.sessionId || input.session_id || input.contextId, "sessionId")
139
+ const name = requiredString(input.name, "name")
140
+ const refersTo = requiredString(input.refersTo || input.refers_to, "refersTo")
141
+ return this._call("defineName", sessionId, {
142
+ name,
143
+ refersTo: refersTo,
144
+ scope: input.scope,
145
+ scopeSheetName: input.scopeSheetName ?? input.scope_sheet_name
146
+ })
147
+ }
148
+
149
+ async updateName(input = {}) {
150
+ requireCapability(this, "supportsNamedRangeMutations", "updateName")
151
+ const sessionId = requiredString(input.sessionId || input.session_id || input.contextId, "sessionId")
152
+ const name = requiredString(input.name, "name")
153
+ return this._call("updateName", sessionId, {
154
+ name,
155
+ refersTo: input.refersTo ?? input.refers_to,
156
+ scope: input.scope,
157
+ scopeSheetName: input.scopeSheetName ?? input.scope_sheet_name
158
+ })
159
+ }
160
+
161
+ async deleteName(input = {}) {
162
+ requireCapability(this, "supportsNamedRangeMutations", "deleteName")
163
+ const sessionId = requiredString(input.sessionId || input.session_id || input.contextId, "sessionId")
164
+ const name = requiredString(input.name, "name")
165
+ return this._call("deleteName", sessionId, {
166
+ name,
167
+ scope: input.scope,
168
+ scopeSheetName: input.scopeSheetName ?? input.scope_sheet_name
169
+ })
170
+ }
171
+
172
+ async sheetOverview(input = {}) {
173
+ requireCapability(this, "supportsSheetOverview", "sheetOverview")
174
+ const sessionId = requiredString(input.sessionId || input.session_id || input.contextId, "sessionId")
175
+ const sheetName = requiredString(input.sheetName || input.sheet_name, "sheetName")
176
+ const result = await this._call("sheetOverview", sessionId, {
177
+ ...input,
178
+ sheetName,
179
+ maxRegions: input.maxRegions ?? input.max_regions,
180
+ maxHeaders: input.maxHeaders ?? input.max_headers,
181
+ includeHeaders: input.includeHeaders ?? input.include_headers
182
+ })
183
+ return normalizeSheetOverviewResult(result, sheetName, sessionId)
184
+ }
185
+
186
+ async listSheets(input = {}) {
187
+ requireCapability(this, "supportsListSheets", "listSheets")
188
+ const sessionId = requiredString(input.sessionId || input.session_id || input.contextId, "sessionId")
189
+ const result = await this._call("listSheets", sessionId)
190
+ return normalizeListSheetsResult(result)
191
+ }
192
+
193
+ async rangeValues(input = {}) {
194
+ requireCapability(this, "supportsRangeValues", "rangeValues")
195
+ const sessionId = requiredString(input.sessionId || input.session_id || input.contextId, "sessionId")
196
+ const sheetName = requiredString(input.sheetName || input.sheet_name, "sheetName")
197
+ const ranges = input.ranges
198
+
199
+ const result = await this._call("rangeValues", sessionId, {
200
+ sheetName,
201
+ ranges
202
+ })
203
+
204
+ return normalizeRangeValuesResult(result, sheetName)
205
+ }
206
+
207
+ async findValue(input = {}) {
208
+ requireCapability(this, "supportsFindValue", "findValue")
209
+ const sessionId = requiredString(input.sessionId || input.session_id || input.contextId, "sessionId")
210
+ const query = requiredString(input.query, "query")
211
+
212
+ const result = await this._call("findValue", sessionId, {
213
+ ...input,
214
+ query,
215
+ sheetName: input.sheetName ?? input.sheet_name,
216
+ caseSensitive: input.caseSensitive ?? input.case_sensitive,
217
+ limit: input.limit,
218
+ offset: input.offset
219
+ })
220
+
221
+ return normalizeFindValueResult(result, sessionId)
222
+ }
223
+
224
+ async readTable(input = {}) {
225
+ requireCapability(this, "supportsReadTable", "readTable")
226
+ const sessionId = requiredString(input.sessionId || input.session_id || input.contextId, "sessionId")
227
+
228
+ const result = await this._call("readTable", sessionId, {
229
+ ...input,
230
+ sheetName: input.sheetName ?? input.sheet_name,
231
+ includeHeaders: input.includeHeaders ?? input.include_headers,
232
+ includeTypes: input.includeTypes ?? input.include_types
233
+ })
234
+
235
+ return normalizeReadTableResult(result, sessionId, input.sheetName || input.sheet_name)
236
+ }
237
+
238
+ async sheetPage(input = {}) {
239
+ requireCapability(this, "supportsSheetPage", "sheetPage")
240
+ const sessionId = requiredString(input.sessionId || input.session_id || input.contextId, "sessionId")
241
+ const sheetName = requiredString(input.sheetName || input.sheet_name, "sheetName")
242
+
243
+ const result = await this._call("sheetPage", sessionId, {
244
+ ...input,
245
+ sheetName,
246
+ startRow: input.startRow ?? input.start_row,
247
+ pageSize: input.pageSize ?? input.page_size,
248
+ columnsByHeader: input.columnsByHeader ?? input.columns_by_header,
249
+ includeFormulas: input.includeFormulas ?? input.include_formulas,
250
+ includeStyles: input.includeStyles ?? input.include_styles,
251
+ includeHeader: input.includeHeader ?? input.include_header
252
+ })
253
+
254
+ return normalizeSheetPageResult(result, sheetName)
255
+ }
256
+
257
+ async gridExport(input = {}) {
258
+ requireCapability(this, "supportsGridExport", "gridExport")
259
+ const sessionId = requiredString(input.sessionId || input.session_id || input.contextId, "sessionId")
260
+ const sheetName = requiredString(input.sheetName || input.sheet_name, "sheetName")
261
+
262
+ const result = await this._call("gridExport", sessionId, {
263
+ ...input,
264
+ sheetName,
265
+ range: input.range
266
+ })
267
+
268
+ return normalizeGridExportResult(result)
269
+ }
270
+
271
+ async transformBatch(input = {}) {
272
+ requireCapability(this, "supportsTransformBatch", "transformBatch")
273
+ const sessionId = requiredString(input.sessionId || input.session_id || input.contextId, "sessionId")
274
+
275
+ // Convert SDK generic `mode: "preview"` to Wasm specific `dryRun` if missing options
276
+ const options = input.options ?? {}
277
+ if (input.mode === "preview" && options.dryRun === undefined) {
278
+ options.dryRun = true
279
+ }
280
+
281
+ const result = await this._call("transformBatch", sessionId, input.ops || [], options)
282
+
283
+ return normalizeTransformBatchResult(result)
284
+ }
285
+
286
+ async replaceInFormulas() {
287
+ requireCapability(this, "supportsReplaceInFormulas", "replaceInFormulas")
288
+ throw new SpreadsheetSdkError("replaceInFormulas is not implemented for WASM backend (fork-only)", {
289
+ code: "UNSUPPORTED",
290
+ backend: this.kind,
291
+ operation: "replaceInFormulas"
292
+ })
293
+ }
294
+
295
+ async exportWorkbook(input = {}) {
296
+ requireCapability(this, "supportsExportWorkbook", "exportWorkbook")
297
+ const sessionId = requiredString(input.sessionId || input.session_id || input.contextId, "sessionId")
298
+ return this._call("exportWorkbook", sessionId)
299
+ }
300
+
301
+ async disposeSession(input = {}) {
302
+ requireCapability(this, "supportsSessionLifecycle", "disposeSession")
303
+ const sessionId = requiredString(input.sessionId || input.session_id || input.contextId, "sessionId")
304
+ return this._call("disposeSession", sessionId)
305
+ }
306
+
307
+ async createFork() {
308
+ requireCapability(this, "supportsForkLifecycle", "createFork")
309
+ throw new SpreadsheetSdkError("createFork is not implemented for WASM backend", {
310
+ code: "UNSUPPORTED",
311
+ backend: this.kind,
312
+ operation: "createFork"
313
+ })
314
+ }
315
+
316
+ async listForks() {
317
+ requireCapability(this, "supportsForkLifecycle", "listForks")
318
+ throw new SpreadsheetSdkError("listForks is not implemented for WASM backend", {
319
+ code: "UNSUPPORTED",
320
+ backend: this.kind,
321
+ operation: "listForks"
322
+ })
323
+ }
324
+
325
+ async saveFork() {
326
+ requireCapability(this, "supportsForkLifecycle", "saveFork")
327
+ throw new SpreadsheetSdkError("saveFork is not implemented for WASM backend", {
328
+ code: "UNSUPPORTED",
329
+ backend: this.kind,
330
+ operation: "saveFork"
331
+ })
332
+ }
333
+
334
+ async discardFork() {
335
+ requireCapability(this, "supportsForkLifecycle", "discardFork")
336
+ throw new SpreadsheetSdkError("discardFork is not implemented for WASM backend", {
337
+ code: "UNSUPPORTED",
338
+ backend: this.kind,
339
+ operation: "discardFork"
340
+ })
341
+ }
342
+
343
+ async listStagedChanges() {
344
+ requireCapability(this, "supportsStaging", "listStagedChanges")
345
+ throw new SpreadsheetSdkError("listStagedChanges is not implemented for WASM backend", {
346
+ code: "UNSUPPORTED",
347
+ backend: this.kind,
348
+ operation: "listStagedChanges"
349
+ })
350
+ }
351
+
352
+ async applyStagedChange() {
353
+ requireCapability(this, "supportsStaging", "applyStagedChange")
354
+ throw new SpreadsheetSdkError("applyStagedChange is not implemented for WASM backend", {
355
+ code: "UNSUPPORTED",
356
+ backend: this.kind,
357
+ operation: "applyStagedChange"
358
+ })
359
+ }
360
+
361
+ async discardStagedChange() {
362
+ requireCapability(this, "supportsStaging", "discardStagedChange")
363
+ throw new SpreadsheetSdkError("discardStagedChange is not implemented for WASM backend", {
364
+ code: "UNSUPPORTED",
365
+ backend: this.kind,
366
+ operation: "discardStagedChange"
367
+ })
368
+ }
369
+
370
+ async _call(binding, ...args) {
371
+ const fn = this._bindings[binding]
372
+ if (typeof fn !== "function") {
373
+ throw new SpreadsheetSdkError(`wasm bindings missing '${binding}'`, {
374
+ code: "INVALID_ARGUMENT",
375
+ backend: this.kind,
376
+ operation: binding
377
+ })
378
+ }
379
+
380
+ try {
381
+ return await fn(...args)
382
+ } catch (error) {
383
+ throw normalizeBackendError(error, {
384
+ backend: this.kind,
385
+ operation: binding
386
+ })
387
+ }
388
+ }
389
+ }
390
+
391
+ module.exports = {
392
+ WasmBackend
393
+ }