Son CV dans un terminal web en Javascript!
https://terminal-cv.gregandev.fr
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
123 lines
3.4 KiB
123 lines
3.4 KiB
// @flow
|
|
import {validateConfig} from './validateConfig';
|
|
import {Transformer} from '@parcel/plugin';
|
|
import nullthrows from 'nullthrows';
|
|
import WorkerFarm from '@parcel/workers';
|
|
import loadSharp from './loadSharp';
|
|
|
|
// from https://github.com/lovell/sharp/blob/df7b8ba73808fc494be413e88cfb621b6279218c/lib/output.js#L6-L17
|
|
const FORMATS = new Map([
|
|
['jpeg', 'jpeg'],
|
|
['jpg', 'jpeg'],
|
|
['png', 'png'],
|
|
['webp', 'webp'],
|
|
['gif', 'gif'],
|
|
['tiff', 'tiff'],
|
|
['avif', 'avif'],
|
|
['heic', 'heif'],
|
|
['heif', 'heif'],
|
|
]);
|
|
|
|
let isSharpLoadedOnMainThread = false;
|
|
|
|
export default (new Transformer({
|
|
async loadConfig({config}) {
|
|
let configFile: any = await config.getConfig(
|
|
['sharp.config.json'], // '.sharprc', '.sharprc.json'
|
|
{packageKey: 'sharp'},
|
|
);
|
|
|
|
if (configFile?.contents) {
|
|
validateConfig(configFile.contents, configFile.filePath);
|
|
return configFile.contents;
|
|
} else {
|
|
return {};
|
|
}
|
|
},
|
|
|
|
async transform({config, asset, options}) {
|
|
asset.bundleBehavior = 'isolated';
|
|
|
|
const originalFormat = FORMATS.get(asset.type);
|
|
if (!originalFormat) {
|
|
throw new Error(
|
|
`The image transformer does not support ${asset.type} images.`,
|
|
);
|
|
}
|
|
|
|
const width = asset.query.has('width')
|
|
? parseInt(asset.query.get('width'), 10)
|
|
: null;
|
|
const height = asset.query.has('height')
|
|
? parseInt(asset.query.get('height'), 10)
|
|
: null;
|
|
const quality = asset.query.has('quality')
|
|
? parseInt(asset.query.get('quality'), 10)
|
|
: config.quality;
|
|
let targetFormat = asset.query
|
|
.get('as')
|
|
?.toLowerCase()
|
|
.trim();
|
|
if (targetFormat && !FORMATS.has(targetFormat)) {
|
|
throw new Error(
|
|
`The image transformer does not support ${targetFormat} images.`,
|
|
);
|
|
}
|
|
|
|
const format = nullthrows(FORMATS.get(targetFormat || originalFormat));
|
|
const outputOptions = config[format];
|
|
|
|
if (width || height || quality || targetFormat || outputOptions) {
|
|
// Sharp must be required from the main thread as well to prevent errors when workers exit
|
|
// See https://sharp.pixelplumbing.com/install#worker-threads and https://github.com/lovell/sharp/issues/2263
|
|
if (WorkerFarm.isWorker() && !isSharpLoadedOnMainThread) {
|
|
let api = WorkerFarm.getWorkerApi();
|
|
await api.callMaster({
|
|
location: __dirname + '/loadSharp.js',
|
|
args: [
|
|
options.packageManager,
|
|
asset.filePath,
|
|
options.shouldAutoInstall,
|
|
],
|
|
});
|
|
|
|
isSharpLoadedOnMainThread = true;
|
|
}
|
|
|
|
let inputBuffer = await asset.getBuffer();
|
|
let sharp = await loadSharp(
|
|
options.packageManager,
|
|
asset.filePath,
|
|
options.shouldAutoInstall,
|
|
true,
|
|
);
|
|
|
|
let imagePipeline = sharp(inputBuffer);
|
|
|
|
imagePipeline.withMetadata();
|
|
|
|
if (width || height) {
|
|
imagePipeline.resize(width, height);
|
|
}
|
|
|
|
imagePipeline.rotate();
|
|
|
|
const normalizedOutputOptions = outputOptions || {};
|
|
if (format === 'jpeg') {
|
|
normalizedOutputOptions.mozjpeg =
|
|
normalizedOutputOptions.mozjpeg ?? true;
|
|
}
|
|
imagePipeline[format]({
|
|
quality,
|
|
...normalizedOutputOptions,
|
|
});
|
|
|
|
asset.type = format;
|
|
|
|
let buffer = await imagePipeline.toBuffer();
|
|
asset.setBuffer(buffer);
|
|
}
|
|
|
|
return [asset];
|
|
},
|
|
}): Transformer);
|
|
|