@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.
Files changed (273) hide show
  1. package/LICENSE +201 -21
  2. package/LICENSE-MIT +21 -0
  3. package/NOTICE +24 -0
  4. package/README.md +87 -57
  5. package/build/accounts/auth.d.ts +1 -1
  6. package/build/accounts/auth.js +1 -1
  7. package/build/accounts/oauth.js +3 -3
  8. package/build/accounts/oauth.js.map +1 -1
  9. package/build/accounts/token-service.js +1 -1
  10. package/build/accounts/token-service.js.map +1 -1
  11. package/build/coverage/analyze.d.ts +1 -1
  12. package/build/coverage/analyze.js +6 -4
  13. package/build/coverage/analyze.js.map +1 -1
  14. package/build/coverage/baseline.js +37 -20
  15. package/build/coverage/baseline.js.map +1 -1
  16. package/build/coverage/compare.d.ts +1 -1
  17. package/build/coverage/compare.js +19 -10
  18. package/build/coverage/compare.js.map +1 -1
  19. package/build/coverage/discover.d.ts +5 -5
  20. package/build/coverage/discover.js +71 -155
  21. package/build/coverage/discover.js.map +1 -1
  22. package/build/coverage/report.js +3 -3
  23. package/build/coverage/report.js.map +1 -1
  24. package/build/coverage/types.d.ts +19 -4
  25. package/build/executor/index.d.ts +0 -3
  26. package/build/executor/index.js +1 -2
  27. package/build/executor/index.js.map +1 -1
  28. package/build/factory/defaults.js +30 -4
  29. package/build/factory/defaults.js.map +1 -1
  30. package/build/factory/generator.d.ts +10 -4
  31. package/build/factory/generator.js +86 -96
  32. package/build/factory/generator.js.map +1 -1
  33. package/build/factory/manifest/README.md +4 -3
  34. package/build/factory/manifest/calendar.yaml +1 -11
  35. package/build/factory/manifest/docs.yaml +15 -6
  36. package/build/factory/manifest/drive.yaml +1 -5
  37. package/build/factory/manifest/gmail.yaml +32 -25
  38. package/build/factory/manifest/meet.yaml +1 -1
  39. package/build/factory/manifest/sheets.yaml +2 -5
  40. package/build/factory/manifest/tasks.yaml +40 -2
  41. package/build/factory/patches.js +2 -0
  42. package/build/factory/patches.js.map +1 -1
  43. package/build/factory/registry.d.ts +2 -3
  44. package/build/factory/registry.js +3 -9
  45. package/build/factory/registry.js.map +1 -1
  46. package/build/factory/safety.js +4 -4
  47. package/build/factory/safety.js.map +1 -1
  48. package/build/factory/types.d.ts +16 -15
  49. package/build/google/client.d.ts +45 -0
  50. package/build/google/client.js +232 -0
  51. package/build/google/client.js.map +1 -0
  52. package/build/google/descriptor.d.ts +40 -0
  53. package/build/google/descriptor.js +37 -0
  54. package/build/google/descriptor.js.map +1 -0
  55. package/build/google/descriptor.json +5271 -0
  56. package/build/google/errors.d.ts +45 -0
  57. package/build/google/errors.js +44 -0
  58. package/build/google/errors.js.map +1 -0
  59. package/build/google/methods.d.ts +37 -0
  60. package/build/google/methods.js +13 -0
  61. package/build/google/methods.js.map +1 -0
  62. package/build/index.js +30 -4
  63. package/build/index.js.map +1 -1
  64. package/build/node-floor.d.ts +16 -0
  65. package/build/node-floor.js +73 -0
  66. package/build/node-floor.js.map +1 -0
  67. package/build/server/formatting/markdown.d.ts +1 -1
  68. package/build/server/formatting/markdown.js +1 -1
  69. package/build/server/formatting/next-steps.js +1 -1
  70. package/build/server/formatting/next-steps.js.map +1 -1
  71. package/build/server/handlers/accounts.js +2 -2
  72. package/build/server/handlers/accounts.js.map +1 -1
  73. package/build/server/scratchpad/adapters/import-doc.js +15 -13
  74. package/build/server/scratchpad/adapters/import-doc.js.map +1 -1
  75. package/build/server/scratchpad/adapters/import-drive.js +16 -11
  76. package/build/server/scratchpad/adapters/import-drive.js.map +1 -1
  77. package/build/server/scratchpad/adapters/import-email.js +3 -15
  78. package/build/server/scratchpad/adapters/import-email.js.map +1 -1
  79. package/build/server/scratchpad/adapters/import-meet.js +5 -17
  80. package/build/server/scratchpad/adapters/import-meet.js.map +1 -1
  81. package/build/server/scratchpad/adapters/import-sheet.js +5 -6
  82. package/build/server/scratchpad/adapters/import-sheet.js.map +1 -1
  83. package/build/server/scratchpad/adapters/send-calendar.js +18 -13
  84. package/build/server/scratchpad/adapters/send-calendar.js.map +1 -1
  85. package/build/server/scratchpad/adapters/send-doc.js +22 -17
  86. package/build/server/scratchpad/adapters/send-doc.js.map +1 -1
  87. package/build/server/scratchpad/adapters/send-email-draft.d.ts +1 -1
  88. package/build/server/scratchpad/adapters/send-email-draft.js +17 -25
  89. package/build/server/scratchpad/adapters/send-email-draft.js.map +1 -1
  90. package/build/server/scratchpad/adapters/send-email.d.ts +2 -2
  91. package/build/server/scratchpad/adapters/send-email.js +21 -25
  92. package/build/server/scratchpad/adapters/send-email.js.map +1 -1
  93. package/build/server/scratchpad/adapters/send-sheet.js +10 -10
  94. package/build/server/scratchpad/adapters/send-sheet.js.map +1 -1
  95. package/build/server/scratchpad/adapters/send-task.js +9 -8
  96. package/build/server/scratchpad/adapters/send-task.js.map +1 -1
  97. package/build/server/scratchpad/handler.js +22 -28
  98. package/build/server/scratchpad/handler.js.map +1 -1
  99. package/build/server/scratchpad/manager.d.ts +1 -1
  100. package/build/server/server.js +13 -10
  101. package/build/server/server.js.map +1 -1
  102. package/build/server/session/tracker.js +21 -25
  103. package/build/server/session/tracker.js.map +1 -1
  104. package/build/server/tools.d.ts +1 -1
  105. package/build/server/tools.js +3 -3
  106. package/build/server/tools.js.map +1 -1
  107. package/build/services/calendar/patch.js +178 -68
  108. package/build/services/calendar/patch.js.map +1 -1
  109. package/build/services/docs/patch.d.ts +5 -3
  110. package/build/services/docs/patch.js +89 -19
  111. package/build/services/docs/patch.js.map +1 -1
  112. package/build/services/drive/patch.d.ts +1 -1
  113. package/build/services/drive/patch.js +115 -143
  114. package/build/services/drive/patch.js.map +1 -1
  115. package/build/services/gmail/attachments.js +10 -15
  116. package/build/services/gmail/attachments.js.map +1 -1
  117. package/build/services/gmail/mail.d.ts +34 -0
  118. package/build/services/gmail/mail.js +245 -0
  119. package/build/services/gmail/mail.js.map +1 -0
  120. package/build/services/gmail/mime.d.ts +45 -4
  121. package/build/services/gmail/mime.js +138 -4
  122. package/build/services/gmail/mime.js.map +1 -1
  123. package/build/services/gmail/patch.js +103 -53
  124. package/build/services/gmail/patch.js.map +1 -1
  125. package/build/services/meet/patch.js +24 -31
  126. package/build/services/meet/patch.js.map +1 -1
  127. package/build/services/sheets/patch.js +30 -35
  128. package/build/services/sheets/patch.js.map +1 -1
  129. package/build/services/tasks/patch.d.ts +18 -0
  130. package/build/services/tasks/patch.js +37 -0
  131. package/build/services/tasks/patch.js.map +1 -0
  132. package/build/version.d.ts +1 -1
  133. package/build/version.js +2 -2
  134. package/build/version.js.map +1 -1
  135. package/package.json +23 -12
  136. package/build/__helpers__/testSetup.d.ts +0 -1
  137. package/build/__helpers__/testSetup.js +0 -6
  138. package/build/__helpers__/testSetup.js.map +0 -1
  139. package/build/__tests__/accounts/credentials.test.d.ts +0 -1
  140. package/build/__tests__/accounts/credentials.test.js +0 -127
  141. package/build/__tests__/accounts/credentials.test.js.map +0 -1
  142. package/build/__tests__/accounts/oauth.test.d.ts +0 -1
  143. package/build/__tests__/accounts/oauth.test.js +0 -71
  144. package/build/__tests__/accounts/oauth.test.js.map +0 -1
  145. package/build/__tests__/accounts/registry.test.d.ts +0 -1
  146. package/build/__tests__/accounts/registry.test.js +0 -74
  147. package/build/__tests__/accounts/registry.test.js.map +0 -1
  148. package/build/__tests__/accounts/token-service.test.d.ts +0 -1
  149. package/build/__tests__/accounts/token-service.test.js +0 -126
  150. package/build/__tests__/accounts/token-service.test.js.map +0 -1
  151. package/build/__tests__/executor/errors.test.d.ts +0 -1
  152. package/build/__tests__/executor/errors.test.js +0 -42
  153. package/build/__tests__/executor/errors.test.js.map +0 -1
  154. package/build/__tests__/executor/gws.test.d.ts +0 -1
  155. package/build/__tests__/executor/gws.test.js +0 -187
  156. package/build/__tests__/executor/gws.test.js.map +0 -1
  157. package/build/__tests__/executor/paths.test.d.ts +0 -1
  158. package/build/__tests__/executor/paths.test.js +0 -60
  159. package/build/__tests__/executor/paths.test.js.map +0 -1
  160. package/build/__tests__/executor/resolve-binary.test.d.ts +0 -1
  161. package/build/__tests__/executor/resolve-binary.test.js +0 -58
  162. package/build/__tests__/executor/resolve-binary.test.js.map +0 -1
  163. package/build/__tests__/executor/workspace.test.d.ts +0 -1
  164. package/build/__tests__/executor/workspace.test.js +0 -143
  165. package/build/__tests__/executor/workspace.test.js.map +0 -1
  166. package/build/__tests__/factory/calendar-patch.test.d.ts +0 -5
  167. package/build/__tests__/factory/calendar-patch.test.js +0 -269
  168. package/build/__tests__/factory/calendar-patch.test.js.map +0 -1
  169. package/build/__tests__/factory/drive-patch.test.d.ts +0 -5
  170. package/build/__tests__/factory/drive-patch.test.js +0 -344
  171. package/build/__tests__/factory/drive-patch.test.js.map +0 -1
  172. package/build/__tests__/factory/generator.test.d.ts +0 -1
  173. package/build/__tests__/factory/generator.test.js +0 -240
  174. package/build/__tests__/factory/generator.test.js.map +0 -1
  175. package/build/__tests__/factory/patch-coverage.test.d.ts +0 -10
  176. package/build/__tests__/factory/patch-coverage.test.js +0 -182
  177. package/build/__tests__/factory/patch-coverage.test.js.map +0 -1
  178. package/build/__tests__/factory/safety.test.d.ts +0 -1
  179. package/build/__tests__/factory/safety.test.js +0 -107
  180. package/build/__tests__/factory/safety.test.js.map +0 -1
  181. package/build/__tests__/factory/sheets-patch.test.d.ts +0 -6
  182. package/build/__tests__/factory/sheets-patch.test.js +0 -498
  183. package/build/__tests__/factory/sheets-patch.test.js.map +0 -1
  184. package/build/__tests__/integration/executor.test.d.ts +0 -5
  185. package/build/__tests__/integration/executor.test.js +0 -38
  186. package/build/__tests__/integration/executor.test.js.map +0 -1
  187. package/build/__tests__/integration/handlers.test.d.ts +0 -6
  188. package/build/__tests__/integration/handlers.test.js +0 -95
  189. package/build/__tests__/integration/handlers.test.js.map +0 -1
  190. package/build/__tests__/integration/setup.d.ts +0 -19
  191. package/build/__tests__/integration/setup.js +0 -61
  192. package/build/__tests__/integration/setup.js.map +0 -1
  193. package/build/__tests__/server/formatting/html-sanitize.test.d.ts +0 -7
  194. package/build/__tests__/server/formatting/html-sanitize.test.js +0 -174
  195. package/build/__tests__/server/formatting/html-sanitize.test.js.map +0 -1
  196. package/build/__tests__/server/formatting/markdown.test.d.ts +0 -1
  197. package/build/__tests__/server/formatting/markdown.test.js +0 -259
  198. package/build/__tests__/server/formatting/markdown.test.js.map +0 -1
  199. package/build/__tests__/server/formatting/next-steps.test.d.ts +0 -1
  200. package/build/__tests__/server/formatting/next-steps.test.js +0 -42
  201. package/build/__tests__/server/formatting/next-steps.test.js.map +0 -1
  202. package/build/__tests__/server/handler.test.d.ts +0 -1
  203. package/build/__tests__/server/handler.test.js +0 -97
  204. package/build/__tests__/server/handler.test.js.map +0 -1
  205. package/build/__tests__/server/handlers/__mocks__/executor.d.ts +0 -173
  206. package/build/__tests__/server/handlers/__mocks__/executor.js +0 -135
  207. package/build/__tests__/server/handlers/__mocks__/executor.js.map +0 -1
  208. package/build/__tests__/server/handlers/accounts.test.d.ts +0 -1
  209. package/build/__tests__/server/handlers/accounts.test.js +0 -129
  210. package/build/__tests__/server/handlers/accounts.test.js.map +0 -1
  211. package/build/__tests__/server/handlers/calendar.test.d.ts +0 -1
  212. package/build/__tests__/server/handlers/calendar.test.js +0 -96
  213. package/build/__tests__/server/handlers/calendar.test.js.map +0 -1
  214. package/build/__tests__/server/handlers/drive.test.d.ts +0 -1
  215. package/build/__tests__/server/handlers/drive.test.js +0 -68
  216. package/build/__tests__/server/handlers/drive.test.js.map +0 -1
  217. package/build/__tests__/server/handlers/email.test.d.ts +0 -1
  218. package/build/__tests__/server/handlers/email.test.js +0 -99
  219. package/build/__tests__/server/handlers/email.test.js.map +0 -1
  220. package/build/__tests__/server/handlers/validate.test.d.ts +0 -1
  221. package/build/__tests__/server/handlers/validate.test.js +0 -88
  222. package/build/__tests__/server/handlers/validate.test.js.map +0 -1
  223. package/build/__tests__/server/queue.test.d.ts +0 -1
  224. package/build/__tests__/server/queue.test.js +0 -199
  225. package/build/__tests__/server/queue.test.js.map +0 -1
  226. package/build/__tests__/server/server.test.d.ts +0 -7
  227. package/build/__tests__/server/server.test.js +0 -135
  228. package/build/__tests__/server/server.test.js.map +0 -1
  229. package/build/__tests__/server/session/context.test.d.ts +0 -1
  230. package/build/__tests__/server/session/context.test.js +0 -101
  231. package/build/__tests__/server/session/context.test.js.map +0 -1
  232. package/build/__tests__/server/session/tracker.test.d.ts +0 -1
  233. package/build/__tests__/server/session/tracker.test.js +0 -146
  234. package/build/__tests__/server/session/tracker.test.js.map +0 -1
  235. package/build/__tests__/server/tools.test.d.ts +0 -1
  236. package/build/__tests__/server/tools.test.js +0 -91
  237. package/build/__tests__/server/tools.test.js.map +0 -1
  238. package/build/__tests__/services/gmail/mime.test.d.ts +0 -1
  239. package/build/__tests__/services/gmail/mime.test.js +0 -23
  240. package/build/__tests__/services/gmail/mime.test.js.map +0 -1
  241. package/build/__tests__/services/meet/patch.test.d.ts +0 -4
  242. package/build/__tests__/services/meet/patch.test.js +0 -374
  243. package/build/__tests__/services/meet/patch.test.js.map +0 -1
  244. package/build/executor/errors.d.ts +0 -15
  245. package/build/executor/errors.js +0 -37
  246. package/build/executor/errors.js.map +0 -1
  247. package/build/executor/gws.d.ts +0 -26
  248. package/build/executor/gws.js +0 -197
  249. package/build/executor/gws.js.map +0 -1
  250. package/build/server/handlers/calendar.d.ts +0 -2
  251. package/build/server/handlers/calendar.js +0 -97
  252. package/build/server/handlers/calendar.js.map +0 -1
  253. package/build/server/handlers/drive.d.ts +0 -2
  254. package/build/server/handlers/drive.js +0 -58
  255. package/build/server/handlers/drive.js.map +0 -1
  256. package/build/server/handlers/email.d.ts +0 -2
  257. package/build/server/handlers/email.js +0 -119
  258. package/build/server/handlers/email.js.map +0 -1
  259. package/build/server/scratchpad/__tests__/docs-sync-integration.test.d.ts +0 -11
  260. package/build/server/scratchpad/__tests__/docs-sync-integration.test.js +0 -187
  261. package/build/server/scratchpad/__tests__/docs-sync-integration.test.js.map +0 -1
  262. package/build/server/scratchpad/__tests__/docs-sync.test.d.ts +0 -16
  263. package/build/server/scratchpad/__tests__/docs-sync.test.js +0 -213
  264. package/build/server/scratchpad/__tests__/docs-sync.test.js.map +0 -1
  265. package/build/server/scratchpad/__tests__/json-path.test.d.ts +0 -4
  266. package/build/server/scratchpad/__tests__/json-path.test.js +0 -121
  267. package/build/server/scratchpad/__tests__/json-path.test.js.map +0 -1
  268. package/build/server/scratchpad/__tests__/manager.test.d.ts +0 -5
  269. package/build/server/scratchpad/__tests__/manager.test.js +0 -886
  270. package/build/server/scratchpad/__tests__/manager.test.js.map +0 -1
  271. package/build/server/scratchpad/__tests__/validate.test.d.ts +0 -4
  272. package/build/server/scratchpad/__tests__/validate.test.js +0 -112
  273. package/build/server/scratchpad/__tests__/validate.test.js.map +0 -1
@@ -0,0 +1,232 @@
1
+ /**
2
+ * The Google API client.
3
+ *
4
+ * The whole of a resource operation: get a token, make the call, hand back the JSON.
5
+ *
6
+ * LOAD-BEARING CONSTRAINT — this layer has NO OPINIONS. It never reshapes, never
7
+ * "fixes", never fills in. It returns exactly what Google returned. Interpretation
8
+ * happens ABOVE it, in the layer we already own and aim at the MCP contract
9
+ * (patches / formatters / next-steps). The moment this file gets helpful, it
10
+ * becomes something that can be subtly wrong in a way no test catches — the exact
11
+ * defect class ADR-101 spent six review rounds learning to fear.
12
+ *
13
+ * Everything here is a consequence of something the DESCRIPTOR said. Where a rule
14
+ * looks arbitrary, it is not: it is a fact we learned by being wrong first, live,
15
+ * against Google (ADR-103, item 2).
16
+ *
17
+ * See ADR-103.
18
+ */
19
+ import { createWriteStream } from 'node:fs';
20
+ import { mkdir } from 'node:fs/promises';
21
+ import { dirname } from 'node:path';
22
+ import { Readable } from 'node:stream';
23
+ import { pipeline } from 'node:stream/promises';
24
+ import { getAccessToken } from '../accounts/token-service.js';
25
+ import { GoogleApiError } from './errors.js';
26
+ import { loadDescriptor } from './descriptor.js';
27
+ function resolve(descriptor, service, resourcePath) {
28
+ const svc = descriptor.services[service];
29
+ if (!svc)
30
+ throw new Error(`descriptor has no service '${service}'`);
31
+ const method = svc.methods[resourcePath];
32
+ if (!method)
33
+ throw new Error(`descriptor has no method '${service}.${resourcePath}'`);
34
+ return { svc, method };
35
+ }
36
+ /**
37
+ * Expand a path template.
38
+ *
39
+ * `{+var}` is RFC 6570 RESERVED expansion — reserved characters, notably `/`,
40
+ * must NOT be percent-encoded. Meet's identifiers ARE paths
41
+ * ("conferenceRecords/abc"), so encoding that slash to %2F 404s every Meet
42
+ * sub-resource operation. The `+` is the descriptor telling us this. Honour it.
43
+ */
44
+ function expandPath(template, pathParams) {
45
+ return template.replace(/\{(\+?)([^}]+)\}/g, (_m, reserved, name) => {
46
+ if (!(name in pathParams))
47
+ throw new Error(`missing required path param '${name}'`);
48
+ const raw = String(pathParams[name]);
49
+ return reserved
50
+ ? raw.split('/').map(encodeURIComponent).join('/')
51
+ : encodeURIComponent(raw);
52
+ });
53
+ }
54
+ /**
55
+ * Split params into path / query / body by what the descriptor DECLARES.
56
+ *
57
+ * Global parameters (`fields`, `alt`, `quotaUser`, `prettyPrint`) are declared
58
+ * ONCE at the document root, not per method. A dispatcher that consults only the
59
+ * method's parameters cannot place `fields`, drops it into the body, and a GET
60
+ * silently discards it — which is exactly how drive.listComments died with
61
+ * "The 'fields' parameter is required". Merge both; the method wins on conflict.
62
+ */
63
+ function splitParams(svc, method, params) {
64
+ const declared = { ...svc.globalParameters, ...method.parameters };
65
+ const path = {};
66
+ const query = {};
67
+ const body = {};
68
+ for (const [key, value] of Object.entries(params)) {
69
+ if (value === undefined || value === null)
70
+ continue;
71
+ const location = declared[key]?.location;
72
+ if (location === 'path')
73
+ path[key] = value;
74
+ else if (location === 'query')
75
+ query[key] = value;
76
+ else
77
+ body[key] = value; // undeclared -> request body; Google validates it, not us
78
+ }
79
+ return { path, query, body };
80
+ }
81
+ function applyQuery(url, query) {
82
+ for (const [key, value] of Object.entries(query)) {
83
+ if (Array.isArray(value))
84
+ value.forEach((v) => url.searchParams.append(key, String(v)));
85
+ else
86
+ url.searchParams.set(key, String(value));
87
+ }
88
+ return url;
89
+ }
90
+ /** Pure: descriptor + params -> the request. No I/O, so it is testable offline. */
91
+ export function buildRequest(descriptor, service, resourcePath, params = {}) {
92
+ const { svc, method } = resolve(descriptor, service, resourcePath);
93
+ const { path, query, body } = splitParams(svc, method, params);
94
+ const base = svc.rootUrl.replace(/\/$/, '') + '/' + svc.servicePath.replace(/^\//, '');
95
+ const url = applyQuery(new URL((base.replace(/\/$/, '') + '/' + expandPath(method.path, path)).replace(/\/+$/, '')), query);
96
+ const hasBody = Object.keys(body).length > 0 && method.httpMethod !== 'GET';
97
+ return { url: url.toString(), method: method.httpMethod, body: hasBody ? body : undefined };
98
+ }
99
+ function parseJson(text) {
100
+ if (!text)
101
+ return {};
102
+ try {
103
+ return JSON.parse(text);
104
+ }
105
+ catch {
106
+ return { error: { message: text.slice(0, 300) } };
107
+ }
108
+ }
109
+ /**
110
+ * Call a Google API method. Returns RAW Google JSON — no envelope, no reshaping.
111
+ * Throws GoogleApiError carrying Google's real error body.
112
+ */
113
+ export async function call(service, resourcePath, params, options) {
114
+ const descriptor = options.descriptor ?? await loadDescriptor();
115
+ const doFetch = options.fetchImpl ?? fetch;
116
+ const request = buildRequest(descriptor, service, resourcePath, params);
117
+ const token = await getAccessToken(options.account);
118
+ const response = await doFetch(request.url, {
119
+ method: request.method,
120
+ headers: {
121
+ Authorization: `Bearer ${token}`,
122
+ ...(request.body ? { 'Content-Type': 'application/json' } : {}),
123
+ },
124
+ ...(request.body ? { body: JSON.stringify(request.body) } : {}),
125
+ });
126
+ const text = await response.text();
127
+ const json = parseJson(text);
128
+ if (!response.ok) {
129
+ throw new GoogleApiError(response.status, json, {
130
+ url: request.url,
131
+ method: request.method,
132
+ });
133
+ }
134
+ return json;
135
+ }
136
+ /**
137
+ * Download media to disk.
138
+ *
139
+ * STREAMED, deliberately. The bytes go from the socket to the file and are never a
140
+ * string at all. Never buffer a download through an in-memory string: accumulating
141
+ * the whole response and JSON.parse-ing it turns a 30 MB attachment into a ~40 MB
142
+ * string, then an object, then a Buffer — uncapped, for every download.
143
+ */
144
+ export async function download(service, resourcePath, params, outputPath, options) {
145
+ const descriptor = options.descriptor ?? await loadDescriptor();
146
+ const doFetch = options.fetchImpl ?? fetch;
147
+ const request = buildRequest(descriptor, service, resourcePath, params);
148
+ const token = await getAccessToken(options.account);
149
+ const response = await doFetch(request.url, {
150
+ method: request.method,
151
+ headers: { Authorization: `Bearer ${token}` },
152
+ });
153
+ if (!response.ok) {
154
+ const json = parseJson(await response.text());
155
+ throw new GoogleApiError(response.status, json, {
156
+ url: request.url,
157
+ method: request.method,
158
+ });
159
+ }
160
+ if (!response.body)
161
+ throw new Error(`no response body for ${service}.${resourcePath}`);
162
+ await mkdir(dirname(outputPath), { recursive: true });
163
+ await pipeline(Readable.fromWeb(response.body), createWriteStream(outputPath));
164
+ return outputPath;
165
+ }
166
+ /**
167
+ * Resumable, chunked media upload.
168
+ *
169
+ * The descriptor carries the upload paths for both protocols because Discovery
170
+ * DECLARES them. Verified live (ADR-103 item 4): a 25 MB attachment — 34.2 MB as
171
+ * RFC822, 93% of Google's declared 36,700,160-byte cap — uploaded in 5 chunks and
172
+ * read back byte-for-byte identical.
173
+ */
174
+ export async function upload(service, resourcePath, params, options) {
175
+ const descriptor = options.descriptor ?? await loadDescriptor();
176
+ const doFetch = options.fetchImpl ?? fetch;
177
+ const { svc, method } = resolve(descriptor, service, resourcePath);
178
+ if (!method.mediaUpload)
179
+ throw new Error(`${service}.${resourcePath} does not support media upload`);
180
+ // Google DECLARES the ceiling. Refusing locally beats a confusing 400 from a
181
+ // 35 MB request that already crossed the wire.
182
+ const max = Number(method.mediaUpload.maxSize);
183
+ if (max && options.media.length > max) {
184
+ throw new Error(`${service}.${resourcePath}: payload is ${options.media.length} bytes; ` +
185
+ `Google's declared limit is ${max} bytes`);
186
+ }
187
+ const token = await getAccessToken(options.account);
188
+ const { path, query } = splitParams(svc, method, params);
189
+ const uploadPath = method.mediaUpload.resumable ?? method.mediaUpload.simple;
190
+ if (!uploadPath)
191
+ throw new Error(`${service}.${resourcePath} declares no upload protocol`);
192
+ const initiateUrl = applyQuery(new URL(expandPath(uploadPath, path), svc.rootUrl), { ...query, uploadType: 'resumable' }).toString();
193
+ const initiate = await doFetch(initiateUrl, {
194
+ method: method.httpMethod,
195
+ headers: {
196
+ Authorization: `Bearer ${token}`,
197
+ 'Content-Type': 'application/json; charset=UTF-8',
198
+ 'X-Upload-Content-Type': options.contentType,
199
+ 'X-Upload-Content-Length': String(options.media.length),
200
+ },
201
+ body: JSON.stringify(options.metadata ?? {}),
202
+ });
203
+ if (!initiate.ok) {
204
+ const json = parseJson(await initiate.text());
205
+ throw new GoogleApiError(initiate.status, json, { url: initiateUrl, method: method.httpMethod });
206
+ }
207
+ const session = initiate.headers.get('location');
208
+ if (!session)
209
+ throw new Error('resumable upload: initiate returned no Location header');
210
+ const chunkSize = options.chunkSize ?? 8 * 1024 * 1024;
211
+ let offset = 0;
212
+ while (offset < options.media.length) {
213
+ const end = Math.min(offset + chunkSize, options.media.length);
214
+ const response = await doFetch(session, {
215
+ method: 'PUT',
216
+ headers: { 'Content-Range': `bytes ${offset}-${end - 1}/${options.media.length}` },
217
+ body: options.media.subarray(offset, end),
218
+ });
219
+ // 308 "Resume Incomplete" is the protocol working, not an error.
220
+ if (response.status === 308) {
221
+ offset = end;
222
+ continue;
223
+ }
224
+ const text = await response.text();
225
+ if (!response.ok) {
226
+ throw new GoogleApiError(response.status, parseJson(text), { url: session, method: 'PUT' });
227
+ }
228
+ return parseJson(text);
229
+ }
230
+ throw new Error('resumable upload: media consumed without a terminal response');
231
+ }
232
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/google/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ export interface ApiParam {
2
+ location: 'path' | 'query';
3
+ required?: boolean;
4
+ repeated?: boolean;
5
+ }
6
+ export interface ApiMediaUpload {
7
+ maxSize?: string;
8
+ accept?: string[];
9
+ simple?: string;
10
+ resumable?: string;
11
+ }
12
+ export interface ApiMethod {
13
+ path: string;
14
+ httpMethod: string;
15
+ parameters: Record<string, ApiParam>;
16
+ scopes?: string[];
17
+ supportsMediaDownload?: boolean;
18
+ mediaUpload?: ApiMediaUpload;
19
+ }
20
+ export interface ApiService {
21
+ version: string;
22
+ rootUrl: string;
23
+ servicePath: string;
24
+ discoveryUrl: string;
25
+ /** `fields`, `alt`, `quotaUser`… declared once at the document root, not per method. */
26
+ globalParameters: Record<string, ApiParam>;
27
+ methods: Record<string, ApiMethod>;
28
+ }
29
+ export interface ApiDescriptor {
30
+ generatedFrom: string;
31
+ services: Record<string, ApiService>;
32
+ }
33
+ /**
34
+ * Load the descriptor. Resolved as a sibling of this module, which makes it work
35
+ * under `src/` (vitest) and under `build/` (the shipped server) alike — the same
36
+ * trick `loadManifest()` uses, and the reason `npx` works.
37
+ */
38
+ export declare function loadDescriptor(): Promise<ApiDescriptor>;
39
+ /** Tests only: drop the memoised descriptor. */
40
+ export declare function resetDescriptorCache(): void;
@@ -0,0 +1,37 @@
1
+ /**
2
+ * The API descriptor: a generated, committed transcription of Google's Discovery
3
+ * documents, pruned to what making a REQUEST needs.
4
+ *
5
+ * Generated at BUILD time by `scripts/generate-descriptor.mjs` and committed, so
6
+ * there is no network dependency at startup and nothing breaks offline. Drift is a
7
+ * CI check, not a production surprise.
8
+ *
9
+ * It records what Discovery says about how to CALL Google. It records nothing
10
+ * about what a RESPONSE means — Discovery's `schemas` block (~90% of the raw
11
+ * document) is deliberately DISCARDED. A descriptor that knows response shapes is
12
+ * a descriptor that can start helpfully reshaping them.
13
+ *
14
+ * See ADR-103.
15
+ */
16
+ import { readFile } from 'node:fs/promises';
17
+ import { dirname, resolve } from 'node:path';
18
+ import { fileURLToPath } from 'node:url';
19
+ let cached;
20
+ /**
21
+ * Load the descriptor. Resolved as a sibling of this module, which makes it work
22
+ * under `src/` (vitest) and under `build/` (the shipped server) alike — the same
23
+ * trick `loadManifest()` uses, and the reason `npx` works.
24
+ */
25
+ export async function loadDescriptor() {
26
+ if (cached)
27
+ return cached;
28
+ const here = dirname(fileURLToPath(import.meta.url));
29
+ const raw = await readFile(resolve(here, 'descriptor.json'), 'utf-8');
30
+ cached = JSON.parse(raw);
31
+ return cached;
32
+ }
33
+ /** Tests only: drop the memoised descriptor. */
34
+ export function resetDescriptorCache() {
35
+ cached = undefined;
36
+ }
37
+ //# sourceMappingURL=descriptor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"descriptor.js","sourceRoot":"","sources":["../../src/google/descriptor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAuCzC,IAAI,MAAiC,CAAC;AAEtC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACrD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,iBAAiB,CAAC,EAAE,OAAO,CAAC,CAAC;IACtE,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAkB,CAAC;IAC1C,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,gDAAgD;AAChD,MAAM,UAAU,oBAAoB;IAClC,MAAM,GAAG,SAAS,CAAC;AACrB,CAAC"}