gogcli-mcp-sheets 2.6.1 → 2.7.1
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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/LICENSE +21 -0
- package/dist/index.js +67 -2
- package/manifest.json +17 -1
- package/package.json +1 -1
- package/server.json +2 -2
- package/src/tools/sheets-extra.ts +70 -1
- package/tests/tools/sheets-extra.test.ts +79 -0
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
},
|
|
8
8
|
"metadata": {
|
|
9
9
|
"description": "Extended Google Sheets for Claude via gogcli — auth + full Sheets support",
|
|
10
|
-
"version": "2.
|
|
10
|
+
"version": "2.7.1"
|
|
11
11
|
},
|
|
12
12
|
"plugins": [
|
|
13
13
|
{
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"displayName": "gogcli (Sheets)",
|
|
16
16
|
"source": "./",
|
|
17
17
|
"description": "Extended Google Sheets for Claude via gogcli — auth + full Sheets support",
|
|
18
|
-
"version": "2.
|
|
18
|
+
"version": "2.7.1",
|
|
19
19
|
"author": {
|
|
20
20
|
"name": "Chris Hall"
|
|
21
21
|
},
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Chris Hall
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.js
CHANGED
|
@@ -31399,7 +31399,7 @@ function registerSheetsTools(server2) {
|
|
|
31399
31399
|
}
|
|
31400
31400
|
|
|
31401
31401
|
// ../gogcli-mcp/src/server.ts
|
|
31402
|
-
var VERSION = true ? "2.
|
|
31402
|
+
var VERSION = true ? "2.7.1" : "0.0.0";
|
|
31403
31403
|
function createServer(options) {
|
|
31404
31404
|
return new McpServer({
|
|
31405
31405
|
name: options?.name ?? "gogcli",
|
|
@@ -31815,6 +31815,71 @@ ${result.content[0].text}` }] };
|
|
|
31815
31815
|
if (cellsJson) args.push(`--cells-json=${cellsJson}`);
|
|
31816
31816
|
return runOrDiagnose(args, { account });
|
|
31817
31817
|
});
|
|
31818
|
+
server2.registerTool("gog_sheets_validation_get", {
|
|
31819
|
+
description: "Read the data-validation rules (dropdowns, checkboxes, number/date conditions, custom formulas) applied to a range.",
|
|
31820
|
+
annotations: { readOnlyHint: true },
|
|
31821
|
+
inputSchema: {
|
|
31822
|
+
spreadsheetId: external_exports.string().describe("Spreadsheet ID"),
|
|
31823
|
+
range: external_exports.string().describe("Range to inspect (e.g. Sheet1!A1:A10)"),
|
|
31824
|
+
account: accountParam
|
|
31825
|
+
}
|
|
31826
|
+
}, async ({ spreadsheetId, range, account }) => {
|
|
31827
|
+
return runOrDiagnose(["sheets", "validation", "get", spreadsheetId, range], { account });
|
|
31828
|
+
});
|
|
31829
|
+
server2.registerTool("gog_sheets_validation_set", {
|
|
31830
|
+
description: "Set a data-validation rule on a range \u2014 dropdowns (ONE_OF_LIST / ONE_OF_RANGE), checkboxes (BOOLEAN), number/date conditions, or custom formulas. Overwrites any existing rule on the range. Repeat values for list entries or between-bounds.",
|
|
31831
|
+
annotations: { destructiveHint: true },
|
|
31832
|
+
inputSchema: {
|
|
31833
|
+
spreadsheetId: external_exports.string().describe("Spreadsheet ID"),
|
|
31834
|
+
range: external_exports.string().describe("Range to apply the rule to (e.g. Sheet1!A1:A10)"),
|
|
31835
|
+
type: external_exports.string().describe("Condition type, e.g. ONE_OF_LIST, ONE_OF_RANGE, NUMBER_BETWEEN, NUMBER_GREATER, DATE_AFTER, BOOLEAN, CUSTOM_FORMULA"),
|
|
31836
|
+
values: external_exports.array(external_exports.string()).optional().describe("Condition values (repeatable): list entries for ONE_OF_LIST, two bounds for *_BETWEEN, a range for ONE_OF_RANGE, a formula for CUSTOM_FORMULA"),
|
|
31837
|
+
strict: external_exports.boolean().optional().describe("Reject invalid input instead of showing a warning"),
|
|
31838
|
+
inputMessage: external_exports.string().optional().describe("Message shown when the cell is selected"),
|
|
31839
|
+
showCustomUi: external_exports.boolean().optional().describe("Show dropdown or checkbox UI where supported"),
|
|
31840
|
+
filteredRowsIncluded: external_exports.boolean().optional().describe("Apply the rule to filtered rows too; required for table-managed dropdown columns"),
|
|
31841
|
+
account: accountParam
|
|
31842
|
+
}
|
|
31843
|
+
}, async ({ spreadsheetId, range, type, values, strict, inputMessage, showCustomUi, filteredRowsIncluded, account }) => {
|
|
31844
|
+
const args = ["sheets", "validation", "set", spreadsheetId, range, `--type=${type}`];
|
|
31845
|
+
if (values) for (const v of values) args.push(`--value=${v}`);
|
|
31846
|
+
if (strict) args.push("--strict");
|
|
31847
|
+
if (inputMessage) args.push(`--input-message=${inputMessage}`);
|
|
31848
|
+
if (showCustomUi) args.push("--show-custom-ui");
|
|
31849
|
+
if (filteredRowsIncluded) args.push("--filtered-rows-included");
|
|
31850
|
+
return runOrDiagnose(args, { account });
|
|
31851
|
+
});
|
|
31852
|
+
server2.registerTool("gog_sheets_validation_clear", {
|
|
31853
|
+
description: "Remove all data-validation rules from a range.",
|
|
31854
|
+
annotations: { destructiveHint: true },
|
|
31855
|
+
inputSchema: {
|
|
31856
|
+
spreadsheetId: external_exports.string().describe("Spreadsheet ID"),
|
|
31857
|
+
range: external_exports.string().describe("Range to clear (e.g. Sheet1!A1:A10)"),
|
|
31858
|
+
filteredRowsIncluded: external_exports.boolean().optional().describe("Clear rules from filtered rows too; required for table-managed dropdown columns"),
|
|
31859
|
+
account: accountParam
|
|
31860
|
+
}
|
|
31861
|
+
}, async ({ spreadsheetId, range, filteredRowsIncluded, account }) => {
|
|
31862
|
+
const args = ["sheets", "validation", "clear", spreadsheetId, range];
|
|
31863
|
+
if (filteredRowsIncluded) args.push("--filtered-rows-included");
|
|
31864
|
+
return runOrDiagnose(args, { account });
|
|
31865
|
+
});
|
|
31866
|
+
server2.registerTool("gog_sheets_delete_dimension", {
|
|
31867
|
+
description: "Delete a span of rows or columns, table-aware: intersecting table objects are preserved (shrunk) along with their remaining data, instead of being corrupted as with a raw DeleteDimension batch update. Target by A1 range (e.g. Sheet1!5:7 or Sheet1!C:D) or by sheet name plus start/end.",
|
|
31868
|
+
annotations: { destructiveHint: true },
|
|
31869
|
+
inputSchema: {
|
|
31870
|
+
spreadsheetId: external_exports.string().describe("Spreadsheet ID"),
|
|
31871
|
+
rangeOrSheet: external_exports.string().describe("A1 range covering the rows/columns to delete, or a sheet name (then start/end are required)"),
|
|
31872
|
+
dimension: external_exports.enum(["ROWS", "COLUMNS"]).describe("Dimension to delete"),
|
|
31873
|
+
start: external_exports.number().int().optional().describe("First row/column to delete (1-based, inclusive; required with a sheet-name target)"),
|
|
31874
|
+
end: external_exports.number().int().optional().describe("Last row/column to delete (1-based, inclusive; required with a sheet-name target)"),
|
|
31875
|
+
account: accountParam
|
|
31876
|
+
}
|
|
31877
|
+
}, async ({ spreadsheetId, rangeOrSheet, dimension, start, end, account }) => {
|
|
31878
|
+
const args = ["sheets", "delete-dimension", spreadsheetId, rangeOrSheet, `--dimension=${dimension}`];
|
|
31879
|
+
if (start !== void 0) args.push(`--start=${start}`);
|
|
31880
|
+
if (end !== void 0) args.push(`--end=${end}`);
|
|
31881
|
+
return runOrDiagnose(args, { account });
|
|
31882
|
+
});
|
|
31818
31883
|
server2.registerTool("gog_sheets_named_ranges_list", {
|
|
31819
31884
|
description: "List all named ranges in a spreadsheet.",
|
|
31820
31885
|
annotations: { readOnlyHint: true },
|
|
@@ -32037,7 +32102,7 @@ ${result.content[0].text}` }] };
|
|
|
32037
32102
|
return runOrDiagnose(["sheets", "table", "clear", spreadsheetId, tableId], { account });
|
|
32038
32103
|
});
|
|
32039
32104
|
server2.registerTool("gog_sheets_table_delete", {
|
|
32040
|
-
description: "Delete a Google Sheets table. WARNING: the underlying `gog`/Sheets behaviour is that deleting a table also DESTROYS every cell value in the table range \u2014 not just the table styling/columns. By default this tool prevents that data loss by emulating the Sheets UI's \"Convert to range\": it reads the table's cells (values AND formulas) first, deletes the table, then restores the data into the now-plain range. Formatting
|
|
32105
|
+
description: "Delete a Google Sheets table. WARNING: the underlying `gog`/Sheets behaviour is that deleting a table also DESTROYS every cell value in the table range \u2014 not just the table styling/columns. By default this tool prevents that data loss by emulating the Sheets UI's \"Convert to range\": it reads the table's cells (values AND formulas) first, deletes the table, then restores the data into the now-plain range. Formatting and banding are still lost; data-validation dropdowns are also not restored automatically, but you can snapshot them first with gog_sheets_validation_get and re-apply with gog_sheets_validation_set. Set keep_data=false to delete the table AND wipe its cell data (the raw destructive behaviour). To preserve everything, snapshot the whole spreadsheet first with gog_sheets_snapshot.",
|
|
32041
32106
|
annotations: { destructiveHint: true },
|
|
32042
32107
|
inputSchema: {
|
|
32043
32108
|
spreadsheetId: external_exports.string().describe("Spreadsheet ID"),
|
package/manifest.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"manifest_version": "0.3",
|
|
4
4
|
"name": "gogcli-mcp-sheets",
|
|
5
5
|
"display_name": "gogcli (Sheets)",
|
|
6
|
-
"version": "2.
|
|
6
|
+
"version": "2.7.1",
|
|
7
7
|
"description": "Extended Google Sheets for Claude via gogcli — auth + full Sheets support",
|
|
8
8
|
"author": {
|
|
9
9
|
"name": "Chris Hall",
|
|
@@ -184,6 +184,22 @@
|
|
|
184
184
|
"name": "gog_sheets_links_set",
|
|
185
185
|
"description": "Set native cell hyperlinks: single link, multi-link rich-text cell (runsJson), or batch (cellsJson)."
|
|
186
186
|
},
|
|
187
|
+
{
|
|
188
|
+
"name": "gog_sheets_validation_get",
|
|
189
|
+
"description": "Read data-validation rules (dropdowns, checkboxes, conditions) on a range."
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
"name": "gog_sheets_validation_set",
|
|
193
|
+
"description": "Set a data-validation rule on a range: dropdowns, checkboxes, number/date conditions, or custom formulas."
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
"name": "gog_sheets_validation_clear",
|
|
197
|
+
"description": "Remove all data-validation rules from a range."
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
"name": "gog_sheets_delete_dimension",
|
|
201
|
+
"description": "Delete a row or column span, table-aware: intersecting tables are shrunk and their remaining data preserved."
|
|
202
|
+
},
|
|
187
203
|
{
|
|
188
204
|
"name": "gog_sheets_named_ranges_list",
|
|
189
205
|
"description": "List all named ranges in a spreadsheet."
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gogcli-mcp-sheets",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.1",
|
|
4
4
|
"mcpName": "io.github.chrischall/gogcli-mcp-sheets",
|
|
5
5
|
"description": "Extended Google Sheets MCP server via gogcli — all base tools plus full Sheets support",
|
|
6
6
|
"author": "Claude Code (AI) <https://www.anthropic.com/claude>",
|
package/server.json
CHANGED
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
"source": "github",
|
|
8
8
|
"subfolder": "packages/gogcli-mcp-sheets"
|
|
9
9
|
},
|
|
10
|
-
"version": "2.
|
|
10
|
+
"version": "2.7.1",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "npm",
|
|
14
14
|
"identifier": "gogcli-mcp-sheets",
|
|
15
|
-
"version": "2.
|
|
15
|
+
"version": "2.7.1",
|
|
16
16
|
"transport": {
|
|
17
17
|
"type": "stdio"
|
|
18
18
|
},
|
|
@@ -466,6 +466,75 @@ export function registerExtraSheetsTools(server: McpServer): void {
|
|
|
466
466
|
return runOrDiagnose(args, { account });
|
|
467
467
|
});
|
|
468
468
|
|
|
469
|
+
server.registerTool('gog_sheets_validation_get', {
|
|
470
|
+
description: 'Read the data-validation rules (dropdowns, checkboxes, number/date conditions, custom formulas) applied to a range.',
|
|
471
|
+
annotations: { readOnlyHint: true },
|
|
472
|
+
inputSchema: {
|
|
473
|
+
spreadsheetId: z.string().describe('Spreadsheet ID'),
|
|
474
|
+
range: z.string().describe('Range to inspect (e.g. Sheet1!A1:A10)'),
|
|
475
|
+
account: accountParam,
|
|
476
|
+
},
|
|
477
|
+
}, async ({ spreadsheetId, range, account }) => {
|
|
478
|
+
return runOrDiagnose(['sheets', 'validation', 'get', spreadsheetId, range], { account });
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
server.registerTool('gog_sheets_validation_set', {
|
|
482
|
+
description: 'Set a data-validation rule on a range — dropdowns (ONE_OF_LIST / ONE_OF_RANGE), checkboxes (BOOLEAN), number/date conditions, or custom formulas. Overwrites any existing rule on the range. Repeat values for list entries or between-bounds.',
|
|
483
|
+
annotations: { destructiveHint: true },
|
|
484
|
+
inputSchema: {
|
|
485
|
+
spreadsheetId: z.string().describe('Spreadsheet ID'),
|
|
486
|
+
range: z.string().describe('Range to apply the rule to (e.g. Sheet1!A1:A10)'),
|
|
487
|
+
type: z.string().describe('Condition type, e.g. ONE_OF_LIST, ONE_OF_RANGE, NUMBER_BETWEEN, NUMBER_GREATER, DATE_AFTER, BOOLEAN, CUSTOM_FORMULA'),
|
|
488
|
+
values: z.array(z.string()).optional().describe('Condition values (repeatable): list entries for ONE_OF_LIST, two bounds for *_BETWEEN, a range for ONE_OF_RANGE, a formula for CUSTOM_FORMULA'),
|
|
489
|
+
strict: z.boolean().optional().describe('Reject invalid input instead of showing a warning'),
|
|
490
|
+
inputMessage: z.string().optional().describe('Message shown when the cell is selected'),
|
|
491
|
+
showCustomUi: z.boolean().optional().describe('Show dropdown or checkbox UI where supported'),
|
|
492
|
+
filteredRowsIncluded: z.boolean().optional().describe('Apply the rule to filtered rows too; required for table-managed dropdown columns'),
|
|
493
|
+
account: accountParam,
|
|
494
|
+
},
|
|
495
|
+
}, async ({ spreadsheetId, range, type, values, strict, inputMessage, showCustomUi, filteredRowsIncluded, account }) => {
|
|
496
|
+
const args = ['sheets', 'validation', 'set', spreadsheetId, range, `--type=${type}`];
|
|
497
|
+
if (values) for (const v of values) args.push(`--value=${v}`);
|
|
498
|
+
if (strict) args.push('--strict');
|
|
499
|
+
if (inputMessage) args.push(`--input-message=${inputMessage}`);
|
|
500
|
+
if (showCustomUi) args.push('--show-custom-ui');
|
|
501
|
+
if (filteredRowsIncluded) args.push('--filtered-rows-included');
|
|
502
|
+
return runOrDiagnose(args, { account });
|
|
503
|
+
});
|
|
504
|
+
|
|
505
|
+
server.registerTool('gog_sheets_validation_clear', {
|
|
506
|
+
description: 'Remove all data-validation rules from a range.',
|
|
507
|
+
annotations: { destructiveHint: true },
|
|
508
|
+
inputSchema: {
|
|
509
|
+
spreadsheetId: z.string().describe('Spreadsheet ID'),
|
|
510
|
+
range: z.string().describe('Range to clear (e.g. Sheet1!A1:A10)'),
|
|
511
|
+
filteredRowsIncluded: z.boolean().optional().describe('Clear rules from filtered rows too; required for table-managed dropdown columns'),
|
|
512
|
+
account: accountParam,
|
|
513
|
+
},
|
|
514
|
+
}, async ({ spreadsheetId, range, filteredRowsIncluded, account }) => {
|
|
515
|
+
const args = ['sheets', 'validation', 'clear', spreadsheetId, range];
|
|
516
|
+
if (filteredRowsIncluded) args.push('--filtered-rows-included');
|
|
517
|
+
return runOrDiagnose(args, { account });
|
|
518
|
+
});
|
|
519
|
+
|
|
520
|
+
server.registerTool('gog_sheets_delete_dimension', {
|
|
521
|
+
description: 'Delete a span of rows or columns, table-aware: intersecting table objects are preserved (shrunk) along with their remaining data, instead of being corrupted as with a raw DeleteDimension batch update. Target by A1 range (e.g. Sheet1!5:7 or Sheet1!C:D) or by sheet name plus start/end.',
|
|
522
|
+
annotations: { destructiveHint: true },
|
|
523
|
+
inputSchema: {
|
|
524
|
+
spreadsheetId: z.string().describe('Spreadsheet ID'),
|
|
525
|
+
rangeOrSheet: z.string().describe('A1 range covering the rows/columns to delete, or a sheet name (then start/end are required)'),
|
|
526
|
+
dimension: z.enum(['ROWS', 'COLUMNS']).describe('Dimension to delete'),
|
|
527
|
+
start: z.number().int().optional().describe('First row/column to delete (1-based, inclusive; required with a sheet-name target)'),
|
|
528
|
+
end: z.number().int().optional().describe('Last row/column to delete (1-based, inclusive; required with a sheet-name target)'),
|
|
529
|
+
account: accountParam,
|
|
530
|
+
},
|
|
531
|
+
}, async ({ spreadsheetId, rangeOrSheet, dimension, start, end, account }) => {
|
|
532
|
+
const args = ['sheets', 'delete-dimension', spreadsheetId, rangeOrSheet, `--dimension=${dimension}`];
|
|
533
|
+
if (start !== undefined) args.push(`--start=${start}`);
|
|
534
|
+
if (end !== undefined) args.push(`--end=${end}`);
|
|
535
|
+
return runOrDiagnose(args, { account });
|
|
536
|
+
});
|
|
537
|
+
|
|
469
538
|
server.registerTool('gog_sheets_named_ranges_list', {
|
|
470
539
|
description: 'List all named ranges in a spreadsheet.',
|
|
471
540
|
annotations: { readOnlyHint: true },
|
|
@@ -712,7 +781,7 @@ export function registerExtraSheetsTools(server: McpServer): void {
|
|
|
712
781
|
description:
|
|
713
782
|
'Delete a Google Sheets table. WARNING: the underlying `gog`/Sheets behaviour is that deleting a table also DESTROYS every cell value in the table range — not just the table styling/columns. ' +
|
|
714
783
|
'By default this tool prevents that data loss by emulating the Sheets UI\'s "Convert to range": it reads the table\'s cells (values AND formulas) first, deletes the table, then restores the data into the now-plain range. ' +
|
|
715
|
-
'Formatting
|
|
784
|
+
'Formatting and banding are still lost; data-validation dropdowns are also not restored automatically, but you can snapshot them first with gog_sheets_validation_get and re-apply with gog_sheets_validation_set. ' +
|
|
716
785
|
'Set keep_data=false to delete the table AND wipe its cell data (the raw destructive behaviour). To preserve everything, snapshot the whole spreadsheet first with gog_sheets_snapshot.',
|
|
717
786
|
annotations: { destructiveHint: true },
|
|
718
787
|
inputSchema: {
|
|
@@ -1284,3 +1284,82 @@ describe('gog_sheets_snapshot', () => {
|
|
|
1284
1284
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['drive', 'copy', 'sid', 'Backup A', '--parent=folder1'], { account: 'a@b.com' });
|
|
1285
1285
|
});
|
|
1286
1286
|
});
|
|
1287
|
+
|
|
1288
|
+
// gog 0.24.0
|
|
1289
|
+
describe('gog_sheets_validation_get', () => {
|
|
1290
|
+
it('reads validation rules for a range', async () => {
|
|
1291
|
+
vi.mocked(lib.runOrDiagnose).mockResolvedValue(toText('{}'));
|
|
1292
|
+
const handlers = setupHandlers();
|
|
1293
|
+
await handlers.get('gog_sheets_validation_get')!({ spreadsheetId: 'sid', range: 'Sheet1!A1:A10' });
|
|
1294
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
1295
|
+
['sheets', 'validation', 'get', 'sid', 'Sheet1!A1:A10'],
|
|
1296
|
+
{ account: undefined },
|
|
1297
|
+
);
|
|
1298
|
+
});
|
|
1299
|
+
});
|
|
1300
|
+
|
|
1301
|
+
describe('gog_sheets_validation_set', () => {
|
|
1302
|
+
it('sets a dropdown rule with repeated values', async () => {
|
|
1303
|
+
vi.mocked(lib.runOrDiagnose).mockResolvedValue(toText('{}'));
|
|
1304
|
+
const handlers = setupHandlers();
|
|
1305
|
+
await handlers.get('gog_sheets_validation_set')!({
|
|
1306
|
+
spreadsheetId: 'sid', range: 'A1:A10', type: 'ONE_OF_LIST', values: ['Red', 'Green'],
|
|
1307
|
+
});
|
|
1308
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
1309
|
+
['sheets', 'validation', 'set', 'sid', 'A1:A10', '--type=ONE_OF_LIST', '--value=Red', '--value=Green'],
|
|
1310
|
+
{ account: undefined },
|
|
1311
|
+
);
|
|
1312
|
+
});
|
|
1313
|
+
|
|
1314
|
+
it('passes strict, input message, custom UI and filtered-rows flags', async () => {
|
|
1315
|
+
vi.mocked(lib.runOrDiagnose).mockResolvedValue(toText('{}'));
|
|
1316
|
+
const handlers = setupHandlers();
|
|
1317
|
+
await handlers.get('gog_sheets_validation_set')!({
|
|
1318
|
+
spreadsheetId: 'sid', range: 'A1', type: 'NUMBER_BETWEEN', values: ['1', '10'],
|
|
1319
|
+
strict: true, inputMessage: 'Pick 1-10', showCustomUi: true, filteredRowsIncluded: true,
|
|
1320
|
+
});
|
|
1321
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
1322
|
+
['sheets', 'validation', 'set', 'sid', 'A1', '--type=NUMBER_BETWEEN', '--value=1', '--value=10',
|
|
1323
|
+
'--strict', '--input-message=Pick 1-10', '--show-custom-ui', '--filtered-rows-included'],
|
|
1324
|
+
{ account: undefined },
|
|
1325
|
+
);
|
|
1326
|
+
});
|
|
1327
|
+
});
|
|
1328
|
+
|
|
1329
|
+
describe('gog_sheets_validation_clear', () => {
|
|
1330
|
+
it('clears rules from a range', async () => {
|
|
1331
|
+
vi.mocked(lib.runOrDiagnose).mockResolvedValue(toText('{}'));
|
|
1332
|
+
const handlers = setupHandlers();
|
|
1333
|
+
await handlers.get('gog_sheets_validation_clear')!({ spreadsheetId: 'sid', range: 'A1:A10', filteredRowsIncluded: true });
|
|
1334
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
1335
|
+
['sheets', 'validation', 'clear', 'sid', 'A1:A10', '--filtered-rows-included'],
|
|
1336
|
+
{ account: undefined },
|
|
1337
|
+
);
|
|
1338
|
+
});
|
|
1339
|
+
});
|
|
1340
|
+
|
|
1341
|
+
describe('gog_sheets_delete_dimension', () => {
|
|
1342
|
+
it('deletes a row span from a sheet target', async () => {
|
|
1343
|
+
vi.mocked(lib.runOrDiagnose).mockResolvedValue(toText('{}'));
|
|
1344
|
+
const handlers = setupHandlers();
|
|
1345
|
+
await handlers.get('gog_sheets_delete_dimension')!({
|
|
1346
|
+
spreadsheetId: 'sid', rangeOrSheet: 'Sheet1', dimension: 'ROWS', start: 5, end: 7,
|
|
1347
|
+
});
|
|
1348
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
1349
|
+
['sheets', 'delete-dimension', 'sid', 'Sheet1', '--dimension=ROWS', '--start=5', '--end=7'],
|
|
1350
|
+
{ account: undefined },
|
|
1351
|
+
);
|
|
1352
|
+
});
|
|
1353
|
+
|
|
1354
|
+
it('deletes columns by A1 range without start/end', async () => {
|
|
1355
|
+
vi.mocked(lib.runOrDiagnose).mockResolvedValue(toText('{}'));
|
|
1356
|
+
const handlers = setupHandlers();
|
|
1357
|
+
await handlers.get('gog_sheets_delete_dimension')!({
|
|
1358
|
+
spreadsheetId: 'sid', rangeOrSheet: 'Sheet1!C:D', dimension: 'COLUMNS', account: 'a@b.com',
|
|
1359
|
+
});
|
|
1360
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
1361
|
+
['sheets', 'delete-dimension', 'sid', 'Sheet1!C:D', '--dimension=COLUMNS'],
|
|
1362
|
+
{ account: 'a@b.com' },
|
|
1363
|
+
);
|
|
1364
|
+
});
|
|
1365
|
+
});
|