@open-mercato/core 0.6.5-develop.4384.1.ce2ec6eaaa → 0.6.5-develop.4393.1.de282b5dfd
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 +2 -2
- package/dist/generated/entities/channel_ingest_dead_letter/index.js +25 -0
- package/dist/generated/entities/channel_ingest_dead_letter/index.js.map +7 -0
- package/dist/generated/entities/channel_thread_mapping/index.js +25 -0
- package/dist/generated/entities/channel_thread_mapping/index.js.map +7 -0
- package/dist/generated/entities/channel_thread_token/index.js +17 -0
- package/dist/generated/entities/channel_thread_token/index.js.map +7 -0
- package/dist/generated/entities/communication_channel/index.js +43 -0
- package/dist/generated/entities/communication_channel/index.js.map +7 -0
- package/dist/generated/entities/customer_interaction/index.js +4 -0
- package/dist/generated/entities/customer_interaction/index.js.map +2 -2
- package/dist/generated/entities/external_conversation/index.js +25 -0
- package/dist/generated/entities/external_conversation/index.js.map +7 -0
- package/dist/generated/entities/external_message/index.js +25 -0
- package/dist/generated/entities/external_message/index.js.map +7 -0
- package/dist/generated/entities/integration_credentials/index.js +3 -1
- package/dist/generated/entities/integration_credentials/index.js.map +2 -2
- package/dist/generated/entities/message/index.js +2 -0
- package/dist/generated/entities/message/index.js.map +2 -2
- package/dist/generated/entities/message_channel_link/index.js +33 -0
- package/dist/generated/entities/message_channel_link/index.js.map +7 -0
- package/dist/generated/entities/message_reaction/index.js +25 -0
- package/dist/generated/entities/message_reaction/index.js.map +7 -0
- package/dist/generated/entities.ids.generated.js +11 -0
- package/dist/generated/entities.ids.generated.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +117 -0
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/helpers/integration/authFixtures.js +2 -1
- package/dist/helpers/integration/authFixtures.js.map +2 -2
- package/dist/helpers/integration/communicationChannelsFixtures.js +58 -0
- package/dist/helpers/integration/communicationChannelsFixtures.js.map +7 -0
- package/dist/modules/communication_channels/acl.js +47 -0
- package/dist/modules/communication_channels/acl.js.map +7 -0
- package/dist/modules/communication_channels/api/delete/channels/[id]/route.js +133 -0
- package/dist/modules/communication_channels/api/delete/channels/[id]/route.js.map +7 -0
- package/dist/modules/communication_channels/api/delete/messages/[messageId]/reactions/[reactionId]/route.js +113 -0
- package/dist/modules/communication_channels/api/delete/messages/[messageId]/reactions/[reactionId]/route.js.map +7 -0
- package/dist/modules/communication_channels/api/get/channels/[id]/health/route.js +138 -0
- package/dist/modules/communication_channels/api/get/channels/[id]/health/route.js.map +7 -0
- package/dist/modules/communication_channels/api/get/channels/[id]/route.js +93 -0
- package/dist/modules/communication_channels/api/get/channels/[id]/route.js.map +7 -0
- package/dist/modules/communication_channels/api/get/channels/route.js +96 -0
- package/dist/modules/communication_channels/api/get/channels/route.js.map +7 -0
- package/dist/modules/communication_channels/api/get/me/channels/route.js +82 -0
- package/dist/modules/communication_channels/api/get/me/channels/route.js.map +7 -0
- package/dist/modules/communication_channels/api/get/oauth/[provider]/callback/route.js +274 -0
- package/dist/modules/communication_channels/api/get/oauth/[provider]/callback/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/channels/[id]/import-history/route.js +168 -0
- package/dist/modules/communication_channels/api/post/channels/[id]/import-history/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/channels/[id]/poll-now/route.js +143 -0
- package/dist/modules/communication_channels/api/post/channels/[id]/poll-now/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/channels/[id]/push/register/route.js +127 -0
- package/dist/modules/communication_channels/api/post/channels/[id]/push/register/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/channels/[id]/set-primary/route.js +99 -0
- package/dist/modules/communication_channels/api/post/channels/[id]/set-primary/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/channels/[id]/test-send/route.js +197 -0
- package/dist/modules/communication_channels/api/post/channels/[id]/test-send/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/channels/connect/credentials/route.js +124 -0
- package/dist/modules/communication_channels/api/post/channels/connect/credentials/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/messages/[messageId]/reactions/route.js +120 -0
- package/dist/modules/communication_channels/api/post/messages/[messageId]/reactions/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/oauth/[provider]/initiate/route.js +157 -0
- package/dist/modules/communication_channels/api/post/oauth/[provider]/initiate/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/send-as-user/route.js +115 -0
- package/dist/modules/communication_channels/api/post/send-as-user/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/test-seed/route.js +217 -0
- package/dist/modules/communication_channels/api/post/test-seed/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/webhook/[provider]/route.js +175 -0
- package/dist/modules/communication_channels/api/post/webhook/[provider]/route.js.map +7 -0
- package/dist/modules/communication_channels/api/post/webhooks/gmail/route.js +123 -0
- package/dist/modules/communication_channels/api/post/webhooks/gmail/route.js.map +7 -0
- package/dist/modules/communication_channels/api/put/threads/[threadId]/assign/route.js +117 -0
- package/dist/modules/communication_channels/api/put/threads/[threadId]/assign/route.js.map +7 -0
- package/dist/modules/communication_channels/backend/communication_channels/channels/[id]/page.js +180 -0
- package/dist/modules/communication_channels/backend/communication_channels/channels/[id]/page.js.map +7 -0
- package/dist/modules/communication_channels/backend/communication_channels/channels/[id]/page.meta.js +36 -0
- package/dist/modules/communication_channels/backend/communication_channels/channels/[id]/page.meta.js.map +7 -0
- package/dist/modules/communication_channels/backend/communication_channels/channels/page.js +107 -0
- package/dist/modules/communication_channels/backend/communication_channels/channels/page.js.map +7 -0
- package/dist/modules/communication_channels/backend/communication_channels/channels/page.meta.js +38 -0
- package/dist/modules/communication_channels/backend/communication_channels/channels/page.meta.js.map +7 -0
- package/dist/modules/communication_channels/backend/profile/communication-channels/page.js +727 -0
- package/dist/modules/communication_channels/backend/profile/communication-channels/page.js.map +7 -0
- package/dist/modules/communication_channels/backend/profile/communication-channels/page.meta.js +38 -0
- package/dist/modules/communication_channels/backend/profile/communication-channels/page.meta.js.map +7 -0
- package/dist/modules/communication_channels/commands/connect-credential-channel.js +154 -0
- package/dist/modules/communication_channels/commands/connect-credential-channel.js.map +7 -0
- package/dist/modules/communication_channels/commands/delete-channel.js +137 -0
- package/dist/modules/communication_channels/commands/delete-channel.js.map +7 -0
- package/dist/modules/communication_channels/commands/deliver-outbound-message.js +400 -0
- package/dist/modules/communication_channels/commands/deliver-outbound-message.js.map +7 -0
- package/dist/modules/communication_channels/commands/disconnect-channel.js +163 -0
- package/dist/modules/communication_channels/commands/disconnect-channel.js.map +7 -0
- package/dist/modules/communication_channels/commands/ingest-inbound-message.js +413 -0
- package/dist/modules/communication_channels/commands/ingest-inbound-message.js.map +7 -0
- package/dist/modules/communication_channels/commands/interceptors.js +68 -0
- package/dist/modules/communication_channels/commands/interceptors.js.map +7 -0
- package/dist/modules/communication_channels/commands/process-inbound-reaction.js +198 -0
- package/dist/modules/communication_channels/commands/process-inbound-reaction.js.map +7 -0
- package/dist/modules/communication_channels/commands/push-register.js +146 -0
- package/dist/modules/communication_channels/commands/push-register.js.map +7 -0
- package/dist/modules/communication_channels/commands/push-renew.js +23 -0
- package/dist/modules/communication_channels/commands/push-renew.js.map +7 -0
- package/dist/modules/communication_channels/commands/push-unregister.js +108 -0
- package/dist/modules/communication_channels/commands/push-unregister.js.map +7 -0
- package/dist/modules/communication_channels/commands/queue-import-history.js +113 -0
- package/dist/modules/communication_channels/commands/queue-import-history.js.map +7 -0
- package/dist/modules/communication_channels/commands/reassign-conversation.js +193 -0
- package/dist/modules/communication_channels/commands/reassign-conversation.js.map +7 -0
- package/dist/modules/communication_channels/commands/set-primary-channel.js +114 -0
- package/dist/modules/communication_channels/commands/set-primary-channel.js.map +7 -0
- package/dist/modules/communication_channels/commands/toggle-outbound-reaction.js +260 -0
- package/dist/modules/communication_channels/commands/toggle-outbound-reaction.js.map +7 -0
- package/dist/modules/communication_channels/data/enrichers.js +286 -0
- package/dist/modules/communication_channels/data/enrichers.js.map +7 -0
- package/dist/modules/communication_channels/data/entities.js +447 -0
- package/dist/modules/communication_channels/data/entities.js.map +7 -0
- package/dist/modules/communication_channels/data/extensions.js +67 -0
- package/dist/modules/communication_channels/data/extensions.js.map +7 -0
- package/dist/modules/communication_channels/data/validators.js +123 -0
- package/dist/modules/communication_channels/data/validators.js.map +7 -0
- package/dist/modules/communication_channels/di.js +35 -0
- package/dist/modules/communication_channels/di.js.map +7 -0
- package/dist/modules/communication_channels/encryption.js +12 -0
- package/dist/modules/communication_channels/encryption.js.map +7 -0
- package/dist/modules/communication_channels/events.js +124 -0
- package/dist/modules/communication_channels/events.js.map +7 -0
- package/dist/modules/communication_channels/index.js +20 -0
- package/dist/modules/communication_channels/index.js.map +7 -0
- package/dist/modules/communication_channels/lib/access-control.js +43 -0
- package/dist/modules/communication_channels/lib/access-control.js.map +7 -0
- package/dist/modules/communication_channels/lib/adapter-compat.js +36 -0
- package/dist/modules/communication_channels/lib/adapter-compat.js.map +7 -0
- package/dist/modules/communication_channels/lib/adapter-registry-singleton.js +22 -0
- package/dist/modules/communication_channels/lib/adapter-registry-singleton.js.map +7 -0
- package/dist/modules/communication_channels/lib/adapter.js +1 -0
- package/dist/modules/communication_channels/lib/adapter.js.map +7 -0
- package/dist/modules/communication_channels/lib/connect-channel.js +95 -0
- package/dist/modules/communication_channels/lib/connect-channel.js.map +7 -0
- package/dist/modules/communication_channels/lib/contact-resolver.js +79 -0
- package/dist/modules/communication_channels/lib/contact-resolver.js.map +7 -0
- package/dist/modules/communication_channels/lib/credential-refresh.js +97 -0
- package/dist/modules/communication_channels/lib/credential-refresh.js.map +7 -0
- package/dist/modules/communication_channels/lib/dead-letter.js +62 -0
- package/dist/modules/communication_channels/lib/dead-letter.js.map +7 -0
- package/dist/modules/communication_channels/lib/email-capabilities.js +47 -0
- package/dist/modules/communication_channels/lib/email-capabilities.js.map +7 -0
- package/dist/modules/communication_channels/lib/email-contact.js +14 -0
- package/dist/modules/communication_channels/lib/email-contact.js.map +7 -0
- package/dist/modules/communication_channels/lib/email-mime.js +259 -0
- package/dist/modules/communication_channels/lib/email-mime.js.map +7 -0
- package/dist/modules/communication_channels/lib/error-classification.js +101 -0
- package/dist/modules/communication_channels/lib/error-classification.js.map +7 -0
- package/dist/modules/communication_channels/lib/gmail-pubsub-jwt.js +185 -0
- package/dist/modules/communication_channels/lib/gmail-pubsub-jwt.js.map +7 -0
- package/dist/modules/communication_channels/lib/mutation-guards.js +114 -0
- package/dist/modules/communication_channels/lib/mutation-guards.js.map +7 -0
- package/dist/modules/communication_channels/lib/oauth-client-config.js +32 -0
- package/dist/modules/communication_channels/lib/oauth-client-config.js.map +7 -0
- package/dist/modules/communication_channels/lib/oauth-state.js +128 -0
- package/dist/modules/communication_channels/lib/oauth-state.js.map +7 -0
- package/dist/modules/communication_channels/lib/oauth-token.js +45 -0
- package/dist/modules/communication_channels/lib/oauth-token.js.map +7 -0
- package/dist/modules/communication_channels/lib/pg-errors.js +11 -0
- package/dist/modules/communication_channels/lib/pg-errors.js.map +7 -0
- package/dist/modules/communication_channels/lib/provider-health.js +24 -0
- package/dist/modules/communication_channels/lib/provider-health.js.map +7 -0
- package/dist/modules/communication_channels/lib/push-state.js +19 -0
- package/dist/modules/communication_channels/lib/push-state.js.map +7 -0
- package/dist/modules/communication_channels/lib/queue.js +54 -0
- package/dist/modules/communication_channels/lib/queue.js.map +7 -0
- package/dist/modules/communication_channels/lib/reaction-processor-types.js +5 -0
- package/dist/modules/communication_channels/lib/reaction-processor-types.js.map +7 -0
- package/dist/modules/communication_channels/lib/reaction-semantics.js +11 -0
- package/dist/modules/communication_channels/lib/reaction-semantics.js.map +7 -0
- package/dist/modules/communication_channels/lib/registry.js +67 -0
- package/dist/modules/communication_channels/lib/registry.js.map +7 -0
- package/dist/modules/communication_channels/lib/route-mutation-guard.js +43 -0
- package/dist/modules/communication_channels/lib/route-mutation-guard.js.map +7 -0
- package/dist/modules/communication_channels/lib/sanitize-channel-html.js +96 -0
- package/dist/modules/communication_channels/lib/sanitize-channel-html.js.map +7 -0
- package/dist/modules/communication_channels/lib/send-as-user.js +194 -0
- package/dist/modules/communication_channels/lib/send-as-user.js.map +7 -0
- package/dist/modules/communication_channels/lib/system-user.js +22 -0
- package/dist/modules/communication_channels/lib/system-user.js.map +7 -0
- package/dist/modules/communication_channels/lib/test-seed.js +68 -0
- package/dist/modules/communication_channels/lib/test-seed.js.map +7 -0
- package/dist/modules/communication_channels/lib/thread-matcher.js +263 -0
- package/dist/modules/communication_channels/lib/thread-matcher.js.map +7 -0
- package/dist/modules/communication_channels/lib/thread-token.js +219 -0
- package/dist/modules/communication_channels/lib/thread-token.js.map +7 -0
- package/dist/modules/communication_channels/lib/use-connect-channel.js +61 -0
- package/dist/modules/communication_channels/lib/use-connect-channel.js.map +7 -0
- package/dist/modules/communication_channels/migrations/Migration20260526134719_communication_channels.js +50 -0
- package/dist/modules/communication_channels/migrations/Migration20260526134719_communication_channels.js.map +7 -0
- package/dist/modules/communication_channels/migrations/Migration20260527195446_communication_channels.js +19 -0
- package/dist/modules/communication_channels/migrations/Migration20260527195446_communication_channels.js.map +7 -0
- package/dist/modules/communication_channels/migrations/Migration20260529231848_communication_channels.js +13 -0
- package/dist/modules/communication_channels/migrations/Migration20260529231848_communication_channels.js.map +7 -0
- package/dist/modules/communication_channels/migrations/Migration20260531120000_communication_channels.js +17 -0
- package/dist/modules/communication_channels/migrations/Migration20260531120000_communication_channels.js.map +7 -0
- package/dist/modules/communication_channels/notifications.client.js +51 -0
- package/dist/modules/communication_channels/notifications.client.js.map +7 -0
- package/dist/modules/communication_channels/notifications.handlers.js +53 -0
- package/dist/modules/communication_channels/notifications.handlers.js.map +7 -0
- package/dist/modules/communication_channels/notifications.js +56 -0
- package/dist/modules/communication_channels/notifications.js.map +7 -0
- package/dist/modules/communication_channels/setup.js +105 -0
- package/dist/modules/communication_channels/setup.js.map +7 -0
- package/dist/modules/communication_channels/subscribers/channel-requires-reauth-notification.js +71 -0
- package/dist/modules/communication_channels/subscribers/channel-requires-reauth-notification.js.map +7 -0
- package/dist/modules/communication_channels/subscribers/outbound-bridge.js +103 -0
- package/dist/modules/communication_channels/subscribers/outbound-bridge.js.map +7 -0
- package/dist/modules/communication_channels/subscribers/user-deleted-cascade.js +51 -0
- package/dist/modules/communication_channels/subscribers/user-deleted-cascade.js.map +7 -0
- package/dist/modules/communication_channels/widgets/components.js +7 -0
- package/dist/modules/communication_channels/widgets/components.js.map +7 -0
- package/dist/modules/communication_channels/widgets/injection/channel-badge/widget.client.js +18 -0
- package/dist/modules/communication_channels/widgets/injection/channel-badge/widget.client.js.map +7 -0
- package/dist/modules/communication_channels/widgets/injection/channel-badge/widget.js +30 -0
- package/dist/modules/communication_channels/widgets/injection/channel-badge/widget.js.map +7 -0
- package/dist/modules/communication_channels/widgets/injection/channel-info-panel/widget.client.js +185 -0
- package/dist/modules/communication_channels/widgets/injection/channel-info-panel/widget.client.js.map +7 -0
- package/dist/modules/communication_channels/widgets/injection/channel-info-panel/widget.js +17 -0
- package/dist/modules/communication_channels/widgets/injection/channel-info-panel/widget.js.map +7 -0
- package/dist/modules/communication_channels/widgets/injection/channel-payload-renderer/widget.client.js +44 -0
- package/dist/modules/communication_channels/widgets/injection/channel-payload-renderer/widget.client.js.map +7 -0
- package/dist/modules/communication_channels/widgets/injection/channel-payload-renderer/widget.js +17 -0
- package/dist/modules/communication_channels/widgets/injection/channel-payload-renderer/widget.js.map +7 -0
- package/dist/modules/communication_channels/widgets/injection/profile-channels-menu/widget.js +23 -0
- package/dist/modules/communication_channels/widgets/injection/profile-channels-menu/widget.js.map +7 -0
- package/dist/modules/communication_channels/widgets/injection/reaction-bar/widget.client.js +141 -0
- package/dist/modules/communication_channels/widgets/injection/reaction-bar/widget.client.js.map +7 -0
- package/dist/modules/communication_channels/widgets/injection/reaction-bar/widget.js +17 -0
- package/dist/modules/communication_channels/widgets/injection/reaction-bar/widget.js.map +7 -0
- package/dist/modules/communication_channels/widgets/injection-table.js +38 -0
- package/dist/modules/communication_channels/widgets/injection-table.js.map +7 -0
- package/dist/modules/communication_channels/widgets/notifications/ChannelRequiresReauthRenderer.js +25 -0
- package/dist/modules/communication_channels/widgets/notifications/ChannelRequiresReauthRenderer.js.map +7 -0
- package/dist/modules/communication_channels/widgets/notifications/MessageReceivedRenderer.js +19 -0
- package/dist/modules/communication_channels/widgets/notifications/MessageReceivedRenderer.js.map +7 -0
- package/dist/modules/communication_channels/widgets/notifications/index.js +7 -0
- package/dist/modules/communication_channels/widgets/notifications/index.js.map +7 -0
- package/dist/modules/communication_channels/workers/channel-import-history.js +185 -0
- package/dist/modules/communication_channels/workers/channel-import-history.js.map +7 -0
- package/dist/modules/communication_channels/workers/gmail-history-sync.js +154 -0
- package/dist/modules/communication_channels/workers/gmail-history-sync.js.map +7 -0
- package/dist/modules/communication_channels/workers/gmail-renew-watch.js +95 -0
- package/dist/modules/communication_channels/workers/gmail-renew-watch.js.map +7 -0
- package/dist/modules/communication_channels/workers/inbound-processor.js +56 -0
- package/dist/modules/communication_channels/workers/inbound-processor.js.map +7 -0
- package/dist/modules/communication_channels/workers/outbound-delivery.js +85 -0
- package/dist/modules/communication_channels/workers/outbound-delivery.js.map +7 -0
- package/dist/modules/communication_channels/workers/poll-channel.js +240 -0
- package/dist/modules/communication_channels/workers/poll-channel.js.map +7 -0
- package/dist/modules/communication_channels/workers/poll-tick.js +132 -0
- package/dist/modules/communication_channels/workers/poll-tick.js.map +7 -0
- package/dist/modules/communication_channels/workers/reaction-processor.js +192 -0
- package/dist/modules/communication_channels/workers/reaction-processor.js.map +7 -0
- package/dist/modules/customers/acl.js +18 -0
- package/dist/modules/customers/acl.js.map +2 -2
- package/dist/modules/customers/api/activities/route.js +9 -0
- package/dist/modules/customers/api/activities/route.js.map +2 -2
- package/dist/modules/customers/api/companies/[id]/route.js +18 -7
- package/dist/modules/customers/api/companies/[id]/route.js.map +2 -2
- package/dist/modules/customers/api/interactions/[id]/visibility/route.js +151 -0
- package/dist/modules/customers/api/interactions/[id]/visibility/route.js.map +7 -0
- package/dist/modules/customers/api/interactions/counts/route.js +6 -0
- package/dist/modules/customers/api/interactions/counts/route.js.map +2 -2
- package/dist/modules/customers/api/interactions/route.js +26 -7
- package/dist/modules/customers/api/interactions/route.js.map +2 -2
- package/dist/modules/customers/api/people/[id]/email-threads/route.js +82 -0
- package/dist/modules/customers/api/people/[id]/email-threads/route.js.map +7 -0
- package/dist/modules/customers/api/people/[id]/emails/route.js +157 -0
- package/dist/modules/customers/api/people/[id]/emails/route.js.map +7 -0
- package/dist/modules/customers/api/people/[id]/route.js +12 -4
- package/dist/modules/customers/api/people/[id]/route.js.map +2 -2
- package/dist/modules/customers/backend/customers/people-v2/[id]/page.js +10 -0
- package/dist/modules/customers/backend/customers/people-v2/[id]/page.js.map +2 -2
- package/dist/modules/customers/commands/deals.js +46 -5
- package/dist/modules/customers/commands/deals.js.map +2 -2
- package/dist/modules/customers/commands/interactions.js +16 -0
- package/dist/modules/customers/commands/interactions.js.map +2 -2
- package/dist/modules/customers/components/detail/ActivityCard.js +32 -0
- package/dist/modules/customers/components/detail/ActivityCard.js.map +2 -2
- package/dist/modules/customers/components/detail/ComposeEmailDialog.js +242 -0
- package/dist/modules/customers/components/detail/ComposeEmailDialog.js.map +7 -0
- package/dist/modules/customers/components/detail/DealForm.js +2 -1
- package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
- package/dist/modules/customers/components/detail/DealsSection.js +10 -0
- package/dist/modules/customers/components/detail/DealsSection.js.map +2 -2
- package/dist/modules/customers/components/detail/EmailCardActions.js +179 -0
- package/dist/modules/customers/components/detail/EmailCardActions.js.map +7 -0
- package/dist/modules/customers/components/detail/EmailReplyForwardActions.js +52 -0
- package/dist/modules/customers/components/detail/EmailReplyForwardActions.js.map +7 -0
- package/dist/modules/customers/components/detail/PersonDetailTabs.js +7 -1
- package/dist/modules/customers/components/detail/PersonDetailTabs.js.map +2 -2
- package/dist/modules/customers/components/detail/PersonEmailThreadsTab.js +366 -0
- package/dist/modules/customers/components/detail/PersonEmailThreadsTab.js.map +7 -0
- package/dist/modules/customers/data/enrichers.js +133 -2
- package/dist/modules/customers/data/enrichers.js.map +2 -2
- package/dist/modules/customers/data/entities.js +18 -0
- package/dist/modules/customers/data/entities.js.map +2 -2
- package/dist/modules/customers/data/extensions.js +16 -0
- package/dist/modules/customers/data/extensions.js.map +7 -0
- package/dist/modules/customers/encryption.js +11 -0
- package/dist/modules/customers/encryption.js.map +2 -2
- package/dist/modules/customers/events.js +4 -1
- package/dist/modules/customers/events.js.map +2 -2
- package/dist/modules/customers/lib/findPeopleByAddresses.js +64 -0
- package/dist/modules/customers/lib/findPeopleByAddresses.js.map +7 -0
- package/dist/modules/customers/lib/kysely.js.map +2 -2
- package/dist/modules/customers/lib/link-channel-message-handler.js +303 -0
- package/dist/modules/customers/lib/link-channel-message-handler.js.map +7 -0
- package/dist/modules/customers/lib/personEmailThreads.js +205 -0
- package/dist/modules/customers/lib/personEmailThreads.js.map +7 -0
- package/dist/modules/customers/lib/visibilityFilter.js +51 -0
- package/dist/modules/customers/lib/visibilityFilter.js.map +7 -0
- package/dist/modules/customers/migrations/Migration20260527012240_customers.js +20 -0
- package/dist/modules/customers/migrations/Migration20260527012240_customers.js.map +7 -0
- package/dist/modules/customers/setup.js +2 -1
- package/dist/modules/customers/setup.js.map +2 -2
- package/dist/modules/customers/subscribers/link-channel-message-received.js +12 -0
- package/dist/modules/customers/subscribers/link-channel-message-received.js.map +7 -0
- package/dist/modules/customers/subscribers/link-channel-message-sent.js +12 -0
- package/dist/modules/customers/subscribers/link-channel-message-sent.js.map +7 -0
- package/dist/modules/integrations/data/entities.js +8 -1
- package/dist/modules/integrations/data/entities.js.map +2 -2
- package/dist/modules/integrations/lib/credentials-service.js +29 -14
- package/dist/modules/integrations/lib/credentials-service.js.map +2 -2
- package/dist/modules/integrations/migrations/Migration20260526154136_integrations.js +15 -0
- package/dist/modules/integrations/migrations/Migration20260526154136_integrations.js.map +7 -0
- package/dist/modules/messages/commands/messages.js +70 -8
- package/dist/modules/messages/commands/messages.js.map +2 -2
- package/dist/modules/messages/components/ComposeMessagePageClient.js +24 -13
- package/dist/modules/messages/components/ComposeMessagePageClient.js.map +2 -2
- package/dist/modules/messages/components/MessageDetailPageClient.js +39 -2
- package/dist/modules/messages/components/MessageDetailPageClient.js.map +2 -2
- package/dist/modules/messages/components/MessagesInboxPageClient.js +1 -0
- package/dist/modules/messages/components/MessagesInboxPageClient.js.map +2 -2
- package/dist/modules/messages/data/entities.js +8 -1
- package/dist/modules/messages/data/entities.js.map +2 -2
- package/dist/modules/messages/migrations/Migration20260531130000.js +15 -0
- package/dist/modules/messages/migrations/Migration20260531130000.js.map +7 -0
- package/dist/modules/messages/widgets/injection-table.js +7 -0
- package/dist/modules/messages/widgets/injection-table.js.map +7 -0
- package/generated/entities/channel_ingest_dead_letter/index.ts +11 -0
- package/generated/entities/channel_thread_mapping/index.ts +11 -0
- package/generated/entities/channel_thread_token/index.ts +7 -0
- package/generated/entities/communication_channel/index.ts +20 -0
- package/generated/entities/customer_interaction/index.ts +2 -0
- package/generated/entities/external_conversation/index.ts +11 -0
- package/generated/entities/external_message/index.ts +11 -0
- package/generated/entities/integration_credentials/index.ts +1 -0
- package/generated/entities/message/index.ts +1 -0
- package/generated/entities/message_channel_link/index.ts +15 -0
- package/generated/entities/message_reaction/index.ts +11 -0
- package/generated/entities.ids.generated.ts +11 -0
- package/generated/entity-fields-registry.ts +117 -0
- package/package.json +9 -7
- package/src/helpers/integration/authFixtures.ts +4 -1
- package/src/helpers/integration/communicationChannelsFixtures.ts +124 -0
- package/src/modules/communication_channels/acl.ts +43 -0
- package/src/modules/communication_channels/api/delete/channels/[id]/route.ts +163 -0
- package/src/modules/communication_channels/api/delete/messages/[messageId]/reactions/[reactionId]/route.ts +143 -0
- package/src/modules/communication_channels/api/get/channels/[id]/health/route.ts +173 -0
- package/src/modules/communication_channels/api/get/channels/[id]/route.ts +111 -0
- package/src/modules/communication_channels/api/get/channels/route.ts +109 -0
- package/src/modules/communication_channels/api/get/me/channels/route.ts +100 -0
- package/src/modules/communication_channels/api/get/oauth/[provider]/callback/route.ts +355 -0
- package/src/modules/communication_channels/api/post/channels/[id]/import-history/route.ts +206 -0
- package/src/modules/communication_channels/api/post/channels/[id]/poll-now/route.ts +174 -0
- package/src/modules/communication_channels/api/post/channels/[id]/push/register/route.ts +158 -0
- package/src/modules/communication_channels/api/post/channels/[id]/set-primary/route.ts +114 -0
- package/src/modules/communication_channels/api/post/channels/[id]/test-send/route.ts +241 -0
- package/src/modules/communication_channels/api/post/channels/connect/credentials/route.ts +134 -0
- package/src/modules/communication_channels/api/post/messages/[messageId]/reactions/route.ts +143 -0
- package/src/modules/communication_channels/api/post/oauth/[provider]/initiate/route.ts +192 -0
- package/src/modules/communication_channels/api/post/send-as-user/route.ts +125 -0
- package/src/modules/communication_channels/api/post/test-seed/route.ts +267 -0
- package/src/modules/communication_channels/api/post/webhook/[provider]/route.ts +227 -0
- package/src/modules/communication_channels/api/post/webhooks/gmail/route.ts +161 -0
- package/src/modules/communication_channels/api/put/threads/[threadId]/assign/route.ts +132 -0
- package/src/modules/communication_channels/backend/communication_channels/channels/[id]/page.meta.ts +34 -0
- package/src/modules/communication_channels/backend/communication_channels/channels/[id]/page.tsx +250 -0
- package/src/modules/communication_channels/backend/communication_channels/channels/page.meta.ts +36 -0
- package/src/modules/communication_channels/backend/communication_channels/channels/page.tsx +137 -0
- package/src/modules/communication_channels/backend/profile/communication-channels/page.meta.ts +36 -0
- package/src/modules/communication_channels/backend/profile/communication-channels/page.tsx +907 -0
- package/src/modules/communication_channels/commands/connect-credential-channel.ts +243 -0
- package/src/modules/communication_channels/commands/delete-channel.ts +193 -0
- package/src/modules/communication_channels/commands/deliver-outbound-message.ts +579 -0
- package/src/modules/communication_channels/commands/disconnect-channel.ts +241 -0
- package/src/modules/communication_channels/commands/ingest-inbound-message.ts +602 -0
- package/src/modules/communication_channels/commands/interceptors.ts +104 -0
- package/src/modules/communication_channels/commands/process-inbound-reaction.ts +265 -0
- package/src/modules/communication_channels/commands/push-register.ts +203 -0
- package/src/modules/communication_channels/commands/push-renew.ts +49 -0
- package/src/modules/communication_channels/commands/push-unregister.ts +168 -0
- package/src/modules/communication_channels/commands/queue-import-history.ts +180 -0
- package/src/modules/communication_channels/commands/reassign-conversation.ts +273 -0
- package/src/modules/communication_channels/commands/set-primary-channel.ts +154 -0
- package/src/modules/communication_channels/commands/toggle-outbound-reaction.ts +347 -0
- package/src/modules/communication_channels/data/enrichers.ts +413 -0
- package/src/modules/communication_channels/data/entities.ts +546 -0
- package/src/modules/communication_channels/data/extensions.ts +76 -0
- package/src/modules/communication_channels/data/validators.ts +138 -0
- package/src/modules/communication_channels/di.ts +40 -0
- package/src/modules/communication_channels/encryption.ts +44 -0
- package/src/modules/communication_channels/events.ts +122 -0
- package/src/modules/communication_channels/i18n/de.json +138 -0
- package/src/modules/communication_channels/i18n/en.json +138 -0
- package/src/modules/communication_channels/i18n/es.json +138 -0
- package/src/modules/communication_channels/i18n/pl.json +138 -0
- package/src/modules/communication_channels/index.ts +19 -0
- package/src/modules/communication_channels/lib/access-control.ts +110 -0
- package/src/modules/communication_channels/lib/adapter-compat.ts +57 -0
- package/src/modules/communication_channels/lib/adapter-registry-singleton.ts +35 -0
- package/src/modules/communication_channels/lib/adapter.ts +605 -0
- package/src/modules/communication_channels/lib/connect-channel.ts +163 -0
- package/src/modules/communication_channels/lib/contact-resolver.ts +162 -0
- package/src/modules/communication_channels/lib/credential-refresh.ts +197 -0
- package/src/modules/communication_channels/lib/dead-letter.ts +87 -0
- package/src/modules/communication_channels/lib/email-capabilities.ts +60 -0
- package/src/modules/communication_channels/lib/email-contact.ts +17 -0
- package/src/modules/communication_channels/lib/email-mime.ts +425 -0
- package/src/modules/communication_channels/lib/error-classification.ts +144 -0
- package/src/modules/communication_channels/lib/gmail-pubsub-jwt.ts +278 -0
- package/src/modules/communication_channels/lib/mutation-guards.ts +215 -0
- package/src/modules/communication_channels/lib/oauth-client-config.ts +79 -0
- package/src/modules/communication_channels/lib/oauth-state.ts +228 -0
- package/src/modules/communication_channels/lib/oauth-token.ts +81 -0
- package/src/modules/communication_channels/lib/pg-errors.ts +12 -0
- package/src/modules/communication_channels/lib/provider-health.ts +47 -0
- package/src/modules/communication_channels/lib/push-state.ts +38 -0
- package/src/modules/communication_channels/lib/queue.ts +66 -0
- package/src/modules/communication_channels/lib/reaction-processor-types.ts +51 -0
- package/src/modules/communication_channels/lib/reaction-semantics.ts +48 -0
- package/src/modules/communication_channels/lib/registry.ts +99 -0
- package/src/modules/communication_channels/lib/route-mutation-guard.ts +68 -0
- package/src/modules/communication_channels/lib/sanitize-channel-html.ts +129 -0
- package/src/modules/communication_channels/lib/send-as-user.ts +284 -0
- package/src/modules/communication_channels/lib/system-user.ts +74 -0
- package/src/modules/communication_channels/lib/test-seed.ts +140 -0
- package/src/modules/communication_channels/lib/thread-matcher.ts +430 -0
- package/src/modules/communication_channels/lib/thread-token.ts +355 -0
- package/src/modules/communication_channels/lib/use-connect-channel.ts +73 -0
- package/src/modules/communication_channels/migrations/.snapshot-open-mercato.json +2142 -0
- package/src/modules/communication_channels/migrations/Migration20260526134719_communication_channels.ts +55 -0
- package/src/modules/communication_channels/migrations/Migration20260527195446_communication_channels.ts +20 -0
- package/src/modules/communication_channels/migrations/Migration20260529231848_communication_channels.ts +13 -0
- package/src/modules/communication_channels/migrations/Migration20260531120000_communication_channels.ts +24 -0
- package/src/modules/communication_channels/notifications.client.ts +50 -0
- package/src/modules/communication_channels/notifications.handlers.ts +86 -0
- package/src/modules/communication_channels/notifications.ts +52 -0
- package/src/modules/communication_channels/setup.ts +158 -0
- package/src/modules/communication_channels/subscribers/channel-requires-reauth-notification.ts +118 -0
- package/src/modules/communication_channels/subscribers/outbound-bridge.ts +175 -0
- package/src/modules/communication_channels/subscribers/user-deleted-cascade.ts +100 -0
- package/src/modules/communication_channels/widgets/components.ts +36 -0
- package/src/modules/communication_channels/widgets/injection/channel-badge/widget.client.tsx +38 -0
- package/src/modules/communication_channels/widgets/injection/channel-badge/widget.ts +51 -0
- package/src/modules/communication_channels/widgets/injection/channel-info-panel/widget.client.tsx +278 -0
- package/src/modules/communication_channels/widgets/injection/channel-info-panel/widget.ts +24 -0
- package/src/modules/communication_channels/widgets/injection/channel-payload-renderer/widget.client.tsx +63 -0
- package/src/modules/communication_channels/widgets/injection/channel-payload-renderer/widget.ts +29 -0
- package/src/modules/communication_channels/widgets/injection/profile-channels-menu/widget.ts +34 -0
- package/src/modules/communication_channels/widgets/injection/reaction-bar/widget.client.tsx +177 -0
- package/src/modules/communication_channels/widgets/injection/reaction-bar/widget.ts +26 -0
- package/src/modules/communication_channels/widgets/injection-table.ts +47 -0
- package/src/modules/communication_channels/widgets/notifications/ChannelRequiresReauthRenderer.tsx +48 -0
- package/src/modules/communication_channels/widgets/notifications/MessageReceivedRenderer.tsx +45 -0
- package/src/modules/communication_channels/widgets/notifications/index.ts +2 -0
- package/src/modules/communication_channels/workers/channel-import-history.ts +252 -0
- package/src/modules/communication_channels/workers/gmail-history-sync.ts +223 -0
- package/src/modules/communication_channels/workers/gmail-renew-watch.ts +141 -0
- package/src/modules/communication_channels/workers/inbound-processor.ts +114 -0
- package/src/modules/communication_channels/workers/outbound-delivery.ts +155 -0
- package/src/modules/communication_channels/workers/poll-channel.ts +391 -0
- package/src/modules/communication_channels/workers/poll-tick.ts +210 -0
- package/src/modules/communication_channels/workers/reaction-processor.ts +264 -0
- package/src/modules/customers/acl.ts +18 -0
- package/src/modules/customers/api/activities/route.ts +13 -0
- package/src/modules/customers/api/companies/[id]/route.ts +21 -1
- package/src/modules/customers/api/interactions/[id]/visibility/route.ts +179 -0
- package/src/modules/customers/api/interactions/counts/route.ts +10 -0
- package/src/modules/customers/api/interactions/route.ts +51 -5
- package/src/modules/customers/api/people/[id]/email-threads/route.ts +92 -0
- package/src/modules/customers/api/people/[id]/emails/route.ts +184 -0
- package/src/modules/customers/api/people/[id]/route.ts +17 -2
- package/src/modules/customers/backend/customers/people-v2/[id]/page.tsx +11 -1
- package/src/modules/customers/commands/deals.ts +65 -6
- package/src/modules/customers/commands/interactions.ts +30 -0
- package/src/modules/customers/components/detail/ActivityCard.tsx +48 -0
- package/src/modules/customers/components/detail/ComposeEmailDialog.tsx +329 -0
- package/src/modules/customers/components/detail/DealForm.tsx +2 -1
- package/src/modules/customers/components/detail/DealsSection.tsx +26 -0
- package/src/modules/customers/components/detail/EmailCardActions.tsx +258 -0
- package/src/modules/customers/components/detail/EmailReplyForwardActions.tsx +53 -0
- package/src/modules/customers/components/detail/PersonDetailTabs.tsx +8 -1
- package/src/modules/customers/components/detail/PersonEmailThreadsTab.tsx +448 -0
- package/src/modules/customers/data/enrichers.ts +252 -1
- package/src/modules/customers/data/entities.ts +46 -1
- package/src/modules/customers/data/extensions.ts +26 -0
- package/src/modules/customers/encryption.ts +11 -0
- package/src/modules/customers/events.ts +4 -0
- package/src/modules/customers/i18n/de.json +41 -0
- package/src/modules/customers/i18n/en.json +41 -0
- package/src/modules/customers/i18n/es.json +41 -0
- package/src/modules/customers/i18n/pl.json +41 -0
- package/src/modules/customers/lib/findPeopleByAddresses.ts +107 -0
- package/src/modules/customers/lib/kysely.ts +16 -0
- package/src/modules/customers/lib/link-channel-message-handler.ts +571 -0
- package/src/modules/customers/lib/personEmailThreads.ts +325 -0
- package/src/modules/customers/lib/visibilityFilter.ts +152 -0
- package/src/modules/customers/migrations/.snapshot-open-mercato.json +61 -0
- package/src/modules/customers/migrations/Migration20260527012240_customers.ts +23 -0
- package/src/modules/customers/setup.ts +1 -0
- package/src/modules/customers/subscribers/link-channel-message-received.ts +21 -0
- package/src/modules/customers/subscribers/link-channel-message-sent.ts +21 -0
- package/src/modules/integrations/AGENTS.md +9 -0
- package/src/modules/integrations/data/entities.ts +21 -1
- package/src/modules/integrations/lib/credentials-service.ts +49 -13
- package/src/modules/integrations/migrations/.snapshot-open-mercato.json +26 -1
- package/src/modules/integrations/migrations/Migration20260526154136_integrations.ts +15 -0
- package/src/modules/messages/commands/messages.ts +101 -8
- package/src/modules/messages/components/ComposeMessagePageClient.tsx +17 -0
- package/src/modules/messages/components/MessageDetailPageClient.tsx +43 -0
- package/src/modules/messages/components/MessagesInboxPageClient.tsx +4 -0
- package/src/modules/messages/data/entities.ts +11 -0
- package/src/modules/messages/migrations/.snapshot-open-mercato.json +18 -0
- package/src/modules/messages/migrations/Migration20260531130000.ts +15 -0
- package/src/modules/messages/widgets/injection-table.ts +29 -0
package/dist/modules/communication_channels/widgets/injection/channel-payload-renderer/widget.js.map
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/modules/communication_channels/widgets/injection/channel-payload-renderer/widget.ts"],
|
|
4
|
+
"sourcesContent": ["import type { InjectionWidgetModule } from '@open-mercato/shared/modules/widgets/injection'\nimport ChannelPayloadRendererWidget from './widget.client'\n\n/**\n * Channel payload renderer \u2014 renders the channel-native rich payload of a message\n * (Slack Block Kit, WhatsApp interactive, email MIME, etc.) below the body in the\n * messages detail page (`detail:messages:message:body:after`).\n *\n * For `email/*` content types, HTML is sanitized via `sanitizeChannelHtml` before\n * being passed to `dangerouslySetInnerHTML` \u2014 see SPEC-045d \u00A74.6.\n *\n * Provider packages override this via UMES component replacement (handle\n * `widget:communication_channels.injection.channel-payload-renderer`) to render\n * Block Kit, interactive buttons, contact cards, location maps, etc.\n */\nconst widget: InjectionWidgetModule<Record<string, unknown>, Record<string, unknown>> = {\n metadata: {\n id: 'communication_channels.injection.channel-payload-renderer',\n title: 'Channel payload renderer',\n description:\n 'Renders channel-native rich payload (Block Kit, interactive, MIME) below the message body in the detail view. Generic fallback; provider packages can replace it for richer rendering.',\n features: ['communication_channels.view'],\n priority: 100,\n enabled: true,\n },\n Widget: ChannelPayloadRendererWidget,\n}\n\nexport default widget\n"],
|
|
5
|
+
"mappings": "AACA,OAAO,kCAAkC;AAczC,MAAM,SAAkF;AAAA,EACtF,UAAU;AAAA,IACR,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aACE;AAAA,IACF,UAAU,CAAC,6BAA6B;AAAA,IACxC,UAAU;AAAA,IACV,SAAS;AAAA,EACX;AAAA,EACA,QAAQ;AACV;AAEA,IAAO,iBAAQ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { InjectionPosition } from "@open-mercato/shared/modules/widgets/injection-position";
|
|
2
|
+
const widget = {
|
|
3
|
+
metadata: {
|
|
4
|
+
id: "communication_channels.injection.profile-channels-menu",
|
|
5
|
+
title: "My communication channels profile menu item"
|
|
6
|
+
},
|
|
7
|
+
menuItems: [
|
|
8
|
+
{
|
|
9
|
+
id: "communication-channels-profile-link",
|
|
10
|
+
labelKey: "communication_channels.profile.title",
|
|
11
|
+
label: "My communication channels",
|
|
12
|
+
icon: "Mail",
|
|
13
|
+
href: "/backend/profile/communication-channels",
|
|
14
|
+
features: ["communication_channels.connect_user_channel"],
|
|
15
|
+
placement: { position: InjectionPosition.After, relativeTo: "change-password" }
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
};
|
|
19
|
+
var widget_default = widget;
|
|
20
|
+
export {
|
|
21
|
+
widget_default as default
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=widget.js.map
|
package/dist/modules/communication_channels/widgets/injection/profile-channels-menu/widget.js.map
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/modules/communication_channels/widgets/injection/profile-channels-menu/widget.ts"],
|
|
4
|
+
"sourcesContent": ["import { InjectionPosition } from '@open-mercato/shared/modules/widgets/injection-position'\nimport type { InjectionMenuItemWidget } from '@open-mercato/shared/modules/widgets/injection'\n\n/**\n * Adds a \"My communication channels\" entry to the top-right profile dropdown,\n * directly under \"Change Password\". The per-user channel-connect page\n * (`/backend/profile/communication-channels`) is `pageContext: 'profile'`, so it\n * is excluded from the main sidebar and otherwise only reachable via the\n * profile-mode sidebar or a direct URL \u2014 this gives it a discoverable entry.\n *\n * Feature-gated on `communication_channels.connect_user_channel` (the same guard\n * as the page), so users who cannot connect a channel don't see a dead link.\n * Wildcard grants (`communication_channels.*`, `*`) are honored by the menu\n * filter's wildcard-aware matcher.\n */\nconst widget: InjectionMenuItemWidget = {\n metadata: {\n id: 'communication_channels.injection.profile-channels-menu',\n title: 'My communication channels profile menu item',\n },\n menuItems: [\n {\n id: 'communication-channels-profile-link',\n labelKey: 'communication_channels.profile.title',\n label: 'My communication channels',\n icon: 'Mail',\n href: '/backend/profile/communication-channels',\n features: ['communication_channels.connect_user_channel'],\n placement: { position: InjectionPosition.After, relativeTo: 'change-password' },\n },\n ],\n}\n\nexport default widget\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,yBAAyB;AAelC,MAAM,SAAkC;AAAA,EACtC,UAAU;AAAA,IACR,IAAI;AAAA,IACJ,OAAO;AAAA,EACT;AAAA,EACA,WAAW;AAAA,IACT;AAAA,MACE,IAAI;AAAA,MACJ,UAAU;AAAA,MACV,OAAO;AAAA,MACP,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU,CAAC,6CAA6C;AAAA,MACxD,WAAW,EAAE,UAAU,kBAAkB,OAAO,YAAY,kBAAkB;AAAA,IAChF;AAAA,EACF;AACF;AAEA,IAAO,iBAAQ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Button } from "@open-mercato/ui/primitives/button";
|
|
5
|
+
import { apiCall } from "@open-mercato/ui/backend/utils/apiCall";
|
|
6
|
+
import { useGuardedMutation } from "@open-mercato/ui/backend/injection/useGuardedMutation";
|
|
7
|
+
import { flash } from "@open-mercato/ui/backend/FlashMessages";
|
|
8
|
+
import { useT } from "@open-mercato/shared/lib/i18n/context";
|
|
9
|
+
const REACTION_BAR_MUTATION_CONTEXT_ID = "communication-channels-reaction-bar";
|
|
10
|
+
function ReactionBarWidget({
|
|
11
|
+
data
|
|
12
|
+
}) {
|
|
13
|
+
const t = useT();
|
|
14
|
+
const messageId = data?.id ?? null;
|
|
15
|
+
const initial = React.useMemo(() => data?._reactions ?? [], [data?._reactions]);
|
|
16
|
+
const [groups, setGroups] = React.useState(initial);
|
|
17
|
+
const [busyEmoji, setBusyEmoji] = React.useState(null);
|
|
18
|
+
const { runMutation, retryLastMutation } = useGuardedMutation({
|
|
19
|
+
contextId: REACTION_BAR_MUTATION_CONTEXT_ID,
|
|
20
|
+
blockedMessage: t("ui.forms.flash.saveBlocked", "Save blocked by validation")
|
|
21
|
+
});
|
|
22
|
+
React.useEffect(() => setGroups(initial), [initial]);
|
|
23
|
+
if (!messageId || groups.length === 0) return null;
|
|
24
|
+
const onToggle = async (group) => {
|
|
25
|
+
if (busyEmoji) return;
|
|
26
|
+
setBusyEmoji(group.emoji);
|
|
27
|
+
try {
|
|
28
|
+
if (group.reactedByMe) {
|
|
29
|
+
if (!group.myReactionId) {
|
|
30
|
+
flash(
|
|
31
|
+
t(
|
|
32
|
+
"communication_channels.reaction.cannotRemoveExternal",
|
|
33
|
+
"Reactions from external participants can only be removed in the provider app."
|
|
34
|
+
),
|
|
35
|
+
"error"
|
|
36
|
+
);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const response2 = await runMutation({
|
|
40
|
+
operation: () => apiCall(
|
|
41
|
+
`/api/communication_channels/messages/${messageId}/reactions/${group.myReactionId}`,
|
|
42
|
+
{ method: "DELETE" }
|
|
43
|
+
),
|
|
44
|
+
context: {
|
|
45
|
+
formId: REACTION_BAR_MUTATION_CONTEXT_ID,
|
|
46
|
+
resourceKind: "communication_channels.message",
|
|
47
|
+
resourceId: messageId,
|
|
48
|
+
retryLastMutation
|
|
49
|
+
},
|
|
50
|
+
mutationPayload: { action: "remove-reaction", reactionId: group.myReactionId, emoji: group.emoji }
|
|
51
|
+
});
|
|
52
|
+
if (!response2.ok) {
|
|
53
|
+
const errBody = response2.result;
|
|
54
|
+
flash(
|
|
55
|
+
errBody?.error ?? t("communication_channels.errors.reactionFailed", "Reaction failed"),
|
|
56
|
+
"error"
|
|
57
|
+
);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
setGroups(
|
|
61
|
+
(prev) => prev.map(
|
|
62
|
+
(g) => g.emoji === group.emoji ? { ...g, count: Math.max(0, g.count - 1), reactedByMe: false, myReactionId: null } : g
|
|
63
|
+
).filter((g) => g.count > 0)
|
|
64
|
+
);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const response = await runMutation({
|
|
68
|
+
operation: () => apiCall(
|
|
69
|
+
`/api/communication_channels/messages/${messageId}/reactions`,
|
|
70
|
+
{
|
|
71
|
+
method: "POST",
|
|
72
|
+
body: JSON.stringify({ emoji: group.emoji }),
|
|
73
|
+
headers: { "content-type": "application/json" }
|
|
74
|
+
}
|
|
75
|
+
),
|
|
76
|
+
context: {
|
|
77
|
+
formId: REACTION_BAR_MUTATION_CONTEXT_ID,
|
|
78
|
+
resourceKind: "communication_channels.message",
|
|
79
|
+
resourceId: messageId,
|
|
80
|
+
retryLastMutation
|
|
81
|
+
},
|
|
82
|
+
mutationPayload: { action: "add-reaction", emoji: group.emoji }
|
|
83
|
+
});
|
|
84
|
+
if (!response.ok) {
|
|
85
|
+
const errBody = response.result;
|
|
86
|
+
flash(
|
|
87
|
+
errBody?.error ?? t("communication_channels.errors.reactionFailed", "Reaction failed"),
|
|
88
|
+
"error"
|
|
89
|
+
);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const created = response.result;
|
|
93
|
+
setGroups(
|
|
94
|
+
(prev) => prev.map(
|
|
95
|
+
(g) => g.emoji === group.emoji ? {
|
|
96
|
+
...g,
|
|
97
|
+
count: g.count + 1,
|
|
98
|
+
reactedByMe: true,
|
|
99
|
+
myReactionId: created?.id ?? g.myReactionId
|
|
100
|
+
} : g
|
|
101
|
+
)
|
|
102
|
+
);
|
|
103
|
+
} catch (err) {
|
|
104
|
+
flash(
|
|
105
|
+
err instanceof Error ? err.message : t("communication_channels.errors.reactionFailed", "Reaction failed"),
|
|
106
|
+
"error"
|
|
107
|
+
);
|
|
108
|
+
} finally {
|
|
109
|
+
setBusyEmoji(null);
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
return /* @__PURE__ */ jsx(
|
|
113
|
+
"div",
|
|
114
|
+
{
|
|
115
|
+
className: "mt-2 flex flex-wrap gap-1",
|
|
116
|
+
"aria-label": t("communication_channels.reaction.bar.aria", "Reactions"),
|
|
117
|
+
children: groups.map((group) => /* @__PURE__ */ jsxs(
|
|
118
|
+
Button,
|
|
119
|
+
{
|
|
120
|
+
type: "button",
|
|
121
|
+
variant: group.reactedByMe ? "default" : "outline",
|
|
122
|
+
size: "sm",
|
|
123
|
+
disabled: busyEmoji === group.emoji,
|
|
124
|
+
onClick: () => void onToggle(group),
|
|
125
|
+
"aria-label": t("communication_channels.reaction.toggleAria", "Toggle {emoji} reaction", {
|
|
126
|
+
emoji: group.emoji
|
|
127
|
+
}),
|
|
128
|
+
children: [
|
|
129
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": true, children: group.emoji }),
|
|
130
|
+
/* @__PURE__ */ jsx("span", { className: "ml-1 text-xs", children: group.count })
|
|
131
|
+
]
|
|
132
|
+
},
|
|
133
|
+
group.emoji
|
|
134
|
+
))
|
|
135
|
+
}
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
export {
|
|
139
|
+
ReactionBarWidget as default
|
|
140
|
+
};
|
|
141
|
+
//# sourceMappingURL=widget.client.js.map
|
package/dist/modules/communication_channels/widgets/injection/reaction-bar/widget.client.js.map
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/modules/communication_channels/widgets/injection/reaction-bar/widget.client.tsx"],
|
|
4
|
+
"sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport type { InjectionWidgetComponentProps } from '@open-mercato/shared/modules/widgets/injection'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\n\ntype ReactionGroup = {\n emoji: string\n count: number\n users: Array<{\n userId?: string | null\n externalId?: string | null\n displayName?: string | null\n }>\n reactedByMe: boolean\n myReactionId: string | null\n}\n\ntype MessageWithReactions = Record<string, unknown> & {\n id?: string\n _reactions?: ReactionGroup[]\n}\n\nconst REACTION_BAR_MUTATION_CONTEXT_ID = 'communication-channels-reaction-bar'\n\ntype ReactionMutationContext = {\n formId: string\n resourceKind: string\n resourceId: string\n retryLastMutation: () => Promise<boolean>\n}\n\nexport default function ReactionBarWidget({\n data,\n}: InjectionWidgetComponentProps<Record<string, unknown>, MessageWithReactions>) {\n const t = useT()\n const messageId = data?.id ?? null\n const initial = React.useMemo(() => data?._reactions ?? [], [data?._reactions])\n const [groups, setGroups] = React.useState<ReactionGroup[]>(initial)\n const [busyEmoji, setBusyEmoji] = React.useState<string | null>(null)\n const { runMutation, retryLastMutation } = useGuardedMutation<ReactionMutationContext>({\n contextId: REACTION_BAR_MUTATION_CONTEXT_ID,\n blockedMessage: t('ui.forms.flash.saveBlocked', 'Save blocked by validation'),\n })\n\n // Keep local state in sync if the host page re-renders with fresh data.\n React.useEffect(() => setGroups(initial), [initial])\n\n if (!messageId || groups.length === 0) return null\n\n const onToggle = async (group: ReactionGroup) => {\n if (busyEmoji) return\n setBusyEmoji(group.emoji)\n try {\n if (group.reactedByMe) {\n if (!group.myReactionId) {\n flash(\n t(\n 'communication_channels.reaction.cannotRemoveExternal',\n 'Reactions from external participants can only be removed in the provider app.',\n ),\n 'error',\n )\n return\n }\n const response = await runMutation({\n operation: () => apiCall<{ ok?: boolean; error?: string }>(\n `/api/communication_channels/messages/${messageId}/reactions/${group.myReactionId}`,\n { method: 'DELETE' },\n ),\n context: {\n formId: REACTION_BAR_MUTATION_CONTEXT_ID,\n resourceKind: 'communication_channels.message',\n resourceId: messageId,\n retryLastMutation,\n },\n mutationPayload: { action: 'remove-reaction', reactionId: group.myReactionId, emoji: group.emoji },\n })\n if (!response.ok) {\n const errBody = response.result as { error?: string } | null\n flash(\n errBody?.error\n ?? t('communication_channels.errors.reactionFailed', 'Reaction failed'),\n 'error',\n )\n return\n }\n setGroups((prev) =>\n prev\n .map((g) =>\n g.emoji === group.emoji\n ? { ...g, count: Math.max(0, g.count - 1), reactedByMe: false, myReactionId: null }\n : g,\n )\n .filter((g) => g.count > 0),\n )\n return\n }\n const response = await runMutation({\n operation: () => apiCall<{ id: string; messageId: string; emoji: string }>(\n `/api/communication_channels/messages/${messageId}/reactions`,\n {\n method: 'POST',\n body: JSON.stringify({ emoji: group.emoji }),\n headers: { 'content-type': 'application/json' },\n },\n ),\n context: {\n formId: REACTION_BAR_MUTATION_CONTEXT_ID,\n resourceKind: 'communication_channels.message',\n resourceId: messageId,\n retryLastMutation,\n },\n mutationPayload: { action: 'add-reaction', emoji: group.emoji },\n })\n if (!response.ok) {\n const errBody = response.result as { error?: string } | null\n flash(\n errBody?.error\n ?? t('communication_channels.errors.reactionFailed', 'Reaction failed'),\n 'error',\n )\n return\n }\n const created = response.result as { id?: string } | null\n setGroups((prev) =>\n prev.map((g) =>\n g.emoji === group.emoji\n ? {\n ...g,\n count: g.count + 1,\n reactedByMe: true,\n myReactionId: created?.id ?? g.myReactionId,\n }\n : g,\n ),\n )\n } catch (err) {\n flash(\n err instanceof Error\n ? err.message\n : t('communication_channels.errors.reactionFailed', 'Reaction failed'),\n 'error',\n )\n } finally {\n setBusyEmoji(null)\n }\n }\n\n return (\n <div\n className=\"mt-2 flex flex-wrap gap-1\"\n aria-label={t('communication_channels.reaction.bar.aria', 'Reactions')}\n >\n {groups.map((group) => (\n <Button\n key={group.emoji}\n type=\"button\"\n variant={group.reactedByMe ? 'default' : 'outline'}\n size=\"sm\"\n disabled={busyEmoji === group.emoji}\n onClick={() => void onToggle(group)}\n aria-label={t('communication_channels.reaction.toggleAria', 'Toggle {emoji} reaction', {\n emoji: group.emoji,\n })}\n >\n <span aria-hidden>{group.emoji}</span>\n <span className=\"ml-1 text-xs\">{group.count}</span>\n </Button>\n ))}\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["response"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import ReactionBarWidget from "./widget.client.js";
|
|
2
|
+
const widget = {
|
|
3
|
+
metadata: {
|
|
4
|
+
id: "communication_channels.injection.reaction-bar",
|
|
5
|
+
title: "Reaction bar",
|
|
6
|
+
description: "Renders grouped emoji reactions below channel-linked messages. Tapping an emoji toggles the current user's reaction.",
|
|
7
|
+
features: ["communication_channels.view"],
|
|
8
|
+
priority: 90,
|
|
9
|
+
enabled: true
|
|
10
|
+
},
|
|
11
|
+
Widget: ReactionBarWidget
|
|
12
|
+
};
|
|
13
|
+
var widget_default = widget;
|
|
14
|
+
export {
|
|
15
|
+
widget_default as default
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=widget.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/modules/communication_channels/widgets/injection/reaction-bar/widget.ts"],
|
|
4
|
+
"sourcesContent": ["import type { InjectionWidgetModule } from '@open-mercato/shared/modules/widgets/injection'\nimport ReactionBarWidget from './widget.client'\n\n/**\n * Reaction bar \u2014 renders the grouped emoji counts below a channel-linked message\n * (`detail:messages:message:body:after`). Click an emoji to toggle the current\n * user's reaction (calls the slice-2d outbound reactions API).\n *\n * Reads the `_reactions` enrichment field added by `messageReactionsEnricher`.\n * Gated by the `communication_channels.react` feature at the API layer; the\n * widget itself surfaces only when there is at least one reaction.\n */\nconst widget: InjectionWidgetModule<Record<string, unknown>, Record<string, unknown>> = {\n metadata: {\n id: 'communication_channels.injection.reaction-bar',\n title: 'Reaction bar',\n description:\n 'Renders grouped emoji reactions below channel-linked messages. Tapping an emoji toggles the current user\\'s reaction.',\n features: ['communication_channels.view'],\n priority: 90,\n enabled: true,\n },\n Widget: ReactionBarWidget,\n}\n\nexport default widget\n"],
|
|
5
|
+
"mappings": "AACA,OAAO,uBAAuB;AAW9B,MAAM,SAAkF;AAAA,EACtF,UAAU;AAAA,IACR,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aACE;AAAA,IACF,UAAU,CAAC,6BAA6B;AAAA,IACxC,UAAU;AAAA,IACV,SAAS;AAAA,EACX;AAAA,EACA,QAAQ;AACV;AAEA,IAAO,iBAAQ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
const injectionTable = {
|
|
2
|
+
"data-table:messages:columns": [
|
|
3
|
+
{
|
|
4
|
+
widgetId: "communication_channels.injection.channel-badge",
|
|
5
|
+
priority: 100
|
|
6
|
+
}
|
|
7
|
+
],
|
|
8
|
+
"detail:messages:message:body:after": [
|
|
9
|
+
{
|
|
10
|
+
widgetId: "communication_channels.injection.channel-payload-renderer",
|
|
11
|
+
priority: 100
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
widgetId: "communication_channels.injection.reaction-bar",
|
|
15
|
+
priority: 90
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
"detail:messages:message:sidebar": [
|
|
19
|
+
{
|
|
20
|
+
widgetId: "communication_channels.injection.channel-info-panel",
|
|
21
|
+
priority: 100
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
// Profile dropdown (top-right avatar): a discoverable entry to the per-user
|
|
25
|
+
// channel-connect page, placed directly under "Change Password".
|
|
26
|
+
"menu:topbar:profile-dropdown": [
|
|
27
|
+
{
|
|
28
|
+
widgetId: "communication_channels.injection.profile-channels-menu",
|
|
29
|
+
priority: 100
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
};
|
|
33
|
+
var injection_table_default = injectionTable;
|
|
34
|
+
export {
|
|
35
|
+
injection_table_default as default,
|
|
36
|
+
injectionTable
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=injection-table.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/communication_channels/widgets/injection-table.ts"],
|
|
4
|
+
"sourcesContent": ["import type { ModuleInjectionTable } from '@open-mercato/shared/modules/widgets/injection'\n\n/**\n * Hub widget \u2192 messages-module spot wiring (SPEC-045d \u00A79.3).\n *\n * The Messages module exposes 4 injection spots (registered in slice 2a). The\n * hub mounts its widgets here so channel-linked messages get channel-aware\n * rendering without modifying the Messages module's templates.\n *\n * Provider packages can register additional widgets at the same spots OR\n * replace these hub-default widgets via UMES component replacement (handles\n * like `widget:communication_channels.injection.channel-badge`).\n */\nexport const injectionTable: ModuleInjectionTable = {\n 'data-table:messages:columns': [\n {\n widgetId: 'communication_channels.injection.channel-badge',\n priority: 100,\n },\n ],\n 'detail:messages:message:body:after': [\n {\n widgetId: 'communication_channels.injection.channel-payload-renderer',\n priority: 100,\n },\n {\n widgetId: 'communication_channels.injection.reaction-bar',\n priority: 90,\n },\n ],\n 'detail:messages:message:sidebar': [\n {\n widgetId: 'communication_channels.injection.channel-info-panel',\n priority: 100,\n },\n ],\n // Profile dropdown (top-right avatar): a discoverable entry to the per-user\n // channel-connect page, placed directly under \"Change Password\".\n 'menu:topbar:profile-dropdown': [\n {\n widgetId: 'communication_channels.injection.profile-channels-menu',\n priority: 100,\n },\n ],\n}\n\nexport default injectionTable\n"],
|
|
5
|
+
"mappings": "AAaO,MAAM,iBAAuC;AAAA,EAClD,+BAA+B;AAAA,IAC7B;AAAA,MACE,UAAU;AAAA,MACV,UAAU;AAAA,IACZ;AAAA,EACF;AAAA,EACA,sCAAsC;AAAA,IACpC;AAAA,MACE,UAAU;AAAA,MACV,UAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,UAAU;AAAA,MACV,UAAU;AAAA,IACZ;AAAA,EACF;AAAA,EACA,mCAAmC;AAAA,IACjC;AAAA,MACE,UAAU;AAAA,MACV,UAAU;AAAA,IACZ;AAAA,EACF;AAAA;AAAA;AAAA,EAGA,gCAAgC;AAAA,IAC9B;AAAA,MACE,UAAU;AAAA,MACV,UAAU;AAAA,IACZ;AAAA,EACF;AACF;AAEA,IAAO,0BAAQ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/modules/communication_channels/widgets/notifications/ChannelRequiresReauthRenderer.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useT } from "@open-mercato/shared/lib/i18n/context";
|
|
4
|
+
function ChannelRequiresReauthRenderer({ notification }) {
|
|
5
|
+
const t = useT();
|
|
6
|
+
const channelName = notification.metadata?.channelDisplayName ?? t("communication_channels.notifications.channel_requires_reauth.unknownChannel", "A channel");
|
|
7
|
+
const providerKey = notification.metadata?.providerKey ?? "";
|
|
8
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
9
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-status-warning-text", children: notification.title ?? t(
|
|
10
|
+
"communication_channels.notifications.channel_requires_reauth.title",
|
|
11
|
+
"Channel needs reconnection"
|
|
12
|
+
) }),
|
|
13
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: providerKey ? `${channelName} (${providerKey})` : channelName }),
|
|
14
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: notification.body ?? t(
|
|
15
|
+
"communication_channels.notifications.channel_requires_reauth.body",
|
|
16
|
+
"Authentication expired. Reconnect this channel to resume sending and receiving messages."
|
|
17
|
+
) })
|
|
18
|
+
] });
|
|
19
|
+
}
|
|
20
|
+
var ChannelRequiresReauthRenderer_default = ChannelRequiresReauthRenderer;
|
|
21
|
+
export {
|
|
22
|
+
ChannelRequiresReauthRenderer,
|
|
23
|
+
ChannelRequiresReauthRenderer_default as default
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=ChannelRequiresReauthRenderer.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/modules/communication_channels/widgets/notifications/ChannelRequiresReauthRenderer.tsx"],
|
|
4
|
+
"sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\n\ntype NotificationRendererProps = {\n notification: {\n id: string\n type: string\n title?: string | null\n body?: string | null\n sourceEntityType?: string | null\n sourceEntityId?: string | null\n metadata?: Record<string, unknown> | null\n }\n}\n\nexport function ChannelRequiresReauthRenderer({ notification }: NotificationRendererProps) {\n const t = useT()\n const channelName =\n (notification.metadata?.channelDisplayName as string | undefined) ??\n t('communication_channels.notifications.channel_requires_reauth.unknownChannel', 'A channel')\n const providerKey = (notification.metadata?.providerKey as string | undefined) ?? ''\n\n return (\n <div className=\"flex flex-col gap-1\">\n <span className=\"font-medium text-status-warning-text\">\n {notification.title ??\n t(\n 'communication_channels.notifications.channel_requires_reauth.title',\n 'Channel needs reconnection',\n )}\n </span>\n <span className=\"text-sm text-muted-foreground\">\n {providerKey ? `${channelName} (${providerKey})` : channelName}\n </span>\n <span className=\"text-sm text-muted-foreground\">\n {notification.body ??\n t(\n 'communication_channels.notifications.channel_requires_reauth.body',\n 'Authentication expired. Reconnect this channel to resume sending and receiving messages.',\n )}\n </span>\n </div>\n )\n}\n\nexport default ChannelRequiresReauthRenderer\n"],
|
|
5
|
+
"mappings": ";AAyBI,SACE,KADF;AAtBJ,SAAS,YAAY;AAcd,SAAS,8BAA8B,EAAE,aAAa,GAA8B;AACzF,QAAM,IAAI,KAAK;AACf,QAAM,cACH,aAAa,UAAU,sBACxB,EAAE,+EAA+E,WAAW;AAC9F,QAAM,cAAe,aAAa,UAAU,eAAsC;AAElF,SACE,qBAAC,SAAI,WAAU,uBACb;AAAA,wBAAC,UAAK,WAAU,wCACb,uBAAa,SACZ;AAAA,MACE;AAAA,MACA;AAAA,IACF,GACJ;AAAA,IACA,oBAAC,UAAK,WAAU,iCACb,wBAAc,GAAG,WAAW,KAAK,WAAW,MAAM,aACrD;AAAA,IACA,oBAAC,UAAK,WAAU,iCACb,uBAAa,QACZ;AAAA,MACE;AAAA,MACA;AAAA,IACF,GACJ;AAAA,KACF;AAEJ;AAEA,IAAO,wCAAQ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useT } from "@open-mercato/shared/lib/i18n/context";
|
|
4
|
+
function MessageReceivedRenderer({ notification }) {
|
|
5
|
+
const t = useT();
|
|
6
|
+
const senderName = notification.metadata?.senderDisplayName ?? notification.metadata?.senderIdentifier ?? t("communication_channels.notifications.message_received.unknownSender", "Unknown sender");
|
|
7
|
+
const channelLabel = notification.metadata?.channelDisplayName ?? notification.metadata?.providerKey ?? "";
|
|
8
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
9
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: notification.title ?? t("communication_channels.notifications.message_received.title", "New external message") }),
|
|
10
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: channelLabel ? `${senderName} \xB7 ${channelLabel}` : senderName }),
|
|
11
|
+
notification.body ? /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground line-clamp-2", children: notification.body }) : null
|
|
12
|
+
] });
|
|
13
|
+
}
|
|
14
|
+
var MessageReceivedRenderer_default = MessageReceivedRenderer;
|
|
15
|
+
export {
|
|
16
|
+
MessageReceivedRenderer,
|
|
17
|
+
MessageReceivedRenderer_default as default
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=MessageReceivedRenderer.js.map
|
package/dist/modules/communication_channels/widgets/notifications/MessageReceivedRenderer.js.map
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/modules/communication_channels/widgets/notifications/MessageReceivedRenderer.tsx"],
|
|
4
|
+
"sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\n\ntype NotificationRendererProps = {\n notification: {\n id: string\n type: string\n title?: string | null\n body?: string | null\n sourceEntityType?: string | null\n sourceEntityId?: string | null\n metadata?: Record<string, unknown> | null\n }\n}\n\nexport function MessageReceivedRenderer({ notification }: NotificationRendererProps) {\n const t = useT()\n const senderName =\n (notification.metadata?.senderDisplayName as string | undefined) ??\n (notification.metadata?.senderIdentifier as string | undefined) ??\n t('communication_channels.notifications.message_received.unknownSender', 'Unknown sender')\n const channelLabel =\n (notification.metadata?.channelDisplayName as string | undefined) ??\n (notification.metadata?.providerKey as string | undefined) ??\n ''\n\n return (\n <div className=\"flex flex-col gap-1\">\n <span className=\"font-medium text-foreground\">\n {notification.title ??\n t('communication_channels.notifications.message_received.title', 'New external message')}\n </span>\n <span className=\"text-sm text-muted-foreground\">\n {channelLabel ? `${senderName} \u00B7 ${channelLabel}` : senderName}\n </span>\n {notification.body ? (\n <span className=\"text-sm text-muted-foreground line-clamp-2\">{notification.body}</span>\n ) : null}\n </div>\n )\n}\n\nexport default MessageReceivedRenderer\n"],
|
|
5
|
+
"mappings": ";AA6BI,SACE,KADF;AA1BJ,SAAS,YAAY;AAcd,SAAS,wBAAwB,EAAE,aAAa,GAA8B;AACnF,QAAM,IAAI,KAAK;AACf,QAAM,aACH,aAAa,UAAU,qBACvB,aAAa,UAAU,oBACxB,EAAE,uEAAuE,gBAAgB;AAC3F,QAAM,eACH,aAAa,UAAU,sBACvB,aAAa,UAAU,eACxB;AAEF,SACE,qBAAC,SAAI,WAAU,uBACb;AAAA,wBAAC,UAAK,WAAU,+BACb,uBAAa,SACZ,EAAE,+DAA+D,sBAAsB,GAC3F;AAAA,IACA,oBAAC,UAAK,WAAU,iCACb,yBAAe,GAAG,UAAU,SAAM,YAAY,KAAK,YACtD;AAAA,IACC,aAAa,OACZ,oBAAC,UAAK,WAAU,8CAA8C,uBAAa,MAAK,IAC9E;AAAA,KACN;AAEJ;AAEA,IAAO,kCAAQ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { MessageReceivedRenderer } from "./MessageReceivedRenderer.js";
|
|
2
|
+
import { ChannelRequiresReauthRenderer } from "./ChannelRequiresReauthRenderer.js";
|
|
3
|
+
export {
|
|
4
|
+
ChannelRequiresReauthRenderer,
|
|
5
|
+
MessageReceivedRenderer
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/modules/communication_channels/widgets/notifications/index.ts"],
|
|
4
|
+
"sourcesContent": ["export { MessageReceivedRenderer } from './MessageReceivedRenderer'\nexport { ChannelRequiresReauthRenderer } from './ChannelRequiresReauthRenderer'\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,+BAA+B;AACxC,SAAS,qCAAqC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { findOneWithDecryption } from "@open-mercato/shared/lib/encryption/find";
|
|
2
|
+
import { CommunicationChannel } from "../data/entities.js";
|
|
3
|
+
import {
|
|
4
|
+
COMMUNICATION_CHANNELS_INGEST_INBOUND_COMMAND_ID
|
|
5
|
+
} from "../commands/ingest-inbound-message.js";
|
|
6
|
+
import { COMMUNICATION_CHANNELS_QUEUES } from "../lib/queue.js";
|
|
7
|
+
import { refreshCredentialsIfNeeded } from "../lib/credential-refresh.js";
|
|
8
|
+
import { classifyOutboundError } from "../lib/error-classification.js";
|
|
9
|
+
const metadata = {
|
|
10
|
+
queue: COMMUNICATION_CHANNELS_QUEUES.importHistory,
|
|
11
|
+
id: "communication_channels:channel-import-history",
|
|
12
|
+
concurrency: 1
|
|
13
|
+
};
|
|
14
|
+
async function handle(job, ctx) {
|
|
15
|
+
const payload = job.payload;
|
|
16
|
+
const { progressJobId, channelId, sinceDays, contactEmails, maxMessages, scope } = payload;
|
|
17
|
+
const progressService = ctx.resolve("progressService");
|
|
18
|
+
const progressContext = {
|
|
19
|
+
tenantId: scope.tenantId,
|
|
20
|
+
organizationId: scope.organizationId
|
|
21
|
+
};
|
|
22
|
+
const em = ctx.resolve("em").fork();
|
|
23
|
+
const adapterRegistry = ctx.resolve("channelAdapterRegistry");
|
|
24
|
+
try {
|
|
25
|
+
await progressService.startJob(progressJobId, progressContext);
|
|
26
|
+
const channel = await findOneWithDecryption(
|
|
27
|
+
em,
|
|
28
|
+
CommunicationChannel,
|
|
29
|
+
{
|
|
30
|
+
id: channelId,
|
|
31
|
+
tenantId: scope.tenantId,
|
|
32
|
+
organizationId: scope.organizationId,
|
|
33
|
+
deletedAt: null
|
|
34
|
+
},
|
|
35
|
+
void 0,
|
|
36
|
+
scope
|
|
37
|
+
);
|
|
38
|
+
if (!channel) {
|
|
39
|
+
await progressService.failJob(
|
|
40
|
+
progressJobId,
|
|
41
|
+
{ errorMessage: "Channel not found" },
|
|
42
|
+
progressContext
|
|
43
|
+
);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (!channel.isActive || channel.status !== "connected") {
|
|
47
|
+
await progressService.failJob(
|
|
48
|
+
progressJobId,
|
|
49
|
+
{ errorMessage: `Channel is not connected (status=${channel.status})` },
|
|
50
|
+
progressContext
|
|
51
|
+
);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const adapter = adapterRegistry?.get(channel.providerKey);
|
|
55
|
+
if (!adapter || typeof adapter.importHistory !== "function") {
|
|
56
|
+
await progressService.failJob(
|
|
57
|
+
progressJobId,
|
|
58
|
+
{
|
|
59
|
+
errorMessage: `Provider "${channel.providerKey}" does not support history import`
|
|
60
|
+
},
|
|
61
|
+
progressContext
|
|
62
|
+
);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
let credentialsService = null;
|
|
66
|
+
try {
|
|
67
|
+
credentialsService = ctx.resolve("integrationCredentialsService");
|
|
68
|
+
} catch {
|
|
69
|
+
credentialsService = null;
|
|
70
|
+
}
|
|
71
|
+
const credentialsScope = {
|
|
72
|
+
tenantId: scope.tenantId,
|
|
73
|
+
organizationId: scope.organizationId,
|
|
74
|
+
userId: channel.userId ?? null
|
|
75
|
+
};
|
|
76
|
+
let credentials = {};
|
|
77
|
+
if (channel.credentialsRef && credentialsService) {
|
|
78
|
+
try {
|
|
79
|
+
credentials = await credentialsService.resolve(`channel_${channel.providerKey}`, credentialsScope) ?? {};
|
|
80
|
+
} catch {
|
|
81
|
+
credentials = {};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
const refreshed = await refreshCredentialsIfNeeded(
|
|
85
|
+
{ adapter, channelId: channel.id, credentials, scope: credentialsScope },
|
|
86
|
+
{ credentialsService }
|
|
87
|
+
);
|
|
88
|
+
credentials = refreshed.credentials;
|
|
89
|
+
const commandBus = ctx.resolve("commandBus");
|
|
90
|
+
const containerProxy = { resolve: ctx.resolve.bind(ctx) };
|
|
91
|
+
const commandCtx = {
|
|
92
|
+
container: containerProxy,
|
|
93
|
+
auth: null,
|
|
94
|
+
organizationScope: null,
|
|
95
|
+
selectedOrganizationId: scope.organizationId,
|
|
96
|
+
organizationIds: [scope.organizationId]
|
|
97
|
+
};
|
|
98
|
+
let cursor;
|
|
99
|
+
let processedCount = 0;
|
|
100
|
+
let totalCount = maxMessages;
|
|
101
|
+
let firstPage = true;
|
|
102
|
+
const MAX_PAGES = 100;
|
|
103
|
+
for (let pageIndex = 0; pageIndex < MAX_PAGES; pageIndex += 1) {
|
|
104
|
+
if (await progressService.isCancellationRequested(progressJobId, scope.tenantId)) {
|
|
105
|
+
await progressService.markCancelled(progressJobId, progressContext);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const page = await adapter.importHistory({
|
|
109
|
+
credentials,
|
|
110
|
+
scope: { tenantId: scope.tenantId, organizationId: scope.organizationId },
|
|
111
|
+
sinceDays,
|
|
112
|
+
contactEmails,
|
|
113
|
+
maxMessages,
|
|
114
|
+
cursor
|
|
115
|
+
});
|
|
116
|
+
if (firstPage && typeof page.totalCandidates === "number") {
|
|
117
|
+
totalCount = Math.min(maxMessages, page.totalCandidates);
|
|
118
|
+
await progressService.updateProgress(
|
|
119
|
+
progressJobId,
|
|
120
|
+
{ totalCount, processedCount: 0 },
|
|
121
|
+
progressContext
|
|
122
|
+
);
|
|
123
|
+
firstPage = false;
|
|
124
|
+
}
|
|
125
|
+
for (const message of page.messages) {
|
|
126
|
+
if (processedCount >= maxMessages) break;
|
|
127
|
+
try {
|
|
128
|
+
const input = {
|
|
129
|
+
channelId: channel.id,
|
|
130
|
+
providerKey: channel.providerKey,
|
|
131
|
+
channelType: channel.channelType,
|
|
132
|
+
scope: { tenantId: scope.tenantId, organizationId: scope.organizationId },
|
|
133
|
+
message
|
|
134
|
+
};
|
|
135
|
+
await commandBus.execute(COMMUNICATION_CHANNELS_INGEST_INBOUND_COMMAND_ID, {
|
|
136
|
+
input,
|
|
137
|
+
ctx: commandCtx
|
|
138
|
+
});
|
|
139
|
+
} catch (err) {
|
|
140
|
+
const classification = classifyOutboundError(err);
|
|
141
|
+
if (classification.transient) {
|
|
142
|
+
throw err;
|
|
143
|
+
}
|
|
144
|
+
console.warn(
|
|
145
|
+
`[communication_channels:channel-import-history] permanent ingest failure on channel ${channel.id}; skipping message ${message.externalMessageId}. Reason: ${classification.message}`
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
processedCount += 1;
|
|
149
|
+
}
|
|
150
|
+
await progressService.updateProgress(
|
|
151
|
+
progressJobId,
|
|
152
|
+
{ processedCount, totalCount },
|
|
153
|
+
progressContext
|
|
154
|
+
);
|
|
155
|
+
if (processedCount >= maxMessages) break;
|
|
156
|
+
if (!page.hasMore || !page.nextCursor) break;
|
|
157
|
+
cursor = page.nextCursor;
|
|
158
|
+
}
|
|
159
|
+
await progressService.completeJob(
|
|
160
|
+
progressJobId,
|
|
161
|
+
{ resultSummary: { importedCount: processedCount, channelId } },
|
|
162
|
+
progressContext
|
|
163
|
+
);
|
|
164
|
+
} catch (err) {
|
|
165
|
+
const message = err instanceof Error ? err.message : "Import history job failed";
|
|
166
|
+
const stack = err instanceof Error ? err.stack : void 0;
|
|
167
|
+
try {
|
|
168
|
+
await progressService.failJob(
|
|
169
|
+
progressJobId,
|
|
170
|
+
{ errorMessage: message.slice(0, 2e3), errorStack: stack?.slice(0, 1e4) },
|
|
171
|
+
progressContext
|
|
172
|
+
);
|
|
173
|
+
} catch (failErr) {
|
|
174
|
+
console.error(
|
|
175
|
+
`[communication_channels:channel-import-history] failed to mark progress job ${progressJobId} as failed: ${failErr instanceof Error ? failErr.message : String(failErr)}`
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
throw err;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
export {
|
|
182
|
+
handle as default,
|
|
183
|
+
metadata
|
|
184
|
+
};
|
|
185
|
+
//# sourceMappingURL=channel-import-history.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/communication_channels/workers/channel-import-history.ts"],
|
|
4
|
+
"sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport type { JobContext, QueuedJob, WorkerMeta } from '@open-mercato/queue'\nimport type { CommandBus } from '@open-mercato/shared/lib/commands'\nimport { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { CommunicationChannel } from '../data/entities'\nimport {\n COMMUNICATION_CHANNELS_INGEST_INBOUND_COMMAND_ID,\n type IngestInboundMessageInput,\n} from '../commands/ingest-inbound-message'\nimport { COMMUNICATION_CHANNELS_QUEUES } from '../lib/queue'\nimport { refreshCredentialsIfNeeded } from '../lib/credential-refresh'\nimport { classifyOutboundError } from '../lib/error-classification'\nimport type { ChannelAdapterRegistry } from '../lib/registry'\nimport type {\n ChannelImportHistoryJobPayload,\n} from '../commands/queue-import-history'\nimport type {\n ProgressService,\n ProgressServiceContext,\n} from '../../progress/lib/progressService'\n\n/**\n * Spec B \u00A7 Phase B6 \u2014 operator-triggered backlog import worker.\n *\n * Distinct from `poll-channel` (which runs every scheduler tick and ingests\n * *new* mail since the channel cursor). This worker reaches backward in time\n * by calling `adapter.importHistory` with explicit `sinceDays` / `contactEmails`\n * filters, paginating until the adapter signals `hasMore: false` or the\n * `maxMessages` cap is reached.\n *\n * Runs with `concurrency: 1` to avoid hammering the provider with multiple\n * historical sweeps in parallel; per-channel concurrency is additionally\n * enforced at enqueue time by `queueImportHistory`.\n */\nexport const metadata: WorkerMeta = {\n queue: COMMUNICATION_CHANNELS_QUEUES.importHistory,\n id: 'communication_channels:channel-import-history',\n concurrency: 1,\n}\n\ntype HandlerContext = JobContext & {\n resolve: <T = unknown>(name: string) => T\n}\n\ntype CredentialsServiceLike = {\n resolve: (\n integrationId: string,\n scope: { organizationId: string; tenantId: string; userId?: string | null },\n ) => Promise<Record<string, unknown> | null>\n save?: (\n integrationId: string,\n credentials: Record<string, unknown>,\n scope: { organizationId: string; tenantId: string; userId?: string | null },\n ) => Promise<void>\n}\n\nexport default async function handle(\n job: QueuedJob<ChannelImportHistoryJobPayload>,\n ctx: HandlerContext,\n): Promise<void> {\n const payload = job.payload\n const { progressJobId, channelId, sinceDays, contactEmails, maxMessages, scope } = payload\n\n const progressService = ctx.resolve<ProgressService>('progressService')\n const progressContext: ProgressServiceContext = {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n }\n\n const em = (ctx.resolve('em') as EntityManager).fork()\n const adapterRegistry = ctx.resolve<ChannelAdapterRegistry>('channelAdapterRegistry')\n\n try {\n await progressService.startJob(progressJobId, progressContext)\n\n const channel = await findOneWithDecryption(\n em,\n CommunicationChannel,\n {\n id: channelId,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n deletedAt: null,\n },\n undefined,\n scope,\n )\n if (!channel) {\n await progressService.failJob(\n progressJobId,\n { errorMessage: 'Channel not found' },\n progressContext,\n )\n return\n }\n if (!channel.isActive || channel.status !== 'connected') {\n await progressService.failJob(\n progressJobId,\n { errorMessage: `Channel is not connected (status=${channel.status})` },\n progressContext,\n )\n return\n }\n\n const adapter = adapterRegistry?.get(channel.providerKey)\n if (!adapter || typeof adapter.importHistory !== 'function') {\n await progressService.failJob(\n progressJobId,\n {\n errorMessage: `Provider \"${channel.providerKey}\" does not support history import`,\n },\n progressContext,\n )\n return\n }\n\n // Resolve + refresh credentials. Same flow as poll-channel.\n let credentialsService: CredentialsServiceLike | null = null\n try {\n credentialsService = ctx.resolve<CredentialsServiceLike>('integrationCredentialsService')\n } catch {\n credentialsService = null\n }\n const credentialsScope = {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: channel.userId ?? null,\n }\n let credentials: Record<string, unknown> = {}\n if (channel.credentialsRef && credentialsService) {\n try {\n credentials =\n (await credentialsService.resolve(`channel_${channel.providerKey}`, credentialsScope)) ?? {}\n } catch {\n credentials = {}\n }\n }\n const refreshed = await refreshCredentialsIfNeeded(\n { adapter, channelId: channel.id, credentials, scope: credentialsScope },\n { credentialsService },\n )\n credentials = refreshed.credentials\n\n const commandBus = ctx.resolve<CommandBus>('commandBus')\n const containerProxy = { resolve: ctx.resolve.bind(ctx) }\n const commandCtx = {\n container: containerProxy as never,\n auth: null,\n organizationScope: null,\n selectedOrganizationId: scope.organizationId,\n organizationIds: [scope.organizationId],\n }\n\n let cursor: string | undefined\n let processedCount = 0\n let totalCount = maxMessages\n let firstPage = true\n\n // Bounded loop guards against a misbehaving adapter (infinite hasMore).\n // 100 pages * HARD_CAP (default 200) = 20k messages \u2014 far above the 5k cap\n // enforced by the schema, so this only trips on adapter bugs.\n const MAX_PAGES = 100\n for (let pageIndex = 0; pageIndex < MAX_PAGES; pageIndex += 1) {\n if (await progressService.isCancellationRequested(progressJobId, scope.tenantId)) {\n await progressService.markCancelled(progressJobId, progressContext)\n return\n }\n\n const page = await adapter.importHistory!({\n credentials,\n scope: { tenantId: scope.tenantId, organizationId: scope.organizationId },\n sinceDays,\n contactEmails,\n maxMessages,\n cursor,\n })\n\n if (firstPage && typeof page.totalCandidates === 'number') {\n totalCount = Math.min(maxMessages, page.totalCandidates)\n await progressService.updateProgress(\n progressJobId,\n { totalCount, processedCount: 0 },\n progressContext,\n )\n firstPage = false\n }\n\n for (const message of page.messages) {\n if (processedCount >= maxMessages) break\n try {\n const input: IngestInboundMessageInput = {\n channelId: channel.id,\n providerKey: channel.providerKey,\n channelType: channel.channelType,\n scope: { tenantId: scope.tenantId, organizationId: scope.organizationId },\n message,\n }\n await commandBus.execute(COMMUNICATION_CHANNELS_INGEST_INBOUND_COMMAND_ID, {\n input,\n ctx: commandCtx as never,\n })\n } catch (err) {\n // Import-history is best-effort per-message. Same classification\n // logic as poll-channel: a transient failure aborts the whole job\n // (the operator can retry), permanent failures are logged and\n // skipped (the bad message would loop forever otherwise).\n const classification = classifyOutboundError(err)\n if (classification.transient) {\n throw err\n }\n console.warn(\n `[communication_channels:channel-import-history] permanent ingest failure on channel ${channel.id}; skipping message ${message.externalMessageId}. Reason: ${classification.message}`,\n )\n }\n processedCount += 1\n }\n\n await progressService.updateProgress(\n progressJobId,\n { processedCount, totalCount },\n progressContext,\n )\n\n if (processedCount >= maxMessages) break\n if (!page.hasMore || !page.nextCursor) break\n cursor = page.nextCursor\n }\n\n await progressService.completeJob(\n progressJobId,\n { resultSummary: { importedCount: processedCount, channelId } },\n progressContext,\n )\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Import history job failed'\n const stack = err instanceof Error ? err.stack : undefined\n try {\n await progressService.failJob(\n progressJobId,\n { errorMessage: message.slice(0, 2000), errorStack: stack?.slice(0, 10000) },\n progressContext,\n )\n } catch (failErr) {\n console.error(\n `[communication_channels:channel-import-history] failed to mark progress job ${progressJobId} as failed: ${\n failErr instanceof Error ? failErr.message : String(failErr)\n }`,\n )\n }\n throw err\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|