import { isNil } from 'lodash'; import { File, Transformation, TransformationParams, TransformationPreset, TransformationPresetFormat, TransformationPresetResize, } from '../types'; // Extract transforms from a preset export function resolvePreset(input: TransformationParams | TransformationPreset, file: File): Transformation[] { // Do the format conversion last return [extractResize(input), ...(input.transforms ?? []), extractToFormat(input, file)].filter( (transform): transform is Transformation => transform !== undefined ); } function extractOptions>( keys: (keyof T)[], numberKeys: (keyof T)[] = [], booleanKeys: (keyof T)[] = [] ) { return function (input: TransformationParams | TransformationPreset): T { return Object.entries(input).reduce( (config, [key, value]) => keys.includes(key as any) && isNil(value) === false ? { ...config, [key]: numberKeys.includes(key as any) ? +value : booleanKeys.includes(key as any) ? Boolean(value) : value, } : config, {} as T ); }; } // Extract format transform from a preset function extractToFormat(input: TransformationParams | TransformationPreset, file: File): Transformation | undefined { const options = extractOptions(['format', 'quality'], ['quality'])(input); return Object.keys(options).length > 0 ? [ 'toFormat', options.format || (file.type!.split('/')[1] as any), { quality: options.quality, }, ] : undefined; } function extractResize(input: TransformationParams | TransformationPreset): Transformation | undefined { const resizable = ['width', 'height'].some((key) => key in input); if (!resizable) return undefined; return [ 'resize', extractOptions( ['width', 'height', 'fit', 'withoutEnlargement'], ['width', 'height'], ['withoutEnlargement'] )(input), ]; } /** * Try to extract a file format from an array of `Transformation`'s. */ export function maybeExtractFormat(transforms: Transformation[]): string | undefined { const toFormats = transforms.filter((t) => t[0] === 'toFormat'); const lastToFormat = toFormats[toFormats.length - 1]; return lastToFormat ? lastToFormat[1]?.toString() : undefined; }