Apply consistent Sharp library configuration (#23064)

* Apply consistent Sharp library configuration (#20995)

* rename useSharp to getSharpInstance

* Update changeset

* Update export style

---------

Co-authored-by: Pascal Jufer <pascal-jufer@bluewin.ch>
Co-authored-by: Rijk van Zanten <rijkvanzanten@me.com>
This commit is contained in:
insomnia.exe
2024-07-22 22:09:03 +03:00
committed by GitHub
parent 49c93b376d
commit 3a69bb7d02
6 changed files with 61 additions and 8 deletions

View File

@@ -0,0 +1,5 @@
---
'@directus/api': patch
---
Ensured `ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION` is also respected for extraction of metadata during image upload

View File

@@ -13,7 +13,6 @@ import { contentType } from 'mime-types';
import type { Readable } from 'node:stream';
import hash from 'object-hash';
import path from 'path';
import type { FailOnOptions } from 'sharp';
import sharp from 'sharp';
import { SUPPORTED_IMAGE_TRANSFORM_FORMATS } from '../constants.js';
import getDatabase from '../database/index.js';
@@ -25,6 +24,7 @@ import { isValidUuid } from '../utils/is-valid-uuid.js';
import * as TransformationUtils from '../utils/transformations.js';
import { AuthorizationService } from './authorization.js';
import { FilesService } from './files.js';
import { getSharpInstance } from './files/lib/get-sharp-instance.js';
const env = useEnv();
const logger = useLogger();
@@ -162,11 +162,7 @@ export class AssetsService {
const readStream = await storage.location(file.storage).read(file.filename_disk, range);
const transformer = sharp({
limitInputPixels: Math.pow(env['ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION'] as number, 2),
sequentialRead: true,
failOn: env['ASSETS_INVALID_IMAGE_SENSITIVITY_LEVEL'] as FailOnOptions,
});
const transformer = getSharpInstance();
transformer.timeout({
seconds: clamp(Math.round(getMilliseconds(env['ASSETS_TRANSFORM_TIMEOUT'], 0) / 1000), 1, 3600),

View File

@@ -0,0 +1,37 @@
import { useEnv } from '@directus/env';
import { getSharpInstance } from './get-sharp-instance';
import { beforeAll, expect, test, vi } from 'vitest';
vi.mock('@directus/env');
vi.mock('sharp', () => {
const sharp = {
// using object with default property to mock default import
default: vi.fn(),
};
return sharp;
});
const ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION = 94906265;
const ASSETS_INVALID_IMAGE_SENSITIVITY_LEVEL = 'error';
beforeAll(() => {
vi.mocked(useEnv).mockReturnValue({
ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION,
ASSETS_INVALID_IMAGE_SENSITIVITY_LEVEL,
});
});
test('getSharpInstance should apply the correct options', async () => {
const sharp = await import('sharp');
getSharpInstance();
expect(sharp.default).toHaveBeenCalledWith({
limitInputPixels: Math.pow(ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION, 2),
sequentialRead: true,
failOn: ASSETS_INVALID_IMAGE_SENSITIVITY_LEVEL,
});
});

View File

@@ -0,0 +1,12 @@
import { useEnv } from '@directus/env';
import sharp, { type FailOnOptions, type Sharp } from 'sharp';
export function getSharpInstance(): Sharp {
const env = useEnv();
return sharp({
limitInputPixels: Math.trunc(Math.pow(env['ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION'] as number, 2)),
sequentialRead: true,
failOn: env['ASSETS_INVALID_IMAGE_SENSITIVITY_LEVEL'] as FailOnOptions,
});
}

View File

@@ -4,10 +4,10 @@ import { type IccProfile, parse as parseIcc } from 'icc';
import { pick } from 'lodash-es';
import type { Readable } from 'node:stream';
import { pipeline } from 'node:stream/promises';
import sharp from 'sharp';
import { useEnv } from '@directus/env';
import { useLogger } from '../../../logger/index.js';
import { parseIptc, parseXmp } from './parse-image-metadata.js';
import { getSharpInstance } from '../lib/get-sharp-instance.js';
const env = useEnv();
const logger = useLogger();
@@ -18,10 +18,12 @@ export async function getMetadata(
stream: Readable,
allowList: string | string[] = env['FILE_METADATA_ALLOW_LIST'] as string[],
): Promise<Metadata> {
const transformer = getSharpInstance();
return new Promise((resolve, reject) => {
pipeline(
stream,
sharp().metadata(async (err, sharpMetadata) => {
transformer.metadata(async (err, sharpMetadata) => {
if (err) {
reject(err);
return;

View File

@@ -142,4 +142,5 @@
- brandondrew
- alantiller
- SP12893678
- AndriyAntonenko
- jacobwise