payload 3.0.0-beta.46 → 3.0.0-beta.48

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.
Files changed (65) hide show
  1. package/dist/admin/LanguageOptions.d.ts +2 -1
  2. package/dist/admin/LanguageOptions.d.ts.map +1 -1
  3. package/dist/admin/LanguageOptions.js.map +1 -1
  4. package/dist/admin/forms/Label.d.ts +1 -0
  5. package/dist/admin/forms/Label.d.ts.map +1 -1
  6. package/dist/admin/forms/Label.js.map +1 -1
  7. package/dist/admin/views/types.d.ts +1 -1
  8. package/dist/admin/views/types.d.ts.map +1 -1
  9. package/dist/admin/views/types.js.map +1 -1
  10. package/dist/auth/operations/forgotPassword.js +1 -1
  11. package/dist/auth/operations/forgotPassword.js.map +1 -1
  12. package/dist/auth/operations/local/login.d.ts +1 -2
  13. package/dist/auth/operations/local/login.d.ts.map +1 -1
  14. package/dist/auth/operations/local/login.js.map +1 -1
  15. package/dist/auth/operations/local/resetPassword.d.ts +1 -2
  16. package/dist/auth/operations/local/resetPassword.d.ts.map +1 -1
  17. package/dist/auth/operations/local/resetPassword.js.map +1 -1
  18. package/dist/auth/operations/local/unlock.d.ts +1 -2
  19. package/dist/auth/operations/local/unlock.d.ts.map +1 -1
  20. package/dist/auth/operations/local/unlock.js.map +1 -1
  21. package/dist/auth/operations/local/verifyEmail.d.ts +1 -2
  22. package/dist/auth/operations/local/verifyEmail.d.ts.map +1 -1
  23. package/dist/auth/operations/local/verifyEmail.js.map +1 -1
  24. package/dist/auth/operations/refresh.d.ts +1 -2
  25. package/dist/auth/operations/refresh.d.ts.map +1 -1
  26. package/dist/auth/operations/refresh.js.map +1 -1
  27. package/dist/bin/loader/index.d.ts.map +1 -1
  28. package/dist/bin/loader/index.js +2 -1
  29. package/dist/bin/loader/index.js.map +1 -1
  30. package/dist/bin/loader/resolveOriginalPath.d.ts.map +1 -1
  31. package/dist/bin/loader/resolveOriginalPath.js +6 -2
  32. package/dist/bin/loader/resolveOriginalPath.js.map +1 -1
  33. package/dist/collections/operations/local/create.d.ts +1 -2
  34. package/dist/collections/operations/local/create.d.ts.map +1 -1
  35. package/dist/collections/operations/local/create.js.map +1 -1
  36. package/dist/collections/operations/local/delete.d.ts +2 -4
  37. package/dist/collections/operations/local/delete.d.ts.map +1 -1
  38. package/dist/collections/operations/local/delete.js.map +1 -1
  39. package/dist/config/defaults.d.ts.map +1 -1
  40. package/dist/config/defaults.js +2 -1
  41. package/dist/config/defaults.js.map +1 -1
  42. package/dist/config/schema.d.ts.map +1 -1
  43. package/dist/config/schema.js +10 -1
  44. package/dist/config/schema.js.map +1 -1
  45. package/dist/config/shared/openGraphSchema.js +2 -2
  46. package/dist/config/shared/openGraphSchema.js.map +1 -1
  47. package/dist/config/types.d.ts +3 -1
  48. package/dist/config/types.d.ts.map +1 -1
  49. package/dist/config/types.js.map +1 -1
  50. package/dist/globals/config/types.d.ts +1 -2
  51. package/dist/globals/config/types.d.ts.map +1 -1
  52. package/dist/globals/config/types.js.map +1 -1
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +4 -0
  55. package/dist/index.js.map +1 -1
  56. package/dist/uploads/cropImage.js +2 -2
  57. package/dist/uploads/cropImage.js.map +1 -1
  58. package/dist/uploads/generateFileData.js +4 -4
  59. package/dist/uploads/generateFileData.js.map +1 -1
  60. package/dist/uploads/getBaseFields.js +1 -1
  61. package/dist/uploads/getBaseFields.js.map +1 -1
  62. package/dist/uploads/imageResizer.d.ts.map +1 -1
  63. package/dist/uploads/imageResizer.js +21 -11
  64. package/dist/uploads/imageResizer.js.map +1 -1
  65. package/package.json +2 -2
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { ExecutionResult, GraphQLSchema, ValidationRule } from 'graphql'\nimport type { OperationArgs, Request as graphQLRequest } from 'graphql-http'\nimport type pino from 'pino'\n\nimport { spawn } from 'child_process'\nimport crypto from 'crypto'\nimport { fileURLToPath } from 'node:url'\nimport path from 'path'\n\nimport type { AuthArgs } from './auth/operations/auth.js'\nimport type { Result as ForgotPasswordResult } from './auth/operations/forgotPassword.js'\nimport type { Options as ForgotPasswordOptions } from './auth/operations/local/forgotPassword.js'\nimport type { Options as LoginOptions } from './auth/operations/local/login.js'\nimport type { Options as ResetPasswordOptions } from './auth/operations/local/resetPassword.js'\nimport type { Options as UnlockOptions } from './auth/operations/local/unlock.js'\nimport type { Options as VerifyEmailOptions } from './auth/operations/local/verifyEmail.js'\nimport type { Result as LoginResult } from './auth/operations/login.js'\nimport type { Result as ResetPasswordResult } from './auth/operations/resetPassword.js'\nimport type { AuthStrategy, User } from './auth/types.js'\nimport type { BulkOperationResult, Collection, TypeWithID } from './collections/config/types.js'\nimport type { Options as CountOptions } from './collections/operations/local/count.js'\nimport type { Options as CreateOptions } from './collections/operations/local/create.js'\nimport type {\n ByIDOptions as DeleteByIDOptions,\n ManyOptions as DeleteManyOptions,\n Options as DeleteOptions,\n} from './collections/operations/local/delete.js'\nimport type { Options as DuplicateOptions } from './collections/operations/local/duplicate.js'\nimport type { Options as FindOptions } from './collections/operations/local/find.js'\nimport type { Options as FindByIDOptions } from './collections/operations/local/findByID.js'\nimport type { Options as FindVersionByIDOptions } from './collections/operations/local/findVersionByID.js'\nimport type { Options as FindVersionsOptions } from './collections/operations/local/findVersions.js'\nimport type { Options as RestoreVersionOptions } from './collections/operations/local/restoreVersion.js'\nimport type {\n ByIDOptions as UpdateByIDOptions,\n ManyOptions as UpdateManyOptions,\n Options as UpdateOptions,\n} from './collections/operations/local/update.js'\nimport type { InitOptions, SanitizedConfig } from './config/types.js'\nimport type { BaseDatabaseAdapter, PaginatedDocs } from './database/types.js'\nimport type { InitializedEmailAdapter } from './email/types.js'\nimport type { TypeWithID as GlobalTypeWithID, Globals } from './globals/config/types.js'\nimport type { Options as FindGlobalOptions } from './globals/operations/local/findOne.js'\nimport type { Options as FindGlobalVersionByIDOptions } from './globals/operations/local/findVersionByID.js'\nimport type { Options as FindGlobalVersionsOptions } from './globals/operations/local/findVersions.js'\nimport type { Options as RestoreGlobalVersionOptions } from './globals/operations/local/restoreVersion.js'\nimport type { Options as UpdateGlobalOptions } from './globals/operations/local/update.js'\nimport type { TypeWithVersion } from './versions/types.js'\n\nimport { decrypt, encrypt } from './auth/crypto.js'\nimport { APIKeyAuthentication } from './auth/strategies/apiKey.js'\nimport { JWTAuthentication } from './auth/strategies/jwt.js'\nimport localOperations from './collections/operations/local/index.js'\nimport { validateSchema } from './config/validate.js'\nimport { consoleEmailAdapter } from './email/consoleEmailAdapter.js'\nimport { fieldAffectsData } from './fields/config/types.js'\nimport localGlobalOperations from './globals/operations/local/index.js'\nimport flattenFields from './utilities/flattenTopLevelFields.js'\nimport Logger from './utilities/logger.js'\nimport { serverInit as serverInitTelemetry } from './utilities/telemetry/events/serverInit.js'\n\nconst filename = fileURLToPath(import.meta.url)\nconst dirname = path.dirname(filename)\n\n/**\n * @description Payload\n */\nexport class BasePayload<TGeneratedTypes extends GeneratedTypes> {\n /**\n * @description Authorization and Authentication using headers and cookies to run auth user strategies\n * @returns cookies: Map<string, string>\n * @returns permissions: Permissions\n * @returns user: User\n */\n auth = async (options: AuthArgs) => {\n const { auth } = localOperations.auth\n return auth(this, options)\n }\n\n authStrategies: AuthStrategy[]\n\n collections: {\n [slug: number | string | symbol]: Collection\n } = {}\n\n config: SanitizedConfig\n\n /**\n * @description Performs count operation\n * @param options\n * @returns count of documents satisfying query\n */\n count = async <T extends keyof TGeneratedTypes['collections']>(\n options: CountOptions<T>,\n ): Promise<{ totalDocs: number }> => {\n const { count } = localOperations\n return count(this, options)\n }\n\n /**\n * @description Performs create operation\n * @param options\n * @returns created document\n */\n create = async <T extends keyof TGeneratedTypes['collections']>(\n options: CreateOptions<T>,\n ): Promise<TGeneratedTypes['collections'][T]> => {\n const { create } = localOperations\n return create<T>(this, options)\n }\n db: DatabaseAdapter\n\n decrypt = decrypt\n\n duplicate = async <T extends keyof TGeneratedTypes['collections']>(\n options: DuplicateOptions<T>,\n ): Promise<TGeneratedTypes['collections'][T]> => {\n const { duplicate } = localOperations\n return duplicate<T>(this, options)\n }\n\n email: InitializedEmailAdapter\n\n // TODO: re-implement or remove?\n // errorHandler: ErrorHandler\n\n encrypt = encrypt\n\n extensions: (args: {\n args: OperationArgs<any>\n req: graphQLRequest<unknown, unknown>\n result: ExecutionResult\n }) => Promise<any>\n\n /**\n * @description Find documents with criteria\n * @param options\n * @returns documents satisfying query\n */\n find = async <T extends keyof TGeneratedTypes['collections']>(\n options: FindOptions<T>,\n ): Promise<PaginatedDocs<TGeneratedTypes['collections'][T]>> => {\n const { find } = localOperations\n return find<T>(this, options)\n }\n\n /**\n * @description Find document by ID\n * @param options\n * @returns document with specified ID\n */\n findByID = async <T extends keyof TGeneratedTypes['collections']>(\n options: FindByIDOptions<T>,\n ): Promise<TGeneratedTypes['collections'][T]> => {\n const { findByID } = localOperations\n return findByID<T>(this, options)\n }\n\n findGlobal = async <T extends keyof TGeneratedTypes['globals']>(\n options: FindGlobalOptions<T>,\n ): Promise<TGeneratedTypes['globals'][T]> => {\n const { findOne } = localGlobalOperations\n return findOne<T>(this, options)\n }\n\n /**\n * @description Find global version by ID\n * @param options\n * @returns global version with specified ID\n */\n findGlobalVersionByID = async <T extends keyof TGeneratedTypes['globals']>(\n options: FindGlobalVersionByIDOptions<T>,\n ): Promise<TypeWithVersion<TGeneratedTypes['globals'][T]>> => {\n const { findVersionByID } = localGlobalOperations\n return findVersionByID<T>(this, options)\n }\n\n /**\n * @description Find global versions with criteria\n * @param options\n * @returns versions satisfying query\n */\n findGlobalVersions = async <T extends keyof TGeneratedTypes['globals']>(\n options: FindGlobalVersionsOptions<T>,\n ): Promise<PaginatedDocs<TypeWithVersion<TGeneratedTypes['globals'][T]>>> => {\n const { findVersions } = localGlobalOperations\n return findVersions<T>(this, options)\n }\n\n /**\n * @description Find version by ID\n * @param options\n * @returns version with specified ID\n */\n findVersionByID = async <T extends keyof TGeneratedTypes['collections']>(\n options: FindVersionByIDOptions<T>,\n ): Promise<TypeWithVersion<TGeneratedTypes['collections'][T]>> => {\n const { findVersionByID } = localOperations\n return findVersionByID<T>(this, options)\n }\n\n /**\n * @description Find versions with criteria\n * @param options\n * @returns versions satisfying query\n */\n findVersions = async <T extends keyof TGeneratedTypes['collections']>(\n options: FindVersionsOptions<T>,\n ): Promise<PaginatedDocs<TypeWithVersion<TGeneratedTypes['collections'][T]>>> => {\n const { findVersions } = localOperations\n return findVersions<T>(this, options)\n }\n\n forgotPassword = async <T extends keyof TGeneratedTypes['collections']>(\n options: ForgotPasswordOptions<T>,\n ): Promise<ForgotPasswordResult> => {\n const { forgotPassword } = localOperations.auth\n return forgotPassword<T>(this, options)\n }\n\n getAPIURL = (): string => `${this.config.serverURL}${this.config.routes.api}`\n\n getAdminURL = (): string => `${this.config.serverURL}${this.config.routes.admin}`\n\n globals: Globals\n\n logger: pino.Logger\n\n login = async <T extends keyof TGeneratedTypes['collections']>(\n options: LoginOptions<T>,\n ): Promise<LoginResult & { user: TGeneratedTypes['collections'][T] }> => {\n const { login } = localOperations.auth\n return login<T>(this, options)\n }\n\n resetPassword = async <T extends keyof TGeneratedTypes['collections']>(\n options: ResetPasswordOptions<T>,\n ): Promise<ResetPasswordResult> => {\n const { resetPassword } = localOperations.auth\n return resetPassword<T>(this, options)\n }\n\n /**\n * @description Restore global version by ID\n * @param options\n * @returns version with specified ID\n */\n restoreGlobalVersion = async <T extends keyof TGeneratedTypes['globals']>(\n options: RestoreGlobalVersionOptions<T>,\n ): Promise<TGeneratedTypes['globals'][T]> => {\n const { restoreVersion } = localGlobalOperations\n return restoreVersion<T>(this, options)\n }\n\n /**\n * @description Restore version by ID\n * @param options\n * @returns version with specified ID\n */\n restoreVersion = async <T extends keyof TGeneratedTypes['collections']>(\n options: RestoreVersionOptions<T>,\n ): Promise<TGeneratedTypes['collections'][T]> => {\n const { restoreVersion } = localOperations\n return restoreVersion<T>(this, options)\n }\n\n schema: GraphQLSchema\n\n secret: string\n\n sendEmail: InitializedEmailAdapter['sendEmail']\n\n types: {\n arrayTypes: any\n blockInputTypes: any\n blockTypes: any\n fallbackLocaleInputType?: any\n groupTypes: any\n localeInputType?: any\n tabTypes: any\n }\n\n unlock = async <T extends keyof TGeneratedTypes['collections']>(\n options: UnlockOptions<T>,\n ): Promise<boolean> => {\n const { unlock } = localOperations.auth\n return unlock(this, options)\n }\n\n updateGlobal = async <T extends keyof TGeneratedTypes['globals']>(\n options: UpdateGlobalOptions<T>,\n ): Promise<TGeneratedTypes['globals'][T]> => {\n const { update } = localGlobalOperations\n return update<T>(this, options)\n }\n\n validationRules: (args: OperationArgs<any>) => ValidationRule[]\n\n verifyEmail = async <T extends keyof TGeneratedTypes['collections']>(\n options: VerifyEmailOptions<T>,\n ): Promise<boolean> => {\n const { verifyEmail } = localOperations.auth\n return verifyEmail(this, options)\n }\n\n versions: {\n [slug: string]: any // TODO: Type this\n } = {}\n\n async bin({\n args,\n cwd,\n log,\n }: {\n args: string[]\n cwd?: string\n log?: boolean\n }): Promise<{ code: number }> {\n return new Promise((resolve, reject) => {\n const spawned = spawn('node', [path.resolve(dirname, '../bin.js'), ...args], {\n cwd,\n stdio: log || log === undefined ? 'inherit' : 'ignore',\n })\n\n spawned.on('exit', (code) => {\n resolve({ code })\n })\n\n spawned.on('error', (error) => {\n reject(error)\n })\n })\n }\n\n /**\n * @description delete one or more documents\n * @param options\n * @returns Updated document(s)\n */\n delete<T extends keyof TGeneratedTypes['collections']>(\n options: DeleteByIDOptions<T>,\n ): Promise<TGeneratedTypes['collections'][T]>\n\n delete<T extends keyof TGeneratedTypes['collections']>(\n options: DeleteManyOptions<T>,\n ): Promise<BulkOperationResult<T>>\n\n delete<T extends keyof TGeneratedTypes['collections']>(\n options: DeleteOptions<T>,\n ): Promise<BulkOperationResult<T> | TGeneratedTypes['collections'][T]> {\n const { deleteLocal } = localOperations\n return deleteLocal<T>(this, options)\n }\n\n /**\n * @description Initializes Payload\n * @param options\n */\n async init(options: InitOptions): Promise<Payload> {\n if (!options?.config) {\n throw new Error('Error: the payload config is required to initialize payload.')\n }\n\n this.logger = Logger('payload', options.loggerOptions, options.loggerDestination)\n\n this.config = await options.config\n\n if (process.env.NODE_ENV !== 'production') {\n validateSchema(this.config, this.logger)\n }\n\n if (!this.config.secret) {\n throw new Error('Error: missing secret key. A secret key is needed to secure Payload.')\n }\n\n this.secret = crypto.createHash('sha256').update(this.config.secret).digest('hex').slice(0, 32)\n\n this.globals = {\n config: this.config.globals,\n }\n\n this.config.collections.forEach((collection) => {\n const customID = flattenFields(collection.fields).find(\n (field) => fieldAffectsData(field) && field.name === 'id',\n )\n\n let customIDType\n\n if (customID?.type === 'number' || customID?.type === 'text') customIDType = customID.type\n\n this.collections[collection.slug] = {\n config: collection,\n customIDType,\n }\n })\n\n // Generate types on startup\n if (process.env.NODE_ENV !== 'production' && this.config.typescript.autoGenerate !== false) {\n // We cannot run it directly here, as generate-types imports json-schema-to-typescript, which breaks on turbopack.\n // see: https://github.com/vercel/next.js/issues/66723\n void this.bin({\n args: ['generate:types'],\n log: false,\n })\n }\n\n this.db = this.config.db.init({ payload: this })\n this.db.payload = this\n\n if (this.db?.init) {\n await this.db.init()\n }\n\n if (!options.disableDBConnect && this.db.connect) {\n await this.db.connect()\n }\n\n // Load email adapter\n if (this.config.email instanceof Promise) {\n const awaitedAdapter = await this.config.email\n this.email = awaitedAdapter({ payload: this })\n } else if (this.config.email) {\n this.email = this.config.email({ payload: this })\n } else {\n this.logger.warn(\n `No email adapter provided. Email will be written to console. More info at https://payloadcms.com/docs/email/overview.`,\n )\n\n this.email = consoleEmailAdapter({ payload: this })\n }\n\n this.sendEmail = this.email['sendEmail']\n\n serverInitTelemetry(this)\n\n // 1. loop over collections, if collection has auth strategy, initialize and push to array\n let jwtStrategyEnabled = false\n this.authStrategies = this.config.collections.reduce((authStrategies, collection) => {\n if (collection?.auth) {\n if (collection.auth.strategies.length > 0) {\n authStrategies.push(...collection.auth.strategies)\n }\n\n // 2. if api key enabled, push api key strategy into the array\n if (collection.auth?.useAPIKey) {\n authStrategies.push({\n name: `${collection.slug}-api-key`,\n authenticate: APIKeyAuthentication(collection),\n })\n }\n\n // 3. if localStrategy flag is true\n if (!collection.auth.disableLocalStrategy && !jwtStrategyEnabled) {\n jwtStrategyEnabled = true\n }\n }\n\n return authStrategies\n }, [] as AuthStrategy[])\n\n // 4. if enabled, push jwt strategy into authStrategies last\n if (jwtStrategyEnabled) {\n this.authStrategies.push({\n name: 'local-jwt',\n authenticate: JWTAuthentication,\n })\n }\n\n if (!options.disableOnInit) {\n if (typeof options.onInit === 'function') await options.onInit(this)\n if (typeof this.config.onInit === 'function') await this.config.onInit(this)\n }\n\n return this\n }\n\n update<T extends keyof TGeneratedTypes['collections']>(\n options: UpdateManyOptions<T>,\n ): Promise<BulkOperationResult<T>>\n\n /**\n * @description Update one or more documents\n * @param options\n * @returns Updated document(s)\n */\n update<T extends keyof TGeneratedTypes['collections']>(\n options: UpdateByIDOptions<T>,\n ): Promise<TGeneratedTypes['collections'][T]>\n\n update<T extends keyof TGeneratedTypes['collections']>(\n options: UpdateOptions<T>,\n ): Promise<BulkOperationResult<T> | TGeneratedTypes['collections'][T]> {\n const { update } = localOperations\n return update<T>(this, options)\n }\n}\n\nconst initialized = new BasePayload()\n\nexport default initialized\n\nlet cached = global._payload\n\nif (!cached) {\n // eslint-disable-next-line no-multi-assign\n cached = global._payload = { payload: null, promise: null }\n}\n\nexport const getPayload = async (options: InitOptions): Promise<BasePayload<GeneratedTypes>> => {\n if (!options?.config) {\n throw new Error('Error: the payload config is required for getPayload to work.')\n }\n\n if (cached.payload) {\n return cached.payload\n }\n\n if (!cached.promise) {\n cached.promise = new BasePayload<GeneratedTypes>().init(options)\n }\n\n try {\n cached.payload = await cached.promise\n } catch (e) {\n cached.promise = null\n throw e\n }\n\n return cached.payload\n}\n\ntype GeneratedTypes = {\n collections: {\n [slug: number | string | symbol]: TypeWithID & Record<string, unknown>\n }\n globals: {\n [slug: number | string | symbol]: GlobalTypeWithID & Record<string, unknown>\n }\n locale: null | string\n user: User\n}\n\ntype Payload = BasePayload<GeneratedTypes>\n\ninterface RequestContext {\n [key: string]: unknown\n}\n\ntype DatabaseAdapter = BaseDatabaseAdapter\n\nexport type { DatabaseAdapter, GeneratedTypes, Payload, RequestContext }\n"],"names":["spawn","crypto","fileURLToPath","path","decrypt","encrypt","APIKeyAuthentication","JWTAuthentication","localOperations","validateSchema","consoleEmailAdapter","fieldAffectsData","localGlobalOperations","flattenFields","Logger","serverInit","serverInitTelemetry","filename","url","dirname","BasePayload","auth","options","authStrategies","collections","config","count","create","db","duplicate","email","extensions","find","findByID","findGlobal","findOne","findGlobalVersionByID","findVersionByID","findGlobalVersions","findVersions","forgotPassword","getAPIURL","serverURL","routes","api","getAdminURL","admin","globals","logger","login","resetPassword","restoreGlobalVersion","restoreVersion","schema","secret","sendEmail","types","unlock","updateGlobal","update","validationRules","verifyEmail","versions","bin","args","cwd","log","Promise","resolve","reject","spawned","stdio","undefined","on","code","error","delete","deleteLocal","init","Error","loggerOptions","loggerDestination","process","env","NODE_ENV","createHash","digest","slice","forEach","collection","customID","fields","field","name","customIDType","type","slug","typescript","autoGenerate","payload","disableDBConnect","connect","awaitedAdapter","warn","jwtStrategyEnabled","reduce","strategies","length","push","useAPIKey","authenticate","disableLocalStrategy","disableOnInit","onInit","initialized","cached","global","_payload","promise","getPayload","e"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { ExecutionResult, GraphQLSchema, ValidationRule } from 'graphql'\nimport type { OperationArgs, Request as graphQLRequest } from 'graphql-http'\nimport type pino from 'pino'\n\nimport { spawn } from 'child_process'\nimport crypto from 'crypto'\nimport { fileURLToPath } from 'node:url'\nimport path from 'path'\n\nimport type { AuthArgs } from './auth/operations/auth.js'\nimport type { Result as ForgotPasswordResult } from './auth/operations/forgotPassword.js'\nimport type { Options as ForgotPasswordOptions } from './auth/operations/local/forgotPassword.js'\nimport type { Options as LoginOptions } from './auth/operations/local/login.js'\nimport type { Options as ResetPasswordOptions } from './auth/operations/local/resetPassword.js'\nimport type { Options as UnlockOptions } from './auth/operations/local/unlock.js'\nimport type { Options as VerifyEmailOptions } from './auth/operations/local/verifyEmail.js'\nimport type { Result as LoginResult } from './auth/operations/login.js'\nimport type { Result as ResetPasswordResult } from './auth/operations/resetPassword.js'\nimport type { AuthStrategy, User } from './auth/types.js'\nimport type { BulkOperationResult, Collection, TypeWithID } from './collections/config/types.js'\nimport type { Options as CountOptions } from './collections/operations/local/count.js'\nimport type { Options as CreateOptions } from './collections/operations/local/create.js'\nimport type {\n ByIDOptions as DeleteByIDOptions,\n ManyOptions as DeleteManyOptions,\n Options as DeleteOptions,\n} from './collections/operations/local/delete.js'\nimport type { Options as DuplicateOptions } from './collections/operations/local/duplicate.js'\nimport type { Options as FindOptions } from './collections/operations/local/find.js'\nimport type { Options as FindByIDOptions } from './collections/operations/local/findByID.js'\nimport type { Options as FindVersionByIDOptions } from './collections/operations/local/findVersionByID.js'\nimport type { Options as FindVersionsOptions } from './collections/operations/local/findVersions.js'\nimport type { Options as RestoreVersionOptions } from './collections/operations/local/restoreVersion.js'\nimport type {\n ByIDOptions as UpdateByIDOptions,\n ManyOptions as UpdateManyOptions,\n Options as UpdateOptions,\n} from './collections/operations/local/update.js'\nimport type { InitOptions, SanitizedConfig } from './config/types.js'\nimport type { BaseDatabaseAdapter, PaginatedDocs } from './database/types.js'\nimport type { InitializedEmailAdapter } from './email/types.js'\nimport type { TypeWithID as GlobalTypeWithID, Globals } from './globals/config/types.js'\nimport type { Options as FindGlobalOptions } from './globals/operations/local/findOne.js'\nimport type { Options as FindGlobalVersionByIDOptions } from './globals/operations/local/findVersionByID.js'\nimport type { Options as FindGlobalVersionsOptions } from './globals/operations/local/findVersions.js'\nimport type { Options as RestoreGlobalVersionOptions } from './globals/operations/local/restoreVersion.js'\nimport type { Options as UpdateGlobalOptions } from './globals/operations/local/update.js'\nimport type { TypeWithVersion } from './versions/types.js'\n\nimport { decrypt, encrypt } from './auth/crypto.js'\nimport { APIKeyAuthentication } from './auth/strategies/apiKey.js'\nimport { JWTAuthentication } from './auth/strategies/jwt.js'\nimport localOperations from './collections/operations/local/index.js'\nimport { validateSchema } from './config/validate.js'\nimport { consoleEmailAdapter } from './email/consoleEmailAdapter.js'\nimport { fieldAffectsData } from './fields/config/types.js'\nimport localGlobalOperations from './globals/operations/local/index.js'\nimport flattenFields from './utilities/flattenTopLevelFields.js'\nimport Logger from './utilities/logger.js'\nimport { serverInit as serverInitTelemetry } from './utilities/telemetry/events/serverInit.js'\n\nconst filename = fileURLToPath(import.meta.url)\nconst dirname = path.dirname(filename)\n\n/**\n * @description Payload\n */\nexport class BasePayload<TGeneratedTypes extends GeneratedTypes> {\n /**\n * @description Authorization and Authentication using headers and cookies to run auth user strategies\n * @returns cookies: Map<string, string>\n * @returns permissions: Permissions\n * @returns user: User\n */\n auth = async (options: AuthArgs) => {\n const { auth } = localOperations.auth\n return auth(this, options)\n }\n\n authStrategies: AuthStrategy[]\n\n collections: {\n [slug: number | string | symbol]: Collection\n } = {}\n\n config: SanitizedConfig\n\n /**\n * @description Performs count operation\n * @param options\n * @returns count of documents satisfying query\n */\n count = async <T extends keyof TGeneratedTypes['collections']>(\n options: CountOptions<T>,\n ): Promise<{ totalDocs: number }> => {\n const { count } = localOperations\n return count(this, options)\n }\n\n /**\n * @description Performs create operation\n * @param options\n * @returns created document\n */\n create = async <T extends keyof TGeneratedTypes['collections']>(\n options: CreateOptions<T>,\n ): Promise<TGeneratedTypes['collections'][T]> => {\n const { create } = localOperations\n return create<T>(this, options)\n }\n db: DatabaseAdapter\n\n decrypt = decrypt\n\n duplicate = async <T extends keyof TGeneratedTypes['collections']>(\n options: DuplicateOptions<T>,\n ): Promise<TGeneratedTypes['collections'][T]> => {\n const { duplicate } = localOperations\n return duplicate<T>(this, options)\n }\n\n email: InitializedEmailAdapter\n\n // TODO: re-implement or remove?\n // errorHandler: ErrorHandler\n\n encrypt = encrypt\n\n extensions: (args: {\n args: OperationArgs<any>\n req: graphQLRequest<unknown, unknown>\n result: ExecutionResult\n }) => Promise<any>\n\n /**\n * @description Find documents with criteria\n * @param options\n * @returns documents satisfying query\n */\n find = async <T extends keyof TGeneratedTypes['collections']>(\n options: FindOptions<T>,\n ): Promise<PaginatedDocs<TGeneratedTypes['collections'][T]>> => {\n const { find } = localOperations\n return find<T>(this, options)\n }\n\n /**\n * @description Find document by ID\n * @param options\n * @returns document with specified ID\n */\n findByID = async <T extends keyof TGeneratedTypes['collections']>(\n options: FindByIDOptions<T>,\n ): Promise<TGeneratedTypes['collections'][T]> => {\n const { findByID } = localOperations\n return findByID<T>(this, options)\n }\n\n findGlobal = async <T extends keyof TGeneratedTypes['globals']>(\n options: FindGlobalOptions<T>,\n ): Promise<TGeneratedTypes['globals'][T]> => {\n const { findOne } = localGlobalOperations\n return findOne<T>(this, options)\n }\n\n /**\n * @description Find global version by ID\n * @param options\n * @returns global version with specified ID\n */\n findGlobalVersionByID = async <T extends keyof TGeneratedTypes['globals']>(\n options: FindGlobalVersionByIDOptions<T>,\n ): Promise<TypeWithVersion<TGeneratedTypes['globals'][T]>> => {\n const { findVersionByID } = localGlobalOperations\n return findVersionByID<T>(this, options)\n }\n\n /**\n * @description Find global versions with criteria\n * @param options\n * @returns versions satisfying query\n */\n findGlobalVersions = async <T extends keyof TGeneratedTypes['globals']>(\n options: FindGlobalVersionsOptions<T>,\n ): Promise<PaginatedDocs<TypeWithVersion<TGeneratedTypes['globals'][T]>>> => {\n const { findVersions } = localGlobalOperations\n return findVersions<T>(this, options)\n }\n\n /**\n * @description Find version by ID\n * @param options\n * @returns version with specified ID\n */\n findVersionByID = async <T extends keyof TGeneratedTypes['collections']>(\n options: FindVersionByIDOptions<T>,\n ): Promise<TypeWithVersion<TGeneratedTypes['collections'][T]>> => {\n const { findVersionByID } = localOperations\n return findVersionByID<T>(this, options)\n }\n\n /**\n * @description Find versions with criteria\n * @param options\n * @returns versions satisfying query\n */\n findVersions = async <T extends keyof TGeneratedTypes['collections']>(\n options: FindVersionsOptions<T>,\n ): Promise<PaginatedDocs<TypeWithVersion<TGeneratedTypes['collections'][T]>>> => {\n const { findVersions } = localOperations\n return findVersions<T>(this, options)\n }\n\n forgotPassword = async <T extends keyof TGeneratedTypes['collections']>(\n options: ForgotPasswordOptions<T>,\n ): Promise<ForgotPasswordResult> => {\n const { forgotPassword } = localOperations.auth\n return forgotPassword<T>(this, options)\n }\n\n getAPIURL = (): string => `${this.config.serverURL}${this.config.routes.api}`\n\n getAdminURL = (): string => `${this.config.serverURL}${this.config.routes.admin}`\n\n globals: Globals\n\n logger: pino.Logger\n\n login = async <T extends keyof TGeneratedTypes['collections']>(\n options: LoginOptions<T>,\n ): Promise<LoginResult & { user: TGeneratedTypes['collections'][T] }> => {\n const { login } = localOperations.auth\n return login<T>(this, options)\n }\n\n resetPassword = async <T extends keyof TGeneratedTypes['collections']>(\n options: ResetPasswordOptions<T>,\n ): Promise<ResetPasswordResult> => {\n const { resetPassword } = localOperations.auth\n return resetPassword<T>(this, options)\n }\n\n /**\n * @description Restore global version by ID\n * @param options\n * @returns version with specified ID\n */\n restoreGlobalVersion = async <T extends keyof TGeneratedTypes['globals']>(\n options: RestoreGlobalVersionOptions<T>,\n ): Promise<TGeneratedTypes['globals'][T]> => {\n const { restoreVersion } = localGlobalOperations\n return restoreVersion<T>(this, options)\n }\n\n /**\n * @description Restore version by ID\n * @param options\n * @returns version with specified ID\n */\n restoreVersion = async <T extends keyof TGeneratedTypes['collections']>(\n options: RestoreVersionOptions<T>,\n ): Promise<TGeneratedTypes['collections'][T]> => {\n const { restoreVersion } = localOperations\n return restoreVersion<T>(this, options)\n }\n\n schema: GraphQLSchema\n\n secret: string\n\n sendEmail: InitializedEmailAdapter['sendEmail']\n\n types: {\n arrayTypes: any\n blockInputTypes: any\n blockTypes: any\n fallbackLocaleInputType?: any\n groupTypes: any\n localeInputType?: any\n tabTypes: any\n }\n\n unlock = async <T extends keyof TGeneratedTypes['collections']>(\n options: UnlockOptions<T>,\n ): Promise<boolean> => {\n const { unlock } = localOperations.auth\n return unlock(this, options)\n }\n\n updateGlobal = async <T extends keyof TGeneratedTypes['globals']>(\n options: UpdateGlobalOptions<T>,\n ): Promise<TGeneratedTypes['globals'][T]> => {\n const { update } = localGlobalOperations\n return update<T>(this, options)\n }\n\n validationRules: (args: OperationArgs<any>) => ValidationRule[]\n\n verifyEmail = async <T extends keyof TGeneratedTypes['collections']>(\n options: VerifyEmailOptions<T>,\n ): Promise<boolean> => {\n const { verifyEmail } = localOperations.auth\n return verifyEmail(this, options)\n }\n\n versions: {\n [slug: string]: any // TODO: Type this\n } = {}\n\n async bin({\n args,\n cwd,\n log,\n }: {\n args: string[]\n cwd?: string\n log?: boolean\n }): Promise<{ code: number }> {\n return new Promise((resolve, reject) => {\n const spawned = spawn('node', [path.resolve(dirname, '../bin.js'), ...args], {\n cwd,\n stdio: log || log === undefined ? 'inherit' : 'ignore',\n })\n\n spawned.on('exit', (code) => {\n resolve({ code })\n })\n\n spawned.on('error', (error) => {\n reject(error)\n })\n })\n }\n\n /**\n * @description delete one or more documents\n * @param options\n * @returns Updated document(s)\n */\n delete<T extends keyof TGeneratedTypes['collections']>(\n options: DeleteByIDOptions<T>,\n ): Promise<TGeneratedTypes['collections'][T]>\n\n delete<T extends keyof TGeneratedTypes['collections']>(\n options: DeleteManyOptions<T>,\n ): Promise<BulkOperationResult<T>>\n\n delete<T extends keyof TGeneratedTypes['collections']>(\n options: DeleteOptions<T>,\n ): Promise<BulkOperationResult<T> | TGeneratedTypes['collections'][T]> {\n const { deleteLocal } = localOperations\n return deleteLocal<T>(this, options)\n }\n\n /**\n * @description Initializes Payload\n * @param options\n */\n async init(options: InitOptions): Promise<Payload> {\n if (!options?.config) {\n throw new Error('Error: the payload config is required to initialize payload.')\n }\n\n this.logger = Logger('payload', options.loggerOptions, options.loggerDestination)\n\n this.config = await options.config\n\n if (process.env.NODE_ENV !== 'production') {\n validateSchema(this.config, this.logger)\n }\n\n if (!this.config.secret) {\n throw new Error('Error: missing secret key. A secret key is needed to secure Payload.')\n }\n\n this.secret = crypto.createHash('sha256').update(this.config.secret).digest('hex').slice(0, 32)\n\n this.globals = {\n config: this.config.globals,\n }\n\n this.config.collections.forEach((collection) => {\n const customID = flattenFields(collection.fields).find(\n (field) => fieldAffectsData(field) && field.name === 'id',\n )\n\n let customIDType\n\n if (customID?.type === 'number' || customID?.type === 'text') customIDType = customID.type\n\n this.collections[collection.slug] = {\n config: collection,\n customIDType,\n }\n })\n\n // Generate types on startup\n if (process.env.NODE_ENV !== 'production' && this.config.typescript.autoGenerate !== false) {\n // We cannot run it directly here, as generate-types imports json-schema-to-typescript, which breaks on turbopack.\n // see: https://github.com/vercel/next.js/issues/66723\n void this.bin({\n args: ['generate:types'],\n log: false,\n })\n }\n\n this.db = this.config.db.init({ payload: this })\n this.db.payload = this\n\n if (this.db?.init) {\n await this.db.init()\n }\n\n if (!options.disableDBConnect && this.db.connect) {\n await this.db.connect()\n }\n\n // Load email adapter\n if (this.config.email instanceof Promise) {\n const awaitedAdapter = await this.config.email\n this.email = awaitedAdapter({ payload: this })\n } else if (this.config.email) {\n this.email = this.config.email({ payload: this })\n } else {\n this.logger.warn(\n `No email adapter provided. Email will be written to console. More info at https://payloadcms.com/docs/email/overview.`,\n )\n\n this.email = consoleEmailAdapter({ payload: this })\n }\n\n // Warn if image resizing is enabled but sharp is not installed\n if (\n !this.config.sharp &&\n this.config.collections.some((c) => c.upload.imageSizes || c.upload.formatOptions)\n ) {\n this.logger.warn(\n `Image resizing is enabled for one or more collections, but sharp not installed. Please install 'sharp' and pass into the config.`,\n )\n }\n\n this.sendEmail = this.email['sendEmail']\n\n serverInitTelemetry(this)\n\n // 1. loop over collections, if collection has auth strategy, initialize and push to array\n let jwtStrategyEnabled = false\n this.authStrategies = this.config.collections.reduce((authStrategies, collection) => {\n if (collection?.auth) {\n if (collection.auth.strategies.length > 0) {\n authStrategies.push(...collection.auth.strategies)\n }\n\n // 2. if api key enabled, push api key strategy into the array\n if (collection.auth?.useAPIKey) {\n authStrategies.push({\n name: `${collection.slug}-api-key`,\n authenticate: APIKeyAuthentication(collection),\n })\n }\n\n // 3. if localStrategy flag is true\n if (!collection.auth.disableLocalStrategy && !jwtStrategyEnabled) {\n jwtStrategyEnabled = true\n }\n }\n\n return authStrategies\n }, [] as AuthStrategy[])\n\n // 4. if enabled, push jwt strategy into authStrategies last\n if (jwtStrategyEnabled) {\n this.authStrategies.push({\n name: 'local-jwt',\n authenticate: JWTAuthentication,\n })\n }\n\n if (!options.disableOnInit) {\n if (typeof options.onInit === 'function') await options.onInit(this)\n if (typeof this.config.onInit === 'function') await this.config.onInit(this)\n }\n\n return this\n }\n\n update<T extends keyof TGeneratedTypes['collections']>(\n options: UpdateManyOptions<T>,\n ): Promise<BulkOperationResult<T>>\n\n /**\n * @description Update one or more documents\n * @param options\n * @returns Updated document(s)\n */\n update<T extends keyof TGeneratedTypes['collections']>(\n options: UpdateByIDOptions<T>,\n ): Promise<TGeneratedTypes['collections'][T]>\n\n update<T extends keyof TGeneratedTypes['collections']>(\n options: UpdateOptions<T>,\n ): Promise<BulkOperationResult<T> | TGeneratedTypes['collections'][T]> {\n const { update } = localOperations\n return update<T>(this, options)\n }\n}\n\nconst initialized = new BasePayload()\n\nexport default initialized\n\nlet cached = global._payload\n\nif (!cached) {\n // eslint-disable-next-line no-multi-assign\n cached = global._payload = { payload: null, promise: null }\n}\n\nexport const getPayload = async (options: InitOptions): Promise<BasePayload<GeneratedTypes>> => {\n if (!options?.config) {\n throw new Error('Error: the payload config is required for getPayload to work.')\n }\n\n if (cached.payload) {\n return cached.payload\n }\n\n if (!cached.promise) {\n cached.promise = new BasePayload<GeneratedTypes>().init(options)\n }\n\n try {\n cached.payload = await cached.promise\n } catch (e) {\n cached.promise = null\n throw e\n }\n\n return cached.payload\n}\n\ntype GeneratedTypes = {\n collections: {\n [slug: number | string | symbol]: TypeWithID & Record<string, unknown>\n }\n globals: {\n [slug: number | string | symbol]: GlobalTypeWithID & Record<string, unknown>\n }\n locale: null | string\n user: User\n}\n\ntype Payload = BasePayload<GeneratedTypes>\n\ninterface RequestContext {\n [key: string]: unknown\n}\n\ntype DatabaseAdapter = BaseDatabaseAdapter\n\nexport type { DatabaseAdapter, GeneratedTypes, Payload, RequestContext }\n"],"names":["spawn","crypto","fileURLToPath","path","decrypt","encrypt","APIKeyAuthentication","JWTAuthentication","localOperations","validateSchema","consoleEmailAdapter","fieldAffectsData","localGlobalOperations","flattenFields","Logger","serverInit","serverInitTelemetry","filename","url","dirname","BasePayload","auth","options","authStrategies","collections","config","count","create","db","duplicate","email","extensions","find","findByID","findGlobal","findOne","findGlobalVersionByID","findVersionByID","findGlobalVersions","findVersions","forgotPassword","getAPIURL","serverURL","routes","api","getAdminURL","admin","globals","logger","login","resetPassword","restoreGlobalVersion","restoreVersion","schema","secret","sendEmail","types","unlock","updateGlobal","update","validationRules","verifyEmail","versions","bin","args","cwd","log","Promise","resolve","reject","spawned","stdio","undefined","on","code","error","delete","deleteLocal","init","Error","loggerOptions","loggerDestination","process","env","NODE_ENV","createHash","digest","slice","forEach","collection","customID","fields","field","name","customIDType","type","slug","typescript","autoGenerate","payload","disableDBConnect","connect","awaitedAdapter","warn","sharp","some","c","upload","imageSizes","formatOptions","jwtStrategyEnabled","reduce","strategies","length","push","useAPIKey","authenticate","disableLocalStrategy","disableOnInit","onInit","initialized","cached","global","_payload","promise","getPayload","e"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
@@ -4,13 +4,13 @@ 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 = [
7
+ const fileIsAnimatedType = [
8
8
  'image/avif',
9
9
  'image/gif',
10
10
  'image/webp'
11
11
  ].includes(file.mimetype);
12
12
  const sharpOptions = {};
13
- if (fileIsAnimated) sharpOptions.animated = true;
13
+ if (fileIsAnimatedType) sharpOptions.animated = true;
14
14
  const formattedCropData = {
15
15
  height: percentToPixel(height, dimensions.height),
16
16
  left: percentToPixel(x, dimensions.width),
@@ -1 +1 @@
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
+ {"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 fileIsAnimatedType = ['image/avif', 'image/gif', 'image/webp'].includes(file.mimetype)\n\n const sharpOptions: SharpOptions = {}\n\n if (fileIsAnimatedType) 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","fileIsAnimatedType","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,qBAAqB;YAAC;YAAc;YAAa;SAAa,CAACC,QAAQ,CAACP,KAAKQ,QAAQ;QAE3F,MAAMC,eAA6B,CAAC;QAEpC,IAAIH,oBAAoBG,aAAaC,QAAQ,GAAG;QAEhD,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"}
@@ -61,7 +61,7 @@ export const generateFileData = async ({ collection: { config: collectionConfig
61
61
  let newData = data;
62
62
  const filesToSave = [];
63
63
  const fileData = {};
64
- const fileIsAnimated = [
64
+ const fileIsAnimatedType = [
65
65
  'image/avif',
66
66
  'image/gif',
67
67
  'image/webp'
@@ -77,8 +77,8 @@ export const generateFileData = async ({ collection: { config: collectionConfig
77
77
  let mime;
78
78
  const fileHasAdjustments = fileSupportsResize && Boolean(resizeOptions || formatOptions || imageSizes || trimOptions || file.tempFilePath);
79
79
  const sharpOptions = {};
80
- if (fileIsAnimated) sharpOptions.animated = true;
81
- if (sharp && (fileIsAnimated || fileHasAdjustments)) {
80
+ if (fileIsAnimatedType) sharpOptions.animated = true;
81
+ if (sharp && (fileIsAnimatedType || fileHasAdjustments)) {
82
82
  if (file.tempFilePath) {
83
83
  sharpFile = sharp(file.tempFilePath, sharpOptions).rotate() // pass rotate() to auto-rotate based on EXIF data. https://github.com/payloadcms/payload/pull/3081
84
84
  ;
@@ -160,7 +160,7 @@ export const generateFileData = async ({ collection: { config: collectionConfig
160
160
  };
161
161
  fileData.width = info.width;
162
162
  fileData.height = info.height;
163
- if (fileIsAnimated) {
163
+ if (fileIsAnimatedType) {
164
164
  const metadata = await sharpFile.metadata();
165
165
  fileData.height = metadata.pages ? info.height / metadata.pages : info.height;
166
166
  }
@@ -1 +1 @@
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 (sharp && (fileIsAnimated || fileHasAdjustments)) {\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 (fileHasAdjustments) {\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\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 { 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 if (fileIsAnimated) {\n const metadata = await sharpFile.metadata()\n fileData.height = metadata.pages ? info.height / metadata.pages : info.height\n }\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
+ {"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 fileIsAnimatedType = ['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 (fileIsAnimatedType) sharpOptions.animated = true\n\n if (sharp && (fileIsAnimatedType || fileHasAdjustments)) {\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 (fileHasAdjustments) {\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\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 { 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 if (fileIsAnimatedType) {\n const metadata = await sharpFile.metadata()\n fileData.height = metadata.pages ? info.height / metadata.pages : info.height\n }\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","fileIsAnimatedType","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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"}
@@ -154,7 +154,7 @@ export const getBaseUploadFields = ({ collection, config })=>{
154
154
  hooks: {
155
155
  afterRead: [
156
156
  ({ data, value })=>{
157
- if (value) return value;
157
+ if (value && size.height && size.width) return value;
158
158
  const sizeFilename = data?.sizes?.[size.name]?.filename;
159
159
  if (sizeFilename) {
160
160
  return `${config.serverURL}${config.routes.api}/${collection.slug}/file/${sizeFilename}`;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/uploads/getBaseFields.ts"],"sourcesContent":["import type { CollectionConfig } from '../collections/config/types.js'\nimport type { Config } from '../config/types.js'\nimport type { Field } from '../fields/config/types.js'\nimport type { UploadConfig } from './types.js'\n\nimport { mimeTypeValidator } from './mimeTypeValidator.js'\n\ntype GenerateURLArgs = {\n collectionSlug: string\n config: Config\n filename?: string\n}\nconst generateURL = ({ collectionSlug, config, filename }: GenerateURLArgs) => {\n if (filename) {\n return `${config.serverURL || ''}${config.routes.api || ''}/${collectionSlug}/file/${filename}`\n }\n return undefined\n}\n\ntype Options = {\n collection: CollectionConfig\n config: Config\n}\n\nexport const getBaseUploadFields = ({ collection, config }: Options): Field[] => {\n const uploadOptions: UploadConfig = typeof collection.upload === 'object' ? collection.upload : {}\n\n const mimeType: Field = {\n name: 'mimeType',\n type: 'text',\n admin: {\n hidden: true,\n readOnly: true,\n },\n label: 'MIME Type',\n }\n\n const thumbnailURL: Field = {\n name: 'thumbnailURL',\n type: 'text',\n admin: {\n hidden: true,\n readOnly: true,\n },\n hooks: {\n afterRead: [\n ({ originalDoc }) => {\n const adminThumbnail =\n typeof collection.upload !== 'boolean' ? collection.upload?.adminThumbnail : undefined\n\n if (typeof adminThumbnail === 'function') {\n return adminThumbnail({ doc: originalDoc })\n }\n\n if (\n typeof adminThumbnail === 'string' &&\n 'sizes' in originalDoc &&\n originalDoc.sizes?.[adminThumbnail]?.filename\n ) {\n return generateURL({\n collectionSlug: collection.slug,\n config,\n filename: originalDoc.sizes?.[adminThumbnail].filename as string,\n })\n }\n\n return null\n },\n ],\n },\n label: 'Thumbnail URL',\n }\n\n const width: Field = {\n name: 'width',\n type: 'number',\n admin: {\n hidden: true,\n readOnly: true,\n },\n label: ({ t }) => t('upload:width'),\n }\n\n const height: Field = {\n name: 'height',\n type: 'number',\n admin: {\n hidden: true,\n readOnly: true,\n },\n label: ({ t }) => t('upload:height'),\n }\n\n const filesize: Field = {\n name: 'filesize',\n type: 'number',\n admin: {\n hidden: true,\n readOnly: true,\n },\n label: ({ t }) => t('upload:fileSize'),\n }\n\n const filename: Field = {\n name: 'filename',\n type: 'text',\n admin: {\n disableBulkEdit: true,\n hidden: true,\n readOnly: true,\n },\n index: true,\n label: ({ t }) => t('upload:fileName'),\n unique: true,\n }\n\n const url: Field = {\n name: 'url',\n type: 'text',\n admin: {\n hidden: true,\n readOnly: true,\n },\n label: 'URL',\n }\n\n let uploadFields: Field[] = [\n {\n ...url,\n hooks: {\n afterRead: [\n ({ data, value }) => {\n if (value) return value\n\n return generateURL({\n collectionSlug: collection.slug,\n config,\n filename: data?.filename,\n })\n },\n ],\n },\n },\n thumbnailURL,\n filename,\n mimeType,\n filesize,\n width,\n height,\n ]\n\n // Add focal point fields if not disabled\n if (\n uploadOptions.focalPoint !== false ||\n uploadOptions.imageSizes ||\n uploadOptions.resizeOptions\n ) {\n uploadFields = uploadFields.concat(\n ['focalX', 'focalY'].map((name) => {\n return {\n name,\n type: 'number',\n admin: {\n hidden: true,\n },\n }\n }),\n )\n }\n\n if (uploadOptions.mimeTypes) {\n mimeType.validate = mimeTypeValidator(uploadOptions.mimeTypes)\n }\n\n if (uploadOptions.imageSizes) {\n uploadFields = uploadFields.concat([\n {\n name: 'sizes',\n type: 'group',\n admin: {\n hidden: true,\n },\n fields: uploadOptions.imageSizes.map((size) => ({\n name: size.name,\n type: 'group',\n admin: {\n hidden: true,\n },\n fields: [\n {\n ...url,\n hooks: {\n afterRead: [\n ({ data, value }) => {\n if (value) return value\n\n const sizeFilename = data?.sizes?.[size.name]?.filename\n\n if (sizeFilename) {\n return `${config.serverURL}${config.routes.api}/${collection.slug}/file/${sizeFilename}`\n }\n\n return null\n },\n ],\n },\n },\n width,\n height,\n mimeType,\n filesize,\n {\n ...filename,\n unique: false,\n },\n ],\n label: size.name,\n })),\n label: ({ t }) => t('upload:sizes'),\n },\n ])\n }\n return uploadFields\n}\n"],"names":["mimeTypeValidator","generateURL","collectionSlug","config","filename","serverURL","routes","api","undefined","getBaseUploadFields","collection","uploadOptions","upload","mimeType","name","type","admin","hidden","readOnly","label","thumbnailURL","hooks","afterRead","originalDoc","adminThumbnail","doc","sizes","slug","width","t","height","filesize","disableBulkEdit","index","unique","url","uploadFields","data","value","focalPoint","imageSizes","resizeOptions","concat","map","mimeTypes","validate","fields","size","sizeFilename"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
1
+ {"version":3,"sources":["../../src/uploads/getBaseFields.ts"],"sourcesContent":["import type { CollectionConfig } from '../collections/config/types.js'\nimport type { Config } from '../config/types.js'\nimport type { Field } from '../fields/config/types.js'\nimport type { UploadConfig } from './types.js'\n\nimport { mimeTypeValidator } from './mimeTypeValidator.js'\n\ntype GenerateURLArgs = {\n collectionSlug: string\n config: Config\n filename?: string\n}\nconst generateURL = ({ collectionSlug, config, filename }: GenerateURLArgs) => {\n if (filename) {\n return `${config.serverURL || ''}${config.routes.api || ''}/${collectionSlug}/file/${filename}`\n }\n return undefined\n}\n\ntype Options = {\n collection: CollectionConfig\n config: Config\n}\n\nexport const getBaseUploadFields = ({ collection, config }: Options): Field[] => {\n const uploadOptions: UploadConfig = typeof collection.upload === 'object' ? collection.upload : {}\n\n const mimeType: Field = {\n name: 'mimeType',\n type: 'text',\n admin: {\n hidden: true,\n readOnly: true,\n },\n label: 'MIME Type',\n }\n\n const thumbnailURL: Field = {\n name: 'thumbnailURL',\n type: 'text',\n admin: {\n hidden: true,\n readOnly: true,\n },\n hooks: {\n afterRead: [\n ({ originalDoc }) => {\n const adminThumbnail =\n typeof collection.upload !== 'boolean' ? collection.upload?.adminThumbnail : undefined\n\n if (typeof adminThumbnail === 'function') {\n return adminThumbnail({ doc: originalDoc })\n }\n\n if (\n typeof adminThumbnail === 'string' &&\n 'sizes' in originalDoc &&\n originalDoc.sizes?.[adminThumbnail]?.filename\n ) {\n return generateURL({\n collectionSlug: collection.slug,\n config,\n filename: originalDoc.sizes?.[adminThumbnail].filename as string,\n })\n }\n\n return null\n },\n ],\n },\n label: 'Thumbnail URL',\n }\n\n const width: Field = {\n name: 'width',\n type: 'number',\n admin: {\n hidden: true,\n readOnly: true,\n },\n label: ({ t }) => t('upload:width'),\n }\n\n const height: Field = {\n name: 'height',\n type: 'number',\n admin: {\n hidden: true,\n readOnly: true,\n },\n label: ({ t }) => t('upload:height'),\n }\n\n const filesize: Field = {\n name: 'filesize',\n type: 'number',\n admin: {\n hidden: true,\n readOnly: true,\n },\n label: ({ t }) => t('upload:fileSize'),\n }\n\n const filename: Field = {\n name: 'filename',\n type: 'text',\n admin: {\n disableBulkEdit: true,\n hidden: true,\n readOnly: true,\n },\n index: true,\n label: ({ t }) => t('upload:fileName'),\n unique: true,\n }\n\n const url: Field = {\n name: 'url',\n type: 'text',\n admin: {\n hidden: true,\n readOnly: true,\n },\n label: 'URL',\n }\n\n let uploadFields: Field[] = [\n {\n ...url,\n hooks: {\n afterRead: [\n ({ data, value }) => {\n if (value) return value\n\n return generateURL({\n collectionSlug: collection.slug,\n config,\n filename: data?.filename,\n })\n },\n ],\n },\n },\n thumbnailURL,\n filename,\n mimeType,\n filesize,\n width,\n height,\n ]\n\n // Add focal point fields if not disabled\n if (\n uploadOptions.focalPoint !== false ||\n uploadOptions.imageSizes ||\n uploadOptions.resizeOptions\n ) {\n uploadFields = uploadFields.concat(\n ['focalX', 'focalY'].map((name) => {\n return {\n name,\n type: 'number',\n admin: {\n hidden: true,\n },\n }\n }),\n )\n }\n\n if (uploadOptions.mimeTypes) {\n mimeType.validate = mimeTypeValidator(uploadOptions.mimeTypes)\n }\n\n if (uploadOptions.imageSizes) {\n uploadFields = uploadFields.concat([\n {\n name: 'sizes',\n type: 'group',\n admin: {\n hidden: true,\n },\n fields: uploadOptions.imageSizes.map((size) => ({\n name: size.name,\n type: 'group',\n admin: {\n hidden: true,\n },\n fields: [\n {\n ...url,\n hooks: {\n afterRead: [\n ({ data, value }) => {\n if (value && size.height && size.width) return value\n\n const sizeFilename = data?.sizes?.[size.name]?.filename\n\n if (sizeFilename) {\n return `${config.serverURL}${config.routes.api}/${collection.slug}/file/${sizeFilename}`\n }\n\n return null\n },\n ],\n },\n },\n width,\n height,\n mimeType,\n filesize,\n {\n ...filename,\n unique: false,\n },\n ],\n label: size.name,\n })),\n label: ({ t }) => t('upload:sizes'),\n },\n ])\n }\n return uploadFields\n}\n"],"names":["mimeTypeValidator","generateURL","collectionSlug","config","filename","serverURL","routes","api","undefined","getBaseUploadFields","collection","uploadOptions","upload","mimeType","name","type","admin","hidden","readOnly","label","thumbnailURL","hooks","afterRead","originalDoc","adminThumbnail","doc","sizes","slug","width","t","height","filesize","disableBulkEdit","index","unique","url","uploadFields","data","value","focalPoint","imageSizes","resizeOptions","concat","map","mimeTypes","validate","fields","size","sizeFilename"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
@@ -1 +1 @@
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
+ {"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,CAmKxC"}
@@ -161,13 +161,13 @@ import fileExists from './fileExists.js';
161
161
  return defaultResult;
162
162
  }
163
163
  // Determine if the file is animated
164
- const fileIsAnimated = [
164
+ const fileIsAnimatedType = [
165
165
  'image/avif',
166
166
  'image/gif',
167
167
  'image/webp'
168
168
  ].includes(file.mimetype);
169
169
  const sharpOptions = {};
170
- if (fileIsAnimated) sharpOptions.animated = true;
170
+ if (fileIsAnimatedType) sharpOptions.animated = true;
171
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
172
172
  ;
173
173
  const results = await Promise.all(imageSizes.map(async (imageResizeConfig)=>{
@@ -184,14 +184,20 @@ import fileExists from './fileExists.js';
184
184
  let resized = imageToResize;
185
185
  const metadata = await sharpBase.metadata();
186
186
  if (incomingFocalPoint && applyPayloadAdjustments(imageResizeConfig, dimensions)) {
187
- const { height: resizeHeight, width: resizeWidth } = imageResizeConfig;
188
- const resizeAspectRatio = resizeWidth / resizeHeight;
187
+ let { height: resizeHeight, width: resizeWidth } = imageResizeConfig;
189
188
  const originalAspectRatio = dimensions.width / dimensions.height;
190
- const prioritizeHeight = resizeAspectRatio < originalAspectRatio;
189
+ // Calculate resizeWidth based on original aspect ratio if it's undefined
190
+ if (resizeHeight && !resizeWidth) {
191
+ resizeWidth = Math.round(resizeHeight * originalAspectRatio);
192
+ }
193
+ // Calculate resizeHeight based on original aspect ratio if it's undefined
194
+ if (resizeWidth && !resizeHeight) {
195
+ resizeHeight = Math.round(resizeWidth / originalAspectRatio);
196
+ }
191
197
  // Scale the image up or down to fit the resize dimensions
192
198
  const scaledImage = imageToResize.resize({
193
- height: prioritizeHeight ? resizeHeight : null,
194
- width: prioritizeHeight ? null : resizeWidth
199
+ height: resizeHeight,
200
+ width: resizeWidth
195
201
  });
196
202
  const { info: scaledImageInfo } = await scaledImage.toBuffer({
197
203
  resolveWithObject: true
@@ -200,12 +206,16 @@ import fileExists from './fileExists.js';
200
206
  const maxOffsetX = scaledImageInfo.width - safeResizeWidth;
201
207
  const leftFocalEdge = Math.round(scaledImageInfo.width * (incomingFocalPoint.x / 100) - safeResizeWidth / 2);
202
208
  const safeOffsetX = Math.min(Math.max(0, leftFocalEdge), maxOffsetX);
203
- const safeResizeHeight = resizeHeight ?? scaledImageInfo.height;
204
- const maxOffsetY = fileIsAnimated ? resizeHeight - safeResizeHeight : scaledImageInfo.height - safeResizeHeight;
209
+ const isAnimated = fileIsAnimatedType && metadata.pages;
210
+ let safeResizeHeight = resizeHeight ?? scaledImageInfo.height;
211
+ if (isAnimated && resizeHeight === undefined) {
212
+ safeResizeHeight = scaledImageInfo.height / metadata.pages;
213
+ }
214
+ const maxOffsetY = isAnimated ? safeResizeHeight - (resizeHeight ?? safeResizeHeight) : scaledImageInfo.height - safeResizeHeight;
205
215
  const topFocalEdge = Math.round(scaledImageInfo.height * (incomingFocalPoint.y / 100) - safeResizeHeight / 2);
206
216
  const safeOffsetY = Math.min(Math.max(0, topFocalEdge), maxOffsetY);
207
217
  // extract the focal area from the scaled image
208
- resized = (fileIsAnimated ? imageToResize : scaledImage).extract({
218
+ resized = (fileIsAnimatedType ? imageToResize : scaledImage).extract({
209
219
  height: safeResizeHeight,
210
220
  left: safeOffsetX,
211
221
  top: safeOffsetY,
@@ -242,7 +252,7 @@ import fileExists from './fileExists.js';
242
252
  name: imageResizeConfig.name,
243
253
  filename: imageNameWithDimensions,
244
254
  filesize: size,
245
- height: fileIsAnimated && metadata.pages ? height / metadata.pages : height,
255
+ height: fileIsAnimatedType && metadata.pages ? height / metadata.pages : height,
246
256
  mimeType: mimeInfo?.mime || mimeType,
247
257
  sizesToSave: [
248
258
  {
@@ -1 +1 @@
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 && metadata.pages ? 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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"}
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 fileIsAnimatedType = ['image/avif', 'image/gif', 'image/webp'].includes(file.mimetype)\n const sharpOptions: SharpOptions = {}\n\n if (fileIsAnimatedType) 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 let { height: resizeHeight, width: resizeWidth } = imageResizeConfig\n\n const originalAspectRatio = dimensions.width / dimensions.height\n\n // Calculate resizeWidth based on original aspect ratio if it's undefined\n if (resizeHeight && !resizeWidth) {\n resizeWidth = Math.round(resizeHeight * originalAspectRatio)\n }\n\n // Calculate resizeHeight based on original aspect ratio if it's undefined\n if (resizeWidth && !resizeHeight) {\n resizeHeight = Math.round(resizeWidth / originalAspectRatio)\n }\n\n // Scale the image up or down to fit the resize dimensions\n const scaledImage = imageToResize.resize({\n height: resizeHeight,\n width: resizeWidth,\n })\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 isAnimated = fileIsAnimatedType && metadata.pages\n\n let safeResizeHeight = resizeHeight ?? scaledImageInfo.height\n\n if (isAnimated && resizeHeight === undefined) {\n safeResizeHeight = scaledImageInfo.height / metadata.pages\n }\n\n const maxOffsetY = isAnimated\n ? safeResizeHeight - (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 = (fileIsAnimatedType ? 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: fileIsAnimatedType && metadata.pages ? 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","fileIsAnimatedType","includes","mimetype","sharpOptions","animated","sharpBase","tempFilePath","data","rotate","results","Promise","all","map","imageResizeConfig","imageToResize","clone","resized","metadata","resizeHeight","resizeWidth","scaledImage","resize","info","scaledImageInfo","toBuffer","resolveWithObject","safeResizeWidth","maxOffsetX","leftFocalEdge","safeOffsetX","min","max","isAnimated","pages","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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "payload",
3
- "version": "3.0.0-beta.46",
3
+ "version": "3.0.0-beta.48",
4
4
  "description": "Node, React, Headless CMS and Application Framework built on Next.js",
5
5
  "keywords": [
6
6
  "admin panel",
@@ -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.46"
97
+ "@payloadcms/translations": "3.0.0-beta.48"
98
98
  },
99
99
  "devDependencies": {
100
100
  "@monaco-editor/react": "4.5.1",