@hartl-services/medusa-base 0.4.0 → 1.0.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 +1517 -87
- package/.medusa/server/src/admin/index.mjs +1518 -88
- 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 +24 -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 +142 -0
- package/.medusa/server/src/documents/templates/format.js +31 -0
- package/.medusa/server/src/documents/templates/html-factory.js +40 -0
- package/.medusa/server/src/documents/templates/html-utils.js +13 -0
- package/.medusa/server/src/documents/templates/layout.js +97 -0
- package/.medusa/server/src/documents/templates/packing-list.js +50 -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/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 +312 -0
- package/.medusa/server/src/email/application/handle-password-reset-event.js +354 -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/plugin-features.js +31 -0
- package/.medusa/server/src/email/rendering/default-templates.js +91 -0
- package/.medusa/server/src/email/rendering/render-email.js +37 -0
- package/.medusa/server/src/email/rendering/resolve-shop-configuration.js +48 -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 +79 -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/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/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-types.js +24 -0
- package/.medusa/server/src/shop-config/build-food-shop-config.js +248 -0
- package/.medusa/server/src/shop-config/options.js +71 -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 +163 -0
- package/.medusa/server/src/workflows/documents/issue-invoice-after-shipment.js +521 -0
- package/.medusa/server/src/workflows/documents/issue-packing-list.js +384 -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 +299 -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 +64 -0
- package/.medusa/server/src/workflows/email/prepare-order-received-email.js +56 -0
- package/.medusa/server/src/workflows/email/prepare-refund-email.js +47 -0
- package/.medusa/server/src/workflows/email/prepare-return-email.js +75 -0
- package/.medusa/server/src/workflows/email/prepare-shipment-email.js +82 -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 +1619 -7
- 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 +141 -0
- package/dist/documents/templates/format.d.ts +16 -0
- package/dist/documents/templates/format.js +30 -0
- package/dist/documents/templates/html-factory.d.ts +11 -0
- package/dist/documents/templates/html-factory.js +39 -0
- package/dist/documents/templates/html-utils.d.ts +2 -0
- package/dist/documents/templates/html-utils.js +12 -0
- package/dist/documents/templates/layout.d.ts +17 -0
- package/dist/documents/templates/layout.js +96 -0
- package/dist/documents/templates/packing-list.d.ts +3 -0
- package/dist/documents/templates/packing-list.js +49 -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 +174 -0
- package/dist/documents/types/documents.js +2 -0
- package/dist/documents/types/html-factory.d.ts +7 -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 +43 -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 +100 -0
- package/dist/email/types/template-data.js +78 -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/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-types.d.ts +7 -0
- package/dist/public/shop-types.js +23 -0
- package/dist/public/types.d.ts +17 -1
- package/dist/shop-config/build-food-shop-config.d.ts +44 -0
- package/dist/shop-config/build-food-shop-config.js +247 -0
- package/dist/shop-config/options.d.ts +41 -0
- package/dist/shop-config/options.js +70 -0
- package/package.json +48 -5
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildFoodShopConfig = buildFoodShopConfig;
|
|
4
|
+
exports.defineFoodShopConfig = defineFoodShopConfig;
|
|
5
|
+
const logger_1 = require("@medusajs/framework/logger");
|
|
6
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
7
|
+
const config_1 = require("../public/config");
|
|
8
|
+
const sentry_logger_1 = require("../public/sentry-logger");
|
|
9
|
+
const options_1 = require("./options");
|
|
10
|
+
/**
|
|
11
|
+
* Builds the plain `medusa-config.ts` input of a food shop: Medusa core
|
|
12
|
+
* settings, the Redis event bus, SMTP notifications, S3 file storage, tax and
|
|
13
|
+
* Stripe payment providers, and the Hartl Services plugins (the base plugin
|
|
14
|
+
* with its E-Mail, Documents and file storage modules plus five feature
|
|
15
|
+
* plugins). Deployment
|
|
16
|
+
* values are read and validated from `environment`; a missing or invalid one
|
|
17
|
+
* fails with its name.
|
|
18
|
+
*/
|
|
19
|
+
function buildFoodShopConfig(options, environment = process.env) {
|
|
20
|
+
(0, options_1.assertFoodShopConfigOptions)(options);
|
|
21
|
+
const { merchant } = options;
|
|
22
|
+
if (options.loadEnvFile !== false) {
|
|
23
|
+
(0, utils_1.loadEnv)(process.env.NODE_ENV || "development", process.cwd());
|
|
24
|
+
}
|
|
25
|
+
const phase = environment.MEDUSA_BUILD_PHASE === "true" ? "build" : "runtime";
|
|
26
|
+
const allowInsecure = (0, config_1.allowsInsecureLocalServices)(environment, phase);
|
|
27
|
+
const env = (0, config_1.requireEnvironment)(environment, [
|
|
28
|
+
"DATABASE_URL",
|
|
29
|
+
"STORE_CORS",
|
|
30
|
+
"ADMIN_CORS",
|
|
31
|
+
"AUTH_CORS",
|
|
32
|
+
"JWT_SECRET",
|
|
33
|
+
"COOKIE_SECRET",
|
|
34
|
+
"MEDUSA_BACKEND_URL",
|
|
35
|
+
"STOREFRONT_URL",
|
|
36
|
+
...config_1.SMTP_ENVIRONMENT_VARIABLES,
|
|
37
|
+
"STRIPE_API_KEY",
|
|
38
|
+
"STRIPE_WEBHOOK_SECRET",
|
|
39
|
+
"S3_CACHE_STORAGE_BUCKET",
|
|
40
|
+
"S3_CACHE_STORAGE_REGION",
|
|
41
|
+
"DOCUMENT_PDF_EXECUTABLE",
|
|
42
|
+
], phase, {
|
|
43
|
+
...config_1.MEDUSA_BUILD_PLACEHOLDERS,
|
|
44
|
+
...config_1.SMTP_BUILD_PLACEHOLDERS,
|
|
45
|
+
...config_1.S3_BUILD_PLACEHOLDERS,
|
|
46
|
+
...config_1.DOCUMENTS_BUILD_PLACEHOLDERS,
|
|
47
|
+
});
|
|
48
|
+
const storefrontOrigin = (0, config_1.resolvePublicOrigin)(env.STOREFRONT_URL, "STOREFRONT_URL", allowInsecure);
|
|
49
|
+
const backendOrigin = (0, config_1.resolvePublicOrigin)(env.MEDUSA_BACKEND_URL, "MEDUSA_BACKEND_URL", allowInsecure);
|
|
50
|
+
const redis = (0, config_1.resolveRedisEventBus)(environment, phase);
|
|
51
|
+
const stripe = (0, config_1.resolveStripe)(env);
|
|
52
|
+
const storefrontPath = `/${options.storefrontCountryCode}`;
|
|
53
|
+
// S3 file storage: the File Module provider plus the `files.gateway` option
|
|
54
|
+
// of the base plugin that serves its /files routes, both from one validated
|
|
55
|
+
// configuration.
|
|
56
|
+
const s3CacheStorage = (0, config_1.createS3CacheStorageConfig)({
|
|
57
|
+
cache: {
|
|
58
|
+
cleanupIntervalMs: (0, config_1.integerEnvironment)(environment, "S3_CACHE_STORAGE_CLEANUP_INTERVAL_MS", 1, 86_400_000) ?? 900_000,
|
|
59
|
+
dir: (0, config_1.optionalEnvironment)(environment, "S3_CACHE_STORAGE_CACHE_DIR") ??
|
|
60
|
+
"./.medusa-s3-cache",
|
|
61
|
+
expirationStrategy: (0, config_1.resolveExpirationStrategy)(environment, "absolute"),
|
|
62
|
+
ttlMs: (0, config_1.integerEnvironment)(environment, "S3_CACHE_STORAGE_TTL_MS", 0, 604_800_000) ?? 3_600_000,
|
|
63
|
+
},
|
|
64
|
+
gateway: {
|
|
65
|
+
baseUrl: `${backendOrigin}/files`,
|
|
66
|
+
privateDownloadDurationSeconds: (0, config_1.integerEnvironment)(environment, "FILE_GATEWAY_PRIVATE_DOWNLOAD_DURATION_SECONDS", 1, 604_800) ?? 3_600,
|
|
67
|
+
signingSecret: env.JWT_SECRET,
|
|
68
|
+
},
|
|
69
|
+
s3: {
|
|
70
|
+
bucket: env.S3_CACHE_STORAGE_BUCKET,
|
|
71
|
+
credentials: (0, config_1.resolveS3Credentials)(environment, phase),
|
|
72
|
+
endpoint: (0, config_1.optionalEnvironment)(environment, "S3_CACHE_STORAGE_ENDPOINT"),
|
|
73
|
+
forcePathStyle: (0, config_1.booleanEnvironment)(environment, "S3_CACHE_STORAGE_FORCE_PATH_STYLE", false),
|
|
74
|
+
region: env.S3_CACHE_STORAGE_REGION,
|
|
75
|
+
storagePrefix: (0, config_1.optionalEnvironment)(environment, "S3_CACHE_STORAGE_PREFIX"),
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
const modules = [
|
|
79
|
+
...(redis
|
|
80
|
+
? [
|
|
81
|
+
{
|
|
82
|
+
key: utils_1.Modules.EVENT_BUS,
|
|
83
|
+
resolve: "@medusajs/event-bus-redis",
|
|
84
|
+
options: {
|
|
85
|
+
redisUrl: redis.url,
|
|
86
|
+
jobOptions: {
|
|
87
|
+
attempts: 3,
|
|
88
|
+
backoff: {
|
|
89
|
+
delay: 1_000,
|
|
90
|
+
type: "exponential",
|
|
91
|
+
},
|
|
92
|
+
removeOnComplete: true,
|
|
93
|
+
removeOnFail: {
|
|
94
|
+
age: 3_600,
|
|
95
|
+
count: 1_000,
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
]
|
|
101
|
+
: []),
|
|
102
|
+
(0, config_1.createSmtpNotificationModuleConfig)((0, config_1.resolveSmtp)(env, allowInsecure)),
|
|
103
|
+
s3CacheStorage.fileModule,
|
|
104
|
+
{
|
|
105
|
+
resolve: "@medusajs/medusa/tax",
|
|
106
|
+
options: {
|
|
107
|
+
providers: [
|
|
108
|
+
{
|
|
109
|
+
resolve: "@hartl-services/medusa-tax-compliance/providers/tax-compliance",
|
|
110
|
+
},
|
|
111
|
+
],
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
resolve: "@medusajs/medusa/payment",
|
|
116
|
+
options: {
|
|
117
|
+
providers: [
|
|
118
|
+
{
|
|
119
|
+
resolve: "@medusajs/medusa/payment-stripe",
|
|
120
|
+
id: "stripe",
|
|
121
|
+
options: {
|
|
122
|
+
apiKey: stripe.apiKey,
|
|
123
|
+
webhookSecret: stripe.webhookSecret,
|
|
124
|
+
// Capture immediately at checkout. Several enabled payment
|
|
125
|
+
// methods (e.g. SEPA Direct Debit, iDEAL, Klarna) do not
|
|
126
|
+
// support a separate manual-capture step, so authorize-only is
|
|
127
|
+
// not an option while automaticPaymentMethods exposes them.
|
|
128
|
+
capture: true,
|
|
129
|
+
// Which methods appear (card, SEPA, wallets, ...) is controlled
|
|
130
|
+
// in the Stripe Dashboard under Settings -> Payment methods.
|
|
131
|
+
automaticPaymentMethods: true,
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
],
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
];
|
|
138
|
+
const plugins = [
|
|
139
|
+
{
|
|
140
|
+
// Always first: owns the plugin feature toggles the other plugins gate
|
|
141
|
+
// on, and carries E-Mail, Documents and the /files gateway.
|
|
142
|
+
resolve: "@hartl-services/medusa-base",
|
|
143
|
+
options: {
|
|
144
|
+
email: {
|
|
145
|
+
jwtSecret: env.JWT_SECRET,
|
|
146
|
+
shop: {
|
|
147
|
+
displayName: options.displayName,
|
|
148
|
+
affiliatePortalUrl: (0, config_1.shopUrl)(storefrontOrigin, `${storefrontPath}/partnerportal`),
|
|
149
|
+
// The Admin dashboard mounts "/invite" under admin.path ("/app").
|
|
150
|
+
inviteUrl: ({ token }) => {
|
|
151
|
+
const url = new URL("/app/invite", backendOrigin);
|
|
152
|
+
url.searchParams.set("token", token);
|
|
153
|
+
return url.toString();
|
|
154
|
+
},
|
|
155
|
+
orderNotificationEmail: options.orderNotificationEmail,
|
|
156
|
+
// The e-mail module appends "#token=<token>".
|
|
157
|
+
passwordResetUrl: () => (0, config_1.shopUrl)(storefrontOrigin, `${storefrontPath}/reset-password`),
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
documents: {
|
|
161
|
+
// Fallback only: the shop master data in the Admin ("Hartl Services
|
|
162
|
+
// Plugins" -> Shop-Stammdaten) wins per field.
|
|
163
|
+
merchant,
|
|
164
|
+
numbering: {
|
|
165
|
+
// Chooses the annual document-number period; matches the date the
|
|
166
|
+
// HTML factory prints.
|
|
167
|
+
timeZone: options.timeZone,
|
|
168
|
+
},
|
|
169
|
+
pdf: {
|
|
170
|
+
executablePath: env.DOCUMENT_PDF_EXECUTABLE,
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
files: { gateway: s3CacheStorage.gateway },
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
resolve: "@hartl-services/medusa-tax-compliance",
|
|
178
|
+
options: { merchant },
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
resolve: "@hartl-services/medusa-free-shipping",
|
|
182
|
+
options: {},
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
resolve: "@hartl-services/medusa-batch-management",
|
|
186
|
+
options: {},
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
resolve: "@hartl-services/medusa-affiliate",
|
|
190
|
+
options: {
|
|
191
|
+
consignment_reminders: {
|
|
192
|
+
due_day: 10,
|
|
193
|
+
timezone: options.timeZone,
|
|
194
|
+
},
|
|
195
|
+
portal: {
|
|
196
|
+
referral_base_url: (0, config_1.shopUrl)(storefrontOrigin, storefrontPath),
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
resolve: "@hartl-services/medusa-payload-sync",
|
|
202
|
+
// URL, API key and auth collection are Admin settings of the base
|
|
203
|
+
// plugin ("Hartl Services Plugins" -> Payload-CMS-Sync); until they are
|
|
204
|
+
// stored the plugin boots "nicht konfiguriert".
|
|
205
|
+
options: {},
|
|
206
|
+
},
|
|
207
|
+
];
|
|
208
|
+
return {
|
|
209
|
+
admin: {
|
|
210
|
+
// Kept explicit: serving the Admin SPA at "/" instead breaks its own
|
|
211
|
+
// auth, since the SPA's client-side-routing fallback then catches real
|
|
212
|
+
// API routes like /auth/user/providers too. The invite URL depends on
|
|
213
|
+
// this path.
|
|
214
|
+
path: "/app",
|
|
215
|
+
},
|
|
216
|
+
// Medusa's own HTTP error-handler middleware fully "handles" every thrown
|
|
217
|
+
// route/workflow error via logger.error(...) before it can ever reach an
|
|
218
|
+
// uncaught-exception process hook, so Sentry's default Node integrations
|
|
219
|
+
// never see it. This bridges logger.error(...) itself so those errors
|
|
220
|
+
// still reach Sentry.
|
|
221
|
+
logger: (0, sentry_logger_1.withSentryErrorReporting)(logger_1.logger),
|
|
222
|
+
projectConfig: {
|
|
223
|
+
databaseUrl: env.DATABASE_URL,
|
|
224
|
+
http: {
|
|
225
|
+
storeCors: env.STORE_CORS,
|
|
226
|
+
adminCors: env.ADMIN_CORS,
|
|
227
|
+
authCors: env.AUTH_CORS,
|
|
228
|
+
jwtSecret: env.JWT_SECRET,
|
|
229
|
+
cookieSecret: env.COOKIE_SECRET,
|
|
230
|
+
},
|
|
231
|
+
// The storefront turns its customer JWT into a Medusa browser session
|
|
232
|
+
// at login, so its browser-side cart and payment calls carry the
|
|
233
|
+
// customer's identity. Kept at the JWT's own 24h lifetime (Medusa's
|
|
234
|
+
// default is 10h) so the two never disagree about whether the customer
|
|
235
|
+
// is logged in.
|
|
236
|
+
sessionOptions: {
|
|
237
|
+
ttl: 24 * 60 * 60 * 1000,
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
modules,
|
|
241
|
+
plugins,
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
/** `defineConfig(buildFoodShopConfig(options))` for `module.exports`. */
|
|
245
|
+
function defineFoodShopConfig(options, environment = process.env) {
|
|
246
|
+
return (0, utils_1.defineConfig)(buildFoodShopConfig(options, environment));
|
|
247
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { DocumentMerchantOption } from "../documents/types";
|
|
2
|
+
/**
|
|
3
|
+
* The shop-specific facts of a food shop. Deployment values and secrets are
|
|
4
|
+
* not options: they come from the environment (see the README).
|
|
5
|
+
*/
|
|
6
|
+
export type FoodShopConfigOptions = Readonly<{
|
|
7
|
+
/**
|
|
8
|
+
* Fallback for the shop master data (Admin -> "Hartl Services Plugins" ->
|
|
9
|
+
* Shop-Stammdaten) that documents and tax compliance read per field. Its
|
|
10
|
+
* `legalName` is also the seeded store name.
|
|
11
|
+
*/
|
|
12
|
+
merchant: DocumentMerchantOption;
|
|
13
|
+
/** Shop name in the branding of the default e-mail templates. */
|
|
14
|
+
displayName: string;
|
|
15
|
+
/** Receives the shop's order notification e-mails. */
|
|
16
|
+
orderNotificationEmail: string;
|
|
17
|
+
/**
|
|
18
|
+
* IANA time zone (e.g. "Europe/Vienna"): chooses the annual document-number
|
|
19
|
+
* period, matches the dates printed on documents, and schedules the
|
|
20
|
+
* affiliate consignment reminders.
|
|
21
|
+
*/
|
|
22
|
+
timeZone: string;
|
|
23
|
+
/**
|
|
24
|
+
* Country code of the storefront route segment (e.g. "de"): e-mail links
|
|
25
|
+
* point to `/<code>/partnerportal` and `/<code>/reset-password`, and
|
|
26
|
+
* affiliate referral links to `/<code>`.
|
|
27
|
+
*/
|
|
28
|
+
storefrontCountryCode: string;
|
|
29
|
+
/**
|
|
30
|
+
* Load `.env.<NODE_ENV>` from the working directory into `process.env`
|
|
31
|
+
* like `medusa-config.ts` does by default. Pass `false` when the
|
|
32
|
+
* environment is already complete (tests, isolated child processes).
|
|
33
|
+
* Defaults to `true`.
|
|
34
|
+
*/
|
|
35
|
+
loadEnvFile?: boolean;
|
|
36
|
+
}>;
|
|
37
|
+
/**
|
|
38
|
+
* Throws a `TypeError` naming the first invalid option, so a misconfigured
|
|
39
|
+
* shop fails at boot.
|
|
40
|
+
*/
|
|
41
|
+
export declare function assertFoodShopConfigOptions(options: unknown): asserts options is FoodShopConfigOptions;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.assertFoodShopConfigOptions = assertFoodShopConfigOptions;
|
|
4
|
+
const fail = (name, expectation) => {
|
|
5
|
+
throw new TypeError(`Food shop option "${name}" must be ${expectation}.`);
|
|
6
|
+
};
|
|
7
|
+
const requireText = (value, name) => {
|
|
8
|
+
if (typeof value !== "string" || value.trim() === "") {
|
|
9
|
+
return fail(name, "a non-empty string");
|
|
10
|
+
}
|
|
11
|
+
return value;
|
|
12
|
+
};
|
|
13
|
+
const requireCountryCode = (value, name) => {
|
|
14
|
+
if (typeof value !== "string" || !/^[a-z]{2}$/.test(value)) {
|
|
15
|
+
return fail(name, 'a 2-letter lowercase country code such as "de"');
|
|
16
|
+
}
|
|
17
|
+
return value;
|
|
18
|
+
};
|
|
19
|
+
const requireTimeZone = (value, name) => {
|
|
20
|
+
const timeZone = requireText(value, name);
|
|
21
|
+
try {
|
|
22
|
+
new Intl.DateTimeFormat("en-US", { timeZone });
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return fail(name, 'a valid IANA time zone such as "Europe/Vienna"');
|
|
26
|
+
}
|
|
27
|
+
return timeZone;
|
|
28
|
+
};
|
|
29
|
+
const requireEmail = (value, name) => {
|
|
30
|
+
const email = requireText(value, name);
|
|
31
|
+
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
|
|
32
|
+
return fail(name, "a valid e-mail address");
|
|
33
|
+
}
|
|
34
|
+
return email;
|
|
35
|
+
};
|
|
36
|
+
const requireObject = (value, name) => {
|
|
37
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
38
|
+
return fail(name, "an object");
|
|
39
|
+
}
|
|
40
|
+
return value;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Throws a `TypeError` naming the first invalid option, so a misconfigured
|
|
44
|
+
* shop fails at boot.
|
|
45
|
+
*/
|
|
46
|
+
function assertFoodShopConfigOptions(options) {
|
|
47
|
+
const candidate = requireObject(options, "options");
|
|
48
|
+
const merchant = requireObject(candidate.merchant, "merchant");
|
|
49
|
+
requireText(merchant.legalName, "merchant.legalName");
|
|
50
|
+
requireCountryCode(merchant.countryCode, "merchant.countryCode");
|
|
51
|
+
if (merchant.vatNumber !== undefined) {
|
|
52
|
+
requireText(merchant.vatNumber, "merchant.vatNumber");
|
|
53
|
+
}
|
|
54
|
+
const address = requireObject(merchant.registeredAddress, "merchant.registeredAddress");
|
|
55
|
+
requireText(address.address1, "merchant.registeredAddress.address1");
|
|
56
|
+
if (address.address2 !== undefined) {
|
|
57
|
+
requireText(address.address2, "merchant.registeredAddress.address2");
|
|
58
|
+
}
|
|
59
|
+
requireText(address.city, "merchant.registeredAddress.city");
|
|
60
|
+
requireText(address.postalCode, "merchant.registeredAddress.postalCode");
|
|
61
|
+
requireCountryCode(address.countryCode, "merchant.registeredAddress.countryCode");
|
|
62
|
+
requireText(candidate.displayName, "displayName");
|
|
63
|
+
requireEmail(candidate.orderNotificationEmail, "orderNotificationEmail");
|
|
64
|
+
requireTimeZone(candidate.timeZone, "timeZone");
|
|
65
|
+
requireCountryCode(candidate.storefrontCountryCode, "storefrontCountryCode");
|
|
66
|
+
if (candidate.loadEnvFile !== undefined &&
|
|
67
|
+
typeof candidate.loadEnvFile !== "boolean") {
|
|
68
|
+
fail("loadEnvFile", "a boolean");
|
|
69
|
+
}
|
|
70
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hartl-services/medusa-base",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Base plugin for Hartl Services Medusa shops: per-plugin feature toggles with a generic Admin settings page, a Store endpoint for storefronts, enforcement helpers, the complete-cart hook composition, and the Sentry logger wrapper.",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Base plugin for Hartl Services Medusa shops: per-plugin feature toggles with a generic Admin settings page, a Store endpoint for storefronts, enforcement helpers, the complete-cart hook composition, the root redirect, cart-promotion link repair, the built-in E-Mail, Documents and S3 file storage modules, config helpers with the turnkey food-shop preset, and the Sentry logger wrapper and instrumentation.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"files": [
|
|
7
7
|
".medusa/server",
|
|
@@ -33,10 +33,36 @@
|
|
|
33
33
|
"import": "./dist/public/sentry-logger.js",
|
|
34
34
|
"require": "./dist/public/sentry-logger.js"
|
|
35
35
|
},
|
|
36
|
+
"./config": {
|
|
37
|
+
"types": "./dist/public/config.d.ts",
|
|
38
|
+
"import": "./dist/public/config.js",
|
|
39
|
+
"require": "./dist/public/config.js"
|
|
40
|
+
},
|
|
41
|
+
"./types": {
|
|
42
|
+
"types": "./dist/public/shop-types.d.ts",
|
|
43
|
+
"import": "./dist/public/shop-types.js",
|
|
44
|
+
"require": "./dist/public/shop-types.js"
|
|
45
|
+
},
|
|
46
|
+
"./gateway": {
|
|
47
|
+
"types": "./dist/public/gateway.d.ts",
|
|
48
|
+
"import": "./dist/public/gateway.js",
|
|
49
|
+
"require": "./dist/public/gateway.js"
|
|
50
|
+
},
|
|
51
|
+
"./shop-config": {
|
|
52
|
+
"types": "./dist/public/shop-config.d.ts",
|
|
53
|
+
"import": "./dist/public/shop-config.js",
|
|
54
|
+
"require": "./dist/public/shop-config.js"
|
|
55
|
+
},
|
|
56
|
+
"./instrumentation": {
|
|
57
|
+
"types": "./dist/public/instrumentation.d.ts",
|
|
58
|
+
"import": "./dist/public/instrumentation.js",
|
|
59
|
+
"require": "./dist/public/instrumentation.js"
|
|
60
|
+
},
|
|
36
61
|
"./admin-components": {
|
|
37
62
|
"types": "./dist/admin-components/index.d.ts",
|
|
38
63
|
"import": "./dist/admin-components/index.js"
|
|
39
64
|
},
|
|
65
|
+
"./providers/*": "./.medusa/server/src/providers/*/index.js",
|
|
40
66
|
"./.medusa/server/src/modules/*": "./.medusa/server/src/modules/*/index.js",
|
|
41
67
|
"./.medusa/server/src/*": "./.medusa/server/src/*",
|
|
42
68
|
"./admin": {
|
|
@@ -56,7 +82,13 @@
|
|
|
56
82
|
"react-router-dom": "^7.18.2"
|
|
57
83
|
},
|
|
58
84
|
"dependencies": {
|
|
59
|
-
"@
|
|
85
|
+
"@aws-sdk/client-s3": "^3.948.0",
|
|
86
|
+
"@aws-sdk/lib-storage": "^3.954.0",
|
|
87
|
+
"jsonwebtoken": "9.0.3",
|
|
88
|
+
"mime-types": "3.0.1",
|
|
89
|
+
"nodemailer": "6.10.1",
|
|
90
|
+
"ulid": "^2.4.0",
|
|
91
|
+
"@hartl-services/medusa-food-supplements-contracts": "^0.16.0"
|
|
60
92
|
},
|
|
61
93
|
"devDependencies": {
|
|
62
94
|
"@medusajs/admin-sdk": "2.19.0",
|
|
@@ -64,18 +96,26 @@
|
|
|
64
96
|
"@medusajs/framework": "2.19.0",
|
|
65
97
|
"@medusajs/js-sdk": "2.19.0",
|
|
66
98
|
"@medusajs/medusa": "2.19.0",
|
|
99
|
+
"@medusajs/test-utils": "2.19.0",
|
|
67
100
|
"@medusajs/ui": "4.2.1",
|
|
68
101
|
"@sentry/node": "^10.74.0",
|
|
69
102
|
"@swc/core": "^1.7.28",
|
|
70
103
|
"@swc/jest": "^0.2.39",
|
|
71
104
|
"@tanstack/react-query": "5.64.2",
|
|
72
105
|
"@types/jest": "^29.5.14",
|
|
106
|
+
"@types/jsonwebtoken": "^9.0.10",
|
|
107
|
+
"@types/mailparser": "3.4.6",
|
|
108
|
+
"@types/mime-types": "3.0.1",
|
|
73
109
|
"@types/node": "^20.12.11",
|
|
110
|
+
"@types/nodemailer": "6.4.17",
|
|
74
111
|
"@types/react": "^18.3.2",
|
|
75
112
|
"@types/react-dom": "^18.2.25",
|
|
113
|
+
"@types/smtp-server": "3.5.10",
|
|
76
114
|
"jest": "^29.7.0",
|
|
115
|
+
"mailparser": "3.7.2",
|
|
77
116
|
"react": "^18.3.1",
|
|
78
117
|
"react-router-dom": "7.18.2",
|
|
118
|
+
"smtp-server": "3.13.6",
|
|
79
119
|
"typescript": "^5.6.2",
|
|
80
120
|
"vite": "7.3.6",
|
|
81
121
|
"yalc": "^1.0.0-pre.53"
|
|
@@ -91,8 +131,11 @@
|
|
|
91
131
|
"scripts": {
|
|
92
132
|
"build": "medusa plugin:build && tsc -p tsconfig.public.json && tsc -p tsconfig.admin-components.json",
|
|
93
133
|
"dev": "medusa plugin:develop",
|
|
94
|
-
"typecheck": "tsc --noEmit",
|
|
134
|
+
"typecheck": "tsc --noEmit && tsc -p tsconfig.type-tests.json --noEmit",
|
|
95
135
|
"pretest:unit": "pnpm --filter @hartl-services/medusa-food-supplements-contracts build",
|
|
96
|
-
"test:unit": "jest"
|
|
136
|
+
"test:unit": "jest",
|
|
137
|
+
"pretest:contract": "pnpm --filter @hartl-services/medusa-food-supplements-contracts build",
|
|
138
|
+
"test:contract": "jest --config jest.contract.config.js --runInBand",
|
|
139
|
+
"test:integration:modules": "TEST_TYPE=integration:modules NODE_OPTIONS=--experimental-vm-modules jest --config jest.integration.config.js --silent=false --runInBand --forceExit"
|
|
97
140
|
}
|
|
98
141
|
}
|