Conversation
Contributor
📦 esbuild Bundle Analysis for payloadThis analysis was generated by esbuild-bundle-analyzer. 🤖
Largest pathsThese visualization shows top 20 largest paths in the bundle.Meta file: packages/next/meta_index.json, Out file: esbuild/index.js
Meta file: packages/payload/meta_index.json, Out file: esbuild/index.js
Meta file: packages/payload/meta_shared.json, Out file: esbuild/exports/shared.js
Meta file: packages/richtext-lexical/meta_client.json, Out file: esbuild/exports/client_optimized/index.js
Meta file: packages/ui/meta_client.json, Out file: esbuild/exports/client_optimized/index.js
Meta file: packages/ui/meta_shared.json, Out file: esbuild/exports/shared_optimized/index.js
DetailsNext to the size is how much the size has increased or decreased compared with the base branch of this PR.
|
paulpopus
marked this pull request as ready for review
August 20, 2026 18:53
paulpopus
requested review from
AlessioGr,
DanRibbens,
JarrodMFlesch,
denolfe and
jacobsfletch
as code owners
August 20, 2026 18:53
paulpopus
marked this pull request as draft
September 21, 2026 17:06
Resolves 37 conflicts between the file-transformer refactor and 141 commits of upload work on main. Notable semantic resolutions: - `generateFileData` keeps the transformer pipeline from this branch and main's large-client-upload handling. A transformer only runs when the full bytes are available (`hasFullFileContents`); otherwise the temp file is copied straight to its destination or skipped, never buffered. Dimension probing is likewise gated to image types, since probing reads the file. Main's filename-ownership, upload-reference, detected-mime, and external-upload-source fixes are preserved. - `cropImage`/`image-resizing` stay deleted; main's only change to them (the corrected animated-image mime list) already lives in core's `isAnimatedImage`. - `canResizeImage` is restored in core, which still needs it for `isProcessableImage` and `getFileContentRequirement`. - `getFileContentRequirement` now reads `upload.hasImageAdjustments` - the transformer-agnostic projection `sharpTransformer` writes back - instead of the removed per-collection Sharp options. - Storage adapters keep this branch's `operation: 'transform'` handler and main's `doc`-based prefix resolution (dropping the client-supplied `prefix` query param) and XML content-security-policy handling. Their specs move from the renamed `getFileKey` to `buildStoragePathData`. - Template `package.json` files keep main's dependency bumps and only drop `sharp` in favour of `@payloadcms/transformer-sharp`, so the lockfile differs from main solely by that new workspace package. - Test suites and fixtures added on either side are migrated to the other's conventions: `upload-transformers` and the shared animated-resize/transformer-contract helpers move to the `test.suite` fixture, and the `media-header-only-with-sizes` client-upload fixtures declare their `imageSizes` through `sharpTransformer`.
paulpopus
marked this pull request as ready for review
September 23, 2026 12:17
# Conflicts: # packages/codemod/README.md
…ingle-dimension resize
resolveUploadDocument looks up the filename without access filtering, and filenames are only unique per prefix. Without a ?prefix it could match another tenant's document, which was then passed as `doc` to storage handlers — they trust `doc` for the object key, so the other tenant's file was served. Use the document checkFileAccess authorized instead, re-planning the pipeline from its mimeType and re-checking transform access when needed.
Removes unit specs that mocked Payload internals or storage SDKs and only asserted mock calls, for behaviour already exercised by the upload-transformers, uploads, and storage int suites. - storage: mocked s3/gcs/azure getFile specs replaced by a shared runTransformReadsRealSourceTest run against real emulators; r2/vercel-blob keep only adapter-specific cases - upload-transformers: drop the kitchen-sink sharp transformer, ResizePreview playground UI + e2e spec, and fixture binaries duplicated from test/uploads; add int tests for the transformer contract error, Range being ignored for transform sources, and resized response headers - unit specs trimmed to pure functions, config validation, and cases int tests can't reach - drop the tautological transformer contract shape test (validateTransformers already runs on boot) - restore the third-party RegisteredImageSizeOptions type test
Member
|
Pushed 6cc0c01 to trim the tests. The PR diff goes from +12,679 / −2,067 across 197 files to +8,383 / −2,054 across 182 files.
All the touched suites pass locally. |
# Conflicts: # test/uploads/payload-types.ts
# Conflicts: # test/benchmark-blocks/config.ts
This was referenced Sep 30, 2026
paulpopus
commented
Sep 30, 2026
…ough integration tests Replaces mocked handleDynamicFileRequest, getFileFromUploadInstructions and generateFileData unit tests with real Payload and Azure handler coverage, and drops two duplicate upload-transformers tests.
…r int tests Moves the Media and storage Sharp options into shared test helpers, inlines the single-use animated resize helpers, switches upload-transformers to per-test resets, and drops an int test duplicated by existing coverage.
# Conflicts: # test/a11y/collections/Media/index.ts
paulpopus
commented
Oct 2, 2026
| }).toPass({ intervals: [1000], timeout: 15000 }) | ||
| } | ||
|
|
||
| test.describe('Resize preview component', () => { |
Member
Author
There was a problem hiding this comment.
Register this suite in .github/workflows/e2e.config.ts. CI currently creates no Next or TanStack job for these tests. Add { file: 'upload-transformers', shards: 1 } and run both jobs.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
Part 1 of 3 in a stacked PR. This PR holds the tests, fixtures, test configuration and generated test types; the description below covers the whole stack.
@payloadcms/transformer-sharp, its README, workspace registration and lockfileCI is only expected to pass at the top of the stack (#18411).
Summary
Payload core assumed every upload was an image, and processed it only with Sharp. It could only serve image sizes generated in advance, at upload time. This PR replaces that assumption with a generic transformer pipeline configured under
upload.transformers. A transformer can process a file at upload time, serve a dynamically transformed variant at request time, or both.@payloadcms/transformer-sharpis the new official transformer. It reproduces the existing Sharp upload behavior and adds opt-in dynamic width and height resizing to Payload's existing access-controlled file endpoint.Why
Payload could not transform a file when a client requested it. Applications had to pre-generate every image size they might need. Payload also had no extension point for video, documents, or external processing services, because Sharp support was built directly into core. This design moves file processing out of core, so any transformer can use the same upload and request lifecycle.
How
canTransformcheck. Each stage returnscontinueorcomplete, and a thrown error aborts the pipeline and the surrounding operation.readaccess control before Payload retrieves the source file or calls a transformer. Payload setsreq.fileTransformtotrueonly whileaccess.readdecides a transform request, so a collection can allow ordinary reads while restricting transformed variants. No transformer code, includingcanTransform, runs until an access check has passed.transformfile-handler operation, so they can return a readable body to a transformer even when their normal public response redirects to a signed URL.@payloadcms/transformer-sharpowns all Sharp-specific collection configuration, including image sizes, which are now authored asvariantson the transformer instead ofimageSizeson the collection. It writes a Sharp-agnostic projection ofvariants(asupload.imageSizes),crop, andfocalPointback onto the sanitized collection config, so the Admin Panel, generated types, and the existingsizesdocument shape stay unchanged.generatePayloadFileURLhelper always builds the access-controlled Payload file endpoint. Applications and plugins can link to a file, including transformer query parameters, without accidentally bypassing access control.Breaking changes
sharpconfig property is removed. RegistersharpTransformer()from@payloadcms/transformer-sharpunderupload.transformersinstead.constructorOptions,formatOptions,resizeOptions,trimOptions, andwithMetadataare removed fromCollectionConfig['upload']. Configure them throughsharpTransformer({ collections }).imageSizesis removed fromCollectionConfig['upload']. Image sizes are now declared asvariantsonsharpTransformer({ collections: { <slug>: { variants } } }); the entries themselves are unchanged. A collection that still setsupload.imageSizesfails the build. The resolved sizes remain readable on the sanitized config atcollection.upload.imageSizes.sharpis no longer a dependency ofpayload. Install@payloadcms/transformer-sharpexplicitly.SharpDependency,ImageUploadFormatOptions,ImageUploadTrimOptions, andSharpImageSizeOptionsare no longer exported frompayload.SharpDependencyis now exported from@payloadcms/transformer-sharp.Before:
After:
Run
npx @payloadcms/codemod --transform migrate-sharp-to-transformerto migrate mechanically analyzable configuration automatically. It moves collectionimageSizesintosharpTransformerasvariants, and renamesimageSizestovariantsin configs that already usesharpTransformer. Configuration the codemod cannot rewrite safely, such as acollectionsarray built by a function call, is flagged for manual review. See the v4 migration guide for full details.Opt-in dynamic resizing
Dynamic resizing is disabled by default, so a migrated config keeps serving only the original file and its pre-generated
variants. Enable it per collection, and restrict transformed reads withreq.fileTransforminaccess.read:GET /api/media/file/photo.png?width=640then returns a resized image for a signed-in user, and403for anyone else, without fetching the source file.