@aaronsb/google-workspace-mcp 2.7.1 → 4.0.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/LICENSE +201 -21
- package/LICENSE-MIT +21 -0
- package/NOTICE +24 -0
- package/README.md +87 -57
- package/build/accounts/auth.d.ts +1 -1
- package/build/accounts/auth.js +1 -1
- package/build/accounts/oauth.js +3 -3
- package/build/accounts/oauth.js.map +1 -1
- package/build/accounts/token-service.js +1 -1
- package/build/accounts/token-service.js.map +1 -1
- package/build/coverage/analyze.d.ts +1 -1
- package/build/coverage/analyze.js +6 -4
- package/build/coverage/analyze.js.map +1 -1
- package/build/coverage/baseline.js +37 -20
- package/build/coverage/baseline.js.map +1 -1
- package/build/coverage/compare.d.ts +1 -1
- package/build/coverage/compare.js +19 -10
- package/build/coverage/compare.js.map +1 -1
- package/build/coverage/discover.d.ts +5 -5
- package/build/coverage/discover.js +71 -155
- package/build/coverage/discover.js.map +1 -1
- package/build/coverage/report.js +3 -3
- package/build/coverage/report.js.map +1 -1
- package/build/coverage/types.d.ts +19 -4
- package/build/executor/index.d.ts +0 -3
- package/build/executor/index.js +1 -2
- package/build/executor/index.js.map +1 -1
- package/build/factory/defaults.js +30 -4
- package/build/factory/defaults.js.map +1 -1
- package/build/factory/generator.d.ts +10 -4
- package/build/factory/generator.js +86 -96
- package/build/factory/generator.js.map +1 -1
- package/build/factory/manifest/README.md +4 -3
- package/build/factory/manifest/calendar.yaml +1 -11
- package/build/factory/manifest/docs.yaml +15 -6
- package/build/factory/manifest/drive.yaml +1 -5
- package/build/factory/manifest/gmail.yaml +32 -25
- package/build/factory/manifest/meet.yaml +1 -1
- package/build/factory/manifest/sheets.yaml +2 -5
- package/build/factory/manifest/tasks.yaml +40 -2
- package/build/factory/patches.js +2 -0
- package/build/factory/patches.js.map +1 -1
- package/build/factory/registry.d.ts +2 -3
- package/build/factory/registry.js +3 -9
- package/build/factory/registry.js.map +1 -1
- package/build/factory/safety.js +4 -4
- package/build/factory/safety.js.map +1 -1
- package/build/factory/types.d.ts +16 -15
- package/build/google/client.d.ts +45 -0
- package/build/google/client.js +232 -0
- package/build/google/client.js.map +1 -0
- package/build/google/descriptor.d.ts +40 -0
- package/build/google/descriptor.js +37 -0
- package/build/google/descriptor.js.map +1 -0
- package/build/google/descriptor.json +5271 -0
- package/build/google/errors.d.ts +45 -0
- package/build/google/errors.js +44 -0
- package/build/google/errors.js.map +1 -0
- package/build/google/methods.d.ts +37 -0
- package/build/google/methods.js +13 -0
- package/build/google/methods.js.map +1 -0
- package/build/index.js +30 -4
- package/build/index.js.map +1 -1
- package/build/node-floor.d.ts +16 -0
- package/build/node-floor.js +73 -0
- package/build/node-floor.js.map +1 -0
- package/build/server/formatting/markdown.d.ts +1 -1
- package/build/server/formatting/markdown.js +1 -1
- package/build/server/formatting/next-steps.js +1 -1
- package/build/server/formatting/next-steps.js.map +1 -1
- package/build/server/handlers/accounts.js +2 -2
- package/build/server/handlers/accounts.js.map +1 -1
- package/build/server/scratchpad/adapters/import-doc.js +15 -13
- package/build/server/scratchpad/adapters/import-doc.js.map +1 -1
- package/build/server/scratchpad/adapters/import-drive.js +16 -11
- package/build/server/scratchpad/adapters/import-drive.js.map +1 -1
- package/build/server/scratchpad/adapters/import-email.js +3 -15
- package/build/server/scratchpad/adapters/import-email.js.map +1 -1
- package/build/server/scratchpad/adapters/import-meet.js +5 -17
- package/build/server/scratchpad/adapters/import-meet.js.map +1 -1
- package/build/server/scratchpad/adapters/import-sheet.js +5 -6
- package/build/server/scratchpad/adapters/import-sheet.js.map +1 -1
- package/build/server/scratchpad/adapters/send-calendar.js +18 -13
- package/build/server/scratchpad/adapters/send-calendar.js.map +1 -1
- package/build/server/scratchpad/adapters/send-doc.js +22 -17
- package/build/server/scratchpad/adapters/send-doc.js.map +1 -1
- package/build/server/scratchpad/adapters/send-email-draft.d.ts +1 -1
- package/build/server/scratchpad/adapters/send-email-draft.js +17 -25
- package/build/server/scratchpad/adapters/send-email-draft.js.map +1 -1
- package/build/server/scratchpad/adapters/send-email.d.ts +2 -2
- package/build/server/scratchpad/adapters/send-email.js +21 -25
- package/build/server/scratchpad/adapters/send-email.js.map +1 -1
- package/build/server/scratchpad/adapters/send-sheet.js +10 -10
- package/build/server/scratchpad/adapters/send-sheet.js.map +1 -1
- package/build/server/scratchpad/adapters/send-task.js +9 -8
- package/build/server/scratchpad/adapters/send-task.js.map +1 -1
- package/build/server/scratchpad/handler.js +22 -28
- package/build/server/scratchpad/handler.js.map +1 -1
- package/build/server/scratchpad/manager.d.ts +1 -1
- package/build/server/server.js +13 -10
- package/build/server/server.js.map +1 -1
- package/build/server/session/tracker.js +21 -25
- package/build/server/session/tracker.js.map +1 -1
- package/build/server/tools.d.ts +1 -1
- package/build/server/tools.js +3 -3
- package/build/server/tools.js.map +1 -1
- package/build/services/calendar/patch.js +178 -68
- package/build/services/calendar/patch.js.map +1 -1
- package/build/services/docs/patch.d.ts +5 -3
- package/build/services/docs/patch.js +89 -19
- package/build/services/docs/patch.js.map +1 -1
- package/build/services/drive/patch.d.ts +1 -1
- package/build/services/drive/patch.js +115 -143
- package/build/services/drive/patch.js.map +1 -1
- package/build/services/gmail/attachments.js +10 -15
- package/build/services/gmail/attachments.js.map +1 -1
- package/build/services/gmail/mail.d.ts +34 -0
- package/build/services/gmail/mail.js +245 -0
- package/build/services/gmail/mail.js.map +1 -0
- package/build/services/gmail/mime.d.ts +45 -4
- package/build/services/gmail/mime.js +138 -4
- package/build/services/gmail/mime.js.map +1 -1
- package/build/services/gmail/patch.js +103 -53
- package/build/services/gmail/patch.js.map +1 -1
- package/build/services/meet/patch.js +24 -31
- package/build/services/meet/patch.js.map +1 -1
- package/build/services/sheets/patch.js +30 -35
- package/build/services/sheets/patch.js.map +1 -1
- package/build/services/tasks/patch.d.ts +18 -0
- package/build/services/tasks/patch.js +37 -0
- package/build/services/tasks/patch.js.map +1 -0
- package/build/version.d.ts +1 -1
- package/build/version.js +2 -2
- package/build/version.js.map +1 -1
- package/package.json +23 -12
- package/build/__helpers__/testSetup.d.ts +0 -1
- package/build/__helpers__/testSetup.js +0 -6
- package/build/__helpers__/testSetup.js.map +0 -1
- package/build/__tests__/accounts/credentials.test.d.ts +0 -1
- package/build/__tests__/accounts/credentials.test.js +0 -127
- package/build/__tests__/accounts/credentials.test.js.map +0 -1
- package/build/__tests__/accounts/oauth.test.d.ts +0 -1
- package/build/__tests__/accounts/oauth.test.js +0 -71
- package/build/__tests__/accounts/oauth.test.js.map +0 -1
- package/build/__tests__/accounts/registry.test.d.ts +0 -1
- package/build/__tests__/accounts/registry.test.js +0 -74
- package/build/__tests__/accounts/registry.test.js.map +0 -1
- package/build/__tests__/accounts/token-service.test.d.ts +0 -1
- package/build/__tests__/accounts/token-service.test.js +0 -126
- package/build/__tests__/accounts/token-service.test.js.map +0 -1
- package/build/__tests__/executor/errors.test.d.ts +0 -1
- package/build/__tests__/executor/errors.test.js +0 -42
- package/build/__tests__/executor/errors.test.js.map +0 -1
- package/build/__tests__/executor/gws.test.d.ts +0 -1
- package/build/__tests__/executor/gws.test.js +0 -187
- package/build/__tests__/executor/gws.test.js.map +0 -1
- package/build/__tests__/executor/paths.test.d.ts +0 -1
- package/build/__tests__/executor/paths.test.js +0 -60
- package/build/__tests__/executor/paths.test.js.map +0 -1
- package/build/__tests__/executor/resolve-binary.test.d.ts +0 -1
- package/build/__tests__/executor/resolve-binary.test.js +0 -58
- package/build/__tests__/executor/resolve-binary.test.js.map +0 -1
- package/build/__tests__/executor/workspace.test.d.ts +0 -1
- package/build/__tests__/executor/workspace.test.js +0 -143
- package/build/__tests__/executor/workspace.test.js.map +0 -1
- package/build/__tests__/factory/calendar-patch.test.d.ts +0 -5
- package/build/__tests__/factory/calendar-patch.test.js +0 -269
- package/build/__tests__/factory/calendar-patch.test.js.map +0 -1
- package/build/__tests__/factory/drive-patch.test.d.ts +0 -5
- package/build/__tests__/factory/drive-patch.test.js +0 -344
- package/build/__tests__/factory/drive-patch.test.js.map +0 -1
- package/build/__tests__/factory/generator.test.d.ts +0 -1
- package/build/__tests__/factory/generator.test.js +0 -240
- package/build/__tests__/factory/generator.test.js.map +0 -1
- package/build/__tests__/factory/patch-coverage.test.d.ts +0 -10
- package/build/__tests__/factory/patch-coverage.test.js +0 -182
- package/build/__tests__/factory/patch-coverage.test.js.map +0 -1
- package/build/__tests__/factory/safety.test.d.ts +0 -1
- package/build/__tests__/factory/safety.test.js +0 -107
- package/build/__tests__/factory/safety.test.js.map +0 -1
- package/build/__tests__/factory/sheets-patch.test.d.ts +0 -6
- package/build/__tests__/factory/sheets-patch.test.js +0 -498
- package/build/__tests__/factory/sheets-patch.test.js.map +0 -1
- package/build/__tests__/integration/executor.test.d.ts +0 -5
- package/build/__tests__/integration/executor.test.js +0 -38
- package/build/__tests__/integration/executor.test.js.map +0 -1
- package/build/__tests__/integration/handlers.test.d.ts +0 -6
- package/build/__tests__/integration/handlers.test.js +0 -95
- package/build/__tests__/integration/handlers.test.js.map +0 -1
- package/build/__tests__/integration/setup.d.ts +0 -19
- package/build/__tests__/integration/setup.js +0 -61
- package/build/__tests__/integration/setup.js.map +0 -1
- package/build/__tests__/server/formatting/html-sanitize.test.d.ts +0 -7
- package/build/__tests__/server/formatting/html-sanitize.test.js +0 -174
- package/build/__tests__/server/formatting/html-sanitize.test.js.map +0 -1
- package/build/__tests__/server/formatting/markdown.test.d.ts +0 -1
- package/build/__tests__/server/formatting/markdown.test.js +0 -259
- package/build/__tests__/server/formatting/markdown.test.js.map +0 -1
- package/build/__tests__/server/formatting/next-steps.test.d.ts +0 -1
- package/build/__tests__/server/formatting/next-steps.test.js +0 -42
- package/build/__tests__/server/formatting/next-steps.test.js.map +0 -1
- package/build/__tests__/server/handler.test.d.ts +0 -1
- package/build/__tests__/server/handler.test.js +0 -97
- package/build/__tests__/server/handler.test.js.map +0 -1
- package/build/__tests__/server/handlers/__mocks__/executor.d.ts +0 -173
- package/build/__tests__/server/handlers/__mocks__/executor.js +0 -135
- package/build/__tests__/server/handlers/__mocks__/executor.js.map +0 -1
- package/build/__tests__/server/handlers/accounts.test.d.ts +0 -1
- package/build/__tests__/server/handlers/accounts.test.js +0 -129
- package/build/__tests__/server/handlers/accounts.test.js.map +0 -1
- package/build/__tests__/server/handlers/calendar.test.d.ts +0 -1
- package/build/__tests__/server/handlers/calendar.test.js +0 -96
- package/build/__tests__/server/handlers/calendar.test.js.map +0 -1
- package/build/__tests__/server/handlers/drive.test.d.ts +0 -1
- package/build/__tests__/server/handlers/drive.test.js +0 -68
- package/build/__tests__/server/handlers/drive.test.js.map +0 -1
- package/build/__tests__/server/handlers/email.test.d.ts +0 -1
- package/build/__tests__/server/handlers/email.test.js +0 -99
- package/build/__tests__/server/handlers/email.test.js.map +0 -1
- package/build/__tests__/server/handlers/validate.test.d.ts +0 -1
- package/build/__tests__/server/handlers/validate.test.js +0 -88
- package/build/__tests__/server/handlers/validate.test.js.map +0 -1
- package/build/__tests__/server/queue.test.d.ts +0 -1
- package/build/__tests__/server/queue.test.js +0 -199
- package/build/__tests__/server/queue.test.js.map +0 -1
- package/build/__tests__/server/server.test.d.ts +0 -7
- package/build/__tests__/server/server.test.js +0 -135
- package/build/__tests__/server/server.test.js.map +0 -1
- package/build/__tests__/server/session/context.test.d.ts +0 -1
- package/build/__tests__/server/session/context.test.js +0 -101
- package/build/__tests__/server/session/context.test.js.map +0 -1
- package/build/__tests__/server/session/tracker.test.d.ts +0 -1
- package/build/__tests__/server/session/tracker.test.js +0 -146
- package/build/__tests__/server/session/tracker.test.js.map +0 -1
- package/build/__tests__/server/tools.test.d.ts +0 -1
- package/build/__tests__/server/tools.test.js +0 -91
- package/build/__tests__/server/tools.test.js.map +0 -1
- package/build/__tests__/services/gmail/mime.test.d.ts +0 -1
- package/build/__tests__/services/gmail/mime.test.js +0 -23
- package/build/__tests__/services/gmail/mime.test.js.map +0 -1
- package/build/__tests__/services/meet/patch.test.d.ts +0 -4
- package/build/__tests__/services/meet/patch.test.js +0 -374
- package/build/__tests__/services/meet/patch.test.js.map +0 -1
- package/build/executor/errors.d.ts +0 -15
- package/build/executor/errors.js +0 -37
- package/build/executor/errors.js.map +0 -1
- package/build/executor/gws.d.ts +0 -26
- package/build/executor/gws.js +0 -197
- package/build/executor/gws.js.map +0 -1
- package/build/server/handlers/calendar.d.ts +0 -2
- package/build/server/handlers/calendar.js +0 -97
- package/build/server/handlers/calendar.js.map +0 -1
- package/build/server/handlers/drive.d.ts +0 -2
- package/build/server/handlers/drive.js +0 -58
- package/build/server/handlers/drive.js.map +0 -1
- package/build/server/handlers/email.d.ts +0 -2
- package/build/server/handlers/email.js +0 -119
- package/build/server/handlers/email.js.map +0 -1
- package/build/server/scratchpad/__tests__/docs-sync-integration.test.d.ts +0 -11
- package/build/server/scratchpad/__tests__/docs-sync-integration.test.js +0 -187
- package/build/server/scratchpad/__tests__/docs-sync-integration.test.js.map +0 -1
- package/build/server/scratchpad/__tests__/docs-sync.test.d.ts +0 -16
- package/build/server/scratchpad/__tests__/docs-sync.test.js +0 -213
- package/build/server/scratchpad/__tests__/docs-sync.test.js.map +0 -1
- package/build/server/scratchpad/__tests__/json-path.test.d.ts +0 -4
- package/build/server/scratchpad/__tests__/json-path.test.js +0 -121
- package/build/server/scratchpad/__tests__/json-path.test.js.map +0 -1
- package/build/server/scratchpad/__tests__/manager.test.d.ts +0 -5
- package/build/server/scratchpad/__tests__/manager.test.js +0 -886
- package/build/server/scratchpad/__tests__/manager.test.js.map +0 -1
- package/build/server/scratchpad/__tests__/validate.test.d.ts +0 -4
- package/build/server/scratchpad/__tests__/validate.test.js +0 -112
- package/build/server/scratchpad/__tests__/validate.test.js.map +0 -1
|
@@ -1,259 +0,0 @@
|
|
|
1
|
-
import { formatEmailList, formatEmailDetail, formatEventList, formatEventDetail, formatFileList, formatFileDetail, } from '../../../server/formatting/markdown.js';
|
|
2
|
-
describe('formatEmailList', () => {
|
|
3
|
-
it('formats triage response as markdown with pipe-delimited rows', () => {
|
|
4
|
-
const result = formatEmailList({
|
|
5
|
-
messages: [
|
|
6
|
-
{ id: 'msg-1', from: 'alice@test.com', subject: 'Hello', date: 'Mon, 10 Mar 2026' },
|
|
7
|
-
{ id: 'msg-2', from: 'bob@test.com', subject: 'Meeting' },
|
|
8
|
-
],
|
|
9
|
-
});
|
|
10
|
-
expect(result.text).toContain('## Messages (2)');
|
|
11
|
-
expect(result.text).toContain('msg-1 | alice@test.com | Hello');
|
|
12
|
-
expect(result.text).toContain('msg-2 | bob@test.com | Meeting');
|
|
13
|
-
expect(result.refs.count).toBe(2);
|
|
14
|
-
expect(result.refs.messageId).toBe('msg-1');
|
|
15
|
-
});
|
|
16
|
-
it('handles empty messages with valid API response', () => {
|
|
17
|
-
const result = formatEmailList({ messages: [], resultSizeEstimate: 0, query: 'from:nobody' });
|
|
18
|
-
expect(result.text).toBe('No messages found for query: "from:nobody".');
|
|
19
|
-
expect(result.refs.count).toBe(0);
|
|
20
|
-
expect(result.refs.apiResponseValid).toBe(true);
|
|
21
|
-
});
|
|
22
|
-
it('flags suspicious empty response missing expected fields', () => {
|
|
23
|
-
const result = formatEmailList({});
|
|
24
|
-
expect(result.text).toContain('authentication or scope issue');
|
|
25
|
-
expect(result.refs.apiResponseValid).toBe(false);
|
|
26
|
-
});
|
|
27
|
-
it('handles valid empty response without query', () => {
|
|
28
|
-
const result = formatEmailList({ messages: [], resultSizeEstimate: 0 });
|
|
29
|
-
expect(result.text).toBe('No messages found.');
|
|
30
|
-
expect(result.refs.apiResponseValid).toBe(true);
|
|
31
|
-
});
|
|
32
|
-
it('falls back to items array', () => {
|
|
33
|
-
const result = formatEmailList({ items: [{ id: 'x', from: 'a@b.com', subject: 'Hi' }] });
|
|
34
|
-
expect(result.refs.count).toBe(1);
|
|
35
|
-
expect(result.text).toContain('x |');
|
|
36
|
-
});
|
|
37
|
-
it('provides message IDs array in refs', () => {
|
|
38
|
-
const result = formatEmailList({
|
|
39
|
-
messages: [{ id: 'a' }, { id: 'b' }, { id: 'c' }],
|
|
40
|
-
});
|
|
41
|
-
expect(result.refs.messages).toEqual(['a', 'b', 'c']);
|
|
42
|
-
});
|
|
43
|
-
});
|
|
44
|
-
describe('formatEmailDetail', () => {
|
|
45
|
-
it('formats as prose with headers', () => {
|
|
46
|
-
const result = formatEmailDetail({
|
|
47
|
-
id: 'msg-1', threadId: 'thread-1', snippet: 'Preview',
|
|
48
|
-
labelIds: ['INBOX'],
|
|
49
|
-
payload: {
|
|
50
|
-
headers: [
|
|
51
|
-
{ name: 'From', value: 'alice@test.com' },
|
|
52
|
-
{ name: 'Subject', value: 'Test' },
|
|
53
|
-
{ name: 'Date', value: '2026-03-14' },
|
|
54
|
-
],
|
|
55
|
-
},
|
|
56
|
-
});
|
|
57
|
-
expect(result.text).toContain('## Test');
|
|
58
|
-
expect(result.text).toContain('**From:** alice@test.com');
|
|
59
|
-
expect(result.text).toContain('**Labels:** INBOX');
|
|
60
|
-
expect(result.text).toContain('Preview');
|
|
61
|
-
expect(result.refs.from).toBe('alice@test.com');
|
|
62
|
-
expect(result.refs.subject).toBe('Test');
|
|
63
|
-
expect(result.refs.id).toBe('msg-1');
|
|
64
|
-
});
|
|
65
|
-
it('handles missing payload', () => {
|
|
66
|
-
const result = formatEmailDetail({ id: 'msg-1' });
|
|
67
|
-
expect(result.text).toContain('**From:**');
|
|
68
|
-
expect(result.refs.from).toBe('');
|
|
69
|
-
});
|
|
70
|
-
it('extracts full body from text/plain payload part', () => {
|
|
71
|
-
const fullText = 'Hello Aaron, your invoice has been approved. Please include your Tax ID on future invoices.';
|
|
72
|
-
const base64Body = Buffer.from(fullText).toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
|
73
|
-
const result = formatEmailDetail({
|
|
74
|
-
id: 'msg-2', threadId: 'thread-2', snippet: 'Hello Aaron, your invoice has been',
|
|
75
|
-
payload: {
|
|
76
|
-
headers: [{ name: 'From', value: 'val@jvl.ca' }, { name: 'Subject', value: 'Invoice' }],
|
|
77
|
-
mimeType: 'multipart/alternative',
|
|
78
|
-
parts: [
|
|
79
|
-
{ mimeType: 'text/plain', body: { data: base64Body, size: fullText.length } },
|
|
80
|
-
{ mimeType: 'text/html', body: { data: base64Body, size: fullText.length } },
|
|
81
|
-
],
|
|
82
|
-
},
|
|
83
|
-
});
|
|
84
|
-
expect(result.text).toContain('Tax ID on future invoices');
|
|
85
|
-
expect(result.text).not.toContain('Showing snippet only');
|
|
86
|
-
expect(result.refs.bodyTruncated).toBe(false);
|
|
87
|
-
});
|
|
88
|
-
it('falls back to snippet when payload has no body data', () => {
|
|
89
|
-
const result = formatEmailDetail({
|
|
90
|
-
id: 'msg-3', snippet: 'Snippet fallback',
|
|
91
|
-
payload: {
|
|
92
|
-
headers: [{ name: 'From', value: 'a@b.com' }],
|
|
93
|
-
},
|
|
94
|
-
});
|
|
95
|
-
expect(result.text).toContain('Snippet fallback');
|
|
96
|
-
});
|
|
97
|
-
it('with bodyFormat: html, prefers text/html and returns it sanitized + wrapped', () => {
|
|
98
|
-
const htmlBody = '<p>The party is <b>Saturday at 7pm</b>.</p><script>alert(1)</script>';
|
|
99
|
-
const base64 = (s) => Buffer.from(s).toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
|
100
|
-
const result = formatEmailDetail({
|
|
101
|
-
id: 'msg-html', threadId: 'th', snippet: 'View this email',
|
|
102
|
-
payload: {
|
|
103
|
-
headers: [{ name: 'From', value: 'invites@paperlesspost.com' }, { name: 'Subject', value: 'You\'re invited' }],
|
|
104
|
-
mimeType: 'multipart/alternative',
|
|
105
|
-
parts: [
|
|
106
|
-
{ mimeType: 'text/plain', body: { data: base64('View this email in your browser.'), size: 32 } },
|
|
107
|
-
{ mimeType: 'text/html', body: { data: base64(htmlBody), size: htmlBody.length } },
|
|
108
|
-
],
|
|
109
|
-
},
|
|
110
|
-
}, { bodyFormat: 'html' });
|
|
111
|
-
expect(result.text).toContain('Saturday at 7pm');
|
|
112
|
-
expect(result.text).toContain('<gmail_content trust="untrusted">');
|
|
113
|
-
expect(result.text).not.toContain('<script>');
|
|
114
|
-
expect(result.text).not.toContain('alert(1)');
|
|
115
|
-
// Crucially: the stub text/plain body ("View this email in your browser") is bypassed.
|
|
116
|
-
expect(result.text).not.toContain('View this email in your browser');
|
|
117
|
-
});
|
|
118
|
-
it('with bodyFormat: html and no html part, falls back to the text/plain part', () => {
|
|
119
|
-
const plain = 'Just plain text here.';
|
|
120
|
-
const base64 = (s) => Buffer.from(s).toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
|
121
|
-
const result = formatEmailDetail({
|
|
122
|
-
id: 'msg-plain-only',
|
|
123
|
-
payload: {
|
|
124
|
-
headers: [{ name: 'From', value: 'a@b.com' }],
|
|
125
|
-
mimeType: 'multipart/alternative',
|
|
126
|
-
parts: [
|
|
127
|
-
{ mimeType: 'text/plain', body: { data: base64(plain), size: plain.length } },
|
|
128
|
-
],
|
|
129
|
-
},
|
|
130
|
-
}, { bodyFormat: 'html' });
|
|
131
|
-
expect(result.text).toContain('Just plain text here');
|
|
132
|
-
expect(result.text).not.toContain('<gmail_content');
|
|
133
|
-
});
|
|
134
|
-
it('default bodyFormat (plain) is unchanged — no Spotlighting wrapper, no HTML', () => {
|
|
135
|
-
const plain = 'Hello plain world.';
|
|
136
|
-
const base64 = (s) => Buffer.from(s).toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
|
137
|
-
const result = formatEmailDetail({
|
|
138
|
-
id: 'msg-default',
|
|
139
|
-
payload: {
|
|
140
|
-
headers: [{ name: 'From', value: 'a@b.com' }],
|
|
141
|
-
mimeType: 'multipart/alternative',
|
|
142
|
-
parts: [
|
|
143
|
-
{ mimeType: 'text/plain', body: { data: base64(plain), size: plain.length } },
|
|
144
|
-
{ mimeType: 'text/html', body: { data: base64('<p>Hello <b>HTML</b> world.</p>'), size: 30 } },
|
|
145
|
-
],
|
|
146
|
-
},
|
|
147
|
-
});
|
|
148
|
-
expect(result.text).toContain('Hello plain world');
|
|
149
|
-
expect(result.text).not.toContain('<gmail_content');
|
|
150
|
-
expect(result.text).not.toContain('<p>');
|
|
151
|
-
});
|
|
152
|
-
it('shows snippet with size hint for very large bodies', () => {
|
|
153
|
-
// Generate a body larger than 12k tokens (~48KB+)
|
|
154
|
-
const largeText = 'x'.repeat(60_000);
|
|
155
|
-
const base64Body = Buffer.from(largeText).toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
|
156
|
-
const result = formatEmailDetail({
|
|
157
|
-
id: 'msg-4', snippet: 'This is the snippet',
|
|
158
|
-
payload: {
|
|
159
|
-
headers: [{ name: 'From', value: 'a@b.com' }],
|
|
160
|
-
body: { data: base64Body, size: largeText.length },
|
|
161
|
-
},
|
|
162
|
-
});
|
|
163
|
-
expect(result.text).toContain('This is the snippet');
|
|
164
|
-
expect(result.text).toContain('Showing snippet only');
|
|
165
|
-
expect(result.text).toContain('tokens');
|
|
166
|
-
expect(result.refs.bodyTruncated).toBe(true);
|
|
167
|
-
expect(result.refs.fullBodyTokens).toBeGreaterThan(12_000);
|
|
168
|
-
});
|
|
169
|
-
});
|
|
170
|
-
describe('formatEventList', () => {
|
|
171
|
-
it('formats events with markers and pipe-delimited fields', () => {
|
|
172
|
-
const result = formatEventList({
|
|
173
|
-
items: [
|
|
174
|
-
{ id: 'evt-1', summary: 'Standup', start: { dateTime: '2026-03-14T09:00:00Z' }, end: { dateTime: '2026-03-14T09:30:00Z' }, status: 'confirmed', attendees: [{}, {}] },
|
|
175
|
-
{ id: 'evt-2', summary: 'Lunch', start: { date: '2026-03-14' }, end: { date: '2026-03-14' }, status: 'confirmed' },
|
|
176
|
-
],
|
|
177
|
-
});
|
|
178
|
-
expect(result.text).toContain('## Events (2)');
|
|
179
|
-
expect(result.text).toContain('Standup');
|
|
180
|
-
expect(result.text).toContain('2 attendees');
|
|
181
|
-
expect(result.text).toContain('_(evt-1)_');
|
|
182
|
-
expect(result.refs.count).toBe(2);
|
|
183
|
-
expect(result.refs.eventId).toBe('evt-1');
|
|
184
|
-
});
|
|
185
|
-
it('handles missing title', () => {
|
|
186
|
-
const result = formatEventList({ items: [{ id: 'x', start: {}, end: {} }] });
|
|
187
|
-
expect(result.text).toContain('(no title)');
|
|
188
|
-
});
|
|
189
|
-
it('handles empty items', () => {
|
|
190
|
-
expect(formatEventList({}).text).toBe('No events found.');
|
|
191
|
-
expect(formatEventList({}).refs.count).toBe(0);
|
|
192
|
-
});
|
|
193
|
-
});
|
|
194
|
-
describe('formatEventDetail', () => {
|
|
195
|
-
it('formats as prose with attendees and meet link', () => {
|
|
196
|
-
const result = formatEventDetail({
|
|
197
|
-
id: 'evt-1', summary: 'Meeting',
|
|
198
|
-
start: { dateTime: '2026-03-14T10:00:00Z' },
|
|
199
|
-
end: { dateTime: '2026-03-14T11:00:00Z' },
|
|
200
|
-
organizer: { email: 'org@test.com' },
|
|
201
|
-
attendees: [{ email: 'a@test.com', responseStatus: 'accepted' }],
|
|
202
|
-
conferenceData: { entryPoints: [{ entryPointType: 'video', uri: 'https://meet.google.com/xxx' }] },
|
|
203
|
-
});
|
|
204
|
-
expect(result.text).toContain('## Meeting');
|
|
205
|
-
expect(result.text).toContain('**Organizer:** org@test.com');
|
|
206
|
-
expect(result.text).toContain('[x] a@test.com');
|
|
207
|
-
expect(result.text).toContain('https://meet.google.com/xxx');
|
|
208
|
-
expect(result.refs.organizer).toBe('org@test.com');
|
|
209
|
-
expect(result.refs.meetLink).toBe('https://meet.google.com/xxx');
|
|
210
|
-
});
|
|
211
|
-
it('handles missing conference data', () => {
|
|
212
|
-
const result = formatEventDetail({ id: 'x', start: {}, end: {} });
|
|
213
|
-
expect(result.refs.meetLink).toBeUndefined();
|
|
214
|
-
});
|
|
215
|
-
it('shows declined attendees with [-] marker', () => {
|
|
216
|
-
const result = formatEventDetail({
|
|
217
|
-
id: 'x', start: {}, end: {},
|
|
218
|
-
attendees: [{ email: 'dec@test.com', responseStatus: 'declined' }],
|
|
219
|
-
});
|
|
220
|
-
expect(result.text).toContain('[-] dec@test.com');
|
|
221
|
-
});
|
|
222
|
-
});
|
|
223
|
-
describe('formatFileList', () => {
|
|
224
|
-
it('formats files with pipe-delimited rows', () => {
|
|
225
|
-
const result = formatFileList({
|
|
226
|
-
files: [
|
|
227
|
-
{ id: 'f-1', name: 'report.pdf', mimeType: 'application/pdf', modifiedTime: '2026-03-14', size: '1024', webViewLink: 'https://...' },
|
|
228
|
-
{ id: 'f-2', name: 'notes.gdoc', mimeType: 'application/vnd.google-apps.document', modifiedTime: '2026-03-13' },
|
|
229
|
-
],
|
|
230
|
-
});
|
|
231
|
-
expect(result.text).toContain('## Files (2)');
|
|
232
|
-
expect(result.text).toContain('report.pdf');
|
|
233
|
-
expect(result.text).toContain('pdf');
|
|
234
|
-
expect(result.text).toContain('g/document');
|
|
235
|
-
expect(result.refs.count).toBe(2);
|
|
236
|
-
expect(result.refs.fileId).toBe('f-1');
|
|
237
|
-
});
|
|
238
|
-
it('handles empty files', () => {
|
|
239
|
-
expect(formatFileList({}).text).toBe('No files found.');
|
|
240
|
-
expect(formatFileList({ files: [] }).text).toBe('No files found.');
|
|
241
|
-
});
|
|
242
|
-
});
|
|
243
|
-
describe('formatFileDetail', () => {
|
|
244
|
-
it('formats as prose with metadata', () => {
|
|
245
|
-
const result = formatFileDetail({
|
|
246
|
-
id: 'f-1', name: 'report.pdf', mimeType: 'application/pdf',
|
|
247
|
-
modifiedTime: '2026-03-14T10:00:00Z', size: '1048576',
|
|
248
|
-
webViewLink: 'https://drive.google.com/file/d/f-1/view',
|
|
249
|
-
owners: [{ emailAddress: 'user@test.com' }],
|
|
250
|
-
shared: false,
|
|
251
|
-
});
|
|
252
|
-
expect(result.text).toContain('## report.pdf');
|
|
253
|
-
expect(result.text).toContain('**Size:** 1.0 MB');
|
|
254
|
-
expect(result.text).toContain('**Owner:** user@test.com');
|
|
255
|
-
expect(result.text).toContain('**Shared:** no');
|
|
256
|
-
expect(result.refs.fileId).toBe('f-1');
|
|
257
|
-
});
|
|
258
|
-
});
|
|
259
|
-
//# sourceMappingURL=markdown.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"markdown.test.js","sourceRoot":"","sources":["../../../../src/__tests__/server/formatting/markdown.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { nextSteps } from '../../../server/formatting/next-steps.js';
|
|
2
|
-
describe('nextSteps', () => {
|
|
3
|
-
it('returns markdown footer for known domain/operation', () => {
|
|
4
|
-
const result = nextSteps('email', 'triage');
|
|
5
|
-
expect(result).toContain('---');
|
|
6
|
-
expect(result).toContain('**Next steps:**');
|
|
7
|
-
expect(result).toContain('manage_email');
|
|
8
|
-
});
|
|
9
|
-
it('returns empty string for unknown domain', () => {
|
|
10
|
-
expect(nextSteps('unknown', 'whatever')).toBe('');
|
|
11
|
-
});
|
|
12
|
-
it('returns empty string for unknown operation', () => {
|
|
13
|
-
expect(nextSteps('email', 'nonexistent')).toBe('');
|
|
14
|
-
});
|
|
15
|
-
it('replaces placeholders with context values', () => {
|
|
16
|
-
const result = nextSteps('email', 'read', { messageId: 'msg-123', email: 'u@t.com' });
|
|
17
|
-
expect(result).toContain('msg-123');
|
|
18
|
-
expect(result).toContain('u@t.com');
|
|
19
|
-
});
|
|
20
|
-
it('leaves unreplaced placeholders as-is', () => {
|
|
21
|
-
const result = nextSteps('email', 'read', { messageId: 'msg-123' });
|
|
22
|
-
// email placeholder not in context, stays as <email>
|
|
23
|
-
expect(result).toContain('<email>');
|
|
24
|
-
});
|
|
25
|
-
it('covers all domains with at least one operation', () => {
|
|
26
|
-
const domainOps = {
|
|
27
|
-
accounts: 'list', email: 'triage', calendar: 'list', drive: 'search',
|
|
28
|
-
};
|
|
29
|
-
for (const [domain, op] of Object.entries(domainOps)) {
|
|
30
|
-
const result = nextSteps(domain, op);
|
|
31
|
-
expect(result.length).toBeGreaterThan(0);
|
|
32
|
-
expect(result).toContain('**Next steps:**');
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
it('formats each step with tool name and JSON example', () => {
|
|
36
|
-
const result = nextSteps('drive', 'search');
|
|
37
|
-
// Should contain tool name in backticks and JSON example in backticks
|
|
38
|
-
expect(result).toMatch(/`manage_drive`/);
|
|
39
|
-
expect(result).toMatch(/`\{.*"operation".*\}`/);
|
|
40
|
-
});
|
|
41
|
-
});
|
|
42
|
-
//# sourceMappingURL=next-steps.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"next-steps.test.js","sourceRoot":"","sources":["../../../../src/__tests__/server/formatting/next-steps.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,0CAA0C,CAAC;AAErE,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IACzB,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAChC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,CAAC,SAAS,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QACtF,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;QACpE,qDAAqD;QACrD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,MAAM,SAAS,GAA2B;YACxC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ;SACrE,CAAC;QACF,KAAK,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;YACrD,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YACrC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;YACzC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC5C,sEAAsE;QACtE,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;QACzC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
// Mock registry before handler imports it — avoids import.meta.url in Jest
|
|
2
|
-
jest.mock('../../factory/registry.js', () => {
|
|
3
|
-
const { loadManifest, generateTools } = jest.requireActual('../../factory/generator.js');
|
|
4
|
-
const { patches } = jest.requireActual('../../factory/patches.js');
|
|
5
|
-
const manifest = loadManifest();
|
|
6
|
-
return { manifest, generatedTools: generateTools(manifest, patches) };
|
|
7
|
-
});
|
|
8
|
-
import { handleToolCall } from '../../server/handler.js';
|
|
9
|
-
// Mock gws executor — all factory-generated handlers call through here
|
|
10
|
-
jest.mock('../../executor/gws.js');
|
|
11
|
-
// Mock accounts handler — still hand-coded
|
|
12
|
-
jest.mock('../../server/handlers/accounts.js');
|
|
13
|
-
// Mock queue handler — still hand-coded
|
|
14
|
-
jest.mock('../../server/queue.js');
|
|
15
|
-
import { execute } from '../../executor/gws.js';
|
|
16
|
-
import { handleAccounts } from '../../server/handlers/accounts.js';
|
|
17
|
-
import { handleQueue } from '../../server/queue.js';
|
|
18
|
-
const mockExecute = execute;
|
|
19
|
-
const mockAccounts = handleAccounts;
|
|
20
|
-
const mockQueue = handleQueue;
|
|
21
|
-
const stubResponse = { text: 'ok', refs: {} };
|
|
22
|
-
describe('handleToolCall', () => {
|
|
23
|
-
beforeEach(() => {
|
|
24
|
-
jest.resetAllMocks();
|
|
25
|
-
});
|
|
26
|
-
it('routes manage_accounts to handleAccounts', async () => {
|
|
27
|
-
mockAccounts.mockResolvedValue(stubResponse);
|
|
28
|
-
const params = { operation: 'list' };
|
|
29
|
-
await handleToolCall('manage_accounts', params);
|
|
30
|
-
expect(mockAccounts).toHaveBeenCalledWith(params);
|
|
31
|
-
expect(mockExecute).not.toHaveBeenCalled();
|
|
32
|
-
});
|
|
33
|
-
it('routes manage_email to factory-generated handler', async () => {
|
|
34
|
-
// Factory handler calls execute() for triage (helper: +triage)
|
|
35
|
-
mockExecute.mockResolvedValue({
|
|
36
|
-
success: true,
|
|
37
|
-
data: { messages: [] },
|
|
38
|
-
stderr: '',
|
|
39
|
-
});
|
|
40
|
-
const params = { operation: 'triage', email: 'u@t.com' };
|
|
41
|
-
const result = await handleToolCall('manage_email', params);
|
|
42
|
-
expect(mockExecute).toHaveBeenCalled();
|
|
43
|
-
expect(result).toHaveProperty('text');
|
|
44
|
-
expect(result).toHaveProperty('refs');
|
|
45
|
-
});
|
|
46
|
-
it('routes manage_calendar to factory-generated handler', async () => {
|
|
47
|
-
mockExecute.mockResolvedValue({
|
|
48
|
-
success: true,
|
|
49
|
-
data: { items: [] },
|
|
50
|
-
stderr: '',
|
|
51
|
-
});
|
|
52
|
-
const params = { operation: 'list', email: 'u@t.com' };
|
|
53
|
-
const result = await handleToolCall('manage_calendar', params);
|
|
54
|
-
expect(mockExecute).toHaveBeenCalled();
|
|
55
|
-
expect(result).toHaveProperty('text');
|
|
56
|
-
});
|
|
57
|
-
it('routes manage_drive to factory-generated handler', async () => {
|
|
58
|
-
mockExecute.mockResolvedValue({
|
|
59
|
-
success: true,
|
|
60
|
-
data: { files: [] },
|
|
61
|
-
stderr: '',
|
|
62
|
-
});
|
|
63
|
-
const params = { operation: 'search', email: 'u@t.com' };
|
|
64
|
-
const result = await handleToolCall('manage_drive', params);
|
|
65
|
-
expect(mockExecute).toHaveBeenCalled();
|
|
66
|
-
expect(result).toHaveProperty('text');
|
|
67
|
-
});
|
|
68
|
-
it('routes queue_operations to handleQueue with domain handlers', async () => {
|
|
69
|
-
mockQueue.mockResolvedValue(stubResponse);
|
|
70
|
-
const params = { operations: [{ tool: 'manage_email', args: {} }] };
|
|
71
|
-
await handleToolCall('queue_operations', params);
|
|
72
|
-
expect(mockQueue).toHaveBeenCalledWith(params, expect.objectContaining({
|
|
73
|
-
manage_accounts: expect.any(Function),
|
|
74
|
-
manage_email: expect.any(Function),
|
|
75
|
-
manage_calendar: expect.any(Function),
|
|
76
|
-
manage_drive: expect.any(Function),
|
|
77
|
-
}));
|
|
78
|
-
});
|
|
79
|
-
it('throws on unknown tool name', async () => {
|
|
80
|
-
await expect(handleToolCall('nonexistent', {})).rejects.toThrow('Unknown tool: nonexistent');
|
|
81
|
-
});
|
|
82
|
-
it('propagates executor errors through factory handler', async () => {
|
|
83
|
-
mockExecute.mockRejectedValue(new Error('API failure'));
|
|
84
|
-
await expect(handleToolCall('manage_email', { operation: 'triage', email: 'u@t.com' })).rejects.toThrow('API failure');
|
|
85
|
-
});
|
|
86
|
-
it('returns HandlerResponse with text and refs from factory handler', async () => {
|
|
87
|
-
mockExecute.mockResolvedValue({
|
|
88
|
-
success: true,
|
|
89
|
-
data: { messages: [{ id: 'msg-1', from: 'alice', subject: 'test', date: '2024-01-01' }] },
|
|
90
|
-
stderr: '',
|
|
91
|
-
});
|
|
92
|
-
const result = await handleToolCall('manage_email', { operation: 'triage', email: 'u@t.com' });
|
|
93
|
-
expect(result.text).toContain('msg-1');
|
|
94
|
-
expect(result.refs).toHaveProperty('count', 1);
|
|
95
|
-
});
|
|
96
|
-
});
|
|
97
|
-
//# sourceMappingURL=handler.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"handler.test.js","sourceRoot":"","sources":["../../../src/__tests__/server/handler.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared executor mock for handler tests.
|
|
3
|
-
*
|
|
4
|
-
* Provides typed mock responses matching gws output contracts
|
|
5
|
-
* so handlers can be tested without spawning subprocesses.
|
|
6
|
-
*/
|
|
7
|
-
import type { GwsResult } from '../../../../executor/gws.js';
|
|
8
|
-
import { execute } from '../../../../executor/gws.js';
|
|
9
|
-
export declare const mockExecute: jest.MockedFunction<typeof execute>;
|
|
10
|
-
export declare function mockGwsResponse(data: unknown): GwsResult;
|
|
11
|
-
export declare const gmailTriageResponse: {
|
|
12
|
-
messages: {
|
|
13
|
-
id: string;
|
|
14
|
-
from: string;
|
|
15
|
-
subject: string;
|
|
16
|
-
date: string;
|
|
17
|
-
}[];
|
|
18
|
-
};
|
|
19
|
-
export declare const gmailMessageListResponse: {
|
|
20
|
-
messages: {
|
|
21
|
-
id: string;
|
|
22
|
-
threadId: string;
|
|
23
|
-
}[];
|
|
24
|
-
};
|
|
25
|
-
export declare function gmailMetadataResponse(id: string, from: string, subject: string, date: string): {
|
|
26
|
-
id: string;
|
|
27
|
-
threadId: string;
|
|
28
|
-
snippet: string;
|
|
29
|
-
payload: {
|
|
30
|
-
headers: {
|
|
31
|
-
name: string;
|
|
32
|
-
value: string;
|
|
33
|
-
}[];
|
|
34
|
-
};
|
|
35
|
-
};
|
|
36
|
-
export declare const gmailMessageDetailResponse: {
|
|
37
|
-
id: string;
|
|
38
|
-
threadId: string;
|
|
39
|
-
snippet: string;
|
|
40
|
-
labelIds: string[];
|
|
41
|
-
payload: {
|
|
42
|
-
headers: {
|
|
43
|
-
name: string;
|
|
44
|
-
value: string;
|
|
45
|
-
}[];
|
|
46
|
-
};
|
|
47
|
-
};
|
|
48
|
-
export declare const gmailSendResponse: {
|
|
49
|
-
id: string;
|
|
50
|
-
threadId: string;
|
|
51
|
-
labelIds: string[];
|
|
52
|
-
};
|
|
53
|
-
export declare const calendarAgendaResponse: {
|
|
54
|
-
events: {
|
|
55
|
-
calendar: string;
|
|
56
|
-
summary: string;
|
|
57
|
-
start: string;
|
|
58
|
-
end: string;
|
|
59
|
-
}[];
|
|
60
|
-
timeMin: string;
|
|
61
|
-
timeMax: string;
|
|
62
|
-
};
|
|
63
|
-
export declare const calendarEventsListResponse: {
|
|
64
|
-
items: ({
|
|
65
|
-
id: string;
|
|
66
|
-
summary: string;
|
|
67
|
-
start: {
|
|
68
|
-
dateTime: string;
|
|
69
|
-
};
|
|
70
|
-
end: {
|
|
71
|
-
dateTime: string;
|
|
72
|
-
};
|
|
73
|
-
status: string;
|
|
74
|
-
attendees: never[];
|
|
75
|
-
} | {
|
|
76
|
-
id: string;
|
|
77
|
-
summary: string;
|
|
78
|
-
start: {
|
|
79
|
-
dateTime: string;
|
|
80
|
-
};
|
|
81
|
-
end: {
|
|
82
|
-
dateTime: string;
|
|
83
|
-
};
|
|
84
|
-
status: string;
|
|
85
|
-
attendees?: undefined;
|
|
86
|
-
})[];
|
|
87
|
-
};
|
|
88
|
-
export declare const calendarEventDetailResponse: {
|
|
89
|
-
id: string;
|
|
90
|
-
summary: string;
|
|
91
|
-
start: {
|
|
92
|
-
dateTime: string;
|
|
93
|
-
};
|
|
94
|
-
end: {
|
|
95
|
-
dateTime: string;
|
|
96
|
-
};
|
|
97
|
-
status: string;
|
|
98
|
-
location: string;
|
|
99
|
-
description: string;
|
|
100
|
-
organizer: {
|
|
101
|
-
email: string;
|
|
102
|
-
};
|
|
103
|
-
attendees: {
|
|
104
|
-
email: string;
|
|
105
|
-
responseStatus: string;
|
|
106
|
-
}[];
|
|
107
|
-
};
|
|
108
|
-
export declare const calendarInsertResponse: {
|
|
109
|
-
id: string;
|
|
110
|
-
summary: string;
|
|
111
|
-
status: string;
|
|
112
|
-
htmlLink: string;
|
|
113
|
-
};
|
|
114
|
-
export declare const calendarFreeBusyResponse: {
|
|
115
|
-
calendars: {
|
|
116
|
-
'user@test.com': {
|
|
117
|
-
busy: {
|
|
118
|
-
start: string;
|
|
119
|
-
end: string;
|
|
120
|
-
}[];
|
|
121
|
-
};
|
|
122
|
-
'colleague@test.com': {
|
|
123
|
-
busy: never[];
|
|
124
|
-
};
|
|
125
|
-
};
|
|
126
|
-
};
|
|
127
|
-
export declare const calendarFreeBusyErrorResponse: {
|
|
128
|
-
calendars: {
|
|
129
|
-
'user@test.com': {
|
|
130
|
-
busy: never[];
|
|
131
|
-
};
|
|
132
|
-
'private@test.com': {
|
|
133
|
-
errors: {
|
|
134
|
-
domain: string;
|
|
135
|
-
reason: string;
|
|
136
|
-
}[];
|
|
137
|
-
};
|
|
138
|
-
};
|
|
139
|
-
};
|
|
140
|
-
export declare const driveFileListResponse: {
|
|
141
|
-
files: ({
|
|
142
|
-
id: string;
|
|
143
|
-
name: string;
|
|
144
|
-
mimeType: string;
|
|
145
|
-
modifiedTime: string;
|
|
146
|
-
size: string;
|
|
147
|
-
webViewLink: string;
|
|
148
|
-
} | {
|
|
149
|
-
id: string;
|
|
150
|
-
name: string;
|
|
151
|
-
mimeType: string;
|
|
152
|
-
modifiedTime: string;
|
|
153
|
-
size?: undefined;
|
|
154
|
-
webViewLink?: undefined;
|
|
155
|
-
})[];
|
|
156
|
-
};
|
|
157
|
-
export declare const driveFileDetailResponse: {
|
|
158
|
-
id: string;
|
|
159
|
-
name: string;
|
|
160
|
-
mimeType: string;
|
|
161
|
-
modifiedTime: string;
|
|
162
|
-
size: string;
|
|
163
|
-
webViewLink: string;
|
|
164
|
-
owners: {
|
|
165
|
-
emailAddress: string;
|
|
166
|
-
}[];
|
|
167
|
-
shared: boolean;
|
|
168
|
-
};
|
|
169
|
-
export declare const driveUploadResponse: {
|
|
170
|
-
id: string;
|
|
171
|
-
name: string;
|
|
172
|
-
mimeType: string;
|
|
173
|
-
};
|