@lodashventure/medusa-media-manager 0.1.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.
Files changed (25) hide show
  1. package/.medusa/server/src/admin/index.js +1376 -0
  2. package/.medusa/server/src/admin/index.mjs +1377 -0
  3. package/.medusa/server/src/api/admin/media/assets/[id]/route.js +50 -0
  4. package/.medusa/server/src/api/admin/media/assets/[id]/url/route.js +24 -0
  5. package/.medusa/server/src/api/admin/media/assets/route.js +53 -0
  6. package/.medusa/server/src/api/admin/media/assets/upload/route.js +67 -0
  7. package/.medusa/server/src/api/middlewares.js +53 -0
  8. package/.medusa/server/src/index.js +46 -0
  9. package/.medusa/server/src/modules/media-manager/index.js +13 -0
  10. package/.medusa/server/src/modules/media-manager/migrations/Migration20251104115419.js +83 -0
  11. package/.medusa/server/src/modules/media-manager/migrations/Migration20251104160000.js +15 -0
  12. package/.medusa/server/src/modules/media-manager/models/index.js +14 -0
  13. package/.medusa/server/src/modules/media-manager/models/media-models.js +201 -0
  14. package/.medusa/server/src/modules/media-manager/service.js +778 -0
  15. package/.medusa/server/src/providers/index.js +23 -0
  16. package/.medusa/server/src/providers/storage/azure.js +100 -0
  17. package/.medusa/server/src/providers/storage/factory.js +32 -0
  18. package/.medusa/server/src/providers/storage/gcs.js +91 -0
  19. package/.medusa/server/src/providers/storage/local.js +73 -0
  20. package/.medusa/server/src/providers/storage/s3.js +96 -0
  21. package/.medusa/server/src/providers/storage/types.js +3 -0
  22. package/.medusa/server/src/types/index.js +3 -0
  23. package/.medusa/server/src/workflows/index.js +4 -0
  24. package/README.md +85 -0
  25. package/package.json +82 -0
@@ -0,0 +1,778 @@
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
+ const crypto_1 = __importDefault(require("crypto"));
7
+ const path_1 = __importDefault(require("path"));
8
+ const sharp_1 = __importDefault(require("sharp"));
9
+ const sanitize_html_1 = __importDefault(require("sanitize-html"));
10
+ const uuid_1 = require("uuid");
11
+ const utils_1 = require("@medusajs/framework/utils");
12
+ const models_1 = require("./models");
13
+ const providers_1 = require("../../providers");
14
+ const DEFAULT_PRESETS = [
15
+ {
16
+ name: "thumbnail",
17
+ width: 200,
18
+ height: 200,
19
+ fit: "cover",
20
+ withoutEnlargement: true,
21
+ },
22
+ { name: "small", width: 640, withoutEnlargement: true },
23
+ { name: "medium", width: 1024, withoutEnlargement: true },
24
+ { name: "large", width: 1600, withoutEnlargement: true },
25
+ ];
26
+ const DEFAULT_OPTIONS = {
27
+ storage: {
28
+ driver: "local",
29
+ },
30
+ presets: DEFAULT_PRESETS,
31
+ generate: {
32
+ mode: "eager",
33
+ },
34
+ svg: {
35
+ sanitize: true,
36
+ },
37
+ moderation: {
38
+ enabled: true,
39
+ },
40
+ rbac: {
41
+ deleteRequiresNoUsage: true,
42
+ },
43
+ };
44
+ const IMAGE_MIME_SET = new Set([
45
+ "image/jpeg",
46
+ "image/png",
47
+ "image/webp",
48
+ "image/avif",
49
+ "image/gif",
50
+ "image/heic",
51
+ "image/heif",
52
+ "image/tiff",
53
+ "image/bmp",
54
+ ]);
55
+ const SVG_MIME = "image/svg+xml";
56
+ const VIDEO_MIME_PREFIXES = ["video/"];
57
+ const DOCUMENT_MIME_SET = new Set(["application/pdf"]);
58
+ const VARIANT_FORMAT_PIPELINE = {
59
+ default: ["jpeg", "webp", "avif"],
60
+ png: ["png", "webp", "avif"],
61
+ webp: ["webp", "avif"],
62
+ avif: ["avif", "webp"],
63
+ };
64
+ function slugify(value) {
65
+ return value
66
+ .toLowerCase()
67
+ .replace(/\s+/g, "-")
68
+ .replace(/[^a-z0-9_\-.]/g, "")
69
+ .replace(/-+/g, "-")
70
+ .replace(/^-|-$/g, "");
71
+ }
72
+ function determineAssetType(mime) {
73
+ if (!mime) {
74
+ return "image";
75
+ }
76
+ if (mime === SVG_MIME) {
77
+ return "svg";
78
+ }
79
+ if (IMAGE_MIME_SET.has(mime)) {
80
+ return "image";
81
+ }
82
+ if (VIDEO_MIME_PREFIXES.some((prefix) => mime.startsWith(prefix))) {
83
+ return "video";
84
+ }
85
+ if (DOCUMENT_MIME_SET.has(mime)) {
86
+ return "document";
87
+ }
88
+ return "image";
89
+ }
90
+ function isImageAsset(type, mime) {
91
+ return type === "image" || mime.startsWith("image/");
92
+ }
93
+ function sanitizeSvgContent(svg) {
94
+ const sanitized = (0, sanitize_html_1.default)(svg.toString("utf-8"), {
95
+ allowedTags: sanitize_html_1.default.defaults.allowedTags.concat([
96
+ "svg",
97
+ "path",
98
+ "circle",
99
+ "rect",
100
+ "polygon",
101
+ "line",
102
+ "polyline",
103
+ "g",
104
+ "defs",
105
+ "linearGradient",
106
+ "radialGradient",
107
+ "stop",
108
+ "use",
109
+ ]),
110
+ allowedSchemes: ["http", "https", "data"],
111
+ allowedAttributes: {
112
+ "*": [
113
+ "class",
114
+ "style",
115
+ "fill",
116
+ "stroke",
117
+ "stroke-width",
118
+ "d",
119
+ "viewBox",
120
+ "xmlns",
121
+ "width",
122
+ "height",
123
+ "x",
124
+ "y",
125
+ "rx",
126
+ "ry",
127
+ "points",
128
+ "x1",
129
+ "x2",
130
+ "y1",
131
+ "y2",
132
+ "gradientUnits",
133
+ "gradientTransform",
134
+ "offset",
135
+ "stop-color",
136
+ "stop-opacity",
137
+ "transform",
138
+ "href",
139
+ ],
140
+ },
141
+ });
142
+ return Buffer.from(sanitized);
143
+ }
144
+ async function extractImageMetadata(buffer) {
145
+ const metadata = await (0, sharp_1.default)(buffer).metadata();
146
+ return {
147
+ width: metadata.width ?? null,
148
+ height: metadata.height ?? null,
149
+ format: metadata.format ?? null,
150
+ hasAlpha: metadata.hasAlpha ?? false,
151
+ };
152
+ }
153
+ async function detectMimeFromBuffer(buffer) {
154
+ try {
155
+ const fileType = await import("file-type");
156
+ const result = await fileType.fileTypeFromBuffer(buffer);
157
+ return result?.mime;
158
+ }
159
+ catch {
160
+ return undefined;
161
+ }
162
+ }
163
+ async function generateVariantBuffer({ buffer, preset, format, focalPoint, }) {
164
+ let pipeline = (0, sharp_1.default)(buffer);
165
+ if (preset.width || preset.height) {
166
+ pipeline = pipeline.resize({
167
+ width: preset.width,
168
+ height: preset.height,
169
+ fit: preset.fit ?? "cover",
170
+ withoutEnlargement: preset.withoutEnlargement ?? true,
171
+ });
172
+ }
173
+ const quality = preset.quality ?? 80;
174
+ switch (format) {
175
+ case "jpeg":
176
+ pipeline = pipeline.jpeg({
177
+ quality,
178
+ mozjpeg: true,
179
+ });
180
+ break;
181
+ case "png":
182
+ pipeline = pipeline.png({
183
+ compressionLevel: 9,
184
+ });
185
+ break;
186
+ case "webp":
187
+ pipeline = pipeline.webp({
188
+ quality,
189
+ });
190
+ break;
191
+ case "avif":
192
+ pipeline = pipeline.avif({
193
+ quality,
194
+ });
195
+ break;
196
+ }
197
+ const output = await pipeline.toBuffer();
198
+ const meta = await (0, sharp_1.default)(output).metadata();
199
+ return {
200
+ buffer: output,
201
+ width: meta.width ?? preset.width ?? null,
202
+ height: meta.height ?? preset.height ?? null,
203
+ mime: format === "jpeg" ? "image/jpeg" : `image/${format}`,
204
+ };
205
+ }
206
+ class MediaManagerModuleService extends (0, utils_1.MedusaService)({
207
+ MediaAsset: models_1.MediaAsset,
208
+ MediaVariant: models_1.MediaVariant,
209
+ MediaFolder: models_1.MediaFolder,
210
+ MediaTag: models_1.MediaTag,
211
+ MediaAssetTag: models_1.MediaAssetTag,
212
+ MediaAssetRelation: models_1.MediaAssetRelation,
213
+ MediaAssetVersion: models_1.MediaAssetVersion,
214
+ MediaActivityLog: models_1.MediaActivityLog,
215
+ }) {
216
+ constructor({ logger }, options) {
217
+ super(...arguments);
218
+ this.logger_ = logger;
219
+ const storageOptions = {
220
+ ...DEFAULT_OPTIONS.storage,
221
+ ...(options?.storage ?? {}),
222
+ };
223
+ const presets = options?.presets && options.presets.length
224
+ ? options.presets
225
+ : DEFAULT_PRESETS;
226
+ const generateMode = options?.generate?.mode ?? DEFAULT_OPTIONS.generate?.mode ?? "eager";
227
+ const svgOptions = {
228
+ sanitize: options?.svg?.sanitize ?? DEFAULT_OPTIONS.svg?.sanitize ?? true,
229
+ allowedTags: options?.svg?.allowedTags ?? DEFAULT_OPTIONS.svg?.allowedTags,
230
+ allowedAttributes: options?.svg?.allowedAttributes ??
231
+ DEFAULT_OPTIONS.svg?.allowedAttributes,
232
+ };
233
+ const moderationOptions = {
234
+ enabled: options?.moderation?.enabled ??
235
+ DEFAULT_OPTIONS.moderation?.enabled ??
236
+ true,
237
+ };
238
+ const rbacOptions = {
239
+ deleteRequiresNoUsage: options?.rbac?.deleteRequiresNoUsage ??
240
+ DEFAULT_OPTIONS.rbac?.deleteRequiresNoUsage ??
241
+ true,
242
+ };
243
+ this.options_ = {
244
+ ...DEFAULT_OPTIONS,
245
+ ...options,
246
+ storage: storageOptions,
247
+ presets,
248
+ generate: { mode: generateMode },
249
+ svg: svgOptions,
250
+ moderation: moderationOptions,
251
+ rbac: rbacOptions,
252
+ };
253
+ this.storageDriver_ = (0, providers_1.createStorageDriver)(this.options_.storage);
254
+ this.storageDriver_.ensureReady().catch((err) => {
255
+ this.logger_.warn(`Failed to ensure media storage driver readiness: ${err.message}`);
256
+ });
257
+ }
258
+ // =============================================================================
259
+ // Asset Creation & Upload
260
+ // =============================================================================
261
+ async createAssetsFromUpload(input) {
262
+ if (!input.files?.length) {
263
+ throw new utils_1.MedusaError(utils_1.MedusaErrorTypes.INVALID_DATA, "No files provided for media upload");
264
+ }
265
+ const dedupeResults = [];
266
+ for (const file of input.files) {
267
+ const processed = await this.processSingleUpload(file, {
268
+ folderId: input.folderId,
269
+ visibility: input.visibility ?? "public",
270
+ status: input.status ?? "draft",
271
+ createdBy: input.createdBy,
272
+ metadata: input.metadata,
273
+ custom: input.custom,
274
+ tags: input.tags,
275
+ locale: input.locale,
276
+ });
277
+ dedupeResults.push(processed);
278
+ }
279
+ return dedupeResults;
280
+ }
281
+ async processSingleUpload(file, options) {
282
+ const normalizedBuffer = await this.normalizeBuffer(file);
283
+ const checksum = crypto_1.default
284
+ .createHash("sha256")
285
+ .update(normalizedBuffer)
286
+ .digest("hex");
287
+ const [existing] = await this.listMediaAssets({ checksum_sha256: checksum }, { take: 1 });
288
+ if (existing) {
289
+ await this.recordActivity(existing.id, "asset.reuse", {
290
+ checksum,
291
+ filename: file.filename,
292
+ });
293
+ if (options.tags?.length) {
294
+ await this.applyTags(existing.id, options.tags);
295
+ }
296
+ return {
297
+ asset: existing,
298
+ variants: await this.listMediaVariants({
299
+ asset_id: existing.id,
300
+ status: "generated",
301
+ }),
302
+ reused: true,
303
+ };
304
+ }
305
+ const detectedMime = await detectMimeFromBuffer(normalizedBuffer);
306
+ const mimeType = file.mimeType || detectedMime || "application/octet-stream";
307
+ const type = determineAssetType(mimeType);
308
+ const isImage = isImageAsset(type, mimeType);
309
+ const shouldSanitizeSvg = type === "svg" && this.options_.svg?.sanitize !== false;
310
+ const sanitizedBuffer = shouldSanitizeSvg && mimeType === SVG_MIME
311
+ ? sanitizeSvgContent(normalizedBuffer)
312
+ : normalizedBuffer;
313
+ const imageMeta = isImage
314
+ ? await extractImageMetadata(sanitizedBuffer).catch(() => ({
315
+ width: null,
316
+ height: null,
317
+ format: null,
318
+ }))
319
+ : { width: null, height: null, format: null };
320
+ const assetId = (0, uuid_1.v4)();
321
+ const safeName = slugify(file.filename || `${assetId}.bin`);
322
+ const storageKey = path_1.default
323
+ .join("media", assetId, "original", safeName)
324
+ .replace(/\\/g, "/");
325
+ const uploadResult = await this.storageDriver_.upload(storageKey, sanitizedBuffer, mimeType);
326
+ const createdAssets = (await this.createMediaAssets([
327
+ {
328
+ id: assetId,
329
+ storage_key: uploadResult.key,
330
+ original_filename: file.filename,
331
+ mime: mimeType,
332
+ type,
333
+ size_bytes: sanitizedBuffer.byteLength,
334
+ width: imageMeta.width,
335
+ height: imageMeta.height,
336
+ checksum_sha256: checksum,
337
+ visibility: options.visibility,
338
+ status: options.status,
339
+ folder_id: options.folderId ?? null,
340
+ title: options.metadata?.title ?? null,
341
+ alt_text: options.metadata?.altText ?? null,
342
+ caption: options.metadata?.caption ?? null,
343
+ custom: options.custom ?? null,
344
+ metadata: {
345
+ ...options.metadata,
346
+ reuse_checksum: checksum,
347
+ source_mime: mimeType,
348
+ detected_format: imageMeta.format,
349
+ },
350
+ created_by: options.createdBy,
351
+ uploaded_at: new Date(),
352
+ processing_state: "pending",
353
+ },
354
+ ]));
355
+ const asset = createdAssets[0];
356
+ if (options.tags?.length) {
357
+ await this.applyTags(asset.id, options.tags);
358
+ }
359
+ await this.recordActivity(asset.id, "asset.created", {
360
+ filename: file.filename,
361
+ checksum,
362
+ mimeType,
363
+ size: sanitizedBuffer.byteLength,
364
+ });
365
+ let variants = [];
366
+ if (isImage && this.shouldGenerateVariantsEagerly()) {
367
+ variants = await this.generateAndPersistVariants({
368
+ asset,
369
+ buffer: sanitizedBuffer,
370
+ mimeType,
371
+ focalPoint: null,
372
+ });
373
+ await this.updateMediaAssets({
374
+ selector: { id: asset.id },
375
+ data: {
376
+ processing_state: "processed",
377
+ },
378
+ });
379
+ }
380
+ else if (isImage) {
381
+ await this.queueVariantPlaceholders(asset);
382
+ }
383
+ return { asset, variants, reused: false };
384
+ }
385
+ async normalizeBuffer(file) {
386
+ if (Buffer.isBuffer(file.buffer)) {
387
+ return file.buffer;
388
+ }
389
+ if (typeof file.buffer === "string") {
390
+ return Buffer.from(file.buffer, "binary");
391
+ }
392
+ throw new utils_1.MedusaError(utils_1.MedusaErrorTypes.INVALID_DATA, `Unsupported buffer type for file ${file.filename}`);
393
+ }
394
+ shouldGenerateVariantsEagerly() {
395
+ return this.options_.generate?.mode !== "lazy";
396
+ }
397
+ async queueVariantPlaceholders(asset) {
398
+ const placeholderPayloads = this.options_.presets.map((preset) => ({
399
+ asset_id: asset.id,
400
+ preset: preset.name,
401
+ format: preset.format ?? "jpeg",
402
+ status: "pending",
403
+ generated_at: null,
404
+ }));
405
+ if (placeholderPayloads.length) {
406
+ await this.createMediaVariants(placeholderPayloads);
407
+ }
408
+ }
409
+ async generateAndPersistVariants({ asset, buffer, mimeType, focalPoint, }) {
410
+ const variants = [];
411
+ const metadata = await (0, sharp_1.default)(buffer).metadata();
412
+ const sourceFormat = metadata.format ?? mimeType.split("/").pop();
413
+ const variantFormats = VARIANT_FORMAT_PIPELINE[sourceFormat ?? ""] ??
414
+ VARIANT_FORMAT_PIPELINE.default;
415
+ const variantPayloads = [];
416
+ for (const preset of this.options_.presets) {
417
+ for (const format of variantFormats) {
418
+ const variantBuffer = await generateVariantBuffer({
419
+ assetId: asset.id,
420
+ buffer,
421
+ preset,
422
+ format,
423
+ originalMime: mimeType,
424
+ focalPoint: focalPoint ?? null,
425
+ });
426
+ const variantChecksum = crypto_1.default
427
+ .createHash("sha256")
428
+ .update(variantBuffer.buffer)
429
+ .digest("hex");
430
+ const variantKey = path_1.default
431
+ .join("media", asset.id, "variants", preset.name, `${preset.name}.${format}`)
432
+ .replace(/\\/g, "/");
433
+ const uploadResult = await this.storageDriver_.upload(variantKey, variantBuffer.buffer, variantBuffer.mime);
434
+ variantPayloads.push({
435
+ asset_id: asset.id,
436
+ preset: preset.name,
437
+ format,
438
+ width: variantBuffer.width,
439
+ height: variantBuffer.height,
440
+ size_bytes: variantBuffer.buffer.byteLength,
441
+ storage_key: uploadResult.key,
442
+ checksum_sha256: variantChecksum,
443
+ status: "generated",
444
+ generated_at: new Date(),
445
+ });
446
+ }
447
+ }
448
+ if (variantPayloads.length) {
449
+ const created = (await this.createMediaVariants(variantPayloads));
450
+ variants.push(...created);
451
+ }
452
+ await this.recordActivity(asset.id, "asset.variants.generated", {
453
+ presets: this.options_.presets.map((preset) => preset.name),
454
+ });
455
+ return variants;
456
+ }
457
+ // =============================================================================
458
+ // Metadata & Tag Management
459
+ // =============================================================================
460
+ async updateAssetMetadata(id, updates) {
461
+ const asset = await this.retrieveMediaAsset(id);
462
+ if (!asset) {
463
+ throw new utils_1.MedusaError(utils_1.MedusaErrorTypes.NOT_FOUND, "Asset not found");
464
+ }
465
+ const data = {};
466
+ if (updates.title !== undefined)
467
+ data.title = updates.title;
468
+ if (updates.altText !== undefined)
469
+ data.alt_text = updates.altText;
470
+ if (updates.caption !== undefined)
471
+ data.caption = updates.caption;
472
+ if (updates.custom !== undefined)
473
+ data.custom = updates.custom;
474
+ if (updates.status)
475
+ data.status = updates.status;
476
+ if (updates.visibility)
477
+ data.visibility = updates.visibility;
478
+ if (updates.folderId !== undefined)
479
+ data.folder_id = updates.folderId;
480
+ if (updates.focalPoint) {
481
+ data.focal_x = updates.focalPoint?.x ?? null;
482
+ data.focal_y = updates.focalPoint?.y ?? null;
483
+ }
484
+ if (Object.keys(data).length) {
485
+ await this.updateMediaAssets({
486
+ selector: { id },
487
+ data,
488
+ });
489
+ }
490
+ if (updates.tags) {
491
+ await this.applyTags(id, updates.tags);
492
+ }
493
+ await this.recordActivity(id, "asset.updated", { updates });
494
+ return this.retrieveMediaAsset(id, {
495
+ relations: ["variants", "tag_links.tag", "folder"],
496
+ });
497
+ }
498
+ async applyTags(assetId, tags) {
499
+ const normalized = [...new Set(tags.map((tag) => tag.trim()))].filter(Boolean);
500
+ if (!normalized.length) {
501
+ return;
502
+ }
503
+ const existingTags = await this.listMediaTags({
504
+ name: normalized,
505
+ });
506
+ const missing = normalized.filter((tag) => !existingTags.find((existing) => existing.name === tag));
507
+ let created = [];
508
+ if (missing.length) {
509
+ created = (await this.createMediaTags(missing.map((name) => ({
510
+ name,
511
+ }))));
512
+ }
513
+ const tagIds = [...existingTags, ...created].map((tag) => tag.id);
514
+ const currentLinks = await this.listMediaAssetTags({
515
+ asset_id: assetId,
516
+ });
517
+ const currentTagIds = new Set(currentLinks.map((link) => link.tag_id));
518
+ const toCreate = tagIds.filter((tagId) => !currentTagIds.has(tagId));
519
+ const toRemove = currentLinks
520
+ .filter((link) => !tagIds.includes(link.tag_id))
521
+ .map((link) => link.id);
522
+ if (toCreate.length) {
523
+ await this.createMediaAssetTags(toCreate.map((tagId) => ({
524
+ asset_id: assetId,
525
+ tag_id: tagId,
526
+ })));
527
+ }
528
+ if (toRemove.length) {
529
+ await this.deleteMediaAssetTags(toRemove);
530
+ }
531
+ }
532
+ // =============================================================================
533
+ // Replace & Versioning
534
+ // =============================================================================
535
+ async replaceAssetBinary(assetId, file, actorId) {
536
+ const asset = await this.retrieveMediaAsset(assetId, {
537
+ relations: ["variants"],
538
+ });
539
+ if (!asset) {
540
+ throw new utils_1.MedusaError(utils_1.MedusaErrorTypes.NOT_FOUND, "Asset not found");
541
+ }
542
+ const normalized = await this.normalizeBuffer(file);
543
+ const checksum = crypto_1.default
544
+ .createHash("sha256")
545
+ .update(normalized)
546
+ .digest("hex");
547
+ if (checksum === asset.checksum_sha256) {
548
+ return asset;
549
+ }
550
+ await this.createMediaAssetVersions([
551
+ {
552
+ asset_id: asset.id,
553
+ version: asset.version,
554
+ storage_key: asset.storage_key,
555
+ mime: asset.mime,
556
+ size_bytes: asset.size_bytes,
557
+ checksum_sha256: asset.checksum_sha256,
558
+ metadata: {
559
+ replaced_at: new Date().toISOString(),
560
+ },
561
+ },
562
+ ]);
563
+ const nextVersion = asset.version + 1;
564
+ const safeName = slugify(file.filename || asset.original_filename);
565
+ const storageKey = path_1.default
566
+ .join("media", asset.id, "original", `v${nextVersion}`, safeName)
567
+ .replace(/\\/g, "/");
568
+ const uploadResult = await this.storageDriver_.upload(storageKey, normalized, file.mimeType ?? asset.mime);
569
+ const updatedAsset = await this.updateMediaAssets({
570
+ selector: { id: asset.id },
571
+ data: {
572
+ storage_key: uploadResult.key,
573
+ original_filename: file.filename ?? asset.original_filename,
574
+ mime: file.mimeType ?? asset.mime,
575
+ size_bytes: normalized.byteLength,
576
+ checksum_sha256: checksum,
577
+ version: nextVersion,
578
+ processing_state: "pending",
579
+ updated_by: actorId,
580
+ },
581
+ });
582
+ const existingVariantIds = (asset.variants ?? []).map((variant) => variant.id);
583
+ if (existingVariantIds.length) {
584
+ await this.deleteMediaVariants(existingVariantIds);
585
+ }
586
+ for (const variant of asset.variants ?? []) {
587
+ if (variant.storage_key) {
588
+ await this.storageDriver_.delete(variant.storage_key);
589
+ }
590
+ }
591
+ let variants = [];
592
+ if (isImageAsset(asset.type, asset.mime)) {
593
+ variants = await this.generateAndPersistVariants({
594
+ asset: updatedAsset,
595
+ buffer: normalized,
596
+ mimeType: file.mimeType ?? asset.mime,
597
+ focalPoint: asset.focal_x !== null && asset.focal_y !== null
598
+ ? { x: asset.focal_x, y: asset.focal_y }
599
+ : null,
600
+ });
601
+ }
602
+ await this.recordActivity(asset.id, "asset.replaced", {
603
+ actorId,
604
+ version: nextVersion,
605
+ });
606
+ return {
607
+ asset: updatedAsset,
608
+ variants,
609
+ };
610
+ }
611
+ // =============================================================================
612
+ // Deletion & Usage Safety
613
+ // =============================================================================
614
+ async deleteAssetSafely(assetId, options = {}) {
615
+ const asset = await this.retrieveMediaAsset(assetId, {
616
+ relations: ["relations", "variants", "tag_links", "tag_links.tag"],
617
+ });
618
+ if (!asset) {
619
+ throw new utils_1.MedusaError(utils_1.MedusaErrorTypes.NOT_FOUND, "Asset not found");
620
+ }
621
+ if (this.options_.rbac?.deleteRequiresNoUsage &&
622
+ !options.force &&
623
+ asset.relations?.length) {
624
+ throw new utils_1.MedusaError(utils_1.MedusaErrorTypes.NOT_ALLOWED, "Asset is in use and cannot be deleted without force flag");
625
+ }
626
+ if (asset.relations?.length) {
627
+ await this.deleteMediaAssetRelations(asset.relations.map((relation) => relation.id));
628
+ }
629
+ if (asset.variants?.length) {
630
+ await this.deleteMediaVariants(asset.variants.map((variant) => variant.id));
631
+ for (const variant of asset.variants) {
632
+ if (variant.storage_key) {
633
+ await this.storageDriver_.delete(variant.storage_key);
634
+ }
635
+ }
636
+ }
637
+ if (asset.tag_links?.length) {
638
+ await this.deleteMediaAssetTags(asset.tag_links.map((link) => link.id));
639
+ }
640
+ await this.deleteMediaAssets([asset.id]);
641
+ await this.storageDriver_.delete(asset.storage_key);
642
+ await this.recordActivity(asset.id, "asset.deleted", {
643
+ actor: options.actorId,
644
+ });
645
+ }
646
+ // =============================================================================
647
+ // Search & Filters
648
+ // =============================================================================
649
+ async searchAssets(query, config = {}) {
650
+ const selector = {};
651
+ if (query.type)
652
+ selector.type = query.type;
653
+ if (query.folder)
654
+ selector.folder_id = query.folder;
655
+ if (query.mime)
656
+ selector.mime = query.mime;
657
+ if (query.status)
658
+ selector.status = query.status;
659
+ if (query.visibility)
660
+ selector.visibility = query.visibility;
661
+ if (query.tags?.length)
662
+ selector["tag_links.tag.name"] = query.tags;
663
+ if (query.used !== undefined) {
664
+ selector["relations.id"] = query.used ? { $ne: null } : { $eq: null };
665
+ }
666
+ if (query.min_size !== undefined || query.max_size !== undefined) {
667
+ const sizeSelector = {};
668
+ if (query.min_size !== undefined)
669
+ sizeSelector["$gte"] = query.min_size;
670
+ if (query.max_size !== undefined)
671
+ sizeSelector["$lte"] = query.max_size;
672
+ selector.size_bytes = sizeSelector;
673
+ }
674
+ if (query.min_w !== undefined || query.max_w !== undefined) {
675
+ const widthSelector = {};
676
+ if (query.min_w !== undefined)
677
+ widthSelector["$gte"] = query.min_w;
678
+ if (query.max_w !== undefined)
679
+ widthSelector["$lte"] = query.max_w;
680
+ selector.width = widthSelector;
681
+ }
682
+ if (query.min_h !== undefined || query.max_h !== undefined) {
683
+ const heightSelector = {};
684
+ if (query.min_h !== undefined)
685
+ heightSelector["$gte"] = query.min_h;
686
+ if (query.max_h !== undefined)
687
+ heightSelector["$lte"] = query.max_h;
688
+ selector.height = heightSelector;
689
+ }
690
+ if (query.used !== undefined) {
691
+ selector["relations.id"] = query.used ? { $ne: null } : null;
692
+ }
693
+ if (query.q) {
694
+ selector.$or = [
695
+ { original_filename: { $ilike: `%${query.q}%` } },
696
+ { "tag_links.tag.name": { $ilike: `%${query.q}%` } },
697
+ { title: { $contains: query.q } },
698
+ { caption: { $contains: query.q } },
699
+ ];
700
+ }
701
+ return this.listAndCountMediaAssets(selector, {
702
+ ...config,
703
+ relations: ["variants", "tag_links.tag", "folder", "relations"],
704
+ });
705
+ }
706
+ // =============================================================================
707
+ // URL Helpers
708
+ // =============================================================================
709
+ async getAssetUrl(assetId, options = {}) {
710
+ const asset = await this.retrieveMediaAsset(assetId, {
711
+ relations: ["variants"],
712
+ });
713
+ if (!asset) {
714
+ throw new utils_1.MedusaError(utils_1.MedusaErrorTypes.NOT_FOUND, "Asset not found");
715
+ }
716
+ if (options.variant) {
717
+ const variant = asset.variants?.find((v) => v.preset === options.variant && v.status === "generated");
718
+ if (!variant || !variant.storage_key) {
719
+ throw new utils_1.MedusaError(utils_1.MedusaErrorTypes.NOT_FOUND, `Variant ${options.variant} not found`);
720
+ }
721
+ return options.signed
722
+ ? this.storageDriver_.getSignedUrl(variant.storage_key, {
723
+ expiresInSeconds: options.expiresInSeconds,
724
+ variant: options.variant,
725
+ })
726
+ : this.storageDriver_.getPublicUrl(variant.storage_key);
727
+ }
728
+ if (asset.visibility === "private" || options.signed) {
729
+ return this.storageDriver_.getSignedUrl(asset.storage_key, {
730
+ expiresInSeconds: options.expiresInSeconds,
731
+ });
732
+ }
733
+ return (this.storageDriver_.getPublicUrl(asset.storage_key) ??
734
+ this.storageDriver_.getSignedUrl(asset.storage_key, {
735
+ expiresInSeconds: options.expiresInSeconds,
736
+ }));
737
+ }
738
+ // =============================================================================
739
+ // Relations & Usage
740
+ // =============================================================================
741
+ async reportUsage(assetId) {
742
+ const relations = await this.listMediaAssetRelations({
743
+ asset_id: assetId,
744
+ });
745
+ return {
746
+ count: relations.length,
747
+ relations,
748
+ };
749
+ }
750
+ async linkAsset(assetId, relation) {
751
+ await this.createMediaAssetRelations([
752
+ {
753
+ asset_id: assetId,
754
+ entity_type: relation.entityType,
755
+ entity_id: relation.entityId,
756
+ relation_role: relation.role ?? "primary",
757
+ },
758
+ ]);
759
+ await this.recordActivity(assetId, "asset.linked", relation);
760
+ }
761
+ async unlinkAsset(relationId) {
762
+ await this.deleteMediaAssetRelations([relationId]);
763
+ }
764
+ // =============================================================================
765
+ // Activity & Audit
766
+ // =============================================================================
767
+ async recordActivity(assetId, action, metadata = {}) {
768
+ await this.createMediaActivityLogs([
769
+ {
770
+ asset_id: assetId,
771
+ action,
772
+ metadata,
773
+ },
774
+ ]);
775
+ }
776
+ }
777
+ exports.default = MediaManagerModuleService;
778
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9tb2R1bGVzL21lZGlhLW1hbmFnZXIvc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLG9EQUE0QjtBQUM1QixnREFBd0I7QUFDeEIsa0RBQTBCO0FBQzFCLGtFQUF5QztBQUN6QywrQkFBa0M7QUFDbEMscURBSW1DO0FBYW5DLHFDQVNrQjtBQUVsQiwrQ0FBc0Q7QUF1QnRELE1BQU0sZUFBZSxHQUF5QjtJQUM1QztRQUNFLElBQUksRUFBRSxXQUFXO1FBQ2pCLEtBQUssRUFBRSxHQUFHO1FBQ1YsTUFBTSxFQUFFLEdBQUc7UUFDWCxHQUFHLEVBQUUsT0FBTztRQUNaLGtCQUFrQixFQUFFLElBQUk7S0FDekI7SUFDRCxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxrQkFBa0IsRUFBRSxJQUFJLEVBQUU7SUFDdkQsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsa0JBQWtCLEVBQUUsSUFBSSxFQUFFO0lBQ3pELEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLGtCQUFrQixFQUFFLElBQUksRUFBRTtDQUN6RCxDQUFDO0FBRUYsTUFBTSxlQUFlLEdBQWtCO0lBQ3JDLE9BQU8sRUFBRTtRQUNQLE1BQU0sRUFBRSxPQUFPO0tBQ2hCO0lBQ0QsT0FBTyxFQUFFLGVBQWU7SUFDeEIsUUFBUSxFQUFFO1FBQ1IsSUFBSSxFQUFFLE9BQU87S0FDZDtJQUNELEdBQUcsRUFBRTtRQUNILFFBQVEsRUFBRSxJQUFJO0tBQ2Y7SUFDRCxVQUFVLEVBQUU7UUFDVixPQUFPLEVBQUUsSUFBSTtLQUNkO0lBQ0QsSUFBSSxFQUFFO1FBQ0oscUJBQXFCLEVBQUUsSUFBSTtLQUM1QjtDQUNGLENBQUM7QUFFRixNQUFNLGNBQWMsR0FBRyxJQUFJLEdBQUcs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