digital-tools 2.1.3 → 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 (294) hide show
  1. package/CHANGELOG.md +9 -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 +21 -11
  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 +31 -14
  132. package/src/client.ts +136 -0
  133. package/src/define.ts +30 -24
  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 -4
  199. package/LICENSE +0 -21
  200. package/dist/providers/voice/vapi.d.ts +0 -27
  201. package/dist/providers/voice/vapi.d.ts.map +0 -1
  202. package/dist/providers/voice/vapi.js +0 -440
  203. package/dist/providers/voice/vapi.js.map +0 -1
  204. package/src/define.js +0 -259
  205. package/src/entities/advertising.js +0 -999
  206. package/src/entities/ai.js +0 -756
  207. package/src/entities/analytics.js +0 -1588
  208. package/src/entities/automation.js +0 -601
  209. package/src/entities/communication.js +0 -1150
  210. package/src/entities/crm.js +0 -1386
  211. package/src/entities/design.js +0 -546
  212. package/src/entities/development.js +0 -2212
  213. package/src/entities/document.js +0 -874
  214. package/src/entities/ecommerce.js +0 -1429
  215. package/src/entities/experiment.js +0 -1039
  216. package/src/entities/finance.js +0 -3478
  217. package/src/entities/forms.js +0 -1892
  218. package/src/entities/hr.js +0 -661
  219. package/src/entities/identity.js +0 -997
  220. package/src/entities/index.js +0 -282
  221. package/src/entities/infrastructure.js +0 -1153
  222. package/src/entities/knowledge.js +0 -1438
  223. package/src/entities/marketing.js +0 -1610
  224. package/src/entities/media.js +0 -1634
  225. package/src/entities/notification.js +0 -1199
  226. package/src/entities/presentation.js +0 -1274
  227. package/src/entities/productivity.js +0 -1317
  228. package/src/entities/project-management.js +0 -1136
  229. package/src/entities/recruiting.js +0 -736
  230. package/src/entities/shipping.js +0 -509
  231. package/src/entities/signature.js +0 -1102
  232. package/src/entities/site.js +0 -222
  233. package/src/entities/spreadsheet.js +0 -1341
  234. package/src/entities/storage.js +0 -1198
  235. package/src/entities/support.js +0 -1166
  236. package/src/entities/video-conferencing.js +0 -1750
  237. package/src/entities/video.js +0 -950
  238. package/src/entities.js +0 -1663
  239. package/src/index.js +0 -74
  240. package/src/providers/analytics/index.js +0 -17
  241. package/src/providers/analytics/mixpanel.js +0 -255
  242. package/src/providers/calendar/cal-com.js +0 -303
  243. package/src/providers/calendar/google-calendar.js +0 -335
  244. package/src/providers/calendar/index.js +0 -20
  245. package/src/providers/crm/hubspot.js +0 -566
  246. package/src/providers/crm/index.js +0 -17
  247. package/src/providers/development/github.js +0 -472
  248. package/src/providers/development/index.js +0 -17
  249. package/src/providers/ecommerce/index.js +0 -17
  250. package/src/providers/ecommerce/shopify.js +0 -378
  251. package/src/providers/email/index.js +0 -20
  252. package/src/providers/email/resend.js +0 -258
  253. package/src/providers/email/sendgrid.js +0 -161
  254. package/src/providers/finance/index.js +0 -17
  255. package/src/providers/finance/stripe.js +0 -549
  256. package/src/providers/forms/index.js +0 -17
  257. package/src/providers/forms/typeform.js +0 -500
  258. package/src/providers/index.js +0 -123
  259. package/src/providers/knowledge/index.js +0 -17
  260. package/src/providers/knowledge/notion.js +0 -389
  261. package/src/providers/marketing/index.js +0 -17
  262. package/src/providers/marketing/mailchimp.js +0 -443
  263. package/src/providers/media/cloudinary.js +0 -318
  264. package/src/providers/media/index.js +0 -17
  265. package/src/providers/messaging/index.js +0 -20
  266. package/src/providers/messaging/slack.js +0 -393
  267. package/src/providers/messaging/twilio-sms.js +0 -249
  268. package/src/providers/project-management/index.js +0 -17
  269. package/src/providers/project-management/linear.js +0 -575
  270. package/src/providers/registry.js +0 -86
  271. package/src/providers/spreadsheet/google-sheets.js +0 -375
  272. package/src/providers/spreadsheet/index.js +0 -20
  273. package/src/providers/spreadsheet/xlsx.js +0 -423
  274. package/src/providers/storage/index.js +0 -24
  275. package/src/providers/storage/s3.js +0 -419
  276. package/src/providers/support/index.js +0 -17
  277. package/src/providers/support/zendesk.js +0 -373
  278. package/src/providers/tasks/index.js +0 -17
  279. package/src/providers/tasks/todoist.js +0 -286
  280. package/src/providers/types.js +0 -9
  281. package/src/providers/video-conferencing/google-meet.js +0 -286
  282. package/src/providers/video-conferencing/index.js +0 -31
  283. package/src/providers/video-conferencing/jitsi.js +0 -254
  284. package/src/providers/video-conferencing/teams.js +0 -270
  285. package/src/providers/video-conferencing/zoom.js +0 -332
  286. package/src/registry.js +0 -128
  287. package/src/tools/communication.js +0 -184
  288. package/src/tools/data.js +0 -205
  289. package/src/tools/index.js +0 -11
  290. package/src/tools/web.js +0 -137
  291. package/src/types.js +0 -10
  292. package/test/define.test.js +0 -306
  293. package/test/registry.test.js +0 -357
  294. package/test/tools.test.js +0 -363
@@ -20,6 +20,137 @@ import type {
20
20
  } from '../types.js'
21
21
  import { defineProvider } from '../registry.js'
22
22
 
23
+ // =============================================================================
24
+ // Zendesk API Response Types
25
+ // =============================================================================
26
+
27
+ /**
28
+ * Zendesk API error response
29
+ */
30
+ interface ZendeskErrorResponse {
31
+ error?: string
32
+ description?: string
33
+ details?: Record<string, unknown>
34
+ }
35
+
36
+ /**
37
+ * Zendesk ticket from API
38
+ */
39
+ interface ZendeskTicket {
40
+ id: number
41
+ subject: string
42
+ description: string
43
+ status: string
44
+ priority: string | null
45
+ type: string | null
46
+ requester_id: number | null
47
+ assignee_id: number | null
48
+ tags: string[]
49
+ created_at: string
50
+ updated_at: string
51
+ solved_at: string | null
52
+ }
53
+
54
+ /**
55
+ * Zendesk single ticket response
56
+ */
57
+ interface ZendeskTicketResponse {
58
+ ticket: ZendeskTicket
59
+ }
60
+
61
+ /**
62
+ * Zendesk tickets list response
63
+ */
64
+ interface ZendeskTicketsListResponse {
65
+ tickets: ZendeskTicket[]
66
+ count?: number
67
+ next_page: string | null
68
+ after_cursor?: string
69
+ }
70
+
71
+ /**
72
+ * Zendesk comment from API
73
+ */
74
+ interface ZendeskComment {
75
+ id: number
76
+ body: string
77
+ plain_body?: string
78
+ author_id: number | null
79
+ public: boolean
80
+ created_at: string
81
+ }
82
+
83
+ /**
84
+ * Zendesk comments list response
85
+ */
86
+ interface ZendeskCommentsResponse {
87
+ comments: ZendeskComment[]
88
+ }
89
+
90
+ /**
91
+ * Zendesk audit event
92
+ */
93
+ interface ZendeskAuditEvent {
94
+ type: string
95
+ id?: number
96
+ }
97
+
98
+ /**
99
+ * Zendesk audit from ticket update
100
+ */
101
+ interface ZendeskAudit {
102
+ id?: number
103
+ author_id?: number
104
+ created_at?: string
105
+ events?: ZendeskAuditEvent[]
106
+ }
107
+
108
+ /**
109
+ * Zendesk ticket update response with audit
110
+ */
111
+ interface ZendeskTicketUpdateResponse {
112
+ ticket: ZendeskTicket
113
+ audit?: ZendeskAudit
114
+ }
115
+
116
+ /**
117
+ * Zendesk user from API
118
+ */
119
+ interface ZendeskUser {
120
+ id: number
121
+ name: string
122
+ email: string
123
+ role: string
124
+ created_at: string
125
+ }
126
+
127
+ /**
128
+ * Zendesk single user response
129
+ */
130
+ interface ZendeskUserResponse {
131
+ user: ZendeskUser
132
+ }
133
+
134
+ /**
135
+ * Zendesk users search response
136
+ */
137
+ interface ZendeskUsersSearchResponse {
138
+ users: ZendeskUser[]
139
+ }
140
+
141
+ /**
142
+ * Zendesk ticket update request body
143
+ */
144
+ interface ZendeskTicketUpdateBody {
145
+ subject?: string
146
+ priority?: string
147
+ type?: string
148
+ assignee_id?: string
149
+ tags?: string[]
150
+ custom_fields?: Record<string, unknown>
151
+ comment?: { body: string }
152
+ }
153
+
23
154
  /**
24
155
  * Zendesk provider info
25
156
  */
@@ -47,9 +178,9 @@ export function createZendeskProvider(config: ProviderConfig): SupportProvider {
47
178
  info: zendeskInfo,
48
179
 
49
180
  async initialize(cfg: ProviderConfig): Promise<void> {
50
- subdomain = cfg.subdomain as string
51
- apiKey = cfg.apiKey as string
52
- email = cfg.email as string
181
+ subdomain = cfg['subdomain'] as string
182
+ apiKey = cfg['apiKey'] as string
183
+ email = cfg['email'] as string
53
184
 
54
185
  if (!subdomain || !apiKey || !email) {
55
186
  throw new Error('Zendesk subdomain, API key, and email are required')
@@ -113,14 +244,16 @@ export function createZendeskProvider(config: ProviderConfig): SupportProvider {
113
244
  })
114
245
 
115
246
  if (!response.ok) {
116
- const error = await response.json().catch(() => ({}))
117
- throw new Error((error as any)?.error || `HTTP ${response.status}`)
247
+ const error = (await response.json().catch(() => ({}))) as ZendeskErrorResponse
248
+ throw new Error(error.error || `HTTP ${response.status}`)
118
249
  }
119
250
 
120
- const data = (await response.json()) as any
251
+ const data = (await response.json()) as ZendeskTicketResponse
121
252
  return mapZendeskTicket(data.ticket)
122
253
  } catch (error) {
123
- throw new Error(`Failed to create ticket: ${error instanceof Error ? error.message : 'Unknown error'}`)
254
+ throw new Error(
255
+ `Failed to create ticket: ${error instanceof Error ? error.message : 'Unknown error'}`
256
+ )
124
257
  }
125
258
  },
126
259
 
@@ -138,30 +271,33 @@ export function createZendeskProvider(config: ProviderConfig): SupportProvider {
138
271
  throw new Error(`HTTP ${response.status}`)
139
272
  }
140
273
 
141
- const data = (await response.json()) as any
274
+ const data = (await response.json()) as ZendeskTicketResponse
142
275
  return mapZendeskTicket(data.ticket)
143
276
  } catch {
144
277
  return null
145
278
  }
146
279
  },
147
280
 
148
- async updateTicket(ticketId: string, updates: Partial<CreateTicketOptions>): Promise<TicketData> {
149
- const body: Record<string, unknown> = {
150
- ticket: {
151
- ...(updates.subject && { subject: updates.subject }),
152
- ...(updates.priority && { priority: updates.priority }),
153
- ...(updates.type && { type: updates.type }),
154
- ...(updates.assigneeId && { assignee_id: updates.assigneeId }),
155
- ...(updates.tags && { tags: updates.tags }),
156
- ...(updates.customFields && { custom_fields: updates.customFields }),
157
- },
281
+ async updateTicket(
282
+ ticketId: string,
283
+ updates: Partial<CreateTicketOptions>
284
+ ): Promise<TicketData> {
285
+ const ticketBody: ZendeskTicketUpdateBody = {
286
+ ...(updates.subject && { subject: updates.subject }),
287
+ ...(updates.priority && { priority: updates.priority }),
288
+ ...(updates.type && { type: updates.type }),
289
+ ...(updates.assigneeId && { assignee_id: updates.assigneeId }),
290
+ ...(updates.tags && { tags: updates.tags }),
291
+ ...(updates.customFields && { custom_fields: updates.customFields }),
158
292
  }
159
293
 
160
294
  // Add comment if description is provided
161
295
  if (updates.description) {
162
- (body.ticket as any).comment = { body: updates.description }
296
+ ticketBody.comment = { body: updates.description }
163
297
  }
164
298
 
299
+ const body = { ticket: ticketBody }
300
+
165
301
  try {
166
302
  const response = await fetch(`${baseUrl}/tickets/${ticketId}.json`, {
167
303
  method: 'PUT',
@@ -173,14 +309,16 @@ export function createZendeskProvider(config: ProviderConfig): SupportProvider {
173
309
  })
174
310
 
175
311
  if (!response.ok) {
176
- const error = await response.json().catch(() => ({}))
177
- throw new Error((error as any)?.error || `HTTP ${response.status}`)
312
+ const error = (await response.json().catch(() => ({}))) as ZendeskErrorResponse
313
+ throw new Error(error.error || `HTTP ${response.status}`)
178
314
  }
179
315
 
180
- const data = (await response.json()) as any
316
+ const data = (await response.json()) as ZendeskTicketResponse
181
317
  return mapZendeskTicket(data.ticket)
182
318
  } catch (error) {
183
- throw new Error(`Failed to update ticket: ${error instanceof Error ? error.message : 'Unknown error'}`)
319
+ throw new Error(
320
+ `Failed to update ticket: ${error instanceof Error ? error.message : 'Unknown error'}`
321
+ )
184
322
  }
185
323
  },
186
324
 
@@ -208,17 +346,19 @@ export function createZendeskProvider(config: ProviderConfig): SupportProvider {
208
346
  throw new Error(`HTTP ${response.status}`)
209
347
  }
210
348
 
211
- const data = (await response.json()) as any
349
+ const data = (await response.json()) as ZendeskTicketsListResponse
212
350
  const tickets = (data.tickets || []).map(mapZendeskTicket)
213
351
 
214
352
  return {
215
353
  items: tickets,
216
- total: data.count,
354
+ ...(data.count !== undefined && { total: data.count }),
217
355
  hasMore: data.next_page !== null,
218
- nextCursor: data.after_cursor,
356
+ ...(data.after_cursor !== undefined && { nextCursor: data.after_cursor }),
219
357
  }
220
358
  } catch (error) {
221
- throw new Error(`Failed to list tickets: ${error instanceof Error ? error.message : 'Unknown error'}`)
359
+ throw new Error(
360
+ `Failed to list tickets: ${error instanceof Error ? error.message : 'Unknown error'}`
361
+ )
222
362
  }
223
363
  },
224
364
 
@@ -243,7 +383,11 @@ export function createZendeskProvider(config: ProviderConfig): SupportProvider {
243
383
  }
244
384
  },
245
385
 
246
- async addTicketComment(ticketId: string, body: string, isPublic: boolean = true): Promise<TicketCommentData> {
386
+ async addTicketComment(
387
+ ticketId: string,
388
+ body: string,
389
+ isPublic: boolean = true
390
+ ): Promise<TicketCommentData> {
247
391
  try {
248
392
  const response = await fetch(`${baseUrl}/tickets/${ticketId}.json`, {
249
393
  method: 'PUT',
@@ -262,13 +406,13 @@ export function createZendeskProvider(config: ProviderConfig): SupportProvider {
262
406
  })
263
407
 
264
408
  if (!response.ok) {
265
- const error = await response.json().catch(() => ({}))
266
- throw new Error((error as any)?.error || `HTTP ${response.status}`)
409
+ const error = (await response.json().catch(() => ({}))) as ZendeskErrorResponse
410
+ throw new Error(error.error || `HTTP ${response.status}`)
267
411
  }
268
412
 
269
- const data = (await response.json()) as any
270
- const audit = data.audit || {}
271
- const comment = audit.events?.find((e: any) => e.type === 'Comment')
413
+ const data = (await response.json()) as ZendeskTicketUpdateResponse
414
+ const audit: ZendeskAudit = data.audit || {}
415
+ const comment = audit.events?.find((e: ZendeskAuditEvent) => e.type === 'Comment')
272
416
 
273
417
  return {
274
418
  id: audit.id?.toString() || '',
@@ -279,7 +423,9 @@ export function createZendeskProvider(config: ProviderConfig): SupportProvider {
279
423
  createdAt: new Date(audit.created_at || Date.now()),
280
424
  }
281
425
  } catch (error) {
282
- throw new Error(`Failed to add comment: ${error instanceof Error ? error.message : 'Unknown error'}`)
426
+ throw new Error(
427
+ `Failed to add comment: ${error instanceof Error ? error.message : 'Unknown error'}`
428
+ )
283
429
  }
284
430
  },
285
431
 
@@ -296,8 +442,8 @@ export function createZendeskProvider(config: ProviderConfig): SupportProvider {
296
442
  throw new Error(`HTTP ${response.status}`)
297
443
  }
298
444
 
299
- const data = (await response.json()) as any
300
- return (data.comments || []).map((comment: any) => ({
445
+ const data = (await response.json()) as ZendeskCommentsResponse
446
+ return (data.comments || []).map((comment: ZendeskComment) => ({
301
447
  id: comment.id.toString(),
302
448
  ticketId,
303
449
  body: comment.body || comment.plain_body || '',
@@ -306,7 +452,9 @@ export function createZendeskProvider(config: ProviderConfig): SupportProvider {
306
452
  createdAt: new Date(comment.created_at),
307
453
  }))
308
454
  } catch (error) {
309
- throw new Error(`Failed to list comments: ${error instanceof Error ? error.message : 'Unknown error'}`)
455
+ throw new Error(
456
+ `Failed to list comments: ${error instanceof Error ? error.message : 'Unknown error'}`
457
+ )
310
458
  }
311
459
  },
312
460
 
@@ -324,7 +472,7 @@ export function createZendeskProvider(config: ProviderConfig): SupportProvider {
324
472
  throw new Error(`HTTP ${response.status}`)
325
473
  }
326
474
 
327
- const data = (await response.json()) as any
475
+ const data = (await response.json()) as ZendeskUserResponse
328
476
  return mapZendeskUser(data.user)
329
477
  } catch {
330
478
  return null
@@ -345,10 +493,12 @@ export function createZendeskProvider(config: ProviderConfig): SupportProvider {
345
493
  throw new Error(`HTTP ${response.status}`)
346
494
  }
347
495
 
348
- const data = (await response.json()) as any
496
+ const data = (await response.json()) as ZendeskUsersSearchResponse
349
497
  return (data.users || []).map(mapZendeskUser)
350
498
  } catch (error) {
351
- throw new Error(`Failed to search users: ${error instanceof Error ? error.message : 'Unknown error'}`)
499
+ throw new Error(
500
+ `Failed to search users: ${error instanceof Error ? error.message : 'Unknown error'}`
501
+ )
352
502
  }
353
503
  },
354
504
  }
@@ -357,20 +507,20 @@ export function createZendeskProvider(config: ProviderConfig): SupportProvider {
357
507
  /**
358
508
  * Map Zendesk ticket to TicketData
359
509
  */
360
- function mapZendeskTicket(ticket: any): TicketData {
510
+ function mapZendeskTicket(ticket: ZendeskTicket): TicketData {
361
511
  return {
362
512
  id: ticket.id.toString(),
363
513
  subject: ticket.subject || '',
364
514
  description: ticket.description || '',
365
515
  status: mapZendeskStatus(ticket.status),
366
516
  priority: ticket.priority || 'normal',
367
- type: ticket.type,
368
- requesterId: ticket.requester_id?.toString(),
369
- assigneeId: ticket.assignee_id?.toString(),
517
+ ...(ticket.type !== null && { type: ticket.type }),
518
+ ...(ticket.requester_id !== null && { requesterId: ticket.requester_id.toString() }),
519
+ ...(ticket.assignee_id !== null && { assigneeId: ticket.assignee_id.toString() }),
370
520
  tags: ticket.tags || [],
371
521
  createdAt: new Date(ticket.created_at),
372
522
  updatedAt: new Date(ticket.updated_at),
373
- solvedAt: ticket.solved_at ? new Date(ticket.solved_at) : undefined,
523
+ ...(ticket.solved_at !== null && { solvedAt: new Date(ticket.solved_at) }),
374
524
  }
375
525
  }
376
526
 
@@ -399,7 +549,7 @@ function mapZendeskStatus(status: string): TicketData['status'] {
399
549
  /**
400
550
  * Map Zendesk user to SupportUserData
401
551
  */
402
- function mapZendeskUser(user: any): SupportUserData {
552
+ function mapZendeskUser(user: ZendeskUser): SupportUserData {
403
553
  return {
404
554
  id: user.id.toString(),
405
555
  name: user.name || '',
@@ -100,10 +100,7 @@ export function createTodoistProvider(config: ProviderConfig): TaskProvider {
100
100
  /**
101
101
  * Make authenticated request to Todoist API
102
102
  */
103
- async function todoistRequest<T>(
104
- endpoint: string,
105
- options: RequestInit = {}
106
- ): Promise<T> {
103
+ async function todoistRequest<T>(endpoint: string, options: RequestInit = {}): Promise<T> {
107
104
  const response = await fetch(`${TODOIST_API_URL}${endpoint}`, {
108
105
  ...options,
109
106
  headers: {
@@ -134,7 +131,7 @@ export function createTodoistProvider(config: ProviderConfig): TaskProvider {
134
131
  id: project.id,
135
132
  name: project.name,
136
133
  color: project.color,
137
- parentId: project.parent_id,
134
+ ...(project.parent_id !== undefined && { parentId: project.parent_id }),
138
135
  }
139
136
  }
140
137
 
@@ -154,9 +151,9 @@ export function createTodoistProvider(config: ProviderConfig): TaskProvider {
154
151
  content: task.content,
155
152
  description: task.description,
156
153
  projectId: task.project_id,
157
- parentId: task.parent_id,
154
+ ...(task.parent_id !== undefined && { parentId: task.parent_id }),
158
155
  priority: task.priority,
159
- dueDate,
156
+ ...(dueDate !== undefined && { dueDate }),
160
157
  completed: task.is_completed,
161
158
  labels: task.labels,
162
159
  createdAt: new Date(task.created_at),
@@ -224,33 +221,33 @@ export function createTodoistProvider(config: ProviderConfig): TaskProvider {
224
221
  }
225
222
 
226
223
  if (task.description) {
227
- body.description = task.description
224
+ body['description'] = task.description
228
225
  }
229
226
 
230
227
  if (task.projectId) {
231
- body.project_id = task.projectId
228
+ body['project_id'] = task.projectId
232
229
  }
233
230
 
234
231
  if (task.parentId) {
235
- body.parent_id = task.parentId
232
+ body['parent_id'] = task.parentId
236
233
  }
237
234
 
238
235
  if (task.priority) {
239
- body.priority = task.priority
236
+ body['priority'] = task.priority
240
237
  }
241
238
 
242
239
  if (task.dueDate) {
243
- body.due_date = task.dueDate.toISOString().split('T')[0]
240
+ body['due_date'] = task.dueDate.toISOString().split('T')[0]
244
241
  } else if (task.dueString) {
245
- body.due_string = task.dueString
242
+ body['due_string'] = task.dueString
246
243
  }
247
244
 
248
245
  if (task.labels && task.labels.length > 0) {
249
- body.labels = task.labels
246
+ body['labels'] = task.labels
250
247
  }
251
248
 
252
249
  if (task.assigneeId) {
253
- body.assignee_id = task.assigneeId
250
+ body['assignee_id'] = task.assigneeId
254
251
  }
255
252
 
256
253
  const created = await todoistRequest<TodoistTask>('/tasks', {
@@ -274,36 +271,33 @@ export function createTodoistProvider(config: ProviderConfig): TaskProvider {
274
271
  }
275
272
  },
276
273
 
277
- async updateTask(
278
- taskId: string,
279
- updates: Partial<CreateTaskOptions>
280
- ): Promise<TaskData> {
274
+ async updateTask(taskId: string, updates: Partial<CreateTaskOptions>): Promise<TaskData> {
281
275
  const body: Record<string, unknown> = {}
282
276
 
283
277
  if (updates.content !== undefined) {
284
- body.content = updates.content
278
+ body['content'] = updates.content
285
279
  }
286
280
 
287
281
  if (updates.description !== undefined) {
288
- body.description = updates.description
282
+ body['description'] = updates.description
289
283
  }
290
284
 
291
285
  if (updates.priority !== undefined) {
292
- body.priority = updates.priority
286
+ body['priority'] = updates.priority
293
287
  }
294
288
 
295
289
  if (updates.dueDate) {
296
- body.due_date = updates.dueDate.toISOString().split('T')[0]
290
+ body['due_date'] = updates.dueDate.toISOString().split('T')[0]
297
291
  } else if (updates.dueString) {
298
- body.due_string = updates.dueString
292
+ body['due_string'] = updates.dueString
299
293
  }
300
294
 
301
295
  if (updates.labels !== undefined) {
302
- body.labels = updates.labels
296
+ body['labels'] = updates.labels
303
297
  }
304
298
 
305
299
  if (updates.assigneeId !== undefined) {
306
- body.assignee_id = updates.assigneeId
300
+ body['assignee_id'] = updates.assigneeId
307
301
  }
308
302
 
309
303
  await todoistRequest<void>(`/tasks/${taskId}`, {
@@ -151,10 +151,7 @@ export function createGoogleMeetProvider(config: ProviderConfig): VideoConferenc
151
151
  /**
152
152
  * Make authenticated API request
153
153
  */
154
- async function apiRequest<T>(
155
- endpoint: string,
156
- options: RequestInit = {}
157
- ): Promise<T> {
154
+ async function apiRequest<T>(endpoint: string, options: RequestInit = {}): Promise<T> {
158
155
  const token = await getAccessToken()
159
156
  const url = `${CALENDAR_API_URL}${endpoint}`
160
157
 
@@ -170,7 +167,9 @@ export function createGoogleMeetProvider(config: ProviderConfig): VideoConferenc
170
167
  if (!response.ok) {
171
168
  const errorData = await response.json().catch(() => ({}))
172
169
  throw new Error(
173
- `Google Calendar API error: ${response.status} - ${(errorData as any)?.error?.message || response.statusText}`
170
+ `Google Calendar API error: ${response.status} - ${
171
+ (errorData as any)?.error?.message || response.statusText
172
+ }`
174
173
  )
175
174
  }
176
175
 
@@ -190,8 +189,8 @@ export function createGoogleMeetProvider(config: ProviderConfig): VideoConferenc
190
189
  topic: event.summary,
191
190
  startTime,
192
191
  duration,
193
- timezone: event.start.timeZone,
194
- agenda: event.description,
192
+ ...(event.start.timeZone !== undefined && { timezone: event.start.timeZone }),
193
+ ...(event.description !== undefined && { agenda: event.description }),
195
194
  joinUrl: event.hangoutLink || event.conferenceData?.entryPoints?.[0]?.uri || '',
196
195
  hostId: event.creator?.id || event.creator?.email || '',
197
196
  status: event.status === 'confirmed' ? 'waiting' : 'finished',
@@ -204,8 +203,8 @@ export function createGoogleMeetProvider(config: ProviderConfig): VideoConferenc
204
203
 
205
204
  async initialize(cfg: ProviderConfig): Promise<void> {
206
205
  accessToken = cfg.accessToken as string
207
- clientId = cfg.clientId as string | undefined
208
- clientSecret = cfg.clientSecret as string | undefined
206
+ clientId = cfg['clientId'] as string | undefined
207
+ clientSecret = cfg['clientSecret'] as string | undefined
209
208
  refreshToken = cfg.refreshToken as string | undefined
210
209
 
211
210
  if (!accessToken) {
@@ -213,8 +212,8 @@ export function createGoogleMeetProvider(config: ProviderConfig): VideoConferenc
213
212
  }
214
213
 
215
214
  // Override calendar ID if provided
216
- if (cfg.calendarId) {
217
- calendarId = cfg.calendarId as string
215
+ if (cfg['calendarId']) {
216
+ calendarId = cfg['calendarId'] as string
218
217
  }
219
218
  },
220
219
 
@@ -309,18 +308,18 @@ export function createGoogleMeetProvider(config: ProviderConfig): VideoConferenc
309
308
 
310
309
  const body: Record<string, unknown> = {}
311
310
 
312
- if (updates.topic) body.summary = updates.topic
313
- if (updates.agenda !== undefined) body.description = updates.agenda
311
+ if (updates.topic) body['summary'] = updates.topic
312
+ if (updates.agenda !== undefined) body['description'] = updates.agenda
314
313
 
315
314
  if (updates.startTime) {
316
315
  const endTime = new Date(
317
316
  updates.startTime.getTime() + (updates.duration || current.duration || 60) * 60000
318
317
  )
319
- body.start = {
318
+ body['start'] = {
320
319
  dateTime: updates.startTime.toISOString(),
321
320
  timeZone: updates.timezone || current.timezone || 'UTC',
322
321
  }
323
- body.end = {
322
+ body['end'] = {
324
323
  dateTime: endTime.toISOString(),
325
324
  timeZone: updates.timezone || current.timezone || 'UTC',
326
325
  }
@@ -373,18 +372,16 @@ export function createGoogleMeetProvider(config: ProviderConfig): VideoConferenc
373
372
  )
374
373
 
375
374
  // Filter to only events with Meet links
376
- const meetEvents = response.items.filter(
377
- (event) => event.hangoutLink || event.conferenceData
378
- )
375
+ const meetEvents = response.items.filter((event) => event.hangoutLink || event.conferenceData)
379
376
 
380
377
  return {
381
378
  items: meetEvents.map(convertEvent),
382
379
  hasMore: !!response.nextPageToken,
383
- nextCursor: response.nextPageToken,
380
+ ...(response.nextPageToken !== undefined && { nextCursor: response.nextPageToken }),
384
381
  }
385
382
  },
386
383
 
387
- endMeeting: async function(meetingId: string): Promise<boolean> {
384
+ endMeeting: async function (meetingId: string): Promise<boolean> {
388
385
  // Google Meet doesn't support programmatically ending meetings
389
386
  // We can delete the calendar event instead
390
387
  return await this.deleteMeeting!(meetingId)
@@ -136,14 +136,14 @@ export function createJitsiProvider(config: ProviderConfig): VideoConferencingPr
136
136
  return {
137
137
  id: meeting.id,
138
138
  topic: meeting.topic,
139
- startTime: meeting.startTime,
140
- duration: meeting.duration,
141
- timezone: meeting.timezone,
142
- agenda: meeting.agenda,
139
+ ...(meeting.startTime !== undefined && { startTime: meeting.startTime }),
140
+ ...(meeting.duration !== undefined && { duration: meeting.duration }),
141
+ ...(meeting.timezone !== undefined && { timezone: meeting.timezone }),
142
+ ...(meeting.agenda !== undefined && { agenda: meeting.agenda }),
143
143
  joinUrl: meeting.joinUrl,
144
144
  hostId: meeting.hostId,
145
145
  status: meeting.status,
146
- password: meeting.password,
146
+ ...(meeting.password !== undefined && { password: meeting.password }),
147
147
  createdAt: meeting.createdAt,
148
148
  }
149
149
  }
@@ -152,9 +152,9 @@ export function createJitsiProvider(config: ProviderConfig): VideoConferencingPr
152
152
  info: jitsiInfo,
153
153
 
154
154
  async initialize(cfg: ProviderConfig): Promise<void> {
155
- serverUrl = (cfg.serverUrl as string) || DEFAULT_JITSI_SERVER
156
- jwtSecret = cfg.jwtSecret as string | undefined
157
- hostId = (cfg.hostId as string) || 'default-host'
155
+ serverUrl = (cfg['serverUrl'] as string) || DEFAULT_JITSI_SERVER
156
+ jwtSecret = cfg['jwtSecret'] as string | undefined
157
+ hostId = (cfg['hostId'] as string) || 'default-host'
158
158
 
159
159
  // Remove trailing slash from server URL
160
160
  serverUrl = serverUrl.replace(/\/$/, '')
@@ -202,14 +202,14 @@ export function createJitsiProvider(config: ProviderConfig): VideoConferencingPr
202
202
  const storedMeeting: StoredMeeting = {
203
203
  id,
204
204
  topic: meeting.topic,
205
- startTime: meeting.startTime,
206
- duration: meeting.duration,
207
- timezone: meeting.timezone,
208
- agenda: meeting.agenda,
205
+ ...(meeting.startTime !== undefined && { startTime: meeting.startTime }),
206
+ ...(meeting.duration !== undefined && { duration: meeting.duration }),
207
+ ...(meeting.timezone !== undefined && { timezone: meeting.timezone }),
208
+ ...(meeting.agenda !== undefined && { agenda: meeting.agenda }),
209
209
  joinUrl,
210
210
  hostId,
211
211
  status: 'waiting',
212
- password: meeting.password,
212
+ ...(meeting.password !== undefined && { password: meeting.password }),
213
213
  createdAt: new Date(),
214
214
  roomName,
215
215
  }
@@ -285,7 +285,7 @@ export function createJitsiProvider(config: ProviderConfig): VideoConferencingPr
285
285
  return {
286
286
  items: paginatedItems.map(convertMeeting),
287
287
  hasMore: offset + limit < items.length,
288
- nextCursor: offset + limit < items.length ? (offset + limit).toString() : undefined,
288
+ ...(offset + limit < items.length && { nextCursor: (offset + limit).toString() }),
289
289
  }
290
290
  },
291
291