@lodashventure/medusa-hero 1.0.1
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 +5418 -0
- package/.medusa/server/src/admin/index.mjs +5416 -0
- package/.medusa/server/src/api/admin/categories/[id]/hero/route.js +129 -0
- package/.medusa/server/src/api/admin/categories/[id]/thumbnail/route.js +129 -0
- package/.medusa/server/src/api/admin/heroes/reorder/route.js +18 -0
- package/.medusa/server/src/api/admin/heroes/route.js +62 -0
- package/.medusa/server/src/api/admin/heroes/update-link/route.js +19 -0
- package/.medusa/server/src/api/middlewares.js +49 -0
- package/.medusa/server/src/api/store/hero/route.js +19 -0
- package/.medusa/server/src/modules/hero/index.js +13 -0
- package/.medusa/server/src/modules/hero/migrations/Migration20250414070000.js +15 -0
- package/.medusa/server/src/modules/hero/migrations/Migration20251024170000.js +14 -0
- package/.medusa/server/src/modules/hero/models/hero.js +11 -0
- package/.medusa/server/src/modules/hero/service.js +13 -0
- package/.medusa/server/src/services/gcs-direct-upload.js +53 -0
- package/.medusa/server/src/workflows/delete-heroes.js +95 -0
- package/.medusa/server/src/workflows/reorder-heroes.js +23 -0
- package/.medusa/server/src/workflows/upload-category-image.js +64 -0
- package/.medusa/server/src/workflows/upload-heroes.js +54 -0
- package/README.md +68 -0
- package/package.json +67 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.deleteHeroesWorkflow = void 0;
|
|
4
|
+
const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
|
|
5
|
+
const core_flows_1 = require("@medusajs/medusa/core-flows");
|
|
6
|
+
const hero_1 = require("../modules/hero");
|
|
7
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
8
|
+
const deleteHeroesStep = (0, workflows_sdk_1.createStep)("delete-heroes", async ({ ids }, { container }) => {
|
|
9
|
+
const logger = container.resolve("logger");
|
|
10
|
+
const heroModuleService = container.resolve(hero_1.HERO_MODULE);
|
|
11
|
+
if (!ids.length) {
|
|
12
|
+
throw new Error("At least one hero ID is required");
|
|
13
|
+
}
|
|
14
|
+
logger.info(`Deleting ${ids.length} heroes`);
|
|
15
|
+
// First, fetch the heroes to ensure they exist
|
|
16
|
+
const heroes = await heroModuleService.listHeroes({
|
|
17
|
+
id: ids,
|
|
18
|
+
});
|
|
19
|
+
if (!heroes.length) {
|
|
20
|
+
throw new Error("No heroes found with the provided IDs");
|
|
21
|
+
}
|
|
22
|
+
const heroIds = heroes.map((hero) => hero.id);
|
|
23
|
+
// Try to delete files using the file service
|
|
24
|
+
// We'll handle file deletion errors gracefully since the files might already be deleted
|
|
25
|
+
try {
|
|
26
|
+
const fileService = container.resolve(utils_1.Modules.FILE);
|
|
27
|
+
// Extract filenames from hero URLs and create proper file objects
|
|
28
|
+
const fileKeysToDelete = [];
|
|
29
|
+
for (const hero of heroes) {
|
|
30
|
+
if (hero.url) {
|
|
31
|
+
// Extract filename from URL like https://storage.googleapis.com/sangaroon/filename.jpg
|
|
32
|
+
const urlParts = hero.url.split('/');
|
|
33
|
+
const filename = urlParts[urlParts.length - 1];
|
|
34
|
+
if (filename) {
|
|
35
|
+
logger.info(`Preparing to delete file: ${filename} from URL: ${hero.url}`);
|
|
36
|
+
fileKeysToDelete.push(filename);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
if (fileKeysToDelete.length > 0) {
|
|
41
|
+
logger.info(`Attempting to delete ${fileKeysToDelete.length} files from storage`);
|
|
42
|
+
try {
|
|
43
|
+
// Try to delete files using the deleteFiles method
|
|
44
|
+
// First try with filenames as IDs
|
|
45
|
+
try {
|
|
46
|
+
await fileService.deleteFiles(fileKeysToDelete);
|
|
47
|
+
logger.info(`Successfully deleted files using filenames`);
|
|
48
|
+
}
|
|
49
|
+
catch (deleteError) {
|
|
50
|
+
logger.warn(`Could not delete using filenames: ${deleteError.message}`);
|
|
51
|
+
// Try with hero IDs instead
|
|
52
|
+
try {
|
|
53
|
+
await fileService.deleteFiles(heroIds);
|
|
54
|
+
logger.info(`Successfully deleted files using hero IDs`);
|
|
55
|
+
}
|
|
56
|
+
catch (fallbackError) {
|
|
57
|
+
logger.error(`Could not delete files using hero IDs either: ${fallbackError.message}`);
|
|
58
|
+
// Last attempt: use deleteFilesWorkflow with hero IDs
|
|
59
|
+
try {
|
|
60
|
+
await (0, core_flows_1.deleteFilesWorkflow)(container).run({
|
|
61
|
+
input: { ids: heroIds },
|
|
62
|
+
});
|
|
63
|
+
logger.info(`Successfully deleted files using deleteFilesWorkflow`);
|
|
64
|
+
}
|
|
65
|
+
catch (workflowError) {
|
|
66
|
+
logger.error(`Error deleting files with workflow: ${workflowError.message}`);
|
|
67
|
+
logger.info(`Files may remain in storage, but continuing with hero deletion`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
catch (fileDeleteError) {
|
|
73
|
+
// Log the error but continue with hero deletion
|
|
74
|
+
logger.error(`Error in file deletion process: ${fileDeleteError.message}`);
|
|
75
|
+
logger.info(`Continuing with hero record deletion despite file deletion error`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
logger.info(`No files to delete from storage`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
// If file service is not available or any other error, log and continue
|
|
84
|
+
logger.error(`Error accessing file service: ${error.message}`);
|
|
85
|
+
logger.info(`Continuing with hero record deletion despite file service error`);
|
|
86
|
+
}
|
|
87
|
+
// Delete the hero records regardless of file deletion success
|
|
88
|
+
await heroModuleService.deleteHeroes(heroIds);
|
|
89
|
+
return new workflows_sdk_1.StepResponse(heroIds, heroIds);
|
|
90
|
+
});
|
|
91
|
+
exports.deleteHeroesWorkflow = (0, workflows_sdk_1.createWorkflow)("delete-heroes", (deleteInput) => {
|
|
92
|
+
const post = deleteHeroesStep(deleteInput);
|
|
93
|
+
return new workflows_sdk_1.WorkflowResponse(post);
|
|
94
|
+
});
|
|
95
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVsZXRlLWhlcm9lcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy93b3JrZmxvd3MvZGVsZXRlLWhlcm9lcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxxRUFLMkM7QUFDM0MsNERBQWtFO0FBRWxFLDBDQUE4QztBQUM5QyxxREFBb0Q7QUFNcEQsTUFBTSxnQkFBZ0IsR0FBRyxJQUFBLDBCQUFVLEVBQ2pDLGVBQWUsRUFDZixLQUFLLEVBQUUsRUFBRSxHQUFHLEVBQTZCLEVBQUUsRUFBRSxTQUFTLEVBQUUsRUFBRSxFQUFFO0lBQzFELE1BQU0sTUFBTSxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDM0MsTUFBTSxpQkFBaUIsR0FDckIsU0FBUyxDQUFDLE9BQU8sQ0FBQyxrQkFBVyxDQUFDLENBQUM7SUFFakMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNoQixNQUFNLElBQUksS0FBSyxDQUFDLGtDQUFrQyxDQUFDLENBQUM7SUFDdEQsQ0FBQztJQUVELE1BQU0sQ0FBQyxJQUFJLENBQUMsWUFBWSxHQUFHLENBQUMsTUFBTSxTQUFTLENBQUMsQ0FBQztJQUU3QywrQ0FBK0M7SUFDL0MsTUFBTSxNQUFNLEdBQUcsTUFBTSxpQkFBaUIsQ0FBQyxVQUFVLENBQUM7UUFDaEQsRUFBRSxFQUFFLEdBQUc7S0FDUixDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ25CLE1BQU0sSUFBSSxLQUFLLENBQUMsdUNBQXVDLENBQUMsQ0FBQztJQUMzRCxDQUFDO0lBRUQsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBRTlDLDZDQUE2QztJQUM3Qyx3RkFBd0Y7SUFDeEYsSUFBSSxDQUFDO1FBQ0gsTUFBTSxX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
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.reorderHeroesWorkflow = void 0;
|
|
4
|
+
const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
|
|
5
|
+
const hero_1 = require("../modules/hero");
|
|
6
|
+
const reorderHeroesStep = (0, workflows_sdk_1.createStep)("reorder-heroes", async ({ ids }, { container }) => {
|
|
7
|
+
const logger = container.resolve("logger");
|
|
8
|
+
const heroModuleService = container.resolve(hero_1.HERO_MODULE);
|
|
9
|
+
if (!ids.length) {
|
|
10
|
+
throw new Error("At least one hero ID is required");
|
|
11
|
+
}
|
|
12
|
+
const heroes = await heroModuleService.listHeroes();
|
|
13
|
+
if (heroes.length !== ids.length) {
|
|
14
|
+
throw new Error("Hero IDs and heroes length does not match");
|
|
15
|
+
}
|
|
16
|
+
await heroModuleService.updateHeroes(ids.map((id, index) => ({ id, order: ids.length - index })));
|
|
17
|
+
return new workflows_sdk_1.StepResponse(ids, ids);
|
|
18
|
+
});
|
|
19
|
+
exports.reorderHeroesWorkflow = (0, workflows_sdk_1.createWorkflow)("reorder-heroes", (reorderInput) => {
|
|
20
|
+
const post = reorderHeroesStep(reorderInput);
|
|
21
|
+
return new workflows_sdk_1.WorkflowResponse(post);
|
|
22
|
+
});
|
|
23
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVvcmRlci1oZXJvZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvd29ya2Zsb3dzL3Jlb3JkZXItaGVyb2VzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHFFQUsyQztBQUMzQywwQ0FBOEM7QUFROUMsTUFBTSxpQkFBaUIsR0FBRyxJQUFBLDBCQUFVLEVBQ2xDLGdCQUFnQixFQUNoQixLQUFLLEVBQUUsRUFBRSxHQUFHLEVBQThCLEVBQUUsRUFBRSxTQUFTLEVBQUUsRUFBRSxFQUFFO0lBQzNELE1BQU0sTUFBTSxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDM0MsTUFBTSxpQkFBaUIsR0FDckIsU0FBUyxDQUFDLE9BQU8sQ0FBQyxrQkFBVyxDQUFDLENBQUM7SUFFakMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNoQixNQUFNLElBQUksS0FBSyxDQUFDLGtDQUFrQyxDQUFDLENBQUM7SUFDdEQsQ0FBQztJQUVELE1BQU0sTUFBTSxHQUFHLE1BQU0saUJBQWlCLENBQUMsVUFBVSxFQUFFLENBQUM7SUFDcEQsSUFBSSxNQUFNLENBQUMsTUFBTSxLQUFLLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNqQyxNQUFNLElBQUksS0FBSyxDQUFDLDJDQUEyQyxDQUFDLENBQUM7SUFDL0QsQ0FBQztJQUVELE1BQU0saUJBQWlCLENBQUMsWUFBWSxDQUNsQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxLQUFLLEVBQUUsR0FBRyxDQUFDLE1BQU0sR0FBRyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQzVELENBQUM7SUFFRixPQUFPLElBQUksNEJBQVksQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDcEMsQ0FBQyxDQUNGLENBQUM7QUFFVyxRQUFBLHFCQUFxQixHQUFHLElBQUEsOEJBQWMsRUFDakQsZ0JBQWdCLEVBQ2hCLENBQUMsWUFBd0MsRUFBRSxFQUFFO0lBQzNDLE1BQU0sSUFBSSxHQUFHLGlCQUFpQixDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQzdDLE9BQU8sSUFBSSxnQ0FBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUNwQyxDQUFDLENBQ0YsQ0FBQyJ9
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.uploadCategoryImageWorkflow = 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 utils_1 = require("@medusajs/framework/utils");
|
|
7
|
+
const uploadCategoryImageStep = (0, workflows_sdk_1.createStep)("upload-category-image-step", async ({ categoryId, imageType, fileData }, { container }) => {
|
|
8
|
+
const query = container.resolve(utils_1.ContainerRegistrationKeys.QUERY);
|
|
9
|
+
const gcsUploadService = new gcs_direct_upload_1.GcsDirectUploadService();
|
|
10
|
+
// Generate unique filename for direct upload
|
|
11
|
+
const timestamp = Date.now();
|
|
12
|
+
const ext = fileData.filename.split('.').pop() || 'jpg';
|
|
13
|
+
const filename = `categories/${imageType}-${categoryId}-${timestamp}.${ext}`;
|
|
14
|
+
// Convert base64 to buffer
|
|
15
|
+
const buffer = Buffer.from(fileData.content, "base64");
|
|
16
|
+
// Upload directly to GCS
|
|
17
|
+
const publicUrl = await gcsUploadService.uploadFile(filename, buffer, fileData.mimeType);
|
|
18
|
+
// Retrieve existing category
|
|
19
|
+
const { data: categories } = await query.graph({
|
|
20
|
+
entity: "product_category",
|
|
21
|
+
fields: ["id", "metadata"],
|
|
22
|
+
filters: { id: categoryId },
|
|
23
|
+
});
|
|
24
|
+
if (!categories || categories.length === 0) {
|
|
25
|
+
throw new Error(`Category with id ${categoryId} not found`);
|
|
26
|
+
}
|
|
27
|
+
const category = categories[0];
|
|
28
|
+
// Delete old image if it exists
|
|
29
|
+
const oldImageUrl = category.metadata?.[imageType];
|
|
30
|
+
if (oldImageUrl) {
|
|
31
|
+
try {
|
|
32
|
+
if (oldImageUrl.includes('storage.googleapis.com')) {
|
|
33
|
+
const parts = oldImageUrl.split('/');
|
|
34
|
+
const bucketIndex = parts.indexOf('sangaroon');
|
|
35
|
+
if (bucketIndex !== -1 && bucketIndex < parts.length - 1) {
|
|
36
|
+
const oldFilename = parts.slice(bucketIndex + 1).join('/');
|
|
37
|
+
await gcsUploadService.deleteFile(oldFilename);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
console.error(`Failed to delete old ${imageType}:`, error);
|
|
43
|
+
// Continue even if deletion fails
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// Update category metadata with new image URL
|
|
47
|
+
const updatedMetadata = {
|
|
48
|
+
...category.metadata,
|
|
49
|
+
[imageType]: publicUrl,
|
|
50
|
+
};
|
|
51
|
+
// Note: Category metadata update should be done via the category service
|
|
52
|
+
// For now, we'll return the URL and let the route handler update it
|
|
53
|
+
return new workflows_sdk_1.StepResponse({
|
|
54
|
+
categoryId,
|
|
55
|
+
imageType,
|
|
56
|
+
imageUrl: publicUrl,
|
|
57
|
+
metadata: updatedMetadata,
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
exports.uploadCategoryImageWorkflow = (0, workflows_sdk_1.createWorkflow)("upload-category-image", (input) => {
|
|
61
|
+
const result = uploadCategoryImageStep(input);
|
|
62
|
+
return new workflows_sdk_1.WorkflowResponse(result);
|
|
63
|
+
});
|
|
64
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXBsb2FkLWNhdGVnb3J5LWltYWdlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3dvcmtmbG93cy91cGxvYWQtY2F0ZWdvcnktaW1hZ2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEscUVBTTJDO0FBQzNDLHFFQUF1RTtBQUN2RSxxREFBc0U7QUFZdEUsTUFBTSx1QkFBdUIsR0FBRyxJQUFBLDBCQUFVLEVBQ3hDLDRCQUE0QixFQUM1QixLQUFLLEVBQUUsRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBNEIsRUFBRSxFQUFFLFNBQVMsRUFBRSxFQUFFLEVBQUU7SUFDckYsTUFBTSxLQUFLLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQyxpQ0FBeUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNqRSxNQUFNLGdCQUFnQixHQUFHLElBQUksMENBQXNCLEVBQUUsQ0FBQztJQUV0RCw2Q0FBNkM7SUFDN0MsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO0lBQzdCLE1BQU0sR0FBRyxHQUFHLFFBQVEsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxJQUFJLEtBQUssQ0FBQztJQUN4RCxNQUFNLFFBQVEsR0FBRyxjQUFjLFNBQVMsSUFBSSxVQUFVLElBQUksU0FBUyxJQUFJLEdBQUcsRUFBRSxDQUFDO0lBRTdFLDJCQUEyQjtJQUMzQixNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFFdkQseUJBQXlCO0lBQ3pCLE1BQU0sU0FBUyxHQUFHLE1BQU0sZ0JBQWdCLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBRXpGLDZCQUE2QjtJQUM3QixNQUFNLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxHQUFHLE1BQU0sS0FBSyxDQUFDLEtBQUssQ0FBQztRQUM3QyxNQUFNLEVBQUUsa0JBQWtCO1FBQzFCLE1BQU0sRUFBRSxDQUFDLElBQUksRUFBRSxVQUFVLENBQUM7UUFDMUIsT0FBTyxFQUFFLEVBQUUsRUFBRSxFQUFFLFVBQVUsRUFBRTtLQUM1QixDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsVUFBVSxJQUFJLFVBQVUsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDM0MsTUFBTSxJQUFJLEtBQUssQ0FBQyxvQkFBb0IsVUFBVSxZQUFZLENBQUMsQ0FBQztJQUM5RCxDQUFDO0lBRUQsTUFBTSxRQUFRLEdBQUcsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBRS9CLGdDQUFnQztJQUNoQyxNQUFNLFdBQVcsR0FBRyxRQUFRLENBQUMsUUFBUSxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDbkQsSUFBSSxXQUFXLEVBQUUsQ0FBQztRQUNoQixJQUFJLENBQUM7WUFDSCxJQUFJLFdBQVcsQ0FBQyxRQUFRLENBQUMsd0JBQXdCLENBQUMsRUFBRSxDQUFDO2dCQUNuRCxNQUFNLEtBQUssR0FBRyxXQUFXLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUNyQyxNQUFNLFdBQVcsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDO2dCQUMvQyxJQUFJLFdBQVcsS0FBSyxDQUFDLENBQUMsSUFBSSxXQUFXLEdBQUcsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztvQkFDekQsTUFBTSxXQUFXLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUMzRCxNQUFNLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsQ0FBQztnQkFDakQsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE9BQU8sQ0FBQyxLQUFLLENBQUMsd0JBQXdCLFNBQVMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQzNELGtDQUFrQztRQUNwQyxDQUFDO0lBQ0gsQ0FBQztJQUVELDhDQUE4QztJQUM5QyxNQUFNLGVBQWUsR0FBRztRQUN0QixHQUFHLFFBQVEsQ0FBQyxRQUFRO1FBQ3BCLENBQUMsU0FBUyxDQUFDLEVBQUUsU0FBUztLQUN2QixDQUFDO0lBRUYseUVBQXlFO0lBQ3pFLG9FQUFvRTtJQUVwRSxPQUFPLElBQUksNEJBQVksQ0FBQztRQUN0QixVQUFVO1FBQ1YsU0FBUztRQUNULFFBQVEsRUFBRSxTQUFTO1FBQ25CLFFBQVEsRUFBRSxlQUFlO0tBQzFCLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FDRixDQUFDO0FBRVcsUUFBQSwyQkFBMkIsR0FBRyxJQUFBLDhCQUFjLEVBQ3ZELHVCQUF1QixFQUN2QixDQUFDLEtBQTZDLEVBQUUsRUFBRTtJQUNoRCxNQUFNLE1BQU0sR0FBRyx1QkFBdUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM5QyxPQUFPLElBQUksZ0NBQWdCLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDdEMsQ0FBQyxDQUNGLENBQUMifQ==
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.uploadHeroesWorkflow = void 0;
|
|
4
|
+
const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
|
|
5
|
+
const hero_1 = require("../modules/hero");
|
|
6
|
+
const core_flows_1 = require("@medusajs/medusa/core-flows");
|
|
7
|
+
const uploadHeroesStep = (0, workflows_sdk_1.createStep)("upload-heroes", async ({ files }, { container }) => {
|
|
8
|
+
const logger = container.resolve("logger");
|
|
9
|
+
const heroModuleService = container.resolve(hero_1.HERO_MODULE);
|
|
10
|
+
if (files.length === 0) {
|
|
11
|
+
throw new Error("at least 1 file is required");
|
|
12
|
+
}
|
|
13
|
+
logger.info(`Uploading ${files.length} heroes`);
|
|
14
|
+
const { result } = await (0, core_flows_1.uploadFilesWorkflow)(container).run({
|
|
15
|
+
input: {
|
|
16
|
+
files: files.map((file) => ({
|
|
17
|
+
...file,
|
|
18
|
+
filename: `${file.filename.replace(/ /g, "_")}`,
|
|
19
|
+
})),
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
if (result.some((file) => !file.id || !file.url)) {
|
|
23
|
+
throw new Error(`some files don't have an id or url`);
|
|
24
|
+
}
|
|
25
|
+
const [maxOrderHero] = await heroModuleService.listHeroes({}, { take: 1, order: { order: "DESC" } });
|
|
26
|
+
const maxOrder = maxOrderHero?.order ?? 0;
|
|
27
|
+
const heroes = await heroModuleService.createHeroes(result.map((hero, index) => ({
|
|
28
|
+
id: hero.id,
|
|
29
|
+
url: hero.url,
|
|
30
|
+
order: maxOrder + index + 1,
|
|
31
|
+
})));
|
|
32
|
+
return new workflows_sdk_1.StepResponse(heroes, heroes);
|
|
33
|
+
}, async (heroes, { container }) => {
|
|
34
|
+
const logger = container.resolve("logger");
|
|
35
|
+
const heroModuleService = container.resolve(hero_1.HERO_MODULE);
|
|
36
|
+
if (heroes) {
|
|
37
|
+
// delete files
|
|
38
|
+
await (0, core_flows_1.deleteFilesWorkflow)(container).run({
|
|
39
|
+
input: {
|
|
40
|
+
ids: heroes.map((hero) => hero.id),
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
// delete heroes
|
|
44
|
+
await heroModuleService.deleteHeroes(heroes.map((hero) => hero.id));
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
logger.warn(`Hero not found`);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
exports.uploadHeroesWorkflow = (0, workflows_sdk_1.createWorkflow)("upload-heroes", (heroInput) => {
|
|
51
|
+
const post = uploadHeroesStep(heroInput);
|
|
52
|
+
return new workflows_sdk_1.WorkflowResponse(post);
|
|
53
|
+
});
|
|
54
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXBsb2FkLWhlcm9lcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy93b3JrZmxvd3MvdXBsb2FkLWhlcm9lcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxxRUFLMkM7QUFDM0MsMENBQThDO0FBRTlDLDREQUlxQztBQU1yQyxNQUFNLGdCQUFnQixHQUFHLElBQUEsMEJBQVUsRUFDakMsZUFBZSxFQUNmLEtBQUssRUFBRSxFQUFFLEtBQUssRUFBNkIsRUFBRSxFQUFFLFNBQVMsRUFBRSxFQUFFLEVBQUU7SUFDNUQsTUFBTSxNQUFNLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUMzQyxNQUFNLGlCQUFpQixHQUNyQixTQUFTLENBQUMsT0FBTyxDQUFDLGtCQUFXLENBQUMsQ0FBQztJQUVqQyxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDdkIsTUFBTSxJQUFJLEtBQUssQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO0lBQ2pELENBQUM7SUFFRCxNQUFNLENBQUMsSUFBSSxDQUFDLGFBQWEsS0FBSyxDQUFDLE1BQU0sU0FBUyxDQUFDLENBQUM7SUFFaEQsTUFBTSxFQUFFLE1BQU0sRUFBRSxHQUFHLE1BQU0sSUFBQSxnQ0FBbUIsRUFBQyxTQUFTLENBQUMsQ0FBQyxHQUFHLENBQUM7UUFDMUQsS0FBSyxFQUFFO1lBQ0wsS0FBSyxFQUFFLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7Z0JBQzFCLEdBQUcsSUFBSTtnQkFDUCxRQUFRLEVBQUUsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLEVBQUU7YUFDaEQsQ0FBQyxDQUFDO1NBQ0o7S0FDRixDQUFDLENBQUM7SUFFSCxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ2pELE1BQU0sSUFBSSxLQUFLLENBQUMsb0NBQW9DLENBQUMsQ0FBQztJQUN4RCxDQUFDO0lBRUQsTUFBTSxDQUFDLFlBQVksQ0FBQyxHQUFHLE1BQU0saUJBQWlCLENBQUMsVUFBVSxDQUN2RCxFQUFFLEVBQ0YsRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsRUFBRSxDQUN0QyxDQUFDO0lBQ0YsTUFBTSxRQUFRLEdBQUcsWUFBWSxFQUFFLEtBQUssSUFBSSxDQUFDLENBQUM7SUFFMUMsTUFBTSxNQUFNLEdBQUcsTUFBTSxpQkFBaUIsQ0FBQyxZQUFZLENBQ2pELE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQzNCLEVBQUUsRUFBRSxJQUFJLENBQUMsRUFBRTtRQUNYLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRztRQUNiLEtBQUssRUFBRSxRQUFRLEdBQUcsS0FBSyxHQUFHLENBQUM7S0FDNUIsQ0FBQyxDQUFDLENBQ0osQ0FBQztJQUVGLE9BQU8sSUFBSSw0QkFBWSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztBQUMxQyxDQUFDLEVBRUQsS0FBSyxFQUFFLE1BQU0sRUFBRSxFQUFFLFNBQVMsRUFBRSxFQUFFLEVBQUU7SUFDOUIsTUFBTSxNQUFNLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUMzQyxNQUFNLGlCQUFpQixHQUNyQixTQUFTLENBQUMsT0FBTyxDQUFDLGtCQUFXLENBQUMsQ0FBQztJQUVqQyxJQUFJLE1BQU0sRUFBRSxDQUFDO1FBQ1gsZUFBZTtRQUNmLE1BQU0sSUFBQSxnQ0FBbUIsRUFBQyxTQUFTLENBQUMsQ0FBQyxHQUFHLENBQUM7WUFDdkMsS0FBSyxFQUFFO2dCQUNMLEdBQUcsRUFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO2FBQ25DO1NBQ0YsQ0FBQyxDQUFDO1FBQ0gsZ0JBQWdCO1FBQ2hCLE1BQU0saUJBQWlCLENBQUMsWUFBWSxDQUNsQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQzlCLENBQUM7SUFDSixDQUFDO1NBQU0sQ0FBQztRQUNOLE1BQU0sQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUNoQyxDQUFDO0FBQ0gsQ0FBQyxDQUNGLENBQUM7QUFFVyxRQUFBLG9CQUFvQixHQUFHLElBQUEsOEJBQWMsRUFDaEQsZUFBZSxFQUNmLENBQUMsU0FBb0MsRUFBRSxFQUFFO0lBQ3ZDLE1BQU0sSUFBSSxHQUFHLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBRXpDLE9BQU8sSUFBSSxnQ0FBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUNwQyxDQUFDLENBQ0YsQ0FBQyJ9
|
package/README.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Medusa Hero - Category Media Plugin
|
|
2
|
+
|
|
3
|
+
A Medusa v2 plugin for managing category thumbnail and hero images with drag & drop upload functionality.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Upload category thumbnail images (400x400px recommended)
|
|
8
|
+
- Upload category hero/banner images (1920x600px recommended)
|
|
9
|
+
- Delete category images
|
|
10
|
+
- Drag & drop file upload interface
|
|
11
|
+
- Image preview in admin dashboard
|
|
12
|
+
- Direct upload to Google Cloud Storage
|
|
13
|
+
- Automatic old image cleanup
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
cd backend/plugins/medusa-hero
|
|
19
|
+
npm install
|
|
20
|
+
npm run build
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Configuration
|
|
24
|
+
|
|
25
|
+
Add to your `medusa-config.ts`:
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
{
|
|
29
|
+
resolve: "@lodashventure/medusa-hero",
|
|
30
|
+
options: {},
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## API Endpoints
|
|
35
|
+
|
|
36
|
+
### Admin Endpoints
|
|
37
|
+
|
|
38
|
+
- `GET /admin/categories/:id/thumbnail` - Get category thumbnail
|
|
39
|
+
- `POST /admin/categories/:id/thumbnail` - Upload thumbnail (multipart/form-data)
|
|
40
|
+
- `DELETE /admin/categories/:id/thumbnail` - Delete thumbnail
|
|
41
|
+
- `GET /admin/categories/:id/hero` - Get category hero image
|
|
42
|
+
- `POST /admin/categories/:id/hero` - Upload hero image (multipart/form-data)
|
|
43
|
+
- `DELETE /admin/categories/:id/hero` - Delete hero image
|
|
44
|
+
|
|
45
|
+
## Usage
|
|
46
|
+
|
|
47
|
+
The plugin automatically adds two widgets to the category detail page in the admin dashboard:
|
|
48
|
+
|
|
49
|
+
1. **Category Thumbnail Widget** - For square category images
|
|
50
|
+
2. **Category Hero Widget** - For wide banner images
|
|
51
|
+
|
|
52
|
+
Both widgets support:
|
|
53
|
+
- Drag & drop upload
|
|
54
|
+
- Click to browse
|
|
55
|
+
- Image preview
|
|
56
|
+
- Delete functionality
|
|
57
|
+
- File validation (type & size)
|
|
58
|
+
|
|
59
|
+
## Requirements
|
|
60
|
+
|
|
61
|
+
- Medusa v2.11.0+
|
|
62
|
+
- Node.js 20+
|
|
63
|
+
- Google Cloud Storage configured
|
|
64
|
+
- Environment variables: `CLIENT_EMAIL`, `PRIVATE_KEY`, `BUCKET_NAME`
|
|
65
|
+
|
|
66
|
+
## License
|
|
67
|
+
|
|
68
|
+
MIT
|
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lodashventure/medusa-hero",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Plugin for managing category thumbnail and hero images in Medusa",
|
|
5
|
+
"author": "StandUpCode",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"files": [
|
|
8
|
+
".medusa/server"
|
|
9
|
+
],
|
|
10
|
+
"exports": {
|
|
11
|
+
"./package.json": "./package.json",
|
|
12
|
+
"./workflows": "./.medusa/server/src/workflows/index.js",
|
|
13
|
+
"./.medusa/server/src/modules/*": "./.medusa/server/src/modules/*/index.js",
|
|
14
|
+
"./modules/*": "./.medusa/server/src/modules/*/index.js",
|
|
15
|
+
"./providers/*": "./.medusa/server/src/providers/*/index.js",
|
|
16
|
+
"./admin": "./.medusa/server/src/admin/index.mjs",
|
|
17
|
+
"./*": "./.medusa/server/src/*.js"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"medusa",
|
|
21
|
+
"plugin",
|
|
22
|
+
"medusa-plugin-other",
|
|
23
|
+
"medusa-plugin",
|
|
24
|
+
"medusa-v2",
|
|
25
|
+
"category",
|
|
26
|
+
"images"
|
|
27
|
+
],
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "medusa plugin:build",
|
|
30
|
+
"dev": "medusa plugin:develop",
|
|
31
|
+
"prepublishOnly": "medusa plugin:build"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@medusajs/admin-sdk": "2.11.1",
|
|
35
|
+
"@medusajs/cli": "2.11.1",
|
|
36
|
+
"@medusajs/framework": "2.11.1",
|
|
37
|
+
"@medusajs/icons": "^2.11.1",
|
|
38
|
+
"@medusajs/medusa": "2.11.1",
|
|
39
|
+
"@medusajs/ui": "4.0.4",
|
|
40
|
+
"@swc/core": "1.5.7",
|
|
41
|
+
"@types/multer": "^1.4.12",
|
|
42
|
+
"@types/node": "^20.0.0",
|
|
43
|
+
"@types/react": "^18.3.2",
|
|
44
|
+
"@types/react-dom": "^18.2.25",
|
|
45
|
+
"react": "^18.2.0",
|
|
46
|
+
"react-dom": "^18.2.0",
|
|
47
|
+
"typescript": "^5.6.2"
|
|
48
|
+
},
|
|
49
|
+
"peerDependencies": {
|
|
50
|
+
"@medusajs/admin-sdk": "2.11.1",
|
|
51
|
+
"@medusajs/framework": "2.11.1",
|
|
52
|
+
"@medusajs/icons": "^2.11.1",
|
|
53
|
+
"@medusajs/medusa": "2.11.1",
|
|
54
|
+
"@medusajs/ui": "4.0.3"
|
|
55
|
+
},
|
|
56
|
+
"engines": {
|
|
57
|
+
"node": ">=20"
|
|
58
|
+
},
|
|
59
|
+
"dependencies": {
|
|
60
|
+
"@google-cloud/storage": "^7.7.0",
|
|
61
|
+
"lucide-react": "^0.548.0",
|
|
62
|
+
"multer": "^2.0.2",
|
|
63
|
+
"react-dropzone": "^14.3.8",
|
|
64
|
+
"ts-node": "^10.9.2",
|
|
65
|
+
"yalc": "^1.0.0-pre.53"
|
|
66
|
+
}
|
|
67
|
+
}
|