@hasna/connectors 1.3.22 → 1.3.23

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 (63) hide show
  1. package/bin/index.js +109 -59
  2. package/bin/mcp.js +236 -182
  3. package/bin/serve.js +77 -33
  4. package/connectors/connect-dropbox/src/api/bulk.ts +285 -0
  5. package/connectors/connect-dropbox/src/api/index.ts +4 -0
  6. package/connectors/connect-dropbox/src/cli/index.ts +151 -0
  7. package/connectors/connect-github/src/api/bulk.ts +328 -0
  8. package/connectors/connect-github/src/api/index.ts +4 -0
  9. package/connectors/connect-github/src/cli/index.ts +145 -0
  10. package/connectors/connect-gmail/src/api/history.ts +82 -0
  11. package/connectors/connect-gmail/src/api/index.ts +12 -0
  12. package/connectors/connect-gmail/src/api/settings.ts +280 -0
  13. package/connectors/connect-gmail/src/api/watch.ts +40 -0
  14. package/connectors/connect-gmail/src/cli/index.ts +237 -0
  15. package/connectors/connect-googleads/src/api/bulk.ts +354 -0
  16. package/connectors/connect-googleads/src/api/index.ts +4 -0
  17. package/connectors/connect-googleads/src/cli/index.ts +192 -0
  18. package/connectors/connect-googlecalendar/src/api/acl.ts +66 -0
  19. package/connectors/connect-googlecalendar/src/api/bulk.ts +452 -0
  20. package/connectors/connect-googlecalendar/src/api/freebusy.ts +35 -0
  21. package/connectors/connect-googlecalendar/src/api/index.ts +9 -0
  22. package/connectors/connect-googlecalendar/src/cli/index.ts +522 -0
  23. package/connectors/connect-googlecalendar/src/types/index.ts +90 -0
  24. package/connectors/connect-googlecontacts/src/api/bulk.ts +365 -0
  25. package/connectors/connect-googlecontacts/src/api/groups.ts +164 -0
  26. package/connectors/connect-googlecontacts/src/api/index.ts +8 -0
  27. package/connectors/connect-googlecontacts/src/cli/index.ts +340 -0
  28. package/connectors/connect-googledocs/src/api/bulk.ts +301 -0
  29. package/connectors/connect-googledocs/src/api/index.ts +4 -0
  30. package/connectors/connect-googledocs/src/cli/index.ts +187 -0
  31. package/connectors/connect-googledrive/src/api/bulk.ts +505 -0
  32. package/connectors/connect-googledrive/src/api/changes.ts +139 -0
  33. package/connectors/connect-googledrive/src/api/client.ts +34 -0
  34. package/connectors/connect-googledrive/src/api/index.ts +12 -0
  35. package/connectors/connect-googledrive/src/api/revisions.ts +132 -0
  36. package/connectors/connect-googledrive/src/cli/index.ts +624 -0
  37. package/connectors/connect-googledrive/src/index.ts +2 -0
  38. package/connectors/connect-googlephotos/src/api/bulk.ts +455 -0
  39. package/connectors/connect-googlephotos/src/api/index.ts +8 -0
  40. package/connectors/connect-googlephotos/src/cli/index.ts +185 -0
  41. package/connectors/connect-googletasks/src/api/bulk.ts +359 -0
  42. package/connectors/connect-googletasks/src/api/index.ts +1 -0
  43. package/connectors/connect-googletasks/src/cli/index.ts +178 -0
  44. package/connectors/connect-linear/src/api/bulk.ts +219 -0
  45. package/connectors/connect-linear/src/api/index.ts +4 -0
  46. package/connectors/connect-linear/src/cli/index.ts +116 -0
  47. package/connectors/connect-shopify/src/api/bulk.ts +288 -0
  48. package/connectors/connect-shopify/src/api/index.ts +4 -0
  49. package/connectors/connect-shopify/src/cli/index.ts +108 -0
  50. package/connectors/connect-slack/src/api/bulk.ts +237 -0
  51. package/connectors/connect-slack/src/api/index.ts +4 -0
  52. package/connectors/connect-slack/src/cli/index.ts +157 -0
  53. package/connectors/connect-stripe/src/api/bulk.ts +488 -0
  54. package/connectors/connect-stripe/src/api/index.ts +4 -0
  55. package/connectors/connect-stripe/src/cli/index.ts +206 -0
  56. package/dist/index.js +75 -33
  57. package/dist/lib/runner.d.ts +15 -5
  58. package/package.json +2 -2
  59. package/connectors/connect-cloudflare/bun.lock +0 -32
  60. package/connectors/connect-gmail/bin/index.js +0 -7027
  61. package/connectors/connect-gmail/dist/cli/index.js +0 -7035
  62. package/connectors/connect-gmail/dist/index.js +0 -2174
  63. package/dist/server/server.test.d.ts +0 -1
@@ -0,0 +1,139 @@
1
+ import type { DriveClient } from './client.ts';
2
+ import type { DriveFile } from '../types/index.ts';
3
+
4
+ // ============================================
5
+ // Changes API Types
6
+ // ============================================
7
+
8
+ export interface ListChangesOptions {
9
+ pageToken: string;
10
+ pageSize?: number;
11
+ spaces?: string;
12
+ includeRemoved?: boolean;
13
+ includeItemsFromAllDrives?: boolean;
14
+ restrictToMyDrive?: boolean;
15
+ driveId?: string;
16
+ supportsAllDrives?: boolean;
17
+ }
18
+
19
+ export interface ChangeRecord {
20
+ fileId: string;
21
+ type: 'file' | 'drive' | 'driveMember';
22
+ removed?: boolean;
23
+ file?: DriveFile;
24
+ drive?: {
25
+ id: string;
26
+ name: string;
27
+ kind: string;
28
+ };
29
+ driveMember?: {
30
+ kind: string;
31
+ displayName: string;
32
+ photoLink: string;
33
+ };
34
+ }
35
+
36
+ export interface ListChangesResponse {
37
+ kind: string;
38
+ nextPageToken: string;
39
+ newStartPageToken: string;
40
+ changes: ChangeRecord[];
41
+ }
42
+
43
+ export interface WatchChangesOptions {
44
+ topicName: string;
45
+ params?: Record<string, string>;
46
+ watchType?: string;
47
+ watchId?: string;
48
+ token?: string;
49
+ expiration?: string;
50
+ }
51
+
52
+ export interface WatchResponse {
53
+ kind: string;
54
+ id: string;
55
+ resourceId: string;
56
+ resourceUri: string;
57
+ expiration: string;
58
+ }
59
+
60
+ /**
61
+ * Changes API module - track changes to Drive files and shared drives
62
+ */
63
+ export class ChangesApi {
64
+ constructor(private readonly client: DriveClient) {}
65
+
66
+ /**
67
+ * Get the starting page token for change tracking
68
+ */
69
+ async getStartPageToken(options: {
70
+ supportsAllDrives?: boolean;
71
+ driveId?: string;
72
+ } = {}): Promise<{ nextPageToken: string }> {
73
+ const params: Record<string, string | boolean | undefined> = {};
74
+ if (options.supportsAllDrives !== undefined) params.supportsAllDrives = options.supportsAllDrives;
75
+ if (options.driveId) params.driveId = options.driveId;
76
+
77
+ return this.client.get<{ nextPageToken: string }>('/changes/startPageToken', params);
78
+ }
79
+
80
+ /**
81
+ * List changes for a user
82
+ */
83
+ async list(options: ListChangesOptions): Promise<ListChangesResponse> {
84
+ const params: Record<string, string | number | boolean | undefined> = {
85
+ pageToken: options.pageToken,
86
+ };
87
+ if (options.pageSize) params.pageSize = options.pageSize;
88
+ if (options.spaces) params.spaces = options.spaces;
89
+ if (options.includeRemoved !== undefined) params.includeRemoved = options.includeRemoved;
90
+ if (options.includeItemsFromAllDrives !== undefined) params.includeItemsFromAllDrives = options.includeItemsFromAllDrives;
91
+ if (options.restrictToMyDrive !== undefined) params.restrictToMyDrive = options.restrictToMyDrive;
92
+ if (options.driveId) params.driveId = options.driveId;
93
+ if (options.supportsAllDrives !== undefined) params.supportsAllDrives = options.supportsAllDrives;
94
+
95
+ return this.client.get<ListChangesResponse>('/changes', params);
96
+ }
97
+
98
+ /**
99
+ * Iterate over all changes (handles pagination)
100
+ */
101
+ async *listAll(options: Omit<ListChangesOptions, 'pageToken'> & { startPageToken: string }): AsyncGenerator<ChangeRecord> {
102
+ let pageToken = options.startPageToken;
103
+ const baseOptions = { ...options };
104
+ // @ts-expect-error pageToken will be set
105
+ delete baseOptions.pageToken;
106
+ // @ts-expect-error startPageToken is not part of ListChangesOptions
107
+ delete baseOptions.startPageToken;
108
+
109
+ do {
110
+ const response = await this.list({ ...baseOptions, pageToken });
111
+ for (const record of response.changes || []) {
112
+ yield record;
113
+ }
114
+ if (response.nextPageToken) {
115
+ pageToken = response.nextPageToken;
116
+ } else {
117
+ break;
118
+ }
119
+ } while (true);
120
+ }
121
+
122
+ /**
123
+ * Subscribe to push notifications for changes
124
+ */
125
+ async watch(options: WatchChangesOptions): Promise<WatchResponse> {
126
+ const body: Record<string, unknown> = {
127
+ id: options.watchId,
128
+ type: options.watchType || 'web_hook',
129
+ token: options.token,
130
+ expiration: options.expiration,
131
+ };
132
+ if (options.topicName) {
133
+ body.type = 'web_hook';
134
+ body.params = { topicName: options.topicName, ...(options.params || {}) };
135
+ }
136
+
137
+ return this.client.post<WatchResponse>('/changes/watch', body as unknown as Record<string, unknown>);
138
+ }
139
+ }
@@ -213,4 +213,38 @@ export class DriveClient {
213
213
 
214
214
  return response.arrayBuffer();
215
215
  }
216
+
217
+ async downloadRevision(fileId: string, revisionId: string): Promise<ArrayBuffer> {
218
+ const accessToken = await getValidAccessToken();
219
+ const url = DRIVE_API_BASE + '/files/' + fileId + '/revisions/' + revisionId + '?alt=media&supportsAllDrives=true';
220
+
221
+ const response = await fetch(url, {
222
+ headers: {
223
+ 'Authorization': 'Bearer ' + accessToken,
224
+ },
225
+ });
226
+
227
+ if (!response.ok) {
228
+ throw new DriveApiError('Download revision failed: ' + response.statusText, response.status);
229
+ }
230
+
231
+ return response.arrayBuffer();
232
+ }
233
+
234
+ async exportRevision(fileId: string, revisionId: string, mimeType: string): Promise<ArrayBuffer> {
235
+ const accessToken = await getValidAccessToken();
236
+ const url = DRIVE_API_BASE + '/files/' + fileId + '/revisions/' + revisionId + '/export?mimeType=' + encodeURIComponent(mimeType);
237
+
238
+ const response = await fetch(url, {
239
+ headers: {
240
+ 'Authorization': 'Bearer ' + accessToken,
241
+ },
242
+ });
243
+
244
+ if (!response.ok) {
245
+ throw new DriveApiError('Export revision failed: ' + response.statusText, response.status);
246
+ }
247
+
248
+ return response.arrayBuffer();
249
+ }
216
250
  }
@@ -4,6 +4,9 @@ import { FoldersApi } from './folders.ts';
4
4
  import { TrashApi } from './trash.ts';
5
5
  import { StorageApi } from './storage.ts';
6
6
  import { DrivesApi } from './drives.ts';
7
+ import { BulkApi } from './bulk.ts';
8
+ import { ChangesApi } from './changes.ts';
9
+ import { RevisionsApi } from './revisions.ts';
7
10
 
8
11
  export class Drive {
9
12
  private readonly client: DriveClient;
@@ -14,6 +17,9 @@ export class Drive {
14
17
  public readonly trash: TrashApi;
15
18
  public readonly storage: StorageApi;
16
19
  public readonly drives: DrivesApi;
20
+ public readonly bulk: BulkApi;
21
+ public readonly changes: ChangesApi;
22
+ public readonly revisions: RevisionsApi;
17
23
 
18
24
  constructor() {
19
25
  this.client = new DriveClient();
@@ -22,6 +28,9 @@ export class Drive {
22
28
  this.trash = new TrashApi(this.client);
23
29
  this.storage = new StorageApi(this.client);
24
30
  this.drives = new DrivesApi(this.client);
31
+ this.bulk = new BulkApi(this.client);
32
+ this.changes = new ChangesApi(this.client);
33
+ this.revisions = new RevisionsApi(this.client);
25
34
  }
26
35
 
27
36
  /**
@@ -45,3 +54,6 @@ export { FoldersApi } from './folders.ts';
45
54
  export { TrashApi } from './trash.ts';
46
55
  export { StorageApi } from './storage.ts';
47
56
  export { DrivesApi } from './drives.ts';
57
+ export { BulkApi } from './bulk.ts';
58
+ export { ChangesApi } from './changes.ts';
59
+ export { RevisionsApi } from './revisions.ts';
@@ -0,0 +1,132 @@
1
+ import type { DriveClient } from './client.ts';
2
+
3
+ // ============================================
4
+ // Revisions API Types
5
+ // ============================================
6
+
7
+ export interface FileRevision {
8
+ id: string;
9
+ mimeType: string;
10
+ modifiedTime?: string;
11
+ keepForever?: boolean;
12
+ published?: boolean;
13
+ publishedOutsideDomain?: boolean;
14
+ publishAuto?: boolean;
15
+ publishedLink?: string;
16
+ lastModifyingUser?: {
17
+ displayName: string;
18
+ photoLink: string;
19
+ me: boolean;
20
+ permissionId: string;
21
+ emailAddress: string;
22
+ };
23
+ originalFilename?: string;
24
+ size?: string;
25
+ exportLinks?: Record<string, string>;
26
+ sha1Checksum?: string;
27
+ sha256Checksum?: string;
28
+ md5Checksum?: string;
29
+ contentHints?: {
30
+ thumbnail?: {
31
+ image: string;
32
+ mimeType: string;
33
+ };
34
+ };
35
+ }
36
+
37
+ export interface ListRevisionsResponse {
38
+ kind: string;
39
+ fileExportMimeType?: string;
40
+ revisions: FileRevision[];
41
+ }
42
+
43
+ export interface ListRevisionsOptions {
44
+ pageSize?: number;
45
+ pageToken?: string;
46
+ fields?: string;
47
+ }
48
+
49
+ export interface UpdateRevisionOptions {
50
+ keepForever?: boolean;
51
+ publishAuto?: boolean;
52
+ published?: boolean;
53
+ publishedOutsideDomain?: boolean;
54
+ }
55
+
56
+ /**
57
+ * Revisions API module - manage file revision history
58
+ */
59
+ export class RevisionsApi {
60
+ constructor(private readonly client: DriveClient) {}
61
+
62
+ /**
63
+ * List revisions of a file
64
+ */
65
+ async list(fileId: string, options: ListRevisionsOptions = {}): Promise<ListRevisionsResponse> {
66
+ const params: Record<string, string | number | undefined> = {};
67
+ if (options.pageSize) params.pageSize = options.pageSize;
68
+ if (options.pageToken) params.pageToken = options.pageToken;
69
+ if (options.fields) params.fields = options.fields;
70
+
71
+ return this.client.get<ListRevisionsResponse>(`/files/${fileId}/revisions`, params);
72
+ }
73
+
74
+ /**
75
+ * Iterate over all revisions of a file (handles pagination)
76
+ */
77
+ async *listAll(fileId: string, options: Omit<ListRevisionsOptions, 'pageToken'> = {}): AsyncGenerator<FileRevision> {
78
+ let pageToken: string | undefined;
79
+ do {
80
+ const response = await this.list(fileId, { ...options, pageToken });
81
+ for (const revision of response.revisions || []) {
82
+ yield revision;
83
+ }
84
+ pageToken = response.revisions?.length && response.revisions.length > 0
85
+ ? undefined
86
+ : undefined;
87
+ // Drive revisions API doesn't always paginate, so we check once
88
+ break;
89
+ } while (pageToken);
90
+ }
91
+
92
+ /**
93
+ * Get a specific revision
94
+ */
95
+ async get(fileId: string, revisionId: string): Promise<FileRevision> {
96
+ return this.client.get<FileRevision>(`/files/${fileId}/revisions/${revisionId}`);
97
+ }
98
+
99
+ /**
100
+ * Update revision metadata
101
+ */
102
+ async update(fileId: string, revisionId: string, options: UpdateRevisionOptions): Promise<FileRevision> {
103
+ const body: Record<string, unknown> = {};
104
+ if (options.keepForever !== undefined) body.keepForever = options.keepForever;
105
+ if (options.publishAuto !== undefined) body.publishAuto = options.publishAuto;
106
+ if (options.published !== undefined) body.published = options.published;
107
+ if (options.publishedOutsideDomain !== undefined) body.publishedOutsideDomain = options.publishedOutsideDomain;
108
+
109
+ return this.client.patch<FileRevision>(`/files/${fileId}/revisions/${revisionId}`, body);
110
+ }
111
+
112
+ /**
113
+ * Delete a revision
114
+ */
115
+ async delete(fileId: string, revisionId: string): Promise<void> {
116
+ await this.client.delete(`/files/${fileId}/revisions/${revisionId}`);
117
+ }
118
+
119
+ /**
120
+ * Download the content of a revision
121
+ */
122
+ async download(fileId: string, revisionId: string): Promise<ArrayBuffer> {
123
+ return this.client.downloadRevision(fileId, revisionId);
124
+ }
125
+
126
+ /**
127
+ * Export a Google Workspace document revision in a specific format
128
+ */
129
+ async export(fileId: string, revisionId: string, mimeType: string): Promise<ArrayBuffer> {
130
+ return this.client.exportRevision(fileId, revisionId, mimeType);
131
+ }
132
+ }