@hartl-services/medusa-base 0.4.0 → 1.1.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/.medusa/server/src/admin/index.js +1657 -111
- package/.medusa/server/src/admin/index.mjs +1647 -101
- package/.medusa/server/src/api/admin/email/messages/[id]/resends/route.js +24 -0
- package/.medusa/server/src/api/admin/email/messages/[id]/route.js +12 -0
- package/.medusa/server/src/api/admin/email/messages/route.js +12 -0
- package/.medusa/server/src/api/admin/email/terms-versions/[id]/download/route.js +16 -0
- package/.medusa/server/src/api/admin/email/terms-versions/route.js +47 -0
- package/.medusa/server/src/api/admin/orders/[id]/documents/[document_id]/download/route.js +21 -0
- package/.medusa/server/src/api/admin/orders/[id]/documents/[document_id]/regenerate/route.js +38 -0
- package/.medusa/server/src/api/admin/orders/[id]/documents/regenerate/route.js +32 -0
- package/.medusa/server/src/api/admin/orders/[id]/documents/route.js +36 -0
- package/.medusa/server/src/api/admin/orders/[id]/packing-lists/[fulfillment_id]/download/route.js +24 -0
- package/.medusa/server/src/api/admin/orders/[id]/packing-lists/[fulfillment_id]/retry/route.js +44 -0
- package/.medusa/server/src/api/admin/orders/[id]/packing-lists/route.js +82 -0
- package/.medusa/server/src/api/document-download-response.js +16 -0
- package/.medusa/server/src/api/document-response.js +23 -0
- package/.medusa/server/src/api/files/[asset]/route.js +24 -0
- package/.medusa/server/src/api/files/file-response.js +43 -0
- package/.medusa/server/src/api/files/gateway-options.js +31 -0
- package/.medusa/server/src/api/files/private/[token]/route.js +29 -0
- package/.medusa/server/src/api/files/upload/[token]/route.js +66 -0
- package/.medusa/server/src/api/middlewares.js +168 -1
- package/.medusa/server/src/api/packing-list-response.js +22 -0
- package/.medusa/server/src/api/route.js +27 -0
- package/.medusa/server/src/api/store/documents/[id]/download/route.js +21 -0
- package/.medusa/server/src/api/store/documents/[id]/route.js +15 -0
- package/.medusa/server/src/api/store/documents/route.js +11 -0
- package/.medusa/server/src/api/terms-download-response.js +12 -0
- package/.medusa/server/src/documents/config/index.js +18 -0
- package/.medusa/server/src/documents/paths/documents.js +6 -0
- package/.medusa/server/src/documents/paths/index.js +18 -0
- package/.medusa/server/src/documents/plugin-features.js +38 -0
- package/.medusa/server/src/documents/schemas/documents.js +18 -0
- package/.medusa/server/src/documents/schemas/index.js +18 -0
- package/.medusa/server/src/documents/scripts/verify-documents-file-storage.js +55 -0
- package/.medusa/server/src/documents/templates/financial-document.js +160 -0
- package/.medusa/server/src/documents/templates/format.js +73 -0
- package/.medusa/server/src/documents/templates/html-factory.js +42 -0
- package/.medusa/server/src/documents/templates/html-utils.js +23 -0
- package/.medusa/server/src/documents/templates/layout.js +142 -0
- package/.medusa/server/src/documents/templates/packing-list.js +52 -0
- package/.medusa/server/src/documents/types/admin-api.js +3 -0
- package/.medusa/server/src/documents/types/document-summary.js +3 -0
- package/.medusa/server/src/documents/types/documents.js +3 -0
- package/.medusa/server/src/documents/types/html-factory.js +6 -0
- package/.medusa/server/src/documents/types/index.js +22 -0
- package/.medusa/server/src/documents/types/store-api.js +3 -0
- package/.medusa/server/src/documents/utils/document-merchant.js +22 -0
- package/.medusa/server/src/documents/utils/document-render-settings.js +59 -0
- package/.medusa/server/src/documents/utils/html-to-pdf.js +61 -0
- package/.medusa/server/src/documents/utils/private-file-storage.js +64 -0
- package/.medusa/server/src/documents/utils/resolve-services.js +7 -0
- package/.medusa/server/src/email/application/handle-invite-event.js +318 -0
- package/.medusa/server/src/email/application/handle-password-reset-event.js +366 -0
- package/.medusa/server/src/email/config/index.js +84 -0
- package/.medusa/server/src/email/config/notification-module.js +20 -0
- package/.medusa/server/src/email/domain/business-keys.js +50 -0
- package/.medusa/server/src/email/domain/documents-fact-fingerprint.js +7 -0
- package/.medusa/server/src/email/domain/event-schemas.js +36 -0
- package/.medusa/server/src/email/domain/failure-classification.js +53 -0
- package/.medusa/server/src/email/domain/order-summary.js +103 -0
- package/.medusa/server/src/email/domain/refund-summary.js +43 -0
- package/.medusa/server/src/email/domain/return-summary.js +118 -0
- package/.medusa/server/src/email/domain/shipment-summary.js +74 -0
- package/.medusa/server/src/email/plugin-features.js +39 -0
- package/.medusa/server/src/email/rendering/default-templates.js +719 -0
- package/.medusa/server/src/email/rendering/load-email-shop-details.js +36 -0
- package/.medusa/server/src/email/rendering/render-email.js +50 -0
- package/.medusa/server/src/email/rendering/resolve-shop-configuration.js +67 -0
- package/.medusa/server/src/email/types/email-kinds.js +18 -0
- package/.medusa/server/src/email/types/index.js +21 -0
- package/.medusa/server/src/email/types/shop-configuration.js +3 -0
- package/.medusa/server/src/email/types/smtp-configuration.js +3 -0
- package/.medusa/server/src/email/types/template-data.js +232 -0
- package/.medusa/server/src/files/config/index.js +256 -0
- package/.medusa/server/src/files/gateway/index.js +115 -0
- package/.medusa/server/src/files/types/index.js +6 -0
- package/.medusa/server/src/files/types/public.js +6 -0
- package/.medusa/server/src/jobs/document-fact-publication-reconciliation.js +18 -0
- package/.medusa/server/src/jobs/document-resolution-reconciliation.js +20 -0
- package/.medusa/server/src/jobs/packing-list-reconciliation.js +49 -0
- package/.medusa/server/src/jobs/reconcile-email-attempts.js +63 -0
- package/.medusa/server/src/jobs/reconcile-pending-email-messages.js +41 -0
- package/.medusa/server/src/jobs/retry-email-messages.js +27 -0
- package/.medusa/server/src/migration-scripts/dismiss-orphaned-cart-promotion-links.js +26 -0
- package/.medusa/server/src/modules/documents/domain/cancellation-snapshot.js +97 -0
- package/.medusa/server/src/modules/documents/domain/document-number.js +36 -0
- package/.medusa/server/src/modules/documents/domain/document-resolution.js +24 -0
- package/.medusa/server/src/modules/documents/domain/issuance-rules.js +37 -0
- package/.medusa/server/src/modules/documents/domain/merchant.js +86 -0
- package/.medusa/server/src/modules/documents/domain/options.js +40 -0
- package/.medusa/server/src/modules/documents/domain/packing-list.js +90 -0
- package/.medusa/server/src/modules/documents/domain/snapshot-normalization.js +17 -0
- package/.medusa/server/src/modules/documents/domain/tax-breakdown.js +66 -0
- package/.medusa/server/src/modules/documents/index.js +15 -0
- package/.medusa/server/src/modules/documents/loaders/assert-private-file-storage.js +20 -0
- package/.medusa/server/src/modules/documents/migrations/Migration20260827061749.js +75 -0
- package/.medusa/server/src/modules/documents/migrations/Migration20260830111207.js +28 -0
- package/.medusa/server/src/modules/documents/models/document-artifact.js +25 -0
- package/.medusa/server/src/modules/documents/models/document-number-sequence.js +29 -0
- package/.medusa/server/src/modules/documents/models/document.js +82 -0
- package/.medusa/server/src/modules/documents/models/order-cancellation-resolution.js +51 -0
- package/.medusa/server/src/modules/documents/models/packing-list-revision.js +36 -0
- package/.medusa/server/src/modules/documents/models/packing-list.js +27 -0
- package/.medusa/server/src/modules/documents/models/refund-document-resolution.js +66 -0
- package/.medusa/server/src/modules/documents/models/shipment-invoice-assignment.js +51 -0
- package/.medusa/server/src/modules/documents/models/shipment-invoice-coordinator.js +44 -0
- package/.medusa/server/src/modules/documents/service.js +1701 -0
- package/.medusa/server/src/modules/email/domain/attachment.js +25 -0
- package/.medusa/server/src/modules/email/domain/message-state.js +69 -0
- package/.medusa/server/src/modules/email/index.js +13 -0
- package/.medusa/server/src/modules/email/migrations/Migration20260826173422.js +32 -0
- package/.medusa/server/src/modules/email/migrations/Migration20260827172945.js +16 -0
- package/.medusa/server/src/modules/email/migrations/Migration20260827194804.js +22 -0
- package/.medusa/server/src/modules/email/migrations/Migration20260906195205.js +16 -0
- package/.medusa/server/src/modules/email/models/email-attempt.js +56 -0
- package/.medusa/server/src/modules/email/models/email-message.js +71 -0
- package/.medusa/server/src/modules/email/models/email-terms-version.js +37 -0
- package/.medusa/server/src/modules/email/service.js +1285 -0
- package/.medusa/server/src/modules/plugin-features/domain/plugin-settings.js +4 -3
- package/.medusa/server/src/providers/s3-cache/cache/atomic-write.js +25 -0
- package/.medusa/server/src/providers/s3-cache/cache/cache-manager.js +115 -0
- package/.medusa/server/src/providers/s3-cache/cache/keyed-lock.js +28 -0
- package/.medusa/server/src/providers/s3-cache/index.js +8 -0
- package/.medusa/server/src/providers/s3-cache/object-key.js +53 -0
- package/.medusa/server/src/providers/s3-cache/s3-cache-file.js +229 -0
- package/.medusa/server/src/providers/s3-cache/s3-object-store.js +86 -0
- package/.medusa/server/src/providers/smtp/index.js +8 -0
- package/.medusa/server/src/providers/smtp/service.js +236 -0
- package/.medusa/server/src/providers/smtp/types.js +11 -0
- package/.medusa/server/src/public/config.js +186 -0
- package/.medusa/server/src/public/descriptor.js +3 -1
- package/.medusa/server/src/public/gateway.js +19 -0
- package/.medusa/server/src/public/instrumentation.js +56 -0
- package/.medusa/server/src/public/shop-config.js +12 -0
- package/.medusa/server/src/public/shop-master-data.js +2 -2
- package/.medusa/server/src/public/shop-types.js +24 -0
- package/.medusa/server/src/shop-config/build-food-shop-config.js +252 -0
- package/.medusa/server/src/shop-config/options.js +75 -0
- package/.medusa/server/src/subscribers/affiliate-consignment-reminder-due.js +26 -0
- package/.medusa/server/src/subscribers/documents-order-canceled.js +24 -0
- package/.medusa/server/src/subscribers/documents-order-cancellation-ready.js +26 -0
- package/.medusa/server/src/subscribers/documents-refund-ready.js +24 -0
- package/.medusa/server/src/subscribers/documents-shipment-created.js +36 -0
- package/.medusa/server/src/subscribers/documents-shipment-invoice-assignment-decided.js +26 -0
- package/.medusa/server/src/subscribers/email-order-canceled.js +28 -0
- package/.medusa/server/src/subscribers/email-shipment-created.js +32 -0
- package/.medusa/server/src/subscribers/order-placed.js +27 -0
- package/.medusa/server/src/subscribers/packing-list-allocation-revised.js +32 -0
- package/.medusa/server/src/subscribers/packing-list-fulfillment-canceled.js +54 -0
- package/.medusa/server/src/subscribers/packing-list-fulfillment-created.js +31 -0
- package/.medusa/server/src/subscribers/password-reset.js +23 -0
- package/.medusa/server/src/subscribers/payment-refunded.js +38 -0
- package/.medusa/server/src/subscribers/return-received.js +27 -0
- package/.medusa/server/src/subscribers/return-requested.js +27 -0
- package/.medusa/server/src/subscribers/user-invite.js +23 -0
- package/.medusa/server/src/utils/cart-promotion-links.js +101 -0
- package/.medusa/server/src/workflows/documents/issue-cancellation-after-refund.js +246 -0
- package/.medusa/server/src/workflows/documents/issue-document.js +165 -0
- package/.medusa/server/src/workflows/documents/issue-invoice-after-shipment.js +521 -0
- package/.medusa/server/src/workflows/documents/issue-packing-list.js +390 -0
- package/.medusa/server/src/workflows/documents/publish-document-facts.js +53 -0
- package/.medusa/server/src/workflows/documents/reconcile-document-resolutions.js +48 -0
- package/.medusa/server/src/workflows/documents/reconcile-order-cancellation.js +92 -0
- package/.medusa/server/src/workflows/documents/regenerate-issued-document.js +61 -0
- package/.medusa/server/src/workflows/email/dispatch-email-message.js +301 -0
- package/.medusa/server/src/workflows/email/documents-required-facts.js +30 -0
- package/.medusa/server/src/workflows/email/prepare-affiliate-reminder-email.js +58 -0
- package/.medusa/server/src/workflows/email/prepare-order-canceled-email.js +102 -0
- package/.medusa/server/src/workflows/email/prepare-order-received-email.js +82 -0
- package/.medusa/server/src/workflows/email/prepare-refund-email.js +71 -0
- package/.medusa/server/src/workflows/email/prepare-return-email.js +136 -0
- package/.medusa/server/src/workflows/email/prepare-shipment-email.js +115 -0
- package/.medusa/server/src/workflows/email/retry-email-messages.js +31 -0
- package/.medusa/server/src/workflows/hooks/dismiss-deleted-promotion-cart-links.js +23 -0
- package/README.md +1777 -8
- package/dist/admin-components/features/plugin-features/components/ImageSettingInput.d.ts +15 -0
- package/dist/admin-components/features/plugin-features/components/ImageSettingInput.js +42 -0
- package/dist/admin-components/features/plugin-features/components/PluginSettingsForm.js +4 -2
- package/dist/admin-components/features/plugin-features/hooks/usePluginFeatureEnabled.d.ts +1 -1
- package/dist/admin-components/features/plugin-features/hooks/usePluginFeatures.d.ts +4 -4
- package/dist/admin-components/features/plugin-features/hooks/usePluginSettingsForm.d.ts +1 -1
- package/dist/admin-components/features/plugin-features/lib/image-upload.d.ts +6 -0
- package/dist/admin-components/features/plugin-features/lib/image-upload.js +17 -0
- package/dist/admin-components/features/plugin-features/lib/plugin-features-admin-client.d.ts +4 -4
- package/dist/admin-components/i18n/texts.d.ts +6 -0
- package/dist/admin-components/i18n/texts.js +6 -0
- package/dist/documents/config/index.d.ts +11 -0
- package/dist/documents/config/index.js +17 -0
- package/dist/documents/templates/financial-document.d.ts +3 -0
- package/dist/documents/templates/financial-document.js +159 -0
- package/dist/documents/templates/format.d.ts +30 -0
- package/dist/documents/templates/format.js +72 -0
- package/dist/documents/templates/html-factory.d.ts +15 -0
- package/dist/documents/templates/html-factory.js +41 -0
- package/dist/documents/templates/html-utils.d.ts +8 -0
- package/dist/documents/templates/html-utils.js +22 -0
- package/dist/documents/templates/layout.d.ts +35 -0
- package/dist/documents/templates/layout.js +141 -0
- package/dist/documents/templates/packing-list.d.ts +3 -0
- package/dist/documents/templates/packing-list.js +51 -0
- package/dist/documents/types/admin-api.d.ts +1 -0
- package/dist/documents/types/admin-api.js +2 -0
- package/dist/documents/types/document-summary.d.ts +1 -0
- package/dist/documents/types/document-summary.js +2 -0
- package/dist/documents/types/documents.d.ts +191 -0
- package/dist/documents/types/documents.js +2 -0
- package/dist/documents/types/html-factory.d.ts +8 -0
- package/dist/documents/types/html-factory.js +5 -0
- package/dist/documents/types/index.d.ts +5 -0
- package/dist/documents/types/index.js +21 -0
- package/dist/documents/types/store-api.d.ts +1 -0
- package/dist/documents/types/store-api.js +2 -0
- package/dist/email/config/index.d.ts +17 -0
- package/dist/email/config/index.js +83 -0
- package/dist/email/config/notification-module.d.ts +22 -0
- package/dist/email/config/notification-module.js +19 -0
- package/dist/email/types/email-kinds.d.ts +15 -0
- package/dist/email/types/email-kinds.js +17 -0
- package/dist/email/types/index.d.ts +4 -0
- package/dist/email/types/index.js +20 -0
- package/dist/email/types/shop-configuration.d.ts +68 -0
- package/dist/email/types/shop-configuration.js +2 -0
- package/dist/email/types/smtp-configuration.d.ts +9 -0
- package/dist/email/types/smtp-configuration.js +2 -0
- package/dist/email/types/template-data.d.ts +609 -0
- package/dist/email/types/template-data.js +231 -0
- package/dist/files/config/index.d.ts +32 -0
- package/dist/files/config/index.js +255 -0
- package/dist/files/gateway/index.d.ts +30 -0
- package/dist/files/gateway/index.js +114 -0
- package/dist/files/types/index.d.ts +2 -0
- package/dist/files/types/index.js +5 -0
- package/dist/files/types/public.d.ts +90 -0
- package/dist/files/types/public.js +5 -0
- package/dist/modules/documents/domain/merchant.d.ts +22 -0
- package/dist/modules/documents/domain/merchant.js +85 -0
- package/dist/modules/documents/domain/options.d.ts +34 -0
- package/dist/modules/documents/domain/options.js +39 -0
- package/dist/public/config.d.ts +59 -0
- package/dist/public/config.js +185 -0
- package/dist/public/descriptor.js +2 -0
- package/dist/public/gateway.d.ts +2 -0
- package/dist/public/gateway.js +18 -0
- package/dist/public/instrumentation.d.ts +12 -0
- package/dist/public/instrumentation.js +55 -0
- package/dist/public/shop-config.d.ts +8 -0
- package/dist/public/shop-config.js +11 -0
- package/dist/public/shop-master-data.d.ts +1 -1
- package/dist/public/shop-master-data.js +1 -1
- package/dist/public/shop-types.d.ts +7 -0
- package/dist/public/shop-types.js +23 -0
- package/dist/public/types.d.ts +19 -2
- package/dist/shop-config/build-food-shop-config.d.ts +44 -0
- package/dist/shop-config/build-food-shop-config.js +251 -0
- package/dist/shop-config/options.d.ts +48 -0
- package/dist/shop-config/options.js +74 -0
- package/package.json +48 -5
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { DocumentRenderSettings, DocumentMerchant } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Shop-specific look on top of the default markup. A project passes it to
|
|
4
|
+
* `createDefaultDocumentHtmlFactory` from its own `htmlFactory`, so it keeps
|
|
5
|
+
* the plugin's content and changes only the appearance.
|
|
6
|
+
*/
|
|
7
|
+
export type DocumentTheme = {
|
|
8
|
+
/**
|
|
9
|
+
* CSS appended after the default stylesheet; later rules win. A
|
|
10
|
+
* full-page image such as a watermark belongs in `@page { background }`:
|
|
11
|
+
* it covers the whole sheet on every page, while Chromium clips fixed
|
|
12
|
+
* elements at the page margin and sizes an inline `<svg>` in them wrongly
|
|
13
|
+
* from the second page on.
|
|
14
|
+
*/
|
|
15
|
+
readonly stylesheet?: string;
|
|
16
|
+
};
|
|
17
|
+
export type DocumentLayoutInput = {
|
|
18
|
+
readonly body: string;
|
|
19
|
+
readonly documentTitle: string;
|
|
20
|
+
readonly metadata: readonly {
|
|
21
|
+
readonly label: string;
|
|
22
|
+
readonly value: string;
|
|
23
|
+
}[];
|
|
24
|
+
readonly number: string;
|
|
25
|
+
readonly pageTitle: string;
|
|
26
|
+
/** Escaped recipient address markup; `null` leaves the block empty. */
|
|
27
|
+
readonly recipient: string | null;
|
|
28
|
+
};
|
|
29
|
+
export type DocumentLayout = (input: DocumentLayoutInput) => string;
|
|
30
|
+
export declare const formatCountryName: (countryCode: string) => string;
|
|
31
|
+
/**
|
|
32
|
+
* `includeLegalDetails` adds UID, company register, contact and bank details
|
|
33
|
+
* to the footer (financial documents); packing lists show only the sender.
|
|
34
|
+
*/
|
|
35
|
+
export declare const createDocumentLayout: (merchant: DocumentMerchant, settings: DocumentRenderSettings, includeLegalDetails: boolean, theme?: DocumentTheme) => DocumentLayout;
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createDocumentLayout = exports.formatCountryName = void 0;
|
|
4
|
+
const html_utils_1 = require("./html-utils");
|
|
5
|
+
const formatCountryName = (countryCode) => new Intl.DisplayNames("de", { type: "region" }).of(countryCode.toUpperCase()) ?? countryCode.toUpperCase();
|
|
6
|
+
exports.formatCountryName = formatCountryName;
|
|
7
|
+
const joinLines = (lines) => lines
|
|
8
|
+
.filter((line) => Boolean(line))
|
|
9
|
+
.map(html_utils_1.escapeHtml)
|
|
10
|
+
.join("<br />");
|
|
11
|
+
const renderFooterColumn = (heading, lines) => {
|
|
12
|
+
const content = joinLines(lines);
|
|
13
|
+
if (!content) {
|
|
14
|
+
return "";
|
|
15
|
+
}
|
|
16
|
+
const title = heading
|
|
17
|
+
? `<div class="footer-heading">${(0, html_utils_1.escapeHtml)(heading)}</div>`
|
|
18
|
+
: "";
|
|
19
|
+
return `<div class="footer-column">${title}${content}</div>`;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Legal footer in three columns: sender with UID and company register,
|
|
23
|
+
* contact, bank. Packing lists (`includeLegalDetails: false`) show only the
|
|
24
|
+
* sender's name and address.
|
|
25
|
+
*/
|
|
26
|
+
const renderMerchantFooter = (merchant, includeLegalDetails) => {
|
|
27
|
+
const sender = `<div class="footer-column"><strong>${(0, html_utils_1.escapeHtml)(merchant.legal_name)}</strong><br />${joinLines([
|
|
28
|
+
merchant.address_line1,
|
|
29
|
+
merchant.address_line2,
|
|
30
|
+
`${merchant.postal_code} ${merchant.city}`,
|
|
31
|
+
(0, exports.formatCountryName)(merchant.country_code),
|
|
32
|
+
...(includeLegalDetails
|
|
33
|
+
? [
|
|
34
|
+
merchant.vat_number ? `UID: ${merchant.vat_number}` : null,
|
|
35
|
+
merchant.company_register_number
|
|
36
|
+
? `Firmenbuchnummer: ${merchant.company_register_number}`
|
|
37
|
+
: null,
|
|
38
|
+
merchant.company_register_court
|
|
39
|
+
? `Firmenbuchgericht: ${merchant.company_register_court}`
|
|
40
|
+
: null,
|
|
41
|
+
]
|
|
42
|
+
: []),
|
|
43
|
+
])}</div>`;
|
|
44
|
+
if (!includeLegalDetails) {
|
|
45
|
+
return sender;
|
|
46
|
+
}
|
|
47
|
+
return [
|
|
48
|
+
sender,
|
|
49
|
+
renderFooterColumn("Kontakt", [
|
|
50
|
+
merchant.phone,
|
|
51
|
+
merchant.email,
|
|
52
|
+
merchant.website,
|
|
53
|
+
]),
|
|
54
|
+
// The heading names the IBAN; only the BIC keeps its label.
|
|
55
|
+
renderFooterColumn("Bankverbindung", [
|
|
56
|
+
merchant.iban,
|
|
57
|
+
merchant.bic ? `BIC: ${merchant.bic}` : null,
|
|
58
|
+
]),
|
|
59
|
+
].join("");
|
|
60
|
+
};
|
|
61
|
+
const renderLetterhead = (merchant, settings) => settings.logo_src
|
|
62
|
+
? `<img class="logo" src="${(0, html_utils_1.escapeHtml)(settings.logo_src)}" alt="${(0, html_utils_1.escapeHtml)(merchant.legal_name)}" />`
|
|
63
|
+
: `<div class="logo-text">${(0, html_utils_1.escapeHtml)(merchant.legal_name)}</div>`;
|
|
64
|
+
const renderMetadata = (metadata) => metadata
|
|
65
|
+
.map(({ label, value }) => `<tr><th scope="row">${(0, html_utils_1.escapeHtml)(label)}</th><td>${(0, html_utils_1.escapeHtml)(value)}</td></tr>`)
|
|
66
|
+
.join("");
|
|
67
|
+
/**
|
|
68
|
+
* A4 with only a bottom page margin, which holds the page number
|
|
69
|
+
* (`@bottom-right`; `counter(pages)` works only in page margin boxes). `.page`
|
|
70
|
+
* carries the other margins and repeats them on every printed page
|
|
71
|
+
* (`box-decoration-break: clone`); the fixed footer is positioned in the page
|
|
72
|
+
* area, `--footer-height` reserves its space at the bottom of each page.
|
|
73
|
+
*/
|
|
74
|
+
const DEFAULT_STYLESHEET = `
|
|
75
|
+
@page { size: A4; margin: 0 0 8mm 0; @bottom-right { color: #6b7280; content: "Seite " counter(page) " von " counter(pages); font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 7.5pt; padding-right: 20mm; vertical-align: top; } }
|
|
76
|
+
:root { --accent: #111827; --text: #1f2937; --muted: #6b7280; --line: #d1d5db; --table-head: #f3f4f6; --page-x: 20mm; --page-top: 18mm; --footer-height: 30mm; }
|
|
77
|
+
* { box-sizing: border-box; }
|
|
78
|
+
html, body { margin: 0; padding: 0; }
|
|
79
|
+
body { color: var(--text); font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 10pt; line-height: 1.4; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
|
|
80
|
+
.page { -webkit-box-decoration-break: clone; box-decoration-break: clone; padding: var(--page-top) var(--page-x) calc(var(--footer-height) + 8mm); }
|
|
81
|
+
.letterhead { margin-bottom: 14mm; min-height: 16mm; }
|
|
82
|
+
.logo { display: block; height: 22mm; max-width: 90mm; object-fit: contain; object-position: left center; width: auto; }
|
|
83
|
+
.logo-text { color: var(--accent); font-size: 20pt; font-weight: 700; letter-spacing: 0.02em; }
|
|
84
|
+
.document-head { break-inside: avoid; display: flex; gap: 12mm; justify-content: space-between; margin-bottom: 14mm; page-break-inside: avoid; }
|
|
85
|
+
.recipient { flex: 1 1 0; font-style: normal; padding-top: 9mm; }
|
|
86
|
+
.document-info { flex: 0 0 78mm; }
|
|
87
|
+
h1 { color: var(--accent); font-size: 16pt; font-weight: 400; letter-spacing: 0.08em; margin: 0 0 3mm; text-transform: uppercase; }
|
|
88
|
+
h2 { break-after: avoid; font-size: 10pt; margin: 8mm 0 2mm; page-break-after: avoid; }
|
|
89
|
+
.document-metadata { border-collapse: collapse; width: 100%; }
|
|
90
|
+
.document-metadata th, .document-metadata td { border: 0; font-weight: 400; padding: 0; text-align: left; vertical-align: top; }
|
|
91
|
+
.document-metadata td { text-align: right; }
|
|
92
|
+
.muted, .sku, .batch { color: var(--muted); }
|
|
93
|
+
.batch, .packing-batch { font-size: 8pt; margin-top: 1mm; }
|
|
94
|
+
.packing-batch { display: flex; gap: 12px; justify-content: space-between; }
|
|
95
|
+
table { border-collapse: collapse; page-break-inside: auto; width: 100%; }
|
|
96
|
+
thead { display: table-header-group; }
|
|
97
|
+
tfoot { display: table-footer-group; }
|
|
98
|
+
tbody { page-break-inside: auto; }
|
|
99
|
+
tr { break-inside: avoid; page-break-inside: avoid; }
|
|
100
|
+
.items th { background: var(--table-head); font-weight: 700; text-align: left; }
|
|
101
|
+
.items th.number { text-align: right; }
|
|
102
|
+
.items th, .items td { padding: 2.5mm 2mm; vertical-align: top; }
|
|
103
|
+
.items tbody.lines td { border-bottom: 1px solid var(--line); }
|
|
104
|
+
.number { text-align: right; white-space: nowrap; }
|
|
105
|
+
.money { white-space: nowrap; }
|
|
106
|
+
.items tbody.totals td { padding-bottom: 1.5mm; padding-top: 1.5mm; }
|
|
107
|
+
.items tbody.totals tr:first-child td { padding-top: 3mm; }
|
|
108
|
+
.items tbody.totals tr.grand-total td.label, .items tbody.totals tr.grand-total td.number { border-bottom: 1px solid var(--line); border-top: 1px solid var(--line); font-weight: 700; padding-bottom: 2mm; padding-top: 2mm; }
|
|
109
|
+
.payment-terms { margin-top: 10mm; white-space: pre-line; }
|
|
110
|
+
.recipient, .tax-compliance, .payment-terms, .items tbody.totals { break-inside: avoid; page-break-inside: avoid; }
|
|
111
|
+
.page-footer { align-items: flex-start; bottom: 4mm; color: var(--text); display: flex; font-size: 8pt; gap: 8mm; left: var(--page-x); line-height: 1.35; position: fixed; right: var(--page-x); }
|
|
112
|
+
.footer-column { flex: 1 1 0; }
|
|
113
|
+
.footer-heading { color: var(--muted); }
|
|
114
|
+
`;
|
|
115
|
+
/**
|
|
116
|
+
* `includeLegalDetails` adds UID, company register, contact and bank details
|
|
117
|
+
* to the footer (financial documents); packing lists show only the sender.
|
|
118
|
+
*/
|
|
119
|
+
const createDocumentLayout = (merchant, settings, includeLegalDetails, theme = {}) => ({ body, documentTitle, metadata, number, pageTitle, recipient }) => `<!doctype html>
|
|
120
|
+
<html lang="de">
|
|
121
|
+
<head>
|
|
122
|
+
<meta charset="utf-8" />
|
|
123
|
+
<title>${(0, html_utils_1.escapeHtml)(pageTitle)} ${(0, html_utils_1.escapeHtml)(number)}</title>
|
|
124
|
+
<style>${DEFAULT_STYLESHEET}${theme.stylesheet ?? ""}</style>
|
|
125
|
+
</head>
|
|
126
|
+
<body>
|
|
127
|
+
<footer class="page-footer">${renderMerchantFooter(merchant, includeLegalDetails)}</footer>
|
|
128
|
+
<main class="page">
|
|
129
|
+
<header class="letterhead">${renderLetterhead(merchant, settings)}</header>
|
|
130
|
+
<section class="document-head">
|
|
131
|
+
<address class="recipient">${recipient ?? ""}</address>
|
|
132
|
+
<div class="document-info">
|
|
133
|
+
<h1>${(0, html_utils_1.escapeHtml)(documentTitle)}</h1>
|
|
134
|
+
<table class="document-metadata"><tbody>${renderMetadata(metadata)}</tbody></table>
|
|
135
|
+
</div>
|
|
136
|
+
</section>
|
|
137
|
+
${body}
|
|
138
|
+
</main>
|
|
139
|
+
</body>
|
|
140
|
+
</html>`;
|
|
141
|
+
exports.createDocumentLayout = createDocumentLayout;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.renderPackingList = void 0;
|
|
4
|
+
const format_1 = require("./format");
|
|
5
|
+
const html_utils_1 = require("./html-utils");
|
|
6
|
+
const renderBatchAllocations = (line, timeZone) => {
|
|
7
|
+
if (line.batch_allocations.length === 0) {
|
|
8
|
+
return '<span class="muted">-</span>';
|
|
9
|
+
}
|
|
10
|
+
return line.batch_allocations
|
|
11
|
+
.map((allocation) => `<div class="packing-batch">
|
|
12
|
+
<strong>${(0, html_utils_1.escapeHtml)(allocation.lot_number)}</strong>
|
|
13
|
+
<span>MHD: ${(0, html_utils_1.escapeHtml)((0, format_1.formatDocumentDate)(allocation.expiry_date, timeZone))}</span>
|
|
14
|
+
<span>Menge: ${(0, html_utils_1.escapeHtml)(allocation.quantity)}</span>
|
|
15
|
+
</div>`)
|
|
16
|
+
.join("");
|
|
17
|
+
};
|
|
18
|
+
const renderLines = (input, timeZone) => input.lines
|
|
19
|
+
.map((line) => `<tr>
|
|
20
|
+
<td class="item">
|
|
21
|
+
<div class="item-title">${(0, html_utils_1.escapeHtml)(line.title)}</div>
|
|
22
|
+
${line.sku ? `<div class="sku">SKU: ${(0, html_utils_1.escapeHtml)(line.sku)}</div>` : ""}
|
|
23
|
+
</td>
|
|
24
|
+
<td>${renderBatchAllocations(line, timeZone)}</td>
|
|
25
|
+
<td class="number">${(0, html_utils_1.escapeHtml)(line.quantity)}</td>
|
|
26
|
+
</tr>`)
|
|
27
|
+
.join("");
|
|
28
|
+
const renderPackingList = (input, layout, timeZone) => layout({
|
|
29
|
+
body: `<table class="items packing-items">
|
|
30
|
+
<thead><tr><th class="item">Bezeichnung</th><th>Charge</th><th class="number">Benötigte Menge</th></tr></thead>
|
|
31
|
+
<tbody class="lines">${renderLines(input, timeZone)}</tbody>
|
|
32
|
+
</table>`,
|
|
33
|
+
documentTitle: "Packliste",
|
|
34
|
+
metadata: [
|
|
35
|
+
{ label: "Packlistennummer", value: input.document.number },
|
|
36
|
+
{
|
|
37
|
+
label: "Bestellung",
|
|
38
|
+
value: (0, html_utils_1.formatOrderReference)(input.order.display_id),
|
|
39
|
+
},
|
|
40
|
+
{ label: "Fulfillment", value: input.fulfillment.id },
|
|
41
|
+
{
|
|
42
|
+
label: "Erstellungsdatum",
|
|
43
|
+
value: (0, format_1.formatDocumentDate)(input.document.generated_at, timeZone),
|
|
44
|
+
},
|
|
45
|
+
{ label: "Lagerplatz", value: input.fulfillment.location_name },
|
|
46
|
+
],
|
|
47
|
+
number: input.document.number,
|
|
48
|
+
pageTitle: "Packliste",
|
|
49
|
+
recipient: null,
|
|
50
|
+
});
|
|
51
|
+
exports.renderPackingList = renderPackingList;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type * from "@hartl-services/medusa-food-supplements-contracts/types/documents-admin";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { StoreDocument as DocumentSummary } from "@hartl-services/medusa-food-supplements-contracts/types/documents-store";
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
export type DocumentKind = "invoice" | "cancellation" | "credit_note";
|
|
2
|
+
export type DocumentStatus = "processing" | "issued" | "failed";
|
|
3
|
+
export type ShipmentInvoiceDecision = "pending" | "carrier" | "non_carrier";
|
|
4
|
+
export type RefundResolutionState = "pending_source" | "processing" | "ready" | "not_applicable" | "failed";
|
|
5
|
+
export type RefundCommunicationOwner = "standalone" | "cancellation";
|
|
6
|
+
export type OrderCancellationResolutionState = "pending" | "processing" | "ready" | "failed";
|
|
7
|
+
export type DocumentMoney = {
|
|
8
|
+
amount: string;
|
|
9
|
+
currency_code: string;
|
|
10
|
+
};
|
|
11
|
+
export type DocumentAddress = {
|
|
12
|
+
first_name: string | null;
|
|
13
|
+
last_name: string | null;
|
|
14
|
+
company: string | null;
|
|
15
|
+
address_1: string | null;
|
|
16
|
+
address_2: string | null;
|
|
17
|
+
postal_code: string | null;
|
|
18
|
+
city: string | null;
|
|
19
|
+
country_code: string | null;
|
|
20
|
+
};
|
|
21
|
+
export type DocumentBatchAllocationDTO = {
|
|
22
|
+
batch_id: string;
|
|
23
|
+
lot_number: string;
|
|
24
|
+
expiry_date: string;
|
|
25
|
+
quantity: number;
|
|
26
|
+
};
|
|
27
|
+
export type DocumentTaxComplianceDTO = {
|
|
28
|
+
customer_company_name: string;
|
|
29
|
+
customer_vat_number: string;
|
|
30
|
+
exemption_wording: "steuerfreie_innergemeinschaftliche_lieferung";
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Tax amount of one configured tax rate (name and percentage as calculated on
|
|
34
|
+
* the order's tax lines). Amounts are rounded to the currency's minor unit and
|
|
35
|
+
* sum up exactly to the rounded document tax total.
|
|
36
|
+
*/
|
|
37
|
+
export type DocumentTaxBreakdownEntry = {
|
|
38
|
+
name: string;
|
|
39
|
+
code: string | null;
|
|
40
|
+
rate: number;
|
|
41
|
+
tax_total: DocumentMoney;
|
|
42
|
+
};
|
|
43
|
+
export type DocumentTemplateLine = {
|
|
44
|
+
id: string;
|
|
45
|
+
title: string;
|
|
46
|
+
sku: string | null;
|
|
47
|
+
quantity: number;
|
|
48
|
+
unit_price: DocumentMoney;
|
|
49
|
+
subtotal: DocumentMoney;
|
|
50
|
+
tax_total: DocumentMoney;
|
|
51
|
+
total: DocumentMoney;
|
|
52
|
+
batch_allocations: DocumentBatchAllocationDTO[];
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Stable input contract for the project-owned HTML factory. It is a value
|
|
56
|
+
* snapshot, never a live Medusa order model, so rendering stays isolated from
|
|
57
|
+
* Medusa internals and the Storefront can import the types safely.
|
|
58
|
+
*/
|
|
59
|
+
export type DocumentTemplateInput = {
|
|
60
|
+
document: {
|
|
61
|
+
id: string;
|
|
62
|
+
kind: DocumentKind;
|
|
63
|
+
number: string;
|
|
64
|
+
issued_at: string;
|
|
65
|
+
source_document_number: string | null;
|
|
66
|
+
};
|
|
67
|
+
order: {
|
|
68
|
+
id: string;
|
|
69
|
+
display_id: number | null;
|
|
70
|
+
email: string;
|
|
71
|
+
currency_code: string;
|
|
72
|
+
billing_address: DocumentAddress | null;
|
|
73
|
+
tax_compliance: DocumentTaxComplianceDTO | null;
|
|
74
|
+
};
|
|
75
|
+
lines: DocumentTemplateLine[];
|
|
76
|
+
totals: {
|
|
77
|
+
subtotal: DocumentMoney;
|
|
78
|
+
tax_total: DocumentMoney;
|
|
79
|
+
/** Empty for documents without tax lines and for legacy snapshots. */
|
|
80
|
+
tax_breakdown: DocumentTaxBreakdownEntry[];
|
|
81
|
+
shipping_total: DocumentMoney;
|
|
82
|
+
discount_total: DocumentMoney;
|
|
83
|
+
total: DocumentMoney;
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
export type DocumentSnapshot = DocumentTemplateInput;
|
|
87
|
+
export type PackingListLifecycleStatus = "active" | "canceled";
|
|
88
|
+
export type PackingListGenerationStatus = "processing" | "ready" | "failed";
|
|
89
|
+
export type PackingListBatchAllocation = {
|
|
90
|
+
batch_id: string;
|
|
91
|
+
lot_number: string;
|
|
92
|
+
expiry_date: string;
|
|
93
|
+
quantity: number;
|
|
94
|
+
};
|
|
95
|
+
export type PackingListTemplateLine = {
|
|
96
|
+
line_item_id: string;
|
|
97
|
+
inventory_item_id: string | null;
|
|
98
|
+
title: string;
|
|
99
|
+
sku: string | null;
|
|
100
|
+
quantity: number;
|
|
101
|
+
batch_allocations: PackingListBatchAllocation[];
|
|
102
|
+
};
|
|
103
|
+
export type PackingListTemplateInput = {
|
|
104
|
+
document: {
|
|
105
|
+
kind: "packing_list";
|
|
106
|
+
id: string;
|
|
107
|
+
number: string;
|
|
108
|
+
source_revision: number;
|
|
109
|
+
generated_at: string;
|
|
110
|
+
};
|
|
111
|
+
order: {
|
|
112
|
+
id: string;
|
|
113
|
+
display_id: number | null;
|
|
114
|
+
};
|
|
115
|
+
fulfillment: {
|
|
116
|
+
id: string;
|
|
117
|
+
created_at: string;
|
|
118
|
+
location_id: string;
|
|
119
|
+
location_name: string;
|
|
120
|
+
};
|
|
121
|
+
lines: PackingListTemplateLine[];
|
|
122
|
+
};
|
|
123
|
+
export type PackingListSnapshot = PackingListTemplateInput;
|
|
124
|
+
/**
|
|
125
|
+
* The shop's legal sender facts, read from the base plugin's shop master
|
|
126
|
+
* data ("Shop-Stammdaten") when a document is rendered. Not part of the
|
|
127
|
+
* stored snapshot. Optional fields are `null` when not set; the development
|
|
128
|
+
* UID placeholder `ATU00000000` arrives as `vat_number: null`.
|
|
129
|
+
*/
|
|
130
|
+
export type DocumentMerchant = {
|
|
131
|
+
legal_name: string;
|
|
132
|
+
address_line1: string;
|
|
133
|
+
address_line2: string | null;
|
|
134
|
+
postal_code: string;
|
|
135
|
+
city: string;
|
|
136
|
+
/** Lower-case ISO 3166-1 alpha-2 code. */
|
|
137
|
+
country_code: string;
|
|
138
|
+
vat_number: string | null;
|
|
139
|
+
email: string | null;
|
|
140
|
+
phone: string | null;
|
|
141
|
+
website: string | null;
|
|
142
|
+
iban: string | null;
|
|
143
|
+
bic: string | null;
|
|
144
|
+
company_register_number: string | null;
|
|
145
|
+
company_register_court: string | null;
|
|
146
|
+
};
|
|
147
|
+
/**
|
|
148
|
+
* Optional `merchant` plugin option: used per field only where the shop
|
|
149
|
+
* master data in the base plugin has no value (same shape as the demo shop's
|
|
150
|
+
* `merchant` constant in medusa-config).
|
|
151
|
+
*/
|
|
152
|
+
export type DocumentMerchantOption = {
|
|
153
|
+
countryCode: string;
|
|
154
|
+
legalName: string;
|
|
155
|
+
registeredAddress: {
|
|
156
|
+
address1: string;
|
|
157
|
+
address2?: string;
|
|
158
|
+
city: string;
|
|
159
|
+
countryCode: string;
|
|
160
|
+
postalCode: string;
|
|
161
|
+
};
|
|
162
|
+
vatNumber?: string;
|
|
163
|
+
};
|
|
164
|
+
/**
|
|
165
|
+
* The Documents settings (Admin -> "Hartl Services Plugins" -> Dokumente) a
|
|
166
|
+
* render needs, read when a document is rendered. Not part of the stored
|
|
167
|
+
* snapshot: a regenerated document shows the current values.
|
|
168
|
+
*/
|
|
169
|
+
export type DocumentRenderSettings = {
|
|
170
|
+
/**
|
|
171
|
+
* The uploaded logo as a `data:` URL, ready for `<img src>`; `null` when no
|
|
172
|
+
* logo is set or it could not be loaded (the document then shows the
|
|
173
|
+
* merchant's legal name instead).
|
|
174
|
+
*/
|
|
175
|
+
logo_src: string | null;
|
|
176
|
+
/** Payment terms printed below the totals of an invoice; `null` = none. */
|
|
177
|
+
payment_terms: string | null;
|
|
178
|
+
};
|
|
179
|
+
export type FinancialDocumentRenderInput = DocumentTemplateInput & {
|
|
180
|
+
merchant: DocumentMerchant;
|
|
181
|
+
settings: DocumentRenderSettings;
|
|
182
|
+
};
|
|
183
|
+
export type PackingListRenderInput = PackingListTemplateInput & {
|
|
184
|
+
merchant: DocumentMerchant;
|
|
185
|
+
settings: DocumentRenderSettings;
|
|
186
|
+
};
|
|
187
|
+
export type DocumentRenderInput = FinancialDocumentRenderInput | PackingListRenderInput;
|
|
188
|
+
export type DocumentPdfOptions = {
|
|
189
|
+
/** Absolute executable path or command name for the bundled Chromium renderer. */
|
|
190
|
+
executablePath?: string;
|
|
191
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { DocumentRenderInput } from "./documents";
|
|
2
|
+
/**
|
|
3
|
+
* The only project-specific document extension point. PDF rendering and file
|
|
4
|
+
* storage stay inside the plugin; projects control semantic markup and CSS.
|
|
5
|
+
*/
|
|
6
|
+
export type DocumentHtmlFactory = (input: DocumentRenderInput) => string | Promise<string>;
|
|
7
|
+
export declare const defineDocumentHtmlFactory: (factory: DocumentHtmlFactory) => DocumentHtmlFactory;
|
|
8
|
+
export type { DocumentTheme } from "../templates/layout";
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./admin-api"), exports);
|
|
18
|
+
__exportStar(require("./documents"), exports);
|
|
19
|
+
__exportStar(require("./document-summary"), exports);
|
|
20
|
+
__exportStar(require("./html-factory"), exports);
|
|
21
|
+
__exportStar(require("./store-api"), exports);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type * from "@hartl-services/medusa-food-supplements-contracts/types/documents-store";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ResolvedSmtpConfiguration, ShopEmailConfiguration } from "../types";
|
|
2
|
+
export { createSmtpNotificationModuleConfig } from "./notification-module";
|
|
3
|
+
export declare const defineShopEmailConfiguration: <Configuration extends ShopEmailConfiguration>(configuration: Configuration) => Configuration;
|
|
4
|
+
export type { ResolvedSmtpConfiguration, ShopEmailConfiguration, } from "../types";
|
|
5
|
+
export declare const SMTP_ENVIRONMENT_VARIABLES: readonly ["SMTP_HOST", "SMTP_PORT", "SMTP_SECURE", "SMTP_USER", "SMTP_PASSWORD", "SMTP_FROM", "SMTP_REQUIRE_TLS"];
|
|
6
|
+
/**
|
|
7
|
+
* `medusa build` loads the configuration without deployment secrets. These
|
|
8
|
+
* placeholders only satisfy the required-variable checks of a build; they
|
|
9
|
+
* never reach a running server.
|
|
10
|
+
*/
|
|
11
|
+
export declare const SMTP_BUILD_PLACEHOLDERS: Readonly<Record<string, string>>;
|
|
12
|
+
/**
|
|
13
|
+
* Validates the SMTP environment values and returns the transport
|
|
14
|
+
* configuration. `allowInsecure` permits plain SMTP for development, tests
|
|
15
|
+
* and builds; otherwise `SMTP_SECURE` or `SMTP_REQUIRE_TLS` must be `true`.
|
|
16
|
+
*/
|
|
17
|
+
export declare const resolveSmtp: (values: Readonly<Record<(typeof SMTP_ENVIRONMENT_VARIABLES)[number], string>>, allowInsecure: boolean) => ResolvedSmtpConfiguration;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveSmtp = exports.SMTP_BUILD_PLACEHOLDERS = exports.SMTP_ENVIRONMENT_VARIABLES = exports.defineShopEmailConfiguration = exports.createSmtpNotificationModuleConfig = void 0;
|
|
4
|
+
var notification_module_1 = require("./notification-module");
|
|
5
|
+
Object.defineProperty(exports, "createSmtpNotificationModuleConfig", { enumerable: true, get: function () { return notification_module_1.createSmtpNotificationModuleConfig; } });
|
|
6
|
+
const defineShopEmailConfiguration = (configuration) => configuration;
|
|
7
|
+
exports.defineShopEmailConfiguration = defineShopEmailConfiguration;
|
|
8
|
+
exports.SMTP_ENVIRONMENT_VARIABLES = [
|
|
9
|
+
"SMTP_HOST",
|
|
10
|
+
"SMTP_PORT",
|
|
11
|
+
"SMTP_SECURE",
|
|
12
|
+
"SMTP_USER",
|
|
13
|
+
"SMTP_PASSWORD",
|
|
14
|
+
"SMTP_FROM",
|
|
15
|
+
"SMTP_REQUIRE_TLS",
|
|
16
|
+
];
|
|
17
|
+
/**
|
|
18
|
+
* `medusa build` loads the configuration without deployment secrets. These
|
|
19
|
+
* placeholders only satisfy the required-variable checks of a build; they
|
|
20
|
+
* never reach a running server.
|
|
21
|
+
*/
|
|
22
|
+
exports.SMTP_BUILD_PLACEHOLDERS = {
|
|
23
|
+
SMTP_FROM: "no-reply@smtp.build.invalid",
|
|
24
|
+
SMTP_HOST: "smtp.build.invalid",
|
|
25
|
+
SMTP_PASSWORD: "build-password",
|
|
26
|
+
SMTP_PORT: "2525",
|
|
27
|
+
SMTP_REQUIRE_TLS: "false",
|
|
28
|
+
SMTP_SECURE: "false",
|
|
29
|
+
SMTP_USER: "build-user",
|
|
30
|
+
};
|
|
31
|
+
const optionalValue = (values, name) => {
|
|
32
|
+
const value = values[name]?.trim();
|
|
33
|
+
return value ? value : undefined;
|
|
34
|
+
};
|
|
35
|
+
const integerValue = (values, name, minimum, maximum) => {
|
|
36
|
+
const value = optionalValue(values, name);
|
|
37
|
+
if (value === undefined) {
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
const parsed = Number(value);
|
|
41
|
+
if (!Number.isInteger(parsed) || parsed < minimum || parsed > maximum) {
|
|
42
|
+
throw new TypeError(`${name} must be an integer from ${minimum} through ${maximum}.`);
|
|
43
|
+
}
|
|
44
|
+
return parsed;
|
|
45
|
+
};
|
|
46
|
+
const booleanValue = (values, name, defaultValue) => {
|
|
47
|
+
const value = optionalValue(values, name);
|
|
48
|
+
if (value === undefined) {
|
|
49
|
+
return defaultValue;
|
|
50
|
+
}
|
|
51
|
+
if (value !== "true" && value !== "false") {
|
|
52
|
+
throw new TypeError(`${name} must be either "true" or "false".`);
|
|
53
|
+
}
|
|
54
|
+
return value === "true";
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Validates the SMTP environment values and returns the transport
|
|
58
|
+
* configuration. `allowInsecure` permits plain SMTP for development, tests
|
|
59
|
+
* and builds; otherwise `SMTP_SECURE` or `SMTP_REQUIRE_TLS` must be `true`.
|
|
60
|
+
*/
|
|
61
|
+
const resolveSmtp = (values, allowInsecure) => {
|
|
62
|
+
const port = integerValue(values, "SMTP_PORT", 1, 65535);
|
|
63
|
+
if (port === undefined) {
|
|
64
|
+
throw new TypeError("SMTP_PORT is required.");
|
|
65
|
+
}
|
|
66
|
+
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(values.SMTP_FROM)) {
|
|
67
|
+
throw new TypeError("SMTP_FROM must be a valid email address.");
|
|
68
|
+
}
|
|
69
|
+
const smtp = {
|
|
70
|
+
from: values.SMTP_FROM,
|
|
71
|
+
host: values.SMTP_HOST,
|
|
72
|
+
password: values.SMTP_PASSWORD,
|
|
73
|
+
port,
|
|
74
|
+
requireTls: booleanValue(values, "SMTP_REQUIRE_TLS", false),
|
|
75
|
+
secure: booleanValue(values, "SMTP_SECURE", false),
|
|
76
|
+
user: values.SMTP_USER,
|
|
77
|
+
};
|
|
78
|
+
if (!smtp.secure && !smtp.requireTls && !allowInsecure) {
|
|
79
|
+
throw new TypeError("SMTP must use SMTP_SECURE=true or SMTP_REQUIRE_TLS=true outside development and test.");
|
|
80
|
+
}
|
|
81
|
+
return smtp;
|
|
82
|
+
};
|
|
83
|
+
exports.resolveSmtp = resolveSmtp;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ResolvedSmtpConfiguration } from "../types";
|
|
2
|
+
export declare const createSmtpNotificationModuleConfig: (smtp: ResolvedSmtpConfiguration) => {
|
|
3
|
+
resolve: string;
|
|
4
|
+
options: {
|
|
5
|
+
providers: {
|
|
6
|
+
id: string;
|
|
7
|
+
options: {
|
|
8
|
+
channels: string[];
|
|
9
|
+
smtp: Readonly<{
|
|
10
|
+
from: string;
|
|
11
|
+
host: string;
|
|
12
|
+
password: string;
|
|
13
|
+
port: number;
|
|
14
|
+
requireTls: boolean;
|
|
15
|
+
secure: boolean;
|
|
16
|
+
user: string;
|
|
17
|
+
}>;
|
|
18
|
+
};
|
|
19
|
+
resolve: string;
|
|
20
|
+
}[];
|
|
21
|
+
};
|
|
22
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createSmtpNotificationModuleConfig = void 0;
|
|
4
|
+
const createSmtpNotificationModuleConfig = (smtp) => ({
|
|
5
|
+
resolve: "@medusajs/medusa/notification",
|
|
6
|
+
options: {
|
|
7
|
+
providers: [
|
|
8
|
+
{
|
|
9
|
+
id: "smtp",
|
|
10
|
+
options: {
|
|
11
|
+
channels: ["email"],
|
|
12
|
+
smtp,
|
|
13
|
+
},
|
|
14
|
+
resolve: "@hartl-services/medusa-base/providers/smtp",
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
exports.createSmtpNotificationModuleConfig = createSmtpNotificationModuleConfig;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { z } from "@medusajs/framework/zod";
|
|
2
|
+
export declare const EMAIL_KINDS: readonly ["order.received", "order.received.admin", "order.shipped", "order.canceled", "order.return_requested", "order.return_received", "order.refunded", "auth.password_reset", "affiliate.consignment_report_due", "user.invite"];
|
|
3
|
+
export declare const EmailKindSchema: z.ZodEnum<{
|
|
4
|
+
"order.received": "order.received";
|
|
5
|
+
"order.received.admin": "order.received.admin";
|
|
6
|
+
"order.shipped": "order.shipped";
|
|
7
|
+
"order.canceled": "order.canceled";
|
|
8
|
+
"order.return_requested": "order.return_requested";
|
|
9
|
+
"order.return_received": "order.return_received";
|
|
10
|
+
"order.refunded": "order.refunded";
|
|
11
|
+
"auth.password_reset": "auth.password_reset";
|
|
12
|
+
"affiliate.consignment_report_due": "affiliate.consignment_report_due";
|
|
13
|
+
"user.invite": "user.invite";
|
|
14
|
+
}>;
|
|
15
|
+
export type EmailKind = (typeof EMAIL_KINDS)[number];
|