@antelopejs/dms-mailing 0.3.3 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +232 -22
- package/dist/automation/email-event-trigger.js +2 -2
- package/dist/automation/email-event-trigger.js.map +1 -1
- package/dist/automation/send-template-action.js +2 -2
- package/dist/automation/send-template-action.js.map +1 -1
- package/dist/config.js +3 -1
- package/dist/config.js.map +1 -1
- package/dist/constants.d.ts +10 -1
- package/dist/constants.js +15 -3
- package/dist/constants.js.map +1 -1
- package/dist/crons/attention.d.ts +3 -0
- package/dist/crons/attention.js +19 -0
- package/dist/crons/attention.js.map +1 -0
- package/dist/crons/index.d.ts +2 -0
- package/dist/crons/index.js +2 -0
- package/dist/crons/index.js.map +1 -1
- package/dist/crons/jobs.d.ts +12 -0
- package/dist/crons/jobs.js +27 -0
- package/dist/crons/jobs.js.map +1 -0
- package/dist/crons/retention.d.ts +2 -4
- package/dist/crons/retention.js +7 -22
- package/dist/crons/retention.js.map +1 -1
- package/dist/data/displays.d.ts +5 -0
- package/dist/data/displays.js +23 -0
- package/dist/data/displays.js.map +1 -0
- package/dist/data/index.d.ts +1 -0
- package/dist/data/index.js +1 -0
- package/dist/data/index.js.map +1 -1
- package/dist/data/locale-fallback.d.ts +3 -0
- package/dist/data/locale-fallback.js +20 -0
- package/dist/data/locale-fallback.js.map +1 -0
- package/dist/data/read-only-routes.d.ts +7 -0
- package/dist/data/read-only-routes.js +13 -0
- package/dist/data/read-only-routes.js.map +1 -0
- package/dist/data/sends-table.d.ts +19 -5
- package/dist/data/sends-table.js +185 -17
- package/dist/data/sends-table.js.map +1 -1
- package/dist/data/suppressions-table.d.ts +24 -0
- package/dist/data/suppressions-table.js +120 -0
- package/dist/data/suppressions-table.js.map +1 -0
- package/dist/data/templates-table.d.ts +20 -2
- package/dist/data/templates-table.js +188 -31
- package/dist/data/templates-table.js.map +1 -1
- package/dist/data-types/categories-type.d.ts +11 -13
- package/dist/data-types/categories-type.js +3 -3
- package/dist/data-types/categories-type.js.map +1 -1
- package/dist/data-types/category-type.js +1 -1
- package/dist/data-types/category-type.js.map +1 -1
- package/dist/db/models/index.d.ts +3 -0
- package/dist/db/models/index.js +3 -0
- package/dist/db/models/index.js.map +1 -1
- package/dist/db/models/sends.model.d.ts +12 -1
- package/dist/db/models/sends.model.js +64 -0
- package/dist/db/models/sends.model.js.map +1 -1
- package/dist/db/models/settings.model.d.ts +0 -1
- package/dist/db/models/settings.model.js +0 -7
- package/dist/db/models/settings.model.js.map +1 -1
- package/dist/db/models/suppressions.model.d.ts +28 -0
- package/dist/db/models/suppressions.model.js +46 -0
- package/dist/db/models/suppressions.model.js.map +1 -0
- package/dist/db/models/template-versions.model.d.ts +24 -0
- package/dist/db/models/template-versions.model.js +17 -0
- package/dist/db/models/template-versions.model.js.map +1 -0
- package/dist/db/models/templates.model.d.ts +2 -0
- package/dist/db/models/templates.model.js +3 -0
- package/dist/db/models/templates.model.js.map +1 -1
- package/dist/db/models/webhook-status.model.d.ts +24 -0
- package/dist/db/models/webhook-status.model.js +21 -0
- package/dist/db/models/webhook-status.model.js.map +1 -0
- package/dist/db/tables/index.d.ts +3 -0
- package/dist/db/tables/index.js +3 -0
- package/dist/db/tables/index.js.map +1 -1
- package/dist/db/tables/send-events.table.d.ts +2 -2
- package/dist/db/tables/send-events.table.js.map +1 -1
- package/dist/db/tables/sends.table.d.ts +10 -2
- package/dist/db/tables/sends.table.js +34 -1
- package/dist/db/tables/sends.table.js.map +1 -1
- package/dist/db/tables/suppressions.table.d.ts +12 -0
- package/dist/db/tables/suppressions.table.js +53 -0
- package/dist/db/tables/suppressions.table.js.map +1 -0
- package/dist/db/tables/template-versions.table.d.ts +13 -0
- package/dist/db/tables/template-versions.table.js +59 -0
- package/dist/db/tables/template-versions.table.js.map +1 -0
- package/dist/db/tables/templates.table.d.ts +11 -0
- package/dist/db/tables/templates.table.js +45 -0
- package/dist/db/tables/templates.table.js.map +1 -1
- package/dist/db/tables/webhook-status.table.d.ts +14 -0
- package/dist/db/tables/webhook-status.table.js +58 -0
- package/dist/db/tables/webhook-status.table.js.map +1 -0
- package/dist/engine/changes.d.ts +12 -0
- package/dist/engine/changes.js +107 -0
- package/dist/engine/changes.js.map +1 -0
- package/dist/engine/conditions.js +0 -2
- package/dist/engine/conditions.js.map +1 -1
- package/dist/engine/coverage.d.ts +1 -0
- package/dist/engine/coverage.js +6 -2
- package/dist/engine/coverage.js.map +1 -1
- package/dist/engine/fallback-html.d.ts +1 -1
- package/dist/engine/fallback-html.js +51 -34
- package/dist/engine/fallback-html.js.map +1 -1
- package/dist/engine/index.d.ts +3 -0
- package/dist/engine/index.js +3 -0
- package/dist/engine/index.js.map +1 -1
- package/dist/engine/plain-text.d.ts +3 -0
- package/dist/engine/plain-text.js +60 -0
- package/dist/engine/plain-text.js.map +1 -0
- package/dist/engine/resolve.d.ts +2 -1
- package/dist/engine/resolve.js +17 -9
- package/dist/engine/resolve.js.map +1 -1
- package/dist/engine/system-variables.d.ts +10 -0
- package/dist/engine/system-variables.js +70 -0
- package/dist/engine/system-variables.js.map +1 -0
- package/dist/engine/tokens.d.ts +2 -1
- package/dist/engine/tokens.js +6 -2
- package/dist/engine/tokens.js.map +1 -1
- package/dist/hooks/tenant-export.js +13 -1
- package/dist/hooks/tenant-export.js.map +1 -1
- package/dist/implementations/dms-mailing/index.d.ts +1 -1
- package/dist/implementations/dms-mailing/index.js +2 -2
- package/dist/implementations/dms-mailing/index.js.map +1 -1
- package/dist/index.js +13 -11
- package/dist/index.js.map +1 -1
- package/dist/pages/editor.js +9 -2
- package/dist/pages/editor.js.map +1 -1
- package/dist/pages/index.d.ts +1 -0
- package/dist/pages/index.js +1 -0
- package/dist/pages/index.js.map +1 -1
- package/dist/pages/module.d.ts +2 -0
- package/dist/pages/module.js +26 -2
- package/dist/pages/module.js.map +1 -1
- package/dist/pages/overview.d.ts +2 -6
- package/dist/pages/overview.js +109 -52
- package/dist/pages/overview.js.map +1 -1
- package/dist/pages/sends.d.ts +3 -4
- package/dist/pages/sends.js +197 -60
- package/dist/pages/sends.js.map +1 -1
- package/dist/pages/settings/form.js +114 -53
- package/dist/pages/settings/form.js.map +1 -1
- package/dist/pages/settings/page.d.ts +0 -1
- package/dist/pages/settings/page.js +8 -11
- package/dist/pages/settings/page.js.map +1 -1
- package/dist/pages/suppressions.d.ts +9 -0
- package/dist/pages/suppressions.js +151 -0
- package/dist/pages/suppressions.js.map +1 -0
- package/dist/pages/templates.d.ts +0 -1
- package/dist/pages/templates.js +114 -40
- package/dist/pages/templates.js.map +1 -1
- package/dist/permissions.js +2 -2
- package/dist/permissions.js.map +1 -1
- package/dist/quick-actions.js +7 -4
- package/dist/quick-actions.js.map +1 -1
- package/dist/routes/events.d.ts +8 -5
- package/dist/routes/events.js +55 -24
- package/dist/routes/events.js.map +1 -1
- package/dist/routes/index.d.ts +2 -0
- package/dist/routes/index.js +2 -0
- package/dist/routes/index.js.map +1 -1
- package/dist/routes/metrics.d.ts +60 -23
- package/dist/routes/metrics.js +231 -83
- package/dist/routes/metrics.js.map +1 -1
- package/dist/routes/period.d.ts +2 -1
- package/dist/routes/period.js +9 -3
- package/dist/routes/period.js.map +1 -1
- package/dist/routes/sends.d.ts +49 -8
- package/dist/routes/sends.js +239 -24
- package/dist/routes/sends.js.map +1 -1
- package/dist/routes/settings.d.ts +44 -5
- package/dist/routes/settings.js +190 -15
- package/dist/routes/settings.js.map +1 -1
- package/dist/routes/suppressions.d.ts +16 -0
- package/dist/routes/suppressions.js +92 -0
- package/dist/routes/suppressions.js.map +1 -0
- package/dist/routes/template-versions.d.ts +28 -0
- package/dist/routes/template-versions.js +87 -0
- package/dist/routes/template-versions.js.map +1 -0
- package/dist/routes/templates.d.ts +60 -6
- package/dist/routes/templates.js +204 -35
- package/dist/routes/templates.js.map +1 -1
- package/dist/services/attention.d.ts +19 -6
- package/dist/services/attention.js +177 -12
- package/dist/services/attention.js.map +1 -1
- package/dist/services/catalog.d.ts +3 -0
- package/dist/services/catalog.js +25 -0
- package/dist/services/catalog.js.map +1 -0
- package/dist/services/categories.d.ts +8 -32
- package/dist/services/categories.js +14 -25
- package/dist/services/categories.js.map +1 -1
- package/dist/services/checked-send.d.ts +9 -0
- package/dist/services/checked-send.js +54 -0
- package/dist/services/checked-send.js.map +1 -0
- package/dist/services/events.d.ts +5 -0
- package/dist/services/events.js +102 -9
- package/dist/services/events.js.map +1 -1
- package/dist/services/metrics.d.ts +17 -6
- package/dist/services/metrics.js +57 -18
- package/dist/services/metrics.js.map +1 -1
- package/dist/services/notify.d.ts +18 -10
- package/dist/services/notify.js +82 -37
- package/dist/services/notify.js.map +1 -1
- package/dist/services/provider-banner.d.ts +14 -0
- package/dist/services/provider-banner.js +115 -0
- package/dist/services/provider-banner.js.map +1 -0
- package/dist/services/render.js.map +1 -1
- package/dist/services/send-stat-items.d.ts +7 -0
- package/dist/services/send-stat-items.js +127 -0
- package/dist/services/send-stat-items.js.map +1 -0
- package/dist/services/send-stats.d.ts +23 -0
- package/dist/services/send-stats.js +63 -0
- package/dist/services/send-stats.js.map +1 -0
- package/dist/services/send.d.ts +18 -3
- package/dist/services/send.js +81 -17
- package/dist/services/send.js.map +1 -1
- package/dist/services/settings.d.ts +5 -0
- package/dist/services/settings.js +28 -7
- package/dist/services/settings.js.map +1 -1
- package/dist/services/starters.d.ts +15 -0
- package/dist/services/starters.js +264 -0
- package/dist/services/starters.js.map +1 -0
- package/dist/services/suppressions.d.ts +20 -0
- package/dist/services/suppressions.js +53 -0
- package/dist/services/suppressions.js.map +1 -0
- package/dist/services/template-attention.d.ts +4 -0
- package/dist/services/template-attention.js +43 -0
- package/dist/services/template-attention.js.map +1 -0
- package/dist/services/template-stats.d.ts +27 -0
- package/dist/services/template-stats.js +59 -0
- package/dist/services/template-stats.js.map +1 -0
- package/dist/services/templates.d.ts +31 -4
- package/dist/services/templates.js +240 -21
- package/dist/services/templates.js.map +1 -1
- package/dist/services/webhook-status.d.ts +27 -0
- package/dist/services/webhook-status.js +134 -0
- package/dist/services/webhook-status.js.map +1 -0
- package/dist/types/blocks.d.ts +1 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/sends.d.ts +10 -1
- package/dist/types/sends.js +35 -2
- package/dist/types/sends.js.map +1 -1
- package/dist/types/suppressions.d.ts +9 -0
- package/dist/types/suppressions.js +10 -0
- package/dist/types/suppressions.js.map +1 -0
- package/dist/types/webhook.d.ts +17 -0
- package/dist/types/webhook.js +3 -0
- package/dist/types/webhook.js.map +1 -0
- package/dist/validation/settings.schema.d.ts +144 -9
- package/dist/validation/settings.schema.js +113 -16
- package/dist/validation/settings.schema.js.map +1 -1
- package/dist/validation/templates.schema.d.ts +137 -10
- package/dist/validation/templates.schema.js +28 -2
- package/dist/validation/templates.schema.js.map +1 -1
- package/frontend-vue/app/build/components/FormFieldRow.vue +90 -0
- package/frontend-vue/app/build/components/FormRows.vue +26 -0
- package/frontend-vue/app/build/components/RequiredLegend.vue +11 -0
- package/frontend-vue/app/components/CategoriesInput.vue +323 -77
- package/frontend-vue/app/components/CategoryInput.vue +13 -14
- package/frontend-vue/app/components/CategoryLabel.vue +34 -0
- package/frontend-vue/app/components/DuplicateModal.vue +201 -0
- package/frontend-vue/app/components/Editor.vue +55 -20
- package/frontend-vue/app/components/FixAddressModal.vue +133 -0
- package/frontend-vue/app/components/FunnelCard.vue +146 -43
- package/frontend-vue/app/components/LocaleSelect.vue +98 -0
- package/frontend-vue/app/components/NewTemplateModal.vue +388 -102
- package/frontend-vue/app/components/NewTemplateSourceTile.vue +70 -0
- package/frontend-vue/app/components/OverviewGate.vue +220 -0
- package/frontend-vue/app/components/PageHeader.vue +98 -0
- package/frontend-vue/app/components/RealSendModal.vue +555 -0
- package/frontend-vue/app/components/RecipientsField.vue +41 -0
- package/frontend-vue/app/components/RenderingModal.vue +189 -0
- package/frontend-vue/app/components/RetentionInput.vue +212 -0
- package/frontend-vue/app/components/SendDrawer.vue +542 -209
- package/frontend-vue/app/components/StarterGallery.vue +153 -0
- package/frontend-vue/app/components/SystemVariables.vue +63 -0
- package/frontend-vue/app/components/TemplateCard.vue +218 -57
- package/frontend-vue/app/components/TemplateDrawer.vue +785 -274
- package/frontend-vue/app/components/TemplateGallery.vue +312 -56
- package/frontend-vue/app/components/TemplatePreviewFrame.vue +112 -22
- package/frontend-vue/app/components/TestSendModal.vue +266 -95
- package/frontend-vue/app/components/TokenText.vue +61 -10
- package/frontend-vue/app/components/VariablePath.vue +20 -0
- package/frontend-vue/app/components/VersionHistory.vue +196 -0
- package/frontend-vue/app/components/VersionPreview.vue +164 -0
- package/frontend-vue/app/components/WebhookStatus.vue +130 -0
- package/frontend-vue/app/components/blocks/Button.vue +1 -1
- package/frontend-vue/app/components/blocks/Code.vue +1 -1
- package/frontend-vue/app/components/blocks/Footer.vue +56 -7
- package/frontend-vue/app/components/blocks/Heading.vue +1 -1
- package/frontend-vue/app/components/blocks/Hero.vue +13 -7
- package/frontend-vue/app/components/blocks/List.vue +50 -6
- package/frontend-vue/app/components/blocks/Paragraph.vue +1 -1
- package/frontend-vue/app/components/blocks/Total.vue +3 -3
- package/frontend-vue/app/components/editor/EditorAutocompleteMenu.vue +50 -0
- package/frontend-vue/app/components/editor/EditorBlock.vue +37 -90
- package/frontend-vue/app/components/editor/EditorBlockFields.vue +140 -0
- package/frontend-vue/app/components/editor/EditorBlockInspector.vue +92 -0
- package/frontend-vue/app/components/editor/EditorBlockList.vue +32 -25
- package/frontend-vue/app/components/editor/EditorBlockPicker.vue +58 -0
- package/frontend-vue/app/components/editor/EditorBlockTools.vue +71 -0
- package/frontend-vue/app/components/editor/EditorCanvas.vue +105 -70
- package/frontend-vue/app/components/editor/EditorCompare.vue +211 -0
- package/frontend-vue/app/components/editor/EditorConditionFields.vue +56 -46
- package/frontend-vue/app/components/editor/EditorConditionInspector.vue +54 -0
- package/frontend-vue/app/components/editor/EditorEnvelope.vue +77 -0
- package/frontend-vue/app/components/editor/EditorIfBlock.vue +36 -86
- package/frontend-vue/app/components/editor/EditorInsertPoint.vue +64 -0
- package/frontend-vue/app/components/editor/EditorInspector.vue +80 -0
- package/frontend-vue/app/components/editor/EditorLeftPane.vue +103 -0
- package/frontend-vue/app/components/editor/EditorLifecycle.vue +67 -0
- package/frontend-vue/app/components/editor/EditorLoading.vue +23 -0
- package/frontend-vue/app/components/editor/EditorLocaleSwitch.vue +61 -0
- package/frontend-vue/app/components/editor/EditorMissingLocale.vue +72 -48
- package/frontend-vue/app/components/editor/EditorMissingPolicy.vue +42 -0
- package/frontend-vue/app/components/editor/EditorNotice.vue +127 -0
- package/frontend-vue/app/components/editor/EditorOutline.vue +65 -0
- package/frontend-vue/app/components/editor/EditorPalette.vue +95 -42
- package/frontend-vue/app/components/editor/EditorPaletteGroup.vue +66 -0
- package/frontend-vue/app/components/editor/EditorPublishReview.vue +102 -0
- package/frontend-vue/app/components/editor/EditorSaveState.vue +88 -0
- package/frontend-vue/app/components/editor/EditorShortcutHint.vue +17 -0
- package/frontend-vue/app/components/editor/EditorSimChip.vue +51 -0
- package/frontend-vue/app/components/editor/EditorTemplatePane.vue +131 -0
- package/frontend-vue/app/components/editor/EditorTestDataPane.vue +98 -0
- package/frontend-vue/app/components/editor/EditorTitle.vue +82 -0
- package/frontend-vue/app/components/editor/EditorTokenField.vue +224 -0
- package/frontend-vue/app/components/editor/EditorToolbar.vue +34 -134
- package/frontend-vue/app/components/editor/EditorVariableForm.vue +100 -0
- package/frontend-vue/app/components/editor/EditorVariableRow.vue +87 -0
- package/frontend-vue/app/components/editor/EditorVariablesPane.vue +161 -0
- package/frontend-vue/app/components/editor/EditorViewSwitches.vue +76 -0
- package/frontend-vue/app/components/editor/EditorVisibility.vue +101 -0
- package/frontend-vue/app/components/editor/EditorWorkspace.vue +62 -149
- package/frontend-vue/app/composables/useBlockContext.ts +16 -0
- package/frontend-vue/app/composables/useEditorActions.ts +381 -0
- package/frontend-vue/app/composables/useEditorAnnouncements.ts +51 -0
- package/frontend-vue/app/composables/useEditorContext.ts +30 -23
- package/frontend-vue/app/composables/useEditorSession.ts +299 -0
- package/frontend-vue/app/composables/useEditorShortcuts.ts +81 -0
- package/frontend-vue/app/composables/useLocalizedDefaults.ts +17 -0
- package/frontend-vue/app/composables/useMailingApi.ts +142 -27
- package/frontend-vue/app/composables/useOverviewSetup.ts +13 -0
- package/frontend-vue/app/composables/useReplayToast.ts +72 -0
- package/frontend-vue/app/composables/useTemplateCategories.ts +35 -0
- package/frontend-vue/app/composables/useTemplateDrawer.ts +196 -62
- package/frontend-vue/app/composables/useTemplateEditor.ts +318 -86
- package/frontend-vue/app/emails/EmailMailingTemplate.vue +16 -4
- package/frontend-vue/app/emails/components/MailingBlocks.vue +96 -38
- package/frontend-vue/app/emails/components/MailingTextLines.vue +20 -0
- package/frontend-vue/app/plugins/column-displays.ts +65 -0
- package/frontend-vue/app/plugins/{template-gallery-display.client.ts → template-gallery-display.ts} +1 -1
- package/frontend-vue/app/types/mailing.ts +193 -18
- package/frontend-vue/app/utils/api-error.ts +33 -0
- package/frontend-vue/app/utils/autocomplete.ts +120 -0
- package/frontend-vue/app/utils/blocks/components.ts +10 -10
- package/frontend-vue/app/utils/blocks/dnd.ts +7 -3
- package/frontend-vue/app/utils/blocks/factory.ts +199 -38
- package/frontend-vue/app/utils/blocks/fields.ts +39 -19
- package/frontend-vue/app/utils/blocks/index.ts +1 -0
- package/frontend-vue/app/utils/blocks/outline.ts +91 -0
- package/frontend-vue/app/utils/blocks/tree.ts +114 -2
- package/frontend-vue/app/utils/categories.ts +201 -15
- package/frontend-vue/app/utils/changes.ts +152 -0
- package/frontend-vue/app/utils/conditions.ts +25 -19
- package/frontend-vue/app/utils/editor-checks.ts +266 -0
- package/frontend-vue/app/utils/editor-route.ts +43 -4
- package/frontend-vue/app/utils/funnel.ts +74 -0
- package/frontend-vue/app/utils/gallery.ts +179 -1
- package/frontend-vue/app/utils/history.ts +66 -0
- package/frontend-vue/app/utils/lifecycle.ts +185 -0
- package/frontend-vue/app/utils/locales.ts +107 -2
- package/frontend-vue/app/utils/overview-setup.ts +83 -0
- package/frontend-vue/app/utils/pages.ts +5 -0
- package/frontend-vue/app/utils/paths.ts +51 -15
- package/frontend-vue/app/utils/period.ts +62 -22
- package/frontend-vue/app/utils/problems.ts +181 -0
- package/frontend-vue/app/utils/recipients.ts +49 -0
- package/frontend-vue/app/utils/rendering-title.ts +23 -0
- package/frontend-vue/app/utils/send-actions.ts +207 -0
- package/frontend-vue/app/utils/send-link.ts +28 -0
- package/frontend-vue/app/utils/send-snippet.ts +97 -0
- package/frontend-vue/app/utils/send-stats.ts +24 -0
- package/frontend-vue/app/utils/send-values.ts +156 -0
- package/frontend-vue/app/utils/shortcuts.ts +113 -0
- package/frontend-vue/app/utils/slug.ts +82 -0
- package/frontend-vue/app/utils/starters.ts +23 -0
- package/frontend-vue/app/utils/suppression.ts +112 -0
- package/frontend-vue/app/utils/system-variables.ts +165 -0
- package/frontend-vue/app/utils/template-attention.ts +104 -0
- package/frontend-vue/app/utils/timeline.ts +221 -19
- package/frontend-vue/app/utils/tokens.ts +115 -13
- package/frontend-vue/app/utils/variable-types.ts +23 -0
- package/frontend-vue/app/utils/variables.ts +208 -1
- package/frontend-vue/app/utils/version-history.ts +53 -0
- package/frontend-vue/app/utils/webhook-status.ts +170 -0
- package/frontend-vue/dms.frontend.ts +19 -11
- package/frontend-vue/i18n/locales/mailing-en-GB.json +1173 -161
- package/frontend-vue/i18n/locales/mailing-fr-FR.json +1220 -208
- package/frontend-vue/package.json +4 -1
- package/frontend-vue/pnpm-lock.yaml +46 -161
- package/frontend-vue/tests/api-error.test.ts +27 -0
- package/frontend-vue/tests/autocomplete.test.ts +84 -0
- package/frontend-vue/tests/block-components.test.ts +1 -1
- package/frontend-vue/tests/block-fields.test.ts +12 -2
- package/frontend-vue/tests/blocks-factory.test.ts +46 -0
- package/frontend-vue/tests/blocks-outline.test.ts +102 -0
- package/frontend-vue/tests/blocks-tree.test.ts +28 -1
- package/frontend-vue/tests/categories-input.test.ts +139 -0
- package/frontend-vue/tests/categories.test.ts +148 -15
- package/frontend-vue/tests/changes.test.ts +136 -0
- package/frontend-vue/tests/column-displays.test.ts +73 -0
- package/frontend-vue/tests/conditions.test.ts +49 -19
- package/frontend-vue/tests/dnd.test.ts +10 -0
- package/frontend-vue/tests/editor-block-list.test.ts +24 -2
- package/frontend-vue/tests/editor-checks.test.ts +178 -0
- package/frontend-vue/tests/editor-route.test.ts +37 -9
- package/frontend-vue/tests/editor-session.test.ts +206 -0
- package/frontend-vue/tests/footer-block.test.ts +88 -0
- package/frontend-vue/tests/funnel-card.test.ts +116 -0
- package/frontend-vue/tests/funnel.test.ts +81 -0
- package/frontend-vue/tests/gallery.test.ts +124 -2
- package/frontend-vue/tests/helpers/nuxt-globals.ts +232 -0
- package/frontend-vue/tests/history.test.ts +48 -0
- package/frontend-vue/tests/i18n-editor.test.ts +38 -0
- package/frontend-vue/tests/i18n.test.ts +55 -0
- package/frontend-vue/tests/lifecycle.test.ts +145 -0
- package/frontend-vue/tests/locales.test.ts +60 -0
- package/frontend-vue/tests/localized-defaults.test.ts +54 -0
- package/frontend-vue/tests/new-template-modal.test.ts +210 -0
- package/frontend-vue/tests/overview-gate.test.ts +146 -0
- package/frontend-vue/tests/overview-setup.test.ts +78 -0
- package/frontend-vue/tests/paths.test.ts +23 -0
- package/frontend-vue/tests/period.test.ts +59 -10
- package/frontend-vue/tests/problems.test.ts +153 -0
- package/frontend-vue/tests/recipients.test.ts +47 -0
- package/frontend-vue/tests/rendering-title.test.ts +24 -0
- package/frontend-vue/tests/replay-toast.test.ts +67 -0
- package/frontend-vue/tests/retention-input.test.ts +129 -0
- package/frontend-vue/tests/send-actions.test.ts +128 -0
- package/frontend-vue/tests/send-modals.test.ts +415 -0
- package/frontend-vue/tests/send-snippet.test.ts +51 -0
- package/frontend-vue/tests/send-stats.test.ts +12 -0
- package/frontend-vue/tests/send-values.test.ts +119 -0
- package/frontend-vue/tests/shortcuts.test.ts +75 -0
- package/frontend-vue/tests/slug.test.ts +88 -0
- package/frontend-vue/tests/suppression.test.ts +159 -0
- package/frontend-vue/tests/system-variables.test.ts +133 -0
- package/frontend-vue/tests/template-attention.test.ts +123 -0
- package/frontend-vue/tests/template-drawer.test.ts +449 -0
- package/frontend-vue/tests/template-editor.test.ts +218 -9
- package/frontend-vue/tests/template-gallery-display.test.ts +32 -0
- package/frontend-vue/tests/template-gallery.test.ts +370 -0
- package/frontend-vue/tests/template-overlays.test.ts +125 -0
- package/frontend-vue/tests/timeline.test.ts +175 -20
- package/frontend-vue/tests/tokens.test.ts +79 -1
- package/frontend-vue/tests/variable-path.test.ts +22 -0
- package/frontend-vue/tests/variable-types.test.ts +20 -0
- package/frontend-vue/tests/variables.test.ts +90 -2
- package/frontend-vue/tests/version-history.test.ts +41 -0
- package/frontend-vue/tests/webhook-status.test.ts +108 -0
- package/package.json +11 -9
- package/src/automation/email-event-trigger.ts +3 -3
- package/src/automation/send-template-action.ts +7 -5
- package/src/config.ts +3 -1
- package/src/constants.ts +18 -2
- package/src/crons/attention.ts +21 -0
- package/src/crons/index.ts +2 -0
- package/src/crons/jobs.ts +35 -0
- package/src/crons/retention.ts +7 -22
- package/src/data/displays.ts +18 -0
- package/src/data/index.ts +1 -0
- package/src/data/locale-fallback.ts +26 -0
- package/src/data/read-only-routes.ts +14 -0
- package/src/data/sends-table.ts +204 -19
- package/src/data/suppressions-table.ts +127 -0
- package/src/data/templates-table.ts +295 -63
- package/src/data-types/categories-type.ts +4 -5
- package/src/data-types/category-type.ts +1 -1
- package/src/db/models/index.ts +3 -0
- package/src/db/models/sends.model.ts +102 -1
- package/src/db/models/settings.model.ts +2 -12
- package/src/db/models/suppressions.model.ts +53 -0
- package/src/db/models/template-versions.model.ts +23 -0
- package/src/db/models/templates.model.ts +17 -0
- package/src/db/models/webhook-status.model.ts +25 -0
- package/src/db/tables/index.ts +3 -0
- package/src/db/tables/send-events.table.ts +6 -2
- package/src/db/tables/sends.table.ts +37 -2
- package/src/db/tables/suppressions.table.ts +46 -0
- package/src/db/tables/template-versions.table.ts +44 -0
- package/src/db/tables/templates.table.ts +67 -5
- package/src/db/tables/webhook-status.table.ts +44 -0
- package/src/engine/changes.ts +198 -0
- package/src/engine/conditions.ts +1 -7
- package/src/engine/coverage.ts +7 -2
- package/src/engine/fallback-html.ts +80 -42
- package/src/engine/index.ts +3 -0
- package/src/engine/plain-text.ts +86 -0
- package/src/engine/resolve.ts +49 -15
- package/src/engine/system-variables.ts +124 -0
- package/src/engine/tokens.ts +13 -1
- package/src/hooks/tenant-export.ts +21 -2
- package/src/implementations/dms-mailing/index.ts +1 -1
- package/src/index.ts +29 -13
- package/src/pages/editor.ts +13 -2
- package/src/pages/index.ts +6 -3
- package/src/pages/module.ts +31 -2
- package/src/pages/overview.ts +187 -128
- package/src/pages/sends.ts +271 -112
- package/src/pages/settings/form.ts +144 -54
- package/src/pages/settings/page.ts +9 -17
- package/src/pages/suppressions.ts +157 -0
- package/src/pages/templates.ts +139 -42
- package/src/permissions.ts +6 -4
- package/src/quick-actions.ts +12 -5
- package/src/routes/events.ts +110 -33
- package/src/routes/index.ts +2 -0
- package/src/routes/metrics.ts +348 -98
- package/src/routes/period.ts +23 -6
- package/src/routes/sends.ts +413 -41
- package/src/routes/settings.ts +291 -26
- package/src/routes/suppressions.ts +87 -0
- package/src/routes/template-versions.ts +116 -0
- package/src/routes/templates.ts +334 -48
- package/src/services/attention.ts +283 -30
- package/src/services/catalog.ts +28 -0
- package/src/services/categories.ts +28 -27
- package/src/services/checked-send.ts +123 -0
- package/src/services/events.ts +174 -20
- package/src/services/metrics.ts +137 -28
- package/src/services/notify.ts +126 -44
- package/src/services/provider-banner.ts +165 -0
- package/src/services/render.ts +1 -0
- package/src/services/send-stat-items.ts +160 -0
- package/src/services/send-stats.ts +122 -0
- package/src/services/send.ts +193 -31
- package/src/services/settings.ts +52 -8
- package/src/services/starters.ts +383 -0
- package/src/services/suppressions.ts +116 -0
- package/src/services/template-attention.ts +82 -0
- package/src/services/template-stats.ts +97 -0
- package/src/services/templates.ts +400 -37
- package/src/services/webhook-status.ts +202 -0
- package/src/types/blocks.ts +6 -0
- package/src/types/index.ts +2 -0
- package/src/types/sends.ts +64 -2
- package/src/types/suppressions.ts +27 -0
- package/src/types/webhook.ts +29 -0
- package/src/validation/settings.schema.ts +173 -17
- package/src/validation/templates.schema.ts +53 -1
- package/dist/antelope-modules.d.ts +0 -32
- package/dist/antelope-modules.js +0 -36
- package/dist/antelope-modules.js.map +0 -1
- package/dist/test/antelope.test.d.ts +0 -2
- package/dist/test/antelope.test.js +0 -180
- package/dist/test/antelope.test.js.map +0 -1
- package/dist/test/helpers/http.d.ts +0 -4
- package/dist/test/helpers/http.js +0 -28
- package/dist/test/helpers/http.js.map +0 -1
- package/dist/test/helpers/owner.d.ts +0 -5
- package/dist/test/helpers/owner.js +0 -30
- package/dist/test/helpers/owner.js.map +0 -1
- package/dist/test/integration/events.test.d.ts +0 -1
- package/dist/test/integration/events.test.js +0 -143
- package/dist/test/integration/events.test.js.map +0 -1
- package/dist/test/integration/retention.test.d.ts +0 -1
- package/dist/test/integration/retention.test.js +0 -291
- package/dist/test/integration/retention.test.js.map +0 -1
- package/dist/test/integration/sends.test.d.ts +0 -1
- package/dist/test/integration/sends.test.js +0 -210
- package/dist/test/integration/sends.test.js.map +0 -1
- package/dist/test/integration/settings.test.d.ts +0 -1
- package/dist/test/integration/settings.test.js +0 -137
- package/dist/test/integration/settings.test.js.map +0 -1
- package/dist/test/integration/setup.test.d.ts +0 -1
- package/dist/test/integration/setup.test.js +0 -32
- package/dist/test/integration/setup.test.js.map +0 -1
- package/dist/test/integration/templates.test.d.ts +0 -1
- package/dist/test/integration/templates.test.js +0 -233
- package/dist/test/integration/templates.test.js.map +0 -1
- package/dist/test/integration/tenant-export.test.d.ts +0 -1
- package/dist/test/integration/tenant-export.test.js +0 -85
- package/dist/test/integration/tenant-export.test.js.map +0 -1
- package/dist/test/unit/attention.test.d.ts +0 -1
- package/dist/test/unit/attention.test.js +0 -109
- package/dist/test/unit/attention.test.js.map +0 -1
- package/dist/test/unit/automation.test.d.ts +0 -1
- package/dist/test/unit/automation.test.js +0 -104
- package/dist/test/unit/automation.test.js.map +0 -1
- package/dist/test/unit/categories.test.d.ts +0 -1
- package/dist/test/unit/categories.test.js +0 -38
- package/dist/test/unit/categories.test.js.map +0 -1
- package/dist/test/unit/engine/conditions.test.d.ts +0 -1
- package/dist/test/unit/engine/conditions.test.js +0 -23
- package/dist/test/unit/engine/conditions.test.js.map +0 -1
- package/dist/test/unit/engine/coverage.test.d.ts +0 -1
- package/dist/test/unit/engine/coverage.test.js +0 -106
- package/dist/test/unit/engine/coverage.test.js.map +0 -1
- package/dist/test/unit/engine/fallback-html.test.d.ts +0 -1
- package/dist/test/unit/engine/fallback-html.test.js +0 -78
- package/dist/test/unit/engine/fallback-html.test.js.map +0 -1
- package/dist/test/unit/engine/paths.test.d.ts +0 -1
- package/dist/test/unit/engine/paths.test.js +0 -33
- package/dist/test/unit/engine/paths.test.js.map +0 -1
- package/dist/test/unit/engine/resolve.test.d.ts +0 -1
- package/dist/test/unit/engine/resolve.test.js +0 -157
- package/dist/test/unit/engine/resolve.test.js.map +0 -1
- package/dist/test/unit/engine/tokens.test.d.ts +0 -1
- package/dist/test/unit/engine/tokens.test.js +0 -26
- package/dist/test/unit/engine/tokens.test.js.map +0 -1
- package/dist/test/unit/events.test.d.ts +0 -1
- package/dist/test/unit/events.test.js +0 -13
- package/dist/test/unit/events.test.js.map +0 -1
- package/dist/test/unit/metrics.test.d.ts +0 -1
- package/dist/test/unit/metrics.test.js +0 -108
- package/dist/test/unit/metrics.test.js.map +0 -1
- package/dist/test/unit/notify.test.d.ts +0 -1
- package/dist/test/unit/notify.test.js +0 -49
- package/dist/test/unit/notify.test.js.map +0 -1
- package/dist/test/unit/period.test.d.ts +0 -1
- package/dist/test/unit/period.test.js +0 -61
- package/dist/test/unit/period.test.js.map +0 -1
- package/dist/test/unit/permissions.test.d.ts +0 -1
- package/dist/test/unit/permissions.test.js +0 -27
- package/dist/test/unit/permissions.test.js.map +0 -1
- package/dist/test/unit/provider.test.d.ts +0 -1
- package/dist/test/unit/provider.test.js +0 -47
- package/dist/test/unit/provider.test.js.map +0 -1
- package/dist/test/unit/realtime.test.d.ts +0 -1
- package/dist/test/unit/realtime.test.js +0 -13
- package/dist/test/unit/realtime.test.js.map +0 -1
- package/dist/test/unit/render.test.d.ts +0 -1
- package/dist/test/unit/render.test.js +0 -23
- package/dist/test/unit/render.test.js.map +0 -1
- package/dist/test/unit/retention.test.d.ts +0 -1
- package/dist/test/unit/retention.test.js +0 -66
- package/dist/test/unit/retention.test.js.map +0 -1
- package/dist/test/unit/send-batch.test.d.ts +0 -1
- package/dist/test/unit/send-batch.test.js +0 -46
- package/dist/test/unit/send-batch.test.js.map +0 -1
- package/dist/test/unit/send.test.d.ts +0 -1
- package/dist/test/unit/send.test.js +0 -120
- package/dist/test/unit/send.test.js.map +0 -1
- package/dist/test/unit/smoke.test.d.ts +0 -1
- package/dist/test/unit/smoke.test.js +0 -10
- package/dist/test/unit/smoke.test.js.map +0 -1
- package/dist/test/unit/status.test.d.ts +0 -1
- package/dist/test/unit/status.test.js +0 -16
- package/dist/test/unit/status.test.js.map +0 -1
- package/dist/test/unit/templates.test.d.ts +0 -1
- package/dist/test/unit/templates.test.js +0 -48
- package/dist/test/unit/templates.test.js.map +0 -1
- package/dist/test/unit/tenant-export.test.d.ts +0 -1
- package/dist/test/unit/tenant-export.test.js +0 -59
- package/dist/test/unit/tenant-export.test.js.map +0 -1
- package/dist/test/unit/webhook-secret.test.d.ts +0 -1
- package/dist/test/unit/webhook-secret.test.js +0 -43
- package/dist/test/unit/webhook-secret.test.js.map +0 -1
- package/frontend-vue/app/components/AttentionCard.vue +0 -78
- package/frontend-vue/app/components/HtmlPreviewModal.vue +0 -20
- package/frontend-vue/app/components/ProviderChip.vue +0 -39
- package/frontend-vue/app/components/editor/EditorBlockSettings.vue +0 -186
- package/frontend-vue/app/components/editor/EditorDataPanel.vue +0 -130
- package/frontend-vue/app/components/editor/EditorDraftBar.vue +0 -35
- package/frontend-vue/app/components/editor/EditorRail.vue +0 -58
- package/frontend-vue/app/components/editor/EditorSubjectSettings.vue +0 -37
- package/frontend-vue/app/components/editor/EditorTemplateSettings.vue +0 -87
- package/frontend-vue/app/components/editor/EditorTestSendModal.vue +0 -66
- package/frontend-vue/app/components/editor/EditorVariables.vue +0 -163
- package/frontend-vue/app/composables/useMailingPeriodData.ts +0 -39
- package/src/antelope-modules.ts +0 -48
- package/src/test/antelope.test.ts +0 -190
- package/src/test/helpers/http.ts +0 -23
- package/src/test/helpers/owner.ts +0 -37
- package/src/test/integration/events.test.ts +0 -159
- package/src/test/integration/retention.test.ts +0 -363
- package/src/test/integration/sends.test.ts +0 -233
- package/src/test/integration/settings.test.ts +0 -128
- package/src/test/integration/setup.test.ts +0 -35
- package/src/test/integration/templates.test.ts +0 -272
- package/src/test/integration/tenant-export.test.ts +0 -125
- package/src/test/unit/attention.test.ts +0 -129
- package/src/test/unit/automation.test.ts +0 -130
- package/src/test/unit/categories.test.ts +0 -51
- package/src/test/unit/engine/conditions.test.ts +0 -35
- package/src/test/unit/engine/coverage.test.ts +0 -118
- package/src/test/unit/engine/fallback-html.test.ts +0 -86
- package/src/test/unit/engine/paths.test.ts +0 -39
- package/src/test/unit/engine/resolve.test.ts +0 -176
- package/src/test/unit/engine/tokens.test.ts +0 -26
- package/src/test/unit/events.test.ts +0 -19
- package/src/test/unit/metrics.test.ts +0 -170
- package/src/test/unit/notify.test.ts +0 -71
- package/src/test/unit/period.test.ts +0 -91
- package/src/test/unit/permissions.test.ts +0 -30
- package/src/test/unit/provider.test.ts +0 -57
- package/src/test/unit/realtime.test.ts +0 -11
- package/src/test/unit/render.test.ts +0 -23
- package/src/test/unit/retention.test.ts +0 -91
- package/src/test/unit/send-batch.test.ts +0 -72
- package/src/test/unit/send.test.ts +0 -161
- package/src/test/unit/smoke.test.ts +0 -8
- package/src/test/unit/status.test.ts +0 -14
- package/src/test/unit/templates.test.ts +0 -52
- package/src/test/unit/tenant-export.test.ts +0 -88
- package/src/test/unit/webhook-secret.test.ts +0 -51
package/README.md
CHANGED
|
@@ -7,25 +7,60 @@
|
|
|
7
7
|
</div>
|
|
8
8
|
|
|
9
9
|
Mailing module for the AntelopeJS DMS: a template library with a block-based
|
|
10
|
-
e-mail editor, a send log, an overview
|
|
11
|
-
settings. It owns the data (tenant-scoped Mongo tables), renders
|
|
12
|
-
through the DMS html-render chain and sends them through
|
|
10
|
+
e-mail editor, drafts and published versions, a send log, an overview
|
|
11
|
+
dashboard and settings. It owns the data (tenant-scoped Mongo tables), renders
|
|
12
|
+
e-mails through the DMS html-render chain and sends them through
|
|
13
13
|
`@antelopejs/interface-email`.
|
|
14
14
|
|
|
15
|
+
The module targets `@antelopejs/dms` 0.7 (0.7.21 or later) and `@antelopejs/dms-frontend` 0.5 (0.5.5 or later).
|
|
16
|
+
Like every DMS module, its pages live in the module's own sidebar (Mailing:
|
|
17
|
+
Overview, Templates, Sends; Configure: Settings, Suppression list) and are
|
|
18
|
+
reserved to the platform owner. The design decisions behind the v2 screens are recorded in
|
|
19
|
+
[`docs/design-v2-grill-me.md`](../../docs/design-v2-grill-me.md).
|
|
20
|
+
|
|
21
|
+
## Breaking changes since 0.3
|
|
22
|
+
|
|
23
|
+
The v2 redesign neither reads what 0.3.x wrote nor takes its calls:
|
|
24
|
+
|
|
25
|
+
- **Webhook URL.** `POST /api/mailing/events/<provider>`, with the tenant in
|
|
26
|
+
the body, is gone. Copy the URL **Settings › Provider & webhook** shows
|
|
27
|
+
(`/api/mailing/events/<provider>/<tenantId>`) into the provider again.
|
|
28
|
+
- **Settings writes.** `POST /api/mailing/settings` is gone: send the changed
|
|
29
|
+
fields with `PUT /api/mailing/settings`. A write carrying a read-only field
|
|
30
|
+
(`webhookUrl`, `provider`) is refused.
|
|
31
|
+
- **Categories.** The settings take `categories` as an array only, no longer
|
|
32
|
+
as its JSON text, and always with the `marketing` category (it can be
|
|
33
|
+
renamed, not removed: campaign rules depend on it).
|
|
34
|
+
- **Interface.** The module implements `@antelopejs/interface-dms-mailing`
|
|
35
|
+
0.7, whose `SendStatus` adds `suppressed`.
|
|
36
|
+
- **Data.** A 0.3.x database is not read any more (settings rows without the
|
|
37
|
+
tenant key, templates without version numbers, sends without a stage):
|
|
38
|
+
start the module on an empty database.
|
|
39
|
+
|
|
40
|
+
## Drafts and versions
|
|
41
|
+
|
|
42
|
+
The editor never changes what customers receive. It saves a draft next to the
|
|
43
|
+
published content; **Publish** turns the draft into the next version, keeps
|
|
44
|
+
it in `mailing_template_versions` and makes it what `SendTemplate` sends.
|
|
45
|
+
**Discard** drops the draft. Test sends use the draft (their subject starts
|
|
46
|
+
with `[TEST]`), real sends always use the published version, and every send
|
|
47
|
+
records the version it used and the locale the caller asked for, so the log
|
|
48
|
+
can render exactly what went out and show `DE → EN` fallbacks.
|
|
49
|
+
|
|
15
50
|
## Layout
|
|
16
51
|
|
|
17
52
|
| Path | What it holds |
|
|
18
53
|
| --- | --- |
|
|
19
|
-
| `src/index.ts` | Module lifecycle (`construct`/`start`/`stop`/`destroy`); registers the Vue frontend module, the automation nodes, the tenant-export contributor, the realtime topics and the
|
|
20
|
-
| `src/pages/` | The DMS pages: `overview`, `templates`,
|
|
54
|
+
| `src/index.ts` | Module lifecycle (`construct`/`start`/`stop`/`destroy`); registers the Vue frontend module, the automation nodes, the tenant-export contributor, the realtime topics and the crons. |
|
|
55
|
+
| `src/pages/` | The DMS pages: `overview`, `templates`, the editor (`templates/:id`), `sends`, `settings` and `suppressions`, all inside the module sidebar. Every custom block carries a `.meta()` with i18n keys. |
|
|
21
56
|
| `src/data/` | The `TableView` data controllers behind `/api/mailing/tables/*`. |
|
|
22
|
-
| `src/routes/` | The HTTP API under `/api/mailing` (templates, sends, events, metrics, settings, provider). |
|
|
57
|
+
| `src/routes/` | The HTTP API under `/api/mailing` (templates, sends, events, metrics, settings, provider, suppressions). |
|
|
23
58
|
| `src/engine/` | The pure-TS rendering engine: block tree + variables → resolved e-mail. |
|
|
24
59
|
| `../interface-dms-mailing/` | The separately published public AntelopeJS interface (see below). |
|
|
25
60
|
| `src/automation/` | The `dms-automation` action and trigger. |
|
|
26
|
-
| `src/crons/` | The daily, replay-safe send-log retention job. |
|
|
61
|
+
| `src/crons/` | The daily, replay-safe send-log retention job and the hourly refresh of the templates needing attention. |
|
|
27
62
|
| `src/hooks/` | The tenant data export contributor. |
|
|
28
|
-
| `frontend-vue/` | Vue
|
|
63
|
+
| `frontend-vue/` | Vue module registered under the `Mailing` component prefix: gallery display, template and send drawers, test / real send dialogs, the three-pane block editor, the overview and settings blocks, `dms.email.ts` server template entry and the `mailing-*.json` i18n catalogs. Its own composables and utils are imported by path, not auto-imported. |
|
|
29
64
|
| `playground/` | Standalone AntelopeJS project wiring this module to the DMS, Mongo, the API server and the mailer, for local development. |
|
|
30
65
|
|
|
31
66
|
## Public interface
|
|
@@ -62,25 +97,199 @@ once and issues a single `SendBatch`; otherwise it loops `Send`. Either way one
|
|
|
62
97
|
row per recipient lands in the send log, and the returned
|
|
63
98
|
`SendTemplateResult` describes the first one.
|
|
64
99
|
|
|
100
|
+
A recipient on the [suppression list](#suppression-list) gets nothing: its
|
|
101
|
+
row in the log and its entry in `results` have the status `suppressed`, and
|
|
102
|
+
`error` names the reason as an i18n key
|
|
103
|
+
(`$dms_mailing.errors.suppressed.hard_bounce`, `….complaint`,
|
|
104
|
+
`….unsubscribe`, `….manual`). Do not retry such a send.
|
|
105
|
+
|
|
106
|
+
## What a recipient receives
|
|
107
|
+
|
|
108
|
+
Every e-mail goes out as HTML and as a plain-text part generated from the
|
|
109
|
+
same blocks (`multipart/alternative`), with a `viewport` meta. The header logo
|
|
110
|
+
is the DMS branding's light logo (`branding.logo.default.light`) at an
|
|
111
|
+
absolute public URL (the DMS `clientBaseUrl`): on a `localhost`, private-IP or
|
|
112
|
+
`.local` address, or for an SVG (refused by Gmail and Outlook), it is left out
|
|
113
|
+
rather than shown broken. The editor canvas draws the same header and footer.
|
|
114
|
+
|
|
115
|
+
**Footer links are system variables.** A footer whose unsubscribe or
|
|
116
|
+
preferences label is filled (or a `{{unsubscribeUrl}}` / `{{preferencesUrl}}`
|
|
117
|
+
token anywhere) declares `unsubscribeUrl` / `preferencesUrl` as variables of
|
|
118
|
+
type `url`, required when the template is in the `marketing` category. The
|
|
119
|
+
editor shows them in the Variables tab, the template drawer in its contract and
|
|
120
|
+
its "Call it from code" snippet; pass them in `variables` at send time:
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
await SendTemplate("newsletter-october", {
|
|
124
|
+
tenantId,
|
|
125
|
+
to: "ana@example.com",
|
|
126
|
+
variables: {
|
|
127
|
+
unsubscribeUrl: `https://app.example.com/unsubscribe/${token}`,
|
|
128
|
+
preferencesUrl: "https://app.example.com/preferences",
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
A link whose URL is missing is dropped from the e-mail, and an empty label
|
|
134
|
+
removes the link. For a marketing template, a missing required URL refuses a
|
|
135
|
+
manual real send, and every send when "Missing variables" is set to refuse;
|
|
136
|
+
a test send never waits for it. The starters and the templates of the other
|
|
137
|
+
categories get a footer with a legal line and no unsubscribe link.
|
|
138
|
+
|
|
139
|
+
## Suppression list
|
|
140
|
+
|
|
141
|
+
An address goes on the workspace's suppression list (`mailing_suppressions`)
|
|
142
|
+
when the provider reports a permanent bounce (a `bounced` event that is not
|
|
143
|
+
temporary: no `4xx` / `4.x.x` answer, no `soft` bounce type), a spam
|
|
144
|
+
complaint (`spam`) or an unsubscription (`unsubscribed`), or when someone adds
|
|
145
|
+
it by hand. A test send only adds its address on a permanent bounce: a spam
|
|
146
|
+
report or an unsubscription on a test is the editor's own gesture.
|
|
147
|
+
|
|
148
|
+
Every send path checks the list: `SendTemplate`, the automation action, the
|
|
149
|
+
real send dialog, "Send again" and "Send to another address". A suppressed
|
|
150
|
+
recipient is logged with the status `suppressed` (the Sends page has a tab for
|
|
151
|
+
them, and the figures leave them out) and nothing is handed to the provider.
|
|
152
|
+
A test send to the editor's own address still goes out, and the dialog warns
|
|
153
|
+
that the address is suppressed; a test to any other suppressed address does
|
|
154
|
+
not.
|
|
155
|
+
|
|
156
|
+
**Configure › Suppression list** lists the addresses with their reason and
|
|
157
|
+
the send that caused it, searchable and filtered by reason. **Add an
|
|
158
|
+
address** puts one on the list by hand (with an optional note); **Reactivate**
|
|
159
|
+
lifts it, and the next send reaches it again. The same operations are
|
|
160
|
+
`POST /api/mailing/suppressions` (`{ "email", "note"? }`, `409` when the
|
|
161
|
+
address is already on the list) and `DELETE /api/mailing/suppressions/:id`.
|
|
162
|
+
The tenant data export carries the list as `suppressions.json`.
|
|
163
|
+
|
|
164
|
+
## Configuration
|
|
165
|
+
|
|
166
|
+
The module takes one option, in the `config` of its entry in the project's
|
|
167
|
+
`antelope.config.ts`:
|
|
168
|
+
|
|
169
|
+
```ts
|
|
170
|
+
config: {
|
|
171
|
+
// false renders with the module's own fallback HTML, not the DMS chain.
|
|
172
|
+
useHtmlRender: true,
|
|
173
|
+
},
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
The webhook URL of **Settings › Provider & webhook** starts with the DMS
|
|
177
|
+
`clientBaseUrl`, the dashboard's public origin (read through
|
|
178
|
+
`GetClientBaseUrl`): set it in the `dms` module's config as soon as a real
|
|
179
|
+
provider has to reach the webhook. The module declares the route a public
|
|
180
|
+
endpoint of the dashboard, so the frontend server's proxy lets a provider's
|
|
181
|
+
`POST` through without an `Origin`, never sends it a session and relays the
|
|
182
|
+
`x-mailing-webhook-secret` header. The URL never follows the headers of the
|
|
183
|
+
request that reads it. A provider already posting to the API origin
|
|
184
|
+
(`apiBaseUrl`) keeps working: the path and the header are the same.
|
|
185
|
+
|
|
65
186
|
## Webhook contract
|
|
66
187
|
|
|
67
|
-
Provider events are posted to
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
188
|
+
The module has one generic event format. Provider events are posted to
|
|
189
|
+
|
|
190
|
+
```
|
|
191
|
+
POST <clientBaseUrl>/api/mailing/events/<provider>/<tenantId>
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
the URL **Settings › Provider & webhook** shows, ready to copy. `<provider>`
|
|
195
|
+
is a free label recorded with the event (the settings use the configured
|
|
196
|
+
e-mail provider's name); `<tenantId>` names the workspace.
|
|
197
|
+
|
|
198
|
+
Every request carries the workspace's secret in the `x-mailing-webhook-secret`
|
|
199
|
+
header (Settings › Provider & webhook; rotating it invalidates the old one at
|
|
200
|
+
once). The body is JSON:
|
|
72
201
|
|
|
73
202
|
```sh
|
|
74
|
-
curl -X POST
|
|
203
|
+
curl -X POST https://dms.example.com/api/mailing/events/postmark/<tenantId> \
|
|
75
204
|
-H "Content-Type: application/json" \
|
|
76
|
-
-H "x-mailing-webhook-secret: <
|
|
77
|
-
-d '{"messageId":"<provider message id>","type":"bounced","at":"2026-09-09T10:00:00.000Z","details":{"reason":"
|
|
205
|
+
-H "x-mailing-webhook-secret: <secret>" \
|
|
206
|
+
-d '{"messageId":"<provider message id>","type":"bounced","at":"2026-09-09T10:00:00.000Z","details":{"reason":"550 5.1.1 No such user","bounceType":"hard","eventId":"<provider event id>"}}'
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
| Field | Meaning |
|
|
210
|
+
| --- | --- |
|
|
211
|
+
| `messageId` | The id the provider returned when the e-mail was sent (the send's `providerMessageId`). Required. |
|
|
212
|
+
| `type` | `queued`, `sent`, `delivered`, `opened`, `clicked`, `bounced`, `spam`, `failed` or `unsubscribed`. Required. |
|
|
213
|
+
| `at` | When it happened (ISO date); now by default. |
|
|
214
|
+
| `details.reason` | The provider's words (`550 5.1.1 …`), shown in the log. |
|
|
215
|
+
| `details.bounceType` | `soft`/`transient`/`temporary` or `hard`/`permanent`; without it the SMTP class of `reason` decides. A permanent bounce suppresses the address. |
|
|
216
|
+
| `details.eventId` | The provider's event id: a retried webhook with the same id is ignored. |
|
|
217
|
+
| `details.url`, `details.userAgent` | Shown on the click and open steps. |
|
|
218
|
+
|
|
219
|
+
The answer is `200 {"recorded": true}`, or `{"recorded": false}` when no send
|
|
220
|
+
carries the message id (or the event was already recorded). The event is
|
|
221
|
+
appended to the send's timeline, the status only ever moves forward (a
|
|
222
|
+
delivery after a provider failure wins over it), a hard bounce, a spam report
|
|
223
|
+
or an unsubscription puts the address on the suppression list, and repeated
|
|
224
|
+
problems on a template notify the tenant owners in the DMS bell.
|
|
225
|
+
|
|
226
|
+
A refused call gets a readable JSON body, for the relay's logs:
|
|
227
|
+
|
|
228
|
+
| Status | `reason` | Why |
|
|
229
|
+
| --- | --- | --- |
|
|
230
|
+
| `403` | `missing_secret` | No `x-mailing-webhook-secret` header. |
|
|
231
|
+
| `403` | `bad_secret` | The header does not match the workspace's secret, or the workspace has no mailing settings yet (any mailing page or send creates them). |
|
|
232
|
+
| `400` | `invalid_event` | The secret is right but the body is not an event. |
|
|
233
|
+
|
|
234
|
+
```json
|
|
235
|
+
{ "error": "webhook_refused", "reason": "bad_secret", "message": "The x-mailing-webhook-secret header does not match …" }
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
The secret is checked before the body, so a caller without it learns nothing
|
|
239
|
+
of the format. **Settings › Provider & webhook › Webhook status** shows the
|
|
240
|
+
last event received (when, its type, the provider label, whether it matched a
|
|
241
|
+
send) and the last call refused (when, and why). **Send a test event** posts a
|
|
242
|
+
test event to the URL shown, with the stored secret, from the backend: it
|
|
243
|
+
proves the URL is reachable from the server, the secret and the format, and
|
|
244
|
+
touches no send (its message id is `dms-mailing-webhook-test`).
|
|
245
|
+
|
|
246
|
+
### Relaying a provider
|
|
247
|
+
|
|
248
|
+
Providers post their own format (Postmark, SES through SNS, Mailgun,
|
|
249
|
+
SendGrid, Resend…) and most cannot add a custom header. Put a small relay
|
|
250
|
+
between them and the module: it checks the provider's own signature,
|
|
251
|
+
translates each event and forwards it with the secret. A sketch for Postmark:
|
|
252
|
+
|
|
253
|
+
```ts
|
|
254
|
+
const TYPES: Record<string, string> = {
|
|
255
|
+
Delivery: "delivered",
|
|
256
|
+
Open: "opened",
|
|
257
|
+
Click: "clicked",
|
|
258
|
+
Bounce: "bounced",
|
|
259
|
+
SpamComplaint: "spam",
|
|
260
|
+
SubscriptionChange: "unsubscribed",
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
export async function relayPostmark(event: PostmarkEvent): Promise<void> {
|
|
264
|
+
const type = TYPES[event.RecordType];
|
|
265
|
+
if (!type) return;
|
|
266
|
+
await fetch(MAILING_WEBHOOK_URL, {
|
|
267
|
+
method: "POST",
|
|
268
|
+
headers: {
|
|
269
|
+
"content-type": "application/json",
|
|
270
|
+
"x-mailing-webhook-secret": MAILING_WEBHOOK_SECRET,
|
|
271
|
+
},
|
|
272
|
+
body: JSON.stringify({
|
|
273
|
+
messageId: event.MessageID,
|
|
274
|
+
type,
|
|
275
|
+
at: event.ReceivedAt ?? event.DeliveredAt ?? event.BouncedAt,
|
|
276
|
+
details: {
|
|
277
|
+
reason: event.Details ?? event.Description,
|
|
278
|
+
bounceType: event.Type === "SoftBounce" ? "soft" : "hard",
|
|
279
|
+
eventId: String(event.ID ?? ""),
|
|
280
|
+
url: event.OriginalLink,
|
|
281
|
+
userAgent: event.UserAgent,
|
|
282
|
+
},
|
|
283
|
+
}),
|
|
284
|
+
});
|
|
285
|
+
}
|
|
78
286
|
```
|
|
79
287
|
|
|
80
|
-
|
|
81
|
-
`
|
|
82
|
-
|
|
83
|
-
`
|
|
288
|
+
A module of the same project can skip HTTP altogether and call
|
|
289
|
+
`RecordEmailEvent(tenantId, event)` from the public interface. A provider or
|
|
290
|
+
a relay posts through the dashboard's URL, as a public endpoint the module
|
|
291
|
+
declares (`AddFrontendModule({ publicEndpoints })`), or straight to the API on
|
|
292
|
+
`apiBaseUrl` when it is reachable: the path and the header are the same.
|
|
84
293
|
|
|
85
294
|
## Retention
|
|
86
295
|
|
|
@@ -133,7 +342,8 @@ pnpm frontend:dev # the DMS front-end, in another terminal
|
|
|
133
342
|
|
|
134
343
|
The backend listens on `http://localhost:5010` and needs a MongoDB on
|
|
135
344
|
`mongodb://localhost:27017` (database `playground_dms_mailing`); set
|
|
136
|
-
`MONGO_URL` to point the playground at another instance.
|
|
345
|
+
`MONGO_URL` to point the playground at another instance. E-mails go to an
|
|
346
|
+
Ethereal account, or to a local SMTP server when `SMTP_PORT` is set.
|
|
137
347
|
|
|
138
348
|
Both packages are public on npm, published under the `@antelopejs` scope with
|
|
139
349
|
npm trusted publishing and provenance. The interface package must be released
|
|
@@ -143,7 +353,7 @@ DMS mailing module` publishes this package and refuses to run until the
|
|
|
143
353
|
interface version its dependency range is floored at resolves on npm. Inside
|
|
144
354
|
the workspace that same range resolves to the sibling package, through
|
|
145
355
|
`link-workspace-packages`. The module implements the interface, so that range
|
|
146
|
-
is capped below the next minor (`>=0.
|
|
356
|
+
is capped below the next minor (`>=0.7.0 <0.8.0`): a breaking interface minor
|
|
147
357
|
never reaches a module that does not implement it, and the release workflow
|
|
148
358
|
refuses any other shape.
|
|
149
359
|
|
|
@@ -11,7 +11,7 @@ const CONFIG_SCHEMA = {
|
|
|
11
11
|
properties: {
|
|
12
12
|
types: {
|
|
13
13
|
type: "array",
|
|
14
|
-
items: { type: "string", enum: types_1.
|
|
14
|
+
items: { type: "string", enum: types_1.SEND_EVENT_TYPES },
|
|
15
15
|
description: "Event types the trigger fires on. Leave empty to fire on every event.",
|
|
16
16
|
},
|
|
17
17
|
},
|
|
@@ -22,7 +22,7 @@ const OUTPUT_SCHEMA = {
|
|
|
22
22
|
tenantId: { type: "string" },
|
|
23
23
|
sendId: { type: "string" },
|
|
24
24
|
templateSlug: { type: "string" },
|
|
25
|
-
type: { type: "string", enum: types_1.
|
|
25
|
+
type: { type: "string", enum: types_1.SEND_EVENT_TYPES },
|
|
26
26
|
recipientEmail: { type: "string" },
|
|
27
27
|
},
|
|
28
28
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"email-event-trigger.js","sourceRoot":"","sources":["../../src/automation/email-event-trigger.ts"],"names":[],"mappings":";;;AA8EA,wCAIC;AAGD,oEAEC;AAvFD,gEAA6D;AAK7D,
|
|
1
|
+
{"version":3,"file":"email-event-trigger.js","sourceRoot":"","sources":["../../src/automation/email-event-trigger.ts"],"names":[],"mappings":";;;AA8EA,wCAIC;AAGD,oEAEC;AAvFD,gEAA6D;AAK7D,oCAAgE;AAmBnD,QAAA,sBAAsB,GAAG,qBAAqB,CAAC;AAE5D,MAAM,aAAa,GAAe;IAChC,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE;QACV,KAAK,EAAE;YACL,IAAI,EAAE,OAAO;YACb,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,wBAAgB,EAAE;YACjD,WAAW,EACT,uEAAuE;SAC1E;KACF;CACF,CAAC;AAEF,MAAM,aAAa,GAAe;IAChC,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE;QACV,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC5B,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC1B,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAChC,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,wBAAgB,EAAE;QAChD,cAAc,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;KACnC;CACF,CAAC;AAEF,MAAM,wBAAwB,GAAG,CAAC,CAAC;AAEnC,MAAM,2BAA2B,GAAG,yCAAyC,CAAC;AAE9E,MAAM,aAAa,GAAG,IAAI,GAAG,EAAkC,CAAC;AAEhE,IAAI,qBAAqB,GAAG,wBAAwB,CAAC;AAErD,MAAM,OAAO,GAAG,CACd,YAAoC,EACpC,OAA0B,EACjB,EAAE,CACX,YAAY,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,YAAY,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAE/E,SAAS,OAAO,CACd,MAAc,EACd,YAAoC,EACpC,OAA0B;IAE1B,IAAI,CAAC;QACH,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,iBAAO,CAAC,IAAI,CACV,GAAG,2BAA2B,KAAK,MAAM,kBAAkB,OAAO,CAAC,IAAI,UAAU,EACjF,KAAK,CACN,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAgB,cAAc,CAAC,OAA0B;IACvD,KAAK,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,IAAI,aAAa,EAAE,CAAC;QACnD,IAAI,OAAO,CAAC,YAAY,EAAE,OAAO,CAAC;YAAE,OAAO,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;IAC7E,CAAC;AACH,CAAC;AAGD,SAAgB,4BAA4B;IAC1C,aAAa,CAAC,KAAK,EAAE,CAAC;AACxB,CAAC;AAEY,QAAA,iBAAiB,GAG1B;IACF,EAAE,EAAE,8BAAsB;IAC1B,IAAI,EAAE,cAAc;IACpB,WAAW,EACT,kEAAkE;IACpE,IAAI,EAAE,mBAAmB;IACzB,OAAO,EAAE,YAAY;IACrB,YAAY,EAAE,aAAa;IAC3B,YAAY,EAAE,aAAa;IAC3B,QAAQ,CAAC,MAAM,EAAE,IAAI;QACnB,MAAM,MAAM,GAAG,GAAG,8BAAsB,IAAI,qBAAqB,EAAE,CAAC;QACpE,qBAAqB,IAAI,CAAC,CAAC;QAC3B,aAAa,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QAChE,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;IACD,UAAU,CAAC,MAAM;QACf,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QACrC,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;CACF,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.sendTemplateAction = exports.SEND_TEMPLATE_ACTION_ID = void 0;
|
|
4
|
-
const
|
|
4
|
+
const checked_send_1 = require("../services/checked-send");
|
|
5
5
|
const types_1 = require("../types");
|
|
6
6
|
exports.SEND_TEMPLATE_ACTION_ID = "mailing.send-template";
|
|
7
7
|
const AUTOMATION_SOURCE_PREFIX = "automation:";
|
|
@@ -49,7 +49,7 @@ exports.sendTemplateAction = {
|
|
|
49
49
|
async execute(input, ctx) {
|
|
50
50
|
const source = input.source ?? `${AUTOMATION_SOURCE_PREFIX}${ctx.procedureId}`;
|
|
51
51
|
try {
|
|
52
|
-
const result = await (0,
|
|
52
|
+
const result = await (0, checked_send_1.sendUnlessSuppressed)(input.slug, {
|
|
53
53
|
tenantId: input.tenantId,
|
|
54
54
|
to: input.to,
|
|
55
55
|
locale: input.locale,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"send-template-action.js","sourceRoot":"","sources":["../../src/automation/send-template-action.ts"],"names":[],"mappings":";;;AAMA,
|
|
1
|
+
{"version":3,"file":"send-template-action.js","sourceRoot":"","sources":["../../src/automation/send-template-action.ts"],"names":[],"mappings":";;;AAMA,2DAAgE;AAChE,oCAAyC;AAW5B,QAAA,uBAAuB,GAAG,uBAAuB,CAAC;AAE/D,MAAM,wBAAwB,GAAG,aAAa,CAAC;AAE/C,MAAM,YAAY,GAAe;IAC/B,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE;QACV,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC5B,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,mCAAmC,EAAE;QAM1E,EAAE,EAAE;YACF,IAAI,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC;YACzB,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YACzB,WAAW,EAAE,wDAAwD;SACtE;QACD,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC1B,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC7B,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;KAC3B;IACD,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC;CACrC,CAAC;AAEF,MAAM,iBAAiB,GAAe;IACpC,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;IAC1B,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,qBAAa,EAAE;IAC/C,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;IAC7B,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;CAC1B,CAAC;AAEF,MAAM,aAAa,GAAe;IAChC,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE;QACV,GAAG,iBAAiB;QACpB,OAAO,EAAE;YACP,IAAI,EAAE,OAAO;YACb,WAAW,EAAE,yBAAyB;YACtC,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,iBAAiB,EAAE;SACzD;KACF;CACF,CAAC;AAEF,MAAM,gBAAgB,GAAG,CAAC,MAA0B,EAAwB,EAAE,CAC5E,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC;AAE/D,QAAA,kBAAkB,GAG3B;IACF,EAAE,EAAE,+BAAuB;IAC3B,IAAI,EAAE,sBAAsB;IAC5B,WAAW,EAAE,2DAA2D;IACxE,IAAI,EAAE,sBAAsB;IAC5B,WAAW,EAAE,YAAY;IACzB,YAAY,EAAE,aAAa;IAC3B,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG;QACtB,MAAM,MAAM,GACV,KAAK,CAAC,MAAM,IAAI,GAAG,wBAAwB,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;QAClE,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAA,mCAAoB,EAAC,KAAK,CAAC,IAAI,EAAE;gBACpD,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,EAAE,EAAE,KAAK,CAAC,EAAE;gBACZ,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,MAAM;aACP,CAAC,CAAC;YACH,MAAM,QAAQ,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;YAC1C,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxB,GAAG,CAAC,GAAG,CACL,OAAO,EACP,aAAa,KAAK,CAAC,IAAI,sBAAsB,QAAQ,CAAC,MAAM,eAAe,EAC3E,QAAQ,CACT,CAAC;YACJ,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,aAAa,KAAK,CAAC,IAAI,qBAAqB,EAAE,KAAK,CAAC,CAAC;YACtE,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;CACF,CAAC"}
|
package/dist/config.js
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.setConfig = setConfig;
|
|
4
4
|
exports.getConfig = getConfig;
|
|
5
|
-
const DEFAULTS = {
|
|
5
|
+
const DEFAULTS = {
|
|
6
|
+
useHtmlRender: true,
|
|
7
|
+
};
|
|
6
8
|
let current = DEFAULTS;
|
|
7
9
|
function setConfig(config) {
|
|
8
10
|
current = { ...DEFAULTS, ...config };
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;AAUA,8BAEC;AAED,8BAEC;AAZD,MAAM,QAAQ,GAA+B;IAC3C,aAAa,EAAE,IAAI;CACpB,CAAC;AAEF,IAAI,OAAO,GAA+B,QAAQ,CAAC;AAEnD,SAAgB,SAAS,CAAC,MAAwB;IAChD,OAAO,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,MAAM,EAAE,CAAC;AACvC,CAAC;AAED,SAAgB,SAAS;IACvB,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
package/dist/constants.d.ts
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
export declare const MODULE_ID = "mailing";
|
|
2
2
|
export declare const API_BASE_PATH = "/api/mailing";
|
|
3
3
|
export declare const TABLES_BASE_PATH = "/api/mailing/tables";
|
|
4
|
+
export declare const MODULE_BASE_PATH = "/modules/mailing";
|
|
5
|
+
export declare const TEMPLATES_PATH = "/modules/mailing/templates";
|
|
6
|
+
export declare const SENDS_PATH = "/modules/mailing/sends";
|
|
7
|
+
export declare const SETTINGS_PATH = "/modules/mailing/settings";
|
|
8
|
+
export declare const NEW_TEMPLATE_BUTTON_ID = "create";
|
|
9
|
+
export declare const NEW_TEMPLATE_ACTION_ID = "mailing.new-template";
|
|
4
10
|
export declare const FRONTEND_MODULE_NAME = "@antelopejs/dms-mailing-frontend-vue";
|
|
5
11
|
export declare const EMAIL_TEMPLATE_NAME = "EmailMailingTemplate";
|
|
6
12
|
export declare const MAILING_SEND_PERMISSION = "mailing.send";
|
|
7
13
|
export declare const OVERVIEW_PERIOD_SCOPE = "mailing-overview";
|
|
8
14
|
export declare const SENDS_PERIOD_SCOPE = "mailing-sends";
|
|
9
15
|
export declare const MAILING_SENDS_TOPIC = "mailing:sends";
|
|
10
|
-
export declare const GALLERY_DISPLAY_ID = "gallery";
|
|
16
|
+
export declare const GALLERY_DISPLAY_ID = "mailing:gallery";
|
|
11
17
|
export declare const TEMPLATE_CATEGORIES_TYPE_ID = "mailing_template_categories";
|
|
12
18
|
export declare const TEMPLATE_CATEGORY_TYPE_ID = "mailing_template_category";
|
|
13
19
|
export declare const DEFAULT_FALLBACK_LOCALE = "en";
|
|
@@ -21,5 +27,8 @@ export declare const HTTP_NOT_FOUND = 404;
|
|
|
21
27
|
export declare const HTTP_CONFLICT = 409;
|
|
22
28
|
export declare const HTTP_UNPROCESSABLE = 422;
|
|
23
29
|
export declare const LOCALE_LIST_SEPARATOR = ",";
|
|
30
|
+
export declare const ARCHIVED_STATUS = "archived";
|
|
31
|
+
export declare const UNSUBSCRIBE_URL_PATH = "unsubscribeUrl";
|
|
32
|
+
export declare const PREFERENCES_URL_PATH = "preferencesUrl";
|
|
24
33
|
export declare const SYSTEM_VARIABLE_PATHS: string[];
|
|
25
34
|
export declare const MAX_WINDOW_DAYS = 400;
|
package/dist/constants.js
CHANGED
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MAX_WINDOW_DAYS = exports.SYSTEM_VARIABLE_PATHS = exports.LOCALE_LIST_SEPARATOR = exports.HTTP_UNPROCESSABLE = exports.HTTP_CONFLICT = exports.HTTP_NOT_FOUND = exports.HTTP_FORBIDDEN = exports.HTTP_BAD_REQUEST = exports.SLUG_PATTERN = exports.MAX_NAME_LENGTH = exports.MAX_SLUG_LENGTH = exports.DEFAULT_LOG_RETENTION_DAYS = exports.DEFAULT_FALLBACK_LOCALE = exports.TEMPLATE_CATEGORY_TYPE_ID = exports.TEMPLATE_CATEGORIES_TYPE_ID = exports.GALLERY_DISPLAY_ID = exports.MAILING_SENDS_TOPIC = exports.SENDS_PERIOD_SCOPE = exports.OVERVIEW_PERIOD_SCOPE = exports.MAILING_SEND_PERMISSION = exports.EMAIL_TEMPLATE_NAME = exports.FRONTEND_MODULE_NAME = exports.TABLES_BASE_PATH = exports.API_BASE_PATH = exports.MODULE_ID = void 0;
|
|
3
|
+
exports.MAX_WINDOW_DAYS = exports.SYSTEM_VARIABLE_PATHS = exports.PREFERENCES_URL_PATH = exports.UNSUBSCRIBE_URL_PATH = exports.ARCHIVED_STATUS = exports.LOCALE_LIST_SEPARATOR = exports.HTTP_UNPROCESSABLE = exports.HTTP_CONFLICT = exports.HTTP_NOT_FOUND = exports.HTTP_FORBIDDEN = exports.HTTP_BAD_REQUEST = exports.SLUG_PATTERN = exports.MAX_NAME_LENGTH = exports.MAX_SLUG_LENGTH = exports.DEFAULT_LOG_RETENTION_DAYS = exports.DEFAULT_FALLBACK_LOCALE = exports.TEMPLATE_CATEGORY_TYPE_ID = exports.TEMPLATE_CATEGORIES_TYPE_ID = exports.GALLERY_DISPLAY_ID = exports.MAILING_SENDS_TOPIC = exports.SENDS_PERIOD_SCOPE = exports.OVERVIEW_PERIOD_SCOPE = exports.MAILING_SEND_PERMISSION = exports.EMAIL_TEMPLATE_NAME = exports.FRONTEND_MODULE_NAME = exports.NEW_TEMPLATE_ACTION_ID = exports.NEW_TEMPLATE_BUTTON_ID = exports.SETTINGS_PATH = exports.SENDS_PATH = exports.TEMPLATES_PATH = exports.MODULE_BASE_PATH = exports.TABLES_BASE_PATH = exports.API_BASE_PATH = exports.MODULE_ID = void 0;
|
|
4
4
|
exports.MODULE_ID = "mailing";
|
|
5
5
|
exports.API_BASE_PATH = "/api/mailing";
|
|
6
6
|
exports.TABLES_BASE_PATH = `${exports.API_BASE_PATH}/tables`;
|
|
7
|
+
exports.MODULE_BASE_PATH = `/modules/${exports.MODULE_ID}`;
|
|
8
|
+
exports.TEMPLATES_PATH = `${exports.MODULE_BASE_PATH}/templates`;
|
|
9
|
+
exports.SENDS_PATH = `${exports.MODULE_BASE_PATH}/sends`;
|
|
10
|
+
exports.SETTINGS_PATH = `${exports.MODULE_BASE_PATH}/settings`;
|
|
11
|
+
exports.NEW_TEMPLATE_BUTTON_ID = "create";
|
|
12
|
+
exports.NEW_TEMPLATE_ACTION_ID = "mailing.new-template";
|
|
7
13
|
exports.FRONTEND_MODULE_NAME = "@antelopejs/dms-mailing-frontend-vue";
|
|
8
14
|
exports.EMAIL_TEMPLATE_NAME = "EmailMailingTemplate";
|
|
9
15
|
exports.MAILING_SEND_PERMISSION = "mailing.send";
|
|
10
16
|
exports.OVERVIEW_PERIOD_SCOPE = "mailing-overview";
|
|
11
17
|
exports.SENDS_PERIOD_SCOPE = "mailing-sends";
|
|
12
18
|
exports.MAILING_SENDS_TOPIC = "mailing:sends";
|
|
13
|
-
exports.GALLERY_DISPLAY_ID =
|
|
19
|
+
exports.GALLERY_DISPLAY_ID = `${exports.MODULE_ID}:gallery`;
|
|
14
20
|
exports.TEMPLATE_CATEGORIES_TYPE_ID = "mailing_template_categories";
|
|
15
21
|
exports.TEMPLATE_CATEGORY_TYPE_ID = "mailing_template_category";
|
|
16
22
|
exports.DEFAULT_FALLBACK_LOCALE = "en";
|
|
@@ -24,6 +30,12 @@ exports.HTTP_NOT_FOUND = 404;
|
|
|
24
30
|
exports.HTTP_CONFLICT = 409;
|
|
25
31
|
exports.HTTP_UNPROCESSABLE = 422;
|
|
26
32
|
exports.LOCALE_LIST_SEPARATOR = ",";
|
|
27
|
-
exports.
|
|
33
|
+
exports.ARCHIVED_STATUS = "archived";
|
|
34
|
+
exports.UNSUBSCRIBE_URL_PATH = "unsubscribeUrl";
|
|
35
|
+
exports.PREFERENCES_URL_PATH = "preferencesUrl";
|
|
36
|
+
exports.SYSTEM_VARIABLE_PATHS = [
|
|
37
|
+
exports.UNSUBSCRIBE_URL_PATH,
|
|
38
|
+
exports.PREFERENCES_URL_PATH,
|
|
39
|
+
];
|
|
28
40
|
exports.MAX_WINDOW_DAYS = 400;
|
|
29
41
|
//# sourceMappingURL=constants.js.map
|
package/dist/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,SAAS,GAAG,SAAS,CAAC;AACtB,QAAA,aAAa,GAAG,cAAc,CAAC;AAC/B,QAAA,gBAAgB,GAAG,GAAG,qBAAa,SAAS,CAAC;AAC7C,QAAA,oBAAoB,GAAG,sCAAsC,CAAC;AAC9D,QAAA,mBAAmB,GAAG,sBAAsB,CAAC;AAE7C,QAAA,uBAAuB,GAAG,cAAc,CAAC;AAEzC,QAAA,qBAAqB,GAAG,kBAAkB,CAAC;AAC3C,QAAA,kBAAkB,GAAG,eAAe,CAAC;AAErC,QAAA,mBAAmB,GAAG,eAAe,CAAC;AAEtC,QAAA,kBAAkB,GAAG,
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,SAAS,GAAG,SAAS,CAAC;AACtB,QAAA,aAAa,GAAG,cAAc,CAAC;AAC/B,QAAA,gBAAgB,GAAG,GAAG,qBAAa,SAAS,CAAC;AAC7C,QAAA,gBAAgB,GAAG,YAAY,iBAAS,EAAE,CAAC;AAC3C,QAAA,cAAc,GAAG,GAAG,wBAAgB,YAAY,CAAC;AACjD,QAAA,UAAU,GAAG,GAAG,wBAAgB,QAAQ,CAAC;AACzC,QAAA,aAAa,GAAG,GAAG,wBAAgB,WAAW,CAAC;AAC/C,QAAA,sBAAsB,GAAG,QAAQ,CAAC;AAClC,QAAA,sBAAsB,GAAG,sBAAsB,CAAC;AAChD,QAAA,oBAAoB,GAAG,sCAAsC,CAAC;AAC9D,QAAA,mBAAmB,GAAG,sBAAsB,CAAC;AAE7C,QAAA,uBAAuB,GAAG,cAAc,CAAC;AAEzC,QAAA,qBAAqB,GAAG,kBAAkB,CAAC;AAC3C,QAAA,kBAAkB,GAAG,eAAe,CAAC;AAErC,QAAA,mBAAmB,GAAG,eAAe,CAAC;AAEtC,QAAA,kBAAkB,GAAG,GAAG,iBAAS,UAAU,CAAC;AAC5C,QAAA,2BAA2B,GAAG,6BAA6B,CAAC;AAC5D,QAAA,yBAAyB,GAAG,2BAA2B,CAAC;AAExD,QAAA,uBAAuB,GAAG,IAAI,CAAC;AAC/B,QAAA,0BAA0B,GAAG,EAAE,CAAC;AAChC,QAAA,eAAe,GAAG,EAAE,CAAC;AACrB,QAAA,eAAe,GAAG,GAAG,CAAC;AACtB,QAAA,YAAY,GAAG,sBAAsB,CAAC;AAEtC,QAAA,gBAAgB,GAAG,GAAG,CAAC;AACvB,QAAA,cAAc,GAAG,GAAG,CAAC;AACrB,QAAA,cAAc,GAAG,GAAG,CAAC;AACrB,QAAA,aAAa,GAAG,GAAG,CAAC;AACpB,QAAA,kBAAkB,GAAG,GAAG,CAAC;AAEzB,QAAA,qBAAqB,GAAG,GAAG,CAAC;AAG5B,QAAA,eAAe,GAAG,UAAU,CAAC;AAE7B,QAAA,oBAAoB,GAAG,gBAAgB,CAAC;AACxC,QAAA,oBAAoB,GAAG,gBAAgB,CAAC;AAGxC,QAAA,qBAAqB,GAAG;IACnC,4BAAoB;IACpB,4BAAoB;CACrB,CAAC;AAOW,QAAA,eAAe,GAAG,GAAG,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ATTENTION_JOB = void 0;
|
|
4
|
+
exports.runAttentionRefresh = runAttentionRefresh;
|
|
5
|
+
const interface_database_decorators_1 = require("@antelopejs/interface-database-decorators");
|
|
6
|
+
const db_1 = require("@antelopejs/interface-dms/db");
|
|
7
|
+
const template_attention_1 = require("../services/template-attention");
|
|
8
|
+
const ATTENTION_SCHEDULE = "5 * * * *";
|
|
9
|
+
async function runAttentionRefresh() {
|
|
10
|
+
const tenants = await (0, interface_database_decorators_1.GetModel)(db_1.TenantModel).getAll();
|
|
11
|
+
for (const tenant of tenants)
|
|
12
|
+
await (0, template_attention_1.refreshTemplateAttention)(tenant._id);
|
|
13
|
+
}
|
|
14
|
+
exports.ATTENTION_JOB = {
|
|
15
|
+
name: "mailing-attention",
|
|
16
|
+
schedule: ATTENTION_SCHEDULE,
|
|
17
|
+
run: runAttentionRefresh,
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=attention.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attention.js","sourceRoot":"","sources":["../../src/crons/attention.ts"],"names":[],"mappings":";;;AAWA,kDAGC;AAdD,6FAAqE;AACrE,qDAA2D;AAC3D,uEAA0E;AAO1E,MAAM,kBAAkB,GAAG,WAAW,CAAC;AAEhC,KAAK,UAAU,mBAAmB;IACvC,MAAM,OAAO,GAAG,MAAM,IAAA,wCAAQ,EAAC,gBAAW,CAAC,CAAC,MAAM,EAAE,CAAC;IACrD,KAAK,MAAM,MAAM,IAAI,OAAO;QAAE,MAAM,IAAA,6CAAwB,EAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAC3E,CAAC;AAEY,QAAA,aAAa,GAAY;IACpC,IAAI,EAAE,mBAAmB;IACzB,QAAQ,EAAE,kBAAkB;IAC5B,GAAG,EAAE,mBAAmB;CACzB,CAAC"}
|
package/dist/crons/index.d.ts
CHANGED
package/dist/crons/index.js
CHANGED
|
@@ -14,5 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./attention"), exports);
|
|
18
|
+
__exportStar(require("./jobs"), exports);
|
|
17
19
|
__exportStar(require("./retention"), exports);
|
|
18
20
|
//# sourceMappingURL=index.js.map
|
package/dist/crons/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/crons/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8CAA4B"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/crons/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8CAA4B;AAC5B,yCAAuB;AACvB,8CAA4B"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type ScheduledTask } from "node-cron";
|
|
2
|
+
export interface CronJob {
|
|
3
|
+
name: string;
|
|
4
|
+
schedule: string;
|
|
5
|
+
run: () => Promise<unknown>;
|
|
6
|
+
}
|
|
7
|
+
export interface ScheduledJob {
|
|
8
|
+
name: string;
|
|
9
|
+
task: ScheduledTask;
|
|
10
|
+
}
|
|
11
|
+
export declare function scheduleJob(job: CronJob): ScheduledJob;
|
|
12
|
+
export declare function stopJob(job: ScheduledJob): Promise<void>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.scheduleJob = scheduleJob;
|
|
7
|
+
exports.stopJob = stopJob;
|
|
8
|
+
const logging_1 = require("@antelopejs/interface-core/logging");
|
|
9
|
+
const node_cron_1 = __importDefault(require("node-cron"));
|
|
10
|
+
function scheduleJob(job) {
|
|
11
|
+
const task = node_cron_1.default.schedule(job.schedule, () => {
|
|
12
|
+
void job.run().catch((error) => {
|
|
13
|
+
logging_1.Logging.Error(`Cron '${job.name}' failed:`, error);
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
return { name: job.name, task };
|
|
17
|
+
}
|
|
18
|
+
async function stopJob(job) {
|
|
19
|
+
try {
|
|
20
|
+
await job.task.stop();
|
|
21
|
+
await job.task.destroy();
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
logging_1.Logging.Error(`Cron '${job.name}' failed to stop:`, error);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=jobs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jobs.js","sourceRoot":"","sources":["../../src/crons/jobs.ts"],"names":[],"mappings":";;;;;AAiBA,kCAOC;AAGD,0BAOC;AAlCD,gEAA6D;AAC7D,0DAAqD;AAgBrD,SAAgB,WAAW,CAAC,GAAY;IACtC,MAAM,IAAI,GAAG,mBAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,EAAE;QAC5C,KAAK,GAAG,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;YACtC,iBAAO,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,IAAI,WAAW,EAAE,KAAK,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;AAClC,CAAC;AAGM,KAAK,UAAU,OAAO,CAAC,GAAiB;IAC7C,IAAI,CAAC;QACH,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACtB,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,iBAAO,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,IAAI,mBAAmB,EAAE,KAAK,CAAC,CAAC;IAC7D,CAAC;AACH,CAAC"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare const RETENTION_CRON_NAME = "mailing-retention";
|
|
1
|
+
import type { CronJob } from "./jobs";
|
|
3
2
|
export interface RetentionLimits {
|
|
4
3
|
pageSize: number;
|
|
5
4
|
maxRows: number;
|
|
@@ -14,5 +13,4 @@ export declare function purgeInPages(pass: RetentionPass, limits?: RetentionLimi
|
|
|
14
13
|
export declare function purgeSend(tenantId: string, sendId: string, limit: Date): Promise<number>;
|
|
15
14
|
export declare function purgeOrphanEvents(tenantId: string, pageSize?: number): Promise<void>;
|
|
16
15
|
export declare function runRetention(now?: Date): Promise<number>;
|
|
17
|
-
export declare
|
|
18
|
-
export declare function scheduleRetention(): ScheduledTask;
|
|
16
|
+
export declare const RETENTION_JOB: CronJob;
|
package/dist/crons/retention.js
CHANGED
|
@@ -1,22 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
3
|
+
exports.RETENTION_JOB = exports.RETENTION_LIMITS = void 0;
|
|
7
4
|
exports.retentionLimit = retentionLimit;
|
|
8
5
|
exports.purgeInPages = purgeInPages;
|
|
9
6
|
exports.purgeSend = purgeSend;
|
|
10
7
|
exports.purgeOrphanEvents = purgeOrphanEvents;
|
|
11
8
|
exports.runRetention = runRetention;
|
|
12
|
-
exports.stopRetention = stopRetention;
|
|
13
|
-
exports.scheduleRetention = scheduleRetention;
|
|
14
9
|
const logging_1 = require("@antelopejs/interface-core/logging");
|
|
15
10
|
const interface_database_decorators_1 = require("@antelopejs/interface-database-decorators");
|
|
16
11
|
const db_1 = require("@antelopejs/interface-dms/db");
|
|
17
|
-
const node_cron_1 = __importDefault(require("node-cron"));
|
|
18
12
|
const db_2 = require("../db");
|
|
19
|
-
exports.RETENTION_CRON_NAME = "mailing-retention";
|
|
20
13
|
exports.RETENTION_LIMITS = {
|
|
21
14
|
pageSize: 500,
|
|
22
15
|
maxRows: 20_000,
|
|
@@ -75,7 +68,7 @@ async function purgeOrphanEvents(tenantId, pageSize = exports.RETENTION_LIMITS.p
|
|
|
75
68
|
}
|
|
76
69
|
}
|
|
77
70
|
async function purgeTenant(tenantId, now) {
|
|
78
|
-
const settings = await (0, interface_database_decorators_1.GetModel)(db_2.SettingsModel, tenantId).
|
|
71
|
+
const settings = await (0, interface_database_decorators_1.GetModel)(db_2.SettingsModel, tenantId).get(tenantId);
|
|
79
72
|
if (!settings || settings.logRetentionDays < MIN_RETENTION_DAYS)
|
|
80
73
|
return 0;
|
|
81
74
|
const limit = retentionLimit(settings.logRetentionDays, now);
|
|
@@ -91,17 +84,9 @@ async function runRetention(now = new Date()) {
|
|
|
91
84
|
logging_1.Logging.Info(`[dms-mailing] Retention purged ${purged} sends`);
|
|
92
85
|
return purged;
|
|
93
86
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
100
|
-
function scheduleRetention() {
|
|
101
|
-
return node_cron_1.default.schedule(RETENTION_SCHEDULE, () => {
|
|
102
|
-
void runRetention().catch((error) => {
|
|
103
|
-
logging_1.Logging.Error(`Cron '${exports.RETENTION_CRON_NAME}' failed:`, error);
|
|
104
|
-
});
|
|
105
|
-
});
|
|
106
|
-
}
|
|
87
|
+
exports.RETENTION_JOB = {
|
|
88
|
+
name: "mailing-retention",
|
|
89
|
+
schedule: RETENTION_SCHEDULE,
|
|
90
|
+
run: runRetention,
|
|
91
|
+
};
|
|
107
92
|
//# sourceMappingURL=retention.js.map
|