@digitalpresence/cliclaw 0.1.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/dist/__tests__/calendar.integration.test.d.ts +2 -0
- package/dist/__tests__/calendar.integration.test.d.ts.map +1 -0
- package/dist/__tests__/calendar.integration.test.js +98 -0
- package/dist/__tests__/calendar.integration.test.js.map +1 -0
- package/dist/__tests__/forms.integration.test.d.ts +2 -0
- package/dist/__tests__/forms.integration.test.d.ts.map +1 -0
- package/dist/__tests__/forms.integration.test.js +243 -0
- package/dist/__tests__/forms.integration.test.js.map +1 -0
- package/dist/__tests__/gdrive.integration.test.d.ts +2 -0
- package/dist/__tests__/gdrive.integration.test.d.ts.map +1 -0
- package/dist/__tests__/gdrive.integration.test.js +186 -0
- package/dist/__tests__/gdrive.integration.test.js.map +1 -0
- package/dist/__tests__/gmail.integration.test.d.ts +2 -0
- package/dist/__tests__/gmail.integration.test.d.ts.map +1 -0
- package/dist/__tests__/gmail.integration.test.js +197 -0
- package/dist/__tests__/gmail.integration.test.js.map +1 -0
- package/dist/__tests__/gslides.integration.test.d.ts +2 -0
- package/dist/__tests__/gslides.integration.test.d.ts.map +1 -0
- package/dist/__tests__/gslides.integration.test.js +124 -0
- package/dist/__tests__/gslides.integration.test.js.map +1 -0
- package/dist/__tests__/sheets.integration.test.d.ts +2 -0
- package/dist/__tests__/sheets.integration.test.d.ts.map +1 -0
- package/dist/__tests__/sheets.integration.test.js +150 -0
- package/dist/__tests__/sheets.integration.test.js.map +1 -0
- package/dist/agent/crud.d.ts +6 -0
- package/dist/agent/crud.d.ts.map +1 -0
- package/dist/agent/crud.js +41 -0
- package/dist/agent/crud.js.map +1 -0
- package/dist/agent/memory.d.ts +14 -0
- package/dist/agent/memory.d.ts.map +1 -0
- package/dist/agent/memory.js +66 -0
- package/dist/agent/memory.js.map +1 -0
- package/dist/agent/permissions.d.ts +4 -0
- package/dist/agent/permissions.d.ts.map +1 -0
- package/dist/agent/permissions.js +32 -0
- package/dist/agent/permissions.js.map +1 -0
- package/dist/calendar/accounts.d.ts +3 -0
- package/dist/calendar/accounts.d.ts.map +1 -0
- package/dist/calendar/accounts.js +21 -0
- package/dist/calendar/accounts.js.map +1 -0
- package/dist/calendar/auth.d.ts +3 -0
- package/dist/calendar/auth.d.ts.map +1 -0
- package/dist/calendar/auth.js +41 -0
- package/dist/calendar/auth.js.map +1 -0
- package/dist/calendar/calendars.d.ts +3 -0
- package/dist/calendar/calendars.d.ts.map +1 -0
- package/dist/calendar/calendars.js +28 -0
- package/dist/calendar/calendars.js.map +1 -0
- package/dist/calendar/create.d.ts +3 -0
- package/dist/calendar/create.d.ts.map +1 -0
- package/dist/calendar/create.js +31 -0
- package/dist/calendar/create.js.map +1 -0
- package/dist/calendar/delete.d.ts +3 -0
- package/dist/calendar/delete.d.ts.map +1 -0
- package/dist/calendar/delete.js +21 -0
- package/dist/calendar/delete.js.map +1 -0
- package/dist/calendar/events.d.ts +3 -0
- package/dist/calendar/events.d.ts.map +1 -0
- package/dist/calendar/events.js +37 -0
- package/dist/calendar/events.js.map +1 -0
- package/dist/calendar/get.d.ts +3 -0
- package/dist/calendar/get.d.ts.map +1 -0
- package/dist/calendar/get.js +21 -0
- package/dist/calendar/get.js.map +1 -0
- package/dist/calendar/update.d.ts +3 -0
- package/dist/calendar/update.d.ts.map +1 -0
- package/dist/calendar/update.js +31 -0
- package/dist/calendar/update.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +37 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/agent.d.ts +6 -0
- package/dist/commands/agent.d.ts.map +1 -0
- package/dist/commands/agent.js +107 -0
- package/dist/commands/agent.js.map +1 -0
- package/dist/commands/calendar.d.ts +9 -0
- package/dist/commands/calendar.d.ts.map +1 -0
- package/dist/commands/calendar.js +104 -0
- package/dist/commands/calendar.js.map +1 -0
- package/dist/commands/cron.d.ts +6 -0
- package/dist/commands/cron.d.ts.map +1 -0
- package/dist/commands/cron.js +103 -0
- package/dist/commands/cron.js.map +1 -0
- package/dist/commands/forms.d.ts +9 -0
- package/dist/commands/forms.d.ts.map +1 -0
- package/dist/commands/forms.js +139 -0
- package/dist/commands/forms.js.map +1 -0
- package/dist/commands/gdrive.d.ts +9 -0
- package/dist/commands/gdrive.d.ts.map +1 -0
- package/dist/commands/gdrive.js +198 -0
- package/dist/commands/gdrive.js.map +1 -0
- package/dist/commands/gmail.d.ts +9 -0
- package/dist/commands/gmail.d.ts.map +1 -0
- package/dist/commands/gmail.js +231 -0
- package/dist/commands/gmail.js.map +1 -0
- package/dist/commands/gslides.d.ts +9 -0
- package/dist/commands/gslides.d.ts.map +1 -0
- package/dist/commands/gslides.js +167 -0
- package/dist/commands/gslides.js.map +1 -0
- package/dist/commands/sheets.d.ts +9 -0
- package/dist/commands/sheets.d.ts.map +1 -0
- package/dist/commands/sheets.js +174 -0
- package/dist/commands/sheets.js.map +1 -0
- package/dist/cron/daemon.d.ts +3 -0
- package/dist/cron/daemon.d.ts.map +1 -0
- package/dist/cron/daemon.js +127 -0
- package/dist/cron/daemon.js.map +1 -0
- package/dist/cron/handlers.d.ts +6 -0
- package/dist/cron/handlers.d.ts.map +1 -0
- package/dist/cron/handlers.js +58 -0
- package/dist/cron/handlers.js.map +1 -0
- package/dist/cron/logger.d.ts +4 -0
- package/dist/cron/logger.d.ts.map +1 -0
- package/dist/cron/logger.js +11 -0
- package/dist/cron/logger.js.map +1 -0
- package/dist/cron/progress.d.ts +25 -0
- package/dist/cron/progress.d.ts.map +1 -0
- package/dist/cron/progress.js +71 -0
- package/dist/cron/progress.js.map +1 -0
- package/dist/cron/ralph-wiggum.d.ts +18 -0
- package/dist/cron/ralph-wiggum.d.ts.map +1 -0
- package/dist/cron/ralph-wiggum.js +143 -0
- package/dist/cron/ralph-wiggum.js.map +1 -0
- package/dist/forms/accounts.d.ts +3 -0
- package/dist/forms/accounts.d.ts.map +1 -0
- package/dist/forms/accounts.js +20 -0
- package/dist/forms/accounts.js.map +1 -0
- package/dist/forms/auth.d.ts +3 -0
- package/dist/forms/auth.d.ts.map +1 -0
- package/dist/forms/auth.js +41 -0
- package/dist/forms/auth.js.map +1 -0
- package/dist/forms/create.d.ts +3 -0
- package/dist/forms/create.d.ts.map +1 -0
- package/dist/forms/create.js +28 -0
- package/dist/forms/create.js.map +1 -0
- package/dist/forms/get.d.ts +3 -0
- package/dist/forms/get.d.ts.map +1 -0
- package/dist/forms/get.js +21 -0
- package/dist/forms/get.js.map +1 -0
- package/dist/forms/list.d.ts +3 -0
- package/dist/forms/list.d.ts.map +1 -0
- package/dist/forms/list.js +33 -0
- package/dist/forms/list.js.map +1 -0
- package/dist/forms/questions.d.ts +6 -0
- package/dist/forms/questions.d.ts.map +1 -0
- package/dist/forms/questions.js +179 -0
- package/dist/forms/questions.js.map +1 -0
- package/dist/forms/responses.d.ts +4 -0
- package/dist/forms/responses.d.ts.map +1 -0
- package/dist/forms/responses.js +40 -0
- package/dist/forms/responses.js.map +1 -0
- package/dist/forms/update.d.ts +3 -0
- package/dist/forms/update.d.ts.map +1 -0
- package/dist/forms/update.js +44 -0
- package/dist/forms/update.js.map +1 -0
- package/dist/gdrive/about.d.ts +3 -0
- package/dist/gdrive/about.d.ts.map +1 -0
- package/dist/gdrive/about.js +31 -0
- package/dist/gdrive/about.js.map +1 -0
- package/dist/gdrive/accounts.d.ts +3 -0
- package/dist/gdrive/accounts.d.ts.map +1 -0
- package/dist/gdrive/accounts.js +20 -0
- package/dist/gdrive/accounts.js.map +1 -0
- package/dist/gdrive/auth.d.ts +3 -0
- package/dist/gdrive/auth.d.ts.map +1 -0
- package/dist/gdrive/auth.js +51 -0
- package/dist/gdrive/auth.js.map +1 -0
- package/dist/gdrive/files.d.ts +12 -0
- package/dist/gdrive/files.d.ts.map +1 -0
- package/dist/gdrive/files.js +174 -0
- package/dist/gdrive/files.js.map +1 -0
- package/dist/gdrive/folders.d.ts +4 -0
- package/dist/gdrive/folders.d.ts.map +1 -0
- package/dist/gdrive/folders.js +46 -0
- package/dist/gdrive/folders.js.map +1 -0
- package/dist/gdrive/search.d.ts +3 -0
- package/dist/gdrive/search.d.ts.map +1 -0
- package/dist/gdrive/search.js +23 -0
- package/dist/gdrive/search.js.map +1 -0
- package/dist/gdrive/sharing.d.ts +5 -0
- package/dist/gdrive/sharing.d.ts.map +1 -0
- package/dist/gdrive/sharing.js +54 -0
- package/dist/gdrive/sharing.js.map +1 -0
- package/dist/gmail/accounts.d.ts +3 -0
- package/dist/gmail/accounts.d.ts.map +1 -0
- package/dist/gmail/accounts.js +18 -0
- package/dist/gmail/accounts.js.map +1 -0
- package/dist/gmail/auth.d.ts +3 -0
- package/dist/gmail/auth.d.ts.map +1 -0
- package/dist/gmail/auth.js +50 -0
- package/dist/gmail/auth.js.map +1 -0
- package/dist/gmail/drafts.d.ts +7 -0
- package/dist/gmail/drafts.d.ts.map +1 -0
- package/dist/gmail/drafts.js +103 -0
- package/dist/gmail/drafts.js.map +1 -0
- package/dist/gmail/get.d.ts +4 -0
- package/dist/gmail/get.d.ts.map +1 -0
- package/dist/gmail/get.js +140 -0
- package/dist/gmail/get.js.map +1 -0
- package/dist/gmail/inbox.d.ts +4 -0
- package/dist/gmail/inbox.d.ts.map +1 -0
- package/dist/gmail/inbox.js +45 -0
- package/dist/gmail/inbox.js.map +1 -0
- package/dist/gmail/labels.d.ts +5 -0
- package/dist/gmail/labels.d.ts.map +1 -0
- package/dist/gmail/labels.js +45 -0
- package/dist/gmail/labels.js.map +1 -0
- package/dist/gmail/modify.d.ts +5 -0
- package/dist/gmail/modify.d.ts.map +1 -0
- package/dist/gmail/modify.js +68 -0
- package/dist/gmail/modify.js.map +1 -0
- package/dist/gmail/send.d.ts +5 -0
- package/dist/gmail/send.d.ts.map +1 -0
- package/dist/gmail/send.js +310 -0
- package/dist/gmail/send.js.map +1 -0
- package/dist/gmail/threads.d.ts +4 -0
- package/dist/gmail/threads.d.ts.map +1 -0
- package/dist/gmail/threads.js +47 -0
- package/dist/gmail/threads.js.map +1 -0
- package/dist/gslides/accounts.d.ts +3 -0
- package/dist/gslides/accounts.d.ts.map +1 -0
- package/dist/gslides/accounts.js +20 -0
- package/dist/gslides/accounts.js.map +1 -0
- package/dist/gslides/auth.d.ts +3 -0
- package/dist/gslides/auth.d.ts.map +1 -0
- package/dist/gslides/auth.js +50 -0
- package/dist/gslides/auth.js.map +1 -0
- package/dist/gslides/presentations.d.ts +29 -0
- package/dist/gslides/presentations.d.ts.map +1 -0
- package/dist/gslides/presentations.js +320 -0
- package/dist/gslides/presentations.js.map +1 -0
- package/dist/lib/config.d.ts +6 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +12 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/media-utils.d.ts +5 -0
- package/dist/lib/media-utils.d.ts.map +1 -0
- package/dist/lib/media-utils.js +79 -0
- package/dist/lib/media-utils.js.map +1 -0
- package/dist/lib/output.d.ts +4 -0
- package/dist/lib/output.d.ts.map +1 -0
- package/dist/lib/output.js +12 -0
- package/dist/lib/output.js.map +1 -0
- package/dist/sheets/accounts.d.ts +3 -0
- package/dist/sheets/accounts.d.ts.map +1 -0
- package/dist/sheets/accounts.js +20 -0
- package/dist/sheets/accounts.js.map +1 -0
- package/dist/sheets/auth.d.ts +3 -0
- package/dist/sheets/auth.d.ts.map +1 -0
- package/dist/sheets/auth.js +56 -0
- package/dist/sheets/auth.js.map +1 -0
- package/dist/sheets/cells.d.ts +6 -0
- package/dist/sheets/cells.d.ts.map +1 -0
- package/dist/sheets/cells.js +89 -0
- package/dist/sheets/cells.js.map +1 -0
- package/dist/sheets/format.d.ts +8 -0
- package/dist/sheets/format.d.ts.map +1 -0
- package/dist/sheets/format.js +97 -0
- package/dist/sheets/format.js.map +1 -0
- package/dist/sheets/sheets-tab.d.ts +6 -0
- package/dist/sheets/sheets-tab.d.ts.map +1 -0
- package/dist/sheets/sheets-tab.js +88 -0
- package/dist/sheets/sheets-tab.js.map +1 -0
- package/dist/sheets/spreadsheets.d.ts +6 -0
- package/dist/sheets/spreadsheets.d.ts.map +1 -0
- package/dist/sheets/spreadsheets.js +88 -0
- package/dist/sheets/spreadsheets.js.map +1 -0
- package/package.json +33 -0
- package/src/__tests__/calendar.integration.test.ts +152 -0
- package/src/__tests__/forms.integration.test.ts +403 -0
- package/src/__tests__/gdrive.integration.test.ts +253 -0
- package/src/__tests__/gmail.integration.test.ts +294 -0
- package/src/__tests__/gslides.integration.test.ts +195 -0
- package/src/__tests__/sheets.integration.test.ts +234 -0
- package/src/agent/crud.ts +54 -0
- package/src/agent/memory.ts +95 -0
- package/src/agent/permissions.ts +54 -0
- package/src/calendar/accounts.ts +25 -0
- package/src/calendar/auth.ts +45 -0
- package/src/calendar/calendars.ts +32 -0
- package/src/calendar/create.ts +44 -0
- package/src/calendar/delete.ts +27 -0
- package/src/calendar/events.ts +45 -0
- package/src/calendar/get.ts +27 -0
- package/src/calendar/update.ts +44 -0
- package/src/cli.ts +41 -0
- package/src/commands/agent.ts +128 -0
- package/src/commands/calendar.ts +127 -0
- package/src/commands/cron.ts +126 -0
- package/src/commands/forms.ts +158 -0
- package/src/commands/gdrive.ts +225 -0
- package/src/commands/gmail.ts +290 -0
- package/src/commands/gslides.ts +188 -0
- package/src/commands/sheets.ts +193 -0
- package/src/cron/daemon.ts +143 -0
- package/src/cron/handlers.ts +78 -0
- package/src/cron/logger.ts +20 -0
- package/src/cron/progress.ts +90 -0
- package/src/cron/ralph-wiggum.ts +172 -0
- package/src/forms/accounts.ts +24 -0
- package/src/forms/auth.ts +45 -0
- package/src/forms/create.ts +34 -0
- package/src/forms/get.ts +26 -0
- package/src/forms/list.ts +38 -0
- package/src/forms/questions.ts +209 -0
- package/src/forms/responses.ts +50 -0
- package/src/forms/update.ts +57 -0
- package/src/gdrive/about.ts +36 -0
- package/src/gdrive/accounts.ts +24 -0
- package/src/gdrive/auth.ts +55 -0
- package/src/gdrive/files.ts +237 -0
- package/src/gdrive/folders.ts +58 -0
- package/src/gdrive/search.ts +30 -0
- package/src/gdrive/sharing.ts +72 -0
- package/src/gmail/accounts.ts +22 -0
- package/src/gmail/auth.ts +53 -0
- package/src/gmail/drafts.ts +166 -0
- package/src/gmail/get.ts +195 -0
- package/src/gmail/inbox.ts +78 -0
- package/src/gmail/labels.ts +69 -0
- package/src/gmail/modify.ts +89 -0
- package/src/gmail/send.ts +424 -0
- package/src/gmail/threads.ts +68 -0
- package/src/gslides/accounts.ts +24 -0
- package/src/gslides/auth.ts +54 -0
- package/src/gslides/presentations.ts +384 -0
- package/src/lib/config.ts +14 -0
- package/src/lib/media-utils.ts +82 -0
- package/src/lib/output.ts +13 -0
- package/src/sheets/accounts.ts +24 -0
- package/src/sheets/auth.ts +60 -0
- package/src/sheets/cells.ts +112 -0
- package/src/sheets/format.ts +114 -0
- package/src/sheets/sheets-tab.ts +109 -0
- package/src/sheets/spreadsheets.ts +106 -0
- package/tsconfig.json +8 -0
- package/vitest.config.ts +7 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { google } from "googleapis";
|
|
2
|
+
import type { OAuthClientManager } from "@digitalpresence/cliclaw-auth";
|
|
3
|
+
import { outputJson, outputError, outputAuthRequired } from "../lib/output.js";
|
|
4
|
+
|
|
5
|
+
function getSheets(clientManager: OAuthClientManager, tokenKey: string) {
|
|
6
|
+
const client = clientManager.getClient(tokenKey);
|
|
7
|
+
if (!client.credentials?.access_token && !client.credentials?.refresh_token) {
|
|
8
|
+
outputAuthRequired("sheets");
|
|
9
|
+
}
|
|
10
|
+
return google.sheets({ version: "v4", auth: client });
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function hexToColor(hex: string): { red: number; green: number; blue: number } {
|
|
14
|
+
const h = hex.replace("#", "");
|
|
15
|
+
return {
|
|
16
|
+
red: parseInt(h.substring(0, 2), 16) / 255,
|
|
17
|
+
green: parseInt(h.substring(2, 4), 16) / 255,
|
|
18
|
+
blue: parseInt(h.substring(4, 6), 16) / 255,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function parseA1Range(range: string): { sheetId: number; startRow: number; endRow: number; startCol: number; endCol: number } | null {
|
|
23
|
+
// Simple A1 parser: "Sheet1!A1:D10" or "A1:D10"
|
|
24
|
+
const match = range.match(/^(?:.*!)?([A-Z]+)(\d+):([A-Z]+)(\d+)$/);
|
|
25
|
+
if (!match) return null;
|
|
26
|
+
|
|
27
|
+
function colToIndex(col: string): number {
|
|
28
|
+
let idx = 0;
|
|
29
|
+
for (let i = 0; i < col.length; i++) {
|
|
30
|
+
idx = idx * 26 + (col.charCodeAt(i) - 64);
|
|
31
|
+
}
|
|
32
|
+
return idx - 1;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
sheetId: 0, // Default to first sheet; caller may override
|
|
37
|
+
startRow: parseInt(match[2]) - 1,
|
|
38
|
+
endRow: parseInt(match[4]),
|
|
39
|
+
startCol: colToIndex(match[1]),
|
|
40
|
+
endCol: colToIndex(match[3]) + 1,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export async function handleFormat(
|
|
45
|
+
clientManager: OAuthClientManager,
|
|
46
|
+
account: string,
|
|
47
|
+
spreadsheetId: string,
|
|
48
|
+
range: string,
|
|
49
|
+
options: { bold?: boolean; bgColor?: string; textColor?: string; sheetId?: number },
|
|
50
|
+
): Promise<void> {
|
|
51
|
+
const tokenKey = `gsheets:${account}`;
|
|
52
|
+
try {
|
|
53
|
+
const sheets = getSheets(clientManager, tokenKey);
|
|
54
|
+
|
|
55
|
+
const parsed = parseA1Range(range);
|
|
56
|
+
if (!parsed) {
|
|
57
|
+
outputError("format_failed", `Could not parse range: ${range}`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (options.sheetId !== undefined) {
|
|
61
|
+
parsed!.sheetId = options.sheetId;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const cellFormat: Record<string, unknown> = {};
|
|
65
|
+
const fields: string[] = [];
|
|
66
|
+
|
|
67
|
+
if (options.bold !== undefined) {
|
|
68
|
+
cellFormat.textFormat = { bold: options.bold };
|
|
69
|
+
fields.push("userEnteredFormat.textFormat.bold");
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (options.bgColor) {
|
|
73
|
+
cellFormat.backgroundColor = hexToColor(options.bgColor);
|
|
74
|
+
fields.push("userEnteredFormat.backgroundColor");
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (options.textColor) {
|
|
78
|
+
if (cellFormat.textFormat) {
|
|
79
|
+
(cellFormat.textFormat as Record<string, unknown>).foregroundColor = hexToColor(options.textColor);
|
|
80
|
+
} else {
|
|
81
|
+
cellFormat.textFormat = { foregroundColor: hexToColor(options.textColor) };
|
|
82
|
+
}
|
|
83
|
+
fields.push("userEnteredFormat.textFormat.foregroundColor");
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (fields.length === 0) {
|
|
87
|
+
outputError("format_failed", "No formatting options specified");
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
await sheets.spreadsheets.batchUpdate({
|
|
91
|
+
spreadsheetId,
|
|
92
|
+
requestBody: {
|
|
93
|
+
requests: [{
|
|
94
|
+
repeatCell: {
|
|
95
|
+
range: {
|
|
96
|
+
sheetId: parsed!.sheetId,
|
|
97
|
+
startRowIndex: parsed!.startRow,
|
|
98
|
+
endRowIndex: parsed!.endRow,
|
|
99
|
+
startColumnIndex: parsed!.startCol,
|
|
100
|
+
endColumnIndex: parsed!.endCol,
|
|
101
|
+
},
|
|
102
|
+
cell: { userEnteredFormat: cellFormat },
|
|
103
|
+
fields: fields.join(","),
|
|
104
|
+
},
|
|
105
|
+
}],
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
outputJson({ success: true, range, formatting: options });
|
|
110
|
+
} catch (err) {
|
|
111
|
+
if ((err as Error).message?.includes("format_failed")) throw err;
|
|
112
|
+
outputError("format_failed", err instanceof Error ? err.message : String(err));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { google } from "googleapis";
|
|
2
|
+
import type { OAuthClientManager } from "@digitalpresence/cliclaw-auth";
|
|
3
|
+
import { outputJson, outputError, outputAuthRequired } from "../lib/output.js";
|
|
4
|
+
|
|
5
|
+
function getSheets(clientManager: OAuthClientManager, tokenKey: string) {
|
|
6
|
+
const client = clientManager.getClient(tokenKey);
|
|
7
|
+
if (!client.credentials?.access_token && !client.credentials?.refresh_token) {
|
|
8
|
+
outputAuthRequired("sheets");
|
|
9
|
+
}
|
|
10
|
+
return google.sheets({ version: "v4", auth: client });
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export async function handleListSheets(
|
|
14
|
+
clientManager: OAuthClientManager,
|
|
15
|
+
account: string,
|
|
16
|
+
spreadsheetId: string,
|
|
17
|
+
): Promise<void> {
|
|
18
|
+
const tokenKey = `gsheets:${account}`;
|
|
19
|
+
try {
|
|
20
|
+
const sheets = getSheets(clientManager, tokenKey);
|
|
21
|
+
const res = await sheets.spreadsheets.get({
|
|
22
|
+
spreadsheetId,
|
|
23
|
+
fields: "sheets(properties)",
|
|
24
|
+
});
|
|
25
|
+
const tabList = res.data.sheets?.map((s) => ({
|
|
26
|
+
sheetId: s.properties?.sheetId,
|
|
27
|
+
title: s.properties?.title,
|
|
28
|
+
index: s.properties?.index,
|
|
29
|
+
})) ?? [];
|
|
30
|
+
outputJson(tabList);
|
|
31
|
+
} catch (err) {
|
|
32
|
+
outputError("list_sheets_failed", err instanceof Error ? err.message : String(err));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export async function handleAddSheet(
|
|
37
|
+
clientManager: OAuthClientManager,
|
|
38
|
+
account: string,
|
|
39
|
+
spreadsheetId: string,
|
|
40
|
+
title: string,
|
|
41
|
+
): Promise<void> {
|
|
42
|
+
const tokenKey = `gsheets:${account}`;
|
|
43
|
+
try {
|
|
44
|
+
const sheets = getSheets(clientManager, tokenKey);
|
|
45
|
+
const res = await sheets.spreadsheets.batchUpdate({
|
|
46
|
+
spreadsheetId,
|
|
47
|
+
requestBody: {
|
|
48
|
+
requests: [{ addSheet: { properties: { title } } }],
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
const reply = res.data.replies?.[0]?.addSheet?.properties;
|
|
52
|
+
outputJson({
|
|
53
|
+
success: true,
|
|
54
|
+
sheetId: reply?.sheetId,
|
|
55
|
+
title: reply?.title,
|
|
56
|
+
index: reply?.index,
|
|
57
|
+
});
|
|
58
|
+
} catch (err) {
|
|
59
|
+
outputError("add_sheet_failed", err instanceof Error ? err.message : String(err));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export async function handleDeleteSheet(
|
|
64
|
+
clientManager: OAuthClientManager,
|
|
65
|
+
account: string,
|
|
66
|
+
spreadsheetId: string,
|
|
67
|
+
sheetId: number,
|
|
68
|
+
): Promise<void> {
|
|
69
|
+
const tokenKey = `gsheets:${account}`;
|
|
70
|
+
try {
|
|
71
|
+
const sheets = getSheets(clientManager, tokenKey);
|
|
72
|
+
await sheets.spreadsheets.batchUpdate({
|
|
73
|
+
spreadsheetId,
|
|
74
|
+
requestBody: {
|
|
75
|
+
requests: [{ deleteSheet: { sheetId } }],
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
outputJson({ success: true, sheetId });
|
|
79
|
+
} catch (err) {
|
|
80
|
+
outputError("delete_sheet_failed", err instanceof Error ? err.message : String(err));
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export async function handleRenameSheet(
|
|
85
|
+
clientManager: OAuthClientManager,
|
|
86
|
+
account: string,
|
|
87
|
+
spreadsheetId: string,
|
|
88
|
+
sheetId: number,
|
|
89
|
+
title: string,
|
|
90
|
+
): Promise<void> {
|
|
91
|
+
const tokenKey = `gsheets:${account}`;
|
|
92
|
+
try {
|
|
93
|
+
const sheets = getSheets(clientManager, tokenKey);
|
|
94
|
+
await sheets.spreadsheets.batchUpdate({
|
|
95
|
+
spreadsheetId,
|
|
96
|
+
requestBody: {
|
|
97
|
+
requests: [{
|
|
98
|
+
updateSheetProperties: {
|
|
99
|
+
properties: { sheetId, title },
|
|
100
|
+
fields: "title",
|
|
101
|
+
},
|
|
102
|
+
}],
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
outputJson({ success: true, sheetId, title });
|
|
106
|
+
} catch (err) {
|
|
107
|
+
outputError("rename_sheet_failed", err instanceof Error ? err.message : String(err));
|
|
108
|
+
}
|
|
109
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { google } from "googleapis";
|
|
2
|
+
import type { OAuthClientManager } from "@digitalpresence/cliclaw-auth";
|
|
3
|
+
import { outputJson, outputError, outputAuthRequired } from "../lib/output.js";
|
|
4
|
+
|
|
5
|
+
function getSheets(clientManager: OAuthClientManager, tokenKey: string) {
|
|
6
|
+
const client = clientManager.getClient(tokenKey);
|
|
7
|
+
if (!client.credentials?.access_token && !client.credentials?.refresh_token) {
|
|
8
|
+
outputAuthRequired("sheets");
|
|
9
|
+
}
|
|
10
|
+
return google.sheets({ version: "v4", auth: client });
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function getDrive(clientManager: OAuthClientManager, tokenKey: string) {
|
|
14
|
+
const client = clientManager.getClient(tokenKey);
|
|
15
|
+
return google.drive({ version: "v3", auth: client });
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export async function handleList(
|
|
19
|
+
clientManager: OAuthClientManager,
|
|
20
|
+
account: string,
|
|
21
|
+
maxResults: number,
|
|
22
|
+
): Promise<void> {
|
|
23
|
+
const tokenKey = `gsheets:${account}`;
|
|
24
|
+
try {
|
|
25
|
+
const drive = getDrive(clientManager, tokenKey);
|
|
26
|
+
const res = await drive.files.list({
|
|
27
|
+
q: "mimeType='application/vnd.google-apps.spreadsheet' and trashed = false",
|
|
28
|
+
pageSize: maxResults,
|
|
29
|
+
fields: "files(id, name, modifiedTime, webViewLink)",
|
|
30
|
+
orderBy: "modifiedTime desc",
|
|
31
|
+
});
|
|
32
|
+
outputJson(res.data.files ?? []);
|
|
33
|
+
} catch (err) {
|
|
34
|
+
outputError("list_failed", err instanceof Error ? err.message : String(err));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export async function handleCreate(
|
|
39
|
+
clientManager: OAuthClientManager,
|
|
40
|
+
account: string,
|
|
41
|
+
title: string,
|
|
42
|
+
): Promise<void> {
|
|
43
|
+
const tokenKey = `gsheets:${account}`;
|
|
44
|
+
try {
|
|
45
|
+
const sheets = getSheets(clientManager, tokenKey);
|
|
46
|
+
const res = await sheets.spreadsheets.create({
|
|
47
|
+
requestBody: {
|
|
48
|
+
properties: { title },
|
|
49
|
+
},
|
|
50
|
+
fields: "spreadsheetId,spreadsheetUrl,properties",
|
|
51
|
+
});
|
|
52
|
+
outputJson({
|
|
53
|
+
success: true,
|
|
54
|
+
spreadsheetId: res.data.spreadsheetId,
|
|
55
|
+
url: res.data.spreadsheetUrl,
|
|
56
|
+
title: res.data.properties?.title,
|
|
57
|
+
});
|
|
58
|
+
} catch (err) {
|
|
59
|
+
outputError("create_failed", err instanceof Error ? err.message : String(err));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export async function handleGet(
|
|
64
|
+
clientManager: OAuthClientManager,
|
|
65
|
+
account: string,
|
|
66
|
+
spreadsheetId: string,
|
|
67
|
+
): Promise<void> {
|
|
68
|
+
const tokenKey = `gsheets:${account}`;
|
|
69
|
+
try {
|
|
70
|
+
const sheets = getSheets(clientManager, tokenKey);
|
|
71
|
+
const res = await sheets.spreadsheets.get({
|
|
72
|
+
spreadsheetId,
|
|
73
|
+
fields: "spreadsheetId,spreadsheetUrl,properties,sheets(properties)",
|
|
74
|
+
});
|
|
75
|
+
outputJson({
|
|
76
|
+
spreadsheetId: res.data.spreadsheetId,
|
|
77
|
+
url: res.data.spreadsheetUrl,
|
|
78
|
+
title: res.data.properties?.title,
|
|
79
|
+
locale: res.data.properties?.locale,
|
|
80
|
+
sheets: res.data.sheets?.map((s) => ({
|
|
81
|
+
sheetId: s.properties?.sheetId,
|
|
82
|
+
title: s.properties?.title,
|
|
83
|
+
index: s.properties?.index,
|
|
84
|
+
rowCount: s.properties?.gridProperties?.rowCount,
|
|
85
|
+
columnCount: s.properties?.gridProperties?.columnCount,
|
|
86
|
+
})),
|
|
87
|
+
});
|
|
88
|
+
} catch (err) {
|
|
89
|
+
outputError("get_failed", err instanceof Error ? err.message : String(err));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export async function handleDelete(
|
|
94
|
+
clientManager: OAuthClientManager,
|
|
95
|
+
account: string,
|
|
96
|
+
spreadsheetId: string,
|
|
97
|
+
): Promise<void> {
|
|
98
|
+
const tokenKey = `gsheets:${account}`;
|
|
99
|
+
try {
|
|
100
|
+
const drive = getDrive(clientManager, tokenKey);
|
|
101
|
+
await drive.files.delete({ fileId: spreadsheetId });
|
|
102
|
+
outputJson({ success: true, spreadsheetId });
|
|
103
|
+
} catch (err) {
|
|
104
|
+
outputError("delete_failed", err instanceof Error ? err.message : String(err));
|
|
105
|
+
}
|
|
106
|
+
}
|
package/tsconfig.json
ADDED