Browse Source

feat(core): Pass RequestContext to AssetNamingStrategy functions

BREAKING CHANGE: The AssetNamingStrategy `generateSourceFileName()` & `generatePreviewFileName()`
function signatures have changed: the first argument is now the
RequestContext of the current request.
Michael Bromley 5 years ago
parent
commit
48ae3723bd

+ 10 - 9
packages/asset-server-plugin/src/hashed-asset-naming-strategy.ts

@@ -1,4 +1,4 @@
-import { DefaultAssetNamingStrategy } from '@vendure/core';
+import { DefaultAssetNamingStrategy, RequestContext } from '@vendure/core';
 import { createHash } from 'crypto';
 import path from 'path';
 
@@ -18,19 +18,20 @@ import path from 'path';
  * @docsCategory AssetServerPlugin
  */
 export class HashedAssetNamingStrategy extends DefaultAssetNamingStrategy {
-    generateSourceFileName(originalFileName: string, conflictFileName?: string): string {
-        const filename = super.generateSourceFileName(originalFileName, conflictFileName);
+    generateSourceFileName(ctx: RequestContext, originalFileName: string, conflictFileName?: string): string {
+        const filename = super.generateSourceFileName(ctx, originalFileName, conflictFileName);
         return path.join('source', this.getHashedDir(filename), filename);
     }
-    generatePreviewFileName(originalFileName: string, conflictFileName?: string): string {
-        const filename = super.generatePreviewFileName(originalFileName, conflictFileName);
+    generatePreviewFileName(
+        ctx: RequestContext,
+        originalFileName: string,
+        conflictFileName?: string,
+    ): string {
+        const filename = super.generatePreviewFileName(ctx, originalFileName, conflictFileName);
         return path.join('preview', this.getHashedDir(filename), filename);
     }
 
     private getHashedDir(filename: string): string {
-        return createHash('md5')
-            .update(filename)
-            .digest('hex')
-            .slice(0, 2);
+        return createHash('md5').update(filename).digest('hex').slice(0, 2);
     }
 }

+ 3 - 2
packages/core/src/config/asset-naming-strategy/asset-naming-strategy.ts

@@ -1,3 +1,4 @@
+import { RequestContext } from '../../api/common/request-context';
 import { InjectableStrategy } from '../../common/types/injectable-strategy';
 
 /**
@@ -19,7 +20,7 @@ export interface AssetNamingStrategy extends InjectableStrategy {
      * file name should then be generated. This process will repeat until a unique file name has
      * been returned.
      */
-    generateSourceFileName(originalFileName: string, conflictFileName?: string): string;
+    generateSourceFileName(ctx: RequestContext, originalFileName: string, conflictFileName?: string): string;
 
     /**
      * @description
@@ -28,5 +29,5 @@ export interface AssetNamingStrategy extends InjectableStrategy {
      *
      * The same mechanism of checking for conflicts is used as described above.
      */
-    generatePreviewFileName(sourceFileName: string, conflictFileName?: string): string;
+    generatePreviewFileName(ctx: RequestContext, sourceFileName: string, conflictFileName?: string): string;
 }

+ 24 - 20
packages/core/src/config/asset-naming-strategy/default-asset-naming-strategy.spec.ts

@@ -1,35 +1,39 @@
+import { RequestContext } from '../../api/common/request-context';
+
 import { DefaultAssetNamingStrategy } from './default-asset-naming-strategy';
 
 describe('DefaultAssetNamingStrategy', () => {
+    const ctx = RequestContext.empty();
+
     describe('generateSourceFileName()', () => {
         it('normalizes file names', () => {
             const strategy = new DefaultAssetNamingStrategy();
 
-            expect(strategy.generateSourceFileName('foo.jpg')).toBe('foo.jpg');
-            expect(strategy.generateSourceFileName('curaçao.jpg')).toBe('curacao.jpg');
-            expect(strategy.generateSourceFileName('dấu hỏi.jpg')).toBe('dau-hoi.jpg');
+            expect(strategy.generateSourceFileName(ctx, 'foo.jpg')).toBe('foo.jpg');
+            expect(strategy.generateSourceFileName(ctx, 'curaçao.jpg')).toBe('curacao.jpg');
+            expect(strategy.generateSourceFileName(ctx, 'dấu hỏi.jpg')).toBe('dau-hoi.jpg');
         });
 
         it('increments conflicting file names', () => {
             const strategy = new DefaultAssetNamingStrategy();
 
-            expect(strategy.generateSourceFileName('foo.jpg', 'foo.jpg')).toBe('foo__02.jpg');
-            expect(strategy.generateSourceFileName('foo.jpg', 'foo__02.jpg')).toBe('foo__03.jpg');
-            expect(strategy.generateSourceFileName('foo.jpg', 'foo__09.jpg')).toBe('foo__10.jpg');
-            expect(strategy.generateSourceFileName('foo.jpg', 'foo__99.jpg')).toBe('foo__100.jpg');
-            expect(strategy.generateSourceFileName('foo.jpg', 'foo__999.jpg')).toBe('foo__1000.jpg');
+            expect(strategy.generateSourceFileName(ctx, 'foo.jpg', 'foo.jpg')).toBe('foo__02.jpg');
+            expect(strategy.generateSourceFileName(ctx, 'foo.jpg', 'foo__02.jpg')).toBe('foo__03.jpg');
+            expect(strategy.generateSourceFileName(ctx, 'foo.jpg', 'foo__09.jpg')).toBe('foo__10.jpg');
+            expect(strategy.generateSourceFileName(ctx, 'foo.jpg', 'foo__99.jpg')).toBe('foo__100.jpg');
+            expect(strategy.generateSourceFileName(ctx, 'foo.jpg', 'foo__999.jpg')).toBe('foo__1000.jpg');
         });
 
         it('increments conflicting file names with no extension', () => {
             const strategy = new DefaultAssetNamingStrategy();
 
-            expect(strategy.generateSourceFileName('ext45000000000505', 'ext45000000000505')).toBe(
+            expect(strategy.generateSourceFileName(ctx, 'ext45000000000505', 'ext45000000000505')).toBe(
                 'ext45000000000505__02',
             );
-            expect(strategy.generateSourceFileName('ext45000000000505', 'ext45000000000505__02')).toBe(
+            expect(strategy.generateSourceFileName(ctx, 'ext45000000000505', 'ext45000000000505__02')).toBe(
                 'ext45000000000505__03',
             );
-            expect(strategy.generateSourceFileName('ext45000000000505', 'ext45000000000505__09')).toBe(
+            expect(strategy.generateSourceFileName(ctx, 'ext45000000000505', 'ext45000000000505__09')).toBe(
                 'ext45000000000505__10',
             );
         });
@@ -39,25 +43,25 @@ describe('DefaultAssetNamingStrategy', () => {
         it('adds the preview suffix', () => {
             const strategy = new DefaultAssetNamingStrategy();
 
-            expect(strategy.generatePreviewFileName('foo.jpg')).toBe('foo__preview.jpg');
+            expect(strategy.generatePreviewFileName(ctx, 'foo.jpg')).toBe('foo__preview.jpg');
         });
 
         it('preserves the extension of supported image files', () => {
             const strategy = new DefaultAssetNamingStrategy();
 
-            expect(strategy.generatePreviewFileName('foo.jpg')).toBe('foo__preview.jpg');
-            expect(strategy.generatePreviewFileName('foo.jpeg')).toBe('foo__preview.jpeg');
-            expect(strategy.generatePreviewFileName('foo.png')).toBe('foo__preview.png');
-            expect(strategy.generatePreviewFileName('foo.webp')).toBe('foo__preview.webp');
-            expect(strategy.generatePreviewFileName('foo.tiff')).toBe('foo__preview.tiff');
+            expect(strategy.generatePreviewFileName(ctx, 'foo.jpg')).toBe('foo__preview.jpg');
+            expect(strategy.generatePreviewFileName(ctx, 'foo.jpeg')).toBe('foo__preview.jpeg');
+            expect(strategy.generatePreviewFileName(ctx, 'foo.png')).toBe('foo__preview.png');
+            expect(strategy.generatePreviewFileName(ctx, 'foo.webp')).toBe('foo__preview.webp');
+            expect(strategy.generatePreviewFileName(ctx, 'foo.tiff')).toBe('foo__preview.tiff');
         });
 
         it('adds a png extension for unsupported images and other files', () => {
             const strategy = new DefaultAssetNamingStrategy();
 
-            expect(strategy.generatePreviewFileName('foo.svg')).toBe('foo__preview.svg.png');
-            expect(strategy.generatePreviewFileName('foo.gif')).toBe('foo__preview.gif.png');
-            expect(strategy.generatePreviewFileName('foo.pdf')).toBe('foo__preview.pdf.png');
+            expect(strategy.generatePreviewFileName(ctx, 'foo.svg')).toBe('foo__preview.svg.png');
+            expect(strategy.generatePreviewFileName(ctx, 'foo.gif')).toBe('foo__preview.gif.png');
+            expect(strategy.generatePreviewFileName(ctx, 'foo.pdf')).toBe('foo__preview.pdf.png');
         });
     });
 });

+ 4 - 2
packages/core/src/config/asset-naming-strategy/default-asset-naming-strategy.ts

@@ -1,6 +1,8 @@
 import { normalizeString } from '@vendure/common/lib/normalize-string';
 import path from 'path';
 
+import { RequestContext } from '../../api/common/request-context';
+
 import { AssetNamingStrategy } from './asset-naming-strategy';
 
 /**
@@ -13,7 +15,7 @@ import { AssetNamingStrategy } from './asset-naming-strategy';
 export class DefaultAssetNamingStrategy implements AssetNamingStrategy {
     private readonly numberingRe = /__(\d+)(\.[^.]+)?$/;
 
-    generateSourceFileName(originalFileName: string, conflictFileName?: string): string {
+    generateSourceFileName(ctx: RequestContext, originalFileName: string, conflictFileName?: string): string {
         const normalized = normalizeString(originalFileName, '-');
         if (!conflictFileName) {
             return normalized;
@@ -22,7 +24,7 @@ export class DefaultAssetNamingStrategy implements AssetNamingStrategy {
         }
     }
 
-    generatePreviewFileName(sourceFileName: string, conflictFileName?: string): string {
+    generatePreviewFileName(ctx: RequestContext, sourceFileName: string, conflictFileName?: string): string {
         const previewSuffix = '__preview';
         const previewFileName = this.isSupportedImageFormat(sourceFileName)
             ? this.addSuffix(sourceFileName, previewSuffix)

+ 6 - 6
packages/core/src/service/services/asset.service.ts

@@ -247,8 +247,8 @@ export class AssetService {
             return new MimeTypeError(filename, mimetype);
         }
         const { assetPreviewStrategy, assetStorageStrategy } = assetOptions;
-        const sourceFileName = await this.getSourceFileName(filename);
-        const previewFileName = await this.getPreviewFileName(sourceFileName);
+        const sourceFileName = await this.getSourceFileName(ctx, filename);
+        const previewFileName = await this.getPreviewFileName(ctx, sourceFileName);
 
         const sourceFileIdentifier = await assetStorageStrategy.writeFileFromStream(sourceFileName, stream);
         const sourceFile = await assetStorageStrategy.readFileToBuffer(sourceFileIdentifier);
@@ -280,17 +280,17 @@ export class AssetService {
         return this.connection.getRepository(ctx, Asset).save(asset);
     }
 
-    private async getSourceFileName(fileName: string): Promise<string> {
+    private async getSourceFileName(ctx: RequestContext, fileName: string): Promise<string> {
         const { assetOptions } = this.configService;
         return this.generateUniqueName(fileName, (name, conflict) =>
-            assetOptions.assetNamingStrategy.generateSourceFileName(name, conflict),
+            assetOptions.assetNamingStrategy.generateSourceFileName(ctx, name, conflict),
         );
     }
 
-    private async getPreviewFileName(fileName: string): Promise<string> {
+    private async getPreviewFileName(ctx: RequestContext, fileName: string): Promise<string> {
         const { assetOptions } = this.configService;
         return this.generateUniqueName(fileName, (name, conflict) =>
-            assetOptions.assetNamingStrategy.generatePreviewFileName(name, conflict),
+            assetOptions.assetNamingStrategy.generatePreviewFileName(ctx, name, conflict),
         );
     }