sharp-asset-preview-strategy.ts 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. import { AssetType } from '@vendure/common/lib/generated-types';
  2. import { AssetPreviewStrategy, getAssetType } from '@vendure/core';
  3. import path from 'path';
  4. import sharp from 'sharp';
  5. export class SharpAssetPreviewStrategy implements AssetPreviewStrategy {
  6. constructor(
  7. private config: {
  8. maxHeight: number;
  9. maxWidth: number;
  10. },
  11. ) {}
  12. async generatePreviewImage(mimeType: string, data: Buffer): Promise<Buffer> {
  13. const assetType = getAssetType(mimeType);
  14. const { maxWidth, maxHeight } = this.config;
  15. if (assetType === AssetType.IMAGE) {
  16. const image = sharp(data);
  17. const metadata = await image.metadata();
  18. const width = metadata.width || 0;
  19. const height = metadata.height || 0;
  20. if (maxWidth < width || maxHeight < height) {
  21. return image.resize(maxWidth, maxHeight, { fit: 'inside' }).toBuffer();
  22. } else {
  23. return data;
  24. }
  25. } else {
  26. return sharp(path.join(__dirname, 'file-icon.png'))
  27. .resize(800, 800, { fit: 'outside' })
  28. .overlayWith(this.generateMimeTypeOverlay(mimeType), {
  29. gravity: sharp.gravity.center,
  30. })
  31. .toBuffer();
  32. }
  33. }
  34. private generateMimeTypeOverlay(mimeType: string): Buffer {
  35. return Buffer.from(`
  36. <svg xmlns="http://www.w3.org/2000/svg" height="150" width="800">
  37. <style>
  38. text {
  39. font-size: 64px;
  40. font-family: Arial, sans-serif;
  41. fill: #666;
  42. }
  43. </style>
  44. <text x="400" y="110" text-anchor="middle" width="800">${mimeType}</text>
  45. </svg>`);
  46. }
  47. }