@open-mercato/core 0.4.5-develop-754ef4d2f0 → 0.4.5-develop-9f9549ebc8
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/dist/generated/entities/message/index.js +65 -0
- package/dist/generated/entities/message/index.js.map +7 -0
- package/dist/generated/entities/message_access_token/index.js +19 -0
- package/dist/generated/entities/message_access_token/index.js.map +7 -0
- package/dist/generated/entities/message_confirmation/index.js +21 -0
- package/dist/generated/entities/message_confirmation/index.js.map +7 -0
- package/dist/generated/entities/message_object/index.js +23 -0
- package/dist/generated/entities/message_object/index.js.map +7 -0
- package/dist/generated/entities/message_recipient/index.js +31 -0
- package/dist/generated/entities/message_recipient/index.js.map +7 -0
- package/dist/generated/entities.ids.generated.js +8 -0
- package/dist/generated/entities.ids.generated.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +10 -0
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/modules/auth/components/AclEditor.js +4 -2
- package/dist/modules/auth/components/AclEditor.js.map +2 -2
- package/dist/modules/auth/frontend/reset.js +3 -3
- package/dist/modules/auth/frontend/reset.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/page.js +27 -8
- package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
- package/dist/modules/customers/lib/messageObjectPreviews.js +131 -0
- package/dist/modules/customers/lib/messageObjectPreviews.js.map +7 -0
- package/dist/modules/customers/message-objects.js +71 -0
- package/dist/modules/customers/message-objects.js.map +7 -0
- package/dist/modules/customers/widgets/messages/CustomerMessageObjectDetail.js +51 -0
- package/dist/modules/customers/widgets/messages/CustomerMessageObjectDetail.js.map +7 -0
- package/dist/modules/customers/widgets/messages/CustomerMessageObjectPreview.js +35 -0
- package/dist/modules/customers/widgets/messages/CustomerMessageObjectPreview.js.map +7 -0
- package/dist/modules/customers/widgets/messages/index.js +7 -0
- package/dist/modules/customers/widgets/messages/index.js.map +7 -0
- package/dist/modules/dashboards/components/WidgetVisibilityEditor.js +35 -6
- package/dist/modules/dashboards/components/WidgetVisibilityEditor.js.map +2 -2
- package/dist/modules/messages/acl.js +15 -0
- package/dist/modules/messages/acl.js.map +7 -0
- package/dist/modules/messages/api/[id]/actions/[actionId]/route.js +92 -0
- package/dist/modules/messages/api/[id]/actions/[actionId]/route.js.map +7 -0
- package/dist/modules/messages/api/[id]/archive/route.js +120 -0
- package/dist/modules/messages/api/[id]/archive/route.js.map +7 -0
- package/dist/modules/messages/api/[id]/attachments/route.js +195 -0
- package/dist/modules/messages/api/[id]/attachments/route.js.map +7 -0
- package/dist/modules/messages/api/[id]/confirmation/route.js +67 -0
- package/dist/modules/messages/api/[id]/confirmation/route.js.map +7 -0
- package/dist/modules/messages/api/[id]/conversation/archive/route.js +68 -0
- package/dist/modules/messages/api/[id]/conversation/archive/route.js.map +7 -0
- package/dist/modules/messages/api/[id]/conversation/read/route.js +68 -0
- package/dist/modules/messages/api/[id]/conversation/read/route.js.map +7 -0
- package/dist/modules/messages/api/[id]/conversation/route.js +68 -0
- package/dist/modules/messages/api/[id]/conversation/route.js.map +7 -0
- package/dist/modules/messages/api/[id]/forward/route.js +85 -0
- package/dist/modules/messages/api/[id]/forward/route.js.map +7 -0
- package/dist/modules/messages/api/[id]/forward-preview/route.js +70 -0
- package/dist/modules/messages/api/[id]/forward-preview/route.js.map +7 -0
- package/dist/modules/messages/api/[id]/read/route.js +120 -0
- package/dist/modules/messages/api/[id]/read/route.js.map +7 -0
- package/dist/modules/messages/api/[id]/reply/route.js +87 -0
- package/dist/modules/messages/api/[id]/reply/route.js.map +7 -0
- package/dist/modules/messages/api/[id]/route.js +350 -0
- package/dist/modules/messages/api/[id]/route.js.map +7 -0
- package/dist/modules/messages/api/object-types/route.js +54 -0
- package/dist/modules/messages/api/object-types/route.js.map +7 -0
- package/dist/modules/messages/api/openapi.js +261 -0
- package/dist/modules/messages/api/openapi.js.map +7 -0
- package/dist/modules/messages/api/route.js +262 -0
- package/dist/modules/messages/api/route.js.map +7 -0
- package/dist/modules/messages/api/token/[token]/route.js +99 -0
- package/dist/modules/messages/api/token/[token]/route.js.map +7 -0
- package/dist/modules/messages/api/types/route.js +40 -0
- package/dist/modules/messages/api/types/route.js.map +7 -0
- package/dist/modules/messages/api/unread-count/route.js +43 -0
- package/dist/modules/messages/api/unread-count/route.js.map +7 -0
- package/dist/modules/messages/backend/messages/[id]/page.js +10 -0
- package/dist/modules/messages/backend/messages/[id]/page.js.map +7 -0
- package/dist/modules/messages/backend/messages/[id]/page.meta.js +16 -0
- package/dist/modules/messages/backend/messages/[id]/page.meta.js.map +7 -0
- package/dist/modules/messages/backend/messages/compose/page.js +10 -0
- package/dist/modules/messages/backend/messages/compose/page.js.map +7 -0
- package/dist/modules/messages/backend/messages/compose/page.meta.js +17 -0
- package/dist/modules/messages/backend/messages/compose/page.meta.js.map +7 -0
- package/dist/modules/messages/backend/page.js +10 -0
- package/dist/modules/messages/backend/page.js.map +7 -0
- package/dist/modules/messages/backend/page.meta.js +33 -0
- package/dist/modules/messages/backend/page.meta.js.map +7 -0
- package/dist/modules/messages/commands/actions.js +265 -0
- package/dist/modules/messages/commands/actions.js.map +7 -0
- package/dist/modules/messages/commands/attachments.js +217 -0
- package/dist/modules/messages/commands/attachments.js.map +7 -0
- package/dist/modules/messages/commands/confirmations.js +151 -0
- package/dist/modules/messages/commands/confirmations.js.map +7 -0
- package/dist/modules/messages/commands/conversation.js +240 -0
- package/dist/modules/messages/commands/conversation.js.map +7 -0
- package/dist/modules/messages/commands/messages.js +748 -0
- package/dist/modules/messages/commands/messages.js.map +7 -0
- package/dist/modules/messages/commands/recipients.js +259 -0
- package/dist/modules/messages/commands/recipients.js.map +7 -0
- package/dist/modules/messages/commands/shared.js +258 -0
- package/dist/modules/messages/commands/shared.js.map +7 -0
- package/dist/modules/messages/commands/tokens.js +69 -0
- package/dist/modules/messages/commands/tokens.js.map +7 -0
- package/dist/modules/messages/components/ComposeMessagePageClient.js +24 -0
- package/dist/modules/messages/components/ComposeMessagePageClient.js.map +7 -0
- package/dist/modules/messages/components/MessageDetailPageClient.js +261 -0
- package/dist/modules/messages/components/MessageDetailPageClient.js.map +7 -0
- package/dist/modules/messages/components/MessagesInboxPageClient.js +390 -0
- package/dist/modules/messages/components/MessagesInboxPageClient.js.map +7 -0
- package/dist/modules/messages/components/confirmation/MessageConfirmationActions.js +31 -0
- package/dist/modules/messages/components/confirmation/MessageConfirmationActions.js.map +7 -0
- package/dist/modules/messages/components/confirmation/MessageConfirmationContent.js +69 -0
- package/dist/modules/messages/components/confirmation/MessageConfirmationContent.js.map +7 -0
- package/dist/modules/messages/components/defaults/DefaultMessageActions.js +31 -0
- package/dist/modules/messages/components/defaults/DefaultMessageActions.js.map +7 -0
- package/dist/modules/messages/components/defaults/DefaultMessageContent.js +19 -0
- package/dist/modules/messages/components/defaults/DefaultMessageContent.js.map +7 -0
- package/dist/modules/messages/components/defaults/DefaultMessageListItem.js +90 -0
- package/dist/modules/messages/components/defaults/DefaultMessageListItem.js.map +7 -0
- package/dist/modules/messages/components/defaults/MessageRecordObjectDetail.js +86 -0
- package/dist/modules/messages/components/defaults/MessageRecordObjectDetail.js.map +7 -0
- package/dist/modules/messages/components/defaults/MessageRecordObjectPreview.js +61 -0
- package/dist/modules/messages/components/defaults/MessageRecordObjectPreview.js.map +7 -0
- package/dist/modules/messages/components/message-detail/detail-panels.js +27 -0
- package/dist/modules/messages/components/message-detail/detail-panels.js.map +7 -0
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetails.js +52 -0
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetails.js.map +7 -0
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsActions.js +289 -0
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsActions.js.map +7 -0
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.js +103 -0
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.js.map +7 -0
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsQueries.js +78 -0
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsQueries.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/MainMessageHeader.js +94 -0
- package/dist/modules/messages/components/message-detail/panels/MainMessageHeader.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/MessageHeader.js +110 -0
- package/dist/modules/messages/components/message-detail/panels/MessageHeader.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/MessageListComponent.js +58 -0
- package/dist/modules/messages/components/message-detail/panels/MessageListComponent.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/actions-panel.js +51 -0
- package/dist/modules/messages/components/message-detail/panels/actions-panel.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/attachments-panel.js +66 -0
- package/dist/modules/messages/components/message-detail/panels/attachments-panel.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/body-panel.js +20 -0
- package/dist/modules/messages/components/message-detail/panels/body-panel.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/composer-dialogs.js +36 -0
- package/dist/modules/messages/components/message-detail/panels/composer-dialogs.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/dialogs.js +96 -0
- package/dist/modules/messages/components/message-detail/panels/dialogs.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/index.js +25 -0
- package/dist/modules/messages/components/message-detail/panels/index.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/meta-panel.js +14 -0
- package/dist/modules/messages/components/message-detail/panels/meta-panel.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/objects-panel.js +51 -0
- package/dist/modules/messages/components/message-detail/panels/objects-panel.js.map +7 -0
- package/dist/modules/messages/components/message-detail/panels/thread-panel.js +54 -0
- package/dist/modules/messages/components/message-detail/panels/thread-panel.js.map +7 -0
- package/dist/modules/messages/components/message-detail/types.js +1 -0
- package/dist/modules/messages/components/message-detail/types.js.map +7 -0
- package/dist/modules/messages/components/message-detail/utils.js +54 -0
- package/dist/modules/messages/components/message-detail/utils.js.map +7 -0
- package/dist/modules/messages/components/utils/PriorityBadge.js +52 -0
- package/dist/modules/messages/components/utils/PriorityBadge.js.map +7 -0
- package/dist/modules/messages/components/utils/typeUiRegistry.js +77 -0
- package/dist/modules/messages/components/utils/typeUiRegistry.js.map +7 -0
- package/dist/modules/messages/data/entities.js +309 -0
- package/dist/modules/messages/data/entities.js.map +7 -0
- package/dist/modules/messages/data/validators.js +272 -0
- package/dist/modules/messages/data/validators.js.map +7 -0
- package/dist/modules/messages/emails/MessageEmail.js +108 -0
- package/dist/modules/messages/emails/MessageEmail.js.map +7 -0
- package/dist/modules/messages/events.js +24 -0
- package/dist/modules/messages/events.js.map +7 -0
- package/dist/modules/messages/frontend/messages/view/[token]/page.js +247 -0
- package/dist/modules/messages/frontend/messages/view/[token]/page.js.map +7 -0
- package/dist/modules/messages/frontend/messages/view/[token]/page.meta.js +9 -0
- package/dist/modules/messages/frontend/messages/view/[token]/page.meta.js.map +7 -0
- package/dist/modules/messages/index.js +21 -0
- package/dist/modules/messages/index.js.map +7 -0
- package/dist/modules/messages/lib/actions.js +141 -0
- package/dist/modules/messages/lib/actions.js.map +7 -0
- package/dist/modules/messages/lib/attachments.js +131 -0
- package/dist/modules/messages/lib/attachments.js.map +7 -0
- package/dist/modules/messages/lib/constants.js +7 -0
- package/dist/modules/messages/lib/constants.js.map +7 -0
- package/dist/modules/messages/lib/email-sender.js +201 -0
- package/dist/modules/messages/lib/email-sender.js.map +7 -0
- package/dist/modules/messages/lib/forwarding.js +179 -0
- package/dist/modules/messages/lib/forwarding.js.map +7 -0
- package/dist/modules/messages/lib/message-objects-registry.js +49 -0
- package/dist/modules/messages/lib/message-objects-registry.js.map +7 -0
- package/dist/modules/messages/lib/message-types-registry.js +41 -0
- package/dist/modules/messages/lib/message-types-registry.js.map +7 -0
- package/dist/modules/messages/lib/object-validation.js +20 -0
- package/dist/modules/messages/lib/object-validation.js.map +7 -0
- package/dist/modules/messages/lib/operationMetadata.js +21 -0
- package/dist/modules/messages/lib/operationMetadata.js.map +7 -0
- package/dist/modules/messages/lib/priorityUtils.js +61 -0
- package/dist/modules/messages/lib/priorityUtils.js.map +7 -0
- package/dist/modules/messages/lib/routeHelpers.js +44 -0
- package/dist/modules/messages/lib/routeHelpers.js.map +7 -0
- package/dist/modules/messages/message-objects.js +7 -0
- package/dist/modules/messages/message-objects.js.map +7 -0
- package/dist/modules/messages/message-types.js +67 -0
- package/dist/modules/messages/message-types.js.map +7 -0
- package/dist/modules/messages/migrations/Migration20260213181243.js +31 -0
- package/dist/modules/messages/migrations/Migration20260213181243.js.map +7 -0
- package/dist/modules/messages/migrations/Migration20260215165126.js +16 -0
- package/dist/modules/messages/migrations/Migration20260215165126.js.map +7 -0
- package/dist/modules/messages/notifications.js +27 -0
- package/dist/modules/messages/notifications.js.map +7 -0
- package/dist/modules/messages/setup.js +21 -0
- package/dist/modules/messages/setup.js.map +7 -0
- package/dist/modules/messages/subscribers/message-notification.js +108 -0
- package/dist/modules/messages/subscribers/message-notification.js.map +7 -0
- package/dist/modules/messages/workers/send-email.worker.js +253 -0
- package/dist/modules/messages/workers/send-email.worker.js.map +7 -0
- package/dist/modules/sales/backend/sales/documents/[id]/page.js +30 -11
- package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
- package/dist/modules/sales/commands/payments.js +12 -6
- package/dist/modules/sales/commands/payments.js.map +2 -2
- package/dist/modules/sales/lib/messageObjectPreviews.js +114 -0
- package/dist/modules/sales/lib/messageObjectPreviews.js.map +7 -0
- package/dist/modules/sales/message-objects.js +57 -0
- package/dist/modules/sales/message-objects.js.map +7 -0
- package/dist/modules/sales/widgets/messages/SalesDocumentMessageDetail.js +51 -0
- package/dist/modules/sales/widgets/messages/SalesDocumentMessageDetail.js.map +7 -0
- package/dist/modules/sales/widgets/messages/SalesDocumentMessagePreview.js +36 -0
- package/dist/modules/sales/widgets/messages/SalesDocumentMessagePreview.js.map +7 -0
- package/dist/modules/sales/widgets/messages/index.js +7 -0
- package/dist/modules/sales/widgets/messages/index.js.map +7 -0
- package/dist/modules/staff/backend/staff/leave-requests/[id]/page.js +55 -1
- package/dist/modules/staff/backend/staff/leave-requests/[id]/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/my-leave-requests/[id]/page.js +60 -1
- package/dist/modules/staff/backend/staff/my-leave-requests/[id]/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-members/[id]/page.js +2 -19
- package/dist/modules/staff/backend/staff/team-members/[id]/page.js.map +2 -2
- package/dist/modules/staff/components/LeaveRequestDetail.js +112 -0
- package/dist/modules/staff/components/LeaveRequestDetail.js.map +7 -0
- package/dist/modules/staff/components/LeaveRequestForm.js +3 -1
- package/dist/modules/staff/components/LeaveRequestForm.js.map +2 -2
- package/dist/modules/staff/components/LeaveRequestPreview.js +43 -0
- package/dist/modules/staff/components/LeaveRequestPreview.js.map +7 -0
- package/dist/modules/staff/lib/messageObjectPreviews.js +148 -0
- package/dist/modules/staff/lib/messageObjectPreviews.js.map +7 -0
- package/dist/modules/staff/message-objects.js +104 -0
- package/dist/modules/staff/message-objects.js.map +7 -0
- package/dist/modules/staff/message-types.js +23 -0
- package/dist/modules/staff/message-types.js.map +7 -0
- package/dist/modules/staff/widgets/messages/StaffMessageObjectDetail.js +51 -0
- package/dist/modules/staff/widgets/messages/StaffMessageObjectDetail.js.map +7 -0
- package/dist/modules/staff/widgets/messages/StaffMessageObjectPreview.js +34 -0
- package/dist/modules/staff/widgets/messages/StaffMessageObjectPreview.js.map +7 -0
- package/dist/modules/staff/widgets/messages/index.js +7 -0
- package/dist/modules/staff/widgets/messages/index.js.map +7 -0
- package/dist/modules/workflows/backend/definitions/visual-editor/page.js +6 -6
- package/dist/modules/workflows/backend/definitions/visual-editor/page.js.map +2 -2
- package/generated/entities/message/index.ts +31 -0
- package/generated/entities/message_access_token/index.ts +8 -0
- package/generated/entities/message_confirmation/index.ts +9 -0
- package/generated/entities/message_object/index.ts +10 -0
- package/generated/entities/message_recipient/index.ts +14 -0
- package/generated/entities.ids.generated.ts +8 -0
- package/generated/entity-fields-registry.ts +10 -0
- package/jest.setup.ts +5 -0
- package/package.json +2 -2
- package/src/modules/attachments/i18n/de.json +4 -0
- package/src/modules/attachments/i18n/en.json +4 -0
- package/src/modules/attachments/i18n/es.json +4 -0
- package/src/modules/attachments/i18n/pl.json +4 -0
- package/src/modules/auth/components/AclEditor.tsx +4 -2
- package/src/modules/auth/frontend/reset.tsx +3 -3
- package/src/modules/auth/i18n/de.json +5 -0
- package/src/modules/auth/i18n/en.json +5 -0
- package/src/modules/auth/i18n/es.json +5 -0
- package/src/modules/auth/i18n/pl.json +5 -0
- package/src/modules/catalog/i18n/de.json +21 -0
- package/src/modules/catalog/i18n/en.json +21 -0
- package/src/modules/catalog/i18n/es.json +21 -0
- package/src/modules/catalog/i18n/pl.json +21 -0
- package/src/modules/currencies/i18n/de.json +6 -0
- package/src/modules/currencies/i18n/en.json +6 -0
- package/src/modules/currencies/i18n/es.json +6 -0
- package/src/modules/currencies/i18n/pl.json +6 -0
- package/src/modules/customers/backend/customers/deals/[id]/page.tsx +20 -4
- package/src/modules/customers/i18n/de.json +26 -1
- package/src/modules/customers/i18n/en.json +25 -0
- package/src/modules/customers/i18n/es.json +25 -0
- package/src/modules/customers/i18n/pl.json +25 -0
- package/src/modules/customers/lib/messageObjectPreviews.ts +154 -0
- package/src/modules/customers/message-objects.ts +70 -0
- package/src/modules/customers/widgets/messages/CustomerMessageObjectDetail.tsx +57 -0
- package/src/modules/customers/widgets/messages/CustomerMessageObjectPreview.tsx +49 -0
- package/src/modules/customers/widgets/messages/index.ts +2 -0
- package/src/modules/dashboards/components/WidgetVisibilityEditor.tsx +41 -5
- package/src/modules/dashboards/i18n/de.json +5 -1
- package/src/modules/dashboards/i18n/en.json +5 -1
- package/src/modules/dashboards/i18n/es.json +5 -1
- package/src/modules/dashboards/i18n/pl.json +5 -1
- package/src/modules/dictionaries/i18n/de.json +14 -1
- package/src/modules/dictionaries/i18n/en.json +14 -1
- package/src/modules/dictionaries/i18n/es.json +14 -1
- package/src/modules/dictionaries/i18n/pl.json +14 -1
- package/src/modules/feature_toggles/i18n/de.json +3 -0
- package/src/modules/feature_toggles/i18n/en.json +3 -0
- package/src/modules/feature_toggles/i18n/es.json +3 -0
- package/src/modules/feature_toggles/i18n/pl.json +3 -0
- package/src/modules/messages/acl.ts +11 -0
- package/src/modules/messages/api/[id]/actions/[actionId]/route.ts +103 -0
- package/src/modules/messages/api/[id]/archive/route.ts +138 -0
- package/src/modules/messages/api/[id]/attachments/route.ts +217 -0
- package/src/modules/messages/api/[id]/confirmation/route.ts +73 -0
- package/src/modules/messages/api/[id]/conversation/archive/route.ts +69 -0
- package/src/modules/messages/api/[id]/conversation/read/route.ts +69 -0
- package/src/modules/messages/api/[id]/conversation/route.ts +69 -0
- package/src/modules/messages/api/[id]/forward/route.ts +87 -0
- package/src/modules/messages/api/[id]/forward-preview/route.ts +75 -0
- package/src/modules/messages/api/[id]/read/route.ts +138 -0
- package/src/modules/messages/api/[id]/reply/route.ts +89 -0
- package/src/modules/messages/api/[id]/route.ts +401 -0
- package/src/modules/messages/api/object-types/route.ts +54 -0
- package/src/modules/messages/api/openapi.ts +261 -0
- package/src/modules/messages/api/route.ts +374 -0
- package/src/modules/messages/api/token/[token]/route.ts +103 -0
- package/src/modules/messages/api/types/route.ts +39 -0
- package/src/modules/messages/api/unread-count/route.ts +55 -0
- package/src/modules/messages/backend/messages/[id]/page.meta.ts +12 -0
- package/src/modules/messages/backend/messages/[id]/page.tsx +12 -0
- package/src/modules/messages/backend/messages/compose/page.meta.ts +13 -0
- package/src/modules/messages/backend/messages/compose/page.tsx +12 -0
- package/src/modules/messages/backend/page.meta.ts +31 -0
- package/src/modules/messages/backend/page.tsx +12 -0
- package/src/modules/messages/commands/actions.ts +307 -0
- package/src/modules/messages/commands/attachments.ts +227 -0
- package/src/modules/messages/commands/confirmations.ts +183 -0
- package/src/modules/messages/commands/conversation.ts +292 -0
- package/src/modules/messages/commands/messages.ts +845 -0
- package/src/modules/messages/commands/recipients.ts +281 -0
- package/src/modules/messages/commands/shared.ts +350 -0
- package/src/modules/messages/commands/tokens.ts +80 -0
- package/src/modules/messages/components/ComposeMessagePageClient.tsx +23 -0
- package/src/modules/messages/components/MessageDetailPageClient.tsx +287 -0
- package/src/modules/messages/components/MessagesInboxPageClient.tsx +469 -0
- package/src/modules/messages/components/confirmation/MessageConfirmationActions.tsx +35 -0
- package/src/modules/messages/components/confirmation/MessageConfirmationContent.tsx +88 -0
- package/src/modules/messages/components/defaults/DefaultMessageActions.tsx +37 -0
- package/src/modules/messages/components/defaults/DefaultMessageContent.tsx +21 -0
- package/src/modules/messages/components/defaults/DefaultMessageListItem.tsx +102 -0
- package/src/modules/messages/components/defaults/MessageRecordObjectDetail.tsx +114 -0
- package/src/modules/messages/components/defaults/MessageRecordObjectPreview.tsx +74 -0
- package/src/modules/messages/components/message-detail/detail-panels.ts +13 -0
- package/src/modules/messages/components/message-detail/hooks/useMessageDetails.ts +56 -0
- package/src/modules/messages/components/message-detail/hooks/useMessageDetailsActions.ts +367 -0
- package/src/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.ts +134 -0
- package/src/modules/messages/components/message-detail/hooks/useMessageDetailsQueries.ts +102 -0
- package/src/modules/messages/components/message-detail/panels/MainMessageHeader.tsx +108 -0
- package/src/modules/messages/components/message-detail/panels/MessageHeader.tsx +144 -0
- package/src/modules/messages/components/message-detail/panels/MessageListComponent.tsx +63 -0
- package/src/modules/messages/components/message-detail/panels/actions-panel.tsx +66 -0
- package/src/modules/messages/components/message-detail/panels/attachments-panel.tsx +86 -0
- package/src/modules/messages/components/message-detail/panels/body-panel.tsx +32 -0
- package/src/modules/messages/components/message-detail/panels/composer-dialogs.tsx +42 -0
- package/src/modules/messages/components/message-detail/panels/dialogs.tsx +107 -0
- package/src/modules/messages/components/message-detail/panels/index.ts +11 -0
- package/src/modules/messages/components/message-detail/panels/meta-panel.tsx +19 -0
- package/src/modules/messages/components/message-detail/panels/objects-panel.tsx +65 -0
- package/src/modules/messages/components/message-detail/panels/thread-panel.tsx +65 -0
- package/src/modules/messages/components/message-detail/types.ts +114 -0
- package/src/modules/messages/components/message-detail/utils.ts +62 -0
- package/src/modules/messages/components/utils/PriorityBadge.tsx +63 -0
- package/src/modules/messages/components/utils/typeUiRegistry.ts +106 -0
- package/src/modules/messages/data/entities.ts +284 -0
- package/src/modules/messages/data/validators.ts +297 -0
- package/src/modules/messages/emails/MessageEmail.tsx +143 -0
- package/src/modules/messages/events.ts +24 -0
- package/src/modules/messages/frontend/messages/view/[token]/page.meta.ts +5 -0
- package/src/modules/messages/frontend/messages/view/[token]/page.tsx +389 -0
- package/src/modules/messages/i18n/de.json +240 -0
- package/src/modules/messages/i18n/en.json +240 -0
- package/src/modules/messages/i18n/es.json +240 -0
- package/src/modules/messages/i18n/pl.json +240 -0
- package/src/modules/messages/index.ts +19 -0
- package/src/modules/messages/lib/actions.ts +204 -0
- package/src/modules/messages/lib/attachments.ts +197 -0
- package/src/modules/messages/lib/constants.ts +2 -0
- package/src/modules/messages/lib/email-sender.ts +255 -0
- package/src/modules/messages/lib/forwarding.ts +240 -0
- package/src/modules/messages/lib/message-objects-registry.ts +60 -0
- package/src/modules/messages/lib/message-types-registry.ts +48 -0
- package/src/modules/messages/lib/object-validation.ts +26 -0
- package/src/modules/messages/lib/operationMetadata.ts +43 -0
- package/src/modules/messages/lib/priorityUtils.ts +76 -0
- package/src/modules/messages/lib/routeHelpers.ts +65 -0
- package/src/modules/messages/message-objects.ts +5 -0
- package/src/modules/messages/message-types.ts +65 -0
- package/src/modules/messages/migrations/.snapshot-open-mercato.json +957 -0
- package/src/modules/messages/migrations/Migration20260213181243.ts +34 -0
- package/src/modules/messages/migrations/Migration20260215165126.ts +16 -0
- package/src/modules/messages/notifications.ts +25 -0
- package/src/modules/messages/setup.ts +19 -0
- package/src/modules/messages/subscribers/message-notification.ts +138 -0
- package/src/modules/messages/workers/send-email.worker.ts +321 -0
- package/src/modules/query_index/i18n/es.json +2 -2
- package/src/modules/resources/i18n/de.json +57 -0
- package/src/modules/resources/i18n/en.json +57 -0
- package/src/modules/resources/i18n/es.json +57 -0
- package/src/modules/resources/i18n/pl.json +57 -0
- package/src/modules/sales/backend/sales/documents/[id]/page.tsx +23 -7
- package/src/modules/sales/commands/payments.ts +12 -6
- package/src/modules/sales/i18n/de.json +26 -0
- package/src/modules/sales/i18n/en.json +26 -0
- package/src/modules/sales/i18n/es.json +26 -0
- package/src/modules/sales/i18n/pl.json +26 -0
- package/src/modules/sales/lib/messageObjectPreviews.ts +150 -0
- package/src/modules/sales/message-objects.ts +56 -0
- package/src/modules/sales/widgets/messages/SalesDocumentMessageDetail.tsx +57 -0
- package/src/modules/sales/widgets/messages/SalesDocumentMessagePreview.tsx +46 -0
- package/src/modules/sales/widgets/messages/index.ts +2 -0
- package/src/modules/staff/backend/staff/leave-requests/[id]/page.tsx +54 -0
- package/src/modules/staff/backend/staff/my-leave-requests/[id]/page.tsx +58 -0
- package/src/modules/staff/backend/staff/team-members/[id]/page.tsx +2 -32
- package/src/modules/staff/components/LeaveRequestDetail.tsx +135 -0
- package/src/modules/staff/components/LeaveRequestForm.tsx +3 -0
- package/src/modules/staff/components/LeaveRequestPreview.tsx +74 -0
- package/src/modules/staff/i18n/de.json +22 -0
- package/src/modules/staff/i18n/en.json +22 -0
- package/src/modules/staff/i18n/es.json +22 -0
- package/src/modules/staff/i18n/pl.json +22 -0
- package/src/modules/staff/lib/messageObjectPreviews.ts +182 -0
- package/src/modules/staff/message-objects.ts +102 -0
- package/src/modules/staff/message-types.ts +21 -0
- package/src/modules/staff/widgets/messages/StaffMessageObjectDetail.tsx +57 -0
- package/src/modules/staff/widgets/messages/StaffMessageObjectPreview.tsx +44 -0
- package/src/modules/staff/widgets/messages/index.ts +2 -0
- package/src/modules/workflows/backend/definitions/visual-editor/page.tsx +6 -6
- package/src/modules/workflows/i18n/de.json +41 -0
- package/src/modules/workflows/i18n/en.json +41 -0
- package/src/modules/workflows/i18n/es.json +41 -0
- package/src/modules/workflows/i18n/pl.json +41 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { getMessageObjectType } from "./message-objects-registry.js";
|
|
2
|
+
import { getMessageType } from "./message-types-registry.js";
|
|
3
|
+
function normalizeActionLabel(action, fallback) {
|
|
4
|
+
if (typeof action.label === "string" && action.label.trim().length > 0) {
|
|
5
|
+
return action.label;
|
|
6
|
+
}
|
|
7
|
+
if (typeof fallback === "string" && fallback.trim().length > 0) {
|
|
8
|
+
return fallback.trim();
|
|
9
|
+
}
|
|
10
|
+
return action.id;
|
|
11
|
+
}
|
|
12
|
+
function isTerminalMessageAction(action) {
|
|
13
|
+
if (typeof action.isTerminal === "boolean") return action.isTerminal;
|
|
14
|
+
if (typeof action.commandId === "string" && action.commandId.trim().length > 0) return true;
|
|
15
|
+
if (typeof action.href === "string" && action.href.trim().length > 0) return false;
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
function buildMessageObjectActionId(objectId, actionId) {
|
|
19
|
+
return `object:${objectId}:${actionId}`;
|
|
20
|
+
}
|
|
21
|
+
function readActionDataExpiry(message) {
|
|
22
|
+
if (message.actionData?.expiresAt) return message.actionData.expiresAt;
|
|
23
|
+
const messageType = getMessageType(message.type);
|
|
24
|
+
if (!messageType?.actionsExpireAfterHours || !message.sentAt) return void 0;
|
|
25
|
+
return new Date(
|
|
26
|
+
message.sentAt.getTime() + messageType.actionsExpireAfterHours * 60 * 60 * 1e3
|
|
27
|
+
).toISOString();
|
|
28
|
+
}
|
|
29
|
+
function buildResolvedMessageActions(message, objects) {
|
|
30
|
+
const resolved = [];
|
|
31
|
+
const usedIds = /* @__PURE__ */ new Set();
|
|
32
|
+
const pushAction = (action, source, objectRef, labelFallback) => {
|
|
33
|
+
const id = typeof action.id === "string" ? action.id.trim() : "";
|
|
34
|
+
if (!id || usedIds.has(id)) return;
|
|
35
|
+
usedIds.add(id);
|
|
36
|
+
resolved.push({
|
|
37
|
+
...action,
|
|
38
|
+
id,
|
|
39
|
+
label: normalizeActionLabel(action, labelFallback),
|
|
40
|
+
source,
|
|
41
|
+
objectRef
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
for (const action of message.actionData?.actions ?? []) {
|
|
45
|
+
pushAction(action, "message");
|
|
46
|
+
}
|
|
47
|
+
const messageType = getMessageType(message.type);
|
|
48
|
+
for (const action of messageType?.defaultActions ?? []) {
|
|
49
|
+
pushAction(action, "type_default");
|
|
50
|
+
}
|
|
51
|
+
for (const object of objects) {
|
|
52
|
+
if (!object.actionRequired || !object.actionType) continue;
|
|
53
|
+
const objectType = getMessageObjectType(object.entityModule, object.entityType);
|
|
54
|
+
if (!objectType) continue;
|
|
55
|
+
const actionDef = objectType.actions.find((entry) => entry.id === object.actionType);
|
|
56
|
+
if (!actionDef) continue;
|
|
57
|
+
pushAction(
|
|
58
|
+
{
|
|
59
|
+
id: buildMessageObjectActionId(object.id, actionDef.id),
|
|
60
|
+
label: object.actionLabel ?? actionDef.id,
|
|
61
|
+
labelKey: actionDef.labelKey,
|
|
62
|
+
variant: actionDef.variant,
|
|
63
|
+
icon: actionDef.icon,
|
|
64
|
+
commandId: actionDef.commandId,
|
|
65
|
+
href: actionDef.href,
|
|
66
|
+
isTerminal: actionDef.isTerminal,
|
|
67
|
+
confirmRequired: actionDef.confirmRequired,
|
|
68
|
+
confirmMessage: actionDef.confirmMessage
|
|
69
|
+
},
|
|
70
|
+
"object",
|
|
71
|
+
{
|
|
72
|
+
objectId: object.id,
|
|
73
|
+
entityModule: object.entityModule,
|
|
74
|
+
entityType: object.entityType,
|
|
75
|
+
entityId: object.entityId
|
|
76
|
+
},
|
|
77
|
+
object.actionLabel ?? actionDef.id
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
const expiresAt = readActionDataExpiry(message);
|
|
81
|
+
if (resolved.length === 0 && !expiresAt) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
const configuredPrimaryActionId = message.actionData?.primaryActionId;
|
|
85
|
+
const primaryActionId = configuredPrimaryActionId && resolved.some((entry) => entry.id === configuredPrimaryActionId) ? configuredPrimaryActionId : resolved[0]?.id;
|
|
86
|
+
return {
|
|
87
|
+
actions: resolved,
|
|
88
|
+
primaryActionId,
|
|
89
|
+
expiresAt
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
function findResolvedMessageActionById(message, objects, actionId) {
|
|
93
|
+
const actionData = buildResolvedMessageActions(message, objects);
|
|
94
|
+
const match = actionData?.actions.find((entry) => entry.id === actionId);
|
|
95
|
+
return match ?? null;
|
|
96
|
+
}
|
|
97
|
+
function buildTemplateContext(message, resolutionContext, objectRef) {
|
|
98
|
+
return {
|
|
99
|
+
messageId: message.id,
|
|
100
|
+
sourceEntityId: message.sourceEntityId ?? message.id,
|
|
101
|
+
sourceEntityType: message.sourceEntityType ?? null,
|
|
102
|
+
threadId: message.threadId ?? null,
|
|
103
|
+
parentMessageId: message.parentMessageId ?? null,
|
|
104
|
+
messageType: message.type,
|
|
105
|
+
tenantId: resolutionContext.tenantId,
|
|
106
|
+
organizationId: resolutionContext.organizationId ?? null,
|
|
107
|
+
userId: resolutionContext.userId,
|
|
108
|
+
objectId: objectRef?.objectId ?? null,
|
|
109
|
+
entityId: objectRef?.entityId ?? null,
|
|
110
|
+
entityType: objectRef?.entityType ?? null,
|
|
111
|
+
entityModule: objectRef?.entityModule ?? null
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
function resolveTemplateString(template, context) {
|
|
115
|
+
return template.replace(/\{([a-zA-Z0-9_]+)\}/g, (fullMatch, key) => {
|
|
116
|
+
const value = context[key];
|
|
117
|
+
if (value == null) return fullMatch;
|
|
118
|
+
return String(value);
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
function resolveActionHref(action, message, resolutionContext) {
|
|
122
|
+
if (!action.href) return null;
|
|
123
|
+
const context = buildTemplateContext(message, resolutionContext, action.objectRef);
|
|
124
|
+
return resolveTemplateString(action.href, context);
|
|
125
|
+
}
|
|
126
|
+
function resolveActionCommandInput(action, message, _resolutionContext, requestInput) {
|
|
127
|
+
return {
|
|
128
|
+
...requestInput,
|
|
129
|
+
messageId: message.id,
|
|
130
|
+
actionId: action.id
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
export {
|
|
134
|
+
buildMessageObjectActionId,
|
|
135
|
+
buildResolvedMessageActions,
|
|
136
|
+
findResolvedMessageActionById,
|
|
137
|
+
isTerminalMessageAction,
|
|
138
|
+
resolveActionCommandInput,
|
|
139
|
+
resolveActionHref
|
|
140
|
+
};
|
|
141
|
+
//# sourceMappingURL=actions.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/messages/lib/actions.ts"],
|
|
4
|
+
"sourcesContent": ["import type { Message, MessageAction, MessageActionData, MessageObject } from '../data/entities'\nimport { getMessageObjectType } from './message-objects-registry'\nimport { getMessageType } from './message-types-registry'\n\ntype MessageActionSource = 'message' | 'type_default' | 'object'\n\nexport type MessageActionObjectRef = {\n objectId: string\n entityModule: string\n entityType: string\n entityId: string\n}\n\nexport type ResolvedMessageAction = MessageAction & {\n source: MessageActionSource\n objectRef?: MessageActionObjectRef\n}\n\nexport type MessageActionResolutionContext = {\n tenantId: string\n organizationId?: string | null\n userId: string\n}\n\nfunction normalizeActionLabel(\n action: Pick<MessageAction, 'label' | 'id'>,\n fallback?: string | null,\n): string {\n if (typeof action.label === 'string' && action.label.trim().length > 0) {\n return action.label\n }\n if (typeof fallback === 'string' && fallback.trim().length > 0) {\n return fallback.trim()\n }\n return action.id\n}\n\nexport function isTerminalMessageAction(\n action: Pick<MessageAction, 'isTerminal' | 'commandId' | 'href'>,\n): boolean {\n if (typeof action.isTerminal === 'boolean') return action.isTerminal\n if (typeof action.commandId === 'string' && action.commandId.trim().length > 0) return true\n if (typeof action.href === 'string' && action.href.trim().length > 0) return false\n return true\n}\n\nexport function buildMessageObjectActionId(objectId: string, actionId: string): string {\n return `object:${objectId}:${actionId}`\n}\n\nfunction readActionDataExpiry(message: Message): string | undefined {\n if (message.actionData?.expiresAt) return message.actionData.expiresAt\n const messageType = getMessageType(message.type)\n if (!messageType?.actionsExpireAfterHours || !message.sentAt) return undefined\n return new Date(\n message.sentAt.getTime() + messageType.actionsExpireAfterHours * 60 * 60 * 1000,\n ).toISOString()\n}\n\nexport function buildResolvedMessageActions(\n message: Message,\n objects: MessageObject[],\n): MessageActionData | null {\n const resolved: ResolvedMessageAction[] = []\n const usedIds = new Set<string>()\n\n const pushAction = (\n action: MessageAction,\n source: MessageActionSource,\n objectRef?: MessageActionObjectRef,\n labelFallback?: string | null,\n ) => {\n const id = typeof action.id === 'string' ? action.id.trim() : ''\n if (!id || usedIds.has(id)) return\n usedIds.add(id)\n\n resolved.push({\n ...action,\n id,\n label: normalizeActionLabel(action, labelFallback),\n source,\n objectRef,\n })\n }\n\n for (const action of message.actionData?.actions ?? []) {\n pushAction(action, 'message')\n }\n\n const messageType = getMessageType(message.type)\n for (const action of messageType?.defaultActions ?? []) {\n pushAction(action, 'type_default')\n }\n\n for (const object of objects) {\n if (!object.actionRequired || !object.actionType) continue\n const objectType = getMessageObjectType(object.entityModule, object.entityType)\n if (!objectType) continue\n const actionDef = objectType.actions.find((entry) => entry.id === object.actionType)\n if (!actionDef) continue\n\n pushAction(\n {\n id: buildMessageObjectActionId(object.id, actionDef.id),\n label: object.actionLabel ?? actionDef.id,\n labelKey: actionDef.labelKey,\n variant: actionDef.variant,\n icon: actionDef.icon,\n commandId: actionDef.commandId,\n href: actionDef.href,\n isTerminal: actionDef.isTerminal,\n confirmRequired: actionDef.confirmRequired,\n confirmMessage: actionDef.confirmMessage,\n },\n 'object',\n {\n objectId: object.id,\n entityModule: object.entityModule,\n entityType: object.entityType,\n entityId: object.entityId,\n },\n object.actionLabel ?? actionDef.id,\n )\n }\n\n const expiresAt = readActionDataExpiry(message)\n if (resolved.length === 0 && !expiresAt) {\n return null\n }\n\n const configuredPrimaryActionId = message.actionData?.primaryActionId\n const primaryActionId = configuredPrimaryActionId && resolved.some((entry) => entry.id === configuredPrimaryActionId)\n ? configuredPrimaryActionId\n : resolved[0]?.id\n\n return {\n actions: resolved,\n primaryActionId,\n expiresAt,\n }\n}\n\nexport function findResolvedMessageActionById(\n message: Message,\n objects: MessageObject[],\n actionId: string,\n): ResolvedMessageAction | null {\n const actionData = buildResolvedMessageActions(message, objects)\n const match = actionData?.actions.find((entry) => entry.id === actionId)\n return (match as ResolvedMessageAction | undefined) ?? null\n}\n\nfunction buildTemplateContext(\n message: Message,\n resolutionContext: MessageActionResolutionContext,\n objectRef?: MessageActionObjectRef,\n): Record<string, unknown> {\n return {\n messageId: message.id,\n sourceEntityId: message.sourceEntityId ?? message.id,\n sourceEntityType: message.sourceEntityType ?? null,\n threadId: message.threadId ?? null,\n parentMessageId: message.parentMessageId ?? null,\n messageType: message.type,\n tenantId: resolutionContext.tenantId,\n organizationId: resolutionContext.organizationId ?? null,\n userId: resolutionContext.userId,\n objectId: objectRef?.objectId ?? null,\n entityId: objectRef?.entityId ?? null,\n entityType: objectRef?.entityType ?? null,\n entityModule: objectRef?.entityModule ?? null,\n }\n}\n\nfunction resolveTemplateString(template: string, context: Record<string, unknown>): string {\n return template.replace(/\\{([a-zA-Z0-9_]+)\\}/g, (fullMatch, key: string) => {\n const value = context[key]\n if (value == null) return fullMatch\n return String(value)\n })\n}\n\nexport function resolveActionHref(\n action: ResolvedMessageAction,\n message: Message,\n resolutionContext: MessageActionResolutionContext,\n): string | null {\n if (!action.href) return null\n const context = buildTemplateContext(message, resolutionContext, action.objectRef)\n return resolveTemplateString(action.href, context)\n}\n\nexport function resolveActionCommandInput(\n action: ResolvedMessageAction,\n message: Message,\n _resolutionContext: MessageActionResolutionContext,\n requestInput: Record<string, unknown>,\n): Record<string, unknown> {\n return {\n ...requestInput,\n messageId: message.id,\n actionId: action.id,\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { MESSAGE_ATTACHMENT_ENTITY_ID } from "./constants.js";
|
|
2
|
+
const LIBRARY_ATTACHMENT_ENTITY_ID = "attachments:library";
|
|
3
|
+
function buildOrganizationScopeFilter(organizationId) {
|
|
4
|
+
if (!organizationId) {
|
|
5
|
+
return { organizationId: null };
|
|
6
|
+
}
|
|
7
|
+
return {
|
|
8
|
+
$or: [
|
|
9
|
+
{ organizationId },
|
|
10
|
+
{ organizationId: null }
|
|
11
|
+
]
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
async function linkAttachmentsToMessage(em, messageId, attachmentIds, organizationId, tenantId) {
|
|
15
|
+
if (attachmentIds.length === 0) return;
|
|
16
|
+
const { Attachment } = await import("@open-mercato/core/modules/attachments/data/entities");
|
|
17
|
+
const attachments = await em.find(Attachment, {
|
|
18
|
+
id: { $in: attachmentIds },
|
|
19
|
+
tenantId,
|
|
20
|
+
...buildOrganizationScopeFilter(organizationId)
|
|
21
|
+
});
|
|
22
|
+
for (const attachment of attachments) {
|
|
23
|
+
attachment.entityId = MESSAGE_ATTACHMENT_ENTITY_ID;
|
|
24
|
+
attachment.recordId = messageId;
|
|
25
|
+
}
|
|
26
|
+
await em.flush();
|
|
27
|
+
}
|
|
28
|
+
async function getMessageAttachments(em, messageId, organizationId, tenantId) {
|
|
29
|
+
const { Attachment } = await import("@open-mercato/core/modules/attachments/data/entities");
|
|
30
|
+
const attachments = await em.find(Attachment, {
|
|
31
|
+
entityId: MESSAGE_ATTACHMENT_ENTITY_ID,
|
|
32
|
+
recordId: messageId,
|
|
33
|
+
tenantId,
|
|
34
|
+
...buildOrganizationScopeFilter(organizationId)
|
|
35
|
+
});
|
|
36
|
+
return attachments.map((attachment) => ({
|
|
37
|
+
id: attachment.id,
|
|
38
|
+
fileName: attachment.fileName,
|
|
39
|
+
fileSize: attachment.fileSize,
|
|
40
|
+
mimeType: attachment.mimeType,
|
|
41
|
+
url: attachment.url
|
|
42
|
+
}));
|
|
43
|
+
}
|
|
44
|
+
async function getMessageEmailAttachments(em, messageId, organizationId, tenantId) {
|
|
45
|
+
const { Attachment } = await import("@open-mercato/core/modules/attachments/data/entities");
|
|
46
|
+
const attachments = await em.find(Attachment, {
|
|
47
|
+
entityId: MESSAGE_ATTACHMENT_ENTITY_ID,
|
|
48
|
+
recordId: messageId,
|
|
49
|
+
tenantId,
|
|
50
|
+
...buildOrganizationScopeFilter(organizationId)
|
|
51
|
+
});
|
|
52
|
+
return attachments.map((attachment) => ({
|
|
53
|
+
fileName: attachment.fileName,
|
|
54
|
+
fileSize: attachment.fileSize,
|
|
55
|
+
mimeType: attachment.mimeType,
|
|
56
|
+
partitionCode: attachment.partitionCode,
|
|
57
|
+
storagePath: attachment.storagePath,
|
|
58
|
+
storageDriver: attachment.storageDriver
|
|
59
|
+
}));
|
|
60
|
+
}
|
|
61
|
+
async function linkLibraryAttachmentsToMessage(em, messageId, sourceRecordId, organizationId, tenantId) {
|
|
62
|
+
if (!sourceRecordId.trim()) return;
|
|
63
|
+
const { Attachment } = await import("@open-mercato/core/modules/attachments/data/entities");
|
|
64
|
+
const attachments = await em.find(Attachment, {
|
|
65
|
+
entityId: LIBRARY_ATTACHMENT_ENTITY_ID,
|
|
66
|
+
recordId: sourceRecordId,
|
|
67
|
+
tenantId,
|
|
68
|
+
...buildOrganizationScopeFilter(organizationId)
|
|
69
|
+
});
|
|
70
|
+
if (!attachments.length) return;
|
|
71
|
+
for (const attachment of attachments) {
|
|
72
|
+
attachment.entityId = MESSAGE_ATTACHMENT_ENTITY_ID;
|
|
73
|
+
attachment.recordId = messageId;
|
|
74
|
+
}
|
|
75
|
+
await em.flush();
|
|
76
|
+
}
|
|
77
|
+
async function copyAttachmentsForForward(em, sourceMessageId, targetMessageId, organizationId, tenantId) {
|
|
78
|
+
return copyAttachmentsForForwardMessages(
|
|
79
|
+
em,
|
|
80
|
+
[sourceMessageId],
|
|
81
|
+
targetMessageId,
|
|
82
|
+
organizationId,
|
|
83
|
+
tenantId
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
async function copyAttachmentsForForwardMessages(em, sourceMessageIds, targetMessageId, targetOrganizationId, tenantId) {
|
|
87
|
+
if (sourceMessageIds.length === 0) return 0;
|
|
88
|
+
const { Attachment } = await import("@open-mercato/core/modules/attachments/data/entities");
|
|
89
|
+
const sourceAttachments = await em.find(Attachment, {
|
|
90
|
+
entityId: MESSAGE_ATTACHMENT_ENTITY_ID,
|
|
91
|
+
recordId: { $in: sourceMessageIds },
|
|
92
|
+
tenantId
|
|
93
|
+
});
|
|
94
|
+
if (sourceAttachments.length === 0) {
|
|
95
|
+
return 0;
|
|
96
|
+
}
|
|
97
|
+
const dedupedById = /* @__PURE__ */ new Map();
|
|
98
|
+
for (const sourceAttachment of sourceAttachments) {
|
|
99
|
+
if (!dedupedById.has(sourceAttachment.id)) {
|
|
100
|
+
dedupedById.set(sourceAttachment.id, sourceAttachment);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
for (const sourceAttachment of dedupedById.values()) {
|
|
104
|
+
const copy = em.create(Attachment, {
|
|
105
|
+
entityId: MESSAGE_ATTACHMENT_ENTITY_ID,
|
|
106
|
+
recordId: targetMessageId,
|
|
107
|
+
organizationId: targetOrganizationId,
|
|
108
|
+
tenantId,
|
|
109
|
+
fileName: sourceAttachment.fileName,
|
|
110
|
+
mimeType: sourceAttachment.mimeType,
|
|
111
|
+
fileSize: sourceAttachment.fileSize,
|
|
112
|
+
storageDriver: sourceAttachment.storageDriver,
|
|
113
|
+
storagePath: sourceAttachment.storagePath,
|
|
114
|
+
storageMetadata: sourceAttachment.storageMetadata,
|
|
115
|
+
url: sourceAttachment.url,
|
|
116
|
+
partitionCode: sourceAttachment.partitionCode
|
|
117
|
+
});
|
|
118
|
+
em.persist(copy);
|
|
119
|
+
}
|
|
120
|
+
await em.flush();
|
|
121
|
+
return dedupedById.size;
|
|
122
|
+
}
|
|
123
|
+
export {
|
|
124
|
+
copyAttachmentsForForward,
|
|
125
|
+
copyAttachmentsForForwardMessages,
|
|
126
|
+
getMessageAttachments,
|
|
127
|
+
getMessageEmailAttachments,
|
|
128
|
+
linkAttachmentsToMessage,
|
|
129
|
+
linkLibraryAttachmentsToMessage
|
|
130
|
+
};
|
|
131
|
+
//# sourceMappingURL=attachments.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/messages/lib/attachments.ts"],
|
|
4
|
+
"sourcesContent": ["import type { EntityManager } from '@mikro-orm/core'\nimport { MESSAGE_ATTACHMENT_ENTITY_ID } from './constants'\nconst LIBRARY_ATTACHMENT_ENTITY_ID = 'attachments:library'\n\nfunction buildOrganizationScopeFilter(organizationId: string | null) {\n if (!organizationId) {\n return { organizationId: null }\n }\n return {\n $or: [\n { organizationId },\n { organizationId: null },\n ],\n }\n}\n\nexport async function linkAttachmentsToMessage(\n em: EntityManager,\n messageId: string,\n attachmentIds: string[],\n organizationId: string | null,\n tenantId: string,\n): Promise<void> {\n if (attachmentIds.length === 0) return\n\n const { Attachment } = await import('@open-mercato/core/modules/attachments/data/entities')\n\n const attachments = await em.find(Attachment, {\n id: { $in: attachmentIds },\n tenantId,\n ...buildOrganizationScopeFilter(organizationId),\n })\n\n for (const attachment of attachments) {\n attachment.entityId = MESSAGE_ATTACHMENT_ENTITY_ID\n attachment.recordId = messageId\n }\n\n await em.flush()\n}\n\nexport async function getMessageAttachments(\n em: EntityManager,\n messageId: string,\n organizationId: string | null,\n tenantId: string,\n): Promise<Array<{\n id: string\n fileName: string\n fileSize: number\n mimeType: string\n url: string\n}>> {\n const { Attachment } = await import('@open-mercato/core/modules/attachments/data/entities')\n\n const attachments = await em.find(Attachment, {\n entityId: MESSAGE_ATTACHMENT_ENTITY_ID,\n recordId: messageId,\n tenantId,\n ...buildOrganizationScopeFilter(organizationId),\n })\n\n return attachments.map((attachment) => ({\n id: attachment.id,\n fileName: attachment.fileName,\n fileSize: attachment.fileSize,\n mimeType: attachment.mimeType,\n url: attachment.url,\n }))\n}\n\nexport type MessageEmailAttachment = {\n fileName: string\n fileSize: number\n mimeType: string\n partitionCode: string\n storagePath: string\n storageDriver: string\n}\n\nexport async function getMessageEmailAttachments(\n em: EntityManager,\n messageId: string,\n organizationId: string | null,\n tenantId: string,\n): Promise<MessageEmailAttachment[]> {\n const { Attachment } = await import('@open-mercato/core/modules/attachments/data/entities')\n\n const attachments = await em.find(Attachment, {\n entityId: MESSAGE_ATTACHMENT_ENTITY_ID,\n recordId: messageId,\n tenantId,\n ...buildOrganizationScopeFilter(organizationId),\n })\n\n return attachments.map((attachment) => ({\n fileName: attachment.fileName,\n fileSize: attachment.fileSize,\n mimeType: attachment.mimeType,\n partitionCode: attachment.partitionCode,\n storagePath: attachment.storagePath,\n storageDriver: attachment.storageDriver,\n }))\n}\n\nexport async function linkLibraryAttachmentsToMessage(\n em: EntityManager,\n messageId: string,\n sourceRecordId: string,\n organizationId: string | null,\n tenantId: string,\n): Promise<void> {\n if (!sourceRecordId.trim()) return\n\n const { Attachment } = await import('@open-mercato/core/modules/attachments/data/entities')\n\n const attachments = await em.find(Attachment, {\n entityId: LIBRARY_ATTACHMENT_ENTITY_ID,\n recordId: sourceRecordId,\n tenantId,\n ...buildOrganizationScopeFilter(organizationId),\n })\n\n if (!attachments.length) return\n\n for (const attachment of attachments) {\n attachment.entityId = MESSAGE_ATTACHMENT_ENTITY_ID\n attachment.recordId = messageId\n }\n\n await em.flush()\n}\n\nexport async function copyAttachmentsForForward(\n em: EntityManager,\n sourceMessageId: string,\n targetMessageId: string,\n organizationId: string | null,\n tenantId: string,\n): Promise<number> {\n return copyAttachmentsForForwardMessages(\n em,\n [sourceMessageId],\n targetMessageId,\n organizationId,\n tenantId,\n )\n}\n\nexport async function copyAttachmentsForForwardMessages(\n em: EntityManager,\n sourceMessageIds: string[],\n targetMessageId: string,\n targetOrganizationId: string | null,\n tenantId: string,\n): Promise<number> {\n if (sourceMessageIds.length === 0) return 0\n\n const { Attachment } = await import('@open-mercato/core/modules/attachments/data/entities')\n const sourceAttachments = await em.find(Attachment, {\n entityId: MESSAGE_ATTACHMENT_ENTITY_ID,\n recordId: { $in: sourceMessageIds },\n tenantId,\n })\n if (sourceAttachments.length === 0) {\n return 0\n }\n\n const dedupedById = new Map<string, typeof sourceAttachments[number]>()\n for (const sourceAttachment of sourceAttachments) {\n if (!dedupedById.has(sourceAttachment.id)) {\n dedupedById.set(sourceAttachment.id, sourceAttachment)\n }\n }\n\n for (const sourceAttachment of dedupedById.values()) {\n const copy = em.create(Attachment, {\n entityId: MESSAGE_ATTACHMENT_ENTITY_ID,\n recordId: targetMessageId,\n organizationId: targetOrganizationId,\n tenantId,\n fileName: sourceAttachment.fileName,\n mimeType: sourceAttachment.mimeType,\n fileSize: sourceAttachment.fileSize,\n storageDriver: sourceAttachment.storageDriver,\n storagePath: sourceAttachment.storagePath,\n storageMetadata: sourceAttachment.storageMetadata,\n url: sourceAttachment.url,\n partitionCode: sourceAttachment.partitionCode,\n })\n\n em.persist(copy)\n }\n\n await em.flush()\n return dedupedById.size\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/messages/lib/constants.ts"],
|
|
4
|
+
"sourcesContent": ["export const MESSAGE_ATTACHMENT_ENTITY_ID = 'messages:message'\nexport const MESSAGE_ATTACHMENT_PARTITION = 'messages'\n"],
|
|
5
|
+
"mappings": "AAAO,MAAM,+BAA+B;AACrC,MAAM,+BAA+B;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import crypto from "node:crypto";
|
|
3
|
+
import { promises as fs } from "fs";
|
|
4
|
+
import { sendEmail } from "@open-mercato/shared/lib/email/send";
|
|
5
|
+
import { loadDictionary } from "@open-mercato/shared/lib/i18n/server";
|
|
6
|
+
import { defaultLocale } from "@open-mercato/shared/lib/i18n/config";
|
|
7
|
+
import { createFallbackTranslator } from "@open-mercato/shared/lib/i18n/translate";
|
|
8
|
+
import { MessageAccessToken } from "../data/entities.js";
|
|
9
|
+
import MessageEmail from "../emails/MessageEmail.js";
|
|
10
|
+
import { resolveAttachmentAbsolutePath } from "../../attachments/lib/storage.js";
|
|
11
|
+
const ACCESS_TOKEN_EXPIRY_HOURS = 24 * 7;
|
|
12
|
+
const DEBUG = process.env.MESSAGES_EMAIL_DEBUG === "true";
|
|
13
|
+
const MAX_EMAIL_ATTACHMENTS = 10;
|
|
14
|
+
const MAX_TOTAL_ATTACHMENT_BYTES = 20 * 1024 * 1024;
|
|
15
|
+
function logDebug(message, details) {
|
|
16
|
+
if (!DEBUG) return;
|
|
17
|
+
if (details) {
|
|
18
|
+
console.log(`[messages:email-sender] ${message}`, details);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
console.log(`[messages:email-sender] ${message}`);
|
|
22
|
+
}
|
|
23
|
+
function resolveAppUrl() {
|
|
24
|
+
const raw = process.env.APP_URL?.trim();
|
|
25
|
+
if (!raw) return null;
|
|
26
|
+
return raw.replace(/\/$/, "");
|
|
27
|
+
}
|
|
28
|
+
function buildSenderLabel(sender) {
|
|
29
|
+
const name = sender.name?.trim();
|
|
30
|
+
if (name) return name;
|
|
31
|
+
const email = sender.email?.trim();
|
|
32
|
+
if (email) return email;
|
|
33
|
+
return "System";
|
|
34
|
+
}
|
|
35
|
+
function generateAccessToken() {
|
|
36
|
+
return crypto.randomBytes(32).toString("hex");
|
|
37
|
+
}
|
|
38
|
+
function resolveObjectLabels(objects) {
|
|
39
|
+
return objects.map((item) => `${item.entityModule}.${item.entityType} (${item.entityId})`);
|
|
40
|
+
}
|
|
41
|
+
async function mapAttachmentsForEmail(messageId, attachments) {
|
|
42
|
+
const resendAttachments = [];
|
|
43
|
+
let totalBytes = 0;
|
|
44
|
+
for (const attachment of attachments.slice(0, MAX_EMAIL_ATTACHMENTS)) {
|
|
45
|
+
const absolutePath = resolveAttachmentAbsolutePath(
|
|
46
|
+
attachment.partitionCode,
|
|
47
|
+
attachment.storagePath,
|
|
48
|
+
attachment.storageDriver
|
|
49
|
+
);
|
|
50
|
+
let buffer;
|
|
51
|
+
try {
|
|
52
|
+
buffer = await fs.readFile(absolutePath);
|
|
53
|
+
} catch (error) {
|
|
54
|
+
logDebug("Attachment skipped: file read failed", {
|
|
55
|
+
messageId,
|
|
56
|
+
fileName: attachment.fileName,
|
|
57
|
+
error: error instanceof Error ? error.message : String(error)
|
|
58
|
+
});
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if (totalBytes + buffer.length > MAX_TOTAL_ATTACHMENT_BYTES) {
|
|
62
|
+
logDebug("Attachment skipped: total size limit exceeded", {
|
|
63
|
+
messageId,
|
|
64
|
+
fileName: attachment.fileName,
|
|
65
|
+
nextTotalBytes: totalBytes + buffer.length
|
|
66
|
+
});
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
totalBytes += buffer.length;
|
|
70
|
+
resendAttachments.push({
|
|
71
|
+
filename: attachment.fileName,
|
|
72
|
+
content: buffer.toString("base64"),
|
|
73
|
+
contentType: attachment.mimeType || void 0
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
return resendAttachments;
|
|
77
|
+
}
|
|
78
|
+
async function renderMarkdownEmailBody(body) {
|
|
79
|
+
const ReactMarkdownModule = await import("react-markdown");
|
|
80
|
+
const remarkGfmModule = await import("remark-gfm");
|
|
81
|
+
const ReactMarkdown = ReactMarkdownModule.default ?? ReactMarkdownModule;
|
|
82
|
+
const remarkGfmPlugin = remarkGfmModule.default ?? remarkGfmModule;
|
|
83
|
+
const { renderToStaticMarkup } = await import("react-dom/server");
|
|
84
|
+
return renderToStaticMarkup(
|
|
85
|
+
React.createElement(ReactMarkdown, { remarkPlugins: [remarkGfmPlugin] }, body)
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
async function buildEmailBodyHtml(message) {
|
|
89
|
+
if (message.bodyFormat !== "markdown") return void 0;
|
|
90
|
+
if (!message.body) return void 0;
|
|
91
|
+
return renderMarkdownEmailBody(message.body);
|
|
92
|
+
}
|
|
93
|
+
async function buildEmailCopy(sentAt) {
|
|
94
|
+
const dict = await loadDictionary(defaultLocale);
|
|
95
|
+
const t = createFallbackTranslator(dict);
|
|
96
|
+
return {
|
|
97
|
+
preview: t("messages.email.preview", "You received a message in Open Mercato"),
|
|
98
|
+
heading: t("messages.email.heading", "New message"),
|
|
99
|
+
from: t("messages.email.from", "From"),
|
|
100
|
+
sentAt: t("messages.email.sentAt", "Sent"),
|
|
101
|
+
sentAtLabel: sentAt.toISOString(),
|
|
102
|
+
viewCta: t("messages.email.viewCta", "View message"),
|
|
103
|
+
attachmentsLabel: t("messages.email.attachments", "Attachments"),
|
|
104
|
+
objectsLabel: t("messages.email.objects", "Related records"),
|
|
105
|
+
footer: t("messages.email.footer", "Open Mercato messages")
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
async function createMessageAccessToken(em, messageId, recipientUserId) {
|
|
109
|
+
const token = generateAccessToken();
|
|
110
|
+
const expiresAt = new Date(Date.now() + ACCESS_TOKEN_EXPIRY_HOURS * 60 * 60 * 1e3);
|
|
111
|
+
const record = em.create(MessageAccessToken, {
|
|
112
|
+
messageId,
|
|
113
|
+
recipientUserId,
|
|
114
|
+
token,
|
|
115
|
+
expiresAt,
|
|
116
|
+
useCount: 0
|
|
117
|
+
});
|
|
118
|
+
await em.persistAndFlush(record);
|
|
119
|
+
logDebug("Created access token", {
|
|
120
|
+
messageId,
|
|
121
|
+
recipientUserId,
|
|
122
|
+
expiresAt: expiresAt.toISOString()
|
|
123
|
+
});
|
|
124
|
+
return token;
|
|
125
|
+
}
|
|
126
|
+
async function sendMessageEmailToRecipient(params) {
|
|
127
|
+
const { em, message, recipientUserId, recipientEmail, sender, objects, attachments } = params;
|
|
128
|
+
const token = await createMessageAccessToken(em, message.id, recipientUserId);
|
|
129
|
+
const appUrl = resolveAppUrl();
|
|
130
|
+
const viewUrl = appUrl ? `${appUrl}/messages/view/${token}` : null;
|
|
131
|
+
if (!appUrl) {
|
|
132
|
+
logDebug("APP_URL missing - email link omitted", { messageId: message.id });
|
|
133
|
+
}
|
|
134
|
+
const copy = await buildEmailCopy(message.sentAt ?? /* @__PURE__ */ new Date());
|
|
135
|
+
const bodyHtml = await buildEmailBodyHtml(message);
|
|
136
|
+
const resendAttachments = await mapAttachmentsForEmail(message.id, attachments);
|
|
137
|
+
logDebug("Sending recipient email via Resend", {
|
|
138
|
+
messageId: message.id,
|
|
139
|
+
recipientUserId,
|
|
140
|
+
recipientEmail,
|
|
141
|
+
hasViewUrl: Boolean(viewUrl),
|
|
142
|
+
attachmentsCount: resendAttachments.length,
|
|
143
|
+
hasApiKey: Boolean(process.env.RESEND_API_KEY),
|
|
144
|
+
from: process.env.EMAIL_FROM ?? null
|
|
145
|
+
});
|
|
146
|
+
await sendEmail({
|
|
147
|
+
to: recipientEmail,
|
|
148
|
+
subject: message.subject,
|
|
149
|
+
react: MessageEmail({
|
|
150
|
+
subject: message.subject,
|
|
151
|
+
body: message.body,
|
|
152
|
+
bodyHtml,
|
|
153
|
+
senderName: buildSenderLabel(sender),
|
|
154
|
+
sentAtLabel: copy.sentAtLabel,
|
|
155
|
+
viewUrl,
|
|
156
|
+
copy,
|
|
157
|
+
attachmentNames: attachments.map((item) => item.fileName),
|
|
158
|
+
objectLabels: resolveObjectLabels(objects)
|
|
159
|
+
}),
|
|
160
|
+
attachments: resendAttachments
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
async function sendMessageEmailToExternal(params) {
|
|
164
|
+
const { message, email, sender, objects, attachments } = params;
|
|
165
|
+
const copy = await buildEmailCopy(message.sentAt ?? /* @__PURE__ */ new Date());
|
|
166
|
+
const bodyHtml = await buildEmailBodyHtml(message);
|
|
167
|
+
const resendAttachments = await mapAttachmentsForEmail(message.id, attachments);
|
|
168
|
+
logDebug("Sending external email via Resend", {
|
|
169
|
+
messageId: message.id,
|
|
170
|
+
email,
|
|
171
|
+
attachmentsCount: resendAttachments.length,
|
|
172
|
+
hasApiKey: Boolean(process.env.RESEND_API_KEY),
|
|
173
|
+
from: process.env.EMAIL_FROM ?? null
|
|
174
|
+
});
|
|
175
|
+
await sendEmail({
|
|
176
|
+
to: email,
|
|
177
|
+
subject: message.subject,
|
|
178
|
+
react: MessageEmail({
|
|
179
|
+
subject: message.subject,
|
|
180
|
+
body: message.body,
|
|
181
|
+
bodyHtml,
|
|
182
|
+
senderName: buildSenderLabel(sender),
|
|
183
|
+
sentAtLabel: copy.sentAtLabel,
|
|
184
|
+
viewUrl: null,
|
|
185
|
+
copy,
|
|
186
|
+
attachmentNames: attachments.map((item) => item.fileName),
|
|
187
|
+
objectLabels: resolveObjectLabels(objects)
|
|
188
|
+
}),
|
|
189
|
+
attachments: resendAttachments
|
|
190
|
+
});
|
|
191
|
+
logDebug("External email sent via Resend", {
|
|
192
|
+
messageId: message.id,
|
|
193
|
+
email
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
export {
|
|
197
|
+
createMessageAccessToken,
|
|
198
|
+
sendMessageEmailToExternal,
|
|
199
|
+
sendMessageEmailToRecipient
|
|
200
|
+
};
|
|
201
|
+
//# sourceMappingURL=email-sender.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/messages/lib/email-sender.ts"],
|
|
4
|
+
"sourcesContent": ["import * as React from 'react'\nimport crypto from 'node:crypto'\nimport { promises as fs } from 'fs'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { sendEmail } from '@open-mercato/shared/lib/email/send'\nimport { loadDictionary } from '@open-mercato/shared/lib/i18n/server'\nimport { defaultLocale } from '@open-mercato/shared/lib/i18n/config'\nimport { createFallbackTranslator } from '@open-mercato/shared/lib/i18n/translate'\nimport type { Message, MessageObject } from '../data/entities'\nimport { MessageAccessToken } from '../data/entities'\nimport MessageEmail from '../emails/MessageEmail'\nimport { resolveAttachmentAbsolutePath } from '../../attachments/lib/storage'\nimport type { MessageEmailAttachment } from './attachments'\n\nconst ACCESS_TOKEN_EXPIRY_HOURS = 24 * 7\nconst DEBUG = process.env.MESSAGES_EMAIL_DEBUG === 'true'\nconst MAX_EMAIL_ATTACHMENTS = 10\nconst MAX_TOTAL_ATTACHMENT_BYTES = 20 * 1024 * 1024\n\nexport type SenderIdentity = {\n name: string | null\n email: string | null\n}\n\nfunction logDebug(message: string, details?: Record<string, unknown>) {\n if (!DEBUG) return\n if (details) {\n console.log(`[messages:email-sender] ${message}`, details)\n return\n }\n console.log(`[messages:email-sender] ${message}`)\n}\n\nfunction resolveAppUrl(): string | null {\n const raw = process.env.APP_URL?.trim()\n if (!raw) return null\n return raw.replace(/\\/$/, '')\n}\n\nfunction buildSenderLabel(sender: SenderIdentity): string {\n const name = sender.name?.trim()\n if (name) return name\n const email = sender.email?.trim()\n if (email) return email\n return 'System'\n}\n\nfunction generateAccessToken(): string {\n return crypto.randomBytes(32).toString('hex')\n}\n\nfunction resolveObjectLabels(objects: MessageObject[]): string[] {\n return objects.map((item) => `${item.entityModule}.${item.entityType} (${item.entityId})`)\n}\n\ntype ResendAttachment = {\n filename: string\n content: string\n contentType?: string\n}\n\nasync function mapAttachmentsForEmail(\n messageId: string,\n attachments: MessageEmailAttachment[],\n): Promise<ResendAttachment[]> {\n const resendAttachments: ResendAttachment[] = []\n let totalBytes = 0\n\n for (const attachment of attachments.slice(0, MAX_EMAIL_ATTACHMENTS)) {\n const absolutePath = resolveAttachmentAbsolutePath(\n attachment.partitionCode,\n attachment.storagePath,\n attachment.storageDriver,\n )\n\n let buffer: Buffer\n try {\n buffer = await fs.readFile(absolutePath)\n } catch (error) {\n logDebug('Attachment skipped: file read failed', {\n messageId,\n fileName: attachment.fileName,\n error: error instanceof Error ? error.message : String(error),\n })\n continue\n }\n\n if ((totalBytes + buffer.length) > MAX_TOTAL_ATTACHMENT_BYTES) {\n logDebug('Attachment skipped: total size limit exceeded', {\n messageId,\n fileName: attachment.fileName,\n nextTotalBytes: totalBytes + buffer.length,\n })\n continue\n }\n\n totalBytes += buffer.length\n resendAttachments.push({\n filename: attachment.fileName,\n content: buffer.toString('base64'),\n contentType: attachment.mimeType || undefined,\n })\n }\n\n return resendAttachments\n}\n\nasync function renderMarkdownEmailBody(body: string) {\n const ReactMarkdownModule = await import('react-markdown')\n const remarkGfmModule = await import('remark-gfm')\n const ReactMarkdown =\n (ReactMarkdownModule.default ?? ReactMarkdownModule) as React.ComponentType<{\n remarkPlugins?: unknown\n children?: React.ReactNode\n }>\n const remarkGfmPlugin = remarkGfmModule.default ?? remarkGfmModule\n const { renderToStaticMarkup } = await import('react-dom/server')\n\n return renderToStaticMarkup(\n React.createElement(ReactMarkdown, { remarkPlugins: [remarkGfmPlugin] }, body),\n )\n}\n\nasync function buildEmailBodyHtml(message: Message): Promise<string | undefined> {\n if (message.bodyFormat !== 'markdown') return undefined\n if (!message.body) return undefined\n return renderMarkdownEmailBody(message.body)\n}\n\nasync function buildEmailCopy(sentAt: Date) {\n const dict = await loadDictionary(defaultLocale)\n const t = createFallbackTranslator(dict)\n return {\n preview: t('messages.email.preview', 'You received a message in Open Mercato'),\n heading: t('messages.email.heading', 'New message'),\n from: t('messages.email.from', 'From'),\n sentAt: t('messages.email.sentAt', 'Sent'),\n sentAtLabel: sentAt.toISOString(),\n viewCta: t('messages.email.viewCta', 'View message'),\n attachmentsLabel: t('messages.email.attachments', 'Attachments'),\n objectsLabel: t('messages.email.objects', 'Related records'),\n footer: t('messages.email.footer', 'Open Mercato messages'),\n }\n}\n\nexport async function createMessageAccessToken(\n em: EntityManager,\n messageId: string,\n recipientUserId: string,\n): Promise<string> {\n const token = generateAccessToken()\n const expiresAt = new Date(Date.now() + ACCESS_TOKEN_EXPIRY_HOURS * 60 * 60 * 1000)\n const record = em.create(MessageAccessToken, {\n messageId,\n recipientUserId,\n token,\n expiresAt,\n useCount: 0,\n })\n await em.persistAndFlush(record)\n logDebug('Created access token', {\n messageId,\n recipientUserId,\n expiresAt: expiresAt.toISOString(),\n })\n return token\n}\n\nexport async function sendMessageEmailToRecipient(params: {\n em: EntityManager\n message: Message\n recipientUserId: string\n recipientEmail: string\n sender: SenderIdentity\n objects: MessageObject[]\n attachments: MessageEmailAttachment[]\n}): Promise<void> {\n const { em, message, recipientUserId, recipientEmail, sender, objects, attachments } = params\n const token = await createMessageAccessToken(em, message.id, recipientUserId)\n const appUrl = resolveAppUrl()\n const viewUrl = appUrl ? `${appUrl}/messages/view/${token}` : null\n if (!appUrl) {\n logDebug('APP_URL missing - email link omitted', { messageId: message.id })\n }\n const copy = await buildEmailCopy(message.sentAt ?? new Date())\n const bodyHtml = await buildEmailBodyHtml(message)\n const resendAttachments = await mapAttachmentsForEmail(message.id, attachments)\n logDebug('Sending recipient email via Resend', {\n messageId: message.id,\n recipientUserId,\n recipientEmail,\n hasViewUrl: Boolean(viewUrl),\n attachmentsCount: resendAttachments.length,\n hasApiKey: Boolean(process.env.RESEND_API_KEY),\n from: process.env.EMAIL_FROM ?? null,\n })\n\n await sendEmail({\n to: recipientEmail,\n subject: message.subject,\n react: MessageEmail({\n subject: message.subject,\n body: message.body,\n bodyHtml,\n senderName: buildSenderLabel(sender),\n sentAtLabel: copy.sentAtLabel,\n viewUrl,\n copy,\n attachmentNames: attachments.map((item) => item.fileName),\n objectLabels: resolveObjectLabels(objects),\n }),\n attachments: resendAttachments,\n })\n}\n\nexport async function sendMessageEmailToExternal(params: {\n message: Message\n email: string\n sender: SenderIdentity\n objects: MessageObject[]\n attachments: MessageEmailAttachment[]\n}): Promise<void> {\n const { message, email, sender, objects, attachments } = params\n const copy = await buildEmailCopy(message.sentAt ?? new Date())\n const bodyHtml = await buildEmailBodyHtml(message)\n const resendAttachments = await mapAttachmentsForEmail(message.id, attachments)\n logDebug('Sending external email via Resend', {\n messageId: message.id,\n email,\n attachmentsCount: resendAttachments.length,\n hasApiKey: Boolean(process.env.RESEND_API_KEY),\n from: process.env.EMAIL_FROM ?? null,\n })\n\n await sendEmail({\n to: email,\n subject: message.subject,\n react: MessageEmail({\n subject: message.subject,\n body: message.body,\n bodyHtml,\n senderName: buildSenderLabel(sender),\n sentAtLabel: copy.sentAtLabel,\n viewUrl: null,\n copy,\n attachmentNames: attachments.map((item) => item.fileName),\n objectLabels: resolveObjectLabels(objects),\n }),\n attachments: resendAttachments,\n })\n logDebug('External email sent via Resend', {\n messageId: message.id,\n email,\n })\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|