@lodashventure/medusa-collection-thumbnail 1.1.5 → 1.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.medusa/server/src/admin/index.js +2 -177
- package/.medusa/server/src/admin/index.mjs +4 -179
- package/.medusa/server/src/api/admin/collections/[id]/thumbnail/route.js +211 -0
- package/.medusa/server/{api → src/api}/middlewares.js +1 -1
- package/.medusa/server/src/api/store/collections/[id]/route.js +43 -0
- package/.medusa/server/src/api/store/collections/route.js +71 -0
- package/.medusa/server/src/index.js +15 -0
- package/.medusa/server/{modules → src/modules}/collection/index.js +1 -1
- package/.medusa/server/{modules/collection/migrations/Migration20250921062957.js → src/modules/collection/migrations/Migration20251108000000.js} +4 -4
- package/.medusa/server/{modules → src/modules}/collection/models/collection.js +1 -1
- package/.medusa/server/{modules → src/modules}/collection/service.js +1 -1
- package/.medusa/server/src/services/gcs-direct-upload.js +56 -0
- package/.medusa/server/src/workflows/upload-collection-thumbnail.js +59 -0
- package/README.md +32 -34
- package/package.json +16 -16
- package/.medusa/server/api/admin/collections/[id]/thumbnail/route.d.ts +0 -8
- package/.medusa/server/api/admin/collections/[id]/thumbnail/route.js +0 -211
- package/.medusa/server/api/middlewares.d.ts +0 -2
- package/.medusa/server/api/store/collections/[id]/route.d.ts +0 -2
- package/.medusa/server/api/store/collections/[id]/route.js +0 -46
- package/.medusa/server/api/store/collections/route.d.ts +0 -2
- package/.medusa/server/api/store/collections/route.js +0 -71
- package/.medusa/server/index.d.ts +0 -2
- package/.medusa/server/index.js +0 -8
- package/.medusa/server/links/collection-thumbnail.d.ts +0 -2
- package/.medusa/server/links/collection-thumbnail.js +0 -16
- package/.medusa/server/modules/collection/index.d.ts +0 -21
- package/.medusa/server/modules/collection/migrations/Migration20250921062957.d.ts +0 -5
- package/.medusa/server/modules/collection/models/collection.d.ts +0 -5
- package/.medusa/server/modules/collection/service.d.ts +0 -10
- package/.medusa/server/services/gcs-direct-upload.d.ts +0 -8
- package/.medusa/server/services/gcs-direct-upload.js +0 -59
- package/.medusa/server/workflows/upload-collection-thumbnail.d.ts +0 -13
- package/.medusa/server/workflows/upload-collection-thumbnail.js +0 -59
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GET = void 0;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const GET = async (req, res) => {
|
|
6
|
+
const { id } = req.params;
|
|
7
|
+
const productModuleService = req.scope.resolve(utils_1.Modules.PRODUCT);
|
|
8
|
+
const collectionCustomService = req.scope.resolve("collectionCustom");
|
|
9
|
+
try {
|
|
10
|
+
// Retrieve collection from Medusa's default service
|
|
11
|
+
const collection = await productModuleService.retrieveProductCollection(id);
|
|
12
|
+
if (!collection) {
|
|
13
|
+
return res.status(404).json({ error: "Collection not found" });
|
|
14
|
+
}
|
|
15
|
+
// Retrieve custom data (thumbnail)
|
|
16
|
+
const customData = await collectionCustomService
|
|
17
|
+
.listProductCollectionCustoms({
|
|
18
|
+
collection_id: id,
|
|
19
|
+
})
|
|
20
|
+
.then((result) => result[0]);
|
|
21
|
+
// Enrich collection with thumbnail
|
|
22
|
+
const enrichedCollection = {
|
|
23
|
+
id: collection.id,
|
|
24
|
+
title: collection.title,
|
|
25
|
+
handle: collection.handle,
|
|
26
|
+
thumbnail: customData?.thumbnail || null,
|
|
27
|
+
created_at: collection.created_at,
|
|
28
|
+
updated_at: collection.updated_at,
|
|
29
|
+
};
|
|
30
|
+
return res.json({
|
|
31
|
+
collection: enrichedCollection,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
console.error("Error fetching collection:", error);
|
|
36
|
+
return res.status(500).json({
|
|
37
|
+
error: "Failed to fetch collection",
|
|
38
|
+
message: error.message
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
exports.GET = GET;
|
|
43
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL3N0b3JlL2NvbGxlY3Rpb25zL1tpZF0vcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBSUEscURBQW9EO0FBRzdDLE1BQU0sR0FBRyxHQUFHLEtBQUssRUFDdEIsR0FBa0IsRUFDbEIsR0FBbUIsRUFDbkIsRUFBRTtJQUNGLE1BQU0sRUFBRSxFQUFFLEVBQUUsR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDO0lBQzFCLE1BQU0sb0JBQW9CLEdBQTBCLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUNuRSxlQUFPLENBQUMsT0FBTyxDQUNoQixDQUFDO0lBQ0YsTUFBTSx1QkFBdUIsR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBUSxDQUFDO0lBRTdFLElBQUksQ0FBQztRQUNILG9EQUFvRDtRQUNwRCxNQUFNLFVBQVUsR0FBRyxNQUFNLG9CQUFvQixDQUFDLHlCQUF5QixDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBRTVFLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUNoQixPQUFPLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLHNCQUFzQixFQUFFLENBQUMsQ0FBQztRQUNqRSxDQUFDO1FBRUQsbUNBQW1DO1FBQ25DLE1BQU0sVUFBVSxHQUFHLE1BQU0sdUJBQXVCO2FBQzdDLDRCQUE0QixDQUFDO1lBQzVCLGFBQWEsRUFBRSxFQUFFO1NBQ2xCLENBQUM7YUFDRCxJQUFJLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRS9CLG1DQUFtQztRQUNuQyxNQUFNLGtCQUFrQixHQUFHO1lBQ3pCLEVBQUUsRUFBRSxVQUFVLENBQUMsRUFBRTtZQUNqQixLQUFLLEVBQUUsVUFBVSxDQUFDLEtBQUs7WUFDdkIsTUFBTSxFQUFFLFVBQVUsQ0FBQyxNQUFNO1lBQ3pCLFNBQVMsRUFBRSxVQUFVLEVBQUUsU0FBUyxJQUFJLElBQUk7WUFDeEMsVUFBVSxFQUFFLFVBQVUsQ0FBQyxVQUFVO1lBQ2pDLFVBQVUsRUFBRSxVQUFVLENBQUMsVUFBVTtTQUNsQyxDQUFDO1FBRUYsT0FBTyxHQUFHLENBQUMsSUFBSSxDQUFDO1lBQ2QsVUFBVSxFQUFFLGtCQUFrQjtTQUMvQixDQUFDLENBQUM7SUFDTCxDQUFDO0lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztRQUNmLE9BQU8sQ0FBQyxLQUFLLENBQUMsNEJBQTRCLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDbkQsT0FBTyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQztZQUMxQixLQUFLLEVBQUUsNEJBQTRCO1lBQ25DLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTztTQUN2QixDQUFDLENBQUM7SUFDTCxDQUFDO0FBQ0gsQ0FBQyxDQUFDO0FBN0NXLFFBQUEsR0FBRyxPQTZDZCJ9
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GET = void 0;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const GET = async (req, res) => {
|
|
6
|
+
const productModuleService = req.scope.resolve(utils_1.Modules.PRODUCT);
|
|
7
|
+
const collectionCustomService = req.scope.resolve("collectionCustom");
|
|
8
|
+
try {
|
|
9
|
+
// Parse query parameters
|
|
10
|
+
const limit = parseInt(req.query.limit) || 10;
|
|
11
|
+
const offset = parseInt(req.query.offset) || 0;
|
|
12
|
+
const handle = req.query.handle;
|
|
13
|
+
const created_at = req.query.created_at;
|
|
14
|
+
const updated_at = req.query.updated_at;
|
|
15
|
+
// Build filters for collections
|
|
16
|
+
const filters = {};
|
|
17
|
+
if (handle) {
|
|
18
|
+
filters.handle = handle;
|
|
19
|
+
}
|
|
20
|
+
if (created_at) {
|
|
21
|
+
filters.created_at = created_at;
|
|
22
|
+
}
|
|
23
|
+
if (updated_at) {
|
|
24
|
+
filters.updated_at = updated_at;
|
|
25
|
+
}
|
|
26
|
+
// Retrieve collections from Medusa's default service
|
|
27
|
+
const [collections, count] = await productModuleService.listAndCountProductCollections(filters, {
|
|
28
|
+
skip: offset,
|
|
29
|
+
take: limit,
|
|
30
|
+
order: { created_at: "DESC" },
|
|
31
|
+
});
|
|
32
|
+
// Get all collection IDs
|
|
33
|
+
const collectionIds = collections.map(c => c.id);
|
|
34
|
+
// Retrieve custom data (thumbnails) for all collections
|
|
35
|
+
let customDataMap = {};
|
|
36
|
+
if (collectionIds.length > 0) {
|
|
37
|
+
const customData = await collectionCustomService.listProductCollectionCustoms({
|
|
38
|
+
collection_id: collectionIds,
|
|
39
|
+
});
|
|
40
|
+
// Create a map for quick lookup
|
|
41
|
+
customDataMap = customData.reduce((acc, custom) => {
|
|
42
|
+
acc[custom.collection_id] = custom.thumbnail;
|
|
43
|
+
return acc;
|
|
44
|
+
}, {});
|
|
45
|
+
}
|
|
46
|
+
// Enrich collections with thumbnails
|
|
47
|
+
const enrichedCollections = collections.map(collection => ({
|
|
48
|
+
id: collection.id,
|
|
49
|
+
title: collection.title,
|
|
50
|
+
handle: collection.handle,
|
|
51
|
+
thumbnail: customDataMap[collection.id] || null,
|
|
52
|
+
created_at: collection.created_at,
|
|
53
|
+
updated_at: collection.updated_at,
|
|
54
|
+
}));
|
|
55
|
+
return res.json({
|
|
56
|
+
collections: enrichedCollections,
|
|
57
|
+
count,
|
|
58
|
+
offset,
|
|
59
|
+
limit,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
console.error("Error fetching collections:", error);
|
|
64
|
+
return res.status(500).json({
|
|
65
|
+
error: "Failed to fetch collections",
|
|
66
|
+
message: error.message
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
exports.GET = GET;
|
|
71
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL3N0b3JlL2NvbGxlY3Rpb25zL3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUlBLHFEQUFvRDtBQUc3QyxNQUFNLEdBQUcsR0FBRyxLQUFLLEVBQ3RCLEdBQWtCLEVBQ2xCLEdBQW1CLEVBQ25CLEVBQUU7SUFDRixNQUFNLG9CQUFvQixHQUEwQixHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FDbkUsZUFBTyxDQUFDLE9BQU8sQ0FDaEIsQ0FBQztJQUNGLE1BQU0sdUJBQXVCLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsa0JBQWtCLENBQVEsQ0FBQztJQUU3RSxJQUFJLENBQUM7UUFDSCx5QkFBeUI7UUFDekIsTUFBTSxLQUFLLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsS0FBZSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3hELE1BQU0sTUFBTSxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLE1BQWdCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDekQsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxNQUFnQixDQUFDO1FBQzFDLE1BQU0sVUFBVSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsVUFBaUIsQ0FBQztRQUMvQyxNQUFNLFVBQVUsR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLFVBQWlCLENBQUM7UUFFL0MsZ0NBQWdDO1FBQ2hDLE1BQU0sT0FBTyxHQUFRLEVBQUUsQ0FBQztRQUN4QixJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ1gsT0FBTyxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDMUIsQ0FBQztRQUNELElBQUksVUFBVSxFQUFFLENBQUM7WUFDZixPQUFPLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQztRQUNsQyxDQUFDO1FBQ0QsSUFBSSxVQUFVLEVBQUUsQ0FBQztZQUNmLE9BQU8sQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDO1FBQ2xDLENBQUM7UUFFRCxxREFBcUQ7UUFDckQsTUFBTSxDQUFDLFdBQVcsRUFBRSxLQUFLLENBQUMsR0FBRyxNQUFNLG9CQUFvQixDQUFDLDhCQUE4QixDQUNwRixPQUFPLEVBQ1A7WUFDRSxJQUFJLEVBQUUsTUFBTTtZQUNaLElBQUksRUFBRSxLQUFLO1lBQ1gsS0FBSyxFQUFFLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRTtTQUM5QixDQUNGLENBQUM7UUFFRix5QkFBeUI7UUFDekIsTUFBTSxhQUFhLEdBQUcsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUVqRCx3REFBd0Q7UUFDeEQsSUFBSSxhQUFhLEdBQWtDLEVBQUUsQ0FBQztRQUN0RCxJQUFJLGFBQWEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDN0IsTUFBTSxVQUFVLEdBQUcsTUFBTSx1QkFBdUIsQ0FBQyw0QkFBNEIsQ0FBQztnQkFDNUUsYUFBYSxFQUFFLGFBQWE7YUFDN0IsQ0FBQyxDQUFDO1lBRUgsZ0NBQWdDO1lBQ2hDLGFBQWEsR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBRSxFQUFFO2dCQUNoRCxHQUFHLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUM7Z0JBQzdDLE9BQU8sR0FBRyxDQUFDO1lBQ2IsQ0FBQyxFQUFFLEVBQW1DLENBQUMsQ0FBQztRQUMxQyxDQUFDO1FBRUQscUNBQXFDO1FBQ3JDLE1BQU0sbUJBQW1CLEdBQUcsV0FBVyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDekQsRUFBRSxFQUFFLFVBQVUsQ0FBQyxFQUFFO1lBQ2pCLEtBQUssRUFBRSxVQUFVLENBQUMsS0FBSztZQUN2QixNQUFNLEVBQUUsVUFBVSxDQUFDLE1BQU07WUFDekIsU0FBUyxFQUFFLGFBQWEsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLElBQUksSUFBSTtZQUMvQyxVQUFVLEVBQUUsVUFBVSxDQUFDLFVBQVU7WUFDakMsVUFBVSxFQUFFLFVBQVUsQ0FBQyxVQUFVO1NBQ2xDLENBQUMsQ0FBQyxDQUFDO1FBRUosT0FBTyxHQUFHLENBQUMsSUFBSSxDQUFDO1lBQ2QsV0FBVyxFQUFFLG1CQUFtQjtZQUNoQyxLQUFLO1lBQ0wsTUFBTTtZQUNOLEtBQUs7U0FDTixDQUFDLENBQUM7SUFDTCxDQUFDO0lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztRQUNmLE9BQU8sQ0FBQyxLQUFLLENBQUMsNkJBQTZCLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDcEQsT0FBTyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQztZQUMxQixLQUFLLEVBQUUsNkJBQTZCO1lBQ3BDLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTztTQUN2QixDQUFDLENBQUM7SUFDTCxDQUFDO0FBQ0gsQ0FBQyxDQUFDO0FBL0VXLFFBQUEsR0FBRyxPQStFZCJ9
|
|
@@ -0,0 +1,15 @@
|
|
|
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.COLLECTION_MODULE = exports.CollectionModule = void 0;
|
|
7
|
+
const collection_1 = __importDefault(require("./modules/collection"));
|
|
8
|
+
exports.CollectionModule = collection_1.default;
|
|
9
|
+
// Export the module so MedusaJS can load it
|
|
10
|
+
exports.default = {
|
|
11
|
+
modules: [collection_1.default],
|
|
12
|
+
};
|
|
13
|
+
var collection_2 = require("./modules/collection");
|
|
14
|
+
Object.defineProperty(exports, "COLLECTION_MODULE", { enumerable: true, get: function () { return collection_2.COLLECTION_MODULE; } });
|
|
15
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsc0VBQW9EO0FBUTNDLDJCQVJGLG9CQUFnQixDQVFFO0FBTnpCLDRDQUE0QztBQUM1QyxrQkFBZTtJQUNiLE9BQU8sRUFBRSxDQUFDLG9CQUFnQixDQUFDO0NBQzVCLENBQUM7QUFJRixtREFBeUQ7QUFBaEQsK0dBQUEsaUJBQWlCLE9BQUEifQ==
|
|
@@ -10,4 +10,4 @@ exports.COLLECTION_MODULE = "collectionCustom";
|
|
|
10
10
|
exports.default = (0, utils_1.Module)(exports.COLLECTION_MODULE, {
|
|
11
11
|
service: service_1.default,
|
|
12
12
|
});
|
|
13
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
13
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbW9kdWxlcy9jb2xsZWN0aW9uL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLHFEQUFtRDtBQUNuRCx3REFBZ0Q7QUFFbkMsUUFBQSxpQkFBaUIsR0FBRyxrQkFBa0IsQ0FBQztBQUVwRCxrQkFBZSxJQUFBLGNBQU0sRUFBQyx5QkFBaUIsRUFBRTtJQUN2QyxPQUFPLEVBQUUsaUJBQXVCO0NBQ2pDLENBQUMsQ0FBQyJ9
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.Migration20251108000000 = void 0;
|
|
4
4
|
const migrations_1 = require("@medusajs/framework/mikro-orm/migrations");
|
|
5
|
-
class
|
|
5
|
+
class Migration20251108000000 extends migrations_1.Migration {
|
|
6
6
|
async up() {
|
|
7
7
|
this.addSql(`alter table if exists "product_collection_custom" drop constraint if exists "product_collection_custom_collection_id_unique";`);
|
|
8
8
|
this.addSql(`create table if not exists "product_collection_custom" ("id" text not null, "collection_id" text not null, "thumbnail" text null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "product_collection_custom_pkey" primary key ("id"));`);
|
|
@@ -14,5 +14,5 @@ class Migration20250921062957 extends migrations_1.Migration {
|
|
|
14
14
|
this.addSql(`drop table if exists "product_collection_custom" cascade;`);
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
|
-
exports.
|
|
18
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
17
|
+
exports.Migration20251108000000 = Migration20251108000000;
|
|
18
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTWlncmF0aW9uMjAyNTExMDgwMDAwMDAuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbW9kdWxlcy9jb2xsZWN0aW9uL21pZ3JhdGlvbnMvTWlncmF0aW9uMjAyNTExMDgwMDAwMDAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEseUVBQXFFO0FBRXJFLE1BQWEsdUJBQXdCLFNBQVEsc0JBQVM7SUFFM0MsS0FBSyxDQUFDLEVBQUU7UUFDZixJQUFJLENBQUMsTUFBTSxDQUFDLCtIQUErSCxDQUFDLENBQUM7UUFDN0ksSUFBSSxDQUFDLE1BQU0sQ0FBQyxxVUFBcVUsQ0FBQyxDQUFDO1FBQ25WLElBQUksQ0FBQyxNQUFNLENBQUMsaUtBQWlLLENBQUMsQ0FBQztRQUMvSyxJQUFJLENBQUMsTUFBTSxDQUFDLDZJQUE2SSxDQUFDLENBQUM7UUFDM0osSUFBSSxDQUFDLE1BQU0sQ0FBQyxtSkFBbUosQ0FBQyxDQUFDO0lBQ25LLENBQUM7SUFFUSxLQUFLLENBQUMsSUFBSTtRQUNqQixJQUFJLENBQUMsTUFBTSxDQUFDLDJEQUEyRCxDQUFDLENBQUM7SUFDM0UsQ0FBQztDQUVGO0FBZEQsMERBY0MifQ==
|
|
@@ -13,4 +13,4 @@ exports.ProductCollectionCustom = utils_1.model
|
|
|
13
13
|
on: ["collection_id"],
|
|
14
14
|
},
|
|
15
15
|
]);
|
|
16
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
16
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sbGVjdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9tb2R1bGVzL2NvbGxlY3Rpb24vbW9kZWxzL2NvbGxlY3Rpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEscURBQWtEO0FBRXJDLFFBQUEsdUJBQXVCLEdBQUcsYUFBSztLQUN6QyxNQUFNLENBQUMsMkJBQTJCLEVBQUU7SUFDbkMsRUFBRSxFQUFFLGFBQUssQ0FBQyxFQUFFLEVBQUUsQ0FBQyxVQUFVLEVBQUU7SUFDM0IsYUFBYSxFQUFFLGFBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxNQUFNLEVBQUU7SUFDcEMsU0FBUyxFQUFFLGFBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxRQUFRLEVBQUU7Q0FDbkMsQ0FBQztLQUNELE9BQU8sQ0FBQztJQUNQO1FBQ0UsRUFBRSxFQUFFLENBQUMsZUFBZSxDQUFDO0tBQ3RCO0NBQ0YsQ0FBQyxDQUFDIn0=
|
|
@@ -7,4 +7,4 @@ class CollectionModuleService extends (0, utils_1.MedusaService)({
|
|
|
7
7
|
}) {
|
|
8
8
|
}
|
|
9
9
|
exports.default = CollectionModuleService;
|
|
10
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
10
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9tb2R1bGVzL2NvbGxlY3Rpb24vc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHFEQUEwRDtBQUMxRCxvREFBOEQ7QUFFOUQsTUFBcUIsdUJBQXdCLFNBQVEsSUFBQSxxQkFBYSxFQUFDO0lBQ2pFLHVCQUF1QixFQUF2QixvQ0FBdUI7Q0FDeEIsQ0FBQztDQUFHO0FBRkwsMENBRUsifQ==
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GcsDirectUploadService = void 0;
|
|
4
|
+
const storage_1 = require("@google-cloud/storage");
|
|
5
|
+
class GcsDirectUploadService {
|
|
6
|
+
constructor() {
|
|
7
|
+
// Initialize GCS client with credentials from env
|
|
8
|
+
this.storage = new storage_1.Storage({
|
|
9
|
+
credentials: {
|
|
10
|
+
client_email: process.env.CLIENT_EMAIL,
|
|
11
|
+
private_key: process.env.PRIVATE_KEY.replace(/\\n/g, '\n'),
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
this.bucketName = process.env.BUCKET_NAME || 'sangaroon';
|
|
15
|
+
this.baseUrl = (process.env.GCP_STORAGE_BASE_PUBLIC_URL || 'https://storage.cloud.google.com').replace(/\/+$/, '');
|
|
16
|
+
}
|
|
17
|
+
async uploadFile(filename, buffer, mimeType) {
|
|
18
|
+
try {
|
|
19
|
+
const bucket = this.storage.bucket(this.bucketName);
|
|
20
|
+
const file = bucket.file(filename);
|
|
21
|
+
await file.save(buffer, {
|
|
22
|
+
metadata: {
|
|
23
|
+
contentType: mimeType,
|
|
24
|
+
},
|
|
25
|
+
public: true,
|
|
26
|
+
resumable: false,
|
|
27
|
+
});
|
|
28
|
+
// Return the public URL
|
|
29
|
+
const sanitizedFilename = filename.replace(/^\/+/, '');
|
|
30
|
+
const baseWithBucket = this.baseUrl.endsWith(`/${this.bucketName}`)
|
|
31
|
+
? this.baseUrl
|
|
32
|
+
: `${this.baseUrl}/${this.bucketName}`;
|
|
33
|
+
return `${baseWithBucket}/${sanitizedFilename}`;
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
console.error('Error uploading to GCS:', error);
|
|
37
|
+
throw new Error(`Failed to upload file to GCS: ${error.message}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
async deleteFile(filename) {
|
|
41
|
+
try {
|
|
42
|
+
const bucket = this.storage.bucket(this.bucketName);
|
|
43
|
+
const file = bucket.file(filename);
|
|
44
|
+
const [exists] = await file.exists();
|
|
45
|
+
if (exists) {
|
|
46
|
+
await file.delete();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
console.error('Error deleting from GCS:', error);
|
|
51
|
+
// Don't throw on delete errors
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
exports.GcsDirectUploadService = GcsDirectUploadService;
|
|
56
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2NzLWRpcmVjdC11cGxvYWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvc2VydmljZXMvZ2NzLWRpcmVjdC11cGxvYWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsbURBQWdEO0FBRWhELE1BQWEsc0JBQXNCO0lBS2pDO1FBQ0Usa0RBQWtEO1FBQ2xELElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxpQkFBTyxDQUFDO1lBQ3pCLFdBQVcsRUFBRTtnQkFDWCxZQUFZLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxZQUFhO2dCQUN2QyxXQUFXLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxXQUFZLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUM7YUFDNUQ7U0FDRixDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsVUFBVSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsV0FBVyxJQUFJLFdBQVcsQ0FBQztRQUN6RCxJQUFJLENBQUMsT0FBTyxHQUFHLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQywyQkFBMkIsSUFBSSxrQ0FBa0MsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDckgsQ0FBQztJQUVELEtBQUssQ0FBQyxVQUFVLENBQUMsUUFBZ0IsRUFBRSxNQUFjLEVBQUUsUUFBZ0I7UUFDakUsSUFBSSxDQUFDO1lBQ0gsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ3BELE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7WUFFbkMsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRTtnQkFDdEIsUUFBUSxFQUFFO29CQUNSLFdBQVcsRUFBRSxRQUFRO2lCQUN0QjtnQkFDRCxNQUFNLEVBQUUsSUFBSTtnQkFDWixTQUFTLEVBQUUsS0FBSzthQUNqQixDQUFDLENBQUM7WUFFSCx3QkFBd0I7WUFDeEIsTUFBTSxpQkFBaUIsR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQztZQUN2RCxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztnQkFDakUsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPO2dCQUNkLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ3pDLE9BQU8sR0FBRyxjQUFjLElBQUksaUJBQWlCLEVBQUUsQ0FBQztRQUNsRCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE9BQU8sQ0FBQyxLQUFLLENBQUMseUJBQXlCLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDaEQsTUFBTSxJQUFJLEtBQUssQ0FBQyxpQ0FBaUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFDcEUsQ0FBQztJQUNILENBQUM7SUFFRCxLQUFLLENBQUMsVUFBVSxDQUFDLFFBQWdCO1FBQy9CLElBQUksQ0FBQztZQUNILE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUNwRCxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBRW5DLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxNQUFNLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNyQyxJQUFJLE1BQU0sRUFBRSxDQUFDO2dCQUNYLE1BQU0sSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ3RCLENBQUM7UUFDSCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE9BQU8sQ0FBQyxLQUFLLENBQUMsMEJBQTBCLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDakQsK0JBQStCO1FBQ2pDLENBQUM7SUFDSCxDQUFDO0NBQ0Y7QUF6REQsd0RBeURDIn0=
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.uploadCollectionThumbnailWorkflow = void 0;
|
|
4
|
+
const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
|
|
5
|
+
const gcs_direct_upload_1 = require("../services/gcs-direct-upload");
|
|
6
|
+
const uploadThumbnailStep = (0, workflows_sdk_1.createStep)("upload-thumbnail-step", async ({ collectionId, fileData }, { container }) => {
|
|
7
|
+
const collectionCustomService = container.resolve("collectionCustom");
|
|
8
|
+
const gcsUploadService = new gcs_direct_upload_1.GcsDirectUploadService();
|
|
9
|
+
// Generate unique filename for direct upload (no UUID folders)
|
|
10
|
+
const timestamp = Date.now();
|
|
11
|
+
const ext = fileData.filename.split('.').pop() || 'jpg';
|
|
12
|
+
const filename = `collections/thumbnail-${collectionId}-${timestamp}.${ext}`;
|
|
13
|
+
// Convert base64 to buffer
|
|
14
|
+
const buffer = Buffer.from(fileData.content, "base64");
|
|
15
|
+
// Upload directly to GCS without UUID folder
|
|
16
|
+
const publicUrl = await gcsUploadService.uploadFile(filename, buffer, fileData.mimeType);
|
|
17
|
+
const existingCustom = await collectionCustomService
|
|
18
|
+
.listProductCollectionCustoms({ collection_id: collectionId })
|
|
19
|
+
.then((result) => result[0]);
|
|
20
|
+
// Delete old thumbnail if it exists
|
|
21
|
+
if (existingCustom?.thumbnail) {
|
|
22
|
+
try {
|
|
23
|
+
// Extract filename from the URL
|
|
24
|
+
const oldUrl = existingCustom.thumbnail;
|
|
25
|
+
const isGcsUrl = oldUrl.includes("storage.googleapis.com") ||
|
|
26
|
+
oldUrl.includes("storage.cloud.google.com");
|
|
27
|
+
if (isGcsUrl) {
|
|
28
|
+
const parts = oldUrl.split('/');
|
|
29
|
+
const bucketIndex = parts.indexOf('sangaroon');
|
|
30
|
+
if (bucketIndex !== -1 && bucketIndex < parts.length - 1) {
|
|
31
|
+
const oldFilename = parts.slice(bucketIndex + 1).join('/');
|
|
32
|
+
await gcsUploadService.deleteFile(oldFilename);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
console.error('Failed to delete old thumbnail:', error);
|
|
38
|
+
// Continue even if deletion fails
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (existingCustom) {
|
|
42
|
+
await collectionCustomService.updateProductCollectionCustoms([{ id: existingCustom.id, thumbnail: publicUrl }]);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
await collectionCustomService.createProductCollectionCustoms([{
|
|
46
|
+
collection_id: collectionId,
|
|
47
|
+
thumbnail: publicUrl,
|
|
48
|
+
}]);
|
|
49
|
+
}
|
|
50
|
+
return new workflows_sdk_1.StepResponse({
|
|
51
|
+
collectionId,
|
|
52
|
+
thumbnailUrl: publicUrl,
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
exports.uploadCollectionThumbnailWorkflow = (0, workflows_sdk_1.createWorkflow)("upload-collection-thumbnail", (input) => {
|
|
56
|
+
const result = uploadThumbnailStep(input);
|
|
57
|
+
return new workflows_sdk_1.WorkflowResponse(result);
|
|
58
|
+
});
|
|
59
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXBsb2FkLWNvbGxlY3Rpb24tdGh1bWJuYWlsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3dvcmtmbG93cy91cGxvYWQtY29sbGVjdGlvbi10aHVtYm5haWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEscUVBTTJDO0FBQzNDLHFFQUF1RTtBQVd2RSxNQUFNLG1CQUFtQixHQUFHLElBQUEsMEJBQVUsRUFDcEMsdUJBQXVCLEVBQ3ZCLEtBQUssRUFBRSxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQXdCLEVBQUUsRUFBRSxTQUFTLEVBQUUsRUFBRSxFQUFFO0lBQ3hFLE1BQU0sdUJBQXVCLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBUSxDQUFDO0lBQzdFLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSwwQ0FBc0IsRUFBRSxDQUFDO0lBRXRELCtEQUErRDtJQUMvRCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7SUFDN0IsTUFBTSxHQUFHLEdBQUcsUUFBUSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLElBQUksS0FBSyxDQUFDO0lBQ3hELE1BQU0sUUFBUSxHQUFHLHlCQUF5QixZQUFZLElBQUksU0FBUyxJQUFJLEdBQUcsRUFBRSxDQUFDO0lBRTdFLDJCQUEyQjtJQUMzQixNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFFdkQsNkNBQTZDO0lBQzdDLE1BQU0sU0FBUyxHQUFHLE1BQU0sZ0JBQWdCLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBRXpGLE1BQU0sY0FBYyxHQUFHLE1BQU0sdUJBQXVCO1NBQ2pELDRCQUE0QixDQUFDLEVBQUUsYUFBYSxFQUFFLFlBQVksRUFBRSxDQUFDO1NBQzdELElBQUksQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFL0Isb0NBQW9DO0lBQ3BDLElBQUksY0FBYyxFQUFFLFNBQVMsRUFBRSxDQUFDO1FBQzlCLElBQUksQ0FBQztZQUNILGdDQUFnQztZQUNoQyxNQUFNLE1BQU0sR0FBRyxjQUFjLENBQUMsU0FBUyxDQUFDO1lBQ3hDLE1BQU0sUUFBUSxHQUNaLE1BQU0sQ0FBQyxRQUFRLENBQUMsd0JBQXdCLENBQUM7Z0JBQ3pDLE1BQU0sQ0FBQyxRQUFRLENBQUMsMEJBQTBCLENBQUMsQ0FBQztZQUM5QyxJQUFJLFFBQVEsRUFBRSxDQUFDO2dCQUNiLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ2hDLE1BQU0sV0FBVyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUM7Z0JBQy9DLElBQUksV0FBVyxLQUFLLENBQUMsQ0FBQyxJQUFJLFdBQVcsR0FBRyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO29CQUN6RCxNQUFNLFdBQVcsR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLFdBQVcsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7b0JBQzNELE1BQU0sZ0JBQWdCLENBQUMsVUFBVSxDQUFDLFdBQVcsQ0FBQyxDQUFDO2dCQUNqRCxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsT0FBTyxDQUFDLEtBQUssQ0FBQyxpQ0FBaUMsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUN4RCxrQ0FBa0M7UUFDcEMsQ0FBQztJQUNILENBQUM7SUFFRCxJQUFJLGNBQWMsRUFBRSxDQUFDO1FBQ25CLE1BQU0sdUJBQXVCLENBQUMsOEJBQThCLENBQzFELENBQUMsRUFBRSxFQUFFLEVBQUUsY0FBYyxDQUFDLEVBQUUsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FDbEQsQ0FBQztJQUNKLENBQUM7U0FBTSxDQUFDO1FBQ04sTUFBTSx1QkFBdUIsQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDO2dCQUM1RCxhQUFhLEVBQUUsWUFBWTtnQkFDM0IsU0FBUyxFQUFFLFNBQVM7YUFDckIsQ0FBQyxDQUFDLENBQUM7SUFDTixDQUFDO0lBRUQsT0FBTyxJQUFJLDRCQUFZLENBQUM7UUFDdEIsWUFBWTtRQUNaLFlBQVksRUFBRSxTQUFTO0tBQ3hCLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FDRixDQUFDO0FBRVcsUUFBQSxpQ0FBaUMsR0FBRyxJQUFBLDhCQUFjLEVBQzdELDZCQUE2QixFQUM3QixDQUFDLEtBQXlDLEVBQUUsRUFBRTtJQUM1QyxNQUFNLE1BQU0sR0FBRyxtQkFBbUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMxQyxPQUFPLElBQUksZ0NBQWdCLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDdEMsQ0FBQyxDQUNGLENBQUMifQ==
|
package/README.md
CHANGED
|
@@ -1,71 +1,69 @@
|
|
|
1
1
|
# Medusa Collection Thumbnail Plugin
|
|
2
2
|
|
|
3
|
-
Collection thumbnail management plugin for Medusa v2
|
|
3
|
+
Collection thumbnail management plugin for Medusa v2
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
7
|
+
- ✅ Upload, replace, and delete collection thumbnails
|
|
8
|
+
- ✅ Google Cloud Storage integration
|
|
9
|
+
- ✅ Admin UI widget with drag-and-drop upload
|
|
10
|
+
- ✅ Store API endpoints for fetching collections with thumbnails
|
|
11
|
+
- ✅ Automatic cleanup of old thumbnails
|
|
12
|
+
- ✅ File validation (5MB limit, images only)
|
|
12
13
|
|
|
13
14
|
## Installation
|
|
14
15
|
|
|
15
16
|
```bash
|
|
16
17
|
npm install @lodashventure/medusa-collection-thumbnail
|
|
17
|
-
# or
|
|
18
|
-
yarn add @lodashventure/medusa-collection-thumbnail
|
|
19
|
-
# or
|
|
20
|
-
pnpm add @lodashventure/medusa-collection-thumbnail
|
|
21
18
|
```
|
|
22
19
|
|
|
23
20
|
## Configuration
|
|
24
21
|
|
|
25
|
-
Add to your `medusa-config.
|
|
22
|
+
Add the plugin to your `medusa-config.js`:
|
|
26
23
|
|
|
27
|
-
```
|
|
28
|
-
plugins
|
|
24
|
+
```javascript
|
|
25
|
+
const plugins = [
|
|
26
|
+
// ... other plugins
|
|
29
27
|
{
|
|
30
28
|
resolve: "@lodashventure/medusa-collection-thumbnail",
|
|
31
29
|
options: {},
|
|
32
30
|
},
|
|
33
|
-
]
|
|
34
|
-
|
|
35
|
-
modules: [
|
|
36
|
-
{
|
|
37
|
-
resolve: "@lodashventure/medusa-collection-thumbnail/modules/collection",
|
|
38
|
-
options: {},
|
|
39
|
-
},
|
|
40
|
-
]
|
|
31
|
+
];
|
|
41
32
|
```
|
|
42
33
|
|
|
43
|
-
|
|
34
|
+
## Environment Variables
|
|
35
|
+
|
|
36
|
+
Required environment variables for Google Cloud Storage:
|
|
44
37
|
|
|
45
38
|
```env
|
|
46
|
-
CLIENT_EMAIL=your-
|
|
47
|
-
PRIVATE_KEY=your-
|
|
39
|
+
CLIENT_EMAIL=your-service-account@project.iam.gserviceaccount.com
|
|
40
|
+
PRIVATE_KEY=your-private-key
|
|
48
41
|
BUCKET_NAME=your-bucket-name
|
|
49
42
|
GCP_STORAGE_BASE_PUBLIC_URL=https://storage.cloud.google.com
|
|
50
43
|
```
|
|
51
44
|
|
|
52
|
-
## API
|
|
45
|
+
## API Endpoints
|
|
53
46
|
|
|
54
|
-
### Admin
|
|
47
|
+
### Admin Endpoints
|
|
55
48
|
|
|
56
|
-
- `GET /admin/collections/:id/thumbnail` -
|
|
57
|
-
- `POST /admin/collections/:id/thumbnail` - Upload
|
|
58
|
-
- `DELETE /admin/collections/:id/thumbnail` - Delete
|
|
49
|
+
- `GET /admin/collections/:id/thumbnail` - Fetch thumbnail for a collection
|
|
50
|
+
- `POST /admin/collections/:id/thumbnail` - Upload thumbnail (multipart or base64)
|
|
51
|
+
- `DELETE /admin/collections/:id/thumbnail` - Delete thumbnail
|
|
59
52
|
|
|
60
|
-
### Store
|
|
53
|
+
### Store Endpoints
|
|
61
54
|
|
|
62
55
|
- `GET /store/collections` - List collections with thumbnails
|
|
63
|
-
- `GET /store/collections/:id` - Get collection with thumbnail
|
|
56
|
+
- `GET /store/collections/:id` - Get single collection with thumbnail
|
|
57
|
+
|
|
58
|
+
## Development
|
|
64
59
|
|
|
65
|
-
|
|
60
|
+
```bash
|
|
61
|
+
# Build the plugin
|
|
62
|
+
npm run build
|
|
66
63
|
|
|
67
|
-
|
|
68
|
-
|
|
64
|
+
# Watch mode for development
|
|
65
|
+
npm run dev
|
|
66
|
+
```
|
|
69
67
|
|
|
70
68
|
## License
|
|
71
69
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lodashventure/medusa-collection-thumbnail",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.6",
|
|
4
4
|
"description": "Collection thumbnail management plugin for Medusa v2",
|
|
5
5
|
"author": "Lodashventure",
|
|
6
6
|
"license": "MIT",
|
|
@@ -32,11 +32,11 @@
|
|
|
32
32
|
"prepublishOnly": "medusa plugin:build"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@google-cloud/storage": "^7.17.
|
|
36
|
-
"@medusajs/admin-sdk": "2.11.
|
|
37
|
-
"@medusajs/framework": "2.11.
|
|
38
|
-
"@medusajs/icons": "2.11.
|
|
39
|
-
"@medusajs/ui": "
|
|
35
|
+
"@google-cloud/storage": "^7.17.3",
|
|
36
|
+
"@medusajs/admin-sdk": "2.11.3",
|
|
37
|
+
"@medusajs/framework": "2.11.3",
|
|
38
|
+
"@medusajs/icons": "2.11.3",
|
|
39
|
+
"@medusajs/ui": "^4.0.27",
|
|
40
40
|
"yalc": "1.0.0-pre.53"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
@@ -49,17 +49,17 @@
|
|
|
49
49
|
"react-dom": "^18.0.0"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"@medusajs/admin-shared": "2.11.
|
|
53
|
-
"@medusajs/cli": "2.11.
|
|
54
|
-
"@medusajs/medusa": "2.11.
|
|
55
|
-
"@medusajs/types": "2.11.
|
|
56
|
-
"@swc/core": "^1.
|
|
52
|
+
"@medusajs/admin-shared": "2.11.3",
|
|
53
|
+
"@medusajs/cli": "2.11.3",
|
|
54
|
+
"@medusajs/medusa": "2.11.3",
|
|
55
|
+
"@medusajs/types": "2.11.3",
|
|
56
|
+
"@swc/core": "^1.15.0",
|
|
57
57
|
"@types/multer": "^2.0.0",
|
|
58
|
-
"@types/node": "^
|
|
59
|
-
"@types/react": "^
|
|
60
|
-
"@types/react-dom": "^
|
|
58
|
+
"@types/node": "^24.10.0",
|
|
59
|
+
"@types/react": "^19.2.2",
|
|
60
|
+
"@types/react-dom": "^19.2.2",
|
|
61
61
|
"ts-node": "^10.9.2",
|
|
62
|
-
"typescript": "^5.
|
|
63
|
-
"vite": "^
|
|
62
|
+
"typescript": "^5.9.3",
|
|
63
|
+
"vite": "^7.2.2"
|
|
64
64
|
}
|
|
65
65
|
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http";
|
|
2
|
-
type MedusaRequestWithFile<TBody = unknown> = MedusaRequest<TBody> & {
|
|
3
|
-
file?: Express.Multer.File;
|
|
4
|
-
};
|
|
5
|
-
export declare const GET: (req: MedusaRequest, res: MedusaResponse) => Promise<MedusaResponse>;
|
|
6
|
-
export declare const POST: (req: MedusaRequestWithFile, res: MedusaResponse) => Promise<MedusaResponse>;
|
|
7
|
-
export declare const DELETE: (req: MedusaRequest, res: MedusaResponse) => Promise<MedusaResponse>;
|
|
8
|
-
export {};
|