mirror of
https://github.com/directus/directus.git
synced 2026-01-27 12:07:56 -05:00
* Allow custom transformations of assets This exposes one query parameter `transforms`, which is a JSON array of shard transformation operations. It also updates the asset presets. The UX for this still needs some work * Rename options to arguments for presets More explicit * options -> arguments in setting spec * Better errors for invalid JSON in asset presets * Add limit to transforms query parameter * Use flattened option for extra transforms * Fix placeholder color of code input * Allow "simple mode" aliases * Add documentation Co-authored-by: rijkvanzanten <rijkvanzanten@me.com>
69 lines
2.1 KiB
TypeScript
69 lines
2.1 KiB
TypeScript
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<T extends Record<string, any>>(keys: (keyof T)[], numberKeys: (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 : value,
|
|
}
|
|
: config,
|
|
{} as T
|
|
);
|
|
};
|
|
}
|
|
|
|
// Extract format transform from a preset
|
|
function extractToFormat(input: TransformationParams | TransformationPreset, file: File): Transformation | undefined {
|
|
const options = extractOptions<TransformationPresetFormat>(['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<TransformationPresetResize>(
|
|
['width', 'height', 'fit', 'withoutEnlargement'],
|
|
['width', 'height']
|
|
)(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;
|
|
}
|