digital-tools 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +5 -0
- package/CHANGELOG.md +9 -0
- package/README.md +1144 -0
- package/dist/define.d.ts +109 -0
- package/dist/define.d.ts.map +1 -0
- package/dist/define.js +268 -0
- package/dist/define.js.map +1 -0
- package/dist/entities/advertising.d.ts +79 -0
- package/dist/entities/advertising.d.ts.map +1 -0
- package/dist/entities/advertising.js +1000 -0
- package/dist/entities/advertising.js.map +1 -0
- package/dist/entities/ai.d.ts +69 -0
- package/dist/entities/ai.d.ts.map +1 -0
- package/dist/entities/ai.js +757 -0
- package/dist/entities/ai.js.map +1 -0
- package/dist/entities/analytics.d.ts +83 -0
- package/dist/entities/analytics.d.ts.map +1 -0
- package/dist/entities/analytics.js +1589 -0
- package/dist/entities/analytics.js.map +1 -0
- package/dist/entities/automation.d.ts +61 -0
- package/dist/entities/automation.d.ts.map +1 -0
- package/dist/entities/automation.js +602 -0
- package/dist/entities/automation.js.map +1 -0
- package/dist/entities/communication.d.ts +96 -0
- package/dist/entities/communication.d.ts.map +1 -0
- package/dist/entities/communication.js +1151 -0
- package/dist/entities/communication.js.map +1 -0
- package/dist/entities/crm.d.ts +91 -0
- package/dist/entities/crm.d.ts.map +1 -0
- package/dist/entities/crm.js +1387 -0
- package/dist/entities/crm.js.map +1 -0
- package/dist/entities/design.d.ts +61 -0
- package/dist/entities/design.d.ts.map +1 -0
- package/dist/entities/design.js +547 -0
- package/dist/entities/design.js.map +1 -0
- package/dist/entities/development.d.ts +145 -0
- package/dist/entities/development.d.ts.map +1 -0
- package/dist/entities/development.js +2213 -0
- package/dist/entities/development.js.map +1 -0
- package/dist/entities/document.d.ts +54 -0
- package/dist/entities/document.d.ts.map +1 -0
- package/dist/entities/document.js +875 -0
- package/dist/entities/document.js.map +1 -0
- package/dist/entities/ecommerce.d.ts +93 -0
- package/dist/entities/ecommerce.d.ts.map +1 -0
- package/dist/entities/ecommerce.js +1430 -0
- package/dist/entities/ecommerce.js.map +1 -0
- package/dist/entities/experiment.d.ts +89 -0
- package/dist/entities/experiment.d.ts.map +1 -0
- package/dist/entities/experiment.js +1040 -0
- package/dist/entities/experiment.js.map +1 -0
- package/dist/entities/finance.d.ts +272 -0
- package/dist/entities/finance.d.ts.map +1 -0
- package/dist/entities/finance.js +3479 -0
- package/dist/entities/finance.js.map +1 -0
- package/dist/entities/forms.d.ts +91 -0
- package/dist/entities/forms.d.ts.map +1 -0
- package/dist/entities/forms.js +1893 -0
- package/dist/entities/forms.js.map +1 -0
- package/dist/entities/hr.d.ts +62 -0
- package/dist/entities/hr.d.ts.map +1 -0
- package/dist/entities/hr.js +662 -0
- package/dist/entities/hr.js.map +1 -0
- package/dist/entities/identity.d.ts +90 -0
- package/dist/entities/identity.d.ts.map +1 -0
- package/dist/entities/identity.js +998 -0
- package/dist/entities/identity.js.map +1 -0
- package/dist/entities/index.d.ts +410 -0
- package/dist/entities/index.d.ts.map +1 -0
- package/dist/entities/index.js +283 -0
- package/dist/entities/index.js.map +1 -0
- package/dist/entities/infrastructure.d.ts +98 -0
- package/dist/entities/infrastructure.d.ts.map +1 -0
- package/dist/entities/infrastructure.js +1154 -0
- package/dist/entities/infrastructure.js.map +1 -0
- package/dist/entities/knowledge.d.ts +98 -0
- package/dist/entities/knowledge.d.ts.map +1 -0
- package/dist/entities/knowledge.js +1439 -0
- package/dist/entities/knowledge.js.map +1 -0
- package/dist/entities/marketing.d.ts +82 -0
- package/dist/entities/marketing.d.ts.map +1 -0
- package/dist/entities/marketing.js +1611 -0
- package/dist/entities/marketing.js.map +1 -0
- package/dist/entities/media.d.ts +83 -0
- package/dist/entities/media.d.ts.map +1 -0
- package/dist/entities/media.js +1635 -0
- package/dist/entities/media.js.map +1 -0
- package/dist/entities/notification.d.ts +76 -0
- package/dist/entities/notification.d.ts.map +1 -0
- package/dist/entities/notification.js +1200 -0
- package/dist/entities/notification.js.map +1 -0
- package/dist/entities/presentation.d.ts +61 -0
- package/dist/entities/presentation.d.ts.map +1 -0
- package/dist/entities/presentation.js +1275 -0
- package/dist/entities/presentation.js.map +1 -0
- package/dist/entities/productivity.d.ts +92 -0
- package/dist/entities/productivity.d.ts.map +1 -0
- package/dist/entities/productivity.js +1318 -0
- package/dist/entities/productivity.js.map +1 -0
- package/dist/entities/project-management.d.ts +89 -0
- package/dist/entities/project-management.d.ts.map +1 -0
- package/dist/entities/project-management.js +1137 -0
- package/dist/entities/project-management.js.map +1 -0
- package/dist/entities/recruiting.d.ts +54 -0
- package/dist/entities/recruiting.d.ts.map +1 -0
- package/dist/entities/recruiting.js +737 -0
- package/dist/entities/recruiting.js.map +1 -0
- package/dist/entities/shipping.d.ts +52 -0
- package/dist/entities/shipping.d.ts.map +1 -0
- package/dist/entities/shipping.js +510 -0
- package/dist/entities/shipping.js.map +1 -0
- package/dist/entities/signature.d.ts +83 -0
- package/dist/entities/signature.d.ts.map +1 -0
- package/dist/entities/signature.js +1103 -0
- package/dist/entities/signature.js.map +1 -0
- package/dist/entities/site.d.ts +33 -0
- package/dist/entities/site.d.ts.map +1 -0
- package/dist/entities/site.js +223 -0
- package/dist/entities/site.js.map +1 -0
- package/dist/entities/spreadsheet.d.ts +68 -0
- package/dist/entities/spreadsheet.d.ts.map +1 -0
- package/dist/entities/spreadsheet.js +1342 -0
- package/dist/entities/spreadsheet.js.map +1 -0
- package/dist/entities/storage.d.ts +74 -0
- package/dist/entities/storage.d.ts.map +1 -0
- package/dist/entities/storage.js +1199 -0
- package/dist/entities/storage.js.map +1 -0
- package/dist/entities/support.d.ts +83 -0
- package/dist/entities/support.d.ts.map +1 -0
- package/dist/entities/support.js +1167 -0
- package/dist/entities/support.js.map +1 -0
- package/dist/entities/video-conferencing.d.ts +129 -0
- package/dist/entities/video-conferencing.d.ts.map +1 -0
- package/dist/entities/video-conferencing.js +1751 -0
- package/dist/entities/video-conferencing.js.map +1 -0
- package/dist/entities/video.d.ts +76 -0
- package/dist/entities/video.d.ts.map +1 -0
- package/dist/entities/video.js +951 -0
- package/dist/entities/video.js.map +1 -0
- package/dist/entities.d.ts +147 -0
- package/dist/entities.d.ts.map +1 -0
- package/dist/entities.js +1664 -0
- package/dist/entities.js.map +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +75 -0
- package/dist/index.js.map +1 -0
- package/dist/providers/analytics/index.d.ts +19 -0
- package/dist/providers/analytics/index.d.ts.map +1 -0
- package/dist/providers/analytics/index.js +18 -0
- package/dist/providers/analytics/index.js.map +1 -0
- package/dist/providers/analytics/mixpanel.d.ts +25 -0
- package/dist/providers/analytics/mixpanel.d.ts.map +1 -0
- package/dist/providers/analytics/mixpanel.js +256 -0
- package/dist/providers/analytics/mixpanel.js.map +1 -0
- package/dist/providers/calendar/cal-com.d.ts +26 -0
- package/dist/providers/calendar/cal-com.d.ts.map +1 -0
- package/dist/providers/calendar/cal-com.js +304 -0
- package/dist/providers/calendar/cal-com.js.map +1 -0
- package/dist/providers/calendar/google-calendar.d.ts +25 -0
- package/dist/providers/calendar/google-calendar.d.ts.map +1 -0
- package/dist/providers/calendar/google-calendar.js +336 -0
- package/dist/providers/calendar/google-calendar.js.map +1 -0
- package/dist/providers/calendar/index.d.ts +20 -0
- package/dist/providers/calendar/index.d.ts.map +1 -0
- package/dist/providers/calendar/index.js +21 -0
- package/dist/providers/calendar/index.js.map +1 -0
- package/dist/providers/crm/hubspot.d.ts +25 -0
- package/dist/providers/crm/hubspot.d.ts.map +1 -0
- package/dist/providers/crm/hubspot.js +567 -0
- package/dist/providers/crm/hubspot.js.map +1 -0
- package/dist/providers/crm/index.d.ts +19 -0
- package/dist/providers/crm/index.d.ts.map +1 -0
- package/dist/providers/crm/index.js +18 -0
- package/dist/providers/crm/index.js.map +1 -0
- package/dist/providers/development/github.d.ts +25 -0
- package/dist/providers/development/github.d.ts.map +1 -0
- package/dist/providers/development/github.js +473 -0
- package/dist/providers/development/github.js.map +1 -0
- package/dist/providers/development/index.d.ts +19 -0
- package/dist/providers/development/index.d.ts.map +1 -0
- package/dist/providers/development/index.js +18 -0
- package/dist/providers/development/index.js.map +1 -0
- package/dist/providers/ecommerce/index.d.ts +19 -0
- package/dist/providers/ecommerce/index.d.ts.map +1 -0
- package/dist/providers/ecommerce/index.js +18 -0
- package/dist/providers/ecommerce/index.js.map +1 -0
- package/dist/providers/ecommerce/shopify.d.ts +25 -0
- package/dist/providers/ecommerce/shopify.d.ts.map +1 -0
- package/dist/providers/ecommerce/shopify.js +379 -0
- package/dist/providers/ecommerce/shopify.js.map +1 -0
- package/dist/providers/email/index.d.ts +20 -0
- package/dist/providers/email/index.d.ts.map +1 -0
- package/dist/providers/email/index.js +21 -0
- package/dist/providers/email/index.js.map +1 -0
- package/dist/providers/email/resend.d.ts +25 -0
- package/dist/providers/email/resend.d.ts.map +1 -0
- package/dist/providers/email/resend.js +259 -0
- package/dist/providers/email/resend.js.map +1 -0
- package/dist/providers/email/sendgrid.d.ts +25 -0
- package/dist/providers/email/sendgrid.d.ts.map +1 -0
- package/dist/providers/email/sendgrid.js +162 -0
- package/dist/providers/email/sendgrid.js.map +1 -0
- package/dist/providers/finance/index.d.ts +19 -0
- package/dist/providers/finance/index.d.ts.map +1 -0
- package/dist/providers/finance/index.js +18 -0
- package/dist/providers/finance/index.js.map +1 -0
- package/dist/providers/finance/stripe.d.ts +25 -0
- package/dist/providers/finance/stripe.d.ts.map +1 -0
- package/dist/providers/finance/stripe.js +550 -0
- package/dist/providers/finance/stripe.js.map +1 -0
- package/dist/providers/forms/index.d.ts +19 -0
- package/dist/providers/forms/index.d.ts.map +1 -0
- package/dist/providers/forms/index.js +18 -0
- package/dist/providers/forms/index.js.map +1 -0
- package/dist/providers/forms/typeform.d.ts +25 -0
- package/dist/providers/forms/typeform.d.ts.map +1 -0
- package/dist/providers/forms/typeform.js +501 -0
- package/dist/providers/forms/typeform.js.map +1 -0
- package/dist/providers/index.d.ts +56 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +124 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/knowledge/index.d.ts +19 -0
- package/dist/providers/knowledge/index.d.ts.map +1 -0
- package/dist/providers/knowledge/index.js +18 -0
- package/dist/providers/knowledge/index.js.map +1 -0
- package/dist/providers/knowledge/notion.d.ts +25 -0
- package/dist/providers/knowledge/notion.d.ts.map +1 -0
- package/dist/providers/knowledge/notion.js +390 -0
- package/dist/providers/knowledge/notion.js.map +1 -0
- package/dist/providers/marketing/index.d.ts +19 -0
- package/dist/providers/marketing/index.d.ts.map +1 -0
- package/dist/providers/marketing/index.js +18 -0
- package/dist/providers/marketing/index.js.map +1 -0
- package/dist/providers/marketing/mailchimp.d.ts +25 -0
- package/dist/providers/marketing/mailchimp.d.ts.map +1 -0
- package/dist/providers/marketing/mailchimp.js +444 -0
- package/dist/providers/marketing/mailchimp.js.map +1 -0
- package/dist/providers/media/cloudinary.d.ts +25 -0
- package/dist/providers/media/cloudinary.d.ts.map +1 -0
- package/dist/providers/media/cloudinary.js +319 -0
- package/dist/providers/media/cloudinary.js.map +1 -0
- package/dist/providers/media/index.d.ts +19 -0
- package/dist/providers/media/index.d.ts.map +1 -0
- package/dist/providers/media/index.js +18 -0
- package/dist/providers/media/index.js.map +1 -0
- package/dist/providers/messaging/index.d.ts +24 -0
- package/dist/providers/messaging/index.d.ts.map +1 -0
- package/dist/providers/messaging/index.js +21 -0
- package/dist/providers/messaging/index.js.map +1 -0
- package/dist/providers/messaging/slack.d.ts +25 -0
- package/dist/providers/messaging/slack.d.ts.map +1 -0
- package/dist/providers/messaging/slack.js +394 -0
- package/dist/providers/messaging/slack.js.map +1 -0
- package/dist/providers/messaging/twilio-sms.d.ts +25 -0
- package/dist/providers/messaging/twilio-sms.d.ts.map +1 -0
- package/dist/providers/messaging/twilio-sms.js +250 -0
- package/dist/providers/messaging/twilio-sms.js.map +1 -0
- package/dist/providers/project-management/index.d.ts +19 -0
- package/dist/providers/project-management/index.d.ts.map +1 -0
- package/dist/providers/project-management/index.js +18 -0
- package/dist/providers/project-management/index.js.map +1 -0
- package/dist/providers/project-management/linear.d.ts +25 -0
- package/dist/providers/project-management/linear.d.ts.map +1 -0
- package/dist/providers/project-management/linear.js +576 -0
- package/dist/providers/project-management/linear.js.map +1 -0
- package/dist/providers/registry.d.ts +41 -0
- package/dist/providers/registry.d.ts.map +1 -0
- package/dist/providers/registry.js +87 -0
- package/dist/providers/registry.js.map +1 -0
- package/dist/providers/spreadsheet/google-sheets.d.ts +25 -0
- package/dist/providers/spreadsheet/google-sheets.d.ts.map +1 -0
- package/dist/providers/spreadsheet/google-sheets.js +376 -0
- package/dist/providers/spreadsheet/google-sheets.js.map +1 -0
- package/dist/providers/spreadsheet/index.d.ts +20 -0
- package/dist/providers/spreadsheet/index.d.ts.map +1 -0
- package/dist/providers/spreadsheet/index.js +21 -0
- package/dist/providers/spreadsheet/index.js.map +1 -0
- package/dist/providers/spreadsheet/xlsx.d.ts +26 -0
- package/dist/providers/spreadsheet/xlsx.d.ts.map +1 -0
- package/dist/providers/spreadsheet/xlsx.js +424 -0
- package/dist/providers/spreadsheet/xlsx.js.map +1 -0
- package/dist/providers/storage/index.d.ts +30 -0
- package/dist/providers/storage/index.d.ts.map +1 -0
- package/dist/providers/storage/index.js +25 -0
- package/dist/providers/storage/index.js.map +1 -0
- package/dist/providers/storage/s3.d.ts +25 -0
- package/dist/providers/storage/s3.d.ts.map +1 -0
- package/dist/providers/storage/s3.js +420 -0
- package/dist/providers/storage/s3.js.map +1 -0
- package/dist/providers/support/index.d.ts +19 -0
- package/dist/providers/support/index.d.ts.map +1 -0
- package/dist/providers/support/index.js +18 -0
- package/dist/providers/support/index.js.map +1 -0
- package/dist/providers/support/zendesk.d.ts +25 -0
- package/dist/providers/support/zendesk.d.ts.map +1 -0
- package/dist/providers/support/zendesk.js +374 -0
- package/dist/providers/support/zendesk.js.map +1 -0
- package/dist/providers/tasks/index.d.ts +19 -0
- package/dist/providers/tasks/index.d.ts.map +1 -0
- package/dist/providers/tasks/index.js +18 -0
- package/dist/providers/tasks/index.js.map +1 -0
- package/dist/providers/tasks/todoist.d.ts +25 -0
- package/dist/providers/tasks/todoist.d.ts.map +1 -0
- package/dist/providers/tasks/todoist.js +287 -0
- package/dist/providers/tasks/todoist.js.map +1 -0
- package/dist/providers/types.d.ts +1753 -0
- package/dist/providers/types.d.ts.map +1 -0
- package/dist/providers/types.js +10 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/providers/video-conferencing/google-meet.d.ts +26 -0
- package/dist/providers/video-conferencing/google-meet.d.ts.map +1 -0
- package/dist/providers/video-conferencing/google-meet.js +287 -0
- package/dist/providers/video-conferencing/google-meet.js.map +1 -0
- package/dist/providers/video-conferencing/index.d.ts +22 -0
- package/dist/providers/video-conferencing/index.d.ts.map +1 -0
- package/dist/providers/video-conferencing/index.js +32 -0
- package/dist/providers/video-conferencing/index.js.map +1 -0
- package/dist/providers/video-conferencing/jitsi.d.ts +26 -0
- package/dist/providers/video-conferencing/jitsi.d.ts.map +1 -0
- package/dist/providers/video-conferencing/jitsi.js +255 -0
- package/dist/providers/video-conferencing/jitsi.js.map +1 -0
- package/dist/providers/video-conferencing/teams.d.ts +26 -0
- package/dist/providers/video-conferencing/teams.d.ts.map +1 -0
- package/dist/providers/video-conferencing/teams.js +271 -0
- package/dist/providers/video-conferencing/teams.js.map +1 -0
- package/dist/providers/video-conferencing/zoom.d.ts +25 -0
- package/dist/providers/video-conferencing/zoom.d.ts.map +1 -0
- package/dist/providers/video-conferencing/zoom.js +333 -0
- package/dist/providers/video-conferencing/zoom.js.map +1 -0
- package/dist/providers/voice/vapi.d.ts +27 -0
- package/dist/providers/voice/vapi.d.ts.map +1 -0
- package/dist/providers/voice/vapi.js +440 -0
- package/dist/providers/voice/vapi.js.map +1 -0
- package/dist/registry.d.ts +38 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +129 -0
- package/dist/registry.js.map +1 -0
- package/dist/tools/communication.d.ts +94 -0
- package/dist/tools/communication.d.ts.map +1 -0
- package/dist/tools/communication.js +185 -0
- package/dist/tools/communication.js.map +1 -0
- package/dist/tools/data.d.ts +61 -0
- package/dist/tools/data.d.ts.map +1 -0
- package/dist/tools/data.js +206 -0
- package/dist/tools/data.js.map +1 -0
- package/dist/tools/index.d.ts +12 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +12 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/web.d.ts +45 -0
- package/dist/tools/web.d.ts.map +1 -0
- package/dist/tools/web.js +138 -0
- package/dist/tools/web.js.map +1 -0
- package/dist/types.d.ts +330 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +11 -0
- package/dist/types.js.map +1 -0
- package/package.json +45 -0
- package/src/define.ts +321 -0
- package/src/entities/advertising.ts +1086 -0
- package/src/entities/ai.ts +835 -0
- package/src/entities/analytics.ts +1690 -0
- package/src/entities/automation.ts +669 -0
- package/src/entities/communication.ts +1255 -0
- package/src/entities/crm.ts +1481 -0
- package/src/entities/design.ts +606 -0
- package/src/entities/development.ts +2392 -0
- package/src/entities/document.ts +930 -0
- package/src/entities/ecommerce.ts +1539 -0
- package/src/entities/experiment.ts +1139 -0
- package/src/entities/finance.ts +3907 -0
- package/src/entities/forms.ts +2021 -0
- package/src/entities/hr.ts +725 -0
- package/src/entities/identity.ts +1093 -0
- package/src/entities/index.ts +731 -0
- package/src/entities/infrastructure.ts +1254 -0
- package/src/entities/knowledge.ts +1547 -0
- package/src/entities/marketing.ts +1718 -0
- package/src/entities/media.ts +1747 -0
- package/src/entities/notification.ts +1260 -0
- package/src/entities/presentation.ts +1360 -0
- package/src/entities/productivity.ts +1411 -0
- package/src/entities/project-management.ts +1222 -0
- package/src/entities/recruiting.ts +797 -0
- package/src/entities/shipping.ts +566 -0
- package/src/entities/signature.ts +1204 -0
- package/src/entities/site.ts +244 -0
- package/src/entities/spreadsheet.ts +1434 -0
- package/src/entities/storage.ts +1290 -0
- package/src/entities/support.ts +1267 -0
- package/src/entities/video-conferencing.ts +1874 -0
- package/src/entities/video.ts +1035 -0
- package/src/entities.ts +1795 -0
- package/src/index.ts +176 -0
- package/src/providers/analytics/index.ts +21 -0
- package/src/providers/analytics/mixpanel.ts +311 -0
- package/src/providers/calendar/cal-com.ts +435 -0
- package/src/providers/calendar/google-calendar.ts +412 -0
- package/src/providers/calendar/index.ts +24 -0
- package/src/providers/crm/hubspot.ts +667 -0
- package/src/providers/crm/index.ts +21 -0
- package/src/providers/development/github.ts +608 -0
- package/src/providers/development/index.ts +21 -0
- package/src/providers/ecommerce/index.ts +21 -0
- package/src/providers/ecommerce/shopify.ts +451 -0
- package/src/providers/email/index.ts +24 -0
- package/src/providers/email/resend.ts +301 -0
- package/src/providers/email/sendgrid.ts +196 -0
- package/src/providers/finance/index.ts +21 -0
- package/src/providers/finance/stripe.ts +665 -0
- package/src/providers/forms/index.ts +21 -0
- package/src/providers/forms/typeform.ts +598 -0
- package/src/providers/index.ts +281 -0
- package/src/providers/knowledge/index.ts +21 -0
- package/src/providers/knowledge/notion.ts +497 -0
- package/src/providers/marketing/index.ts +21 -0
- package/src/providers/marketing/mailchimp.ts +656 -0
- package/src/providers/media/cloudinary.ts +373 -0
- package/src/providers/media/index.ts +21 -0
- package/src/providers/messaging/index.ts +24 -0
- package/src/providers/messaging/slack.ts +487 -0
- package/src/providers/messaging/twilio-sms.ts +301 -0
- package/src/providers/project-management/index.ts +21 -0
- package/src/providers/project-management/linear.ts +693 -0
- package/src/providers/registry.ts +119 -0
- package/src/providers/spreadsheet/google-sheets.ts +464 -0
- package/src/providers/spreadsheet/index.ts +24 -0
- package/src/providers/spreadsheet/xlsx.ts +542 -0
- package/src/providers/storage/index.ts +35 -0
- package/src/providers/storage/s3.ts +513 -0
- package/src/providers/support/index.ts +21 -0
- package/src/providers/support/zendesk.ts +417 -0
- package/src/providers/tasks/index.ts +21 -0
- package/src/providers/tasks/todoist.ts +407 -0
- package/src/providers/types.ts +2113 -0
- package/src/providers/video-conferencing/google-meet.ts +412 -0
- package/src/providers/video-conferencing/index.ts +35 -0
- package/src/providers/video-conferencing/jitsi.ts +324 -0
- package/src/providers/video-conferencing/teams.ts +408 -0
- package/src/providers/video-conferencing/zoom.ts +451 -0
- package/src/registry.ts +172 -0
- package/src/tools/communication.ts +256 -0
- package/src/tools/data.ts +236 -0
- package/src/tools/index.ts +12 -0
- package/src/tools/web.ts +161 -0
- package/src/types.ts +539 -0
- package/test/define.test.ts +367 -0
- package/test/registry.test.ts +444 -0
- package/test/tools.test.ts +453 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,513 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AWS S3 Storage Provider
|
|
3
|
+
*
|
|
4
|
+
* Concrete implementation of StorageProvider using AWS S3 REST API.
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type {
|
|
10
|
+
StorageProvider,
|
|
11
|
+
ProviderConfig,
|
|
12
|
+
ProviderHealth,
|
|
13
|
+
ProviderInfo,
|
|
14
|
+
StorageUploadOptions,
|
|
15
|
+
StorageFileData,
|
|
16
|
+
StorageListOptions,
|
|
17
|
+
PaginatedResult,
|
|
18
|
+
} from '../types.js'
|
|
19
|
+
import { defineProvider } from '../registry.js'
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* S3 provider info
|
|
23
|
+
*/
|
|
24
|
+
export const s3Info: ProviderInfo = {
|
|
25
|
+
id: 'storage.s3',
|
|
26
|
+
name: 'AWS S3',
|
|
27
|
+
description: 'Amazon S3 cloud object storage service',
|
|
28
|
+
category: 'storage',
|
|
29
|
+
website: 'https://aws.amazon.com/s3/',
|
|
30
|
+
docsUrl: 'https://docs.aws.amazon.com/s3/',
|
|
31
|
+
requiredConfig: ['accessKeyId', 'secretAccessKey', 'bucket', 'region'],
|
|
32
|
+
optionalConfig: ['endpoint', 'baseUrl'],
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* AWS Signature V4 helper
|
|
37
|
+
*/
|
|
38
|
+
class AwsSignatureV4 {
|
|
39
|
+
constructor(
|
|
40
|
+
private accessKeyId: string,
|
|
41
|
+
private secretAccessKey: string,
|
|
42
|
+
private region: string,
|
|
43
|
+
private service: string = 's3'
|
|
44
|
+
) {}
|
|
45
|
+
|
|
46
|
+
private async sha256(data: string): Promise<ArrayBuffer> {
|
|
47
|
+
const encoder = new TextEncoder()
|
|
48
|
+
return await crypto.subtle.digest('SHA-256', encoder.encode(data))
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
private async hmac(key: ArrayBuffer | string, data: string): Promise<ArrayBuffer> {
|
|
52
|
+
const encoder = new TextEncoder()
|
|
53
|
+
const cryptoKey = await crypto.subtle.importKey(
|
|
54
|
+
'raw',
|
|
55
|
+
typeof key === 'string' ? encoder.encode(key) : key,
|
|
56
|
+
{ name: 'HMAC', hash: 'SHA-256' },
|
|
57
|
+
false,
|
|
58
|
+
['sign']
|
|
59
|
+
)
|
|
60
|
+
return await crypto.subtle.sign('HMAC', cryptoKey, encoder.encode(data))
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
private toHex(buffer: ArrayBuffer): string {
|
|
64
|
+
return Array.from(new Uint8Array(buffer))
|
|
65
|
+
.map((b) => b.toString(16).padStart(2, '0'))
|
|
66
|
+
.join('')
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
private getCanonicalQueryString(params: Record<string, string>): string {
|
|
70
|
+
return Object.keys(params)
|
|
71
|
+
.sort()
|
|
72
|
+
.map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`)
|
|
73
|
+
.join('&')
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async sign(
|
|
77
|
+
method: string,
|
|
78
|
+
path: string,
|
|
79
|
+
headers: Record<string, string>,
|
|
80
|
+
body: string | Buffer | null,
|
|
81
|
+
queryParams: Record<string, string> = {}
|
|
82
|
+
): Promise<Record<string, string>> {
|
|
83
|
+
const now = new Date()
|
|
84
|
+
const dateStamp = now.toISOString().slice(0, 10).replace(/-/g, '')
|
|
85
|
+
const amzDate = now.toISOString().replace(/[:-]|\.\d{3}/g, '')
|
|
86
|
+
|
|
87
|
+
// Ensure required headers
|
|
88
|
+
const signedHeaders: Record<string, string> = {
|
|
89
|
+
...headers,
|
|
90
|
+
'x-amz-date': amzDate,
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (!signedHeaders['host']) {
|
|
94
|
+
signedHeaders['host'] = `${this.service}.${this.region}.amazonaws.com`
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Calculate payload hash
|
|
98
|
+
const payloadHash = this.toHex(
|
|
99
|
+
await this.sha256(body ? (typeof body === 'string' ? body : body.toString()) : '')
|
|
100
|
+
)
|
|
101
|
+
signedHeaders['x-amz-content-sha256'] = payloadHash
|
|
102
|
+
|
|
103
|
+
// Create canonical request
|
|
104
|
+
const canonicalHeaders = Object.keys(signedHeaders)
|
|
105
|
+
.sort()
|
|
106
|
+
.map((key) => `${key.toLowerCase()}:${signedHeaders[key].trim()}`)
|
|
107
|
+
.join('\n')
|
|
108
|
+
|
|
109
|
+
const signedHeadersList = Object.keys(signedHeaders)
|
|
110
|
+
.sort()
|
|
111
|
+
.map((k) => k.toLowerCase())
|
|
112
|
+
.join(';')
|
|
113
|
+
|
|
114
|
+
const canonicalQueryString = this.getCanonicalQueryString(queryParams)
|
|
115
|
+
|
|
116
|
+
const canonicalRequest = [
|
|
117
|
+
method,
|
|
118
|
+
path,
|
|
119
|
+
canonicalQueryString,
|
|
120
|
+
canonicalHeaders,
|
|
121
|
+
'',
|
|
122
|
+
signedHeadersList,
|
|
123
|
+
payloadHash,
|
|
124
|
+
].join('\n')
|
|
125
|
+
|
|
126
|
+
// Create string to sign
|
|
127
|
+
const credentialScope = `${dateStamp}/${this.region}/${this.service}/aws4_request`
|
|
128
|
+
const stringToSign = [
|
|
129
|
+
'AWS4-HMAC-SHA256',
|
|
130
|
+
amzDate,
|
|
131
|
+
credentialScope,
|
|
132
|
+
this.toHex(await this.sha256(canonicalRequest)),
|
|
133
|
+
].join('\n')
|
|
134
|
+
|
|
135
|
+
// Calculate signature
|
|
136
|
+
let key = await this.hmac(`AWS4${this.secretAccessKey}`, dateStamp)
|
|
137
|
+
key = await this.hmac(key, this.region)
|
|
138
|
+
key = await this.hmac(key, this.service)
|
|
139
|
+
key = await this.hmac(key, 'aws4_request')
|
|
140
|
+
const signature = this.toHex(await this.hmac(key, stringToSign))
|
|
141
|
+
|
|
142
|
+
// Add authorization header
|
|
143
|
+
signedHeaders['Authorization'] =
|
|
144
|
+
`AWS4-HMAC-SHA256 Credential=${this.accessKeyId}/${credentialScope}, ` +
|
|
145
|
+
`SignedHeaders=${signedHeadersList}, Signature=${signature}`
|
|
146
|
+
|
|
147
|
+
return signedHeaders
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Create AWS S3 storage provider
|
|
153
|
+
*/
|
|
154
|
+
export function createS3Provider(config: ProviderConfig): StorageProvider {
|
|
155
|
+
let accessKeyId: string
|
|
156
|
+
let secretAccessKey: string
|
|
157
|
+
let bucket: string
|
|
158
|
+
let region: string
|
|
159
|
+
let endpoint: string
|
|
160
|
+
let signer: AwsSignatureV4
|
|
161
|
+
|
|
162
|
+
return {
|
|
163
|
+
info: s3Info,
|
|
164
|
+
|
|
165
|
+
async initialize(cfg: ProviderConfig): Promise<void> {
|
|
166
|
+
accessKeyId = cfg.accessKeyId as string
|
|
167
|
+
secretAccessKey = cfg.secretAccessKey as string
|
|
168
|
+
bucket = cfg.bucket as string
|
|
169
|
+
region = cfg.region as string
|
|
170
|
+
endpoint = (cfg.endpoint as string) || `https://${bucket}.s3.${region}.amazonaws.com`
|
|
171
|
+
|
|
172
|
+
if (!accessKeyId || !secretAccessKey || !bucket || !region) {
|
|
173
|
+
throw new Error('S3 requires accessKeyId, secretAccessKey, bucket, and region')
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
signer = new AwsSignatureV4(accessKeyId, secretAccessKey, region, 's3')
|
|
177
|
+
},
|
|
178
|
+
|
|
179
|
+
async healthCheck(): Promise<ProviderHealth> {
|
|
180
|
+
const start = Date.now()
|
|
181
|
+
try {
|
|
182
|
+
const headers = await signer.sign('HEAD', '/', { host: `${bucket}.s3.${region}.amazonaws.com` }, null)
|
|
183
|
+
|
|
184
|
+
const response = await fetch(`${endpoint}/`, {
|
|
185
|
+
method: 'HEAD',
|
|
186
|
+
headers,
|
|
187
|
+
})
|
|
188
|
+
|
|
189
|
+
return {
|
|
190
|
+
healthy: response.ok,
|
|
191
|
+
latencyMs: Date.now() - start,
|
|
192
|
+
message: response.ok ? 'Connected' : `HTTP ${response.status}`,
|
|
193
|
+
checkedAt: new Date(),
|
|
194
|
+
}
|
|
195
|
+
} catch (error) {
|
|
196
|
+
return {
|
|
197
|
+
healthy: false,
|
|
198
|
+
latencyMs: Date.now() - start,
|
|
199
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
200
|
+
checkedAt: new Date(),
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
|
|
205
|
+
async dispose(): Promise<void> {
|
|
206
|
+
// No cleanup needed
|
|
207
|
+
},
|
|
208
|
+
|
|
209
|
+
async upload(path: string, content: Buffer | string, options?: StorageUploadOptions): Promise<StorageFileData> {
|
|
210
|
+
try {
|
|
211
|
+
const buffer = typeof content === 'string' ? Buffer.from(content) : content
|
|
212
|
+
const headers: Record<string, string> = {
|
|
213
|
+
host: `${bucket}.s3.${region}.amazonaws.com`,
|
|
214
|
+
'content-type': options?.contentType || 'application/octet-stream',
|
|
215
|
+
'content-length': buffer.length.toString(),
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if (options?.acl) {
|
|
219
|
+
headers['x-amz-acl'] = options.acl
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (options?.metadata) {
|
|
223
|
+
Object.entries(options.metadata).forEach(([key, value]) => {
|
|
224
|
+
headers[`x-amz-meta-${key}`] = value
|
|
225
|
+
})
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const signedHeaders = await signer.sign('PUT', `/${path}`, headers, buffer)
|
|
229
|
+
|
|
230
|
+
const response = await fetch(`${endpoint}/${path}`, {
|
|
231
|
+
method: 'PUT',
|
|
232
|
+
headers: signedHeaders,
|
|
233
|
+
body: buffer,
|
|
234
|
+
})
|
|
235
|
+
|
|
236
|
+
if (!response.ok) {
|
|
237
|
+
const errorText = await response.text()
|
|
238
|
+
throw new Error(`S3 upload failed: ${response.status} ${errorText}`)
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const etag = response.headers.get('etag')?.replace(/"/g, '')
|
|
242
|
+
|
|
243
|
+
return {
|
|
244
|
+
path,
|
|
245
|
+
name: path.split('/').pop() || path,
|
|
246
|
+
size: buffer.length,
|
|
247
|
+
contentType: options?.contentType,
|
|
248
|
+
etag,
|
|
249
|
+
lastModified: new Date(),
|
|
250
|
+
isFolder: false,
|
|
251
|
+
url: `${endpoint}/${path}`,
|
|
252
|
+
}
|
|
253
|
+
} catch (error) {
|
|
254
|
+
throw new Error(`Failed to upload to S3: ${error instanceof Error ? error.message : 'Unknown error'}`)
|
|
255
|
+
}
|
|
256
|
+
},
|
|
257
|
+
|
|
258
|
+
async download(path: string): Promise<Buffer> {
|
|
259
|
+
try {
|
|
260
|
+
const headers = await signer.sign('GET', `/${path}`, { host: `${bucket}.s3.${region}.amazonaws.com` }, null)
|
|
261
|
+
|
|
262
|
+
const response = await fetch(`${endpoint}/${path}`, {
|
|
263
|
+
method: 'GET',
|
|
264
|
+
headers,
|
|
265
|
+
})
|
|
266
|
+
|
|
267
|
+
if (!response.ok) {
|
|
268
|
+
throw new Error(`S3 download failed: ${response.status}`)
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
const arrayBuffer = await response.arrayBuffer()
|
|
272
|
+
return Buffer.from(arrayBuffer)
|
|
273
|
+
} catch (error) {
|
|
274
|
+
throw new Error(`Failed to download from S3: ${error instanceof Error ? error.message : 'Unknown error'}`)
|
|
275
|
+
}
|
|
276
|
+
},
|
|
277
|
+
|
|
278
|
+
async delete(path: string): Promise<boolean> {
|
|
279
|
+
try {
|
|
280
|
+
const headers = await signer.sign('DELETE', `/${path}`, { host: `${bucket}.s3.${region}.amazonaws.com` }, null)
|
|
281
|
+
|
|
282
|
+
const response = await fetch(`${endpoint}/${path}`, {
|
|
283
|
+
method: 'DELETE',
|
|
284
|
+
headers,
|
|
285
|
+
})
|
|
286
|
+
|
|
287
|
+
return response.ok || response.status === 204
|
|
288
|
+
} catch (error) {
|
|
289
|
+
throw new Error(`Failed to delete from S3: ${error instanceof Error ? error.message : 'Unknown error'}`)
|
|
290
|
+
}
|
|
291
|
+
},
|
|
292
|
+
|
|
293
|
+
async list(prefix: string = '', options?: StorageListOptions): Promise<PaginatedResult<StorageFileData>> {
|
|
294
|
+
try {
|
|
295
|
+
const queryParams: Record<string, string> = {
|
|
296
|
+
'list-type': '2',
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
if (prefix) {
|
|
300
|
+
queryParams.prefix = prefix
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
if (options?.delimiter) {
|
|
304
|
+
queryParams.delimiter = options.delimiter
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
if (options?.limit) {
|
|
308
|
+
queryParams['max-keys'] = options.limit.toString()
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if (options?.cursor) {
|
|
312
|
+
queryParams['continuation-token'] = options.cursor
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
const headers = await signer.sign('GET', '/', { host: `${bucket}.s3.${region}.amazonaws.com` }, null, queryParams)
|
|
316
|
+
|
|
317
|
+
const queryString = Object.keys(queryParams)
|
|
318
|
+
.map((key) => `${key}=${encodeURIComponent(queryParams[key])}`)
|
|
319
|
+
.join('&')
|
|
320
|
+
|
|
321
|
+
const response = await fetch(`${endpoint}/?${queryString}`, {
|
|
322
|
+
method: 'GET',
|
|
323
|
+
headers,
|
|
324
|
+
})
|
|
325
|
+
|
|
326
|
+
if (!response.ok) {
|
|
327
|
+
throw new Error(`S3 list failed: ${response.status}`)
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
const xmlText = await response.text()
|
|
331
|
+
const items: StorageFileData[] = []
|
|
332
|
+
|
|
333
|
+
// Parse XML response (simple regex-based parsing for now)
|
|
334
|
+
const contentsMatches = xmlText.matchAll(/<Contents>(.*?)<\/Contents>/gs)
|
|
335
|
+
for (const match of contentsMatches) {
|
|
336
|
+
const content = match[1]
|
|
337
|
+
const keyMatch = content.match(/<Key>(.*?)<\/Key>/)
|
|
338
|
+
const sizeMatch = content.match(/<Size>(.*?)<\/Size>/)
|
|
339
|
+
const lastModifiedMatch = content.match(/<LastModified>(.*?)<\/LastModified>/)
|
|
340
|
+
const etagMatch = content.match(/<ETag>(.*?)<\/ETag>/)
|
|
341
|
+
|
|
342
|
+
if (keyMatch) {
|
|
343
|
+
const path = keyMatch[1]
|
|
344
|
+
items.push({
|
|
345
|
+
path,
|
|
346
|
+
name: path.split('/').pop() || path,
|
|
347
|
+
size: sizeMatch ? parseInt(sizeMatch[1], 10) : 0,
|
|
348
|
+
etag: etagMatch ? etagMatch[1].replace(/"/g, '') : undefined,
|
|
349
|
+
lastModified: lastModifiedMatch ? new Date(lastModifiedMatch[1]) : new Date(),
|
|
350
|
+
isFolder: false,
|
|
351
|
+
url: `${endpoint}/${path}`,
|
|
352
|
+
})
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// Parse common prefixes (folders)
|
|
357
|
+
const prefixMatches = xmlText.matchAll(/<CommonPrefixes>.*?<Prefix>(.*?)<\/Prefix>.*?<\/CommonPrefixes>/gs)
|
|
358
|
+
for (const match of prefixMatches) {
|
|
359
|
+
const folderPath = match[1]
|
|
360
|
+
items.push({
|
|
361
|
+
path: folderPath,
|
|
362
|
+
name: folderPath.split('/').filter(Boolean).pop() || folderPath,
|
|
363
|
+
size: 0,
|
|
364
|
+
lastModified: new Date(),
|
|
365
|
+
isFolder: true,
|
|
366
|
+
})
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
const isTruncated = xmlText.includes('<IsTruncated>true</IsTruncated>')
|
|
370
|
+
const nextTokenMatch = xmlText.match(/<NextContinuationToken>(.*?)<\/NextContinuationToken>/)
|
|
371
|
+
|
|
372
|
+
return {
|
|
373
|
+
items,
|
|
374
|
+
hasMore: isTruncated,
|
|
375
|
+
nextCursor: nextTokenMatch ? nextTokenMatch[1] : undefined,
|
|
376
|
+
}
|
|
377
|
+
} catch (error) {
|
|
378
|
+
throw new Error(`Failed to list S3 objects: ${error instanceof Error ? error.message : 'Unknown error'}`)
|
|
379
|
+
}
|
|
380
|
+
},
|
|
381
|
+
|
|
382
|
+
async getMetadata(path: string): Promise<StorageFileData | null> {
|
|
383
|
+
try {
|
|
384
|
+
const headers = await signer.sign('HEAD', `/${path}`, { host: `${bucket}.s3.${region}.amazonaws.com` }, null)
|
|
385
|
+
|
|
386
|
+
const response = await fetch(`${endpoint}/${path}`, {
|
|
387
|
+
method: 'HEAD',
|
|
388
|
+
headers,
|
|
389
|
+
})
|
|
390
|
+
|
|
391
|
+
if (!response.ok) {
|
|
392
|
+
if (response.status === 404) {
|
|
393
|
+
return null
|
|
394
|
+
}
|
|
395
|
+
throw new Error(`S3 metadata fetch failed: ${response.status}`)
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
const contentLength = response.headers.get('content-length')
|
|
399
|
+
const contentType = response.headers.get('content-type')
|
|
400
|
+
const lastModified = response.headers.get('last-modified')
|
|
401
|
+
const etag = response.headers.get('etag')?.replace(/"/g, '')
|
|
402
|
+
|
|
403
|
+
return {
|
|
404
|
+
path,
|
|
405
|
+
name: path.split('/').pop() || path,
|
|
406
|
+
size: contentLength ? parseInt(contentLength, 10) : 0,
|
|
407
|
+
contentType: contentType || undefined,
|
|
408
|
+
etag,
|
|
409
|
+
lastModified: lastModified ? new Date(lastModified) : new Date(),
|
|
410
|
+
isFolder: false,
|
|
411
|
+
url: `${endpoint}/${path}`,
|
|
412
|
+
}
|
|
413
|
+
} catch (error) {
|
|
414
|
+
throw new Error(`Failed to get S3 metadata: ${error instanceof Error ? error.message : 'Unknown error'}`)
|
|
415
|
+
}
|
|
416
|
+
},
|
|
417
|
+
|
|
418
|
+
async copy(source: string, destination: string): Promise<StorageFileData> {
|
|
419
|
+
try {
|
|
420
|
+
const headers = await signer.sign(
|
|
421
|
+
'PUT',
|
|
422
|
+
`/${destination}`,
|
|
423
|
+
{
|
|
424
|
+
host: `${bucket}.s3.${region}.amazonaws.com`,
|
|
425
|
+
'x-amz-copy-source': `/${bucket}/${source}`,
|
|
426
|
+
},
|
|
427
|
+
null
|
|
428
|
+
)
|
|
429
|
+
|
|
430
|
+
const response = await fetch(`${endpoint}/${destination}`, {
|
|
431
|
+
method: 'PUT',
|
|
432
|
+
headers,
|
|
433
|
+
})
|
|
434
|
+
|
|
435
|
+
if (!response.ok) {
|
|
436
|
+
throw new Error(`S3 copy failed: ${response.status}`)
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
// Get metadata of the new file
|
|
440
|
+
const metadata = await this.getMetadata(destination)
|
|
441
|
+
if (!metadata) {
|
|
442
|
+
throw new Error('Failed to get metadata after copy')
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
return metadata
|
|
446
|
+
} catch (error) {
|
|
447
|
+
throw new Error(`Failed to copy in S3: ${error instanceof Error ? error.message : 'Unknown error'}`)
|
|
448
|
+
}
|
|
449
|
+
},
|
|
450
|
+
|
|
451
|
+
async move(source: string, destination: string): Promise<StorageFileData> {
|
|
452
|
+
try {
|
|
453
|
+
// Copy to destination
|
|
454
|
+
const metadata = await this.copy!(source, destination)
|
|
455
|
+
|
|
456
|
+
// Delete source
|
|
457
|
+
await this.delete(source)
|
|
458
|
+
|
|
459
|
+
return metadata
|
|
460
|
+
} catch (error) {
|
|
461
|
+
throw new Error(`Failed to move in S3: ${error instanceof Error ? error.message : 'Unknown error'}`)
|
|
462
|
+
}
|
|
463
|
+
},
|
|
464
|
+
|
|
465
|
+
async getSignedUrl(path: string, expiresIn: number = 3600): Promise<string> {
|
|
466
|
+
try {
|
|
467
|
+
const now = Math.floor(Date.now() / 1000)
|
|
468
|
+
const expires = now + expiresIn
|
|
469
|
+
|
|
470
|
+
const queryParams: Record<string, string> = {
|
|
471
|
+
'X-Amz-Algorithm': 'AWS4-HMAC-SHA256',
|
|
472
|
+
'X-Amz-Credential': `${accessKeyId}/${new Date().toISOString().slice(0, 10).replace(/-/g, '')}/${region}/s3/aws4_request`,
|
|
473
|
+
'X-Amz-Date': new Date().toISOString().replace(/[:-]|\.\d{3}/g, ''),
|
|
474
|
+
'X-Amz-Expires': expiresIn.toString(),
|
|
475
|
+
'X-Amz-SignedHeaders': 'host',
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
const headers = await signer.sign('GET', `/${path}`, { host: `${bucket}.s3.${region}.amazonaws.com` }, null, queryParams)
|
|
479
|
+
|
|
480
|
+
// Extract signature from Authorization header
|
|
481
|
+
const authHeader = headers['Authorization']
|
|
482
|
+
const signatureMatch = authHeader.match(/Signature=([a-f0-9]+)/)
|
|
483
|
+
if (signatureMatch) {
|
|
484
|
+
queryParams['X-Amz-Signature'] = signatureMatch[1]
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
const queryString = Object.keys(queryParams)
|
|
488
|
+
.map((key) => `${key}=${encodeURIComponent(queryParams[key])}`)
|
|
489
|
+
.join('&')
|
|
490
|
+
|
|
491
|
+
return `${endpoint}/${path}?${queryString}`
|
|
492
|
+
} catch (error) {
|
|
493
|
+
throw new Error(`Failed to generate signed URL: ${error instanceof Error ? error.message : 'Unknown error'}`)
|
|
494
|
+
}
|
|
495
|
+
},
|
|
496
|
+
|
|
497
|
+
async createFolder(path: string): Promise<boolean> {
|
|
498
|
+
try {
|
|
499
|
+
// S3 doesn't have real folders, but we can create an empty object with trailing slash
|
|
500
|
+
const folderPath = path.endsWith('/') ? path : `${path}/`
|
|
501
|
+
await this.upload(folderPath, Buffer.from(''), { contentType: 'application/x-directory' })
|
|
502
|
+
return true
|
|
503
|
+
} catch (error) {
|
|
504
|
+
throw new Error(`Failed to create folder in S3: ${error instanceof Error ? error.message : 'Unknown error'}`)
|
|
505
|
+
}
|
|
506
|
+
},
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
/**
|
|
511
|
+
* S3 provider definition
|
|
512
|
+
*/
|
|
513
|
+
export const s3Provider = defineProvider(s3Info, async (config) => createS3Provider(config))
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Support Providers
|
|
3
|
+
*
|
|
4
|
+
* @packageDocumentation
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export { zendeskInfo, zendeskProvider, createZendeskProvider } from './zendesk.js'
|
|
8
|
+
|
|
9
|
+
import { zendeskProvider } from './zendesk.js'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Register all support providers
|
|
13
|
+
*/
|
|
14
|
+
export function registerSupportProviders(): void {
|
|
15
|
+
zendeskProvider.register()
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* All support providers
|
|
20
|
+
*/
|
|
21
|
+
export const supportProviders = [zendeskProvider]
|