digital-tools 2.1.3 → 2.4.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/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +19 -0
  3. package/README.md +2 -0
  4. package/dist/client.d.ts +109 -0
  5. package/dist/client.d.ts.map +1 -0
  6. package/dist/client.js +69 -0
  7. package/dist/client.js.map +1 -0
  8. package/dist/define.d.ts +2 -2
  9. package/dist/define.d.ts.map +1 -1
  10. package/dist/define.js +21 -11
  11. package/dist/define.js.map +1 -1
  12. package/dist/function-ref.d.ts +229 -0
  13. package/dist/function-ref.d.ts.map +1 -0
  14. package/dist/function-ref.js +28 -0
  15. package/dist/function-ref.js.map +1 -0
  16. package/dist/function-sugar.d.ts +57 -0
  17. package/dist/function-sugar.d.ts.map +1 -0
  18. package/dist/function-sugar.js +79 -0
  19. package/dist/function-sugar.js.map +1 -0
  20. package/dist/index.d.ts +10 -3
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +24 -4
  23. package/dist/index.js.map +1 -1
  24. package/dist/providers/analytics/mixpanel.d.ts.map +1 -1
  25. package/dist/providers/analytics/mixpanel.js +21 -18
  26. package/dist/providers/analytics/mixpanel.js.map +1 -1
  27. package/dist/providers/calendar/cal-com.d.ts.map +1 -1
  28. package/dist/providers/calendar/cal-com.js +10 -10
  29. package/dist/providers/calendar/cal-com.js.map +1 -1
  30. package/dist/providers/calendar/google-calendar.d.ts.map +1 -1
  31. package/dist/providers/calendar/google-calendar.js +4 -4
  32. package/dist/providers/calendar/google-calendar.js.map +1 -1
  33. package/dist/providers/crm/hubspot.d.ts.map +1 -1
  34. package/dist/providers/crm/hubspot.js +107 -85
  35. package/dist/providers/crm/hubspot.js.map +1 -1
  36. package/dist/providers/development/github.d.ts.map +1 -1
  37. package/dist/providers/development/github.js +40 -43
  38. package/dist/providers/development/github.js.map +1 -1
  39. package/dist/providers/ecommerce/shopify.d.ts.map +1 -1
  40. package/dist/providers/ecommerce/shopify.js +79 -62
  41. package/dist/providers/ecommerce/shopify.js.map +1 -1
  42. package/dist/providers/email/resend.d.ts.map +1 -1
  43. package/dist/providers/email/resend.js +20 -16
  44. package/dist/providers/email/resend.js.map +1 -1
  45. package/dist/providers/email/sendgrid.d.ts.map +1 -1
  46. package/dist/providers/email/sendgrid.js +12 -9
  47. package/dist/providers/email/sendgrid.js.map +1 -1
  48. package/dist/providers/finance/stripe.d.ts.map +1 -1
  49. package/dist/providers/finance/stripe.js +44 -42
  50. package/dist/providers/finance/stripe.js.map +1 -1
  51. package/dist/providers/forms/typeform.d.ts.map +1 -1
  52. package/dist/providers/forms/typeform.js +68 -58
  53. package/dist/providers/forms/typeform.js.map +1 -1
  54. package/dist/providers/knowledge/notion.d.ts.map +1 -1
  55. package/dist/providers/knowledge/notion.js +75 -41
  56. package/dist/providers/knowledge/notion.js.map +1 -1
  57. package/dist/providers/marketing/mailchimp.d.ts.map +1 -1
  58. package/dist/providers/marketing/mailchimp.js +74 -61
  59. package/dist/providers/marketing/mailchimp.js.map +1 -1
  60. package/dist/providers/media/cloudinary.d.ts.map +1 -1
  61. package/dist/providers/media/cloudinary.js +30 -28
  62. package/dist/providers/media/cloudinary.js.map +1 -1
  63. package/dist/providers/messaging/slack.d.ts.map +1 -1
  64. package/dist/providers/messaging/slack.js +75 -58
  65. package/dist/providers/messaging/slack.js.map +1 -1
  66. package/dist/providers/messaging/twilio-sms.d.ts.map +1 -1
  67. package/dist/providers/messaging/twilio-sms.js +33 -15
  68. package/dist/providers/messaging/twilio-sms.js.map +1 -1
  69. package/dist/providers/project-management/linear.d.ts.map +1 -1
  70. package/dist/providers/project-management/linear.js +31 -27
  71. package/dist/providers/project-management/linear.js.map +1 -1
  72. package/dist/providers/spreadsheet/google-sheets.d.ts.map +1 -1
  73. package/dist/providers/spreadsheet/google-sheets.js +21 -18
  74. package/dist/providers/spreadsheet/google-sheets.js.map +1 -1
  75. package/dist/providers/spreadsheet/xlsx.d.ts.map +1 -1
  76. package/dist/providers/spreadsheet/xlsx.js +4 -4
  77. package/dist/providers/spreadsheet/xlsx.js.map +1 -1
  78. package/dist/providers/storage/index.js +1 -0
  79. package/dist/providers/storage/index.js.map +1 -1
  80. package/dist/providers/storage/s3.d.ts.map +1 -1
  81. package/dist/providers/storage/s3.js +36 -27
  82. package/dist/providers/storage/s3.js.map +1 -1
  83. package/dist/providers/support/zendesk.d.ts.map +1 -1
  84. package/dist/providers/support/zendesk.js +24 -25
  85. package/dist/providers/support/zendesk.js.map +1 -1
  86. package/dist/providers/tasks/todoist.d.ts.map +1 -1
  87. package/dist/providers/tasks/todoist.js +18 -18
  88. package/dist/providers/tasks/todoist.js.map +1 -1
  89. package/dist/providers/video-conferencing/google-meet.d.ts.map +1 -1
  90. package/dist/providers/video-conferencing/google-meet.js +11 -11
  91. package/dist/providers/video-conferencing/google-meet.js.map +1 -1
  92. package/dist/providers/video-conferencing/jitsi.js +14 -14
  93. package/dist/providers/video-conferencing/jitsi.js.map +1 -1
  94. package/dist/providers/video-conferencing/teams.d.ts.map +1 -1
  95. package/dist/providers/video-conferencing/teams.js +9 -7
  96. package/dist/providers/video-conferencing/teams.js.map +1 -1
  97. package/dist/providers/video-conferencing/zoom.d.ts.map +1 -1
  98. package/dist/providers/video-conferencing/zoom.js +26 -24
  99. package/dist/providers/video-conferencing/zoom.js.map +1 -1
  100. package/dist/tools/data.d.ts.map +1 -1
  101. package/dist/tools/data.js +5 -12
  102. package/dist/tools/data.js.map +1 -1
  103. package/dist/tools/index.d.ts +1 -0
  104. package/dist/tools/index.d.ts.map +1 -1
  105. package/dist/tools/index.js +1 -0
  106. package/dist/tools/index.js.map +1 -1
  107. package/dist/tools/system.d.ts +289 -0
  108. package/dist/tools/system.d.ts.map +1 -0
  109. package/dist/tools/system.js +752 -0
  110. package/dist/tools/system.js.map +1 -0
  111. package/dist/tools/web.d.ts.map +1 -1
  112. package/dist/tools/web.js +22 -10
  113. package/dist/tools/web.js.map +1 -1
  114. package/dist/track-record.d.ts +101 -0
  115. package/dist/track-record.d.ts.map +1 -0
  116. package/dist/track-record.js +17 -0
  117. package/dist/track-record.js.map +1 -0
  118. package/dist/types.d.ts +210 -9
  119. package/dist/types.d.ts.map +1 -1
  120. package/dist/verb-registration.d.ts +122 -0
  121. package/dist/verb-registration.d.ts.map +1 -0
  122. package/dist/verb-registration.js +176 -0
  123. package/dist/verb-registration.js.map +1 -0
  124. package/dist/worker.d.ts +93 -0
  125. package/dist/worker.d.ts.map +1 -0
  126. package/dist/worker.js +315 -0
  127. package/dist/worker.js.map +1 -0
  128. package/dist/wrap.d.ts +89 -0
  129. package/dist/wrap.d.ts.map +1 -0
  130. package/dist/wrap.js +225 -0
  131. package/dist/wrap.js.map +1 -0
  132. package/package.json +31 -14
  133. package/src/client.ts +136 -0
  134. package/src/define.ts +30 -24
  135. package/src/function-ref.ts +264 -0
  136. package/src/function-sugar.ts +134 -0
  137. package/src/index.ts +132 -10
  138. package/src/providers/analytics/mixpanel.ts +19 -18
  139. package/src/providers/calendar/cal-com.ts +29 -18
  140. package/src/providers/calendar/google-calendar.ts +20 -14
  141. package/src/providers/crm/hubspot.ts +225 -99
  142. package/src/providers/development/github.ts +206 -135
  143. package/src/providers/ecommerce/shopify.ts +250 -89
  144. package/src/providers/email/resend.ts +101 -28
  145. package/src/providers/email/sendgrid.ts +12 -9
  146. package/src/providers/finance/stripe.ts +128 -49
  147. package/src/providers/forms/typeform.ts +74 -58
  148. package/src/providers/knowledge/notion.ts +340 -88
  149. package/src/providers/marketing/mailchimp.ts +86 -70
  150. package/src/providers/media/cloudinary.ts +99 -41
  151. package/src/providers/messaging/slack.ts +283 -85
  152. package/src/providers/messaging/twilio-sms.ts +35 -15
  153. package/src/providers/project-management/linear.ts +143 -55
  154. package/src/providers/spreadsheet/google-sheets.ts +222 -56
  155. package/src/providers/spreadsheet/xlsx.ts +47 -16
  156. package/src/providers/storage/s3.ts +119 -47
  157. package/src/providers/support/zendesk.ts +196 -46
  158. package/src/providers/tasks/todoist.ts +20 -26
  159. package/src/providers/video-conferencing/google-meet.ts +17 -20
  160. package/src/providers/video-conferencing/jitsi.ts +14 -14
  161. package/src/providers/video-conferencing/teams.ts +14 -13
  162. package/src/providers/video-conferencing/zoom.ts +54 -49
  163. package/src/tools/data.ts +6 -16
  164. package/src/tools/index.ts +1 -0
  165. package/src/tools/system.ts +887 -0
  166. package/src/tools/web.ts +22 -10
  167. package/src/track-record.ts +106 -0
  168. package/src/types.ts +241 -13
  169. package/src/verb-registration.ts +197 -0
  170. package/src/worker.ts +370 -0
  171. package/src/wrap.ts +260 -0
  172. package/test/client.test.ts +146 -0
  173. package/test/communication-tools-extended.test.ts +734 -0
  174. package/test/data-tools-extended.test.ts +743 -0
  175. package/test/define-extended.test.ts +819 -0
  176. package/test/define.test.ts +150 -41
  177. package/test/entities.test.ts +623 -0
  178. package/test/extended-entities.test.ts +1228 -0
  179. package/test/provider-implementations.test.ts +725 -0
  180. package/test/provider-registry-extended.test.ts +583 -0
  181. package/test/providers/google-sheets.test.ts +851 -0
  182. package/test/providers/helpers.ts +554 -0
  183. package/test/providers/hubspot.test.ts +576 -0
  184. package/test/providers/slack.test.ts +932 -0
  185. package/test/providers/stripe.test.ts +701 -0
  186. package/test/providers.test.ts +578 -0
  187. package/test/system-tools-extended.test.ts +632 -0
  188. package/test/system.test.ts +673 -0
  189. package/test/tools.test.ts +15 -11
  190. package/test/types.test.ts +402 -0
  191. package/test/verb-registration.test.ts +395 -0
  192. package/test/web-tools.test.ts +553 -0
  193. package/test/worker-extended.test.ts +699 -0
  194. package/test/worker.test.ts +576 -0
  195. package/test/wrap.test.ts +366 -0
  196. package/tsconfig.json +3 -13
  197. package/vitest.config.ts +37 -0
  198. package/wrangler.jsonc +9 -0
  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
@@ -1,419 +0,0 @@
1
- /**
2
- * AWS S3 Storage Provider
3
- *
4
- * Concrete implementation of StorageProvider using AWS S3 REST API.
5
- *
6
- * @packageDocumentation
7
- */
8
- import { defineProvider } from '../registry.js';
9
- /**
10
- * S3 provider info
11
- */
12
- export const s3Info = {
13
- id: 'storage.s3',
14
- name: 'AWS S3',
15
- description: 'Amazon S3 cloud object storage service',
16
- category: 'storage',
17
- website: 'https://aws.amazon.com/s3/',
18
- docsUrl: 'https://docs.aws.amazon.com/s3/',
19
- requiredConfig: ['accessKeyId', 'secretAccessKey', 'bucket', 'region'],
20
- optionalConfig: ['endpoint', 'baseUrl'],
21
- };
22
- /**
23
- * AWS Signature V4 helper
24
- */
25
- class AwsSignatureV4 {
26
- accessKeyId;
27
- secretAccessKey;
28
- region;
29
- service;
30
- constructor(accessKeyId, secretAccessKey, region, service = 's3') {
31
- this.accessKeyId = accessKeyId;
32
- this.secretAccessKey = secretAccessKey;
33
- this.region = region;
34
- this.service = service;
35
- }
36
- async sha256(data) {
37
- const encoder = new TextEncoder();
38
- return await crypto.subtle.digest('SHA-256', encoder.encode(data));
39
- }
40
- async hmac(key, data) {
41
- const encoder = new TextEncoder();
42
- const cryptoKey = await crypto.subtle.importKey('raw', typeof key === 'string' ? encoder.encode(key) : key, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
43
- return await crypto.subtle.sign('HMAC', cryptoKey, encoder.encode(data));
44
- }
45
- toHex(buffer) {
46
- return Array.from(new Uint8Array(buffer))
47
- .map((b) => b.toString(16).padStart(2, '0'))
48
- .join('');
49
- }
50
- getCanonicalQueryString(params) {
51
- return Object.keys(params)
52
- .sort()
53
- .map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`)
54
- .join('&');
55
- }
56
- async sign(method, path, headers, body, queryParams = {}) {
57
- const now = new Date();
58
- const dateStamp = now.toISOString().slice(0, 10).replace(/-/g, '');
59
- const amzDate = now.toISOString().replace(/[:-]|\.\d{3}/g, '');
60
- // Ensure required headers
61
- const signedHeaders = {
62
- ...headers,
63
- 'x-amz-date': amzDate,
64
- };
65
- if (!signedHeaders['host']) {
66
- signedHeaders['host'] = `${this.service}.${this.region}.amazonaws.com`;
67
- }
68
- // Calculate payload hash
69
- const payloadHash = this.toHex(await this.sha256(body ? (typeof body === 'string' ? body : body.toString()) : ''));
70
- signedHeaders['x-amz-content-sha256'] = payloadHash;
71
- // Create canonical request
72
- const canonicalHeaders = Object.keys(signedHeaders)
73
- .sort()
74
- .map((key) => `${key.toLowerCase()}:${signedHeaders[key].trim()}`)
75
- .join('\n');
76
- const signedHeadersList = Object.keys(signedHeaders)
77
- .sort()
78
- .map((k) => k.toLowerCase())
79
- .join(';');
80
- const canonicalQueryString = this.getCanonicalQueryString(queryParams);
81
- const canonicalRequest = [
82
- method,
83
- path,
84
- canonicalQueryString,
85
- canonicalHeaders,
86
- '',
87
- signedHeadersList,
88
- payloadHash,
89
- ].join('\n');
90
- // Create string to sign
91
- const credentialScope = `${dateStamp}/${this.region}/${this.service}/aws4_request`;
92
- const stringToSign = [
93
- 'AWS4-HMAC-SHA256',
94
- amzDate,
95
- credentialScope,
96
- this.toHex(await this.sha256(canonicalRequest)),
97
- ].join('\n');
98
- // Calculate signature
99
- let key = await this.hmac(`AWS4${this.secretAccessKey}`, dateStamp);
100
- key = await this.hmac(key, this.region);
101
- key = await this.hmac(key, this.service);
102
- key = await this.hmac(key, 'aws4_request');
103
- const signature = this.toHex(await this.hmac(key, stringToSign));
104
- // Add authorization header
105
- signedHeaders['Authorization'] =
106
- `AWS4-HMAC-SHA256 Credential=${this.accessKeyId}/${credentialScope}, ` +
107
- `SignedHeaders=${signedHeadersList}, Signature=${signature}`;
108
- return signedHeaders;
109
- }
110
- }
111
- /**
112
- * Create AWS S3 storage provider
113
- */
114
- export function createS3Provider(config) {
115
- let accessKeyId;
116
- let secretAccessKey;
117
- let bucket;
118
- let region;
119
- let endpoint;
120
- let signer;
121
- return {
122
- info: s3Info,
123
- async initialize(cfg) {
124
- accessKeyId = cfg.accessKeyId;
125
- secretAccessKey = cfg.secretAccessKey;
126
- bucket = cfg.bucket;
127
- region = cfg.region;
128
- endpoint = cfg.endpoint || `https://${bucket}.s3.${region}.amazonaws.com`;
129
- if (!accessKeyId || !secretAccessKey || !bucket || !region) {
130
- throw new Error('S3 requires accessKeyId, secretAccessKey, bucket, and region');
131
- }
132
- signer = new AwsSignatureV4(accessKeyId, secretAccessKey, region, 's3');
133
- },
134
- async healthCheck() {
135
- const start = Date.now();
136
- try {
137
- const headers = await signer.sign('HEAD', '/', { host: `${bucket}.s3.${region}.amazonaws.com` }, null);
138
- const response = await fetch(`${endpoint}/`, {
139
- method: 'HEAD',
140
- headers,
141
- });
142
- return {
143
- healthy: response.ok,
144
- latencyMs: Date.now() - start,
145
- message: response.ok ? 'Connected' : `HTTP ${response.status}`,
146
- checkedAt: new Date(),
147
- };
148
- }
149
- catch (error) {
150
- return {
151
- healthy: false,
152
- latencyMs: Date.now() - start,
153
- message: error instanceof Error ? error.message : 'Unknown error',
154
- checkedAt: new Date(),
155
- };
156
- }
157
- },
158
- async dispose() {
159
- // No cleanup needed
160
- },
161
- async upload(path, content, options) {
162
- try {
163
- const buffer = typeof content === 'string' ? Buffer.from(content) : content;
164
- const headers = {
165
- host: `${bucket}.s3.${region}.amazonaws.com`,
166
- 'content-type': options?.contentType || 'application/octet-stream',
167
- 'content-length': buffer.length.toString(),
168
- };
169
- if (options?.acl) {
170
- headers['x-amz-acl'] = options.acl;
171
- }
172
- if (options?.metadata) {
173
- Object.entries(options.metadata).forEach(([key, value]) => {
174
- headers[`x-amz-meta-${key}`] = value;
175
- });
176
- }
177
- const signedHeaders = await signer.sign('PUT', `/${path}`, headers, buffer);
178
- const response = await fetch(`${endpoint}/${path}`, {
179
- method: 'PUT',
180
- headers: signedHeaders,
181
- body: buffer,
182
- });
183
- if (!response.ok) {
184
- const errorText = await response.text();
185
- throw new Error(`S3 upload failed: ${response.status} ${errorText}`);
186
- }
187
- const etag = response.headers.get('etag')?.replace(/"/g, '');
188
- return {
189
- path,
190
- name: path.split('/').pop() || path,
191
- size: buffer.length,
192
- contentType: options?.contentType,
193
- etag,
194
- lastModified: new Date(),
195
- isFolder: false,
196
- url: `${endpoint}/${path}`,
197
- };
198
- }
199
- catch (error) {
200
- throw new Error(`Failed to upload to S3: ${error instanceof Error ? error.message : 'Unknown error'}`);
201
- }
202
- },
203
- async download(path) {
204
- try {
205
- const headers = await signer.sign('GET', `/${path}`, { host: `${bucket}.s3.${region}.amazonaws.com` }, null);
206
- const response = await fetch(`${endpoint}/${path}`, {
207
- method: 'GET',
208
- headers,
209
- });
210
- if (!response.ok) {
211
- throw new Error(`S3 download failed: ${response.status}`);
212
- }
213
- const arrayBuffer = await response.arrayBuffer();
214
- return Buffer.from(arrayBuffer);
215
- }
216
- catch (error) {
217
- throw new Error(`Failed to download from S3: ${error instanceof Error ? error.message : 'Unknown error'}`);
218
- }
219
- },
220
- async delete(path) {
221
- try {
222
- const headers = await signer.sign('DELETE', `/${path}`, { host: `${bucket}.s3.${region}.amazonaws.com` }, null);
223
- const response = await fetch(`${endpoint}/${path}`, {
224
- method: 'DELETE',
225
- headers,
226
- });
227
- return response.ok || response.status === 204;
228
- }
229
- catch (error) {
230
- throw new Error(`Failed to delete from S3: ${error instanceof Error ? error.message : 'Unknown error'}`);
231
- }
232
- },
233
- async list(prefix = '', options) {
234
- try {
235
- const queryParams = {
236
- 'list-type': '2',
237
- };
238
- if (prefix) {
239
- queryParams.prefix = prefix;
240
- }
241
- if (options?.delimiter) {
242
- queryParams.delimiter = options.delimiter;
243
- }
244
- if (options?.limit) {
245
- queryParams['max-keys'] = options.limit.toString();
246
- }
247
- if (options?.cursor) {
248
- queryParams['continuation-token'] = options.cursor;
249
- }
250
- const headers = await signer.sign('GET', '/', { host: `${bucket}.s3.${region}.amazonaws.com` }, null, queryParams);
251
- const queryString = Object.keys(queryParams)
252
- .map((key) => `${key}=${encodeURIComponent(queryParams[key])}`)
253
- .join('&');
254
- const response = await fetch(`${endpoint}/?${queryString}`, {
255
- method: 'GET',
256
- headers,
257
- });
258
- if (!response.ok) {
259
- throw new Error(`S3 list failed: ${response.status}`);
260
- }
261
- const xmlText = await response.text();
262
- const items = [];
263
- // Parse XML response (simple regex-based parsing for now)
264
- const contentsMatches = xmlText.matchAll(/<Contents>(.*?)<\/Contents>/gs);
265
- for (const match of contentsMatches) {
266
- const content = match[1];
267
- const keyMatch = content.match(/<Key>(.*?)<\/Key>/);
268
- const sizeMatch = content.match(/<Size>(.*?)<\/Size>/);
269
- const lastModifiedMatch = content.match(/<LastModified>(.*?)<\/LastModified>/);
270
- const etagMatch = content.match(/<ETag>(.*?)<\/ETag>/);
271
- if (keyMatch) {
272
- const path = keyMatch[1];
273
- items.push({
274
- path,
275
- name: path.split('/').pop() || path,
276
- size: sizeMatch ? parseInt(sizeMatch[1], 10) : 0,
277
- etag: etagMatch ? etagMatch[1].replace(/"/g, '') : undefined,
278
- lastModified: lastModifiedMatch ? new Date(lastModifiedMatch[1]) : new Date(),
279
- isFolder: false,
280
- url: `${endpoint}/${path}`,
281
- });
282
- }
283
- }
284
- // Parse common prefixes (folders)
285
- const prefixMatches = xmlText.matchAll(/<CommonPrefixes>.*?<Prefix>(.*?)<\/Prefix>.*?<\/CommonPrefixes>/gs);
286
- for (const match of prefixMatches) {
287
- const folderPath = match[1];
288
- items.push({
289
- path: folderPath,
290
- name: folderPath.split('/').filter(Boolean).pop() || folderPath,
291
- size: 0,
292
- lastModified: new Date(),
293
- isFolder: true,
294
- });
295
- }
296
- const isTruncated = xmlText.includes('<IsTruncated>true</IsTruncated>');
297
- const nextTokenMatch = xmlText.match(/<NextContinuationToken>(.*?)<\/NextContinuationToken>/);
298
- return {
299
- items,
300
- hasMore: isTruncated,
301
- nextCursor: nextTokenMatch ? nextTokenMatch[1] : undefined,
302
- };
303
- }
304
- catch (error) {
305
- throw new Error(`Failed to list S3 objects: ${error instanceof Error ? error.message : 'Unknown error'}`);
306
- }
307
- },
308
- async getMetadata(path) {
309
- try {
310
- const headers = await signer.sign('HEAD', `/${path}`, { host: `${bucket}.s3.${region}.amazonaws.com` }, null);
311
- const response = await fetch(`${endpoint}/${path}`, {
312
- method: 'HEAD',
313
- headers,
314
- });
315
- if (!response.ok) {
316
- if (response.status === 404) {
317
- return null;
318
- }
319
- throw new Error(`S3 metadata fetch failed: ${response.status}`);
320
- }
321
- const contentLength = response.headers.get('content-length');
322
- const contentType = response.headers.get('content-type');
323
- const lastModified = response.headers.get('last-modified');
324
- const etag = response.headers.get('etag')?.replace(/"/g, '');
325
- return {
326
- path,
327
- name: path.split('/').pop() || path,
328
- size: contentLength ? parseInt(contentLength, 10) : 0,
329
- contentType: contentType || undefined,
330
- etag,
331
- lastModified: lastModified ? new Date(lastModified) : new Date(),
332
- isFolder: false,
333
- url: `${endpoint}/${path}`,
334
- };
335
- }
336
- catch (error) {
337
- throw new Error(`Failed to get S3 metadata: ${error instanceof Error ? error.message : 'Unknown error'}`);
338
- }
339
- },
340
- async copy(source, destination) {
341
- try {
342
- const headers = await signer.sign('PUT', `/${destination}`, {
343
- host: `${bucket}.s3.${region}.amazonaws.com`,
344
- 'x-amz-copy-source': `/${bucket}/${source}`,
345
- }, null);
346
- const response = await fetch(`${endpoint}/${destination}`, {
347
- method: 'PUT',
348
- headers,
349
- });
350
- if (!response.ok) {
351
- throw new Error(`S3 copy failed: ${response.status}`);
352
- }
353
- // Get metadata of the new file
354
- const metadata = await this.getMetadata(destination);
355
- if (!metadata) {
356
- throw new Error('Failed to get metadata after copy');
357
- }
358
- return metadata;
359
- }
360
- catch (error) {
361
- throw new Error(`Failed to copy in S3: ${error instanceof Error ? error.message : 'Unknown error'}`);
362
- }
363
- },
364
- async move(source, destination) {
365
- try {
366
- // Copy to destination
367
- const metadata = await this.copy(source, destination);
368
- // Delete source
369
- await this.delete(source);
370
- return metadata;
371
- }
372
- catch (error) {
373
- throw new Error(`Failed to move in S3: ${error instanceof Error ? error.message : 'Unknown error'}`);
374
- }
375
- },
376
- async getSignedUrl(path, expiresIn = 3600) {
377
- try {
378
- const now = Math.floor(Date.now() / 1000);
379
- const expires = now + expiresIn;
380
- const queryParams = {
381
- 'X-Amz-Algorithm': 'AWS4-HMAC-SHA256',
382
- 'X-Amz-Credential': `${accessKeyId}/${new Date().toISOString().slice(0, 10).replace(/-/g, '')}/${region}/s3/aws4_request`,
383
- 'X-Amz-Date': new Date().toISOString().replace(/[:-]|\.\d{3}/g, ''),
384
- 'X-Amz-Expires': expiresIn.toString(),
385
- 'X-Amz-SignedHeaders': 'host',
386
- };
387
- const headers = await signer.sign('GET', `/${path}`, { host: `${bucket}.s3.${region}.amazonaws.com` }, null, queryParams);
388
- // Extract signature from Authorization header
389
- const authHeader = headers['Authorization'];
390
- const signatureMatch = authHeader.match(/Signature=([a-f0-9]+)/);
391
- if (signatureMatch) {
392
- queryParams['X-Amz-Signature'] = signatureMatch[1];
393
- }
394
- const queryString = Object.keys(queryParams)
395
- .map((key) => `${key}=${encodeURIComponent(queryParams[key])}`)
396
- .join('&');
397
- return `${endpoint}/${path}?${queryString}`;
398
- }
399
- catch (error) {
400
- throw new Error(`Failed to generate signed URL: ${error instanceof Error ? error.message : 'Unknown error'}`);
401
- }
402
- },
403
- async createFolder(path) {
404
- try {
405
- // S3 doesn't have real folders, but we can create an empty object with trailing slash
406
- const folderPath = path.endsWith('/') ? path : `${path}/`;
407
- await this.upload(folderPath, Buffer.from(''), { contentType: 'application/x-directory' });
408
- return true;
409
- }
410
- catch (error) {
411
- throw new Error(`Failed to create folder in S3: ${error instanceof Error ? error.message : 'Unknown error'}`);
412
- }
413
- },
414
- };
415
- }
416
- /**
417
- * S3 provider definition
418
- */
419
- export const s3Provider = defineProvider(s3Info, async (config) => createS3Provider(config));
@@ -1,17 +0,0 @@
1
- /**
2
- * Support Providers
3
- *
4
- * @packageDocumentation
5
- */
6
- export { zendeskInfo, zendeskProvider, createZendeskProvider } from './zendesk.js';
7
- import { zendeskProvider } from './zendesk.js';
8
- /**
9
- * Register all support providers
10
- */
11
- export function registerSupportProviders() {
12
- zendeskProvider.register();
13
- }
14
- /**
15
- * All support providers
16
- */
17
- export const supportProviders = [zendeskProvider];