feat: image dimensions rework (#5824)
This commit is contained in:
@@ -52,6 +52,7 @@
|
||||
"find-up": "4.1.0",
|
||||
"get-tsconfig": "^4.7.2",
|
||||
"http-status": "1.6.2",
|
||||
"image-size": "^1.1.1",
|
||||
"joi": "^17.12.1",
|
||||
"json-schema-to-typescript": "11.0.3",
|
||||
"jsonwebtoken": "9.0.1",
|
||||
@@ -62,10 +63,10 @@
|
||||
"pino": "8.15.0",
|
||||
"pino-pretty": "10.2.0",
|
||||
"pluralize": "8.0.0",
|
||||
"probe-image-size": "^7.2.3",
|
||||
"sanitize-filename": "1.6.3",
|
||||
"scheduler": "0.23.0",
|
||||
"scmp": "2.1.0"
|
||||
"scmp": "2.1.0",
|
||||
"uuid": "^9.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@swc/core": "^1.4.13"
|
||||
|
||||
@@ -133,7 +133,7 @@ export const generateFileData = async <T>({
|
||||
}
|
||||
|
||||
if (fileSupportsResize || isImage(file.mimetype)) {
|
||||
dimensions = getImageSize(file)
|
||||
dimensions = await getImageSize(file)
|
||||
fileData.width = dimensions.width
|
||||
fileData.height = dimensions.height
|
||||
}
|
||||
|
||||
@@ -1,14 +1,32 @@
|
||||
import fs from 'fs'
|
||||
import probeImageSize from 'probe-image-size'
|
||||
import sizeOfImport from 'image-size'
|
||||
import { promisify } from 'util'
|
||||
|
||||
import type { PayloadRequest } from '../types/index.js'
|
||||
import type { ProbedImageSize } from './types.js'
|
||||
|
||||
export function getImageSize(file: PayloadRequest['file']): ProbedImageSize {
|
||||
import { temporaryFileTask } from './tempFile.js'
|
||||
|
||||
const { imageSize } = sizeOfImport
|
||||
const imageSizePromise = promisify(imageSize)
|
||||
|
||||
export async function getImageSize(file: PayloadRequest['file']): Promise<ProbedImageSize> {
|
||||
if (file.tempFilePath) {
|
||||
const data = fs.readFileSync(file.tempFilePath)
|
||||
return probeImageSize.sync(data)
|
||||
return imageSizePromise(file.tempFilePath)
|
||||
}
|
||||
|
||||
return probeImageSize.sync(file.data)
|
||||
// Tiff file do not support buffers or streams, so we must write to file first
|
||||
// then retrieve dimensions. https://github.com/image-size/image-size/issues/103
|
||||
if (file.mimetype === 'image/tiff') {
|
||||
const dimensions = await temporaryFileTask(
|
||||
async (filepath: string) => {
|
||||
fs.writeFileSync(filepath, file.data)
|
||||
return imageSizePromise(filepath)
|
||||
},
|
||||
{ extension: 'tiff' },
|
||||
)
|
||||
return dimensions
|
||||
}
|
||||
|
||||
return imageSize(file.data)
|
||||
}
|
||||
|
||||
50
packages/payload/src/uploads/tempFile.ts
Normal file
50
packages/payload/src/uploads/tempFile.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import { promises as fsPromises } from 'fs'
|
||||
import os from 'node:os'
|
||||
import path from 'node:path'
|
||||
import { v4 as uuid } from 'uuid'
|
||||
|
||||
async function runTask(temporaryPath: string, callback) {
|
||||
try {
|
||||
return await callback(temporaryPath)
|
||||
} finally {
|
||||
await fsPromises.rm(temporaryPath, { force: true, maxRetries: 2, recursive: true })
|
||||
}
|
||||
}
|
||||
|
||||
type Options = {
|
||||
extension?: string
|
||||
name?: string
|
||||
}
|
||||
|
||||
export const temporaryFileTask = async (callback, options: Options = {}) => {
|
||||
const filePath = await temporaryFile(options)
|
||||
return runTask(filePath, callback)
|
||||
}
|
||||
|
||||
async function temporaryFile(options: Options) {
|
||||
if (options.name) {
|
||||
if (options.extension !== undefined && options.extension !== null) {
|
||||
throw new Error('The `name` and `extension` options are mutually exclusive')
|
||||
}
|
||||
|
||||
return path.join(await temporaryDirectory(), options.name)
|
||||
}
|
||||
|
||||
return (
|
||||
(await getPath()) +
|
||||
(options.extension === undefined || options.extension === null
|
||||
? ''
|
||||
: '.' + options.extension.replace(/^\./, ''))
|
||||
)
|
||||
}
|
||||
|
||||
async function temporaryDirectory({ prefix = '' } = {}) {
|
||||
const directory = await getPath(prefix)
|
||||
await fsPromises.mkdir(directory)
|
||||
return directory
|
||||
}
|
||||
|
||||
async function getPath(prefix = ''): Promise<string> {
|
||||
const temporaryDirectory = await fsPromises.realpath(os.tmpdir())
|
||||
return path.join(temporaryDirectory, prefix + uuid())
|
||||
}
|
||||
65
pnpm-lock.yaml
generated
65
pnpm-lock.yaml
generated
@@ -748,6 +748,9 @@ importers:
|
||||
http-status:
|
||||
specifier: 1.6.2
|
||||
version: 1.6.2
|
||||
image-size:
|
||||
specifier: ^1.1.1
|
||||
version: 1.1.1
|
||||
joi:
|
||||
specifier: ^17.12.1
|
||||
version: 17.12.3
|
||||
@@ -778,9 +781,6 @@ importers:
|
||||
pluralize:
|
||||
specifier: 8.0.0
|
||||
version: 8.0.0
|
||||
probe-image-size:
|
||||
specifier: ^7.2.3
|
||||
version: 7.2.3
|
||||
sanitize-filename:
|
||||
specifier: 1.6.3
|
||||
version: 1.6.3
|
||||
@@ -790,6 +790,9 @@ importers:
|
||||
scmp:
|
||||
specifier: 2.1.0
|
||||
version: 2.1.0
|
||||
uuid:
|
||||
specifier: ^9.0.1
|
||||
version: 9.0.1
|
||||
devDependencies:
|
||||
'@monaco-editor/react':
|
||||
specifier: 4.5.1
|
||||
@@ -8253,17 +8256,6 @@ packages:
|
||||
dependencies:
|
||||
ms: 2.0.0
|
||||
|
||||
/debug@3.2.7:
|
||||
resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
|
||||
peerDependencies:
|
||||
supports-color: '*'
|
||||
peerDependenciesMeta:
|
||||
supports-color:
|
||||
optional: true
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
dev: false
|
||||
|
||||
/debug@4.3.4(supports-color@5.5.0):
|
||||
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
|
||||
engines: {node: '>=6.0'}
|
||||
@@ -10449,6 +10441,14 @@ packages:
|
||||
resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==}
|
||||
engines: {node: '>= 4'}
|
||||
|
||||
/image-size@1.1.1:
|
||||
resolution: {integrity: sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ==}
|
||||
engines: {node: '>=16.x'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
queue: 6.0.2
|
||||
dev: false
|
||||
|
||||
/immer@9.0.21:
|
||||
resolution: {integrity: sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==}
|
||||
|
||||
@@ -12238,18 +12238,6 @@ packages:
|
||||
/natural-compare@1.4.0:
|
||||
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
|
||||
|
||||
/needle@2.9.1:
|
||||
resolution: {integrity: sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ==}
|
||||
engines: {node: '>= 4.4.x'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
debug: 3.2.7
|
||||
iconv-lite: 0.4.24
|
||||
sax: 1.3.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/negotiator@0.6.3:
|
||||
resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==}
|
||||
engines: {node: '>= 0.6'}
|
||||
@@ -13815,16 +13803,6 @@ packages:
|
||||
engines: {node: '>=6'}
|
||||
dev: false
|
||||
|
||||
/probe-image-size@7.2.3:
|
||||
resolution: {integrity: sha512-HubhG4Rb2UH8YtV4ba0Vp5bQ7L78RTONYu/ujmCu5nBI8wGv24s4E9xSKBi0N1MowRpxk76pFCpJtW0KPzOK0w==}
|
||||
dependencies:
|
||||
lodash.merge: 4.6.2
|
||||
needle: 2.9.1
|
||||
stream-parser: 0.3.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/process-nextick-args@2.0.1:
|
||||
resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
|
||||
dev: true
|
||||
@@ -13921,6 +13899,12 @@ packages:
|
||||
resolution: {integrity: sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==}
|
||||
dev: true
|
||||
|
||||
/queue@6.0.2:
|
||||
resolution: {integrity: sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==}
|
||||
dependencies:
|
||||
inherits: 2.0.4
|
||||
dev: false
|
||||
|
||||
/quick-format-unescaped@4.0.4:
|
||||
resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==}
|
||||
|
||||
@@ -14499,6 +14483,7 @@ packages:
|
||||
|
||||
/sax@1.3.0:
|
||||
resolution: {integrity: sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==}
|
||||
dev: true
|
||||
|
||||
/saxes@6.0.0:
|
||||
resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==}
|
||||
@@ -14958,14 +14943,6 @@ packages:
|
||||
stubs: 3.0.0
|
||||
dev: true
|
||||
|
||||
/stream-parser@0.3.1:
|
||||
resolution: {integrity: sha512-bJ/HgKq41nlKvlhccD5kaCr/P+Hu0wPNKPJOH7en+YrJu/9EgqUF+88w5Jb6KNcjOFMhfX4B2asfeAtIGuHObQ==}
|
||||
dependencies:
|
||||
debug: 2.6.9
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/stream-shift@1.0.3:
|
||||
resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==}
|
||||
dev: true
|
||||
|
||||
Reference in New Issue
Block a user