digital-tools 2.1.1 → 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.
Files changed (293) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +2 -0
  3. package/dist/client.d.ts +109 -0
  4. package/dist/client.d.ts.map +1 -0
  5. package/dist/client.js +69 -0
  6. package/dist/client.js.map +1 -0
  7. package/dist/define.d.ts +2 -2
  8. package/dist/define.d.ts.map +1 -1
  9. package/dist/define.js +22 -20
  10. package/dist/define.js.map +1 -1
  11. package/dist/function-ref.d.ts +229 -0
  12. package/dist/function-ref.d.ts.map +1 -0
  13. package/dist/function-ref.js +28 -0
  14. package/dist/function-ref.js.map +1 -0
  15. package/dist/function-sugar.d.ts +57 -0
  16. package/dist/function-sugar.d.ts.map +1 -0
  17. package/dist/function-sugar.js +79 -0
  18. package/dist/function-sugar.js.map +1 -0
  19. package/dist/index.d.ts +10 -3
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +24 -4
  22. package/dist/index.js.map +1 -1
  23. package/dist/providers/analytics/mixpanel.d.ts.map +1 -1
  24. package/dist/providers/analytics/mixpanel.js +21 -18
  25. package/dist/providers/analytics/mixpanel.js.map +1 -1
  26. package/dist/providers/calendar/cal-com.d.ts.map +1 -1
  27. package/dist/providers/calendar/cal-com.js +10 -10
  28. package/dist/providers/calendar/cal-com.js.map +1 -1
  29. package/dist/providers/calendar/google-calendar.d.ts.map +1 -1
  30. package/dist/providers/calendar/google-calendar.js +4 -4
  31. package/dist/providers/calendar/google-calendar.js.map +1 -1
  32. package/dist/providers/crm/hubspot.d.ts.map +1 -1
  33. package/dist/providers/crm/hubspot.js +107 -85
  34. package/dist/providers/crm/hubspot.js.map +1 -1
  35. package/dist/providers/development/github.d.ts.map +1 -1
  36. package/dist/providers/development/github.js +40 -43
  37. package/dist/providers/development/github.js.map +1 -1
  38. package/dist/providers/ecommerce/shopify.d.ts.map +1 -1
  39. package/dist/providers/ecommerce/shopify.js +79 -62
  40. package/dist/providers/ecommerce/shopify.js.map +1 -1
  41. package/dist/providers/email/resend.d.ts.map +1 -1
  42. package/dist/providers/email/resend.js +20 -16
  43. package/dist/providers/email/resend.js.map +1 -1
  44. package/dist/providers/email/sendgrid.d.ts.map +1 -1
  45. package/dist/providers/email/sendgrid.js +12 -9
  46. package/dist/providers/email/sendgrid.js.map +1 -1
  47. package/dist/providers/finance/stripe.d.ts.map +1 -1
  48. package/dist/providers/finance/stripe.js +44 -42
  49. package/dist/providers/finance/stripe.js.map +1 -1
  50. package/dist/providers/forms/typeform.d.ts.map +1 -1
  51. package/dist/providers/forms/typeform.js +68 -58
  52. package/dist/providers/forms/typeform.js.map +1 -1
  53. package/dist/providers/knowledge/notion.d.ts.map +1 -1
  54. package/dist/providers/knowledge/notion.js +75 -41
  55. package/dist/providers/knowledge/notion.js.map +1 -1
  56. package/dist/providers/marketing/mailchimp.d.ts.map +1 -1
  57. package/dist/providers/marketing/mailchimp.js +74 -61
  58. package/dist/providers/marketing/mailchimp.js.map +1 -1
  59. package/dist/providers/media/cloudinary.d.ts.map +1 -1
  60. package/dist/providers/media/cloudinary.js +30 -28
  61. package/dist/providers/media/cloudinary.js.map +1 -1
  62. package/dist/providers/messaging/slack.d.ts.map +1 -1
  63. package/dist/providers/messaging/slack.js +75 -58
  64. package/dist/providers/messaging/slack.js.map +1 -1
  65. package/dist/providers/messaging/twilio-sms.d.ts.map +1 -1
  66. package/dist/providers/messaging/twilio-sms.js +33 -15
  67. package/dist/providers/messaging/twilio-sms.js.map +1 -1
  68. package/dist/providers/project-management/linear.d.ts.map +1 -1
  69. package/dist/providers/project-management/linear.js +31 -27
  70. package/dist/providers/project-management/linear.js.map +1 -1
  71. package/dist/providers/spreadsheet/google-sheets.d.ts.map +1 -1
  72. package/dist/providers/spreadsheet/google-sheets.js +21 -18
  73. package/dist/providers/spreadsheet/google-sheets.js.map +1 -1
  74. package/dist/providers/spreadsheet/xlsx.d.ts.map +1 -1
  75. package/dist/providers/spreadsheet/xlsx.js +4 -4
  76. package/dist/providers/spreadsheet/xlsx.js.map +1 -1
  77. package/dist/providers/storage/index.js +1 -0
  78. package/dist/providers/storage/index.js.map +1 -1
  79. package/dist/providers/storage/s3.d.ts.map +1 -1
  80. package/dist/providers/storage/s3.js +36 -27
  81. package/dist/providers/storage/s3.js.map +1 -1
  82. package/dist/providers/support/zendesk.d.ts.map +1 -1
  83. package/dist/providers/support/zendesk.js +24 -25
  84. package/dist/providers/support/zendesk.js.map +1 -1
  85. package/dist/providers/tasks/todoist.d.ts.map +1 -1
  86. package/dist/providers/tasks/todoist.js +18 -18
  87. package/dist/providers/tasks/todoist.js.map +1 -1
  88. package/dist/providers/video-conferencing/google-meet.d.ts.map +1 -1
  89. package/dist/providers/video-conferencing/google-meet.js +11 -11
  90. package/dist/providers/video-conferencing/google-meet.js.map +1 -1
  91. package/dist/providers/video-conferencing/jitsi.js +14 -14
  92. package/dist/providers/video-conferencing/jitsi.js.map +1 -1
  93. package/dist/providers/video-conferencing/teams.d.ts.map +1 -1
  94. package/dist/providers/video-conferencing/teams.js +9 -7
  95. package/dist/providers/video-conferencing/teams.js.map +1 -1
  96. package/dist/providers/video-conferencing/zoom.d.ts.map +1 -1
  97. package/dist/providers/video-conferencing/zoom.js +26 -24
  98. package/dist/providers/video-conferencing/zoom.js.map +1 -1
  99. package/dist/tools/data.d.ts.map +1 -1
  100. package/dist/tools/data.js +5 -12
  101. package/dist/tools/data.js.map +1 -1
  102. package/dist/tools/index.d.ts +1 -0
  103. package/dist/tools/index.d.ts.map +1 -1
  104. package/dist/tools/index.js +1 -0
  105. package/dist/tools/index.js.map +1 -1
  106. package/dist/tools/system.d.ts +289 -0
  107. package/dist/tools/system.d.ts.map +1 -0
  108. package/dist/tools/system.js +752 -0
  109. package/dist/tools/system.js.map +1 -0
  110. package/dist/tools/web.d.ts.map +1 -1
  111. package/dist/tools/web.js +22 -10
  112. package/dist/tools/web.js.map +1 -1
  113. package/dist/track-record.d.ts +101 -0
  114. package/dist/track-record.d.ts.map +1 -0
  115. package/dist/track-record.js +17 -0
  116. package/dist/track-record.js.map +1 -0
  117. package/dist/types.d.ts +210 -9
  118. package/dist/types.d.ts.map +1 -1
  119. package/dist/verb-registration.d.ts +122 -0
  120. package/dist/verb-registration.d.ts.map +1 -0
  121. package/dist/verb-registration.js +176 -0
  122. package/dist/verb-registration.js.map +1 -0
  123. package/dist/worker.d.ts +93 -0
  124. package/dist/worker.d.ts.map +1 -0
  125. package/dist/worker.js +315 -0
  126. package/dist/worker.js.map +1 -0
  127. package/dist/wrap.d.ts +89 -0
  128. package/dist/wrap.d.ts.map +1 -0
  129. package/dist/wrap.js +225 -0
  130. package/dist/wrap.js.map +1 -0
  131. package/package.json +21 -4
  132. package/src/client.ts +136 -0
  133. package/src/define.ts +31 -37
  134. package/src/function-ref.ts +264 -0
  135. package/src/function-sugar.ts +134 -0
  136. package/src/index.ts +132 -10
  137. package/src/providers/analytics/mixpanel.ts +19 -18
  138. package/src/providers/calendar/cal-com.ts +29 -18
  139. package/src/providers/calendar/google-calendar.ts +20 -14
  140. package/src/providers/crm/hubspot.ts +225 -99
  141. package/src/providers/development/github.ts +206 -135
  142. package/src/providers/ecommerce/shopify.ts +250 -89
  143. package/src/providers/email/resend.ts +101 -28
  144. package/src/providers/email/sendgrid.ts +12 -9
  145. package/src/providers/finance/stripe.ts +128 -49
  146. package/src/providers/forms/typeform.ts +74 -58
  147. package/src/providers/knowledge/notion.ts +340 -88
  148. package/src/providers/marketing/mailchimp.ts +86 -70
  149. package/src/providers/media/cloudinary.ts +99 -41
  150. package/src/providers/messaging/slack.ts +283 -85
  151. package/src/providers/messaging/twilio-sms.ts +35 -15
  152. package/src/providers/project-management/linear.ts +143 -55
  153. package/src/providers/spreadsheet/google-sheets.ts +222 -56
  154. package/src/providers/spreadsheet/xlsx.ts +47 -16
  155. package/src/providers/storage/s3.ts +119 -47
  156. package/src/providers/support/zendesk.ts +196 -46
  157. package/src/providers/tasks/todoist.ts +20 -26
  158. package/src/providers/video-conferencing/google-meet.ts +17 -20
  159. package/src/providers/video-conferencing/jitsi.ts +14 -14
  160. package/src/providers/video-conferencing/teams.ts +14 -13
  161. package/src/providers/video-conferencing/zoom.ts +54 -49
  162. package/src/tools/data.ts +6 -16
  163. package/src/tools/index.ts +1 -0
  164. package/src/tools/system.ts +887 -0
  165. package/src/tools/web.ts +22 -10
  166. package/src/track-record.ts +106 -0
  167. package/src/types.ts +241 -13
  168. package/src/verb-registration.ts +197 -0
  169. package/src/worker.ts +370 -0
  170. package/src/wrap.ts +260 -0
  171. package/test/client.test.ts +146 -0
  172. package/test/communication-tools-extended.test.ts +734 -0
  173. package/test/data-tools-extended.test.ts +743 -0
  174. package/test/define-extended.test.ts +819 -0
  175. package/test/define.test.ts +150 -41
  176. package/test/entities.test.ts +623 -0
  177. package/test/extended-entities.test.ts +1228 -0
  178. package/test/provider-implementations.test.ts +725 -0
  179. package/test/provider-registry-extended.test.ts +583 -0
  180. package/test/providers/google-sheets.test.ts +851 -0
  181. package/test/providers/helpers.ts +554 -0
  182. package/test/providers/hubspot.test.ts +576 -0
  183. package/test/providers/slack.test.ts +932 -0
  184. package/test/providers/stripe.test.ts +701 -0
  185. package/test/providers.test.ts +578 -0
  186. package/test/system-tools-extended.test.ts +632 -0
  187. package/test/system.test.ts +673 -0
  188. package/test/tools.test.ts +15 -11
  189. package/test/types.test.ts +402 -0
  190. package/test/verb-registration.test.ts +395 -0
  191. package/test/web-tools.test.ts +553 -0
  192. package/test/worker-extended.test.ts +699 -0
  193. package/test/worker.test.ts +576 -0
  194. package/test/wrap.test.ts +366 -0
  195. package/tsconfig.json +3 -13
  196. package/vitest.config.ts +37 -0
  197. package/wrangler.jsonc +9 -0
  198. package/.turbo/turbo-build.log +0 -5
  199. package/dist/providers/voice/vapi.d.ts +0 -27
  200. package/dist/providers/voice/vapi.d.ts.map +0 -1
  201. package/dist/providers/voice/vapi.js +0 -440
  202. package/dist/providers/voice/vapi.js.map +0 -1
  203. package/src/define.js +0 -267
  204. package/src/entities/advertising.js +0 -999
  205. package/src/entities/ai.js +0 -756
  206. package/src/entities/analytics.js +0 -1588
  207. package/src/entities/automation.js +0 -601
  208. package/src/entities/communication.js +0 -1150
  209. package/src/entities/crm.js +0 -1386
  210. package/src/entities/design.js +0 -546
  211. package/src/entities/development.js +0 -2212
  212. package/src/entities/document.js +0 -874
  213. package/src/entities/ecommerce.js +0 -1429
  214. package/src/entities/experiment.js +0 -1039
  215. package/src/entities/finance.js +0 -3478
  216. package/src/entities/forms.js +0 -1892
  217. package/src/entities/hr.js +0 -661
  218. package/src/entities/identity.js +0 -997
  219. package/src/entities/index.js +0 -282
  220. package/src/entities/infrastructure.js +0 -1153
  221. package/src/entities/knowledge.js +0 -1438
  222. package/src/entities/marketing.js +0 -1610
  223. package/src/entities/media.js +0 -1634
  224. package/src/entities/notification.js +0 -1199
  225. package/src/entities/presentation.js +0 -1274
  226. package/src/entities/productivity.js +0 -1317
  227. package/src/entities/project-management.js +0 -1136
  228. package/src/entities/recruiting.js +0 -736
  229. package/src/entities/shipping.js +0 -509
  230. package/src/entities/signature.js +0 -1102
  231. package/src/entities/site.js +0 -222
  232. package/src/entities/spreadsheet.js +0 -1341
  233. package/src/entities/storage.js +0 -1198
  234. package/src/entities/support.js +0 -1166
  235. package/src/entities/video-conferencing.js +0 -1750
  236. package/src/entities/video.js +0 -950
  237. package/src/entities.js +0 -1663
  238. package/src/index.js +0 -74
  239. package/src/providers/analytics/index.js +0 -17
  240. package/src/providers/analytics/mixpanel.js +0 -255
  241. package/src/providers/calendar/cal-com.js +0 -303
  242. package/src/providers/calendar/google-calendar.js +0 -335
  243. package/src/providers/calendar/index.js +0 -20
  244. package/src/providers/crm/hubspot.js +0 -566
  245. package/src/providers/crm/index.js +0 -17
  246. package/src/providers/development/github.js +0 -472
  247. package/src/providers/development/index.js +0 -17
  248. package/src/providers/ecommerce/index.js +0 -17
  249. package/src/providers/ecommerce/shopify.js +0 -378
  250. package/src/providers/email/index.js +0 -20
  251. package/src/providers/email/resend.js +0 -258
  252. package/src/providers/email/sendgrid.js +0 -161
  253. package/src/providers/finance/index.js +0 -17
  254. package/src/providers/finance/stripe.js +0 -549
  255. package/src/providers/forms/index.js +0 -17
  256. package/src/providers/forms/typeform.js +0 -500
  257. package/src/providers/index.js +0 -123
  258. package/src/providers/knowledge/index.js +0 -17
  259. package/src/providers/knowledge/notion.js +0 -389
  260. package/src/providers/marketing/index.js +0 -17
  261. package/src/providers/marketing/mailchimp.js +0 -443
  262. package/src/providers/media/cloudinary.js +0 -318
  263. package/src/providers/media/index.js +0 -17
  264. package/src/providers/messaging/index.js +0 -20
  265. package/src/providers/messaging/slack.js +0 -393
  266. package/src/providers/messaging/twilio-sms.js +0 -249
  267. package/src/providers/project-management/index.js +0 -17
  268. package/src/providers/project-management/linear.js +0 -575
  269. package/src/providers/registry.js +0 -86
  270. package/src/providers/spreadsheet/google-sheets.js +0 -375
  271. package/src/providers/spreadsheet/index.js +0 -20
  272. package/src/providers/spreadsheet/xlsx.js +0 -423
  273. package/src/providers/storage/index.js +0 -24
  274. package/src/providers/storage/s3.js +0 -419
  275. package/src/providers/support/index.js +0 -17
  276. package/src/providers/support/zendesk.js +0 -373
  277. package/src/providers/tasks/index.js +0 -17
  278. package/src/providers/tasks/todoist.js +0 -286
  279. package/src/providers/types.js +0 -9
  280. package/src/providers/video-conferencing/google-meet.js +0 -286
  281. package/src/providers/video-conferencing/index.js +0 -31
  282. package/src/providers/video-conferencing/jitsi.js +0 -254
  283. package/src/providers/video-conferencing/teams.js +0 -270
  284. package/src/providers/video-conferencing/zoom.js +0 -332
  285. package/src/registry.js +0 -128
  286. package/src/tools/communication.js +0 -184
  287. package/src/tools/data.js +0 -205
  288. package/src/tools/index.js +0 -11
  289. package/src/tools/web.js +0 -137
  290. package/src/types.js +0 -10
  291. package/test/define.test.js +0 -306
  292. package/test/registry.test.js +0 -357
  293. package/test/tools.test.js +0 -363
@@ -1,286 +0,0 @@
1
- /**
2
- * Google Meet Video Conferencing Provider
3
- *
4
- * Concrete implementation of VideoConferencingProvider using Google Calendar API v3
5
- * to create and manage Google Meet video conferences.
6
- *
7
- * @packageDocumentation
8
- */
9
- import { defineProvider } from '../registry.js';
10
- const CALENDAR_API_URL = 'https://www.googleapis.com/calendar/v3';
11
- /**
12
- * Google Meet provider info
13
- */
14
- export const googleMeetInfo = {
15
- id: 'meeting.google-meet',
16
- name: 'Google Meet',
17
- description: 'Google Meet video conferencing via Google Calendar API',
18
- category: 'video-conferencing',
19
- website: 'https://meet.google.com',
20
- docsUrl: 'https://developers.google.com/calendar/api',
21
- requiredConfig: ['accessToken'],
22
- optionalConfig: ['clientId', 'clientSecret', 'refreshToken'],
23
- };
24
- /**
25
- * Create Google Meet provider
26
- */
27
- export function createGoogleMeetProvider(config) {
28
- let accessToken;
29
- let clientId;
30
- let clientSecret;
31
- let refreshToken;
32
- let tokenExpiresAt = 0;
33
- let calendarId = 'primary';
34
- /**
35
- * Refresh OAuth access token
36
- */
37
- async function refreshAccessToken() {
38
- if (!clientId || !clientSecret || !refreshToken) {
39
- throw new Error('clientId, clientSecret, and refreshToken required for token refresh');
40
- }
41
- const response = await fetch('https://oauth2.googleapis.com/token', {
42
- method: 'POST',
43
- headers: {
44
- 'Content-Type': 'application/x-www-form-urlencoded',
45
- },
46
- body: new URLSearchParams({
47
- client_id: clientId,
48
- client_secret: clientSecret,
49
- refresh_token: refreshToken,
50
- grant_type: 'refresh_token',
51
- }),
52
- });
53
- if (!response.ok) {
54
- throw new Error(`Failed to refresh access token: HTTP ${response.status}`);
55
- }
56
- const data = (await response.json());
57
- accessToken = data.access_token;
58
- tokenExpiresAt = Date.now() + data.expires_in * 1000;
59
- return accessToken;
60
- }
61
- /**
62
- * Get valid access token
63
- */
64
- async function getAccessToken() {
65
- // Return cached token if still valid (with 5-minute buffer)
66
- if (accessToken && Date.now() < tokenExpiresAt - 300000) {
67
- return accessToken;
68
- }
69
- // Try to refresh if we have refresh token
70
- if (refreshToken) {
71
- return refreshAccessToken();
72
- }
73
- // Otherwise use the provided token
74
- return accessToken;
75
- }
76
- /**
77
- * Make authenticated API request
78
- */
79
- async function apiRequest(endpoint, options = {}) {
80
- const token = await getAccessToken();
81
- const url = `${CALENDAR_API_URL}${endpoint}`;
82
- const response = await fetch(url, {
83
- ...options,
84
- headers: {
85
- Authorization: `Bearer ${token}`,
86
- 'Content-Type': 'application/json',
87
- ...options.headers,
88
- },
89
- });
90
- if (!response.ok) {
91
- const errorData = await response.json().catch(() => ({}));
92
- throw new Error(`Google Calendar API error: ${response.status} - ${errorData?.error?.message || response.statusText}`);
93
- }
94
- return response.json();
95
- }
96
- /**
97
- * Convert Google Calendar event to MeetingData
98
- */
99
- function convertEvent(event) {
100
- const startTime = new Date(event.start.dateTime);
101
- const endTime = new Date(event.end.dateTime);
102
- const duration = Math.round((endTime.getTime() - startTime.getTime()) / 60000); // minutes
103
- return {
104
- id: event.id,
105
- topic: event.summary,
106
- startTime,
107
- duration,
108
- timezone: event.start.timeZone,
109
- agenda: event.description,
110
- joinUrl: event.hangoutLink || event.conferenceData?.entryPoints?.[0]?.uri || '',
111
- hostId: event.creator?.id || event.creator?.email || '',
112
- status: event.status === 'confirmed' ? 'waiting' : 'finished',
113
- createdAt: new Date(event.created),
114
- };
115
- }
116
- return {
117
- info: googleMeetInfo,
118
- async initialize(cfg) {
119
- accessToken = cfg.accessToken;
120
- clientId = cfg.clientId;
121
- clientSecret = cfg.clientSecret;
122
- refreshToken = cfg.refreshToken;
123
- if (!accessToken) {
124
- throw new Error('Google Meet requires accessToken');
125
- }
126
- // Override calendar ID if provided
127
- if (cfg.calendarId) {
128
- calendarId = cfg.calendarId;
129
- }
130
- },
131
- async healthCheck() {
132
- const start = Date.now();
133
- try {
134
- // Get calendar to verify API access
135
- await apiRequest(`/calendars/${calendarId}`);
136
- return {
137
- healthy: true,
138
- latencyMs: Date.now() - start,
139
- message: 'Connected',
140
- checkedAt: new Date(),
141
- };
142
- }
143
- catch (error) {
144
- return {
145
- healthy: false,
146
- latencyMs: Date.now() - start,
147
- message: error instanceof Error ? error.message : 'Unknown error',
148
- checkedAt: new Date(),
149
- };
150
- }
151
- },
152
- async dispose() {
153
- // Clear cached token
154
- accessToken = '';
155
- tokenExpiresAt = 0;
156
- },
157
- async createMeeting(meeting) {
158
- const endTime = meeting.startTime
159
- ? new Date(meeting.startTime.getTime() + (meeting.duration || 60) * 60000)
160
- : new Date(Date.now() + (meeting.duration || 60) * 60000);
161
- const body = {
162
- summary: meeting.topic,
163
- description: meeting.agenda,
164
- start: {
165
- dateTime: (meeting.startTime || new Date()).toISOString(),
166
- timeZone: meeting.timezone || 'UTC',
167
- },
168
- end: {
169
- dateTime: endTime.toISOString(),
170
- timeZone: meeting.timezone || 'UTC',
171
- },
172
- conferenceData: {
173
- createRequest: {
174
- requestId: `meet-${Date.now()}`,
175
- conferenceSolutionKey: {
176
- type: 'hangoutsMeet',
177
- },
178
- },
179
- },
180
- };
181
- const response = await apiRequest(`/calendars/${calendarId}/events?conferenceDataVersion=1`, {
182
- method: 'POST',
183
- body: JSON.stringify(body),
184
- });
185
- return convertEvent(response);
186
- },
187
- async getMeeting(meetingId) {
188
- try {
189
- const response = await apiRequest(`/calendars/${calendarId}/events/${meetingId}`);
190
- return convertEvent(response);
191
- }
192
- catch (error) {
193
- if (error instanceof Error && error.message.includes('404')) {
194
- return null;
195
- }
196
- throw error;
197
- }
198
- },
199
- async updateMeeting(meetingId, updates) {
200
- // First get the current event
201
- const current = await this.getMeeting(meetingId);
202
- if (!current) {
203
- throw new Error(`Meeting ${meetingId} not found`);
204
- }
205
- const body = {};
206
- if (updates.topic)
207
- body.summary = updates.topic;
208
- if (updates.agenda !== undefined)
209
- body.description = updates.agenda;
210
- if (updates.startTime) {
211
- const endTime = new Date(updates.startTime.getTime() + (updates.duration || current.duration || 60) * 60000);
212
- body.start = {
213
- dateTime: updates.startTime.toISOString(),
214
- timeZone: updates.timezone || current.timezone || 'UTC',
215
- };
216
- body.end = {
217
- dateTime: endTime.toISOString(),
218
- timeZone: updates.timezone || current.timezone || 'UTC',
219
- };
220
- }
221
- const response = await apiRequest(`/calendars/${calendarId}/events/${meetingId}`, {
222
- method: 'PATCH',
223
- body: JSON.stringify(body),
224
- });
225
- return convertEvent(response);
226
- },
227
- async deleteMeeting(meetingId) {
228
- try {
229
- await apiRequest(`/calendars/${calendarId}/events/${meetingId}`, {
230
- method: 'DELETE',
231
- });
232
- return true;
233
- }
234
- catch (error) {
235
- if (error instanceof Error && error.message.includes('404')) {
236
- return false;
237
- }
238
- throw error;
239
- }
240
- },
241
- async listMeetings(options = {}) {
242
- const params = new URLSearchParams();
243
- // Set time range based on type
244
- const now = new Date();
245
- if (options.type === 'upcoming' || options.type === 'scheduled') {
246
- params.append('timeMin', now.toISOString());
247
- }
248
- else if (options.type === 'previous') {
249
- params.append('timeMax', now.toISOString());
250
- }
251
- params.append('singleEvents', 'true');
252
- params.append('orderBy', 'startTime');
253
- if (options.limit)
254
- params.append('maxResults', options.limit.toString());
255
- if (options.cursor)
256
- params.append('pageToken', options.cursor);
257
- const response = await apiRequest(`/calendars/${calendarId}/events?${params.toString()}`);
258
- // Filter to only events with Meet links
259
- const meetEvents = response.items.filter((event) => event.hangoutLink || event.conferenceData);
260
- return {
261
- items: meetEvents.map(convertEvent),
262
- hasMore: !!response.nextPageToken,
263
- nextCursor: response.nextPageToken,
264
- };
265
- },
266
- endMeeting: async function (meetingId) {
267
- // Google Meet doesn't support programmatically ending meetings
268
- // We can delete the calendar event instead
269
- return await this.deleteMeeting(meetingId);
270
- },
271
- async getParticipants(meetingId) {
272
- // Google Calendar API doesn't provide participant data for past meetings
273
- // This would require Google Meet API access which is more restricted
274
- return [];
275
- },
276
- async getRecordings(meetingId) {
277
- // Google Meet recordings are stored in Google Drive
278
- // This would require Google Drive API access
279
- return [];
280
- },
281
- };
282
- }
283
- /**
284
- * Google Meet provider definition
285
- */
286
- export const googleMeetProvider = defineProvider(googleMeetInfo, async (config) => createGoogleMeetProvider(config));
@@ -1,31 +0,0 @@
1
- /**
2
- * Video Conferencing Providers
3
- *
4
- * @packageDocumentation
5
- */
6
- export { zoomInfo, zoomProvider, createZoomProvider } from './zoom.js';
7
- export { googleMeetInfo, googleMeetProvider, createGoogleMeetProvider } from './google-meet.js';
8
- export { teamsInfo, teamsProvider, createTeamsProvider } from './teams.js';
9
- export { jitsiInfo, jitsiProvider, createJitsiProvider } from './jitsi.js';
10
- import { zoomProvider } from './zoom.js';
11
- import { googleMeetProvider } from './google-meet.js';
12
- import { teamsProvider } from './teams.js';
13
- import { jitsiProvider } from './jitsi.js';
14
- /**
15
- * Register all video conferencing providers
16
- */
17
- export function registerVideoConferencingProviders() {
18
- zoomProvider.register();
19
- googleMeetProvider.register();
20
- teamsProvider.register();
21
- jitsiProvider.register();
22
- }
23
- /**
24
- * All video conferencing providers
25
- */
26
- export const videoConferencingProviders = [
27
- zoomProvider,
28
- googleMeetProvider,
29
- teamsProvider,
30
- jitsiProvider,
31
- ];
@@ -1,254 +0,0 @@
1
- /**
2
- * Jitsi Meet Video Conferencing Provider
3
- *
4
- * Concrete implementation of VideoConferencingProvider using Jitsi Meet.
5
- * Self-hostable open source video conferencing solution.
6
- *
7
- * @packageDocumentation
8
- */
9
- import { defineProvider } from '../registry.js';
10
- const DEFAULT_JITSI_SERVER = 'https://meet.jit.si';
11
- /**
12
- * Jitsi Meet provider info
13
- */
14
- export const jitsiInfo = {
15
- id: 'meeting.jitsi',
16
- name: 'Jitsi Meet',
17
- description: 'Open source self-hostable video conferencing solution',
18
- category: 'video-conferencing',
19
- website: 'https://jitsi.org',
20
- docsUrl: 'https://jitsi.github.io/handbook/docs/devops-guide/devops-guide-docker',
21
- requiredConfig: [],
22
- optionalConfig: ['serverUrl', 'jwtSecret'],
23
- };
24
- /**
25
- * Create Jitsi Meet provider
26
- */
27
- export function createJitsiProvider(config) {
28
- let serverUrl;
29
- let jwtSecret;
30
- let hostId;
31
- // In-memory storage for meetings
32
- const meetings = new Map();
33
- /**
34
- * Generate a unique room name
35
- */
36
- function generateRoomName(topic) {
37
- // Create URL-safe room name from topic
38
- const safeTopic = topic
39
- .toLowerCase()
40
- .replace(/[^a-z0-9]+/g, '-')
41
- .replace(/^-+|-+$/g, '')
42
- .substring(0, 50);
43
- // Add random suffix to ensure uniqueness
44
- const randomSuffix = Math.random().toString(36).substring(2, 8);
45
- return `${safeTopic}-${randomSuffix}`;
46
- }
47
- /**
48
- * Generate JWT token for secure Jitsi meeting (if JWT is enabled)
49
- */
50
- function generateJWT(roomName, moderator = true) {
51
- if (!jwtSecret) {
52
- return undefined;
53
- }
54
- // Note: In production, you would use a proper JWT library
55
- // This is a simplified placeholder
56
- // In real implementation, use jsonwebtoken package
57
- const header = {
58
- alg: 'HS256',
59
- typ: 'JWT',
60
- };
61
- const payload = {
62
- context: {
63
- user: {
64
- moderator,
65
- id: hostId,
66
- },
67
- },
68
- aud: 'jitsi',
69
- iss: 'jitsi',
70
- sub: serverUrl.replace(/^https?:\/\//, ''),
71
- room: roomName,
72
- exp: Math.floor(Date.now() / 1000) + 3600, // 1 hour expiry
73
- };
74
- // This is a placeholder - in real implementation use proper JWT signing
75
- return `${btoa(JSON.stringify(header))}.${btoa(JSON.stringify(payload))}.signature`;
76
- }
77
- /**
78
- * Build join URL for a Jitsi room
79
- */
80
- function buildJoinUrl(roomName, jwt) {
81
- let url = `${serverUrl}/${roomName}`;
82
- if (jwt) {
83
- url += `?jwt=${jwt}`;
84
- }
85
- return url;
86
- }
87
- /**
88
- * Convert stored meeting to MeetingData
89
- */
90
- function convertMeeting(meeting) {
91
- return {
92
- id: meeting.id,
93
- topic: meeting.topic,
94
- startTime: meeting.startTime,
95
- duration: meeting.duration,
96
- timezone: meeting.timezone,
97
- agenda: meeting.agenda,
98
- joinUrl: meeting.joinUrl,
99
- hostId: meeting.hostId,
100
- status: meeting.status,
101
- password: meeting.password,
102
- createdAt: meeting.createdAt,
103
- };
104
- }
105
- return {
106
- info: jitsiInfo,
107
- async initialize(cfg) {
108
- serverUrl = cfg.serverUrl || DEFAULT_JITSI_SERVER;
109
- jwtSecret = cfg.jwtSecret;
110
- hostId = cfg.hostId || 'default-host';
111
- // Remove trailing slash from server URL
112
- serverUrl = serverUrl.replace(/\/$/, '');
113
- },
114
- async healthCheck() {
115
- const start = Date.now();
116
- try {
117
- // Check if Jitsi server is accessible
118
- const response = await fetch(serverUrl, {
119
- method: 'HEAD',
120
- });
121
- if (!response.ok && response.status !== 404) {
122
- throw new Error(`Server returned status ${response.status}`);
123
- }
124
- return {
125
- healthy: true,
126
- latencyMs: Date.now() - start,
127
- message: 'Connected',
128
- checkedAt: new Date(),
129
- };
130
- }
131
- catch (error) {
132
- return {
133
- healthy: false,
134
- latencyMs: Date.now() - start,
135
- message: error instanceof Error ? error.message : 'Unknown error',
136
- checkedAt: new Date(),
137
- };
138
- }
139
- },
140
- async dispose() {
141
- // Clear all stored meetings
142
- meetings.clear();
143
- },
144
- async createMeeting(meeting) {
145
- const id = `jitsi-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
146
- const roomName = generateRoomName(meeting.topic);
147
- const jwt = generateJWT(roomName, true);
148
- const joinUrl = buildJoinUrl(roomName, jwt);
149
- const storedMeeting = {
150
- id,
151
- topic: meeting.topic,
152
- startTime: meeting.startTime,
153
- duration: meeting.duration,
154
- timezone: meeting.timezone,
155
- agenda: meeting.agenda,
156
- joinUrl,
157
- hostId,
158
- status: 'waiting',
159
- password: meeting.password,
160
- createdAt: new Date(),
161
- roomName,
162
- };
163
- meetings.set(id, storedMeeting);
164
- return convertMeeting(storedMeeting);
165
- },
166
- async getMeeting(meetingId) {
167
- const meeting = meetings.get(meetingId);
168
- return meeting ? convertMeeting(meeting) : null;
169
- },
170
- async updateMeeting(meetingId, updates) {
171
- const meeting = meetings.get(meetingId);
172
- if (!meeting) {
173
- throw new Error(`Meeting ${meetingId} not found`);
174
- }
175
- // Update meeting properties
176
- if (updates.topic)
177
- meeting.topic = updates.topic;
178
- if (updates.startTime !== undefined)
179
- meeting.startTime = updates.startTime;
180
- if (updates.duration !== undefined)
181
- meeting.duration = updates.duration;
182
- if (updates.timezone !== undefined)
183
- meeting.timezone = updates.timezone;
184
- if (updates.agenda !== undefined)
185
- meeting.agenda = updates.agenda;
186
- if (updates.password !== undefined)
187
- meeting.password = updates.password;
188
- // If topic changed, regenerate room name and URL
189
- if (updates.topic) {
190
- meeting.roomName = generateRoomName(updates.topic);
191
- const jwt = generateJWT(meeting.roomName, true);
192
- meeting.joinUrl = buildJoinUrl(meeting.roomName, jwt);
193
- }
194
- meetings.set(meetingId, meeting);
195
- return convertMeeting(meeting);
196
- },
197
- async deleteMeeting(meetingId) {
198
- return meetings.delete(meetingId);
199
- },
200
- async listMeetings(options = {}) {
201
- let items = Array.from(meetings.values());
202
- // Filter by type
203
- const now = new Date();
204
- if (options.type === 'upcoming' || options.type === 'scheduled') {
205
- items = items.filter((m) => m.startTime && m.startTime > now);
206
- }
207
- else if (options.type === 'previous') {
208
- items = items.filter((m) => m.startTime && m.startTime < now);
209
- }
210
- else if (options.type === 'live') {
211
- items = items.filter((m) => m.status === 'started');
212
- }
213
- // Sort by start time
214
- items.sort((a, b) => {
215
- const aTime = a.startTime?.getTime() || 0;
216
- const bTime = b.startTime?.getTime() || 0;
217
- return aTime - bTime;
218
- });
219
- // Apply pagination
220
- const offset = parseInt(options.cursor || '0', 10);
221
- const limit = options.limit || 50;
222
- const paginatedItems = items.slice(offset, offset + limit);
223
- return {
224
- items: paginatedItems.map(convertMeeting),
225
- hasMore: offset + limit < items.length,
226
- nextCursor: offset + limit < items.length ? (offset + limit).toString() : undefined,
227
- };
228
- },
229
- async endMeeting(meetingId) {
230
- const meeting = meetings.get(meetingId);
231
- if (!meeting) {
232
- return false;
233
- }
234
- meeting.status = 'finished';
235
- meetings.set(meetingId, meeting);
236
- return true;
237
- },
238
- async getParticipants(meetingId) {
239
- // Jitsi doesn't provide a built-in API for participant data
240
- // This would require setting up Jitsi Meet API with prosody modules
241
- // or integrating with jitsi-videobridge stats
242
- return [];
243
- },
244
- async getRecordings(meetingId) {
245
- // Jitsi recordings would need to be configured with Jibri
246
- // and would require integration with your recording storage
247
- return [];
248
- },
249
- };
250
- }
251
- /**
252
- * Jitsi Meet provider definition
253
- */
254
- export const jitsiProvider = defineProvider(jitsiInfo, async (config) => createJitsiProvider(config));