Skip to content

Commit

Permalink
feat(asset-server-plugin): Allow assetUrlPrefix to be a function
Browse files Browse the repository at this point in the history
Closes #766
  • Loading branch information
michaelbromley committed Mar 16, 2021
1 parent 56bcbff commit 10eb014
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 5 deletions.
22 changes: 22 additions & 0 deletions packages/asset-server-plugin/src/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { REQUEST_CONTEXT_KEY } from '@vendure/core/dist/common/constants';
import { Request } from 'express';

import { AssetServerOptions } from './types';

export function getAssetUrlPrefixFn(options: AssetServerOptions) {
const { assetUrlPrefix, route } = options;
if (assetUrlPrefix == null) {
return (request: Request, identifier: string) =>
`${request.protocol}://${request.get('host')}/${route}/`;
}
if (typeof assetUrlPrefix === 'string') {
return (...args: any[]) => assetUrlPrefix;
}
if (typeof assetUrlPrefix === 'function') {
return (request: Request, identifier: string) => {
const ctx = (request as any)[REQUEST_CONTEXT_KEY];
return assetUrlPrefix(ctx, identifier);
};
}
throw new Error(`The assetUrlPrefix option was of an unexpected type: ${JSON.stringify(assetUrlPrefix)}`);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Request } from 'express';

import { getAssetUrlPrefixFn } from './common';
import { LocalAssetStorageStrategy } from './local-asset-storage-strategy';
import { AssetServerOptions } from './types';

Expand All @@ -8,11 +9,12 @@ import { AssetServerOptions } from './types';
*/
export function defaultAssetStorageStrategyFactory(options: AssetServerOptions) {
const { assetUrlPrefix, assetUploadDir, route } = options;
const prefixFn = getAssetUrlPrefixFn(options);
const toAbsoluteUrlFn = (request: Request, identifier: string): string => {
if (!identifier) {
return '';
}
const prefix = assetUrlPrefix || `${request.protocol}://${request.get('host')}/${route}/`;
const prefix = prefixFn(request, identifier);
return identifier.startsWith(prefix) ? identifier : `${prefix}${identifier}`;
};
return new LocalAssetStorageStrategy(assetUploadDir, toAbsoluteUrlFn);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Request } from 'express';
import * as path from 'path';
import { Readable, Stream } from 'stream';

import { getAssetUrlPrefixFn } from './common';
import { loggerCtx } from './constants';
import { AssetServerOptions } from './types';

Expand Down Expand Up @@ -94,11 +95,12 @@ export interface S3Config {
export function configureS3AssetStorage(s3Config: S3Config) {
return (options: AssetServerOptions) => {
const { assetUrlPrefix, route } = options;
const prefixFn = getAssetUrlPrefixFn(options);
const toAbsoluteUrlFn = (request: Request, identifier: string): string => {
if (!identifier) {
return '';
}
const prefix = assetUrlPrefix || `${request.protocol}://${request.get('host')}/${route}/`;
const prefix = prefixFn(request, identifier);
return identifier.startsWith(prefix) ? identifier : `${prefix}${identifier}`;
};
return new S3AssetStorageStrategy(s3Config, toAbsoluteUrlFn);
Expand Down
8 changes: 5 additions & 3 deletions packages/asset-server-plugin/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AssetNamingStrategy, AssetStorageStrategy } from '@vendure/core';
import { AssetNamingStrategy, AssetStorageStrategy, RequestContext } from '@vendure/core';

/**
* @description
Expand Down Expand Up @@ -56,13 +56,15 @@ export interface AssetServerOptions {
assetUploadDir: string; // TODO: this is strategy-specific and should be moved out of the global options
/**
* @description
* The complete URL prefix of the asset files. For example, "https://demo.vendure.io/assets/"
* The complete URL prefix of the asset files. For example, "https://demo.vendure.io/assets/". A
* function can also be provided to handle more complex cases, such as serving multiple domains
* from a single server. In this case, the function should return a string url prefix.
*
* If not provided, the plugin will attempt to guess based off the incoming
* request and the configured route. However, in all but the simplest cases,
* this guess may not yield correct results.
*/
assetUrlPrefix?: string;
assetUrlPrefix?: string | ((ctx: RequestContext, identifier: string) => string);
/**
* @description
* The max width in pixels of a generated preview image.
Expand Down

0 comments on commit 10eb014

Please sign in to comment.