@hartl-services/medusa-base 0.1.0 → 0.2.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/api/store/plugin-features/route.js +2 -3
- package/.medusa/server/src/modules/plugin-features/service.js +17 -1
- package/.medusa/server/src/public/complete-cart.js +3 -0
- package/.medusa/server/src/utils/discover-complete-cart-participants.js +90 -0
- package/.medusa/server/src/utils/discover-plugin-features.js +14 -6
- package/.medusa/server/src/workflows/hooks/complete-cart-participants.js +163 -0
- package/.medusa/server/src/workflows/hooks/complete-cart.js +17 -0
- package/README.md +66 -0
- package/dist/public/complete-cart.d.ts +21 -0
- package/dist/public/complete-cart.js +2 -0
- package/dist/public/index.d.ts +1 -0
- package/package.json +2 -2
|
@@ -5,9 +5,8 @@ const plugin_features_1 = require("@hartl-services/medusa-food-supplements-contr
|
|
|
5
5
|
const plugin_features_http_1 = require("../../plugin-features-http");
|
|
6
6
|
const wire_response_1 = require("../../wire-response");
|
|
7
7
|
const GET = async (req, res) => {
|
|
8
|
-
const
|
|
9
|
-
const plugins = await Promise.all((0, plugin_features_http_1.listPluginFeatureDescriptors)(req.scope).map((descriptor) => service.retrieveEffectiveFeatures(descriptor)));
|
|
8
|
+
const plugins = await (0, plugin_features_http_1.resolvePluginFeaturesService)(req.scope).listEffectiveFeatures((0, plugin_features_http_1.listPluginFeatureDescriptors)(req.scope));
|
|
10
9
|
res.json((0, wire_response_1.toWireResponse)(plugin_features_1.StorePluginFeaturesListResponseSchema, { plugins }));
|
|
11
10
|
};
|
|
12
11
|
exports.GET = GET;
|
|
13
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
12
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL3N0b3JlL3BsdWdpbi1mZWF0dXJlcy9yb3V0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSwrR0FBaUk7QUFHakkscUVBR21DO0FBQ25DLHVEQUFvRDtBQUU3QyxNQUFNLEdBQUcsR0FBRyxLQUFLLEVBQ3RCLEdBQWtCLEVBQ2xCLEdBQW9ELEVBQ3BELEVBQUU7SUFDRixNQUFNLE9BQU8sR0FBRyxNQUFNLElBQUEsbURBQTRCLEVBQ2hELEdBQUcsQ0FBQyxLQUFLLENBQ1YsQ0FBQyxxQkFBcUIsQ0FBQyxJQUFBLG1EQUE0QixFQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFBO0lBQ2hFLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBQSw4QkFBYyxFQUFDLHVEQUFxQyxFQUFFLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFBO0FBQzlFLENBQUMsQ0FBQTtBQVJZLFFBQUEsR0FBRyxPQVFmIn0=
|
|
@@ -60,6 +60,15 @@ class PluginFeaturesModuleService extends (0, utils_1.MedusaService)({
|
|
|
60
60
|
const stored = await this.retrieveStored(descriptor.plugin_key, sharedContext);
|
|
61
61
|
return (0, effective_features_1.resolveEffectivePluginFeatures)(descriptor, stored);
|
|
62
62
|
}
|
|
63
|
+
/** One query for every descriptor; the Store list uses it. */
|
|
64
|
+
async listEffectiveFeatures(descriptors, sharedContext = {}) {
|
|
65
|
+
if (descriptors.length === 0) {
|
|
66
|
+
return [];
|
|
67
|
+
}
|
|
68
|
+
const rows = await this.listPluginFeatureStates({ plugin_key: descriptors.map((descriptor) => descriptor.plugin_key) }, { take: descriptors.length }, sharedContext);
|
|
69
|
+
const storedByKey = new Map(rows.map((row) => [row.plugin_key, toStored(row)]));
|
|
70
|
+
return descriptors.map((descriptor) => (0, effective_features_1.resolveEffectivePluginFeatures)(descriptor, storedByKey.get(descriptor.plugin_key) ?? null));
|
|
71
|
+
}
|
|
63
72
|
async describePluginFeatures(descriptor, sharedContext = {}) {
|
|
64
73
|
const stored = await this.retrieveStored(descriptor.plugin_key, sharedContext);
|
|
65
74
|
return describe(descriptor, stored);
|
|
@@ -123,6 +132,13 @@ __decorate([
|
|
|
123
132
|
__metadata("design:paramtypes", [Object, Object]),
|
|
124
133
|
__metadata("design:returntype", Promise)
|
|
125
134
|
], PluginFeaturesModuleService.prototype, "retrieveEffectiveFeatures", null);
|
|
135
|
+
__decorate([
|
|
136
|
+
(0, utils_1.InjectManager)(),
|
|
137
|
+
__param(1, (0, utils_1.MedusaContext)()),
|
|
138
|
+
__metadata("design:type", Function),
|
|
139
|
+
__metadata("design:paramtypes", [Array, Object]),
|
|
140
|
+
__metadata("design:returntype", Promise)
|
|
141
|
+
], PluginFeaturesModuleService.prototype, "listEffectiveFeatures", null);
|
|
126
142
|
__decorate([
|
|
127
143
|
(0, utils_1.InjectManager)(),
|
|
128
144
|
__param(1, (0, utils_1.MedusaContext)()),
|
|
@@ -138,4 +154,4 @@ __decorate([
|
|
|
138
154
|
__metadata("design:returntype", Promise)
|
|
139
155
|
], PluginFeaturesModuleService.prototype, "updatePluginFeatures", null);
|
|
140
156
|
exports.default = PluginFeaturesModuleService;
|
|
141
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
157
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9tb2R1bGVzL3BsdWdpbi1mZWF0dXJlcy9zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBRUEscURBT2tDO0FBRWxDLHdFQUl3QztBQU14Qyx5RkFBOEQ7QUFzQjlELE1BQU0sUUFBUSxHQUFHLENBQ2YsR0FBMkIsRUFDaUIsRUFBRTtJQUM5QyxNQUFNLFFBQVEsR0FBNEIsRUFBRSxDQUFBO0lBQzVDLElBQUksR0FBRyxDQUFDLFFBQVEsSUFBSSxPQUFPLEdBQUcsQ0FBQyxRQUFRLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDckQsS0FBSyxNQUFNLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7WUFDeEQsSUFBSSxPQUFPLEtBQUssS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDL0IsUUFBUSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEtBQUssQ0FBQTtZQUN2QixDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFDRCxPQUFPLEVBQUUsT0FBTyxFQUFFLEdBQUcsQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUE7QUFDekUsQ0FBQyxDQUFBO0FBRUQsTUFBTSxRQUFRLEdBQUcsQ0FDZixVQUFtQyxFQUNuQyxNQUEyRCxFQUN0QyxFQUFFO0lBQ3ZCLE1BQU0sTUFBTSxHQUFHLElBQUEsK0NBQTBCLEVBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxDQUFBO0lBRTdELE9BQU87UUFDTCxVQUFVLEVBQUUsVUFBVSxDQUFDLFVBQVU7UUFDakMsS0FBSyxFQUFFLFVBQVUsQ0FBQyxLQUFLO1FBQ3ZCLFdBQVcsRUFBRSxVQUFVLENBQUMsV0FBVyxJQUFJLElB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
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcGxldGUtY2FydC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9wdWJsaWMvY29tcGxldGUtY2FydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIn0=
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.selectCompleteCartParticipants = selectCompleteCartParticipants;
|
|
4
|
+
exports.listCompleteCartParticipants = listCompleteCartParticipants;
|
|
5
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
6
|
+
const discover_plugin_features_1 = require("./discover-plugin-features");
|
|
7
|
+
const HOOK_NAMES = [
|
|
8
|
+
"validate",
|
|
9
|
+
"orderCreated",
|
|
10
|
+
];
|
|
11
|
+
const compare = (left, right) => left < right ? -1 : left > right ? 1 : 0;
|
|
12
|
+
const invalid = (moduleKey, reason) => new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, `Modul "${moduleKey}" deklariert ungültige Complete-Cart-Hooks: ${reason}`);
|
|
13
|
+
const readDeclarations = (moduleKey, service) => {
|
|
14
|
+
if (service === null || typeof service !== "object") {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
const declare = service
|
|
18
|
+
.completeCartHooks;
|
|
19
|
+
if (typeof declare !== "function") {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
let declarations;
|
|
23
|
+
try {
|
|
24
|
+
declarations = declare.call(service);
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
throw invalid(moduleKey, error instanceof Error ? error.message : String(error));
|
|
28
|
+
}
|
|
29
|
+
if (declarations === null ||
|
|
30
|
+
typeof declarations !== "object" ||
|
|
31
|
+
Array.isArray(declarations)) {
|
|
32
|
+
throw invalid(moduleKey, "completeCartHooks() liefert kein Objekt.");
|
|
33
|
+
}
|
|
34
|
+
return declarations;
|
|
35
|
+
};
|
|
36
|
+
const validateStep = (moduleKey, hook, step) => {
|
|
37
|
+
if (!HOOK_NAMES.includes(hook)) {
|
|
38
|
+
throw invalid(moduleKey, `unbekannter Hook "${hook}".`);
|
|
39
|
+
}
|
|
40
|
+
const candidate = step;
|
|
41
|
+
if (candidate === null ||
|
|
42
|
+
typeof candidate !== "object" ||
|
|
43
|
+
typeof candidate.workflow_id !== "string" ||
|
|
44
|
+
!candidate.workflow_id.trim() ||
|
|
45
|
+
typeof candidate.order !== "number" ||
|
|
46
|
+
!Number.isFinite(candidate.order)) {
|
|
47
|
+
throw invalid(moduleKey, `"${hook}" braucht eine workflow_id (String) und eine endliche order (Zahl).`);
|
|
48
|
+
}
|
|
49
|
+
return { workflow_id: candidate.workflow_id, order: candidate.order };
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Selects the participants of one hook from the given modules: every service
|
|
53
|
+
* with a `completeCartHooks()` function. Fails closed: an invalid declaration
|
|
54
|
+
* (for any hook) is `UNEXPECTED_STATE`, never skipped. Sorted by `order`,
|
|
55
|
+
* then module key, then workflow id.
|
|
56
|
+
*/
|
|
57
|
+
function selectCompleteCartParticipants(modules, hook) {
|
|
58
|
+
const participants = [];
|
|
59
|
+
for (const { key, service } of modules) {
|
|
60
|
+
const declarations = readDeclarations(key, service);
|
|
61
|
+
if (!declarations) {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
for (const [declaredHook, step] of Object.entries(declarations)) {
|
|
65
|
+
if (step === undefined) {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
const valid = validateStep(key, declaredHook, step);
|
|
69
|
+
if (declaredHook === hook) {
|
|
70
|
+
participants.push({ module_key: key, ...valid });
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
participants.sort((left, right) => left.order - right.order ||
|
|
75
|
+
compare(left.module_key, right.module_key) ||
|
|
76
|
+
compare(left.workflow_id, right.workflow_id));
|
|
77
|
+
const workflowIds = new Set();
|
|
78
|
+
for (const participant of participants) {
|
|
79
|
+
if (workflowIds.has(participant.workflow_id)) {
|
|
80
|
+
throw invalid(participant.module_key, `Workflow "${participant.workflow_id}" ist für "${hook}" mehrfach deklariert.`);
|
|
81
|
+
}
|
|
82
|
+
workflowIds.add(participant.workflow_id);
|
|
83
|
+
}
|
|
84
|
+
return participants;
|
|
85
|
+
}
|
|
86
|
+
/** The participants of one hook among the modules registered in the app. */
|
|
87
|
+
function listCompleteCartParticipants(container, hook) {
|
|
88
|
+
return selectCompleteCartParticipants((0, discover_plugin_features_1.listRegisteredModules)(container), hook);
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlzY292ZXItY29tcGxldGUtY2FydC1wYXJ0aWNpcGFudHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvdXRpbHMvZGlzY292ZXItY29tcGxldGUtY2FydC1wYXJ0aWNpcGFudHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUE0RkEsd0VBc0NDO0FBR0Qsb0VBS0M7QUF6SUQscURBQXVEO0FBR3ZELHlFQUdtQztBQVFuQyxNQUFNLFVBQVUsR0FBc0I7SUFDcEMsVUFBVTtJQUNWLGNBQWM7Q0FDa0IsQ0FBQTtBQUVsQyxNQUFNLE9BQU8sR0FBRyxDQUFDLElBQVksRUFBRSxLQUFhLEVBQVUsRUFBRSxDQUN0RCxJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7QUFFMUMsTUFBTSxPQUFPLEdBQUcsQ0FBQyxTQUFpQixFQUFFLE1BQWMsRUFBZSxFQUFFLENBQ2pFLElBQUksbUJBQVcsQ0FDYixtQkFBVyxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsRUFDbEMsVUFBVSxTQUFTLCtDQUErQyxNQUFNLEVBQUUsQ0FDM0UsQ0FBQTtBQUVILE1BQU0sZ0JBQWdCLEdBQUcsQ0FDdkIsU0FBaUIsRUFDakIsT0FBZ0IsRUFDcUIsRUFBRTtJQUN2QyxJQUFJLE9BQU8sS0FBSyxJQUFJLElBQUksT0FBTyxPQUFPLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDcEQsT0FBTyxTQUFTLENBQUE7SUFDbEIsQ0FBQztJQUNELE1BQU0sT0FBTyxHQUFJLE9BQTJDO1NBQ3pELGlCQUFpQixDQUFBO0lBQ3BCLElBQUksT0FBTyxPQUFPLEtBQUssVUFBVSxFQUFFLENBQUM7UUFDbEMsT0FBTyxTQUFTLENBQUE7SUFDbEIsQ0FBQztJQUVELElBQUksWUFBcUIsQ0FBQTtJQUN6QixJQUFJLENBQUM7UUFDSCxZQUFZLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQTtJQUN0QyxDQUFDO0lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztRQUNmLE1BQU0sT0FBTyxDQUNYLFNBQVMsRUFDVCxLQUFLLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQ3ZELENBQUE7SUFDSCxDQUFDO0lBQ0QsSUFDRSxZQUFZLEtBQUssSUFBSTtRQUNyQixPQUFPLFlBQVksS0FBSyxRQUFRO1FBQ2hDLEtBQUssQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLEVBQzNCLENBQUM7UUFDRCxNQUFNLE9BQU8sQ0FBQyxTQUFTLEVBQUUsMENBQTBDLENBQUMsQ0FBQTtJQUN0RSxDQUFDO0lBQ0QsT0FBTyxZQUF1QyxDQUFBO0FBQ2hELENBQUMsQ0FBQTtBQUVELE1BQU0sWUFBWSxHQUFHLENBQ25CLFNBQWlCLEVBQ2pCLElBQVksRUFDWixJQUFhLEVBQzJCLEVBQUU7SUFDMUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUMvQixNQUFNLE9BQU8sQ0FBQyxTQUFTLEVBQUUscUJBQXFCLElBQUksSUFBSSxDQUFDLENBQUE7SUFDekQsQ0FBQztJQUNELE1BQU0sU0FBUyxHQUFHLElBQXlELENBQUE7SUFDM0UsSUFDRSxTQUFTLEtBQUssSUFBSTtRQUNsQixPQUFPLFNBQVMsS0FBSyxRQUFRO1FBQzdCLE9BQU8sU0FBUyxDQUFDLFdBQVcsS0FBSyxRQUFRO1FBQ3pDLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUU7UUFDN0IsT0FBTyxTQUFTLENBQUMsS0FBSyxLQUFLLFFBQVE7UUFDbkMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsRUFDakMsQ0FBQztRQUNELE1BQU0sT0FBTyxDQUNYLFNBQVMsRUFDVCxJQUFJLElBQUkscUVBQXFFLENBQzlFLENBQUE7SUFDSCxDQUFDO0lBQ0QsT0FBTyxFQUFFLFdBQVcsRUFBRSxTQUFTLENBQUMsV0FBVyxFQUFFLEtBQUssRUFBRSxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUE7QUFDdkUsQ0FBQyxDQUFBO0FBRUQ7Ozs7O0dBS0c7QUFDSCxTQUFnQiw4QkFBOEIsQ0FDNUMsT0FBb0MsRUFDcEMsSUFBMEI7SUFFMUIsTUFBTSxZQUFZLEdBQW1DLEVBQUUsQ0FBQTtJQUN2RCxLQUFLLE1BQU0sRUFBRSxHQUFHLEVBQUUsT0FBTyxFQUFFLElBQUksT0FBTyxFQUFFLENBQUM7UUFDdkMsTUFBTSxZQUFZLEdBQUcsZ0JBQWdCLENBQUMsR0FBRyxFQUFFLE9BQU8sQ0FBQyxDQUFBO1FBQ25ELElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUNsQixTQUFRO1FBQ1YsQ0FBQztRQUNELEtBQUssTUFBTSxDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUM7WUFDaEUsSUFBSSxJQUFJLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ3ZCLFNBQVE7WUFDVixDQUFDO1lBQ0QsTUFBTSxLQUFLLEdBQUcsWUFBWSxDQUFDLEdBQUcsRUFBRSxZQUFZLEVBQUUsSUFBSSxDQUFDLENBQUE7WUFDbkQsSUFBSSxZQUFZLEtBQUssSUFBSSxFQUFFLENBQUM7Z0JBQzFCLFlBQVksQ0FBQyxJQUFJLENBQUMsRUFBRSxVQUFVLEVBQUUsR0FBRyxFQUFFLEdBQUcsS0FBSyxFQUFFLENBQUMsQ0FBQTtZQUNsRCxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFRCxZQUFZLENBQUMsSUFBSSxDQUNmLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxFQUFFLENBQ2QsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUMsS0FBSztRQUN4QixPQUFPLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxLQUFLLENBQUMsVUFBVSxDQUFDO1FBQzFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FDL0MsQ0FBQTtJQUNELE1BQU0sV0FBVyxHQUFHLElBQUksR0FBRyxFQUFVLENBQUE7SUFDckMsS0FBSyxNQUFNLFdBQVcsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUN2QyxJQUFJLFdBQVcsQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7WUFDN0MsTUFBTSxPQUFPLENBQ1gsV0FBVyxDQUFDLFVBQVUsRUFDdEIsYUFBYSxXQUFXLENBQUMsV0FBVyxjQUFjLElBQUksd0JBQXdCLENBQy9FLENBQUE7UUFDSCxDQUFDO1FBQ0QsV0FBVyxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLENBQUE7SUFDMUMsQ0FBQztJQUNELE9BQU8sWUFBWSxDQUFBO0FBQ3JCLENBQUM7QUFFRCw0RUFBNEU7QUFDNUUsU0FBZ0IsNEJBQTRCLENBQzFDLFNBQTBCLEVBQzFCLElBQTBCO0lBRTFCLE9BQU8sOEJBQThCLENBQUMsSUFBQSxnREFBcUIsRUFBQyxTQUFTLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQTtBQUMvRSxDQUFDIn0=
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.listRegisteredModules = listRegisteredModules;
|
|
3
4
|
exports.discoverPluginFeatureDescriptors = discoverPluginFeatureDescriptors;
|
|
4
5
|
exports.findPluginFeatureDescriptor = findPluginFeatureDescriptor;
|
|
5
6
|
const utils_1 = require("@medusajs/framework/utils");
|
|
@@ -7,6 +8,16 @@ const descriptor_1 = require("../public/descriptor");
|
|
|
7
8
|
// Keyed by the app's config object: stable for the process lifetime, unlike
|
|
8
9
|
// `req.scope`, which is a new scope per request.
|
|
9
10
|
const discovered = new WeakMap();
|
|
11
|
+
const registeredModules = (container, configModule) => Object.keys(configModule.modules ?? {})
|
|
12
|
+
.filter((moduleKey) => container.hasRegistration(moduleKey))
|
|
13
|
+
.map((moduleKey) => ({
|
|
14
|
+
key: moduleKey,
|
|
15
|
+
service: container.resolve(moduleKey),
|
|
16
|
+
}));
|
|
17
|
+
/** Every module listed in medusa-config that is registered in the container. */
|
|
18
|
+
function listRegisteredModules(container) {
|
|
19
|
+
return registeredModules(container, container.resolve(utils_1.ContainerRegistrationKeys.CONFIG_MODULE));
|
|
20
|
+
}
|
|
10
21
|
const readDescriptor = (service) => service !== null && typeof service === "object" && "pluginFeatures" in service
|
|
11
22
|
? service.pluginFeatures
|
|
12
23
|
: undefined;
|
|
@@ -21,11 +32,8 @@ function discoverPluginFeatureDescriptors(container) {
|
|
|
21
32
|
return memo;
|
|
22
33
|
}
|
|
23
34
|
const byPluginKey = new Map();
|
|
24
|
-
for (const moduleKey of
|
|
25
|
-
|
|
26
|
-
continue;
|
|
27
|
-
}
|
|
28
|
-
const candidate = readDescriptor(container.resolve(moduleKey));
|
|
35
|
+
for (const { key: moduleKey, service } of registeredModules(container, configModule)) {
|
|
36
|
+
const candidate = readDescriptor(service);
|
|
29
37
|
if (candidate === undefined) {
|
|
30
38
|
continue;
|
|
31
39
|
}
|
|
@@ -48,4 +56,4 @@ function discoverPluginFeatureDescriptors(container) {
|
|
|
48
56
|
function findPluginFeatureDescriptor(container, pluginKey) {
|
|
49
57
|
return discoverPluginFeatureDescriptors(container).find((descriptor) => descriptor.plugin_key === pluginKey);
|
|
50
58
|
}
|
|
51
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
59
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlzY292ZXItcGx1Z2luLWZlYXR1cmVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3V0aWxzL2Rpc2NvdmVyLXBsdWdpbi1mZWF0dXJlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQTRCQSxzREFPQztBQVdELDRFQStDQztBQUVELGtFQU9DO0FBckdELHFEQUFrRjtBQUVsRixxREFBc0U7QUFTdEUsNEVBQTRFO0FBQzVFLGlEQUFpRDtBQUNqRCxNQUFNLFVBQVUsR0FBRyxJQUFJLE9BQU8sRUFBcUMsQ0FBQTtBQUVuRSxNQUFNLGlCQUFpQixHQUFHLENBQ3hCLFNBQTBCLEVBQzFCLFlBQThCLEVBQ1YsRUFBRSxDQUN0QixNQUFNLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxPQUFPLElBQUksRUFBRSxDQUFDO0tBQ3BDLE1BQU0sQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUMsU0FBUyxDQUFDLGVBQWUsQ0FBQyxTQUFTLENBQUMsQ0FBQztLQUMzRCxHQUFHLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDbkIsR0FBRyxFQUFFLFNBQVM7SUFDZCxPQUFPLEVBQUUsU0FBUyxDQUFDLE9BQU8sQ0FBVSxTQUFTLENBQUM7Q0FDL0MsQ0FBQyxDQUFDLENBQUE7QUFFUCxnRkFBZ0Y7QUFDaEYsU0FBZ0IscUJBQXFCLENBQ25DLFNBQTBCO0lBRTFCLE9BQU8saUJBQWlCLENBQ3RCLFNBQVMsRUFDVCxTQUFTLENBQUMsT0FBTyxDQUFtQixpQ0FBeUIsQ0FBQyxhQUFhLENBQUMsQ0FDN0UsQ0FBQTtBQUNILENBQUM7QUFFRCxNQUFNLGNBQWMsR0FBRyxDQUFDLE9BQWdCLEVBQVcsRUFBRSxDQUNuRCxPQUFPLEtBQUssSUFBSSxJQUFJLE9BQU8sT0FBTyxLQUFLLFFBQVEsSUFBSSxnQkFBZ0IsSUFBSSxPQUFPO0lBQzVFLENBQUMsQ0FBRSxPQUF1QyxDQUFDLGNBQWM7SUFDekQsQ0FBQyxDQUFDLFNBQVMsQ0FBQTtBQUVmOzs7R0FHRztBQUNILFNBQWdCLGdDQUFnQyxDQUM5QyxTQUEwQjtJQUUxQixNQUFNLFlBQVksR0FBRyxTQUFTLENBQUMsT0FBTyxDQUNwQyxpQ0FBeUIsQ0FBQyxhQUFhLENBQ3hDLENBQUE7SUFDRCxNQUFNLElBQUksR0FBRyxVQUFVLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFBO0lBQ3pDLElBQUksSUFBSSxFQUFFLENBQUM7UUFDVCxPQUFPLElBQUksQ0FBQTtJQUNiLENBQUM7SUFFRCxNQUFNLFdBQVcsR0FBRyxJQUFJLEdBQUcsRUFBbUMsQ0FBQTtJQUM5RCxLQUFLLE1BQU0sRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxJQUFJLGlCQUFpQixDQUN6RCxTQUFTLEVBQ1QsWUFBWSxDQUNiLEVBQUUsQ0FBQztRQUNGLE1BQU0sU0FBUyxHQUFHLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUN6QyxJQUFJLFNBQVMsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUM1QixTQUFRO1FBQ1YsQ0FBQztRQUVELE1BQU0sVUFBVSxHQUFHLFNBQW9DLENBQUE7UUFDdkQsSUFBSSxDQUFDO1lBQ0gsSUFBQSw0Q0FBK0IsRUFBQyxVQUFVLENBQUMsQ0FBQTtRQUM3QyxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE1BQU0sSUFBSSxtQkFBVyxDQUNuQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsRUFDbEMsVUFBVSxTQUFTLDZDQUNqQixLQUFLLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUN2RCxFQUFFLENBQ0gsQ0FBQTtRQUNILENBQUM7UUFFRCxJQUFJLFdBQVcsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7WUFDM0MsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLGdCQUFnQixFQUNsQyxlQUFlLFVBQVUsQ0FBQyxVQUFVLHlDQUF5QyxDQUM5RSxDQUFBO1FBQ0gsQ0FBQztRQUNELFdBQVcsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLFVBQVUsRUFBRSxVQUFVLENBQUMsQ0FBQTtJQUNwRCxDQUFDO0lBRUQsTUFBTSxNQUFNLEdBQUcsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUM1RCxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQ2hELENBQUE7SUFDRCxVQUFVLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRSxNQUFNLENBQUMsQ0FBQTtJQUNwQyxPQUFPLE1BQU0sQ0FBQTtBQUNmLENBQUM7QUFFRCxTQUFnQiwyQkFBMkIsQ0FDekMsU0FBMEIsRUFDMUIsU0FBaUI7SUFFakIsT0FBTyxnQ0FBZ0MsQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFJLENBQ3JELENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQyxVQUFVLENBQUMsVUFBVSxLQUFLLFNBQVMsQ0FDcEQsQ0FBQTtBQUNILENBQUMifQ==
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.compensateCompleteCartOrderCreatedParticipants = exports.runCompleteCartOrderCreatedParticipants = exports.runCompleteCartValidateParticipants = void 0;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
|
|
6
|
+
const discover_complete_cart_participants_1 = require("../../utils/discover-complete-cart-participants");
|
|
7
|
+
const participantsFor = (hook, container, modules) => modules
|
|
8
|
+
? (0, discover_complete_cart_participants_1.selectCompleteCartParticipants)(modules, hook)
|
|
9
|
+
: (0, discover_complete_cart_participants_1.listCompleteCartParticipants)(container, hook);
|
|
10
|
+
const logError = (container, message) => {
|
|
11
|
+
try {
|
|
12
|
+
container
|
|
13
|
+
.resolve(utils_1.ContainerRegistrationKeys.LOGGER)
|
|
14
|
+
.error(message);
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
// Logging must not replace the original workflow outcome.
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Cancels (compensates) one participant run by transaction id, also after it
|
|
22
|
+
* finished; the participant workflow must be stored with a retention time.
|
|
23
|
+
* Not `engine.cancel()`: in Medusa 2.19.0 it loads the transaction through a
|
|
24
|
+
* workflow runner without the container, so the participant's compensation
|
|
25
|
+
* cannot resolve its module. Built with the container like `runAsStep` does.
|
|
26
|
+
* Throws the participant's own compensation error, not "Unknown error".
|
|
27
|
+
*/
|
|
28
|
+
const cancelParticipant = async (workflowId, transactionId, container, sharedContext) => {
|
|
29
|
+
const workflow = workflows_sdk_1.MedusaWorkflow.getWorkflow(workflowId);
|
|
30
|
+
if (!workflow) {
|
|
31
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, `Workflow "${workflowId}" is not registered.`);
|
|
32
|
+
}
|
|
33
|
+
const { transaction } = await workflow(container).cancel({
|
|
34
|
+
transactionId,
|
|
35
|
+
container,
|
|
36
|
+
context: { ...sharedContext },
|
|
37
|
+
throwOnError: false,
|
|
38
|
+
});
|
|
39
|
+
if (transaction.getState() !== utils_1.TransactionState.REVERTED) {
|
|
40
|
+
const [first] = transaction.getErrors();
|
|
41
|
+
throw (first?.error ??
|
|
42
|
+
new Error(`Workflow "${workflowId}" ended in state "${transaction.getState()}" instead of reverted.`));
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
const describeError = (error) => error instanceof Error
|
|
46
|
+
? error.message
|
|
47
|
+
: typeof error?.message === "string"
|
|
48
|
+
? error.message
|
|
49
|
+
: String(error);
|
|
50
|
+
/**
|
|
51
|
+
* Runs every `validate` participant in order. No transaction id: validation
|
|
52
|
+
* writes nothing, so there is nothing to compensate. The first error is
|
|
53
|
+
* rethrown unchanged, keeping its MedusaError type for the HTTP status.
|
|
54
|
+
*/
|
|
55
|
+
const runCompleteCartValidateParticipants = async (input, context, modules) => {
|
|
56
|
+
const { container, ...sharedContext } = context;
|
|
57
|
+
const participants = participantsFor("validate", container, modules);
|
|
58
|
+
if (!participants.length) {
|
|
59
|
+
return new workflows_sdk_1.StepResponse(undefined);
|
|
60
|
+
}
|
|
61
|
+
const workflowEngine = container.resolve(utils_1.Modules.WORKFLOW_ENGINE);
|
|
62
|
+
for (const participant of participants) {
|
|
63
|
+
// The engine JSON-clones its options, so the container is never passed
|
|
64
|
+
// to run(); the engine uses the shared app container.
|
|
65
|
+
await workflowEngine.run(participant.workflow_id, {
|
|
66
|
+
input,
|
|
67
|
+
context: {
|
|
68
|
+
...sharedContext,
|
|
69
|
+
preventReleaseEvents: true,
|
|
70
|
+
},
|
|
71
|
+
throwOnError: true,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return new workflows_sdk_1.StepResponse(undefined);
|
|
75
|
+
};
|
|
76
|
+
exports.runCompleteCartValidateParticipants = runCompleteCartValidateParticipants;
|
|
77
|
+
/**
|
|
78
|
+
* Runs every `orderCreated` participant in order under the complete-cart
|
|
79
|
+
* transaction id. If participant k fails, participants 0..k-1 are cancelled
|
|
80
|
+
* in reverse order; a rollback failure is logged, and the ORIGINAL error is
|
|
81
|
+
* rethrown either way.
|
|
82
|
+
*/
|
|
83
|
+
const runCompleteCartOrderCreatedParticipants = async (input, context, modules) => {
|
|
84
|
+
const { container, ...sharedContext } = context;
|
|
85
|
+
const transactionId = context.transactionId;
|
|
86
|
+
if (!transactionId) {
|
|
87
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, "Complete-cart orderCreated hook ran without a transaction id.");
|
|
88
|
+
}
|
|
89
|
+
const participants = participantsFor("orderCreated", container, modules);
|
|
90
|
+
const workflowIds = participants.map(({ workflow_id }) => workflow_id);
|
|
91
|
+
if (!participants.length) {
|
|
92
|
+
return new workflows_sdk_1.StepResponse(undefined, {
|
|
93
|
+
transaction_id: transactionId,
|
|
94
|
+
workflow_ids: workflowIds,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
const workflowEngine = container.resolve(utils_1.Modules.WORKFLOW_ENGINE);
|
|
98
|
+
const completed = [];
|
|
99
|
+
for (const participant of participants) {
|
|
100
|
+
try {
|
|
101
|
+
await workflowEngine.run(participant.workflow_id, {
|
|
102
|
+
input,
|
|
103
|
+
transactionId,
|
|
104
|
+
context: {
|
|
105
|
+
...sharedContext,
|
|
106
|
+
preventReleaseEvents: true,
|
|
107
|
+
},
|
|
108
|
+
throwOnError: true,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
for (const done of [...completed].reverse()) {
|
|
113
|
+
try {
|
|
114
|
+
await cancelParticipant(done.workflow_id, transactionId, container, sharedContext);
|
|
115
|
+
}
|
|
116
|
+
catch (rollbackError) {
|
|
117
|
+
logError(container, `Complete-cart orderCreated rollback failed for module "${done.module_key}", workflow "${done.workflow_id}" (cart ${input.cart_id}, order ${input.order_id}, transaction ${transactionId}) after "${participant.workflow_id}" failed: ${describeError(rollbackError)}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
throw error;
|
|
121
|
+
}
|
|
122
|
+
completed.push(participant);
|
|
123
|
+
}
|
|
124
|
+
return new workflows_sdk_1.StepResponse(undefined, {
|
|
125
|
+
transaction_id: transactionId,
|
|
126
|
+
workflow_ids: workflowIds,
|
|
127
|
+
});
|
|
128
|
+
};
|
|
129
|
+
exports.runCompleteCartOrderCreatedParticipants = runCompleteCartOrderCreatedParticipants;
|
|
130
|
+
/**
|
|
131
|
+
* Cancels the participants in reverse order. Every participant is attempted;
|
|
132
|
+
* failures are logged and the first one is thrown so the parent compensation
|
|
133
|
+
* stays failed. `undefined` means the invoke already rolled back.
|
|
134
|
+
*/
|
|
135
|
+
const compensateCompleteCartOrderCreatedParticipants = async (compensation, context) => {
|
|
136
|
+
if (!compensation) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
const { container, ...sharedContext } = context;
|
|
140
|
+
const workflowIds = [...compensation.workflow_ids].reverse();
|
|
141
|
+
if (!workflowIds.length) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
let failed = false;
|
|
145
|
+
let firstFailure;
|
|
146
|
+
for (const workflowId of workflowIds) {
|
|
147
|
+
try {
|
|
148
|
+
await cancelParticipant(workflowId, compensation.transaction_id, container, sharedContext);
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
logError(container, `Complete-cart orderCreated compensation failed for workflow "${workflowId}" (transaction ${compensation.transaction_id}): ${describeError(error)}`);
|
|
152
|
+
if (!failed) {
|
|
153
|
+
failed = true;
|
|
154
|
+
firstFailure = error;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
if (failed) {
|
|
159
|
+
throw firstFailure;
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
exports.compensateCompleteCartOrderCreatedParticipants = compensateCompleteCartOrderCreatedParticipants;
|
|
163
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcGxldGUtY2FydC1wYXJ0aWNpcGFudHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvd29ya2Zsb3dzL2hvb2tzL2NvbXBsZXRlLWNhcnQtcGFydGljaXBhbnRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUlBLHFEQUtrQztBQUNsQyxxRUFBZ0Y7QUFRaEYseUdBSXdEO0FBbUJ4RCxNQUFNLGVBQWUsR0FBRyxDQUN0QixJQUEwQixFQUMxQixTQUEwQixFQUMxQixPQUFnRCxFQUNoQixFQUFFLENBQ2xDLE9BQU87SUFDTCxDQUFDLENBQUMsSUFBQSxvRUFBOEIsRUFBQyxPQUFPLEVBQUUsSUFBSSxDQUFDO0lBQy9DLENBQUMsQ0FBQyxJQUFBLGtFQUE0QixFQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsQ0FBQTtBQUVuRCxNQUFNLFFBQVEsR0FBRyxDQUFDLFNBQTBCLEVBQUUsT0FBZSxFQUFRLEVBQUU7SUFDckUsSUFBSSxDQUFDO1FBQ0gsU0FBUzthQUNOLE9BQU8sQ0FDTixpQ0FBeUIsQ0FBQyxNQUFNLENBQ2pDO2FBQ0EsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFBO0lBQ25CLENBQUM7SUFBQyxNQUFNLENBQUM7UUFDUCwwREFBMEQ7SUFDNUQsQ0FBQztBQUNILENBQUMsQ0FBQTtBQWdCRDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxpQkFBaUIsR0FBRyxLQUFLLEVBQzdCLFVBQWtCLEVBQ2xCLGFBQXFCLEVBQ3JCLFNBQTBCLEVBQzFCLGFBQXNDLEVBQ3ZCLEVBQUU7SUFDakIsTUFBTSxRQUFRLEdBQ1osOEJBR0QsQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLENBQUE7SUFDekIsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ2QsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFDM0IsYUFBYSxVQUFVLHNCQUFzQixDQUM5QyxDQUFBO0lBQ0gsQ0FBQztJ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
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_flows_1 = require("@medusajs/medusa/core-flows");
|
|
4
|
+
const complete_cart_participants_1 = require("./complete-cart-participants");
|
|
5
|
+
/**
|
|
6
|
+
* The ONLY registrations of these two hooks in the whole shop. Medusa 2.19.0
|
|
7
|
+
* throws "Cannot define multiple hook handlers" for a second handler
|
|
8
|
+
* (workflows-sdk dist/utils/composer/create-hook.js), so plugins declare
|
|
9
|
+
* `completeCartHooks()` on their module service instead and the base runs
|
|
10
|
+
* their workflows. The cart path never reads feature toggles.
|
|
11
|
+
*/
|
|
12
|
+
core_flows_1.completeCartWorkflow.hooks.validate((input, context) => (0, complete_cart_participants_1.runCompleteCartValidateParticipants)(input, context));
|
|
13
|
+
// Medusa 2.19.0 creates this hook internally but omits it from complete cart's
|
|
14
|
+
// public declaration. Keep the cast isolated to this version-specific edge.
|
|
15
|
+
const { orderCreated } = core_flows_1.completeCartWorkflow.hooks;
|
|
16
|
+
orderCreated((input, context) => (0, complete_cart_participants_1.runCompleteCartOrderCreatedParticipants)(input, context), complete_cart_participants_1.compensateCompleteCartOrderCreatedParticipants);
|
|
17
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcGxldGUtY2FydC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy93b3JrZmxvd3MvaG9va3MvY29tcGxldGUtY2FydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUNBLDREQUFrRTtBQUdsRSw2RUFNcUM7QUFFckM7Ozs7OztHQU1HO0FBRUgsaUNBQW9CLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRSxDQUNyRCxJQUFBLGdFQUFtQyxFQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FDcEQsQ0FBQTtBQWFELCtFQUErRTtBQUMvRSw0RUFBNEU7QUFDNUUsTUFBTSxFQUFFLFlBQVksRUFBRSxHQUFHLGlDQUFvQixDQUFDLEtBRTdDLENBQUE7QUFFRCxZQUFZLENBQ1YsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUUsQ0FBQyxJQUFBLG9FQUF1QyxFQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsRUFDM0UsMkVBQThDLENBQy9DLENBQUEifQ==
|
package/README.md
CHANGED
|
@@ -16,6 +16,9 @@ helpers that plugins use to enforce their toggles.
|
|
|
16
16
|
values to the Admin.
|
|
17
17
|
- Exports `definePluginFeatures`, `requirePluginFeature` and
|
|
18
18
|
`isPluginFeatureEnabled` from `@hartl-services/medusa-base` for plugins.
|
|
19
|
+
- Owns the `completeCartWorkflow` hooks `validate` and `orderCreated` and runs
|
|
20
|
+
the workflows that plugins declare for them (see "Complete-cart hook
|
|
21
|
+
composition").
|
|
19
22
|
|
|
20
23
|
## Installation in a shop
|
|
21
24
|
|
|
@@ -164,3 +167,66 @@ existing data.
|
|
|
164
167
|
- Updates are optimistic: `expected_version` 0 creates the row, any other
|
|
165
168
|
value updates exactly that version. A concurrent change answers 409; the
|
|
166
169
|
Admin page reloads and shows a notice.
|
|
170
|
+
|
|
171
|
+
## Complete-cart hook composition
|
|
172
|
+
|
|
173
|
+
**Why.** Medusa 2.19.0 allows exactly one handler per workflow hook; a second
|
|
174
|
+
registration throws "Cannot define multiple hook handlers" at boot. Several
|
|
175
|
+
plugins need `completeCartWorkflow.hooks.validate` and the (undeclared, but
|
|
176
|
+
existing) `orderCreated` hook, so the base registers both, once
|
|
177
|
+
(`src/workflows/hooks/complete-cart.ts`), and runs the plugins' workflows.
|
|
178
|
+
**A plugin must never register these two hooks itself.**
|
|
179
|
+
|
|
180
|
+
**How a plugin participates.** Its module service implements
|
|
181
|
+
`CompleteCartParticipant` (plain data, `import type` only):
|
|
182
|
+
|
|
183
|
+
```ts
|
|
184
|
+
import type { CompleteCartHookDeclarations } from "@hartl-services/medusa-base"
|
|
185
|
+
|
|
186
|
+
class MyModuleService extends MedusaService({ /* … */ }) {
|
|
187
|
+
completeCartHooks(): CompleteCartHookDeclarations {
|
|
188
|
+
return {
|
|
189
|
+
validate: { workflow_id: "my-validate-complete-cart", order: 150 },
|
|
190
|
+
orderCreated: { workflow_id: "my-order-created", order: 150 },
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
- A `validate` workflow receives `CompleteCartValidateInput` (`{ input, cart }`)
|
|
197
|
+
and fails the checkout by throwing (a `MedusaError` keeps its type, so
|
|
198
|
+
`NOT_ALLOWED`/`INVALID_DATA` answer 400). It must not write.
|
|
199
|
+
- An `orderCreated` workflow receives `CompleteCartOrderCreatedInput`
|
|
200
|
+
(`{ order_id, cart_id }`) and must be compensable. Create it with
|
|
201
|
+
`store: true` and a `retentionTime` of at least three days (Medusa's own
|
|
202
|
+
`completeCartWorkflow` retention): the base cancels it by transaction id also
|
|
203
|
+
after it finished, and the in-memory workflow engine deletes an unstored
|
|
204
|
+
finished transaction.
|
|
205
|
+
- The base discovers participants like feature descriptors (every module in
|
|
206
|
+
`medusa-config` that is registered in the container). Fail closed: an
|
|
207
|
+
invalid declaration (non-string or blank `workflow_id`, non-finite `order`,
|
|
208
|
+
unknown hook name, the same workflow twice for one hook) is
|
|
209
|
+
`UNEXPECTED_STATE` and blocks checkout, naming the module key.
|
|
210
|
+
|
|
211
|
+
**Ordering.** Ascending `order`, then module key, then workflow id. In use:
|
|
212
|
+
Affiliate 100 (`affiliate-validate-complete-cart`,
|
|
213
|
+
`finalize-affiliate-order-attribution`), tax compliance 200
|
|
214
|
+
(`freeze-tax-compliance-order-evidence`, `orderCreated` only).
|
|
215
|
+
|
|
216
|
+
**Rollback semantics.**
|
|
217
|
+
|
|
218
|
+
- `validate` participants run one after another without their own transaction
|
|
219
|
+
id (they write nothing). The first error stops the chain and is rethrown
|
|
220
|
+
unchanged.
|
|
221
|
+
- `orderCreated` participants run one after another through the workflow
|
|
222
|
+
engine under the complete-cart transaction id, with the parent's event group
|
|
223
|
+
(`preventReleaseEvents`). If participant *k* fails, the base cancels
|
|
224
|
+
participants *k-1 … 0* in reverse order, logs every failed cancellation
|
|
225
|
+
(module key, workflow id, cart, order, transaction), and rethrows the
|
|
226
|
+
original error.
|
|
227
|
+
- When a later complete-cart step fails, the hook's compensation cancels every
|
|
228
|
+
participant in reverse order, attempts all of them, logs each failure and
|
|
229
|
+
then throws the first one, so the complete-cart compensation stays failed
|
|
230
|
+
instead of silently leaving partial state.
|
|
231
|
+
- The base never swallows a participant error and never reads toggles here.
|
|
232
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { completeCartWorkflow } from "@medusajs/medusa/core-flows";
|
|
2
|
+
/** The two complete-cart hooks the base composes (see README). */
|
|
3
|
+
export type CompleteCartHookName = "validate" | "orderCreated";
|
|
4
|
+
/** One participant workflow, run by id through the workflow engine. */
|
|
5
|
+
export type CompleteCartParticipantStep = {
|
|
6
|
+
readonly workflow_id: string;
|
|
7
|
+
/** Lower runs first; ties sort by module key, then workflow id. */
|
|
8
|
+
readonly order: number;
|
|
9
|
+
};
|
|
10
|
+
export type CompleteCartHookDeclarations = Partial<Record<CompleteCartHookName, CompleteCartParticipantStep>>;
|
|
11
|
+
/** Implemented by a plugin's module service. Plain data only: the base runs the workflows by id. */
|
|
12
|
+
export interface CompleteCartParticipant {
|
|
13
|
+
completeCartHooks(): CompleteCartHookDeclarations;
|
|
14
|
+
}
|
|
15
|
+
/** Input of a `validate` participant workflow: `{ input, cart }`. */
|
|
16
|
+
export type CompleteCartValidateInput = Parameters<Parameters<typeof completeCartWorkflow.hooks.validate>[0]>[0];
|
|
17
|
+
/** Input of an `orderCreated` participant workflow. */
|
|
18
|
+
export type CompleteCartOrderCreatedInput = {
|
|
19
|
+
order_id: string;
|
|
20
|
+
cart_id: string;
|
|
21
|
+
};
|
package/dist/public/index.d.ts
CHANGED
|
@@ -3,3 +3,4 @@ export { definePluginFeatures } from "./descriptor";
|
|
|
3
3
|
export { resolveEffectivePluginFeatures } from "./effective-features";
|
|
4
4
|
export { isPluginFeatureEnabled, requirePluginFeature } from "./enforcement";
|
|
5
5
|
export type { EffectivePluginFeatures, PluginFeatureDefinition, PluginFeatureDescriptor, PluginFeatureProvider, } from "./types";
|
|
6
|
+
export type { CompleteCartHookDeclarations, CompleteCartHookName, CompleteCartOrderCreatedInput, CompleteCartParticipant, CompleteCartParticipantStep, CompleteCartValidateInput, } from "./complete-cart";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hartl-services/medusa-base",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Base plugin for Hartl Services Medusa shops: per-plugin feature toggles with a generic Admin settings page, a Store endpoint for storefronts, and enforcement helpers for plugin routes, subscribers and jobs.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"files": [
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"react-router-dom": "^7.18.2"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@hartl-services/medusa-food-supplements-contracts": "^0.
|
|
49
|
+
"@hartl-services/medusa-food-supplements-contracts": "^0.11.0"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@medusajs/admin-sdk": "2.19.0",
|