Allow custom transformations of assets (#6593)

* 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>
This commit is contained in:
Tim
2021-07-22 07:57:47 +12:00
committed by GitHub
parent 7dffa48570
commit 2c9ff3bca6
15 changed files with 387 additions and 118 deletions

View File

@@ -1,10 +1,84 @@
export type Transformation = {
import { ResizeOptions, Sharp } from 'sharp';
// List of allowed sharp methods to expose.
//
// This is a literal, so we can use it to validate request parameters.
export const TransformationMethods /*: readonly (keyof Sharp)[]*/ = [
// Output options
// https://sharp.pixelplumbing.com/api-output
'toFormat',
'jpeg',
'png',
'tiff',
'webp',
// Resizing
// https://sharp.pixelplumbing.com/api-resize
'resize',
'extend',
'extract',
'trim',
// Image operations
// https://sharp.pixelplumbing.com/api-operation
'rotate',
'flip',
'flop',
'sharpen',
'median',
'blur',
'flatten',
'gamma',
'negate',
'normalise',
'normalize',
'clahe',
'convolve',
'threshold',
'linear',
'recomb',
'modulate',
// Color manipulation
// https://sharp.pixelplumbing.com/api-colour
'tint',
'greyscale',
'grayscale',
'toColorspace',
'toColourspace',
// Channel manipulation
// https://sharp.pixelplumbing.com/api-channel
'removeAlpha',
'ensureAlpha',
'extractChannel',
'bandbool',
] as const;
// Helper types
type AllowedSharpMethods = Pick<Sharp, typeof TransformationMethods[number]>;
export type TransformationMap = {
[M in keyof AllowedSharpMethods]: readonly [M, ...Parameters<AllowedSharpMethods[M]>];
};
export type Transformation = TransformationMap[keyof TransformationMap];
export type TransformationParams = {
key?: string;
width?: number; // width
height?: number; // height
fit?: 'cover' | 'contain' | 'inside' | 'outside'; // fit
withoutEnlargement?: boolean; // Without Enlargement
transforms?: Transformation[];
};
// Transformation preset is defined in the admin UI.
export type TransformationPreset = TransformationPresetFormat &
TransformationPresetResize &
TransformationParams & { key: string };
export type TransformationPresetFormat = {
format?: 'jpg' | 'jpeg' | 'png' | 'webp' | 'tiff';
quality?: number;
};
// @NOTE Keys used in Transformation should match ASSET_GENERATION_QUERY_KEYS in constants.ts
export type TransformationPresetResize = Pick<ResizeOptions, 'width' | 'height' | 'fit' | 'withoutEnlargement'>;
// @NOTE Keys used in TransformationParams should match ASSET_GENERATION_QUERY_KEYS in constants.ts