medusa-product-helper 0.0.2 → 0.0.3
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/admin/wishlist/stats/route.js +32 -0
- package/.medusa/server/src/api/store/wishlist/[product_id]/route.js +36 -0
- package/.medusa/server/src/api/store/wishlist/route.js +66 -0
- package/.medusa/server/src/api/store/wishlist/validators.js +8 -0
- package/.medusa/server/src/modules/wishlist/index.js +14 -0
- package/.medusa/server/src/modules/wishlist/migrations/Migration20251125060140.js +15 -0
- package/.medusa/server/src/modules/wishlist/models/wishlist.js +10 -0
- package/.medusa/server/src/modules/wishlist/service.js +88 -0
- package/.medusa/server/src/shared/wishlist/helper.js +40 -0
- package/.medusa/server/src/shared/wishlist/index.js +6 -0
- package/.medusa/server/src/workflows/add-to-wishlist.js +52 -0
- package/.medusa/server/src/workflows/get-wishlist.js +78 -0
- package/.medusa/server/src/workflows/index.js +10 -0
- package/.medusa/server/src/workflows/remove-from-wishlist.js +30 -0
- package/README.md +311 -0
- package/package.json +2 -1
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GET = void 0;
|
|
4
|
+
const wishlist_1 = require("../../../../modules/wishlist");
|
|
5
|
+
const GET = async (req, res) => {
|
|
6
|
+
try {
|
|
7
|
+
const wishlistService = req.scope.resolve(wishlist_1.WISHLIST_MODULE);
|
|
8
|
+
const productId = req.query.product_id;
|
|
9
|
+
// If product_id is provided, return count for that product only
|
|
10
|
+
if (productId) {
|
|
11
|
+
const counts = await wishlistService.getWishlistCounts([productId]);
|
|
12
|
+
const count = counts.find((c) => c.product_id === productId);
|
|
13
|
+
res.json({
|
|
14
|
+
product_id: productId,
|
|
15
|
+
wishlist_count: count?.wishlist_count || 0,
|
|
16
|
+
});
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
// Otherwise, return counts for all products
|
|
20
|
+
const counts = await wishlistService.getWishlistCounts();
|
|
21
|
+
res.json({ stats: counts });
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
if (error instanceof Error) {
|
|
25
|
+
res.status(400).json({ message: error.message });
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
res.status(500).json({ message: "Internal server error" });
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
exports.GET = GET;
|
|
32
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL3dpc2hsaXN0L3N0YXRzL3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLDJEQUE4RDtBQUd2RCxNQUFNLEdBQUcsR0FBRyxLQUFLLEVBQ3RCLEdBQWtCLEVBQ2xCLEdBQW1CLEVBQ0osRUFBRTtJQUNqQixJQUFJLENBQUM7UUFDSCxNQUFNLGVBQWUsR0FBMEIsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQzlELDBCQUFlLENBQ2hCLENBQUE7UUFFRCxNQUFNLFNBQVMsR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLFVBQWdDLENBQUE7UUFFNUQsZ0VBQWdFO1FBQ2hFLElBQUksU0FBUyxFQUFFLENBQUM7WUFDZCxNQUFNLE1BQU0sR0FBRyxNQUFNLGVBQWUsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUE7WUFDbkUsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFVBQVUsS0FBSyxTQUFTLENBQUMsQ0FBQTtZQUU1RCxHQUFHLENBQUMsSUFBSSxDQUFDO2dCQUNQLFVBQVUsRUFBRSxTQUFTO2dCQUNyQixjQUFjLEVBQUUsS0FBSyxFQUFFLGNBQWMsSUFBSSxDQUFDO2FBQzNDLENBQUMsQ0FBQTtZQUNGLE9BQU07UUFDUixDQUFDO1FBRUQsNENBQTRDO1FBQzVDLE1BQU0sTUFBTSxHQUFHLE1BQU0sZUFBZSxDQUFDLGlCQUFpQixFQUFFLENBQUE7UUFFeEQsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFBO0lBQzdCLENBQUM7SUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1FBQ2YsSUFBSSxLQUFLLFlBQVksS0FBSyxFQUFFLENBQUM7WUFDM0IsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUE7WUFDaEQsT0FBTTtRQUNSLENBQUM7UUFDRCxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxDQUFDLENBQUE7SUFDNUQsQ0FBQztBQUNILENBQUMsQ0FBQTtBQWxDWSxRQUFBLEdBQUcsT0FrQ2YifQ==
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DELETE = void 0;
|
|
4
|
+
const remove_from_wishlist_1 = require("../../../../workflows/remove-from-wishlist");
|
|
5
|
+
const DELETE = async (req, res) => {
|
|
6
|
+
try {
|
|
7
|
+
const { product_id } = req.params;
|
|
8
|
+
if (!product_id) {
|
|
9
|
+
res.status(400).json({ message: "product_id is required" });
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
// Get customer ID from auth context
|
|
13
|
+
const customerId = req.auth_context?.actor_id;
|
|
14
|
+
if (!customerId) {
|
|
15
|
+
res.status(401).json({ message: "Unauthorized" });
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
// Execute remove from wishlist workflow
|
|
19
|
+
const { result } = await (0, remove_from_wishlist_1.removeFromWishlistWorkflow)(req.scope).run({
|
|
20
|
+
input: {
|
|
21
|
+
customer_id: customerId,
|
|
22
|
+
product_id: product_id,
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
res.json({ success: result.success });
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
if (error instanceof Error) {
|
|
29
|
+
res.status(400).json({ message: error.message });
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
res.status(500).json({ message: "Internal server error" });
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
exports.DELETE = DELETE;
|
|
36
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL3N0b3JlL3dpc2hsaXN0L1twcm9kdWN0X2lkXS9yb3V0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSxxRkFBdUY7QUFFaEYsTUFBTSxNQUFNLEdBQUcsS0FBSyxFQUN6QixHQUFrQixFQUNsQixHQUFtQixFQUNKLEVBQUU7SUFDakIsSUFBSSxDQUFDO1FBQ0gsTUFBTSxFQUFFLFVBQVUsRUFBRSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUE7UUFFakMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ2hCLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsT0FBTyxFQUFFLHdCQUF3QixFQUFFLENBQUMsQ0FBQTtZQUMzRCxPQUFNO1FBQ1IsQ0FBQztRQUVELG9DQUFvQztRQUNwQyxNQUFNLFVBQVUsR0FBSSxHQUFXLENBQUMsWUFBWSxFQUFFLFFBQVEsQ0FBQTtRQUV0RCxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDaEIsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFPLEVBQUUsY0FBYyxFQUFFLENBQUMsQ0FBQTtZQUNqRCxPQUFNO1FBQ1IsQ0FBQztRQUVELHdDQUF3QztRQUN4QyxNQUFNLEVBQUUsTUFBTSxFQUFFLEdBQUcsTUFBTSxJQUFBLGlEQUEwQixFQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUM7WUFDakUsS0FBSyxFQUFFO2dCQUNMLFdBQVcsRUFBRSxVQUFVO2dCQUN2QixVQUFVLEVBQUUsVUFBVTthQUN2QjtTQUNGLENBQUMsQ0FBQTtRQUVGLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUE7SUFDdkMsQ0FBQztJQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7UUFDZixJQUFJLEtBQUssWUFBWSxLQUFLLEVBQUUsQ0FBQztZQUMzQixHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQTtZQUNoRCxPQUFNO1FBQ1IsQ0FBQztRQUNELEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsT0FBTyxFQUFFLHVCQUF1QixFQUFFLENBQUMsQ0FBQTtJQUM1RCxDQUFDO0FBQ0gsQ0FBQyxDQUFBO0FBcENZLFFBQUEsTUFBTSxVQW9DbEIifQ==
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GET = exports.POST = void 0;
|
|
4
|
+
const add_to_wishlist_1 = require("../../../workflows/add-to-wishlist");
|
|
5
|
+
const get_wishlist_1 = require("../../../workflows/get-wishlist");
|
|
6
|
+
const validators_1 = require("./validators");
|
|
7
|
+
const POST = async (req, res) => {
|
|
8
|
+
try {
|
|
9
|
+
// Validate request body
|
|
10
|
+
const validated = validators_1.AddToWishlistSchema.parse(req.body);
|
|
11
|
+
// Get customer ID from auth context
|
|
12
|
+
const customerId = req.auth_context?.actor_id;
|
|
13
|
+
if (!customerId) {
|
|
14
|
+
res.status(401).json({ message: "Unauthorized" });
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
// Execute add to wishlist workflow
|
|
18
|
+
const { result } = await (0, add_to_wishlist_1.addToWishlistWorkflow)(req.scope).run({
|
|
19
|
+
input: {
|
|
20
|
+
customer_id: customerId,
|
|
21
|
+
product_id: validated.product_id,
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
res.json({ wishlist_item: result.wishlist_item });
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
if (error instanceof Error) {
|
|
28
|
+
res.status(400).json({ message: error.message });
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
res.status(500).json({ message: "Internal server error" });
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
exports.POST = POST;
|
|
35
|
+
const GET = async (req, res) => {
|
|
36
|
+
try {
|
|
37
|
+
// Get customer ID from auth context
|
|
38
|
+
const customerId = req.auth_context?.actor_id;
|
|
39
|
+
if (!customerId) {
|
|
40
|
+
res.status(401).json({ message: "Unauthorized" });
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
// Parse query parameters
|
|
44
|
+
const includeDetails = req.query.include_details === "true" ||
|
|
45
|
+
req.query.include_details === "1";
|
|
46
|
+
// Execute get wishlist workflow
|
|
47
|
+
const { result } = await (0, get_wishlist_1.getWishlistWorkflow)(req.scope).run({
|
|
48
|
+
input: {
|
|
49
|
+
customer_id: customerId,
|
|
50
|
+
options: {
|
|
51
|
+
includeDetails: includeDetails,
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
res.json({ wishlist: result.wishlist });
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
if (error instanceof Error) {
|
|
59
|
+
res.status(400).json({ message: error.message });
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
res.status(500).json({ message: "Internal server error" });
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
exports.GET = GET;
|
|
66
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL3N0b3JlL3dpc2hsaXN0L3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLHdFQUEwRTtBQUMxRSxrRUFBcUU7QUFDckUsNkNBQWtEO0FBRTNDLE1BQU0sSUFBSSxHQUFHLEtBQUssRUFDdkIsR0FBa0IsRUFDbEIsR0FBbUIsRUFDSixFQUFFO0lBQ2pCLElBQUksQ0FBQztRQUNILHdCQUF3QjtRQUN4QixNQUFNLFNBQVMsR0FBRyxnQ0FBbUIsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFBO1FBRXJELG9DQUFvQztRQUNwQyxNQUFNLFVBQVUsR0FBSSxHQUFXLENBQUMsWUFBWSxFQUFFLFFBQVEsQ0FBQTtRQUV0RCxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDaEIsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFPLEVBQUUsY0FBYyxFQUFFLENBQUMsQ0FBQTtZQUNqRCxPQUFNO1FBQ1IsQ0FBQztRQUVELG1DQUFtQztRQUNuQyxNQUFNLEVBQUUsTUFBTSxFQUFFLEdBQUcsTUFBTSxJQUFBLHVDQUFxQixFQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUM7WUFDNUQsS0FBSyxFQUFFO2dCQUNMLFdBQVcsRUFBRSxVQUFVO2dCQUN2QixVQUFVLEVBQUUsU0FBUyxDQUFDLFVBQVU7YUFDakM7U0FDRixDQUFDLENBQUE7UUFFRixHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsYUFBYSxFQUFFLE1BQU0sQ0FBQyxhQUFhLEVBQUUsQ0FBQyxDQUFBO0lBQ25ELENBQUM7SUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1FBQ2YsSUFBSSxLQUFLLFlBQVksS0FBSyxFQUFFLENBQUM7WUFDM0IsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUE7WUFDaEQsT0FBTTtRQUNSLENBQUM7UUFDRCxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxDQUFDLENBQUE7SUFDNUQsQ0FBQztBQUNILENBQUMsQ0FBQTtBQWhDWSxRQUFBLElBQUksUUFnQ2hCO0FBRU0sTUFBTSxHQUFHLEdBQUcsS0FBSyxFQUN0QixHQUFrQixFQUNsQixHQUFtQixFQUNKLEVBQUU7SUFDakIsSUFBSSxDQUFDO1FBQ0gsb0NBQW9DO1FBQ3BDLE1BQU0sVUFBVSxHQUFJLEdBQVcsQ0FBQyxZQUFZLEVBQUUsUUFBUSxDQUFBO1FBRXRELElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUNoQixHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLE9BQU8sRUFBRSxjQUFjLEVBQUUsQ0FBQyxDQUFBO1lBQ2pELE9BQU07UUFDUixDQUFDO1FBRUQseUJBQXlCO1FBQ3pCLE1BQU0sY0FBYyxHQUNsQixHQUFHLENBQUMsS0FBSyxDQUFDLGVBQWUsS0FBSyxNQUFNO1lBQ3BDLEdBQUcsQ0FBQyxLQUFLLENBQUMsZUFBZSxLQUFLLEdBQUcsQ0FBQTtRQUVuQyxnQ0FBZ0M7UUFDaEMsTUFBTSxFQUFFLE1BQU0sRUFBRSxHQUFHLE1BQU0sSUFBQSxrQ0FBbUIsRUFBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDO1lBQzFELEtBQUssRUFBRTtnQkFDTCxXQUFXLEVBQUUsVUFBVTtnQkFDdkIsT0FBTyxFQUFFO29CQUNQLGNBQWMsRUFBRSxjQUFjO2lCQUMvQjthQUNGO1NBQ0YsQ0FBQyxDQUFBO1FBRUYsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQTtJQUN6QyxDQUFDO0lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztRQUNmLElBQUksS0FBSyxZQUFZLEtBQUssRUFBRSxDQUFDO1lBQzNCLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFBO1lBQ2hELE9BQU07UUFDUixDQUFDO1FBQ0QsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsQ0FBQyxDQUFBO0lBQzVELENBQUM7QUFDSCxDQUFDLENBQUE7QUFwQ1ksUUFBQSxHQUFHLE9Bb0NmIn0=
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AddToWishlistSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
exports.AddToWishlistSchema = zod_1.z.object({
|
|
6
|
+
product_id: zod_1.z.string().min(1, "product_id is required"),
|
|
7
|
+
});
|
|
8
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdG9ycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcGkvc3RvcmUvd2lzaGxpc3QvdmFsaWRhdG9ycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2QkFBdUI7QUFFVixRQUFBLG1CQUFtQixHQUFHLE9BQUMsQ0FBQyxNQUFNLENBQUM7SUFDMUMsVUFBVSxFQUFFLE9BQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLHdCQUF3QixDQUFDO0NBQ3hELENBQUMsQ0FBQSJ9
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.WishlistModuleService = exports.WISHLIST_MODULE = void 0;
|
|
7
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
8
|
+
const service_1 = __importDefault(require("./service"));
|
|
9
|
+
exports.WishlistModuleService = service_1.default;
|
|
10
|
+
exports.WISHLIST_MODULE = "wishlist";
|
|
11
|
+
exports.default = (0, utils_1.Module)(exports.WISHLIST_MODULE, {
|
|
12
|
+
service: service_1.default,
|
|
13
|
+
});
|
|
14
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbW9kdWxlcy93aXNobGlzdC9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxxREFBa0Q7QUFDbEQsd0RBQTZDO0FBUXBDLGdDQVJGLGlCQUFxQixDQVFFO0FBTmpCLFFBQUEsZUFBZSxHQUFHLFVBQVUsQ0FBQTtBQUV6QyxrQkFBZSxJQUFBLGNBQU0sRUFBQyx1QkFBZSxFQUFFO0lBQ3JDLE9BQU8sRUFBRSxpQkFBcUI7Q0FDL0IsQ0FBQyxDQUFBIn0=
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Migration20251125060140 = void 0;
|
|
4
|
+
const migrations_1 = require("@mikro-orm/migrations");
|
|
5
|
+
class Migration20251125060140 extends migrations_1.Migration {
|
|
6
|
+
async up() {
|
|
7
|
+
this.addSql(`create table if not exists "wishlist" ("id" text not null, "customer_id" text not null, "product_id" text not null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "wishlist_pkey" primary key ("id"));`);
|
|
8
|
+
this.addSql(`CREATE INDEX IF NOT EXISTS "IDX_wishlist_deleted_at" ON "wishlist" (deleted_at) WHERE deleted_at IS NULL;`);
|
|
9
|
+
}
|
|
10
|
+
async down() {
|
|
11
|
+
this.addSql(`drop table if exists "wishlist" cascade;`);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
exports.Migration20251125060140 = Migration20251125060140;
|
|
15
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTWlncmF0aW9uMjAyNTExMjUwNjAxNDAuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbW9kdWxlcy93aXNobGlzdC9taWdyYXRpb25zL01pZ3JhdGlvbjIwMjUxMTI1MDYwMTQwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHNEQUFrRDtBQUVsRCxNQUFhLHVCQUF3QixTQUFRLHNCQUFTO0lBRTNDLEtBQUssQ0FBQyxFQUFFO1FBQ2YsSUFBSSxDQUFDLE1BQU0sQ0FBQyxzU0FBc1MsQ0FBQyxDQUFDO1FBQ3BULElBQUksQ0FBQyxNQUFNLENBQUMsMkdBQTJHLENBQUMsQ0FBQztJQUMzSCxDQUFDO0lBRVEsS0FBSyxDQUFDLElBQUk7UUFDakIsSUFBSSxDQUFDLE1BQU0sQ0FBQywwQ0FBMEMsQ0FBQyxDQUFDO0lBQzFELENBQUM7Q0FFRjtBQVhELDBEQVdDIn0=
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Wishlist = void 0;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
exports.Wishlist = utils_1.model.define("wishlist", {
|
|
6
|
+
id: utils_1.model.id().primaryKey(),
|
|
7
|
+
customer_id: utils_1.model.text().searchable(),
|
|
8
|
+
product_id: utils_1.model.text().searchable(),
|
|
9
|
+
});
|
|
10
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2lzaGxpc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbW9kdWxlcy93aXNobGlzdC9tb2RlbHMvd2lzaGxpc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEscURBQWlEO0FBRXBDLFFBQUEsUUFBUSxHQUFHLGFBQUssQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUFFO0lBQy9DLEVBQUUsRUFBRSxhQUFLLENBQUMsRUFBRSxFQUFFLENBQUMsVUFBVSxFQUFFO0lBQzNCLFdBQVcsRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsVUFBVSxFQUFFO0lBQ3RDLFVBQVUsRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsVUFBVSxFQUFFO0NBQ3RDLENBQUMsQ0FBQSJ9
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
4
|
+
const wishlist_1 = require("./models/wishlist");
|
|
5
|
+
class WishlistModuleService extends (0, utils_1.MedusaService)({
|
|
6
|
+
Wishlist: wishlist_1.Wishlist,
|
|
7
|
+
}) {
|
|
8
|
+
/**
|
|
9
|
+
* Add a product to customer's wishlist (idempotent - no duplicates)
|
|
10
|
+
*/
|
|
11
|
+
async addToWishlist(customerId, productId) {
|
|
12
|
+
// Check if already exists
|
|
13
|
+
const existing = await this.listWishlists({
|
|
14
|
+
customer_id: customerId,
|
|
15
|
+
product_id: productId,
|
|
16
|
+
});
|
|
17
|
+
if (existing.length > 0) {
|
|
18
|
+
return existing[0];
|
|
19
|
+
}
|
|
20
|
+
// Create new wishlist entry
|
|
21
|
+
const wishlist = await this.createWishlists({
|
|
22
|
+
customer_id: customerId,
|
|
23
|
+
product_id: productId,
|
|
24
|
+
});
|
|
25
|
+
return wishlist;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Remove a product from customer's wishlist
|
|
29
|
+
*/
|
|
30
|
+
async removeFromWishlist(customerId, productId) {
|
|
31
|
+
const wishlistItems = await this.listWishlists({
|
|
32
|
+
customer_id: customerId,
|
|
33
|
+
product_id: productId,
|
|
34
|
+
});
|
|
35
|
+
if (wishlistItems.length > 0) {
|
|
36
|
+
await this.deleteWishlists(wishlistItems.map((item) => item.id));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Get customer's wishlist with optional filtering and details
|
|
41
|
+
*/
|
|
42
|
+
async getWishlist(customerId, options = {}) {
|
|
43
|
+
const filters = {
|
|
44
|
+
customer_id: customerId,
|
|
45
|
+
};
|
|
46
|
+
if (options.productIds && options.productIds.length > 0) {
|
|
47
|
+
filters.product_id = options.productIds;
|
|
48
|
+
}
|
|
49
|
+
const wishlistItems = await this.listWishlists(filters);
|
|
50
|
+
if (options.includeDetails) {
|
|
51
|
+
return wishlistItems;
|
|
52
|
+
}
|
|
53
|
+
// Return only product IDs
|
|
54
|
+
return wishlistItems.map((item) => item.product_id);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Get wishlist counts per product (for admin)
|
|
58
|
+
*/
|
|
59
|
+
async getWishlistCounts(productIds) {
|
|
60
|
+
const filters = {};
|
|
61
|
+
if (productIds && productIds.length > 0) {
|
|
62
|
+
filters.product_id = productIds;
|
|
63
|
+
}
|
|
64
|
+
const wishlistItems = await this.listWishlists(filters);
|
|
65
|
+
// Count occurrences per product_id
|
|
66
|
+
const counts = new Map();
|
|
67
|
+
for (const item of wishlistItems) {
|
|
68
|
+
const productId = item.product_id;
|
|
69
|
+
counts.set(productId, (counts.get(productId) || 0) + 1);
|
|
70
|
+
}
|
|
71
|
+
return Array.from(counts.entries()).map(([product_id, wishlist_count]) => ({
|
|
72
|
+
product_id,
|
|
73
|
+
wishlist_count,
|
|
74
|
+
}));
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Check if a product is in customer's wishlist
|
|
78
|
+
*/
|
|
79
|
+
async isInWishlist(customerId, productId) {
|
|
80
|
+
const wishlistItems = await this.listWishlists({
|
|
81
|
+
customer_id: customerId,
|
|
82
|
+
product_id: productId,
|
|
83
|
+
});
|
|
84
|
+
return wishlistItems.length > 0;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
exports.default = WishlistModuleService;
|
|
88
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9tb2R1bGVzL3dpc2hsaXN0L3NlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxxREFBeUQ7QUFDekQsZ0RBQTRDO0FBb0I1QyxNQUFNLHFCQUFzQixTQUFRLElBQUEscUJBQWEsRUFBQztJQUNoRCxRQUFRLEVBQVIsbUJBQVE7Q0FDVCxDQUFDO0lBQ0E7O09BRUc7SUFDSCxLQUFLLENBQUMsYUFBYSxDQUNqQixVQUFrQixFQUNsQixTQUFpQjtRQUVqQiwwQkFBMEI7UUFDMUIsTUFBTSxRQUFRLEdBQUcsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDO1lBQ3hDLFdBQVcsRUFBRSxVQUFVO1lBQ3ZCLFVBQVUsRUFBRSxTQUFTO1NBQ3RCLENBQUMsQ0FBQTtRQUVGLElBQUksUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN4QixPQUFPLFFBQVEsQ0FBQyxDQUFDLENBQWlCLENBQUE7UUFDcEMsQ0FBQztRQUVELDRCQUE0QjtRQUM1QixNQUFNLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxlQUFlLENBQUM7WUFDMUMsV0FBVyxFQUFFLFVBQVU7WUFDdkIsVUFBVSxFQUFFLFNBQVM7U0FDdEIsQ0FBQyxDQUFBO1FBRUYsT0FBTyxRQUF3QixDQUFBO0lBQ2pDLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxrQkFBa0IsQ0FDdEIsVUFBa0IsRUFDbEIsU0FBaUI7UUFFakIsTUFBTSxhQUFhLEdBQUcsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDO1lBQzdDLFdBQVcsRUFBRSxVQUFVO1lBQ3ZCLFVBQVUsRUFBRSxTQUFTO1NBQ3RCLENBQUMsQ0FBQTtRQUVGLElBQUksYUFBYSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUM3QixNQUFNLElBQUksQ0FBQyxlQUFlLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUE7UUFDbEUsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxXQUFXLENBQ2YsVUFBa0IsRUFDbEIsVUFBOEIsRUFBRTtRQUVoQyxNQUFNLE9BQU8sR0FBNEI7WUFDdkMsV0FBVyxFQUFFLFVBQVU7U0FDeEIsQ0FBQTtRQUVELElBQUksT0FBTyxDQUFDLFVBQVUsSUFBSSxPQUFPLENBQUMsVUFBVSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN4RCxPQUFPLENBQUMsVUFBVSxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUE7UUFDekMsQ0FBQztRQUVELE1BQU0sYUFBYSxHQUFHLE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUV2RCxJQUFJLE9BQU8sQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUMzQixPQUFPLGFBQStCLENBQUE7UUFDeEMsQ0FBQztRQUVELDBCQUEwQjtRQUMxQixPQUFPLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQTtJQUNyRCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsaUJBQWlCLENBQ3JCLFVBQXFCO1FBRXJCLE1BQU0sT0FBTyxHQUE0QixFQUFFLENBQUE7UUFFM0MsSUFBSSxVQUFVLElBQUksVUFBVSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN4QyxPQUFPLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQTtRQUNqQyxDQUFDO1FBRUQsTUFBTSxhQUFhLEdBQUcsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFBO1FBRXZELG1DQUFtQztRQUNuQyxNQUFNLE1BQU0sR0FBRyxJQUFJLEdBQUcsRUFBa0IsQ0FBQTtRQUV4QyxLQUFLLE1BQU0sSUFBSSxJQUFJLGFBQWEsRUFBRSxDQUFDO1lBQ2pDLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxVQUFvQixDQUFBO1lBQzNDLE1BQU0sQ0FBQyxHQUFHLENBQUMsU0FBUyxFQUFFLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQTtRQUN6RCxDQUFDO1FBRUQsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsVUFBVSxFQUFFLGNBQWMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQ3pFLFVBQVU7WUFDVixjQUFjO1NBQ2YsQ0FBQyxDQUFDLENBQUE7SUFDTCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsWUFBWSxDQUNoQixVQUFrQixFQUNsQixTQUFpQjtRQUVqQixNQUFNLGFBQWEsR0FBRyxNQUFNLElBQUksQ0FBQyxhQUFhLENBQUM7WUFDN0MsV0FBVyxFQUFFLFVBQVU7WUFDdkIsVUFBVSxFQUFFLFNBQVM7U0FDdEIsQ0FBQyxDQUFBO1FBRUYsT0FBTyxhQUFhLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQTtJQUNqQyxDQUFDO0NBQ0Y7QUFFRCxrQkFBZSxxQkFBcUIsQ0FBQSJ9
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getWishlist = getWishlist;
|
|
4
|
+
const wishlist_1 = require("../../modules/wishlist");
|
|
5
|
+
/**
|
|
6
|
+
* Helper function to get customer's wishlist
|
|
7
|
+
* This function can be used directly by UI components without implementing the entire logic
|
|
8
|
+
*
|
|
9
|
+
* @param container - Medusa container instance
|
|
10
|
+
* @param customerId - Customer ID
|
|
11
|
+
* @param options - Options for getting wishlist
|
|
12
|
+
* @returns Promise of wishlist items (IDs or full details based on options)
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* // Get only product IDs
|
|
16
|
+
* const wishlist = await getWishlist(container, customerId)
|
|
17
|
+
* // Returns: ['prod_123', 'prod_456']
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* // Get full product details
|
|
21
|
+
* const wishlist = await getWishlist(container, customerId, { includeDetails: true })
|
|
22
|
+
* // Returns: [{ product_id: 'prod_123', product: {...}, ... }]
|
|
23
|
+
*/
|
|
24
|
+
async function getWishlist(container, customerId, options = {}) {
|
|
25
|
+
const wishlistService = container.resolve(wishlist_1.WISHLIST_MODULE);
|
|
26
|
+
const serviceOptions = {
|
|
27
|
+
includeDetails: options.includeDetails ?? false,
|
|
28
|
+
productIds: options.productIds,
|
|
29
|
+
};
|
|
30
|
+
const wishlist = await wishlistService.getWishlist(customerId, serviceOptions);
|
|
31
|
+
// If includeDetails is false, wishlist is an array of product IDs
|
|
32
|
+
if (!options.includeDetails) {
|
|
33
|
+
return wishlist;
|
|
34
|
+
}
|
|
35
|
+
// If includeDetails is true, we need to enrich with product details
|
|
36
|
+
// For now, return the wishlist items as-is (they should already have details if includeDetails was true)
|
|
37
|
+
// In a real implementation, you might want to use remote query to enrich here
|
|
38
|
+
return wishlist;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVscGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL3NoYXJlZC93aXNobGlzdC9oZWxwZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUE4Q0Esa0NBeUJDO0FBdEVELHFEQUF3RDtBQTBCeEQ7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWtCRztBQUNJLEtBQUssVUFBVSxXQUFXLENBQy9CLFNBQXdCLEVBQ3hCLFVBQWtCLEVBQ2xCLFVBQW9DLEVBQUU7SUFFdEMsTUFBTSxlQUFlLEdBQTBCLFNBQVMsQ0FBQyxPQUFPLENBQzlELDBCQUFlLENBQ2hCLENBQUE7SUFFRCxNQUFNLGNBQWMsR0FBdUI7UUFDekMsY0FBYyxFQUFFLE9BQU8sQ0FBQyxjQUFjLElBQUksS0FBSztRQUMvQyxVQUFVLEVBQUUsT0FBTyxDQUFDLFVBQVU7S0FDL0IsQ0FBQTtJQUVELE1BQU0sUUFBUSxHQUFHLE1BQU0sZUFBZSxDQUFDLFdBQVcsQ0FBQyxVQUFVLEVBQUUsY0FBYyxDQUFDLENBQUE7SUFFOUUsa0VBQWtFO0lBQ2xFLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDNUIsT0FBTyxRQUFvQixDQUFBO0lBQzdCLENBQUM7SUFFRCxvRUFBb0U7SUFDcEUseUdBQXlHO0lBQ3pHLDhFQUE4RTtJQUM5RSxPQUFPLFFBQWtDLENBQUE7QUFDM0MsQ0FBQyJ9
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getWishlist = void 0;
|
|
4
|
+
var helper_1 = require("./helper");
|
|
5
|
+
Object.defineProperty(exports, "getWishlist", { enumerable: true, get: function () { return helper_1.getWishlist; } });
|
|
6
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvc2hhcmVkL3dpc2hsaXN0L2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLG1DQUFzQztBQUE3QixxR0FBQSxXQUFXLE9BQUEifQ==
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.addToWishlistWorkflow = void 0;
|
|
4
|
+
const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
|
|
5
|
+
const wishlist_1 = require("../modules/wishlist");
|
|
6
|
+
const validateCustomerAndProductStep = (0, workflows_sdk_1.createStep)("validate-customer-and-product", async (input, { container }) => {
|
|
7
|
+
// Validate customer exists using remote query
|
|
8
|
+
const remoteQuery = container.resolve("remoteQuery");
|
|
9
|
+
const customerQuery = {
|
|
10
|
+
customer: {
|
|
11
|
+
fields: ["id"],
|
|
12
|
+
filters: {
|
|
13
|
+
id: input.customer_id,
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
const [customer] = await remoteQuery(customerQuery);
|
|
18
|
+
if (!customer) {
|
|
19
|
+
throw new Error(`Customer with id ${input.customer_id} not found`);
|
|
20
|
+
}
|
|
21
|
+
// Validate product exists using remote query
|
|
22
|
+
const productQuery = {
|
|
23
|
+
product: {
|
|
24
|
+
fields: ["id"],
|
|
25
|
+
filters: {
|
|
26
|
+
id: input.product_id,
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
const [product] = await remoteQuery(productQuery);
|
|
31
|
+
if (!product) {
|
|
32
|
+
throw new Error(`Product with id ${input.product_id} not found`);
|
|
33
|
+
}
|
|
34
|
+
return new workflows_sdk_1.StepResponse({
|
|
35
|
+
customer_id: input.customer_id,
|
|
36
|
+
product_id: input.product_id,
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
const addToWishlistStep = (0, workflows_sdk_1.createStep)("add-to-wishlist", async (input, { container }) => {
|
|
40
|
+
const wishlistService = container.resolve(wishlist_1.WISHLIST_MODULE);
|
|
41
|
+
const wishlistItem = await wishlistService.addToWishlist(input.customer_id, input.product_id);
|
|
42
|
+
return new workflows_sdk_1.StepResponse(wishlistItem);
|
|
43
|
+
});
|
|
44
|
+
exports.addToWishlistWorkflow = (0, workflows_sdk_1.createWorkflow)("add-to-wishlist", (input) => {
|
|
45
|
+
const validated = validateCustomerAndProductStep(input);
|
|
46
|
+
const wishlistItem = addToWishlistStep(validated);
|
|
47
|
+
return new workflows_sdk_1.WorkflowResponse({
|
|
48
|
+
wishlist_item: wishlistItem,
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
exports.default = exports.addToWishlistWorkflow;
|
|
52
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRkLXRvLXdpc2hsaXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3dvcmtmbG93cy9hZGQtdG8td2lzaGxpc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEscUVBSzBDO0FBQzFDLGtEQUFxRDtBQWtCckQsTUFBTSw4QkFBOEIsR0FBRyxJQUFBLDBCQUFVLEVBQy9DLCtCQUErQixFQUMvQixLQUFLLEVBQUUsS0FBeUIsRUFBRSxFQUFFLFNBQVMsRUFBRSxFQUFFLEVBQUU7SUFDakQsOENBQThDO0lBQzlDLE1BQU0sV0FBVyxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQ25DLGFBQWEsQ0FDb0IsQ0FBQTtJQUVuQyxNQUFNLGFBQWEsR0FBRztRQUNwQixRQUFRLEVBQUU7WUFDUixNQUFNLEVBQUUsQ0FBQyxJQUFJLENBQUM7WUFDZCxPQUFPLEVBQUU7Z0JBQ1AsRUFBRSxFQUFFLEtBQUssQ0FBQyxXQUFXO2FBQ3RCO1NBQ0Y7S0FDRixDQUFBO0lBRUQsTUFBTSxDQUFDLFFBQVEsQ0FBQyxHQUFHLE1BQU0sV0FBVyxDQUFDLGFBQWEsQ0FBQyxDQUFBO0lBRW5ELElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNkLE1BQU0sSUFBSSxLQUFLLENBQUMsb0JBQW9CLEtBQUssQ0FBQyxXQUFXLFlBQVksQ0FBQyxDQUFBO0lBQ3BFLENBQUM7SUFFRCw2Q0FBNkM7SUFDN0MsTUFBTSxZQUFZLEdBQUc7UUFDbkIsT0FBTyxFQUFFO1lBQ1AsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDO1lBQ2QsT0FBTyxFQUFFO2dCQUNQLEVBQUUsRUFBRSxLQUFLLENBQUMsVUFBVTthQUNyQjtTQUNGO0tBQ0YsQ0FBQTtJQUVELE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxNQUFNLFdBQVcsQ0FBQyxZQUFZLENBQUMsQ0FBQTtJQUVqRCxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDYixNQUFNLElBQUksS0FBSyxDQUFDLG1CQUFtQixLQUFLLENBQUMsVUFBVSxZQUFZLENBQUMsQ0FBQTtJQUNsRSxDQUFDO0lBRUQsT0FBTyxJQUFJLDRCQUFZLENBQUM7UUFDdEIsV0FBVyxFQUFFLEtBQUssQ0FBQyxXQUFXO1FBQzlCLFVBQVUsRUFBRSxLQUFLLENBQUMsVUFBVTtLQUM3QixDQUFDLENBQUE7QUFDSixDQUFDLENBQ0YsQ0FBQTtBQUVELE1BQU0saUJBQWlCLEdBQUcsSUFBQSwwQkFBVSxFQUNsQyxpQkFBaUIsRUFDakIsS0FBSyxFQUNILEtBQWtELEVBQ2xELEVBQUUsU0FBUyxFQUFFLEVBQ2IsRUFBRTtJQUNGLE1BQU0sZUFBZSxHQUEwQixTQUFTLENBQUMsT0FBTyxDQUM5RCwwQkFBZSxDQUNoQixDQUFBO0lBRUQsTUFBTSxZQUFZLEdBQUcsTUFBTSxlQUFlLENBQUMsYUFBYSxDQUN0RCxLQUFLLENBQUMsV0FBVyxFQUNqQixLQUFLLENBQUMsVUFBVSxDQUNqQixDQUFBO0lBRUQsT0FBTyxJQUFJLDRCQUFZLENBQUMsWUFBWSxDQUFDLENBQUE7QUFDdkMsQ0FBQyxDQUNGLENBQUE7QUFFWSxRQUFBLHFCQUFxQixHQUFHLElBQUEsOEJBQWMsRUFDakQsaUJBQWlCLEVBQ2pCLENBQUMsS0FBeUIsRUFBeUMsRUFBRTtJQUNuRSxNQUFNLFNBQVMsR0FBRyw4QkFBOEIsQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUN2RCxNQUFNLFlBQVksR0FBRyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsQ0FBQTtJQUVqRCxPQUFPLElBQUksZ0NBQWdCLENBQUM7UUFDMUIsYUFBYSxFQUFFLFlBQVk7S0FDNUIsQ0FBQyxDQUFBO0FBQ0osQ0FBQyxDQUNGLENBQUE7QUFFRCxrQkFBZSw2QkFBcUIsQ0FBQSJ9
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getWishlistWorkflow = void 0;
|
|
4
|
+
const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
|
|
5
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
6
|
+
const wishlist_1 = require("../modules/wishlist");
|
|
7
|
+
const fetchWishlistItemsStep = (0, workflows_sdk_1.createStep)("fetch-wishlist-items", async (input, { container }) => {
|
|
8
|
+
const wishlistService = container.resolve(wishlist_1.WISHLIST_MODULE);
|
|
9
|
+
const wishlist = await wishlistService.getWishlist(input.customer_id, input.options);
|
|
10
|
+
const includeDetails = input.options?.includeDetails ?? false;
|
|
11
|
+
// Convert to consistent format
|
|
12
|
+
let formattedWishlist;
|
|
13
|
+
if (includeDetails) {
|
|
14
|
+
formattedWishlist = wishlist.map((item) => ({
|
|
15
|
+
id: item.id,
|
|
16
|
+
product_id: item.product_id,
|
|
17
|
+
created_at: item.created_at,
|
|
18
|
+
}));
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
formattedWishlist = wishlist.map((product_id) => ({
|
|
22
|
+
product_id,
|
|
23
|
+
}));
|
|
24
|
+
}
|
|
25
|
+
return new workflows_sdk_1.StepResponse({
|
|
26
|
+
wishlist: formattedWishlist,
|
|
27
|
+
includeDetails,
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
const enrichWithProductDetailsStep = (0, workflows_sdk_1.createStep)("enrich-with-product-details", async (input, { container }) => {
|
|
31
|
+
if (!input.includeDetails || input.wishlist.length === 0) {
|
|
32
|
+
// Return as-is if no details needed or empty
|
|
33
|
+
return new workflows_sdk_1.StepResponse({ wishlist: input.wishlist });
|
|
34
|
+
}
|
|
35
|
+
// Get full wishlist items with product_id
|
|
36
|
+
const wishlistItems = input.wishlist;
|
|
37
|
+
const productIds = wishlistItems.map((item) => item.product_id);
|
|
38
|
+
// Fetch product details using remote query
|
|
39
|
+
const remoteQuery = container.resolve(utils_1.ContainerRegistrationKeys.REMOTE_QUERY);
|
|
40
|
+
const queryObject = (0, utils_1.remoteQueryObjectFromString)({
|
|
41
|
+
entryPoint: "product",
|
|
42
|
+
fields: [
|
|
43
|
+
"id",
|
|
44
|
+
"title",
|
|
45
|
+
"handle",
|
|
46
|
+
"description",
|
|
47
|
+
"thumbnail",
|
|
48
|
+
"status",
|
|
49
|
+
"created_at",
|
|
50
|
+
"updated_at",
|
|
51
|
+
],
|
|
52
|
+
variables: {
|
|
53
|
+
filters: {
|
|
54
|
+
id: productIds,
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
const products = await remoteQuery(queryObject);
|
|
59
|
+
// Create a map of product_id to product details
|
|
60
|
+
const productMap = new Map(products.map((product) => [product.id, product]));
|
|
61
|
+
// Merge wishlist items with product details
|
|
62
|
+
const enrichedWishlist = wishlistItems.map((item) => ({
|
|
63
|
+
id: item.id,
|
|
64
|
+
product_id: item.product_id,
|
|
65
|
+
product: productMap.get(item.product_id) || null,
|
|
66
|
+
created_at: item.created_at,
|
|
67
|
+
}));
|
|
68
|
+
return new workflows_sdk_1.StepResponse({ wishlist: enrichedWishlist });
|
|
69
|
+
});
|
|
70
|
+
exports.getWishlistWorkflow = (0, workflows_sdk_1.createWorkflow)("get-wishlist", (input) => {
|
|
71
|
+
const wishlistData = fetchWishlistItemsStep(input);
|
|
72
|
+
const enrichedWishlist = enrichWithProductDetailsStep(wishlistData);
|
|
73
|
+
return new workflows_sdk_1.WorkflowResponse({
|
|
74
|
+
wishlist: enrichedWishlist.wishlist,
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
exports.default = exports.getWishlistWorkflow;
|
|
78
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2V0LXdpc2hsaXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3dvcmtmbG93cy9nZXQtd2lzaGxpc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEscUVBSzBDO0FBQzFDLHFEQUdrQztBQUVsQyxrREFBcUQ7QUFvQnJELE1BQU0sc0JBQXNCLEdBQUcsSUFBQSwwQkFBVSxFQUN2QyxzQkFBc0IsRUFDdEIsS0FBSyxFQUFFLEtBQXVCLEVBQUUsRUFBRSxTQUFTLEVBQUUsRUFBRSxFQUFFO0lBQy9DLE1BQU0sZUFBZSxHQUEwQixTQUFTLENBQUMsT0FBTyxDQUM5RCwwQkFBZSxDQUNoQixDQUFBO0lBRUQsTUFBTSxRQUFRLEdBQUcsTUFBTSxlQUFlLENBQUMsV0FBVyxDQUNoRCxLQUFLLENBQUMsV0FBVyxFQUNqQixLQUFLLENBQUMsT0FBTyxDQUNkLENBQUE7SUFFRCxNQUFNLGNBQWMsR0FBRyxLQUFLLENBQUMsT0FBTyxFQUFFLGNBQWMsSUFBSSxLQUFLLENBQUE7SUFFN0QsK0JBQStCO0lBQy9CLElBQUksaUJBS0YsQ0FBQTtJQUVGLElBQUksY0FBYyxFQUFFLENBQUM7UUFDbkIsaUJBQWlCLEdBQUksUUFLbEIsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDakIsRUFBRSxFQUFFLElBQUksQ0FBQyxFQUFFO1lBQ1gsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVO1lBQzNCLFVBQVUsRUFBRSxJQUFJLENBQUMsVUFBVTtTQUM1QixDQUFDLENBQUMsQ0FBQTtJQUNMLENBQUM7U0FBTSxDQUFDO1FBQ04saUJBQWlCLEdBQUksUUFBcUIsQ0FBQyxHQUFHLENBQUMsQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDOUQsVUFBVTtTQUNYLENBQUMsQ0FBQyxDQUFBO0lBQ0wsQ0FBQztJQUVELE9BQU8sSUFBSSw0QkFBWSxDQUFDO1FBQ3RCLFFBQVEsRUFBRSxpQkFBaUI7UUFDM0IsY0FBYztLQUNmLENBQUMsQ0FBQTtBQUNKLENBQUMsQ0FDRixDQUFBO0FBRUQsTUFBTSw0QkFBNEIsR0FBRyxJQUFBLDBCQUFVLEVBQzdDLDZCQUE2QixFQUM3QixLQUFLLEVBQ0gsS0FHQyxFQUNELEVBQUUsU0FBUyxFQUFFLEVBQ2IsRUFBRTtJQUNGLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxJQUFJLEtBQUssQ0FBQyxRQUFRLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ3pELDZDQUE2QztRQUM3QyxPQUFPLElBQUksNEJBQVksQ0FBQyxFQUFFLFFBQVEsRUFBRSxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQTtJQUN2RCxDQUFDO0lBRUQsMENBQTBDO0lBQzFDLE1BQU0sYUFBYSxHQUFHLEtBQUssQ0FBQyxRQUsxQixDQUFBO0lBRUYsTUFBTSxVQUFVLEdBQUcsYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQW9CLENBQUMsQ0FBQTtJQUV6RSwyQ0FBMkM7SUFDM0MsTUFBTSxXQUFXLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FDbkMsaUNBQXlCLENBQUMsWUFBWSxDQUN2QyxDQUFBO0lBRUQsTUFBTSxXQUFXLEdBQUcsSUFBQSxtQ0FBMkIsRUFBQztRQUM5QyxVQUFVLEVBQUUsU0FBUztRQUNyQixNQUFNLEVBQUU7WUFDTixJQUFJO1lBQ0osT0FBTztZQUNQLFFBQVE7WUFDUixhQUFhO1lBQ2IsV0FBVztZQUNYLFFBQVE7WUFDUixZQUFZO1lBQ1osWUFBWTtTQUNiO1FBQ0QsU0FBUyxFQUFFO1lBQ1QsT0FBTyxFQUFFO2dCQUNQLEVBQUUsRUFBRSxVQUFVO2FBQ2Y7U0FDRjtLQUNGLENBQUMsQ0FBQTtJQUVGLE1BQU0sUUFBUSxHQUFHLE1BQU0sV0FBVyxDQUFDLFdBQVcsQ0FBQyxDQUFBO0lBRS9DLGdEQUFnRDtJQUNoRCxNQUFNLFVBQVUsR0FBRyxJQUFJLEdBQUcsQ0FDeEIsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQXVCLEVBQUUsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLEVBQUUsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUNqRSxDQUFBO0lBRUQsNENBQTRDO0lBQzVDLE1BQU0sZ0JBQWdCLEdBQUcsYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNwRCxFQUFFLEVBQUUsSUFBSSxDQUFDLEVBQUU7UUFDWCxVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQW9CO1FBQ3JDLE9BQU8sRUFBRSxVQUFVLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxVQUFvQixDQUFDLElBQUksSUFBSTtRQUMxRCxVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQVU7S0FDNUIsQ0FBQyxDQUFDLENBQUE7SUFFSCxPQUFPLElBQUksNEJBQVksQ0FBQyxFQUFFLFFBQVEsRUFBRSxnQkFBZ0IsRUFBRSxDQUFDLENBQUE7QUFDekQsQ0FBQyxDQUNGLENBQUE7QUFFWSxRQUFBLG1CQUFtQixHQUFHLElBQUEsOEJBQWMsRUFDL0MsY0FBYyxFQUNkLENBQUMsS0FBdUIsRUFBdUMsRUFBRTtJQUMvRCxNQUFNLFlBQVksR0FBRyxzQkFBc0IsQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUNsRCxNQUFNLGdCQUFnQixHQUFHLDRCQUE0QixDQUFDLFlBQVksQ0FBQyxDQUFBO0lBRW5FLE9BQU8sSUFBSSxnQ0FBZ0IsQ0FBQztRQUMxQixRQUFRLEVBQUUsZ0JBQWdCLENBQUMsUUFBUTtLQUNwQyxDQUFDLENBQUE7QUFDSixDQUFDLENBQ0YsQ0FBQTtBQUVELGtCQUFlLDJCQUFtQixDQUFBIn0=
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getWishlistWorkflow = exports.removeFromWishlistWorkflow = exports.addToWishlistWorkflow = void 0;
|
|
4
|
+
var add_to_wishlist_1 = require("./add-to-wishlist");
|
|
5
|
+
Object.defineProperty(exports, "addToWishlistWorkflow", { enumerable: true, get: function () { return add_to_wishlist_1.addToWishlistWorkflow; } });
|
|
6
|
+
var remove_from_wishlist_1 = require("./remove-from-wishlist");
|
|
7
|
+
Object.defineProperty(exports, "removeFromWishlistWorkflow", { enumerable: true, get: function () { return remove_from_wishlist_1.removeFromWishlistWorkflow; } });
|
|
8
|
+
var get_wishlist_1 = require("./get-wishlist");
|
|
9
|
+
Object.defineProperty(exports, "getWishlistWorkflow", { enumerable: true, get: function () { return get_wishlist_1.getWishlistWorkflow; } });
|
|
10
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvd29ya2Zsb3dzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHFEQUF5RDtBQUFoRCx3SEFBQSxxQkFBcUIsT0FBQTtBQUM5QiwrREFBbUU7QUFBMUQsa0lBQUEsMEJBQTBCLE9BQUE7QUFDbkMsK0NBQW9EO0FBQTNDLG1IQUFBLG1CQUFtQixPQUFBIn0=
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.removeFromWishlistWorkflow = void 0;
|
|
4
|
+
const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
|
|
5
|
+
const wishlist_1 = require("../modules/wishlist");
|
|
6
|
+
const validateWishlistItemExistsStep = (0, workflows_sdk_1.createStep)("validate-wishlist-item-exists", async (input, { container }) => {
|
|
7
|
+
const wishlistService = container.resolve(wishlist_1.WISHLIST_MODULE);
|
|
8
|
+
const exists = await wishlistService.isInWishlist(input.customer_id, input.product_id);
|
|
9
|
+
if (!exists) {
|
|
10
|
+
throw new Error(`Wishlist item not found for customer ${input.customer_id} and product ${input.product_id}`);
|
|
11
|
+
}
|
|
12
|
+
return new workflows_sdk_1.StepResponse({
|
|
13
|
+
customer_id: input.customer_id,
|
|
14
|
+
product_id: input.product_id,
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
const removeFromWishlistStep = (0, workflows_sdk_1.createStep)("remove-from-wishlist", async (input, { container }) => {
|
|
18
|
+
const wishlistService = container.resolve(wishlist_1.WISHLIST_MODULE);
|
|
19
|
+
await wishlistService.removeFromWishlist(input.customer_id, input.product_id);
|
|
20
|
+
return new workflows_sdk_1.StepResponse({ success: true });
|
|
21
|
+
});
|
|
22
|
+
exports.removeFromWishlistWorkflow = (0, workflows_sdk_1.createWorkflow)("remove-from-wishlist", (input) => {
|
|
23
|
+
const validated = validateWishlistItemExistsStep(input);
|
|
24
|
+
const result = removeFromWishlistStep(validated);
|
|
25
|
+
return new workflows_sdk_1.WorkflowResponse({
|
|
26
|
+
success: result.success,
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
exports.default = exports.removeFromWishlistWorkflow;
|
|
30
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVtb3ZlLWZyb20td2lzaGxpc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvd29ya2Zsb3dzL3JlbW92ZS1mcm9tLXdpc2hsaXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHFFQUswQztBQUMxQyxrREFBcUQ7QUFZckQsTUFBTSw4QkFBOEIsR0FBRyxJQUFBLDBCQUFVLEVBQy9DLCtCQUErQixFQUMvQixLQUFLLEVBQUUsS0FBOEIsRUFBRSxFQUFFLFNBQVMsRUFBRSxFQUFFLEVBQUU7SUFDdEQsTUFBTSxlQUFlLEdBQTBCLFNBQVMsQ0FBQyxPQUFPLENBQzlELDBCQUFlLENBQ2hCLENBQUE7SUFFRCxNQUFNLE1BQU0sR0FBRyxNQUFNLGVBQWUsQ0FBQyxZQUFZLENBQy9DLEtBQUssQ0FBQyxXQUFXLEVBQ2pCLEtBQUssQ0FBQyxVQUFVLENBQ2pCLENBQUE7SUFFRCxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDWixNQUFNLElBQUksS0FBSyxDQUNiLHdDQUF3QyxLQUFLLENBQUMsV0FBVyxnQkFBZ0IsS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUM1RixDQUFBO0lBQ0gsQ0FBQztJQUVELE9BQU8sSUFBSSw0QkFBWSxDQUFDO1FBQ3RCLFdBQVcsRUFBRSxLQUFLLENBQUMsV0FBVztRQUM5QixVQUFVLEVBQUUsS0FBSyxDQUFDLFVBQVU7S0FDN0IsQ0FBQyxDQUFBO0FBQ0osQ0FBQyxDQUNGLENBQUE7QUFFRCxNQUFNLHNCQUFzQixHQUFHLElBQUEsMEJBQVUsRUFDdkMsc0JBQXNCLEVBQ3RCLEtBQUssRUFDSCxLQUFrRCxFQUNsRCxFQUFFLFNBQVMsRUFBRSxFQUNiLEVBQUU7SUFDRixNQUFNLGVBQWUsR0FBMEIsU0FBUyxDQUFDLE9BQU8sQ0FDOUQsMEJBQWUsQ0FDaEIsQ0FBQTtJQUVELE1BQU0sZUFBZSxDQUFDLGtCQUFrQixDQUN0QyxLQUFLLENBQUMsV0FBVyxFQUNqQixLQUFLLENBQUMsVUFBVSxDQUNqQixDQUFBO0lBRUQsT0FBTyxJQUFJLDRCQUFZLENBQUMsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQTtBQUM1QyxDQUFDLENBQ0YsQ0FBQTtBQUVZLFFBQUEsMEJBQTBCLEdBQUcsSUFBQSw4QkFBYyxFQUN0RCxzQkFBc0IsRUFDdEIsQ0FDRSxLQUE4QixFQUNjLEVBQUU7SUFDOUMsTUFBTSxTQUFTLEdBQUcsOEJBQThCLENBQUMsS0FBSyxDQUFDLENBQUE7SUFDdkQsTUFBTSxNQUFNLEdBQUcsc0JBQXNCLENBQUMsU0FBUyxDQUFDLENBQUE7SUFFaEQsT0FBTyxJQUFJLGdDQUFnQixDQUFDO1FBQzFCLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTztLQUN4QixDQUFDLENBQUE7QUFDSixDQUFDLENBQ0YsQ0FBQTtBQUVELGtCQUFlLGtDQUEwQixDQUFBIn0=
|
package/README.md
CHANGED
|
@@ -215,6 +215,317 @@ Configure rating-based filtering:
|
|
|
215
215
|
- `max`: Maximum rating (0-5)
|
|
216
216
|
- `require_reviews`: Require at least one review
|
|
217
217
|
|
|
218
|
+
## Wishlist Feature
|
|
219
|
+
|
|
220
|
+
The plugin includes a comprehensive wishlist feature that allows customers to save products they're interested in and admins to view wishlist statistics.
|
|
221
|
+
|
|
222
|
+
### Module Registration
|
|
223
|
+
|
|
224
|
+
The wishlist module is automatically registered when you add the plugin to your Medusa configuration. No additional configuration is required for basic usage.
|
|
225
|
+
|
|
226
|
+
### Database Migration
|
|
227
|
+
|
|
228
|
+
After installing the plugin, generate and run the database migration:
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
npx medusa plugin:db:generate
|
|
232
|
+
npx medusa db:migrate
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
This will create the `wishlist` table with the following structure:
|
|
236
|
+
- `id`: Primary key
|
|
237
|
+
- `customer_id`: Customer identifier (searchable)
|
|
238
|
+
- `product_id`: Product identifier (searchable)
|
|
239
|
+
- `created_at`: Timestamp when item was added
|
|
240
|
+
- `updated_at`: Timestamp when item was last updated
|
|
241
|
+
|
|
242
|
+
The table enforces a unique constraint on the combination of `customer_id` and `product_id`, ensuring no duplicate entries.
|
|
243
|
+
|
|
244
|
+
### Store API Endpoints
|
|
245
|
+
|
|
246
|
+
#### Add Product to Wishlist
|
|
247
|
+
|
|
248
|
+
**POST** `/store/wishlist`
|
|
249
|
+
|
|
250
|
+
Add a product to the current customer's wishlist. The operation is idempotent - adding the same product multiple times will not create duplicates.
|
|
251
|
+
|
|
252
|
+
**Authentication**: Required (customer must be authenticated)
|
|
253
|
+
|
|
254
|
+
**Request Body**:
|
|
255
|
+
```json
|
|
256
|
+
{
|
|
257
|
+
"product_id": "prod_123"
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
**Response**:
|
|
262
|
+
```json
|
|
263
|
+
{
|
|
264
|
+
"wishlist_item": {
|
|
265
|
+
"id": "wish_123",
|
|
266
|
+
"customer_id": "cus_123",
|
|
267
|
+
"product_id": "prod_123",
|
|
268
|
+
"created_at": "2024-01-01T00:00:00.000Z",
|
|
269
|
+
"updated_at": "2024-01-01T00:00:00.000Z"
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
**Example**:
|
|
275
|
+
```bash
|
|
276
|
+
curl -X POST https://your-store.com/store/wishlist \
|
|
277
|
+
-H "Authorization: Bearer YOUR_TOKEN" \
|
|
278
|
+
-H "Content-Type: application/json" \
|
|
279
|
+
-d '{"product_id": "prod_123"}'
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
#### Remove Product from Wishlist
|
|
283
|
+
|
|
284
|
+
**DELETE** `/store/wishlist/:product_id`
|
|
285
|
+
|
|
286
|
+
Remove a product from the current customer's wishlist.
|
|
287
|
+
|
|
288
|
+
**Authentication**: Required (customer must be authenticated)
|
|
289
|
+
|
|
290
|
+
**Response**:
|
|
291
|
+
```json
|
|
292
|
+
{
|
|
293
|
+
"success": true
|
|
294
|
+
}
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
**Example**:
|
|
298
|
+
```bash
|
|
299
|
+
curl -X DELETE https://your-store.com/store/wishlist/prod_123 \
|
|
300
|
+
-H "Authorization: Bearer YOUR_TOKEN"
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
#### Get Customer Wishlist
|
|
304
|
+
|
|
305
|
+
**GET** `/store/wishlist`
|
|
306
|
+
|
|
307
|
+
Get the current customer's wishlist. Can return either product IDs only or full product details.
|
|
308
|
+
|
|
309
|
+
**Authentication**: Required (customer must be authenticated)
|
|
310
|
+
|
|
311
|
+
**Query Parameters**:
|
|
312
|
+
- `include_details` (boolean, default: `false`): If `true`, returns full product details. If `false`, returns only product IDs.
|
|
313
|
+
|
|
314
|
+
**Response (IDs only)**:
|
|
315
|
+
```json
|
|
316
|
+
{
|
|
317
|
+
"wishlist": [
|
|
318
|
+
{
|
|
319
|
+
"product_id": "prod_123"
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
"product_id": "prod_456"
|
|
323
|
+
}
|
|
324
|
+
]
|
|
325
|
+
}
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
**Response (with details)**:
|
|
329
|
+
```json
|
|
330
|
+
{
|
|
331
|
+
"wishlist": [
|
|
332
|
+
{
|
|
333
|
+
"id": "wish_123",
|
|
334
|
+
"product_id": "prod_123",
|
|
335
|
+
"product": {
|
|
336
|
+
"id": "prod_123",
|
|
337
|
+
"title": "Product Name",
|
|
338
|
+
"handle": "product-name",
|
|
339
|
+
"description": "Product description",
|
|
340
|
+
"thumbnail": "https://example.com/image.jpg",
|
|
341
|
+
"status": "published",
|
|
342
|
+
"created_at": "2024-01-01T00:00:00.000Z",
|
|
343
|
+
"updated_at": "2024-01-01T00:00:00.000Z"
|
|
344
|
+
},
|
|
345
|
+
"created_at": "2024-01-01T00:00:00.000Z"
|
|
346
|
+
}
|
|
347
|
+
]
|
|
348
|
+
}
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
**Example**:
|
|
352
|
+
```bash
|
|
353
|
+
# Get only product IDs
|
|
354
|
+
curl https://your-store.com/store/wishlist \
|
|
355
|
+
-H "Authorization: Bearer YOUR_TOKEN"
|
|
356
|
+
|
|
357
|
+
# Get full product details
|
|
358
|
+
curl "https://your-store.com/store/wishlist?include_details=true" \
|
|
359
|
+
-H "Authorization: Bearer YOUR_TOKEN"
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### Admin API Endpoints
|
|
363
|
+
|
|
364
|
+
#### Get Wishlist Statistics
|
|
365
|
+
|
|
366
|
+
**GET** `/admin/wishlist/stats`
|
|
367
|
+
|
|
368
|
+
Get wishlist statistics showing how many users have added each product to their wishlist.
|
|
369
|
+
|
|
370
|
+
**Authentication**: Required (admin authentication)
|
|
371
|
+
|
|
372
|
+
**Query Parameters**:
|
|
373
|
+
- `product_id` (string, optional): If provided, returns the wishlist count for that specific product only.
|
|
374
|
+
|
|
375
|
+
**Response (all products)**:
|
|
376
|
+
```json
|
|
377
|
+
{
|
|
378
|
+
"stats": [
|
|
379
|
+
{
|
|
380
|
+
"product_id": "prod_123",
|
|
381
|
+
"wishlist_count": 42
|
|
382
|
+
},
|
|
383
|
+
{
|
|
384
|
+
"product_id": "prod_456",
|
|
385
|
+
"wishlist_count": 15
|
|
386
|
+
}
|
|
387
|
+
]
|
|
388
|
+
}
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
**Response (single product)**:
|
|
392
|
+
```json
|
|
393
|
+
{
|
|
394
|
+
"product_id": "prod_123",
|
|
395
|
+
"wishlist_count": 42
|
|
396
|
+
}
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
**Example**:
|
|
400
|
+
```bash
|
|
401
|
+
# Get statistics for all products
|
|
402
|
+
curl https://your-store.com/admin/wishlist/stats \
|
|
403
|
+
-H "Authorization: Bearer ADMIN_TOKEN"
|
|
404
|
+
|
|
405
|
+
# Get statistics for a specific product
|
|
406
|
+
curl "https://your-store.com/admin/wishlist/stats?product_id=prod_123" \
|
|
407
|
+
-H "Authorization: Bearer ADMIN_TOKEN"
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### Helper Function
|
|
411
|
+
|
|
412
|
+
The plugin provides a helper function that can be used directly by UI components without implementing the entire logic.
|
|
413
|
+
|
|
414
|
+
#### Import the Helper
|
|
415
|
+
|
|
416
|
+
```typescript
|
|
417
|
+
import { getWishlist } from "medusa-product-helper/wishlist-helper"
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
#### Usage Examples
|
|
421
|
+
|
|
422
|
+
**Get only product IDs**:
|
|
423
|
+
```typescript
|
|
424
|
+
import { getWishlist } from "medusa-product-helper/wishlist-helper"
|
|
425
|
+
|
|
426
|
+
// In your component or service
|
|
427
|
+
const productIds = await getWishlist(container, customerId)
|
|
428
|
+
// Returns: ['prod_123', 'prod_456']
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
**Get full product details**:
|
|
432
|
+
```typescript
|
|
433
|
+
import { getWishlist } from "medusa-product-helper/wishlist-helper"
|
|
434
|
+
|
|
435
|
+
const wishlist = await getWishlist(container, customerId, {
|
|
436
|
+
includeDetails: true
|
|
437
|
+
})
|
|
438
|
+
// Returns: [
|
|
439
|
+
// {
|
|
440
|
+
// product_id: 'prod_123',
|
|
441
|
+
// product: { ... },
|
|
442
|
+
// id: 'wish_123',
|
|
443
|
+
// created_at: Date
|
|
444
|
+
// },
|
|
445
|
+
// ...
|
|
446
|
+
// ]
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
**Filter by specific products**:
|
|
450
|
+
```typescript
|
|
451
|
+
import { getWishlist } from "medusa-product-helper/wishlist-helper"
|
|
452
|
+
|
|
453
|
+
const wishlist = await getWishlist(container, customerId, {
|
|
454
|
+
includeDetails: true,
|
|
455
|
+
productIds: ['prod_123', 'prod_456']
|
|
456
|
+
})
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
#### Helper Options
|
|
460
|
+
|
|
461
|
+
- `includeDetails` (boolean, default: `false`): If `true`, returns full product details. If `false`, returns only product IDs.
|
|
462
|
+
- `productIds` (string[], optional): Filter wishlist by specific product IDs.
|
|
463
|
+
|
|
464
|
+
### Using Workflows Directly
|
|
465
|
+
|
|
466
|
+
You can also use the workflows directly in your custom code:
|
|
467
|
+
|
|
468
|
+
```typescript
|
|
469
|
+
import { addToWishlistWorkflow } from "medusa-product-helper/workflows"
|
|
470
|
+
import { removeFromWishlistWorkflow } from "medusa-product-helper/workflows"
|
|
471
|
+
import { getWishlistWorkflow } from "medusa-product-helper/workflows"
|
|
472
|
+
|
|
473
|
+
// Add to wishlist
|
|
474
|
+
const { result } = await addToWishlistWorkflow(container).run({
|
|
475
|
+
input: {
|
|
476
|
+
customer_id: "cus_123",
|
|
477
|
+
product_id: "prod_123"
|
|
478
|
+
}
|
|
479
|
+
})
|
|
480
|
+
|
|
481
|
+
// Remove from wishlist
|
|
482
|
+
const { result } = await removeFromWishlistWorkflow(container).run({
|
|
483
|
+
input: {
|
|
484
|
+
customer_id: "cus_123",
|
|
485
|
+
product_id: "prod_123"
|
|
486
|
+
}
|
|
487
|
+
})
|
|
488
|
+
|
|
489
|
+
// Get wishlist
|
|
490
|
+
const { result } = await getWishlistWorkflow(container).run({
|
|
491
|
+
input: {
|
|
492
|
+
customer_id: "cus_123",
|
|
493
|
+
options: {
|
|
494
|
+
includeDetails: true
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
})
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
### Using the Module Service Directly
|
|
501
|
+
|
|
502
|
+
You can also access the wishlist module service directly:
|
|
503
|
+
|
|
504
|
+
```typescript
|
|
505
|
+
import { WISHLIST_MODULE } from "medusa-product-helper/modules/wishlist"
|
|
506
|
+
import type { WishlistModuleService } from "medusa-product-helper/modules/wishlist"
|
|
507
|
+
|
|
508
|
+
// In your route or service
|
|
509
|
+
const wishlistService: WishlistModuleService = container.resolve(WISHLIST_MODULE)
|
|
510
|
+
|
|
511
|
+
// Add to wishlist
|
|
512
|
+
await wishlistService.addToWishlist(customerId, productId)
|
|
513
|
+
|
|
514
|
+
// Remove from wishlist
|
|
515
|
+
await wishlistService.removeFromWishlist(customerId, productId)
|
|
516
|
+
|
|
517
|
+
// Get wishlist
|
|
518
|
+
const wishlist = await wishlistService.getWishlist(customerId, {
|
|
519
|
+
includeDetails: true
|
|
520
|
+
})
|
|
521
|
+
|
|
522
|
+
// Check if product is in wishlist
|
|
523
|
+
const isInWishlist = await wishlistService.isInWishlist(customerId, productId)
|
|
524
|
+
|
|
525
|
+
// Get wishlist counts (for admin)
|
|
526
|
+
const counts = await wishlistService.getWishlistCounts(['prod_123', 'prod_456'])
|
|
527
|
+
```
|
|
528
|
+
|
|
218
529
|
## Getting Started
|
|
219
530
|
|
|
220
531
|
Visit the [Quickstart Guide](https://docs.medusajs.com/learn/installation) to set up a server.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "medusa-product-helper",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "A starter for Medusa plugins.",
|
|
5
5
|
"author": "Medusa (https://medusajs.com)",
|
|
6
6
|
"license": "MIT",
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"./.medusa/server/src/modules/*": "./.medusa/server/src/modules/*/index.js",
|
|
14
14
|
"./modules/*": "./.medusa/server/src/modules/*/index.js",
|
|
15
15
|
"./providers/*": "./.medusa/server/src/providers/*/index.js",
|
|
16
|
+
"./wishlist-helper": "./.medusa/server/src/shared/wishlist/index.js",
|
|
16
17
|
"./*": "./.medusa/server/src/*.js",
|
|
17
18
|
"./admin": {
|
|
18
19
|
"import": "./.medusa/server/src/admin/index.mjs",
|