harden media
This commit is contained in:
127
adapters/media/MediaResolverAdapter.ts
Normal file
127
adapters/media/MediaResolverAdapter.ts
Normal file
@@ -0,0 +1,127 @@
|
||||
/**
|
||||
* MediaResolverAdapter (Composite)
|
||||
*
|
||||
* Composite adapter that delegates resolution to type-specific adapters.
|
||||
* This is the main entry point for media resolution.
|
||||
*/
|
||||
|
||||
import { MediaResolverPort } from '@core/ports/media/MediaResolverPort';
|
||||
import { MediaReference } from '@core/domain/media/MediaReference';
|
||||
import { DefaultMediaResolverAdapter } from './resolvers/DefaultMediaResolverAdapter';
|
||||
import { GeneratedMediaResolverAdapter } from './resolvers/GeneratedMediaResolverAdapter';
|
||||
import { UploadedMediaResolverAdapter } from './resolvers/UploadedMediaResolverAdapter';
|
||||
|
||||
/**
|
||||
* Configuration for the composite MediaResolverAdapter
|
||||
*/
|
||||
export interface MediaResolverAdapterConfig {
|
||||
/**
|
||||
* Base path for default assets (defaults to '/media/default')
|
||||
*/
|
||||
defaultPath?: string;
|
||||
|
||||
/**
|
||||
* Base path for generated assets (defaults to '/media/generated')
|
||||
*/
|
||||
generatedPath?: string;
|
||||
|
||||
/**
|
||||
* Base path for uploaded assets (defaults to '/media/uploaded')
|
||||
*/
|
||||
uploadedPath?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* MediaResolverAdapter
|
||||
*
|
||||
* Composite adapter that delegates to type-specific resolvers.
|
||||
* Implements the MediaResolverPort interface.
|
||||
*
|
||||
* Returns path-only URLs (e.g., /media/teams/123/logo) without baseUrl.
|
||||
*
|
||||
* Usage:
|
||||
* ```typescript
|
||||
* const resolver = new MediaResolverAdapter({
|
||||
* defaultPath: '/media/default',
|
||||
* generatedPath: '/media/generated',
|
||||
* uploadedPath: '/media/uploaded'
|
||||
* });
|
||||
*
|
||||
* const path = await resolver.resolve(mediaReference);
|
||||
* ```
|
||||
*/
|
||||
export class MediaResolverAdapter implements MediaResolverPort {
|
||||
private readonly defaultResolver: DefaultMediaResolverAdapter;
|
||||
private readonly generatedResolver: GeneratedMediaResolverAdapter;
|
||||
private readonly uploadedResolver: UploadedMediaResolverAdapter;
|
||||
|
||||
constructor(config: MediaResolverAdapterConfig = {}) {
|
||||
// Initialize type-specific resolvers
|
||||
this.defaultResolver = new DefaultMediaResolverAdapter({
|
||||
basePath: config.defaultPath
|
||||
});
|
||||
|
||||
this.generatedResolver = new GeneratedMediaResolverAdapter({
|
||||
basePath: config.generatedPath
|
||||
});
|
||||
|
||||
this.uploadedResolver = new UploadedMediaResolverAdapter({
|
||||
basePath: config.uploadedPath
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a media reference to a path-only URL
|
||||
*
|
||||
* Delegates to the appropriate type-specific resolver based on the reference type.
|
||||
* Returns paths like /media/... (no baseUrl).
|
||||
*/
|
||||
async resolve(ref: MediaReference): Promise<string | null> {
|
||||
if (!ref) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Delegate to the appropriate resolver based on type
|
||||
switch (ref.type) {
|
||||
case 'system-default':
|
||||
return this.defaultResolver.resolve(ref);
|
||||
|
||||
case 'generated':
|
||||
return this.generatedResolver.resolve(ref);
|
||||
|
||||
case 'uploaded':
|
||||
return this.uploadedResolver.resolve(ref);
|
||||
|
||||
case 'none':
|
||||
return null;
|
||||
|
||||
default:
|
||||
// Unknown type
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory function for creating MediaResolverAdapter instances
|
||||
*/
|
||||
export function createMediaResolver(
|
||||
config: MediaResolverAdapterConfig = {}
|
||||
): MediaResolverAdapter {
|
||||
return new MediaResolverAdapter(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default configuration for development/testing
|
||||
*/
|
||||
export const DefaultResolvers = {
|
||||
/**
|
||||
* Creates a resolver for local development
|
||||
*/
|
||||
local: () => createMediaResolver({}),
|
||||
|
||||
/**
|
||||
* Creates a resolver for production
|
||||
*/
|
||||
production: () => createMediaResolver({})
|
||||
};
|
||||
Reference in New Issue
Block a user