gogcli-mcp-contacts 2.2.0 → 2.3.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/index.js +124 -1
- package/manifest.json +29 -1
- package/package.json +1 -1
- package/src/tools/contacts-extra.ts +130 -0
- package/tests/tools/contacts-extra.test.ts +142 -0
package/dist/index.js
CHANGED
|
@@ -31298,7 +31298,7 @@ var failIfNotEmptyParam = external_exports.boolean().optional().describe(
|
|
|
31298
31298
|
);
|
|
31299
31299
|
|
|
31300
31300
|
// ../gogcli-mcp/src/server.ts
|
|
31301
|
-
var VERSION = true ? "2.
|
|
31301
|
+
var VERSION = true ? "2.3.0" : "0.0.0";
|
|
31302
31302
|
function createServer(options) {
|
|
31303
31303
|
return new McpServer({
|
|
31304
31304
|
name: options?.name ?? "gogcli",
|
|
@@ -31358,6 +31358,129 @@ function registerExtraContactsTools(server2) {
|
|
|
31358
31358
|
if (type) args.push(`--type=${type}`);
|
|
31359
31359
|
return runOrDiagnose(args, { account });
|
|
31360
31360
|
});
|
|
31361
|
+
server2.registerTool("gog_contacts_update", {
|
|
31362
|
+
description: "Update an existing Google Contact. Empty string clears a field; repeatable fields (url/address/custom/relation) take comma/semicolon-separated lists.",
|
|
31363
|
+
inputSchema: {
|
|
31364
|
+
resourceName: external_exports.string().describe("Contact resource name (people/...)"),
|
|
31365
|
+
given: external_exports.string().optional().describe("Given (first) name"),
|
|
31366
|
+
family: external_exports.string().optional().describe("Family (last) name"),
|
|
31367
|
+
email: external_exports.string().optional().describe("Email address (empty string clears)"),
|
|
31368
|
+
phone: external_exports.string().optional().describe("Phone number (empty string clears)"),
|
|
31369
|
+
org: external_exports.string().optional().describe("Organization/company name (empty string clears)"),
|
|
31370
|
+
title: external_exports.string().optional().describe("Job title (empty string clears)"),
|
|
31371
|
+
url: external_exports.string().optional().describe("URL(s), comma-separated (empty string clears all)"),
|
|
31372
|
+
note: external_exports.string().optional().describe("Note/biography (empty string clears)"),
|
|
31373
|
+
address: external_exports.string().optional().describe("Postal address(es), semicolon-separated (empty string clears all)"),
|
|
31374
|
+
birthday: external_exports.string().optional().describe("Birthday in YYYY-MM-DD (empty string clears)"),
|
|
31375
|
+
ignoreEtag: external_exports.boolean().optional().describe("Allow update even if a supplied etag is stale (may overwrite concurrent changes)"),
|
|
31376
|
+
account: accountParam
|
|
31377
|
+
}
|
|
31378
|
+
}, async ({ resourceName, given, family, email: email3, phone, org, title, url: url2, note, address, birthday, ignoreEtag, account }) => {
|
|
31379
|
+
const args = ["contacts", "update", resourceName];
|
|
31380
|
+
if (given !== void 0) args.push(`--given=${given}`);
|
|
31381
|
+
if (family !== void 0) args.push(`--family=${family}`);
|
|
31382
|
+
if (email3 !== void 0) args.push(`--email=${email3}`);
|
|
31383
|
+
if (phone !== void 0) args.push(`--phone=${phone}`);
|
|
31384
|
+
if (org !== void 0) args.push(`--org=${org}`);
|
|
31385
|
+
if (title !== void 0) args.push(`--title=${title}`);
|
|
31386
|
+
if (url2 !== void 0) args.push(`--url=${url2}`);
|
|
31387
|
+
if (note !== void 0) args.push(`--note=${note}`);
|
|
31388
|
+
if (address !== void 0) args.push(`--address=${address}`);
|
|
31389
|
+
if (birthday !== void 0) args.push(`--birthday=${birthday}`);
|
|
31390
|
+
if (ignoreEtag) args.push("--ignore-etag");
|
|
31391
|
+
return runOrDiagnose(args, { account });
|
|
31392
|
+
});
|
|
31393
|
+
server2.registerTool("gog_contacts_delete", {
|
|
31394
|
+
description: "Delete a Google Contact by resource name.",
|
|
31395
|
+
annotations: { destructiveHint: true },
|
|
31396
|
+
inputSchema: {
|
|
31397
|
+
resourceName: external_exports.string().describe("Contact resource name (people/...)"),
|
|
31398
|
+
account: accountParam
|
|
31399
|
+
}
|
|
31400
|
+
}, async ({ resourceName, account }) => {
|
|
31401
|
+
return runOrDiagnose(["contacts", "delete", resourceName], { account });
|
|
31402
|
+
});
|
|
31403
|
+
server2.registerTool("gog_contacts_export", {
|
|
31404
|
+
description: "Export contacts as vCard (.vcf). Provide a selector (resource name, email, or name), or use query / all to export multiple.",
|
|
31405
|
+
annotations: { readOnlyHint: true },
|
|
31406
|
+
inputSchema: {
|
|
31407
|
+
selector: external_exports.string().optional().describe("Contact resource name (people/...), email, or name"),
|
|
31408
|
+
query: external_exports.string().optional().describe("Search query to export (max 30 results)"),
|
|
31409
|
+
all: external_exports.boolean().optional().describe("Export all personal contacts"),
|
|
31410
|
+
out: external_exports.string().optional().describe("Output path (.vcf), or - for stdout (default: stdout)"),
|
|
31411
|
+
max: external_exports.number().optional().describe("Max results for query (1-30)"),
|
|
31412
|
+
page: external_exports.string().optional().describe("Start page token for all"),
|
|
31413
|
+
account: accountParam
|
|
31414
|
+
}
|
|
31415
|
+
}, async ({ selector, query, all, out, max, page, account }) => {
|
|
31416
|
+
const args = ["contacts", "export"];
|
|
31417
|
+
if (selector) args.push(selector);
|
|
31418
|
+
if (query) args.push(`--query=${query}`);
|
|
31419
|
+
if (all) args.push("--all");
|
|
31420
|
+
if (out) args.push(`--out=${out}`);
|
|
31421
|
+
if (max !== void 0) args.push(`--max=${max}`);
|
|
31422
|
+
if (page) args.push(`--page=${page}`);
|
|
31423
|
+
return runOrDiagnose(args, { account });
|
|
31424
|
+
});
|
|
31425
|
+
server2.registerTool("gog_contacts_dedupe", {
|
|
31426
|
+
description: "Find likely duplicate personal contacts (preview only \u2014 does not modify anything).",
|
|
31427
|
+
annotations: { readOnlyHint: true },
|
|
31428
|
+
inputSchema: {
|
|
31429
|
+
match: external_exports.string().optional().describe("Match fields, comma-separated from email,phone,name (default: email,phone)"),
|
|
31430
|
+
max: external_exports.number().optional().describe("Max contacts to scan (0 = all)"),
|
|
31431
|
+
account: accountParam
|
|
31432
|
+
}
|
|
31433
|
+
}, async ({ match, max, account }) => {
|
|
31434
|
+
const args = ["contacts", "dedupe"];
|
|
31435
|
+
if (match) args.push(`--match=${match}`);
|
|
31436
|
+
if (max !== void 0) args.push(`--max=${max}`);
|
|
31437
|
+
return runOrDiagnose(args, { account });
|
|
31438
|
+
});
|
|
31439
|
+
server2.registerTool("gog_contacts_directory_list", {
|
|
31440
|
+
description: "List people from the Google Workspace directory (domain shared contacts).",
|
|
31441
|
+
annotations: { readOnlyHint: true },
|
|
31442
|
+
inputSchema: {
|
|
31443
|
+
max: external_exports.number().optional().describe("Max results (default: 50)"),
|
|
31444
|
+
page: external_exports.string().optional().describe("Page token"),
|
|
31445
|
+
all: external_exports.boolean().optional().describe("Fetch all pages"),
|
|
31446
|
+
account: accountParam
|
|
31447
|
+
}
|
|
31448
|
+
}, async ({ max, page, all, account }) => {
|
|
31449
|
+
const args = ["contacts", "directory", "list"];
|
|
31450
|
+
if (max !== void 0) args.push(`--max=${max}`);
|
|
31451
|
+
if (page) args.push(`--page=${page}`);
|
|
31452
|
+
if (all) args.push("--all");
|
|
31453
|
+
return runOrDiagnose(args, { account });
|
|
31454
|
+
});
|
|
31455
|
+
server2.registerTool("gog_contacts_other_list", {
|
|
31456
|
+
description: 'List "other contacts" \u2014 auto-collected addresses (e.g. people you have emailed) that are not in your saved contacts.',
|
|
31457
|
+
annotations: { readOnlyHint: true },
|
|
31458
|
+
inputSchema: {
|
|
31459
|
+
max: external_exports.number().optional().describe("Max results (default: 100)"),
|
|
31460
|
+
page: external_exports.string().optional().describe("Page token"),
|
|
31461
|
+
all: external_exports.boolean().optional().describe("Fetch all pages"),
|
|
31462
|
+
account: accountParam
|
|
31463
|
+
}
|
|
31464
|
+
}, async ({ max, page, all, account }) => {
|
|
31465
|
+
const args = ["contacts", "other", "list"];
|
|
31466
|
+
if (max !== void 0) args.push(`--max=${max}`);
|
|
31467
|
+
if (page) args.push(`--page=${page}`);
|
|
31468
|
+
if (all) args.push("--all");
|
|
31469
|
+
return runOrDiagnose(args, { account });
|
|
31470
|
+
});
|
|
31471
|
+
server2.registerTool("gog_contacts_other_search", {
|
|
31472
|
+
description: 'Search "other contacts" \u2014 auto-collected addresses not in your saved contacts.',
|
|
31473
|
+
annotations: { readOnlyHint: true },
|
|
31474
|
+
inputSchema: {
|
|
31475
|
+
query: external_exports.string().describe("Search query"),
|
|
31476
|
+
max: external_exports.number().optional().describe("Max results (default: 50)"),
|
|
31477
|
+
account: accountParam
|
|
31478
|
+
}
|
|
31479
|
+
}, async ({ query, max, account }) => {
|
|
31480
|
+
const args = ["contacts", "other", "search", query];
|
|
31481
|
+
if (max !== void 0) args.push(`--max=${max}`);
|
|
31482
|
+
return runOrDiagnose(args, { account });
|
|
31483
|
+
});
|
|
31361
31484
|
server2.registerTool("gog_people_raw", {
|
|
31362
31485
|
description: "Dump the raw People API response as JSON (lossless; for scripting and LLM consumption).",
|
|
31363
31486
|
annotations: { readOnlyHint: true },
|
package/manifest.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"manifest_version": "0.3",
|
|
4
4
|
"name": "gogcli-mcp-contacts",
|
|
5
5
|
"display_name": "gogcli (Contacts)",
|
|
6
|
-
"version": "2.
|
|
6
|
+
"version": "2.3.0",
|
|
7
7
|
"description": "Extended Google Contacts for Claude via gogcli — auth + Contacts + Workspace directory (People API)",
|
|
8
8
|
"author": {
|
|
9
9
|
"name": "Chris Hall",
|
|
@@ -113,6 +113,34 @@
|
|
|
113
113
|
{
|
|
114
114
|
"name": "gog_people_raw",
|
|
115
115
|
"description": "Dump raw People API JSON for a person"
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"name": "gog_contacts_update",
|
|
119
|
+
"description": "Update an existing contact (empty string clears a field)"
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"name": "gog_contacts_delete",
|
|
123
|
+
"description": "Delete a contact by resource name"
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
"name": "gog_contacts_export",
|
|
127
|
+
"description": "Export contacts as vCard (.vcf)"
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"name": "gog_contacts_dedupe",
|
|
131
|
+
"description": "Find likely duplicate contacts (preview only)"
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
"name": "gog_contacts_directory_list",
|
|
135
|
+
"description": "List people from the Workspace directory"
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"name": "gog_contacts_other_list",
|
|
139
|
+
"description": "List auto-collected other contacts"
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
"name": "gog_contacts_other_search",
|
|
143
|
+
"description": "Search auto-collected other contacts"
|
|
116
144
|
}
|
|
117
145
|
],
|
|
118
146
|
"compatibility": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gogcli-mcp-contacts",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"mcpName": "io.github.chrischall/gogcli-mcp-contacts",
|
|
5
5
|
"description": "Extended Google Contacts + People MCP server via gogcli — auth + Contacts + Workspace directory (People API)",
|
|
6
6
|
"author": "Claude Code (AI) <https://www.anthropic.com/claude>",
|
|
@@ -59,6 +59,136 @@ export function registerExtraContactsTools(server: McpServer): void {
|
|
|
59
59
|
return runOrDiagnose(args, { account });
|
|
60
60
|
});
|
|
61
61
|
|
|
62
|
+
server.registerTool('gog_contacts_update', {
|
|
63
|
+
description: 'Update an existing Google Contact. Empty string clears a field; repeatable fields (url/address/custom/relation) take comma/semicolon-separated lists.',
|
|
64
|
+
inputSchema: {
|
|
65
|
+
resourceName: z.string().describe('Contact resource name (people/...)'),
|
|
66
|
+
given: z.string().optional().describe('Given (first) name'),
|
|
67
|
+
family: z.string().optional().describe('Family (last) name'),
|
|
68
|
+
email: z.string().optional().describe('Email address (empty string clears)'),
|
|
69
|
+
phone: z.string().optional().describe('Phone number (empty string clears)'),
|
|
70
|
+
org: z.string().optional().describe('Organization/company name (empty string clears)'),
|
|
71
|
+
title: z.string().optional().describe('Job title (empty string clears)'),
|
|
72
|
+
url: z.string().optional().describe('URL(s), comma-separated (empty string clears all)'),
|
|
73
|
+
note: z.string().optional().describe('Note/biography (empty string clears)'),
|
|
74
|
+
address: z.string().optional().describe('Postal address(es), semicolon-separated (empty string clears all)'),
|
|
75
|
+
birthday: z.string().optional().describe('Birthday in YYYY-MM-DD (empty string clears)'),
|
|
76
|
+
ignoreEtag: z.boolean().optional().describe('Allow update even if a supplied etag is stale (may overwrite concurrent changes)'),
|
|
77
|
+
account: accountParam,
|
|
78
|
+
},
|
|
79
|
+
}, async ({ resourceName, given, family, email, phone, org, title, url, note, address, birthday, ignoreEtag, account }) => {
|
|
80
|
+
const args = ['contacts', 'update', resourceName];
|
|
81
|
+
if (given !== undefined) args.push(`--given=${given}`);
|
|
82
|
+
if (family !== undefined) args.push(`--family=${family}`);
|
|
83
|
+
if (email !== undefined) args.push(`--email=${email}`);
|
|
84
|
+
if (phone !== undefined) args.push(`--phone=${phone}`);
|
|
85
|
+
if (org !== undefined) args.push(`--org=${org}`);
|
|
86
|
+
if (title !== undefined) args.push(`--title=${title}`);
|
|
87
|
+
if (url !== undefined) args.push(`--url=${url}`);
|
|
88
|
+
if (note !== undefined) args.push(`--note=${note}`);
|
|
89
|
+
if (address !== undefined) args.push(`--address=${address}`);
|
|
90
|
+
if (birthday !== undefined) args.push(`--birthday=${birthday}`);
|
|
91
|
+
if (ignoreEtag) args.push('--ignore-etag');
|
|
92
|
+
return runOrDiagnose(args, { account });
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
server.registerTool('gog_contacts_delete', {
|
|
96
|
+
description: 'Delete a Google Contact by resource name.',
|
|
97
|
+
annotations: { destructiveHint: true },
|
|
98
|
+
inputSchema: {
|
|
99
|
+
resourceName: z.string().describe('Contact resource name (people/...)'),
|
|
100
|
+
account: accountParam,
|
|
101
|
+
},
|
|
102
|
+
}, async ({ resourceName, account }) => {
|
|
103
|
+
return runOrDiagnose(['contacts', 'delete', resourceName], { account });
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
server.registerTool('gog_contacts_export', {
|
|
107
|
+
description: 'Export contacts as vCard (.vcf). Provide a selector (resource name, email, or name), or use query / all to export multiple.',
|
|
108
|
+
annotations: { readOnlyHint: true },
|
|
109
|
+
inputSchema: {
|
|
110
|
+
selector: z.string().optional().describe('Contact resource name (people/...), email, or name'),
|
|
111
|
+
query: z.string().optional().describe('Search query to export (max 30 results)'),
|
|
112
|
+
all: z.boolean().optional().describe('Export all personal contacts'),
|
|
113
|
+
out: z.string().optional().describe('Output path (.vcf), or - for stdout (default: stdout)'),
|
|
114
|
+
max: z.number().optional().describe('Max results for query (1-30)'),
|
|
115
|
+
page: z.string().optional().describe('Start page token for all'),
|
|
116
|
+
account: accountParam,
|
|
117
|
+
},
|
|
118
|
+
}, async ({ selector, query, all, out, max, page, account }) => {
|
|
119
|
+
const args = ['contacts', 'export'];
|
|
120
|
+
if (selector) args.push(selector);
|
|
121
|
+
if (query) args.push(`--query=${query}`);
|
|
122
|
+
if (all) args.push('--all');
|
|
123
|
+
if (out) args.push(`--out=${out}`);
|
|
124
|
+
if (max !== undefined) args.push(`--max=${max}`);
|
|
125
|
+
if (page) args.push(`--page=${page}`);
|
|
126
|
+
return runOrDiagnose(args, { account });
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
server.registerTool('gog_contacts_dedupe', {
|
|
130
|
+
description: 'Find likely duplicate personal contacts (preview only — does not modify anything).',
|
|
131
|
+
annotations: { readOnlyHint: true },
|
|
132
|
+
inputSchema: {
|
|
133
|
+
match: z.string().optional().describe('Match fields, comma-separated from email,phone,name (default: email,phone)'),
|
|
134
|
+
max: z.number().optional().describe('Max contacts to scan (0 = all)'),
|
|
135
|
+
account: accountParam,
|
|
136
|
+
},
|
|
137
|
+
}, async ({ match, max, account }) => {
|
|
138
|
+
const args = ['contacts', 'dedupe'];
|
|
139
|
+
if (match) args.push(`--match=${match}`);
|
|
140
|
+
if (max !== undefined) args.push(`--max=${max}`);
|
|
141
|
+
return runOrDiagnose(args, { account });
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
server.registerTool('gog_contacts_directory_list', {
|
|
145
|
+
description: 'List people from the Google Workspace directory (domain shared contacts).',
|
|
146
|
+
annotations: { readOnlyHint: true },
|
|
147
|
+
inputSchema: {
|
|
148
|
+
max: z.number().optional().describe('Max results (default: 50)'),
|
|
149
|
+
page: z.string().optional().describe('Page token'),
|
|
150
|
+
all: z.boolean().optional().describe('Fetch all pages'),
|
|
151
|
+
account: accountParam,
|
|
152
|
+
},
|
|
153
|
+
}, async ({ max, page, all, account }) => {
|
|
154
|
+
const args = ['contacts', 'directory', 'list'];
|
|
155
|
+
if (max !== undefined) args.push(`--max=${max}`);
|
|
156
|
+
if (page) args.push(`--page=${page}`);
|
|
157
|
+
if (all) args.push('--all');
|
|
158
|
+
return runOrDiagnose(args, { account });
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
server.registerTool('gog_contacts_other_list', {
|
|
162
|
+
description: 'List "other contacts" — auto-collected addresses (e.g. people you have emailed) that are not in your saved contacts.',
|
|
163
|
+
annotations: { readOnlyHint: true },
|
|
164
|
+
inputSchema: {
|
|
165
|
+
max: z.number().optional().describe('Max results (default: 100)'),
|
|
166
|
+
page: z.string().optional().describe('Page token'),
|
|
167
|
+
all: z.boolean().optional().describe('Fetch all pages'),
|
|
168
|
+
account: accountParam,
|
|
169
|
+
},
|
|
170
|
+
}, async ({ max, page, all, account }) => {
|
|
171
|
+
const args = ['contacts', 'other', 'list'];
|
|
172
|
+
if (max !== undefined) args.push(`--max=${max}`);
|
|
173
|
+
if (page) args.push(`--page=${page}`);
|
|
174
|
+
if (all) args.push('--all');
|
|
175
|
+
return runOrDiagnose(args, { account });
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
server.registerTool('gog_contacts_other_search', {
|
|
179
|
+
description: 'Search "other contacts" — auto-collected addresses not in your saved contacts.',
|
|
180
|
+
annotations: { readOnlyHint: true },
|
|
181
|
+
inputSchema: {
|
|
182
|
+
query: z.string().describe('Search query'),
|
|
183
|
+
max: z.number().optional().describe('Max results (default: 50)'),
|
|
184
|
+
account: accountParam,
|
|
185
|
+
},
|
|
186
|
+
}, async ({ query, max, account }) => {
|
|
187
|
+
const args = ['contacts', 'other', 'search', query];
|
|
188
|
+
if (max !== undefined) args.push(`--max=${max}`);
|
|
189
|
+
return runOrDiagnose(args, { account });
|
|
190
|
+
});
|
|
191
|
+
|
|
62
192
|
server.registerTool('gog_people_raw', {
|
|
63
193
|
description: 'Dump the raw People API response as JSON (lossless; for scripting and LLM consumption).',
|
|
64
194
|
annotations: { readOnlyHint: true },
|
|
@@ -73,6 +73,148 @@ describe('gog_people_relations', () => {
|
|
|
73
73
|
});
|
|
74
74
|
});
|
|
75
75
|
|
|
76
|
+
describe('gog_contacts_update', () => {
|
|
77
|
+
it('calls runOrDiagnose with just resourceName', async () => {
|
|
78
|
+
await handlers.get('gog_contacts_update')!({ resourceName: 'people/c1' });
|
|
79
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['contacts', 'update', 'people/c1'], { account: undefined });
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('passes all fields including empty-string clears', async () => {
|
|
83
|
+
await handlers.get('gog_contacts_update')!({
|
|
84
|
+
resourceName: 'people/c1',
|
|
85
|
+
given: 'Ada',
|
|
86
|
+
family: 'Lovelace',
|
|
87
|
+
email: '',
|
|
88
|
+
phone: '+1',
|
|
89
|
+
org: 'Analytical',
|
|
90
|
+
title: 'Engineer',
|
|
91
|
+
url: 'https://a.com',
|
|
92
|
+
note: 'hi',
|
|
93
|
+
address: '1 St;City',
|
|
94
|
+
birthday: '1815-12-10',
|
|
95
|
+
ignoreEtag: true,
|
|
96
|
+
});
|
|
97
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
98
|
+
[
|
|
99
|
+
'contacts', 'update', 'people/c1',
|
|
100
|
+
'--given=Ada', '--family=Lovelace', '--email=', '--phone=+1',
|
|
101
|
+
'--org=Analytical', '--title=Engineer', '--url=https://a.com',
|
|
102
|
+
'--note=hi', '--address=1 St;City', '--birthday=1815-12-10', '--ignore-etag',
|
|
103
|
+
],
|
|
104
|
+
{ account: undefined },
|
|
105
|
+
);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('omits --ignore-etag when false', async () => {
|
|
109
|
+
await handlers.get('gog_contacts_update')!({ resourceName: 'people/c1', ignoreEtag: false });
|
|
110
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['contacts', 'update', 'people/c1'], { account: undefined });
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
describe('gog_contacts_delete', () => {
|
|
115
|
+
it('calls runOrDiagnose with resourceName', async () => {
|
|
116
|
+
await handlers.get('gog_contacts_delete')!({ resourceName: 'people/c1' });
|
|
117
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['contacts', 'delete', 'people/c1'], { account: undefined });
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
describe('gog_contacts_export', () => {
|
|
122
|
+
it('calls runOrDiagnose with no options', async () => {
|
|
123
|
+
await handlers.get('gog_contacts_export')!({});
|
|
124
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['contacts', 'export'], { account: undefined });
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it('passes selector and all flags', async () => {
|
|
128
|
+
await handlers.get('gog_contacts_export')!({
|
|
129
|
+
selector: 'people/c1',
|
|
130
|
+
query: 'ada',
|
|
131
|
+
all: true,
|
|
132
|
+
out: 'out.vcf',
|
|
133
|
+
max: 10,
|
|
134
|
+
page: 'tok',
|
|
135
|
+
});
|
|
136
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
137
|
+
['contacts', 'export', 'people/c1', '--query=ada', '--all', '--out=out.vcf', '--max=10', '--page=tok'],
|
|
138
|
+
{ account: undefined },
|
|
139
|
+
);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it('omits --all when false', async () => {
|
|
143
|
+
await handlers.get('gog_contacts_export')!({ all: false });
|
|
144
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['contacts', 'export'], { account: undefined });
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
describe('gog_contacts_dedupe', () => {
|
|
149
|
+
it('calls runOrDiagnose with no options', async () => {
|
|
150
|
+
await handlers.get('gog_contacts_dedupe')!({});
|
|
151
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['contacts', 'dedupe'], { account: undefined });
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it('passes --match and --max', async () => {
|
|
155
|
+
await handlers.get('gog_contacts_dedupe')!({ match: 'name', max: 100 });
|
|
156
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
157
|
+
['contacts', 'dedupe', '--match=name', '--max=100'],
|
|
158
|
+
{ account: undefined },
|
|
159
|
+
);
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
describe('gog_contacts_directory_list', () => {
|
|
164
|
+
it('calls runOrDiagnose with no options', async () => {
|
|
165
|
+
await handlers.get('gog_contacts_directory_list')!({});
|
|
166
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['contacts', 'directory', 'list'], { account: undefined });
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
it('passes pagination flags', async () => {
|
|
170
|
+
await handlers.get('gog_contacts_directory_list')!({ max: 50, page: 'tok', all: true });
|
|
171
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
172
|
+
['contacts', 'directory', 'list', '--max=50', '--page=tok', '--all'],
|
|
173
|
+
{ account: undefined },
|
|
174
|
+
);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
it('omits --all when false', async () => {
|
|
178
|
+
await handlers.get('gog_contacts_directory_list')!({ all: false });
|
|
179
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['contacts', 'directory', 'list'], { account: undefined });
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
describe('gog_contacts_other_list', () => {
|
|
184
|
+
it('calls runOrDiagnose with no options', async () => {
|
|
185
|
+
await handlers.get('gog_contacts_other_list')!({});
|
|
186
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['contacts', 'other', 'list'], { account: undefined });
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it('passes pagination flags', async () => {
|
|
190
|
+
await handlers.get('gog_contacts_other_list')!({ max: 100, page: 'tok', all: true });
|
|
191
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
192
|
+
['contacts', 'other', 'list', '--max=100', '--page=tok', '--all'],
|
|
193
|
+
{ account: undefined },
|
|
194
|
+
);
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it('omits --all when false', async () => {
|
|
198
|
+
await handlers.get('gog_contacts_other_list')!({ all: false });
|
|
199
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['contacts', 'other', 'list'], { account: undefined });
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
describe('gog_contacts_other_search', () => {
|
|
204
|
+
it('calls runOrDiagnose with query', async () => {
|
|
205
|
+
await handlers.get('gog_contacts_other_search')!({ query: 'ada' });
|
|
206
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['contacts', 'other', 'search', 'ada'], { account: undefined });
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
it('passes --max when provided', async () => {
|
|
210
|
+
await handlers.get('gog_contacts_other_search')!({ query: 'ada', max: 25 });
|
|
211
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
212
|
+
['contacts', 'other', 'search', 'ada', '--max=25'],
|
|
213
|
+
{ account: undefined },
|
|
214
|
+
);
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
|
|
76
218
|
describe('gog_people_raw', () => {
|
|
77
219
|
it('calls runOrDiagnose with userId', async () => {
|
|
78
220
|
await handlers.get('gog_people_raw')!({ userId: 'people/c123' });
|