digital-tools 2.0.2 → 2.1.1

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 (93) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/package.json +3 -4
  3. package/src/define.js +267 -0
  4. package/src/entities/advertising.js +999 -0
  5. package/src/entities/ai.js +756 -0
  6. package/src/entities/analytics.js +1588 -0
  7. package/src/entities/automation.js +601 -0
  8. package/src/entities/communication.js +1150 -0
  9. package/src/entities/crm.js +1386 -0
  10. package/src/entities/design.js +546 -0
  11. package/src/entities/development.js +2212 -0
  12. package/src/entities/document.js +874 -0
  13. package/src/entities/ecommerce.js +1429 -0
  14. package/src/entities/experiment.js +1039 -0
  15. package/src/entities/finance.js +3478 -0
  16. package/src/entities/forms.js +1892 -0
  17. package/src/entities/hr.js +661 -0
  18. package/src/entities/identity.js +997 -0
  19. package/src/entities/index.js +282 -0
  20. package/src/entities/infrastructure.js +1153 -0
  21. package/src/entities/knowledge.js +1438 -0
  22. package/src/entities/marketing.js +1610 -0
  23. package/src/entities/media.js +1634 -0
  24. package/src/entities/notification.js +1199 -0
  25. package/src/entities/presentation.js +1274 -0
  26. package/src/entities/productivity.js +1317 -0
  27. package/src/entities/project-management.js +1136 -0
  28. package/src/entities/recruiting.js +736 -0
  29. package/src/entities/shipping.js +509 -0
  30. package/src/entities/signature.js +1102 -0
  31. package/src/entities/site.js +222 -0
  32. package/src/entities/spreadsheet.js +1341 -0
  33. package/src/entities/storage.js +1198 -0
  34. package/src/entities/support.js +1166 -0
  35. package/src/entities/video-conferencing.js +1750 -0
  36. package/src/entities/video.js +950 -0
  37. package/src/entities.js +1663 -0
  38. package/src/index.js +74 -0
  39. package/src/providers/analytics/index.js +17 -0
  40. package/src/providers/analytics/mixpanel.js +255 -0
  41. package/src/providers/calendar/cal-com.js +303 -0
  42. package/src/providers/calendar/google-calendar.js +335 -0
  43. package/src/providers/calendar/index.js +20 -0
  44. package/src/providers/crm/hubspot.js +566 -0
  45. package/src/providers/crm/index.js +17 -0
  46. package/src/providers/development/github.js +472 -0
  47. package/src/providers/development/index.js +17 -0
  48. package/src/providers/ecommerce/index.js +17 -0
  49. package/src/providers/ecommerce/shopify.js +378 -0
  50. package/src/providers/email/index.js +20 -0
  51. package/src/providers/email/resend.js +258 -0
  52. package/src/providers/email/sendgrid.js +161 -0
  53. package/src/providers/finance/index.js +17 -0
  54. package/src/providers/finance/stripe.js +549 -0
  55. package/src/providers/forms/index.js +17 -0
  56. package/src/providers/forms/typeform.js +500 -0
  57. package/src/providers/index.js +123 -0
  58. package/src/providers/knowledge/index.js +17 -0
  59. package/src/providers/knowledge/notion.js +389 -0
  60. package/src/providers/marketing/index.js +17 -0
  61. package/src/providers/marketing/mailchimp.js +443 -0
  62. package/src/providers/media/cloudinary.js +318 -0
  63. package/src/providers/media/index.js +17 -0
  64. package/src/providers/messaging/index.js +20 -0
  65. package/src/providers/messaging/slack.js +393 -0
  66. package/src/providers/messaging/twilio-sms.js +249 -0
  67. package/src/providers/project-management/index.js +17 -0
  68. package/src/providers/project-management/linear.js +575 -0
  69. package/src/providers/registry.js +86 -0
  70. package/src/providers/spreadsheet/google-sheets.js +375 -0
  71. package/src/providers/spreadsheet/index.js +20 -0
  72. package/src/providers/spreadsheet/xlsx.js +423 -0
  73. package/src/providers/storage/index.js +24 -0
  74. package/src/providers/storage/s3.js +419 -0
  75. package/src/providers/support/index.js +17 -0
  76. package/src/providers/support/zendesk.js +373 -0
  77. package/src/providers/tasks/index.js +17 -0
  78. package/src/providers/tasks/todoist.js +286 -0
  79. package/src/providers/types.js +9 -0
  80. package/src/providers/video-conferencing/google-meet.js +286 -0
  81. package/src/providers/video-conferencing/index.js +31 -0
  82. package/src/providers/video-conferencing/jitsi.js +254 -0
  83. package/src/providers/video-conferencing/teams.js +270 -0
  84. package/src/providers/video-conferencing/zoom.js +332 -0
  85. package/src/registry.js +128 -0
  86. package/src/tools/communication.js +184 -0
  87. package/src/tools/data.js +205 -0
  88. package/src/tools/index.js +11 -0
  89. package/src/tools/web.js +137 -0
  90. package/src/types.js +10 -0
  91. package/test/define.test.js +306 -0
  92. package/test/registry.test.js +357 -0
  93. package/test/tools.test.js +363 -0
@@ -0,0 +1,335 @@
1
+ /**
2
+ * Google Calendar Provider
3
+ *
4
+ * Concrete implementation of CalendarProvider using Google Calendar API v3.
5
+ *
6
+ * @packageDocumentation
7
+ */
8
+ import { defineProvider } from '../registry.js';
9
+ const GOOGLE_CALENDAR_API_URL = 'https://www.googleapis.com/calendar/v3';
10
+ /**
11
+ * Google Calendar provider info
12
+ */
13
+ export const googleCalendarInfo = {
14
+ id: 'calendar.google-calendar',
15
+ name: 'Google Calendar',
16
+ description: 'Google Calendar API for managing calendars and events',
17
+ category: 'calendar',
18
+ website: 'https://calendar.google.com',
19
+ docsUrl: 'https://developers.google.com/calendar/api/v3/reference',
20
+ requiredConfig: ['accessToken'],
21
+ optionalConfig: ['calendarId'],
22
+ };
23
+ /**
24
+ * Create Google Calendar provider
25
+ */
26
+ export function createGoogleCalendarProvider(config) {
27
+ let accessToken;
28
+ let defaultCalendarId;
29
+ /**
30
+ * Helper to make authenticated API requests
31
+ */
32
+ async function apiRequest(endpoint, options = {}) {
33
+ try {
34
+ const response = await fetch(`${GOOGLE_CALENDAR_API_URL}${endpoint}`, {
35
+ ...options,
36
+ headers: {
37
+ Authorization: `Bearer ${accessToken}`,
38
+ 'Content-Type': 'application/json',
39
+ ...options.headers,
40
+ },
41
+ });
42
+ if (response.ok) {
43
+ const data = (await response.json());
44
+ return { ok: true, status: response.status, data };
45
+ }
46
+ const errorData = await response.json().catch(() => ({}));
47
+ return {
48
+ ok: false,
49
+ status: response.status,
50
+ error: errorData?.error?.message || response.statusText,
51
+ };
52
+ }
53
+ catch (error) {
54
+ return {
55
+ ok: false,
56
+ status: 0,
57
+ error: error instanceof Error ? error.message : 'Unknown error',
58
+ };
59
+ }
60
+ }
61
+ return {
62
+ info: googleCalendarInfo,
63
+ async initialize(cfg) {
64
+ accessToken = cfg.accessToken;
65
+ defaultCalendarId = cfg.calendarId;
66
+ if (!accessToken) {
67
+ throw new Error('Google Calendar access token is required');
68
+ }
69
+ },
70
+ async healthCheck() {
71
+ const start = Date.now();
72
+ const result = await apiRequest('/users/me/calendarList', { method: 'GET' });
73
+ return {
74
+ healthy: result.ok,
75
+ latencyMs: Date.now() - start,
76
+ message: result.ok ? 'Connected' : result.error || `HTTP ${result.status}`,
77
+ checkedAt: new Date(),
78
+ };
79
+ },
80
+ async dispose() {
81
+ // No cleanup needed
82
+ },
83
+ async listCalendars(options) {
84
+ const params = new URLSearchParams();
85
+ if (options?.limit)
86
+ params.append('maxResults', String(options.limit));
87
+ if (options?.cursor)
88
+ params.append('pageToken', options.cursor);
89
+ const result = await apiRequest(`/users/me/calendarList?${params}`);
90
+ if (!result.ok || !result.data) {
91
+ return { items: [], hasMore: false };
92
+ }
93
+ const items = result.data.items.map((cal) => ({
94
+ id: cal.id,
95
+ name: cal.summary,
96
+ description: cal.description,
97
+ timeZone: cal.timeZone,
98
+ primary: cal.primary || false,
99
+ accessRole: cal.accessRole,
100
+ }));
101
+ return {
102
+ items,
103
+ hasMore: !!result.data.nextPageToken,
104
+ nextCursor: result.data.nextPageToken,
105
+ };
106
+ },
107
+ async getCalendar(calendarId) {
108
+ const result = await apiRequest(`/calendars/${encodeURIComponent(calendarId)}`);
109
+ if (!result.ok || !result.data) {
110
+ return null;
111
+ }
112
+ const cal = result.data;
113
+ return {
114
+ id: cal.id,
115
+ name: cal.summary,
116
+ description: cal.description,
117
+ timeZone: cal.timeZone,
118
+ primary: false,
119
+ accessRole: 'owner',
120
+ };
121
+ },
122
+ async createEvent(calendarId, event) {
123
+ const body = {
124
+ summary: event.summary,
125
+ description: event.description,
126
+ location: event.location,
127
+ start: {
128
+ dateTime: event.start.toISOString(),
129
+ timeZone: 'UTC',
130
+ },
131
+ end: {
132
+ dateTime: event.end.toISOString(),
133
+ timeZone: 'UTC',
134
+ },
135
+ attendees: event.attendees?.map((email) => ({ email })),
136
+ reminders: event.reminders
137
+ ? {
138
+ useDefault: false,
139
+ overrides: event.reminders.map((r) => ({ method: r.method, minutes: r.minutes })),
140
+ }
141
+ : { useDefault: true },
142
+ recurrence: event.recurrence,
143
+ conferenceData: event.conferenceData
144
+ ? {
145
+ createRequest: {
146
+ requestId: `${Date.now()}-${Math.random()}`,
147
+ conferenceSolutionKey: {
148
+ type: event.conferenceData.type === 'hangoutsMeet' ? 'hangoutsMeet' : 'hangoutsMeet',
149
+ },
150
+ },
151
+ }
152
+ : undefined,
153
+ };
154
+ const params = event.conferenceData ? '?conferenceDataVersion=1' : '';
155
+ const result = await apiRequest(`/calendars/${encodeURIComponent(calendarId)}/events${params}`, {
156
+ method: 'POST',
157
+ body: JSON.stringify(body),
158
+ });
159
+ if (!result.ok || !result.data) {
160
+ throw new Error(result.error || 'Failed to create event');
161
+ }
162
+ const evt = result.data;
163
+ return {
164
+ id: evt.id,
165
+ calendarId,
166
+ summary: evt.summary,
167
+ description: evt.description,
168
+ location: evt.location,
169
+ start: new Date(evt.start.dateTime || evt.start.date),
170
+ end: new Date(evt.end.dateTime || evt.end.date),
171
+ attendees: evt.attendees?.map((a) => ({
172
+ email: a.email,
173
+ responseStatus: a.responseStatus,
174
+ })),
175
+ status: evt.status,
176
+ recurringEventId: evt.recurringEventId,
177
+ htmlLink: evt.htmlLink,
178
+ };
179
+ },
180
+ async getEvent(calendarId, eventId) {
181
+ const result = await apiRequest(`/calendars/${encodeURIComponent(calendarId)}/events/${encodeURIComponent(eventId)}`);
182
+ if (!result.ok || !result.data) {
183
+ return null;
184
+ }
185
+ const evt = result.data;
186
+ return {
187
+ id: evt.id,
188
+ calendarId,
189
+ summary: evt.summary,
190
+ description: evt.description,
191
+ location: evt.location,
192
+ start: new Date(evt.start.dateTime || evt.start.date),
193
+ end: new Date(evt.end.dateTime || evt.end.date),
194
+ attendees: evt.attendees?.map((a) => ({
195
+ email: a.email,
196
+ responseStatus: a.responseStatus,
197
+ })),
198
+ status: evt.status,
199
+ recurringEventId: evt.recurringEventId,
200
+ htmlLink: evt.htmlLink,
201
+ };
202
+ },
203
+ async updateEvent(calendarId, eventId, updates) {
204
+ const body = {};
205
+ if (updates.summary !== undefined)
206
+ body.summary = updates.summary;
207
+ if (updates.description !== undefined)
208
+ body.description = updates.description;
209
+ if (updates.location !== undefined)
210
+ body.location = updates.location;
211
+ if (updates.start) {
212
+ body.start = {
213
+ dateTime: updates.start.toISOString(),
214
+ timeZone: 'UTC',
215
+ };
216
+ }
217
+ if (updates.end) {
218
+ body.end = {
219
+ dateTime: updates.end.toISOString(),
220
+ timeZone: 'UTC',
221
+ };
222
+ }
223
+ if (updates.attendees) {
224
+ body.attendees = updates.attendees.map((email) => ({ email }));
225
+ }
226
+ if (updates.reminders) {
227
+ body.reminders = {
228
+ useDefault: false,
229
+ overrides: updates.reminders.map((r) => ({ method: r.method, minutes: r.minutes })),
230
+ };
231
+ }
232
+ if (updates.recurrence) {
233
+ body.recurrence = updates.recurrence;
234
+ }
235
+ const result = await apiRequest(`/calendars/${encodeURIComponent(calendarId)}/events/${encodeURIComponent(eventId)}`, {
236
+ method: 'PATCH',
237
+ body: JSON.stringify(body),
238
+ });
239
+ if (!result.ok || !result.data) {
240
+ throw new Error(result.error || 'Failed to update event');
241
+ }
242
+ const evt = result.data;
243
+ return {
244
+ id: evt.id,
245
+ calendarId,
246
+ summary: evt.summary,
247
+ description: evt.description,
248
+ location: evt.location,
249
+ start: new Date(evt.start.dateTime || evt.start.date),
250
+ end: new Date(evt.end.dateTime || evt.end.date),
251
+ attendees: evt.attendees?.map((a) => ({
252
+ email: a.email,
253
+ responseStatus: a.responseStatus,
254
+ })),
255
+ status: evt.status,
256
+ recurringEventId: evt.recurringEventId,
257
+ htmlLink: evt.htmlLink,
258
+ };
259
+ },
260
+ async deleteEvent(calendarId, eventId) {
261
+ const result = await apiRequest(`/calendars/${encodeURIComponent(calendarId)}/events/${encodeURIComponent(eventId)}`, {
262
+ method: 'DELETE',
263
+ });
264
+ return result.ok;
265
+ },
266
+ async listEvents(calendarId, options) {
267
+ const params = new URLSearchParams();
268
+ if (options?.limit)
269
+ params.append('maxResults', String(options.limit));
270
+ if (options?.cursor)
271
+ params.append('pageToken', options.cursor);
272
+ if (options?.timeMin)
273
+ params.append('timeMin', options.timeMin.toISOString());
274
+ if (options?.timeMax)
275
+ params.append('timeMax', options.timeMax.toISOString());
276
+ if (options?.singleEvents !== undefined)
277
+ params.append('singleEvents', String(options.singleEvents));
278
+ if (options?.orderBy)
279
+ params.append('orderBy', options.orderBy);
280
+ const result = await apiRequest(`/calendars/${encodeURIComponent(calendarId)}/events?${params}`);
281
+ if (!result.ok || !result.data) {
282
+ return { items: [], hasMore: false };
283
+ }
284
+ const items = result.data.items.map((evt) => ({
285
+ id: evt.id,
286
+ calendarId,
287
+ summary: evt.summary,
288
+ description: evt.description,
289
+ location: evt.location,
290
+ start: new Date(evt.start.dateTime || evt.start.date),
291
+ end: new Date(evt.end.dateTime || evt.end.date),
292
+ attendees: evt.attendees?.map((a) => ({
293
+ email: a.email,
294
+ responseStatus: a.responseStatus,
295
+ })),
296
+ status: evt.status,
297
+ recurringEventId: evt.recurringEventId,
298
+ htmlLink: evt.htmlLink,
299
+ }));
300
+ return {
301
+ items,
302
+ hasMore: !!result.data.nextPageToken,
303
+ nextCursor: result.data.nextPageToken,
304
+ };
305
+ },
306
+ async findAvailability(calendarIds, timeMin, timeMax) {
307
+ const body = {
308
+ timeMin: timeMin.toISOString(),
309
+ timeMax: timeMax.toISOString(),
310
+ items: calendarIds.map((id) => ({ id })),
311
+ };
312
+ const result = await apiRequest('/freeBusy', {
313
+ method: 'POST',
314
+ body: JSON.stringify(body),
315
+ });
316
+ if (!result.ok || !result.data) {
317
+ return [];
318
+ }
319
+ return calendarIds.map((calendarId) => {
320
+ const calendar = result.data.calendars[calendarId];
321
+ return {
322
+ calendarId,
323
+ busy: calendar?.busy?.map((slot) => ({
324
+ start: new Date(slot.start),
325
+ end: new Date(slot.end),
326
+ })) || [],
327
+ };
328
+ });
329
+ },
330
+ };
331
+ }
332
+ /**
333
+ * Google Calendar provider definition
334
+ */
335
+ export const googleCalendarProvider = defineProvider(googleCalendarInfo, async (config) => createGoogleCalendarProvider(config));
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Calendar Providers
3
+ *
4
+ * @packageDocumentation
5
+ */
6
+ export { googleCalendarInfo, googleCalendarProvider, createGoogleCalendarProvider } from './google-calendar.js';
7
+ export { calComInfo, calComProvider, createCalComProvider } from './cal-com.js';
8
+ import { googleCalendarProvider } from './google-calendar.js';
9
+ import { calComProvider } from './cal-com.js';
10
+ /**
11
+ * Register all calendar providers
12
+ */
13
+ export function registerCalendarProviders() {
14
+ googleCalendarProvider.register();
15
+ calComProvider.register();
16
+ }
17
+ /**
18
+ * All calendar providers
19
+ */
20
+ export const calendarProviders = [googleCalendarProvider, calComProvider];