payload 3.0.0-beta.40 → 3.0.0-beta.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/sanitize.d.ts.map +1 -1
- package/dist/config/sanitize.js +6 -0
- package/dist/config/sanitize.js.map +1 -1
- package/dist/database/migrations/getPredefinedMigration.d.ts.map +1 -1
- package/dist/database/migrations/getPredefinedMigration.js +3 -6
- package/dist/database/migrations/getPredefinedMigration.js.map +1 -1
- package/dist/uploads/cropImage.d.ts.map +1 -1
- package/dist/uploads/cropImage.js +8 -1
- package/dist/uploads/cropImage.js.map +1 -1
- package/dist/uploads/generateFileData.d.ts.map +1 -1
- package/dist/uploads/generateFileData.js +10 -6
- package/dist/uploads/generateFileData.js.map +1 -1
- package/dist/uploads/getFileByPath.d.ts.map +1 -1
- package/dist/uploads/getFileByPath.js +2 -3
- package/dist/uploads/getFileByPath.js.map +1 -1
- package/dist/uploads/imageResizer.d.ts +1 -1
- package/dist/uploads/imageResizer.d.ts.map +1 -1
- package/dist/uploads/imageResizer.js +16 -8
- package/dist/uploads/imageResizer.js.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../src/config/sanitize.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,MAAM,EAGN,eAAe,EAChB,MAAM,YAAY,CAAA;AAuCnB,eAAO,MAAM,cAAc,mBAA0B,MAAM,KAAG,QAAQ,eAAe,
|
|
1
|
+
{"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../src/config/sanitize.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,MAAM,EAGN,eAAe,EAChB,MAAM,YAAY,CAAA;AAuCnB,eAAO,MAAM,cAAc,mBAA0B,MAAM,KAAG,QAAQ,eAAe,CA+HpF,CAAA"}
|
package/dist/config/sanitize.js
CHANGED
|
@@ -37,6 +37,12 @@ export const sanitizeConfig = async (incomingConfig)=>{
|
|
|
37
37
|
if (!configWithDefaults?.serverURL) {
|
|
38
38
|
configWithDefaults.serverURL = '';
|
|
39
39
|
}
|
|
40
|
+
if (process.env.NEXT_BASE_PATH) {
|
|
41
|
+
if (!incomingConfig?.routes?.api) {
|
|
42
|
+
// check for incomingConfig, as configWithDefaults will always have a default value for routes.api
|
|
43
|
+
configWithDefaults.routes.api = process.env.NEXT_BASE_PATH + '/api';
|
|
44
|
+
}
|
|
45
|
+
}
|
|
40
46
|
const config = sanitizeAdminConfig(configWithDefaults);
|
|
41
47
|
if (config.localization && config.localization.locales?.length > 0) {
|
|
42
48
|
// clone localization config so to not break everything
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/config/sanitize.ts"],"sourcesContent":["import type { AcceptedLanguages } from '@payloadcms/translations'\n\nimport { en } from '@payloadcms/translations/languages/en'\nimport merge from 'deepmerge'\n\nimport type {\n Config,\n LocalizationConfigWithLabels,\n LocalizationConfigWithNoLabels,\n SanitizedConfig,\n} from './types.js'\n\nimport { defaultUserCollection } from '../auth/defaultUser.js'\nimport { sanitizeCollection } from '../collections/config/sanitize.js'\nimport { migrationsCollection } from '../database/migrations/migrationsCollection.js'\nimport { InvalidConfiguration } from '../errors/index.js'\nimport { sanitizeGlobals } from '../globals/config/sanitize.js'\nimport getPreferencesCollection from '../preferences/preferencesCollection.js'\nimport checkDuplicateCollections from '../utilities/checkDuplicateCollections.js'\nimport { deepMerge } from '../utilities/deepMerge.js'\nimport { isPlainObject } from '../utilities/isPlainObject.js'\nimport { defaults } from './defaults.js'\n\nconst sanitizeAdminConfig = (configToSanitize: Config): Partial<SanitizedConfig> => {\n const sanitizedConfig = { ...configToSanitize }\n\n // add default user collection if none provided\n if (!sanitizedConfig?.admin?.user) {\n const firstCollectionWithAuth = sanitizedConfig.collections.find(({ auth }) => Boolean(auth))\n if (firstCollectionWithAuth) {\n sanitizedConfig.admin.user = firstCollectionWithAuth.slug\n } else {\n sanitizedConfig.admin.user = defaultUserCollection.slug\n sanitizedConfig.collections.push(defaultUserCollection)\n }\n }\n\n const userCollection = sanitizedConfig.collections.find(\n ({ slug }) => slug === sanitizedConfig.admin.user,\n )\n if (!userCollection || !userCollection.auth) {\n throw new InvalidConfiguration(\n `${sanitizedConfig.admin.user} is not a valid admin user collection`,\n )\n }\n\n return sanitizedConfig as unknown as Partial<SanitizedConfig>\n}\n\nexport const sanitizeConfig = async (incomingConfig: Config): Promise<SanitizedConfig> => {\n const configWithDefaults: Config = merge(defaults, incomingConfig, {\n isMergeableObject: isPlainObject,\n }) as Config\n\n if (!configWithDefaults?.serverURL) {\n configWithDefaults.serverURL = ''\n }\n\n const config: Partial<SanitizedConfig> = sanitizeAdminConfig(configWithDefaults)\n\n if (config.localization && config.localization.locales?.length > 0) {\n // clone localization config so to not break everything\n const firstLocale = config.localization.locales[0]\n if (typeof firstLocale === 'string') {\n config.localization.localeCodes = [\n ...(config.localization as unknown as LocalizationConfigWithNoLabels).locales,\n ]\n\n // is string[], so convert to Locale[]\n config.localization.locales = (\n config.localization as unknown as LocalizationConfigWithNoLabels\n ).locales.map((locale) => ({\n code: locale,\n label: locale,\n rtl: false,\n toString: () => locale,\n }))\n } else {\n // is Locale[], so convert to string[] for localeCodes\n config.localization.localeCodes = config.localization.locales.reduce((locales, locale) => {\n locales.push(locale.code)\n return locales\n }, [] as string[])\n\n config.localization.locales = (\n config.localization as LocalizationConfigWithLabels\n ).locales.map((locale) => ({\n ...locale,\n toString: () => locale.code,\n }))\n }\n }\n\n const i18nConfig: SanitizedConfig['i18n'] = {\n fallbackLanguage: 'en',\n supportedLanguages: {\n en,\n },\n translations: {},\n }\n\n if (incomingConfig?.i18n) {\n i18nConfig.supportedLanguages =\n incomingConfig.i18n?.supportedLanguages || i18nConfig.supportedLanguages\n\n const supportedLangKeys = <AcceptedLanguages[]>Object.keys(i18nConfig.supportedLanguages)\n const fallbackLang = incomingConfig.i18n?.fallbackLanguage || i18nConfig.fallbackLanguage\n\n i18nConfig.fallbackLanguage = supportedLangKeys.includes(fallbackLang)\n ? fallbackLang\n : supportedLangKeys[0]\n i18nConfig.translations =\n (incomingConfig.i18n?.translations as SanitizedConfig['i18n']['translations']) ||\n i18nConfig.translations\n }\n\n config.i18n = i18nConfig\n\n configWithDefaults.collections.push(getPreferencesCollection(config as unknown as Config))\n configWithDefaults.collections.push(migrationsCollection)\n\n const richTextSanitizationPromises: Array<(config: SanitizedConfig) => Promise<void>> = []\n for (let i = 0; i < config.collections.length; i++) {\n config.collections[i] = await sanitizeCollection(\n config as unknown as Config,\n config.collections[i],\n richTextSanitizationPromises,\n )\n }\n\n checkDuplicateCollections(config.collections)\n\n if (config.globals.length > 0) {\n config.globals = await sanitizeGlobals(\n config as unknown as Config,\n richTextSanitizationPromises,\n )\n }\n\n if (config.serverURL !== '') {\n config.csrf.push(config.serverURL)\n }\n\n // Get deduped list of upload adapters\n if (!config.upload) config.upload = { adapters: [] }\n config.upload.adapters = Array.from(\n new Set(config.collections.map((c) => c.upload?.adapter).filter(Boolean)),\n )\n\n /*\n Execute richText sanitization\n */\n if (typeof incomingConfig.editor === 'function') {\n config.editor = await incomingConfig.editor({\n config: config as SanitizedConfig,\n isRoot: true,\n })\n if (config.editor.i18n && Object.keys(config.editor.i18n).length >= 0) {\n config.i18n.translations = deepMerge(config.i18n.translations, config.editor.i18n)\n }\n }\n\n const promises: Promise<void>[] = []\n for (const sanitizeFunction of richTextSanitizationPromises) {\n promises.push(sanitizeFunction(config as SanitizedConfig))\n }\n await Promise.all(promises)\n\n return config as SanitizedConfig\n}\n"],"names":["en","merge","defaultUserCollection","sanitizeCollection","migrationsCollection","InvalidConfiguration","sanitizeGlobals","getPreferencesCollection","checkDuplicateCollections","deepMerge","isPlainObject","defaults","sanitizeAdminConfig","configToSanitize","sanitizedConfig","admin","user","firstCollectionWithAuth","collections","find","auth","Boolean","slug","push","userCollection","sanitizeConfig","incomingConfig","configWithDefaults","isMergeableObject","serverURL","config","localization","locales","length","firstLocale","localeCodes","map","locale","code","label","rtl","toString","reduce","i18nConfig","fallbackLanguage","supportedLanguages","translations","i18n","supportedLangKeys","Object","keys","fallbackLang","includes","richTextSanitizationPromises","i","globals","csrf","upload","adapters","Array","from","Set","c","adapter","filter","editor","isRoot","promises","sanitizeFunction","Promise","all"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/config/sanitize.ts"],"sourcesContent":["import type { AcceptedLanguages } from '@payloadcms/translations'\n\nimport { en } from '@payloadcms/translations/languages/en'\nimport merge from 'deepmerge'\n\nimport type {\n Config,\n LocalizationConfigWithLabels,\n LocalizationConfigWithNoLabels,\n SanitizedConfig,\n} from './types.js'\n\nimport { defaultUserCollection } from '../auth/defaultUser.js'\nimport { sanitizeCollection } from '../collections/config/sanitize.js'\nimport { migrationsCollection } from '../database/migrations/migrationsCollection.js'\nimport { InvalidConfiguration } from '../errors/index.js'\nimport { sanitizeGlobals } from '../globals/config/sanitize.js'\nimport getPreferencesCollection from '../preferences/preferencesCollection.js'\nimport checkDuplicateCollections from '../utilities/checkDuplicateCollections.js'\nimport { deepMerge } from '../utilities/deepMerge.js'\nimport { isPlainObject } from '../utilities/isPlainObject.js'\nimport { defaults } from './defaults.js'\n\nconst sanitizeAdminConfig = (configToSanitize: Config): Partial<SanitizedConfig> => {\n const sanitizedConfig = { ...configToSanitize }\n\n // add default user collection if none provided\n if (!sanitizedConfig?.admin?.user) {\n const firstCollectionWithAuth = sanitizedConfig.collections.find(({ auth }) => Boolean(auth))\n if (firstCollectionWithAuth) {\n sanitizedConfig.admin.user = firstCollectionWithAuth.slug\n } else {\n sanitizedConfig.admin.user = defaultUserCollection.slug\n sanitizedConfig.collections.push(defaultUserCollection)\n }\n }\n\n const userCollection = sanitizedConfig.collections.find(\n ({ slug }) => slug === sanitizedConfig.admin.user,\n )\n if (!userCollection || !userCollection.auth) {\n throw new InvalidConfiguration(\n `${sanitizedConfig.admin.user} is not a valid admin user collection`,\n )\n }\n\n return sanitizedConfig as unknown as Partial<SanitizedConfig>\n}\n\nexport const sanitizeConfig = async (incomingConfig: Config): Promise<SanitizedConfig> => {\n const configWithDefaults: Config = merge(defaults, incomingConfig, {\n isMergeableObject: isPlainObject,\n }) as Config\n\n if (!configWithDefaults?.serverURL) {\n configWithDefaults.serverURL = ''\n }\n\n if (process.env.NEXT_BASE_PATH) {\n if (!incomingConfig?.routes?.api) {\n // check for incomingConfig, as configWithDefaults will always have a default value for routes.api\n configWithDefaults.routes.api = process.env.NEXT_BASE_PATH + '/api'\n }\n }\n\n const config: Partial<SanitizedConfig> = sanitizeAdminConfig(configWithDefaults)\n\n if (config.localization && config.localization.locales?.length > 0) {\n // clone localization config so to not break everything\n const firstLocale = config.localization.locales[0]\n if (typeof firstLocale === 'string') {\n config.localization.localeCodes = [\n ...(config.localization as unknown as LocalizationConfigWithNoLabels).locales,\n ]\n\n // is string[], so convert to Locale[]\n config.localization.locales = (\n config.localization as unknown as LocalizationConfigWithNoLabels\n ).locales.map((locale) => ({\n code: locale,\n label: locale,\n rtl: false,\n toString: () => locale,\n }))\n } else {\n // is Locale[], so convert to string[] for localeCodes\n config.localization.localeCodes = config.localization.locales.reduce((locales, locale) => {\n locales.push(locale.code)\n return locales\n }, [] as string[])\n\n config.localization.locales = (\n config.localization as LocalizationConfigWithLabels\n ).locales.map((locale) => ({\n ...locale,\n toString: () => locale.code,\n }))\n }\n }\n\n const i18nConfig: SanitizedConfig['i18n'] = {\n fallbackLanguage: 'en',\n supportedLanguages: {\n en,\n },\n translations: {},\n }\n\n if (incomingConfig?.i18n) {\n i18nConfig.supportedLanguages =\n incomingConfig.i18n?.supportedLanguages || i18nConfig.supportedLanguages\n\n const supportedLangKeys = <AcceptedLanguages[]>Object.keys(i18nConfig.supportedLanguages)\n const fallbackLang = incomingConfig.i18n?.fallbackLanguage || i18nConfig.fallbackLanguage\n\n i18nConfig.fallbackLanguage = supportedLangKeys.includes(fallbackLang)\n ? fallbackLang\n : supportedLangKeys[0]\n i18nConfig.translations =\n (incomingConfig.i18n?.translations as SanitizedConfig['i18n']['translations']) ||\n i18nConfig.translations\n }\n\n config.i18n = i18nConfig\n\n configWithDefaults.collections.push(getPreferencesCollection(config as unknown as Config))\n configWithDefaults.collections.push(migrationsCollection)\n\n const richTextSanitizationPromises: Array<(config: SanitizedConfig) => Promise<void>> = []\n for (let i = 0; i < config.collections.length; i++) {\n config.collections[i] = await sanitizeCollection(\n config as unknown as Config,\n config.collections[i],\n richTextSanitizationPromises,\n )\n }\n\n checkDuplicateCollections(config.collections)\n\n if (config.globals.length > 0) {\n config.globals = await sanitizeGlobals(\n config as unknown as Config,\n richTextSanitizationPromises,\n )\n }\n\n if (config.serverURL !== '') {\n config.csrf.push(config.serverURL)\n }\n\n // Get deduped list of upload adapters\n if (!config.upload) config.upload = { adapters: [] }\n config.upload.adapters = Array.from(\n new Set(config.collections.map((c) => c.upload?.adapter).filter(Boolean)),\n )\n\n /*\n Execute richText sanitization\n */\n if (typeof incomingConfig.editor === 'function') {\n config.editor = await incomingConfig.editor({\n config: config as SanitizedConfig,\n isRoot: true,\n })\n if (config.editor.i18n && Object.keys(config.editor.i18n).length >= 0) {\n config.i18n.translations = deepMerge(config.i18n.translations, config.editor.i18n)\n }\n }\n\n const promises: Promise<void>[] = []\n for (const sanitizeFunction of richTextSanitizationPromises) {\n promises.push(sanitizeFunction(config as SanitizedConfig))\n }\n await Promise.all(promises)\n\n return config as SanitizedConfig\n}\n"],"names":["en","merge","defaultUserCollection","sanitizeCollection","migrationsCollection","InvalidConfiguration","sanitizeGlobals","getPreferencesCollection","checkDuplicateCollections","deepMerge","isPlainObject","defaults","sanitizeAdminConfig","configToSanitize","sanitizedConfig","admin","user","firstCollectionWithAuth","collections","find","auth","Boolean","slug","push","userCollection","sanitizeConfig","incomingConfig","configWithDefaults","isMergeableObject","serverURL","process","env","NEXT_BASE_PATH","routes","api","config","localization","locales","length","firstLocale","localeCodes","map","locale","code","label","rtl","toString","reduce","i18nConfig","fallbackLanguage","supportedLanguages","translations","i18n","supportedLangKeys","Object","keys","fallbackLang","includes","richTextSanitizationPromises","i","globals","csrf","upload","adapters","Array","from","Set","c","adapter","filter","editor","isRoot","promises","sanitizeFunction","Promise","all"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getPredefinedMigration.d.ts","sourceRoot":"","sources":["../../../src/database/migrations/getPredefinedMigration.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAExD;;GAEG;AACH,eAAO,MAAM,sBAAsB,iEAKhC;IACD,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,OAAO,EAAE,OAAO,CAAA;CACjB,KAAG,QAAQ,qBAAqB,
|
|
1
|
+
{"version":3,"file":"getPredefinedMigration.d.ts","sourceRoot":"","sources":["../../../src/database/migrations/getPredefinedMigration.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAExD;;GAEG;AACH,eAAO,MAAM,sBAAsB,iEAKhC;IACD,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,OAAO,EAAE,OAAO,CAAA;CACjB,KAAG,QAAQ,qBAAqB,CA2BhC,CAAA"}
|
|
@@ -15,18 +15,15 @@ import { pathToFileURL } from 'url';
|
|
|
15
15
|
cleanPath = cleanPath.replaceAll('\\', '/');
|
|
16
16
|
const moduleURL = pathToFileURL(cleanPath);
|
|
17
17
|
try {
|
|
18
|
-
const { downSQL, imports, upSQL } = await eval(`import'${moduleURL.href}')`);
|
|
18
|
+
const { downSQL, imports, upSQL } = await eval(`import('${moduleURL.href}')`);
|
|
19
19
|
return {
|
|
20
20
|
downSQL,
|
|
21
21
|
imports,
|
|
22
22
|
upSQL
|
|
23
23
|
};
|
|
24
24
|
} catch (error) {
|
|
25
|
-
payload.logger.error({
|
|
26
|
-
|
|
27
|
-
msg: `Error loading predefined migration ${migrationName}`
|
|
28
|
-
});
|
|
29
|
-
process.exit(1);
|
|
25
|
+
payload.logger.error(`Error loading predefined migration ${migrationName}`);
|
|
26
|
+
throw error;
|
|
30
27
|
}
|
|
31
28
|
} else {
|
|
32
29
|
payload.logger.error({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/database/migrations/getPredefinedMigration.ts"],"sourcesContent":["import fs from 'fs'\nimport path from 'path'\nimport { pathToFileURL } from 'url'\n\nimport type { Payload } from '../../index.js'\nimport type { MigrationTemplateArgs } from '../types.js'\n\n/**\n * Get predefined migration 'up', 'down' and 'imports'\n */\nexport const getPredefinedMigration = async ({\n dirname,\n file,\n migrationName: migrationNameArg,\n payload,\n}: {\n dirname: string\n file?: string\n migrationName?: string\n payload: Payload\n}): Promise<MigrationTemplateArgs> => {\n // Check for predefined migration.\n // Either passed in via --file or prefixed with '@payloadcms/db-mongodb/' for example\n if (file || migrationNameArg?.startsWith('@payloadcms/')) {\n // removes the package name from the migrationName.\n const migrationName = (file || migrationNameArg).split('/').slice(2).join('/')\n let cleanPath = path.join(dirname, `./predefinedMigrations/${migrationName}.mjs`)\n\n // Check if predefined migration exists\n if (fs.existsSync(cleanPath)) {\n cleanPath = cleanPath.replaceAll('\\\\', '/')\n const moduleURL = pathToFileURL(cleanPath)\n try {\n const { downSQL, imports, upSQL } = await eval(`import'${moduleURL.href}')`)\n return { downSQL, imports, upSQL }\n } catch (error) {\n payload.logger.error(
|
|
1
|
+
{"version":3,"sources":["../../../src/database/migrations/getPredefinedMigration.ts"],"sourcesContent":["import fs from 'fs'\nimport path from 'path'\nimport { pathToFileURL } from 'url'\n\nimport type { Payload } from '../../index.js'\nimport type { MigrationTemplateArgs } from '../types.js'\n\n/**\n * Get predefined migration 'up', 'down' and 'imports'\n */\nexport const getPredefinedMigration = async ({\n dirname,\n file,\n migrationName: migrationNameArg,\n payload,\n}: {\n dirname: string\n file?: string\n migrationName?: string\n payload: Payload\n}): Promise<MigrationTemplateArgs> => {\n // Check for predefined migration.\n // Either passed in via --file or prefixed with '@payloadcms/db-mongodb/' for example\n if (file || migrationNameArg?.startsWith('@payloadcms/')) {\n // removes the package name from the migrationName.\n const migrationName = (file || migrationNameArg).split('/').slice(2).join('/')\n let cleanPath = path.join(dirname, `./predefinedMigrations/${migrationName}.mjs`)\n\n // Check if predefined migration exists\n if (fs.existsSync(cleanPath)) {\n cleanPath = cleanPath.replaceAll('\\\\', '/')\n const moduleURL = pathToFileURL(cleanPath)\n try {\n const { downSQL, imports, upSQL } = await eval(`import('${moduleURL.href}')`)\n return { downSQL, imports, upSQL }\n } catch (error) {\n payload.logger.error(`Error loading predefined migration ${migrationName}`)\n throw error\n }\n } else {\n payload.logger.error({\n msg: `Canned migration ${migrationName} not found.`,\n })\n process.exit(1)\n }\n }\n return {}\n}\n"],"names":["fs","path","pathToFileURL","getPredefinedMigration","dirname","file","migrationName","migrationNameArg","payload","startsWith","split","slice","join","cleanPath","existsSync","replaceAll","moduleURL","downSQL","imports","upSQL","eval","href","error","logger","msg","process","exit"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,OAAOA,QAAQ,KAAI;AACnB,OAAOC,UAAU,OAAM;AACvB,SAASC,aAAa,QAAQ,MAAK;AAKnC;;CAEC,GACD,OAAO,MAAMC,yBAAyB,OAAO,EAC3CC,OAAO,EACPC,IAAI,EACJC,eAAeC,gBAAgB,EAC/BC,OAAO,EAMR;IACC,kCAAkC;IAClC,qFAAqF;IACrF,IAAIH,QAAQE,kBAAkBE,WAAW,iBAAiB;QACxD,mDAAmD;QACnD,MAAMH,gBAAgB,AAACD,CAAAA,QAAQE,gBAAe,EAAGG,KAAK,CAAC,KAAKC,KAAK,CAAC,GAAGC,IAAI,CAAC;QAC1E,IAAIC,YAAYZ,KAAKW,IAAI,CAACR,SAAS,CAAC,uBAAuB,EAAEE,cAAc,IAAI,CAAC;QAEhF,uCAAuC;QACvC,IAAIN,GAAGc,UAAU,CAACD,YAAY;YAC5BA,YAAYA,UAAUE,UAAU,CAAC,MAAM;YACvC,MAAMC,YAAYd,cAAcW;YAChC,IAAI;gBACF,MAAM,EAAEI,OAAO,EAAEC,OAAO,EAAEC,KAAK,EAAE,GAAG,MAAMC,KAAK,CAAC,QAAQ,EAAEJ,UAAUK,IAAI,CAAC,EAAE,CAAC;gBAC5E,OAAO;oBAAEJ;oBAASC;oBAASC;gBAAM;YACnC,EAAE,OAAOG,OAAO;gBACdd,QAAQe,MAAM,CAACD,KAAK,CAAC,CAAC,mCAAmC,EAAEhB,cAAc,CAAC;gBAC1E,MAAMgB;YACR;QACF,OAAO;YACLd,QAAQe,MAAM,CAACD,KAAK,CAAC;gBACnBE,KAAK,CAAC,iBAAiB,EAAElB,cAAc,WAAW,CAAC;YACrD;YACAmB,QAAQC,IAAI,CAAC;QACf;IACF;IACA,OAAO,CAAC;AACV,EAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cropImage.d.ts","sourceRoot":"","sources":["../../src/uploads/cropImage.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cropImage.d.ts","sourceRoot":"","sources":["../../src/uploads/cropImage.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,cAAc,wCAE1B,CAAA;AAED,wBAAsB,SAAS,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE;;;;;CAAA,gBA0BpE"}
|
|
@@ -4,13 +4,20 @@ export const percentToPixel = (value, dimension)=>{
|
|
|
4
4
|
export async function cropImage({ cropData, dimensions, file, sharp }) {
|
|
5
5
|
try {
|
|
6
6
|
const { height, width, x, y } = cropData;
|
|
7
|
+
const fileIsAnimated = [
|
|
8
|
+
'image/avif',
|
|
9
|
+
'image/gif',
|
|
10
|
+
'image/webp'
|
|
11
|
+
].includes(file.mimetype);
|
|
12
|
+
const sharpOptions = {};
|
|
13
|
+
if (fileIsAnimated) sharpOptions.animated = true;
|
|
7
14
|
const formattedCropData = {
|
|
8
15
|
height: percentToPixel(height, dimensions.height),
|
|
9
16
|
left: percentToPixel(x, dimensions.width),
|
|
10
17
|
top: percentToPixel(y, dimensions.height),
|
|
11
18
|
width: percentToPixel(width, dimensions.width)
|
|
12
19
|
};
|
|
13
|
-
const cropped = sharp(file.tempFilePath || file.data).extract(formattedCropData);
|
|
20
|
+
const cropped = sharp(file.tempFilePath || file.data, sharpOptions).extract(formattedCropData);
|
|
14
21
|
return await cropped.toBuffer({
|
|
15
22
|
resolveWithObject: true
|
|
16
23
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/uploads/cropImage.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"sources":["../../src/uploads/cropImage.ts"],"sourcesContent":["import type { SharpOptions } from 'sharp'\n\nexport const percentToPixel = (value, dimension) => {\n return Math.floor((parseFloat(value) / 100) * dimension)\n}\n\nexport async function cropImage({ cropData, dimensions, file, sharp }) {\n try {\n const { height, width, x, y } = cropData\n\n const fileIsAnimated = ['image/avif', 'image/gif', 'image/webp'].includes(file.mimetype)\n\n const sharpOptions: SharpOptions = {}\n\n if (fileIsAnimated) sharpOptions.animated = true\n\n const formattedCropData = {\n height: percentToPixel(height, dimensions.height),\n left: percentToPixel(x, dimensions.width),\n top: percentToPixel(y, dimensions.height),\n width: percentToPixel(width, dimensions.width),\n }\n\n const cropped = sharp(file.tempFilePath || file.data, sharpOptions).extract(formattedCropData)\n\n return await cropped.toBuffer({\n resolveWithObject: true,\n })\n } catch (error) {\n console.error(`Error cropping image:`, error)\n throw error\n }\n}\n"],"names":["percentToPixel","value","dimension","Math","floor","parseFloat","cropImage","cropData","dimensions","file","sharp","height","width","x","y","fileIsAnimated","includes","mimetype","sharpOptions","animated","formattedCropData","left","top","cropped","tempFilePath","data","extract","toBuffer","resolveWithObject","error","console"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAEA,OAAO,MAAMA,iBAAiB,CAACC,OAAOC;IACpC,OAAOC,KAAKC,KAAK,CAAC,AAACC,WAAWJ,SAAS,MAAOC;AAChD,EAAC;AAED,OAAO,eAAeI,UAAU,EAAEC,QAAQ,EAAEC,UAAU,EAAEC,IAAI,EAAEC,KAAK,EAAE;IACnE,IAAI;QACF,MAAM,EAAEC,MAAM,EAAEC,KAAK,EAAEC,CAAC,EAAEC,CAAC,EAAE,GAAGP;QAEhC,MAAMQ,iBAAiB;YAAC;YAAc;YAAa;SAAa,CAACC,QAAQ,CAACP,KAAKQ,QAAQ;QAEvF,MAAMC,eAA6B,CAAC;QAEpC,IAAIH,gBAAgBG,aAAaC,QAAQ,GAAG;QAE5C,MAAMC,oBAAoB;YACxBT,QAAQX,eAAeW,QAAQH,WAAWG,MAAM;YAChDU,MAAMrB,eAAea,GAAGL,WAAWI,KAAK;YACxCU,KAAKtB,eAAec,GAAGN,WAAWG,MAAM;YACxCC,OAAOZ,eAAeY,OAAOJ,WAAWI,KAAK;QAC/C;QAEA,MAAMW,UAAUb,MAAMD,KAAKe,YAAY,IAAIf,KAAKgB,IAAI,EAAEP,cAAcQ,OAAO,CAACN;QAE5E,OAAO,MAAMG,QAAQI,QAAQ,CAAC;YAC5BC,mBAAmB;QACrB;IACF,EAAE,OAAOC,OAAO;QACdC,QAAQD,KAAK,CAAC,CAAC,qBAAqB,CAAC,EAAEA;QACvC,MAAMA;IACR;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generateFileData.d.ts","sourceRoot":"","sources":["../../src/uploads/generateFileData.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"generateFileData.d.ts","sourceRoot":"","sources":["../../src/uploads/generateFileData.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAA;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAA;AAC/D,OAAO,KAAK,EAAY,UAAU,EAAgC,MAAM,YAAY,CAAA;AAYpF,KAAK,IAAI,CAAC,CAAC,IAAI;IACb,UAAU,EAAE,UAAU,CAAA;IACtB,MAAM,EAAE,eAAe,CAAA;IACvB,IAAI,EAAE,CAAC,CAAA;IACP,SAAS,EAAE,QAAQ,GAAG,QAAQ,CAAA;IAC9B,WAAW,CAAC,EAAE,CAAC,CAAA;IACf,sBAAsB,CAAC,EAAE,OAAO,CAAA;IAChC,GAAG,EAAE,sBAAsB,CAAA;IAC3B,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAC7B,CAAA;AAED,KAAK,MAAM,CAAC,CAAC,IAAI,OAAO,CAAC;IACvB,IAAI,EAAE,CAAC,CAAA;IACP,KAAK,EAAE,UAAU,EAAE,CAAA;CACpB,CAAC,CAAA;AAEF,eAAO,MAAM,gBAAgB,oIAQ1B,KAAK,CAAC,CAAC,KAAG,OAAO,CAAC,CA+OpB,CAAA"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
const { fromBuffer } = fileType;
|
|
1
|
+
import { fileTypeFromBuffer } from 'file-type';
|
|
3
2
|
import fs from 'fs';
|
|
4
3
|
import mkdirp from 'mkdirp';
|
|
5
4
|
import sanitize from 'sanitize-filename';
|
|
@@ -62,7 +61,11 @@ export const generateFileData = async ({ collection: { config: collectionConfig
|
|
|
62
61
|
let newData = data;
|
|
63
62
|
const filesToSave = [];
|
|
64
63
|
const fileData = {};
|
|
65
|
-
const fileIsAnimated =
|
|
64
|
+
const fileIsAnimated = [
|
|
65
|
+
'image/avif',
|
|
66
|
+
'image/gif',
|
|
67
|
+
'image/webp'
|
|
68
|
+
].includes(file.mimetype);
|
|
66
69
|
const cropData = typeof uploadEdits === 'object' && 'crop' in uploadEdits ? uploadEdits.crop : undefined;
|
|
67
70
|
try {
|
|
68
71
|
const fileSupportsResize = canResizeImage(file.mimetype);
|
|
@@ -72,7 +75,7 @@ export const generateFileData = async ({ collection: { config: collectionConfig
|
|
|
72
75
|
let fileBuffer;
|
|
73
76
|
let ext;
|
|
74
77
|
let mime;
|
|
75
|
-
const fileHasAdjustments = fileSupportsResize && Boolean(resizeOptions || formatOptions || trimOptions || file.tempFilePath);
|
|
78
|
+
const fileHasAdjustments = fileSupportsResize && Boolean(resizeOptions || formatOptions || imageSizes || trimOptions || file.tempFilePath);
|
|
76
79
|
const sharpOptions = {};
|
|
77
80
|
if (fileIsAnimated) sharpOptions.animated = true;
|
|
78
81
|
if (fileHasAdjustments && sharp) {
|
|
@@ -103,7 +106,7 @@ export const generateFileData = async ({ collection: { config: collectionConfig
|
|
|
103
106
|
fileBuffer = await sharpFile.toBuffer({
|
|
104
107
|
resolveWithObject: true
|
|
105
108
|
});
|
|
106
|
-
({ ext, mime } = await
|
|
109
|
+
({ ext, mime } = await fileTypeFromBuffer(fileBuffer.data) // This is getting an incorrect gif height back.
|
|
107
110
|
);
|
|
108
111
|
fileData.width = fileBuffer.info.width;
|
|
109
112
|
fileData.height = fileBuffer.info.height;
|
|
@@ -138,6 +141,7 @@ export const generateFileData = async ({ collection: { config: collectionConfig
|
|
|
138
141
|
fileData.filename = fsSafeName;
|
|
139
142
|
let fileForResize = file;
|
|
140
143
|
if (cropData && sharp) {
|
|
144
|
+
const metadata = await sharpFile.metadata();
|
|
141
145
|
const { data: croppedImage, info } = await cropImage({
|
|
142
146
|
cropData,
|
|
143
147
|
dimensions,
|
|
@@ -154,7 +158,7 @@ export const generateFileData = async ({ collection: { config: collectionConfig
|
|
|
154
158
|
size: info.size
|
|
155
159
|
};
|
|
156
160
|
fileData.width = info.width;
|
|
157
|
-
fileData.height = info.height;
|
|
161
|
+
fileData.height = fileIsAnimated ? info.height / metadata.pages : info.height;
|
|
158
162
|
fileData.filesize = info.size;
|
|
159
163
|
if (file.tempFilePath) {
|
|
160
164
|
await fs.promises.writeFile(file.tempFilePath, croppedImage) // write fileBuffer to the temp path
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/uploads/generateFileData.ts"],"sourcesContent":["import type { OutputInfo, Sharp, SharpOptions } from 'sharp'\n\nimport fileType from 'file-type'\nconst { fromBuffer } = fileType\nimport fs from 'fs'\nimport mkdirp from 'mkdirp'\nimport sanitize from 'sanitize-filename'\n\nimport type { Collection } from '../collections/config/types.js'\nimport type { SanitizedConfig } from '../config/types.js'\nimport type { PayloadRequestWithData } from '../types/index.js'\nimport type { FileData, FileToSave, ProbedImageSize, UploadEdits } from './types.js'\n\nimport { FileRetrievalError, FileUploadError, MissingFile } from '../errors/index.js'\nimport { canResizeImage } from './canResizeImage.js'\nimport { cropImage } from './cropImage.js'\nimport { getExternalFile } from './getExternalFile.js'\nimport { getFileByPath } from './getFileByPath.js'\nimport { getImageSize } from './getImageSize.js'\nimport { getSafeFileName } from './getSafeFilename.js'\nimport { resizeAndTransformImageSizes } from './imageResizer.js'\nimport { isImage } from './isImage.js'\n\ntype Args<T> = {\n collection: Collection\n config: SanitizedConfig\n data: T\n operation: 'create' | 'update'\n originalDoc?: T\n overwriteExistingFiles?: boolean\n req: PayloadRequestWithData\n throwOnMissingFile?: boolean\n}\n\ntype Result<T> = Promise<{\n data: T\n files: FileToSave[]\n}>\n\nexport const generateFileData = async <T>({\n collection: { config: collectionConfig },\n data,\n operation,\n originalDoc,\n overwriteExistingFiles,\n req,\n throwOnMissingFile,\n}: Args<T>): Result<T> => {\n if (!collectionConfig.upload) {\n return {\n data,\n files: [],\n }\n }\n\n const { sharp } = req.payload.config\n\n let file = req.file\n\n const uploadEdits = parseUploadEditsFromReqOrIncomingData({\n data,\n operation,\n originalDoc,\n req,\n })\n\n const {\n disableLocalStorage,\n focalPoint: focalPointEnabled = true,\n formatOptions,\n imageSizes,\n resizeOptions,\n staticDir,\n trimOptions,\n } = collectionConfig.upload\n\n const staticPath = staticDir\n\n if (!file && uploadEdits && data) {\n const { filename, url } = data as FileData\n\n try {\n if (url && url.startsWith('/') && !disableLocalStorage) {\n const filePath = `${staticPath}/${filename}`\n const response = await getFileByPath(filePath)\n file = response\n overwriteExistingFiles = true\n } else if (filename && url) {\n file = await getExternalFile({\n data: data as FileData,\n req,\n uploadConfig: collectionConfig.upload,\n })\n overwriteExistingFiles = true\n }\n } catch (err: unknown) {\n throw new FileRetrievalError(req.t, err instanceof Error ? err.message : undefined)\n }\n }\n\n if (!file) {\n if (throwOnMissingFile) throw new MissingFile(req.t)\n\n return {\n data,\n files: [],\n }\n }\n\n if (!disableLocalStorage) {\n mkdirp.sync(staticPath)\n }\n\n let newData = data\n const filesToSave: FileToSave[] = []\n const fileData: Partial<FileData> = {}\n const fileIsAnimated = file.mimetype === 'image/gif' || file.mimetype === 'image/webp'\n const cropData =\n typeof uploadEdits === 'object' && 'crop' in uploadEdits ? uploadEdits.crop : undefined\n\n try {\n const fileSupportsResize = canResizeImage(file.mimetype)\n let fsSafeName: string\n let sharpFile: Sharp | undefined\n let dimensions: ProbedImageSize | undefined\n let fileBuffer: { data: Buffer; info: OutputInfo }\n let ext\n let mime: string\n const fileHasAdjustments =\n fileSupportsResize &&\n Boolean(resizeOptions || formatOptions || trimOptions || file.tempFilePath)\n\n const sharpOptions: SharpOptions = {}\n\n if (fileIsAnimated) sharpOptions.animated = true\n\n if (fileHasAdjustments && sharp) {\n if (file.tempFilePath) {\n sharpFile = sharp(file.tempFilePath, sharpOptions).rotate() // pass rotate() to auto-rotate based on EXIF data. https://github.com/payloadcms/payload/pull/3081\n } else {\n sharpFile = sharp(file.data, sharpOptions).rotate() // pass rotate() to auto-rotate based on EXIF data. https://github.com/payloadcms/payload/pull/3081\n }\n\n if (resizeOptions) {\n sharpFile = sharpFile.resize(resizeOptions)\n }\n if (formatOptions) {\n sharpFile = sharpFile.toFormat(formatOptions.format, formatOptions.options)\n }\n if (trimOptions) {\n sharpFile = sharpFile.trim(trimOptions)\n }\n }\n\n if (fileSupportsResize || isImage(file.mimetype)) {\n dimensions = await getImageSize(file)\n fileData.width = dimensions.width\n fileData.height = dimensions.height\n }\n\n if (sharpFile) {\n const metadata = await sharpFile.metadata()\n fileBuffer = await sharpFile.toBuffer({ resolveWithObject: true })\n ;({ ext, mime } = await fromBuffer(fileBuffer.data)) // This is getting an incorrect gif height back.\n fileData.width = fileBuffer.info.width\n fileData.height = fileBuffer.info.height\n fileData.filesize = fileBuffer.info.size\n\n // Animated GIFs + WebP aggregate the height from every frame, so we need to use divide by number of pages\n if (metadata.pages) {\n fileData.height = fileBuffer.info.height / metadata.pages\n fileData.filesize = fileBuffer.data.length\n }\n } else {\n mime = file.mimetype\n fileData.filesize = file.size\n\n if (file.name.includes('.')) {\n ext = file.name.split('.').pop()\n } else {\n ext = ''\n }\n }\n\n // Adust SVG mime type. fromBuffer modifies it.\n if (mime === 'application/xml' && ext === 'svg') mime = 'image/svg+xml'\n fileData.mimeType = mime\n\n const baseFilename = sanitize(file.name.substring(0, file.name.lastIndexOf('.')) || file.name)\n fsSafeName = `${baseFilename}${ext ? `.${ext}` : ''}`\n\n if (!overwriteExistingFiles) {\n fsSafeName = await getSafeFileName({\n collectionSlug: collectionConfig.slug,\n desiredFilename: fsSafeName,\n req,\n staticPath,\n })\n }\n\n fileData.filename = fsSafeName\n let fileForResize = file\n\n if (cropData && sharp) {\n const { data: croppedImage, info } = await cropImage({ cropData, dimensions, file, sharp })\n\n filesToSave.push({\n buffer: croppedImage,\n path: `${staticPath}/${fsSafeName}`,\n })\n\n fileForResize = {\n ...file,\n data: croppedImage,\n size: info.size,\n }\n fileData.width = info.width\n fileData.height = info.height\n fileData.filesize = info.size\n\n if (file.tempFilePath) {\n await fs.promises.writeFile(file.tempFilePath, croppedImage) // write fileBuffer to the temp path\n } else {\n req.file = fileForResize\n }\n } else {\n filesToSave.push({\n buffer: fileBuffer?.data || file.data,\n path: `${staticPath}/${fsSafeName}`,\n })\n\n // If using temp files and the image is being resized, write the file to the temp path\n if (fileBuffer?.data || file.data.length > 0) {\n if (file.tempFilePath) {\n await fs.promises.writeFile(file.tempFilePath, fileBuffer?.data || file.data) // write fileBuffer to the temp path\n } else {\n // Assign the _possibly modified_ file to the request object\n req.file = {\n ...file,\n data: fileBuffer?.data || file.data,\n size: fileBuffer?.info.size,\n }\n }\n }\n }\n\n if (fileSupportsResize && (Array.isArray(imageSizes) || focalPointEnabled !== false)) {\n req.payloadUploadSizes = {}\n const { focalPoint, sizeData, sizesToSave } = await resizeAndTransformImageSizes({\n config: collectionConfig,\n dimensions: !cropData\n ? dimensions\n : {\n ...dimensions,\n height: fileData.height,\n width: fileData.width,\n },\n file: fileForResize,\n mimeType: fileData.mimeType,\n req,\n savedFilename: fsSafeName || file.name,\n sharp,\n staticPath,\n uploadEdits,\n })\n\n fileData.sizes = sizeData\n fileData.focalX = focalPoint?.x\n fileData.focalY = focalPoint?.y\n filesToSave.push(...sizesToSave)\n }\n } catch (err) {\n req.payload.logger.error(err)\n throw new FileUploadError(req.t)\n }\n\n newData = {\n ...newData,\n ...fileData,\n }\n\n return {\n data: newData,\n files: filesToSave,\n }\n}\n\n/**\n * Parse upload edits from req or incoming data\n */\nfunction parseUploadEditsFromReqOrIncomingData(args: {\n data: unknown\n operation: 'create' | 'update'\n originalDoc: unknown\n req: PayloadRequestWithData\n}): UploadEdits {\n const { data, operation, originalDoc, req } = args\n\n // Get intended focal point change from query string or incoming data\n const {\n uploadEdits = {},\n }: {\n uploadEdits?: UploadEdits\n } = req.query || {}\n\n if (uploadEdits.focalPoint) return uploadEdits\n\n const incomingData = data as FileData\n const origDoc = originalDoc as FileData\n\n // If no change in focal point, return undefined.\n // This prevents a refocal operation triggered from admin, because it always sends the focal point.\n if (origDoc && incomingData.focalX === origDoc.focalX && incomingData.focalY === origDoc.focalY) {\n return undefined\n }\n\n if (incomingData?.focalX && incomingData?.focalY) {\n uploadEdits.focalPoint = {\n x: incomingData.focalX,\n y: incomingData.focalY,\n }\n return uploadEdits\n }\n\n // If no focal point is set, default to center\n if (operation === 'create') {\n uploadEdits.focalPoint = {\n x: 50,\n y: 50,\n }\n }\n return uploadEdits\n}\n"],"names":["fileType","fromBuffer","fs","mkdirp","sanitize","FileRetrievalError","FileUploadError","MissingFile","canResizeImage","cropImage","getExternalFile","getFileByPath","getImageSize","getSafeFileName","resizeAndTransformImageSizes","isImage","generateFileData","collection","config","collectionConfig","data","operation","originalDoc","overwriteExistingFiles","req","throwOnMissingFile","upload","files","sharp","payload","file","uploadEdits","parseUploadEditsFromReqOrIncomingData","disableLocalStorage","focalPoint","focalPointEnabled","formatOptions","imageSizes","resizeOptions","staticDir","trimOptions","staticPath","filename","url","startsWith","filePath","response","uploadConfig","err","t","Error","message","undefined","sync","newData","filesToSave","fileData","fileIsAnimated","mimetype","cropData","crop","fileSupportsResize","fsSafeName","sharpFile","dimensions","fileBuffer","ext","mime","fileHasAdjustments","Boolean","tempFilePath","sharpOptions","animated","rotate","resize","toFormat","format","options","trim","width","height","metadata","toBuffer","resolveWithObject","info","filesize","size","pages","length","name","includes","split","pop","mimeType","baseFilename","substring","lastIndexOf","collectionSlug","slug","desiredFilename","fileForResize","croppedImage","push","buffer","path","promises","writeFile","Array","isArray","payloadUploadSizes","sizeData","sizesToSave","savedFilename","sizes","focalX","x","focalY","y","logger","error","args","query","incomingData","origDoc"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/uploads/generateFileData.ts"],"sourcesContent":["import type { OutputInfo, Sharp, SharpOptions } from 'sharp'\n\nimport { fileTypeFromBuffer } from 'file-type'\nimport fs from 'fs'\nimport mkdirp from 'mkdirp'\nimport sanitize from 'sanitize-filename'\n\nimport type { Collection } from '../collections/config/types.js'\nimport type { SanitizedConfig } from '../config/types.js'\nimport type { PayloadRequestWithData } from '../types/index.js'\nimport type { FileData, FileToSave, ProbedImageSize, UploadEdits } from './types.js'\n\nimport { FileRetrievalError, FileUploadError, MissingFile } from '../errors/index.js'\nimport { canResizeImage } from './canResizeImage.js'\nimport { cropImage } from './cropImage.js'\nimport { getExternalFile } from './getExternalFile.js'\nimport { getFileByPath } from './getFileByPath.js'\nimport { getImageSize } from './getImageSize.js'\nimport { getSafeFileName } from './getSafeFilename.js'\nimport { resizeAndTransformImageSizes } from './imageResizer.js'\nimport { isImage } from './isImage.js'\n\ntype Args<T> = {\n collection: Collection\n config: SanitizedConfig\n data: T\n operation: 'create' | 'update'\n originalDoc?: T\n overwriteExistingFiles?: boolean\n req: PayloadRequestWithData\n throwOnMissingFile?: boolean\n}\n\ntype Result<T> = Promise<{\n data: T\n files: FileToSave[]\n}>\n\nexport const generateFileData = async <T>({\n collection: { config: collectionConfig },\n data,\n operation,\n originalDoc,\n overwriteExistingFiles,\n req,\n throwOnMissingFile,\n}: Args<T>): Result<T> => {\n if (!collectionConfig.upload) {\n return {\n data,\n files: [],\n }\n }\n\n const { sharp } = req.payload.config\n\n let file = req.file\n\n const uploadEdits = parseUploadEditsFromReqOrIncomingData({\n data,\n operation,\n originalDoc,\n req,\n })\n\n const {\n disableLocalStorage,\n focalPoint: focalPointEnabled = true,\n formatOptions,\n imageSizes,\n resizeOptions,\n staticDir,\n trimOptions,\n } = collectionConfig.upload\n\n const staticPath = staticDir\n\n if (!file && uploadEdits && data) {\n const { filename, url } = data as FileData\n\n try {\n if (url && url.startsWith('/') && !disableLocalStorage) {\n const filePath = `${staticPath}/${filename}`\n const response = await getFileByPath(filePath)\n file = response\n overwriteExistingFiles = true\n } else if (filename && url) {\n file = await getExternalFile({\n data: data as FileData,\n req,\n uploadConfig: collectionConfig.upload,\n })\n overwriteExistingFiles = true\n }\n } catch (err: unknown) {\n throw new FileRetrievalError(req.t, err instanceof Error ? err.message : undefined)\n }\n }\n\n if (!file) {\n if (throwOnMissingFile) throw new MissingFile(req.t)\n\n return {\n data,\n files: [],\n }\n }\n\n if (!disableLocalStorage) {\n mkdirp.sync(staticPath)\n }\n\n let newData = data\n const filesToSave: FileToSave[] = []\n const fileData: Partial<FileData> = {}\n const fileIsAnimated = ['image/avif', 'image/gif', 'image/webp'].includes(file.mimetype)\n const cropData =\n typeof uploadEdits === 'object' && 'crop' in uploadEdits ? uploadEdits.crop : undefined\n\n try {\n const fileSupportsResize = canResizeImage(file.mimetype)\n let fsSafeName: string\n let sharpFile: Sharp | undefined\n let dimensions: ProbedImageSize | undefined\n let fileBuffer: { data: Buffer; info: OutputInfo }\n let ext\n let mime: string\n const fileHasAdjustments =\n fileSupportsResize &&\n Boolean(resizeOptions || formatOptions || imageSizes || trimOptions || file.tempFilePath)\n\n const sharpOptions: SharpOptions = {}\n\n if (fileIsAnimated) sharpOptions.animated = true\n\n if (fileHasAdjustments && sharp) {\n if (file.tempFilePath) {\n sharpFile = sharp(file.tempFilePath, sharpOptions).rotate() // pass rotate() to auto-rotate based on EXIF data. https://github.com/payloadcms/payload/pull/3081\n } else {\n sharpFile = sharp(file.data, sharpOptions).rotate() // pass rotate() to auto-rotate based on EXIF data. https://github.com/payloadcms/payload/pull/3081\n }\n\n if (resizeOptions) {\n sharpFile = sharpFile.resize(resizeOptions)\n }\n if (formatOptions) {\n sharpFile = sharpFile.toFormat(formatOptions.format, formatOptions.options)\n }\n if (trimOptions) {\n sharpFile = sharpFile.trim(trimOptions)\n }\n }\n\n if (fileSupportsResize || isImage(file.mimetype)) {\n dimensions = await getImageSize(file)\n fileData.width = dimensions.width\n fileData.height = dimensions.height\n }\n\n if (sharpFile) {\n const metadata = await sharpFile.metadata()\n fileBuffer = await sharpFile.toBuffer({ resolveWithObject: true })\n ;({ ext, mime } = await fileTypeFromBuffer(fileBuffer.data)) // This is getting an incorrect gif height back.\n fileData.width = fileBuffer.info.width\n fileData.height = fileBuffer.info.height\n fileData.filesize = fileBuffer.info.size\n\n // Animated GIFs + WebP aggregate the height from every frame, so we need to use divide by number of pages\n if (metadata.pages) {\n fileData.height = fileBuffer.info.height / metadata.pages\n fileData.filesize = fileBuffer.data.length\n }\n } else {\n mime = file.mimetype\n fileData.filesize = file.size\n\n if (file.name.includes('.')) {\n ext = file.name.split('.').pop()\n } else {\n ext = ''\n }\n }\n\n // Adust SVG mime type. fromBuffer modifies it.\n if (mime === 'application/xml' && ext === 'svg') mime = 'image/svg+xml'\n fileData.mimeType = mime\n\n const baseFilename = sanitize(file.name.substring(0, file.name.lastIndexOf('.')) || file.name)\n fsSafeName = `${baseFilename}${ext ? `.${ext}` : ''}`\n\n if (!overwriteExistingFiles) {\n fsSafeName = await getSafeFileName({\n collectionSlug: collectionConfig.slug,\n desiredFilename: fsSafeName,\n req,\n staticPath,\n })\n }\n\n fileData.filename = fsSafeName\n let fileForResize = file\n\n if (cropData && sharp) {\n const metadata = await sharpFile.metadata()\n const { data: croppedImage, info } = await cropImage({ cropData, dimensions, file, sharp })\n\n filesToSave.push({\n buffer: croppedImage,\n path: `${staticPath}/${fsSafeName}`,\n })\n\n fileForResize = {\n ...file,\n data: croppedImage,\n size: info.size,\n }\n fileData.width = info.width\n fileData.height = fileIsAnimated ? info.height / metadata.pages : info.height\n fileData.filesize = info.size\n\n if (file.tempFilePath) {\n await fs.promises.writeFile(file.tempFilePath, croppedImage) // write fileBuffer to the temp path\n } else {\n req.file = fileForResize\n }\n } else {\n filesToSave.push({\n buffer: fileBuffer?.data || file.data,\n path: `${staticPath}/${fsSafeName}`,\n })\n\n // If using temp files and the image is being resized, write the file to the temp path\n if (fileBuffer?.data || file.data.length > 0) {\n if (file.tempFilePath) {\n await fs.promises.writeFile(file.tempFilePath, fileBuffer?.data || file.data) // write fileBuffer to the temp path\n } else {\n // Assign the _possibly modified_ file to the request object\n req.file = {\n ...file,\n data: fileBuffer?.data || file.data,\n size: fileBuffer?.info.size,\n }\n }\n }\n }\n\n if (fileSupportsResize && (Array.isArray(imageSizes) || focalPointEnabled !== false)) {\n req.payloadUploadSizes = {}\n const { focalPoint, sizeData, sizesToSave } = await resizeAndTransformImageSizes({\n config: collectionConfig,\n dimensions: !cropData\n ? dimensions\n : {\n ...dimensions,\n height: fileData.height,\n width: fileData.width,\n },\n file: fileForResize,\n mimeType: fileData.mimeType,\n req,\n savedFilename: fsSafeName || file.name,\n sharp,\n staticPath,\n uploadEdits,\n })\n\n fileData.sizes = sizeData\n fileData.focalX = focalPoint?.x\n fileData.focalY = focalPoint?.y\n filesToSave.push(...sizesToSave)\n }\n } catch (err) {\n req.payload.logger.error(err)\n throw new FileUploadError(req.t)\n }\n\n newData = {\n ...newData,\n ...fileData,\n }\n\n return {\n data: newData,\n files: filesToSave,\n }\n}\n\n/**\n * Parse upload edits from req or incoming data\n */\nfunction parseUploadEditsFromReqOrIncomingData(args: {\n data: unknown\n operation: 'create' | 'update'\n originalDoc: unknown\n req: PayloadRequestWithData\n}): UploadEdits {\n const { data, operation, originalDoc, req } = args\n\n // Get intended focal point change from query string or incoming data\n const {\n uploadEdits = {},\n }: {\n uploadEdits?: UploadEdits\n } = req.query || {}\n\n if (uploadEdits.focalPoint) return uploadEdits\n\n const incomingData = data as FileData\n const origDoc = originalDoc as FileData\n\n // If no change in focal point, return undefined.\n // This prevents a refocal operation triggered from admin, because it always sends the focal point.\n if (origDoc && incomingData.focalX === origDoc.focalX && incomingData.focalY === origDoc.focalY) {\n return undefined\n }\n\n if (incomingData?.focalX && incomingData?.focalY) {\n uploadEdits.focalPoint = {\n x: incomingData.focalX,\n y: incomingData.focalY,\n }\n return uploadEdits\n }\n\n // If no focal point is set, default to center\n if (operation === 'create') {\n uploadEdits.focalPoint = {\n x: 50,\n y: 50,\n }\n }\n return uploadEdits\n}\n"],"names":["fileTypeFromBuffer","fs","mkdirp","sanitize","FileRetrievalError","FileUploadError","MissingFile","canResizeImage","cropImage","getExternalFile","getFileByPath","getImageSize","getSafeFileName","resizeAndTransformImageSizes","isImage","generateFileData","collection","config","collectionConfig","data","operation","originalDoc","overwriteExistingFiles","req","throwOnMissingFile","upload","files","sharp","payload","file","uploadEdits","parseUploadEditsFromReqOrIncomingData","disableLocalStorage","focalPoint","focalPointEnabled","formatOptions","imageSizes","resizeOptions","staticDir","trimOptions","staticPath","filename","url","startsWith","filePath","response","uploadConfig","err","t","Error","message","undefined","sync","newData","filesToSave","fileData","fileIsAnimated","includes","mimetype","cropData","crop","fileSupportsResize","fsSafeName","sharpFile","dimensions","fileBuffer","ext","mime","fileHasAdjustments","Boolean","tempFilePath","sharpOptions","animated","rotate","resize","toFormat","format","options","trim","width","height","metadata","toBuffer","resolveWithObject","info","filesize","size","pages","length","name","split","pop","mimeType","baseFilename","substring","lastIndexOf","collectionSlug","slug","desiredFilename","fileForResize","croppedImage","push","buffer","path","promises","writeFile","Array","isArray","payloadUploadSizes","sizeData","sizesToSave","savedFilename","sizes","focalX","x","focalY","y","logger","error","args","query","incomingData","origDoc"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getFileByPath.d.ts","sourceRoot":"","sources":["../../src/uploads/getFileByPath.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"getFileByPath.d.ts","sourceRoot":"","sources":["../../src/uploads/getFileByPath.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAA;AAM/D,eAAO,MAAM,aAAa,aAAoB,MAAM,KAAG,QAAQ,sBAAsB,CAAC,MAAM,CAAC,CAoB5F,CAAA"}
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { fileTypeFromFile } from 'file-type';
|
|
2
2
|
import fs from 'fs';
|
|
3
3
|
import path from 'path';
|
|
4
|
-
const { fromFile } = fileType;
|
|
5
4
|
const mimeTypeEstimate = {
|
|
6
5
|
svg: 'image/svg+xml'
|
|
7
6
|
};
|
|
8
7
|
export const getFileByPath = async (filePath)=>{
|
|
9
8
|
if (typeof filePath === 'string') {
|
|
10
9
|
const data = fs.readFileSync(filePath);
|
|
11
|
-
const mimetype =
|
|
10
|
+
const mimetype = fileTypeFromFile(filePath);
|
|
12
11
|
const { size } = fs.statSync(filePath);
|
|
13
12
|
const name = path.basename(filePath);
|
|
14
13
|
const ext = path.extname(filePath).slice(1);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/uploads/getFileByPath.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"sources":["../../src/uploads/getFileByPath.ts"],"sourcesContent":["import { fileTypeFromFile } from 'file-type'\nimport fs from 'fs'\nimport path from 'path'\n\nimport type { PayloadRequestWithData } from '../types/index.js'\n\nconst mimeTypeEstimate = {\n svg: 'image/svg+xml',\n}\n\nexport const getFileByPath = async (filePath: string): Promise<PayloadRequestWithData['file']> => {\n if (typeof filePath === 'string') {\n const data = fs.readFileSync(filePath)\n const mimetype = fileTypeFromFile(filePath)\n const { size } = fs.statSync(filePath)\n\n const name = path.basename(filePath)\n const ext = path.extname(filePath).slice(1)\n\n const mime = (await mimetype)?.mime || mimeTypeEstimate[ext]\n\n return {\n name,\n data,\n mimetype: mime,\n size,\n }\n }\n\n return undefined\n}\n"],"names":["fileTypeFromFile","fs","path","mimeTypeEstimate","svg","getFileByPath","filePath","data","readFileSync","mimetype","size","statSync","name","basename","ext","extname","slice","mime","undefined"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,SAASA,gBAAgB,QAAQ,YAAW;AAC5C,OAAOC,QAAQ,KAAI;AACnB,OAAOC,UAAU,OAAM;AAIvB,MAAMC,mBAAmB;IACvBC,KAAK;AACP;AAEA,OAAO,MAAMC,gBAAgB,OAAOC;IAClC,IAAI,OAAOA,aAAa,UAAU;QAChC,MAAMC,OAAON,GAAGO,YAAY,CAACF;QAC7B,MAAMG,WAAWT,iBAAiBM;QAClC,MAAM,EAAEI,IAAI,EAAE,GAAGT,GAAGU,QAAQ,CAACL;QAE7B,MAAMM,OAAOV,KAAKW,QAAQ,CAACP;QAC3B,MAAMQ,MAAMZ,KAAKa,OAAO,CAACT,UAAUU,KAAK,CAAC;QAEzC,MAAMC,OAAO,AAAC,CAAA,MAAMR,QAAO,GAAIQ,QAAQd,gBAAgB,CAACW,IAAI;QAE5D,OAAO;YACLF;YACAL;YACAE,UAAUQ;YACVP;QACF;IACF;IAEA,OAAOQ;AACT,EAAC"}
|
|
@@ -27,7 +27,7 @@ type ImageSizesResult = {
|
|
|
27
27
|
*
|
|
28
28
|
* The image will be resized according to the provided
|
|
29
29
|
* resize config. If no image sizes are requested, the resolved data will be empty.
|
|
30
|
-
* For every image that
|
|
30
|
+
* For every image that does not need to be resized, a result object with `null`
|
|
31
31
|
* parameters will be returned.
|
|
32
32
|
*
|
|
33
33
|
* @param resizeConfig - the resize config
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"imageResizer.d.ts","sourceRoot":"","sources":["../../src/uploads/imageResizer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"imageResizer.d.ts","sourceRoot":"","sources":["../../src/uploads/imageResizer.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAA;AAC/E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAA;AAC/D,OAAO,KAAK,EAEV,SAAS,EACT,UAAU,EAEV,eAAe,EACf,WAAW,EACZ,MAAM,YAAY,CAAA;AAKnB,KAAK,UAAU,GAAG;IAChB,MAAM,EAAE,yBAAyB,CAAA;IACjC,UAAU,EAAE,eAAe,CAAA;IAC3B,IAAI,EAAE,sBAAsB,CAAC,MAAM,CAAC,CAAA;IACpC,QAAQ,EAAE,MAAM,CAAA;IAChB,GAAG,EAAE,sBAAsB,CAAA;IAC3B,aAAa,EAAE,MAAM,CAAA;IACrB,KAAK,CAAC,EAAE,eAAe,CAAA;IACvB,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,WAAW,CAAA;CAC1B,CAAA;AAED,sEAAsE;AACtE,KAAK,gBAAgB,GAAG;IACtB,UAAU,CAAC,EAAE,WAAW,CAAC,YAAY,CAAC,CAAA;IACtC,QAAQ,EAAE,SAAS,CAAA;IACnB,WAAW,EAAE,UAAU,EAAE,CAAA;CAC1B,CAAA;AA6KD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,4BAA4B,CAAC,EACjD,MAAM,EACN,UAAU,EACV,IAAI,EACJ,QAAQ,EACR,GAAG,EACH,aAAa,EACb,KAAK,EACL,UAAU,EACV,WAAW,GACZ,EAAE,UAAU,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAmJxC"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
const { fromBuffer } = fileType;
|
|
1
|
+
import { fileTypeFromBuffer } from 'file-type';
|
|
3
2
|
import fs from 'fs';
|
|
4
3
|
import sanitize from 'sanitize-filename';
|
|
5
4
|
import { isNumber } from '../utilities/isNumber.js';
|
|
@@ -139,7 +138,7 @@ import fileExists from './fileExists.js';
|
|
|
139
138
|
*
|
|
140
139
|
* The image will be resized according to the provided
|
|
141
140
|
* resize config. If no image sizes are requested, the resolved data will be empty.
|
|
142
|
-
* For every image that
|
|
141
|
+
* For every image that does not need to be resized, a result object with `null`
|
|
143
142
|
* parameters will be returned.
|
|
144
143
|
*
|
|
145
144
|
* @param resizeConfig - the resize config
|
|
@@ -161,7 +160,15 @@ import fileExists from './fileExists.js';
|
|
|
161
160
|
if (!imageSizes || !sharp) {
|
|
162
161
|
return defaultResult;
|
|
163
162
|
}
|
|
164
|
-
|
|
163
|
+
// Determine if the file is animated
|
|
164
|
+
const fileIsAnimated = [
|
|
165
|
+
'image/avif',
|
|
166
|
+
'image/gif',
|
|
167
|
+
'image/webp'
|
|
168
|
+
].includes(file.mimetype);
|
|
169
|
+
const sharpOptions = {};
|
|
170
|
+
if (fileIsAnimated) sharpOptions.animated = true;
|
|
171
|
+
const sharpBase = sharp(file.tempFilePath || file.data, sharpOptions).rotate() // pass rotate() to auto-rotate based on EXIF data. https://github.com/payloadcms/payload/pull/3081
|
|
165
172
|
;
|
|
166
173
|
const results = await Promise.all(imageSizes.map(async (imageResizeConfig)=>{
|
|
167
174
|
imageResizeConfig = sanitizeResizeConfig(imageResizeConfig);
|
|
@@ -175,6 +182,7 @@ import fileExists from './fileExists.js';
|
|
|
175
182
|
}
|
|
176
183
|
const imageToResize = sharpBase.clone();
|
|
177
184
|
let resized = imageToResize;
|
|
185
|
+
const metadata = await sharpBase.metadata();
|
|
178
186
|
if (incomingFocalPoint && applyPayloadAdjustments(imageResizeConfig, dimensions)) {
|
|
179
187
|
const { height: resizeHeight, width: resizeWidth } = imageResizeConfig;
|
|
180
188
|
const resizeAspectRatio = resizeWidth / resizeHeight;
|
|
@@ -193,11 +201,11 @@ import fileExists from './fileExists.js';
|
|
|
193
201
|
const leftFocalEdge = Math.round(scaledImageInfo.width * (incomingFocalPoint.x / 100) - safeResizeWidth / 2);
|
|
194
202
|
const safeOffsetX = Math.min(Math.max(0, leftFocalEdge), maxOffsetX);
|
|
195
203
|
const safeResizeHeight = resizeHeight ?? scaledImageInfo.height;
|
|
196
|
-
const maxOffsetY = scaledImageInfo.height - safeResizeHeight;
|
|
204
|
+
const maxOffsetY = fileIsAnimated ? resizeHeight - safeResizeHeight : scaledImageInfo.height - safeResizeHeight;
|
|
197
205
|
const topFocalEdge = Math.round(scaledImageInfo.height * (incomingFocalPoint.y / 100) - safeResizeHeight / 2);
|
|
198
206
|
const safeOffsetY = Math.min(Math.max(0, topFocalEdge), maxOffsetY);
|
|
199
207
|
// extract the focal area from the scaled image
|
|
200
|
-
resized = scaledImage.extract({
|
|
208
|
+
resized = (fileIsAnimated ? imageToResize : scaledImage).extract({
|
|
201
209
|
height: safeResizeHeight,
|
|
202
210
|
left: safeOffsetX,
|
|
203
211
|
top: safeOffsetY,
|
|
@@ -219,7 +227,7 @@ import fileExists from './fileExists.js';
|
|
|
219
227
|
if (req.payloadUploadSizes) {
|
|
220
228
|
req.payloadUploadSizes[imageResizeConfig.name] = bufferData;
|
|
221
229
|
}
|
|
222
|
-
const mimeInfo = await
|
|
230
|
+
const mimeInfo = await fileTypeFromBuffer(bufferData);
|
|
223
231
|
const imageNameWithDimensions = createImageName(sanitizedImage.name, bufferInfo, mimeInfo?.ext || sanitizedImage.ext);
|
|
224
232
|
const imagePath = `${staticPath}/${imageNameWithDimensions}`;
|
|
225
233
|
if (await fileExists(imagePath)) {
|
|
@@ -234,7 +242,7 @@ import fileExists from './fileExists.js';
|
|
|
234
242
|
name: imageResizeConfig.name,
|
|
235
243
|
filename: imageNameWithDimensions,
|
|
236
244
|
filesize: size,
|
|
237
|
-
height,
|
|
245
|
+
height: fileIsAnimated ? height / metadata.pages : height,
|
|
238
246
|
mimeType: mimeInfo?.mime || mimeType,
|
|
239
247
|
sizesToSave: [
|
|
240
248
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/uploads/imageResizer.ts"],"sourcesContent":["import type { OutputInfo } from 'sharp'\n\nimport fileType from 'file-type'\nconst { fromBuffer } = fileType\n\nimport fs from 'fs'\nimport sanitize from 'sanitize-filename'\n\nimport type { SanitizedCollectionConfig } from '../collections/config/types.js'\nimport type { SharpDependency } from '../config/types.js'\nimport type { PayloadRequestWithData } from '../types/index.js'\nimport type {\n FileSize,\n FileSizes,\n FileToSave,\n ImageSize,\n ProbedImageSize,\n UploadEdits,\n} from './types.js'\n\nimport { isNumber } from '../utilities/isNumber.js'\nimport fileExists from './fileExists.js'\n\ntype ResizeArgs = {\n config: SanitizedCollectionConfig\n dimensions: ProbedImageSize\n file: PayloadRequestWithData['file']\n mimeType: string\n req: PayloadRequestWithData\n savedFilename: string\n sharp?: SharpDependency\n staticPath: string\n uploadEdits?: UploadEdits\n}\n\n/** Result from resizing and transforming the requested image sizes */\ntype ImageSizesResult = {\n focalPoint?: UploadEdits['focalPoint']\n sizeData: FileSizes\n sizesToSave: FileToSave[]\n}\n\ntype SanitizedImageData = {\n ext: string\n name: string\n}\n\n/**\n * Sanitize the image name and extract the extension from the source image\n *\n * @param sourceImage - the source image\n * @returns the sanitized name and extension\n */\nconst getSanitizedImageData = (sourceImage: string): SanitizedImageData => {\n const extension = sourceImage.split('.').pop()\n const name = sanitize(sourceImage.substring(0, sourceImage.lastIndexOf('.')) || sourceImage)\n return { name, ext: extension }\n}\n\n/**\n * Create a new image name based on the output image name, the dimensions and\n * the extension.\n *\n * Ignore the fact that duplicate names could happen if the there is one\n * size with `width AND height` and one with only `height OR width`. Because\n * space is expensive, we will reuse the same image for both sizes.\n *\n * @param outputImageName - the sanitized image name\n * @param bufferInfo - the buffer info\n * @param extension - the extension to use\n * @returns the new image name that is not taken\n */\nconst createImageName = (\n outputImageName: string,\n { height, width }: OutputInfo,\n extension: string,\n) => `${outputImageName}-${width}x${height}.${extension}`\n\ntype CreateResultArgs = {\n filename?: FileSize['filename']\n filesize?: FileSize['filesize']\n height?: FileSize['height']\n mimeType?: FileSize['mimeType']\n name: string\n sizesToSave?: FileToSave[]\n width?: FileSize['width']\n}\n\n/**\n * Create the result object for the image resize operation based on the\n * provided parameters. If the name is not provided, an empty result object\n * is returned.\n *\n * @param name - the name of the image\n * @param filename - the filename of the image\n * @param width - the width of the image\n * @param height - the height of the image\n * @param filesize - the filesize of the image\n * @param mimeType - the mime type of the image\n * @param sizesToSave - the sizes to save\n * @returns the result object\n */\nconst createResult = ({\n name,\n filename = null,\n filesize = null,\n height = null,\n mimeType = null,\n sizesToSave = [],\n width = null,\n}: CreateResultArgs): ImageSizesResult => {\n return {\n sizeData: {\n [name]: {\n filename,\n filesize,\n height,\n mimeType,\n width,\n },\n },\n sizesToSave,\n }\n}\n\n/**\n * Check if the image needs to be resized according to the requested dimensions\n * and the original image size. If the resize options withoutEnlargement or withoutReduction are provided,\n * the image will be resized regardless of the requested dimensions, given that the\n * width or height to be resized is provided.\n *\n * @param resizeConfig - object containing the requested dimensions and resize options\n * @param original - the original image size\n * @returns true if resizing is not needed, false otherwise\n */\nconst preventResize = (\n { height: desiredHeight, width: desiredWidth, withoutEnlargement, withoutReduction }: ImageSize,\n original: ProbedImageSize,\n): boolean => {\n // default is to allow reduction\n if (withoutReduction !== undefined) {\n return false // needs resize\n }\n\n // default is to prevent enlargement\n if (withoutEnlargement !== undefined) {\n return false // needs resize\n }\n\n const isWidthOrHeightNotDefined = !desiredHeight || !desiredWidth\n if (isWidthOrHeightNotDefined) {\n // If width and height are not defined, it means there is a format conversion\n // and the image needs to be \"resized\" (transformed).\n return false // needs resize\n }\n\n const hasInsufficientWidth = desiredWidth > original.width\n const hasInsufficientHeight = desiredHeight > original.height\n if (hasInsufficientWidth && hasInsufficientHeight) {\n // doesn't need resize - prevent enlargement. This should only happen if both width and height are insufficient.\n // if only one dimension is insufficient and the other is sufficient, resizing needs to happen, as the image\n // should be resized to the sufficient dimension.\n return true // do not create a new size\n }\n\n return false // needs resize\n}\n\n/**\n * Check if the image should be passed directly to sharp without payload adjusting properties.\n *\n * @param resizeConfig - object containing the requested dimensions and resize options\n * @param original - the original image size\n * @returns true if the image should passed directly to sharp\n */\nconst applyPayloadAdjustments = (\n { fit, height, width, withoutEnlargement, withoutReduction }: ImageSize,\n original: ProbedImageSize,\n) => {\n if (fit === 'contain' || fit === 'inside') return false\n if (!isNumber(height) && !isNumber(width)) return false\n\n const targetAspectRatio = width / height\n const originalAspectRatio = original.width / original.height\n if (originalAspectRatio === targetAspectRatio) return false\n\n const skipEnlargement = withoutEnlargement && (original.height < height || original.width < width)\n const skipReduction = withoutReduction && (original.height > height || original.width > width)\n if (skipEnlargement || skipReduction) return false\n\n return true\n}\n\n/**\n * Sanitize the resize config. If the resize config has the `withoutReduction`\n * property set to true, the `fit` and `position` properties will be set to `contain`\n * and `top left` respectively.\n *\n * @param resizeConfig - the resize config\n * @returns a sanitized resize config\n */\nconst sanitizeResizeConfig = (resizeConfig: ImageSize): ImageSize => {\n if (resizeConfig.withoutReduction) {\n return {\n ...resizeConfig,\n // Why fit `contain` should also be set to https://github.com/lovell/sharp/issues/3595\n fit: resizeConfig?.fit || 'contain',\n position: resizeConfig?.position || 'left top',\n }\n }\n return resizeConfig\n}\n\n/**\n * For the provided image sizes, handle the resizing and the transforms\n * (format, trim, etc.) of each requested image size and return the result object.\n * This only handles the image sizes. The transforms of the original image\n * are handled in {@link ./generateFileData.ts}.\n *\n * The image will be resized according to the provided\n * resize config. If no image sizes are requested, the resolved data will be empty.\n * For every image that dos not need to be resized, an result object with `null`\n * parameters will be returned.\n *\n * @param resizeConfig - the resize config\n * @returns the result of the resize operation(s)\n */\nexport async function resizeAndTransformImageSizes({\n config,\n dimensions,\n file,\n mimeType,\n req,\n savedFilename,\n sharp,\n staticPath,\n uploadEdits,\n}: ResizeArgs): Promise<ImageSizesResult> {\n const { focalPoint: focalPointEnabled = true, imageSizes } = config.upload\n\n // Focal point adjustments\n const incomingFocalPoint = uploadEdits.focalPoint\n ? {\n x: isNumber(uploadEdits.focalPoint.x) ? Math.round(uploadEdits.focalPoint.x) : 50,\n y: isNumber(uploadEdits.focalPoint.y) ? Math.round(uploadEdits.focalPoint.y) : 50,\n }\n : undefined\n\n const defaultResult: ImageSizesResult = {\n ...(focalPointEnabled && incomingFocalPoint && { focalPoint: incomingFocalPoint }),\n sizeData: {},\n sizesToSave: [],\n }\n\n if (!imageSizes || !sharp) {\n return defaultResult\n }\n\n const sharpBase = sharp(file.tempFilePath || file.data).rotate() // pass rotate() to auto-rotate based on EXIF data. https://github.com/payloadcms/payload/pull/3081\n\n const results: ImageSizesResult[] = await Promise.all(\n imageSizes.map(async (imageResizeConfig): Promise<ImageSizesResult> => {\n imageResizeConfig = sanitizeResizeConfig(imageResizeConfig)\n\n // This checks if a resize should happen. If not, the resized image will be\n // skipped COMPLETELY and thus will not be included in the resulting images.\n // All further format/trim options will thus be skipped as well.\n if (preventResize(imageResizeConfig, dimensions)) {\n return createResult({ name: imageResizeConfig.name })\n }\n\n const imageToResize = sharpBase.clone()\n let resized = imageToResize\n\n if (incomingFocalPoint && applyPayloadAdjustments(imageResizeConfig, dimensions)) {\n const { height: resizeHeight, width: resizeWidth } = imageResizeConfig\n const resizeAspectRatio = resizeWidth / resizeHeight\n const originalAspectRatio = dimensions.width / dimensions.height\n const prioritizeHeight = resizeAspectRatio < originalAspectRatio\n\n // Scale the image up or down to fit the resize dimensions\n const scaledImage = imageToResize.resize({\n height: prioritizeHeight ? resizeHeight : null,\n width: prioritizeHeight ? null : resizeWidth,\n })\n const { info: scaledImageInfo } = await scaledImage.toBuffer({ resolveWithObject: true })\n\n const safeResizeWidth = resizeWidth ?? scaledImageInfo.width\n const maxOffsetX = scaledImageInfo.width - safeResizeWidth\n const leftFocalEdge = Math.round(\n scaledImageInfo.width * (incomingFocalPoint.x / 100) - safeResizeWidth / 2,\n )\n const safeOffsetX = Math.min(Math.max(0, leftFocalEdge), maxOffsetX)\n\n const safeResizeHeight = resizeHeight ?? scaledImageInfo.height\n const maxOffsetY = scaledImageInfo.height - safeResizeHeight\n const topFocalEdge = Math.round(\n scaledImageInfo.height * (incomingFocalPoint.y / 100) - safeResizeHeight / 2,\n )\n const safeOffsetY = Math.min(Math.max(0, topFocalEdge), maxOffsetY)\n\n // extract the focal area from the scaled image\n resized = scaledImage.extract({\n height: safeResizeHeight,\n left: safeOffsetX,\n top: safeOffsetY,\n width: safeResizeWidth,\n })\n } else {\n resized = imageToResize.resize(imageResizeConfig)\n }\n\n if (imageResizeConfig.formatOptions) {\n resized = resized.toFormat(\n imageResizeConfig.formatOptions.format,\n imageResizeConfig.formatOptions.options,\n )\n }\n\n if (imageResizeConfig.trimOptions) {\n resized = resized.trim(imageResizeConfig.trimOptions)\n }\n\n const { data: bufferData, info: bufferInfo } = await resized.toBuffer({\n resolveWithObject: true,\n })\n\n const sanitizedImage = getSanitizedImageData(savedFilename)\n\n if (req.payloadUploadSizes) {\n req.payloadUploadSizes[imageResizeConfig.name] = bufferData\n }\n\n const mimeInfo = await fromBuffer(bufferData)\n\n const imageNameWithDimensions = createImageName(\n sanitizedImage.name,\n bufferInfo,\n mimeInfo?.ext || sanitizedImage.ext,\n )\n\n const imagePath = `${staticPath}/${imageNameWithDimensions}`\n\n if (await fileExists(imagePath)) {\n try {\n fs.unlinkSync(imagePath)\n } catch {\n // Ignore unlink errors\n }\n }\n\n const { height, size, width } = bufferInfo\n return createResult({\n name: imageResizeConfig.name,\n filename: imageNameWithDimensions,\n filesize: size,\n height,\n mimeType: mimeInfo?.mime || mimeType,\n sizesToSave: [{ buffer: bufferData, path: imagePath }],\n width,\n })\n }),\n )\n\n return results.reduce(\n (acc, result) => {\n Object.assign(acc.sizeData, result.sizeData)\n acc.sizesToSave.push(...result.sizesToSave)\n return acc\n },\n { ...defaultResult },\n )\n}\n"],"names":["fileType","fromBuffer","fs","sanitize","isNumber","fileExists","getSanitizedImageData","sourceImage","extension","split","pop","name","substring","lastIndexOf","ext","createImageName","outputImageName","height","width","createResult","filename","filesize","mimeType","sizesToSave","sizeData","preventResize","desiredHeight","desiredWidth","withoutEnlargement","withoutReduction","original","undefined","isWidthOrHeightNotDefined","hasInsufficientWidth","hasInsufficientHeight","applyPayloadAdjustments","fit","targetAspectRatio","originalAspectRatio","skipEnlargement","skipReduction","sanitizeResizeConfig","resizeConfig","position","resizeAndTransformImageSizes","config","dimensions","file","req","savedFilename","sharp","staticPath","uploadEdits","focalPoint","focalPointEnabled","imageSizes","upload","incomingFocalPoint","x","Math","round","y","defaultResult","sharpBase","tempFilePath","data","rotate","results","Promise","all","map","imageResizeConfig","imageToResize","clone","resized","resizeHeight","resizeWidth","resizeAspectRatio","prioritizeHeight","scaledImage","resize","info","scaledImageInfo","toBuffer","resolveWithObject","safeResizeWidth","maxOffsetX","leftFocalEdge","safeOffsetX","min","max","safeResizeHeight","maxOffsetY","topFocalEdge","safeOffsetY","extract","left","top","formatOptions","toFormat","format","options","trimOptions","trim","bufferData","bufferInfo","sanitizedImage","payloadUploadSizes","mimeInfo","imageNameWithDimensions","imagePath","unlinkSync","size","mime","buffer","path","reduce","acc","result","Object","assign","push"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/uploads/imageResizer.ts"],"sourcesContent":["import type { OutputInfo, Sharp, SharpOptions } from 'sharp'\n\nimport { fileTypeFromBuffer } from 'file-type'\nimport fs from 'fs'\nimport sanitize from 'sanitize-filename'\n\nimport type { SanitizedCollectionConfig } from '../collections/config/types.js'\nimport type { SharpDependency } from '../config/types.js'\nimport type { PayloadRequestWithData } from '../types/index.js'\nimport type {\n FileSize,\n FileSizes,\n FileToSave,\n ImageSize,\n ProbedImageSize,\n UploadEdits,\n} from './types.js'\n\nimport { isNumber } from '../utilities/isNumber.js'\nimport fileExists from './fileExists.js'\n\ntype ResizeArgs = {\n config: SanitizedCollectionConfig\n dimensions: ProbedImageSize\n file: PayloadRequestWithData['file']\n mimeType: string\n req: PayloadRequestWithData\n savedFilename: string\n sharp?: SharpDependency\n staticPath: string\n uploadEdits?: UploadEdits\n}\n\n/** Result from resizing and transforming the requested image sizes */\ntype ImageSizesResult = {\n focalPoint?: UploadEdits['focalPoint']\n sizeData: FileSizes\n sizesToSave: FileToSave[]\n}\n\ntype SanitizedImageData = {\n ext: string\n name: string\n}\n\n/**\n * Sanitize the image name and extract the extension from the source image\n *\n * @param sourceImage - the source image\n * @returns the sanitized name and extension\n */\nconst getSanitizedImageData = (sourceImage: string): SanitizedImageData => {\n const extension = sourceImage.split('.').pop()\n const name = sanitize(sourceImage.substring(0, sourceImage.lastIndexOf('.')) || sourceImage)\n return { name, ext: extension }\n}\n\n/**\n * Create a new image name based on the output image name, the dimensions and\n * the extension.\n *\n * Ignore the fact that duplicate names could happen if the there is one\n * size with `width AND height` and one with only `height OR width`. Because\n * space is expensive, we will reuse the same image for both sizes.\n *\n * @param outputImageName - the sanitized image name\n * @param bufferInfo - the buffer info\n * @param extension - the extension to use\n * @returns the new image name that is not taken\n */\nconst createImageName = (\n outputImageName: string,\n { height, width }: OutputInfo,\n extension: string,\n) => `${outputImageName}-${width}x${height}.${extension}`\n\ntype CreateResultArgs = {\n filename?: FileSize['filename']\n filesize?: FileSize['filesize']\n height?: FileSize['height']\n mimeType?: FileSize['mimeType']\n name: string\n sizesToSave?: FileToSave[]\n width?: FileSize['width']\n}\n\n/**\n * Create the result object for the image resize operation based on the\n * provided parameters. If the name is not provided, an empty result object\n * is returned.\n *\n * @param name - the name of the image\n * @param filename - the filename of the image\n * @param width - the width of the image\n * @param height - the height of the image\n * @param filesize - the filesize of the image\n * @param mimeType - the mime type of the image\n * @param sizesToSave - the sizes to save\n * @returns the result object\n */\nconst createResult = ({\n name,\n filename = null,\n filesize = null,\n height = null,\n mimeType = null,\n sizesToSave = [],\n width = null,\n}: CreateResultArgs): ImageSizesResult => {\n return {\n sizeData: {\n [name]: {\n filename,\n filesize,\n height,\n mimeType,\n width,\n },\n },\n sizesToSave,\n }\n}\n\n/**\n * Check if the image needs to be resized according to the requested dimensions\n * and the original image size. If the resize options withoutEnlargement or withoutReduction are provided,\n * the image will be resized regardless of the requested dimensions, given that the\n * width or height to be resized is provided.\n *\n * @param resizeConfig - object containing the requested dimensions and resize options\n * @param original - the original image size\n * @returns true if resizing is not needed, false otherwise\n */\nconst preventResize = (\n { height: desiredHeight, width: desiredWidth, withoutEnlargement, withoutReduction }: ImageSize,\n original: ProbedImageSize,\n): boolean => {\n // default is to allow reduction\n if (withoutReduction !== undefined) {\n return false // needs resize\n }\n\n // default is to prevent enlargement\n if (withoutEnlargement !== undefined) {\n return false // needs resize\n }\n\n const isWidthOrHeightNotDefined = !desiredHeight || !desiredWidth\n if (isWidthOrHeightNotDefined) {\n // If width and height are not defined, it means there is a format conversion\n // and the image needs to be \"resized\" (transformed).\n return false // needs resize\n }\n\n const hasInsufficientWidth = desiredWidth > original.width\n const hasInsufficientHeight = desiredHeight > original.height\n if (hasInsufficientWidth && hasInsufficientHeight) {\n // doesn't need resize - prevent enlargement. This should only happen if both width and height are insufficient.\n // if only one dimension is insufficient and the other is sufficient, resizing needs to happen, as the image\n // should be resized to the sufficient dimension.\n return true // do not create a new size\n }\n\n return false // needs resize\n}\n\n/**\n * Check if the image should be passed directly to sharp without payload adjusting properties.\n *\n * @param resizeConfig - object containing the requested dimensions and resize options\n * @param original - the original image size\n * @returns true if the image should passed directly to sharp\n */\nconst applyPayloadAdjustments = (\n { fit, height, width, withoutEnlargement, withoutReduction }: ImageSize,\n original: ProbedImageSize,\n) => {\n if (fit === 'contain' || fit === 'inside') return false\n if (!isNumber(height) && !isNumber(width)) return false\n\n const targetAspectRatio = width / height\n const originalAspectRatio = original.width / original.height\n if (originalAspectRatio === targetAspectRatio) return false\n\n const skipEnlargement = withoutEnlargement && (original.height < height || original.width < width)\n const skipReduction = withoutReduction && (original.height > height || original.width > width)\n if (skipEnlargement || skipReduction) return false\n\n return true\n}\n\n/**\n * Sanitize the resize config. If the resize config has the `withoutReduction`\n * property set to true, the `fit` and `position` properties will be set to `contain`\n * and `top left` respectively.\n *\n * @param resizeConfig - the resize config\n * @returns a sanitized resize config\n */\nconst sanitizeResizeConfig = (resizeConfig: ImageSize): ImageSize => {\n if (resizeConfig.withoutReduction) {\n return {\n ...resizeConfig,\n // Why fit `contain` should also be set to https://github.com/lovell/sharp/issues/3595\n fit: resizeConfig?.fit || 'contain',\n position: resizeConfig?.position || 'left top',\n }\n }\n return resizeConfig\n}\n\n/**\n * For the provided image sizes, handle the resizing and the transforms\n * (format, trim, etc.) of each requested image size and return the result object.\n * This only handles the image sizes. The transforms of the original image\n * are handled in {@link ./generateFileData.ts}.\n *\n * The image will be resized according to the provided\n * resize config. If no image sizes are requested, the resolved data will be empty.\n * For every image that does not need to be resized, a result object with `null`\n * parameters will be returned.\n *\n * @param resizeConfig - the resize config\n * @returns the result of the resize operation(s)\n */\nexport async function resizeAndTransformImageSizes({\n config,\n dimensions,\n file,\n mimeType,\n req,\n savedFilename,\n sharp,\n staticPath,\n uploadEdits,\n}: ResizeArgs): Promise<ImageSizesResult> {\n const { focalPoint: focalPointEnabled = true, imageSizes } = config.upload\n\n // Focal point adjustments\n const incomingFocalPoint = uploadEdits.focalPoint\n ? {\n x: isNumber(uploadEdits.focalPoint.x) ? Math.round(uploadEdits.focalPoint.x) : 50,\n y: isNumber(uploadEdits.focalPoint.y) ? Math.round(uploadEdits.focalPoint.y) : 50,\n }\n : undefined\n\n const defaultResult: ImageSizesResult = {\n ...(focalPointEnabled && incomingFocalPoint && { focalPoint: incomingFocalPoint }),\n sizeData: {},\n sizesToSave: [],\n }\n\n if (!imageSizes || !sharp) {\n return defaultResult\n }\n\n // Determine if the file is animated\n const fileIsAnimated = ['image/avif', 'image/gif', 'image/webp'].includes(file.mimetype)\n const sharpOptions: SharpOptions = {}\n\n if (fileIsAnimated) sharpOptions.animated = true\n\n const sharpBase: Sharp | undefined = sharp(file.tempFilePath || file.data, sharpOptions).rotate() // pass rotate() to auto-rotate based on EXIF data. https://github.com/payloadcms/payload/pull/3081\n\n const results: ImageSizesResult[] = await Promise.all(\n imageSizes.map(async (imageResizeConfig): Promise<ImageSizesResult> => {\n imageResizeConfig = sanitizeResizeConfig(imageResizeConfig)\n\n // This checks if a resize should happen. If not, the resized image will be\n // skipped COMPLETELY and thus will not be included in the resulting images.\n // All further format/trim options will thus be skipped as well.\n if (preventResize(imageResizeConfig, dimensions)) {\n return createResult({ name: imageResizeConfig.name })\n }\n\n const imageToResize = sharpBase.clone()\n let resized = imageToResize\n\n const metadata = await sharpBase.metadata()\n\n if (incomingFocalPoint && applyPayloadAdjustments(imageResizeConfig, dimensions)) {\n const { height: resizeHeight, width: resizeWidth } = imageResizeConfig\n const resizeAspectRatio = resizeWidth / resizeHeight\n const originalAspectRatio = dimensions.width / dimensions.height\n const prioritizeHeight = resizeAspectRatio < originalAspectRatio\n\n // Scale the image up or down to fit the resize dimensions\n const scaledImage = imageToResize.resize({\n height: prioritizeHeight ? resizeHeight : null,\n width: prioritizeHeight ? null : resizeWidth,\n })\n const { info: scaledImageInfo } = await scaledImage.toBuffer({ resolveWithObject: true })\n\n const safeResizeWidth = resizeWidth ?? scaledImageInfo.width\n const maxOffsetX = scaledImageInfo.width - safeResizeWidth\n const leftFocalEdge = Math.round(\n scaledImageInfo.width * (incomingFocalPoint.x / 100) - safeResizeWidth / 2,\n )\n const safeOffsetX = Math.min(Math.max(0, leftFocalEdge), maxOffsetX)\n\n const safeResizeHeight = resizeHeight ?? scaledImageInfo.height\n\n const maxOffsetY = fileIsAnimated\n ? resizeHeight - safeResizeHeight\n : scaledImageInfo.height - safeResizeHeight\n\n const topFocalEdge = Math.round(\n scaledImageInfo.height * (incomingFocalPoint.y / 100) - safeResizeHeight / 2,\n )\n const safeOffsetY = Math.min(Math.max(0, topFocalEdge), maxOffsetY)\n\n // extract the focal area from the scaled image\n resized = (fileIsAnimated ? imageToResize : scaledImage).extract({\n height: safeResizeHeight,\n left: safeOffsetX,\n top: safeOffsetY,\n width: safeResizeWidth,\n })\n } else {\n resized = imageToResize.resize(imageResizeConfig)\n }\n\n if (imageResizeConfig.formatOptions) {\n resized = resized.toFormat(\n imageResizeConfig.formatOptions.format,\n imageResizeConfig.formatOptions.options,\n )\n }\n\n if (imageResizeConfig.trimOptions) {\n resized = resized.trim(imageResizeConfig.trimOptions)\n }\n\n const { data: bufferData, info: bufferInfo } = await resized.toBuffer({\n resolveWithObject: true,\n })\n\n const sanitizedImage = getSanitizedImageData(savedFilename)\n\n if (req.payloadUploadSizes) {\n req.payloadUploadSizes[imageResizeConfig.name] = bufferData\n }\n\n const mimeInfo = await fileTypeFromBuffer(bufferData)\n\n const imageNameWithDimensions = createImageName(\n sanitizedImage.name,\n bufferInfo,\n mimeInfo?.ext || sanitizedImage.ext,\n )\n\n const imagePath = `${staticPath}/${imageNameWithDimensions}`\n\n if (await fileExists(imagePath)) {\n try {\n fs.unlinkSync(imagePath)\n } catch {\n // Ignore unlink errors\n }\n }\n\n const { height, size, width } = bufferInfo\n return createResult({\n name: imageResizeConfig.name,\n filename: imageNameWithDimensions,\n filesize: size,\n height: fileIsAnimated ? height / metadata.pages : height,\n mimeType: mimeInfo?.mime || mimeType,\n sizesToSave: [{ buffer: bufferData, path: imagePath }],\n width,\n })\n }),\n )\n\n return results.reduce(\n (acc, result) => {\n Object.assign(acc.sizeData, result.sizeData)\n acc.sizesToSave.push(...result.sizesToSave)\n return acc\n },\n { ...defaultResult },\n )\n}\n"],"names":["fileTypeFromBuffer","fs","sanitize","isNumber","fileExists","getSanitizedImageData","sourceImage","extension","split","pop","name","substring","lastIndexOf","ext","createImageName","outputImageName","height","width","createResult","filename","filesize","mimeType","sizesToSave","sizeData","preventResize","desiredHeight","desiredWidth","withoutEnlargement","withoutReduction","original","undefined","isWidthOrHeightNotDefined","hasInsufficientWidth","hasInsufficientHeight","applyPayloadAdjustments","fit","targetAspectRatio","originalAspectRatio","skipEnlargement","skipReduction","sanitizeResizeConfig","resizeConfig","position","resizeAndTransformImageSizes","config","dimensions","file","req","savedFilename","sharp","staticPath","uploadEdits","focalPoint","focalPointEnabled","imageSizes","upload","incomingFocalPoint","x","Math","round","y","defaultResult","fileIsAnimated","includes","mimetype","sharpOptions","animated","sharpBase","tempFilePath","data","rotate","results","Promise","all","map","imageResizeConfig","imageToResize","clone","resized","metadata","resizeHeight","resizeWidth","resizeAspectRatio","prioritizeHeight","scaledImage","resize","info","scaledImageInfo","toBuffer","resolveWithObject","safeResizeWidth","maxOffsetX","leftFocalEdge","safeOffsetX","min","max","safeResizeHeight","maxOffsetY","topFocalEdge","safeOffsetY","extract","left","top","formatOptions","toFormat","format","options","trimOptions","trim","bufferData","bufferInfo","sanitizedImage","payloadUploadSizes","mimeInfo","imageNameWithDimensions","imagePath","unlinkSync","size","pages","mime","buffer","path","reduce","acc","result","Object","assign","push"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "payload",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.42",
|
|
4
4
|
"description": "Node, React, Headless CMS and Application Framework built on Next.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"admin panel",
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
"console-table-printer": "2.11.2",
|
|
77
77
|
"dataloader": "2.2.2",
|
|
78
78
|
"deepmerge": "4.3.1",
|
|
79
|
-
"file-type": "
|
|
79
|
+
"file-type": "17.1.6",
|
|
80
80
|
"find-up": "7.0.0",
|
|
81
81
|
"get-tsconfig": "^4.7.2",
|
|
82
82
|
"http-status": "1.6.2",
|
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
"scmp": "2.1.0",
|
|
95
95
|
"ts-essentials": "7.0.3",
|
|
96
96
|
"uuid": "^9.0.1",
|
|
97
|
-
"@payloadcms/translations": "3.0.0-beta.
|
|
97
|
+
"@payloadcms/translations": "3.0.0-beta.42"
|
|
98
98
|
},
|
|
99
99
|
"devDependencies": {
|
|
100
100
|
"@monaco-editor/react": "4.5.1",
|