{"_id":"@assemblyltd/payload-chunked-upload","_rev":"5-3580214dc555f33a735df0c5937ad0d4","name":"@assemblyltd/payload-chunked-upload","dist-tags":{"latest":"0.1.4"},"versions":{"0.1.0":{"name":"@assemblyltd/payload-chunked-upload","version":"0.1.0","keywords":["payload","payloadcms","plugin","upload","chunked","tus","cloudflare"],"license":"MIT","_id":"@assemblyltd/payload-chunked-upload@0.1.0","maintainers":[{"name":"assemblyltd","email":"info@assembly.com.hk"}],"dist":{"shasum":"a896433ea37ccd890621a5fc08385fb176c9c23f","tarball":"https://registry.npmjs.org/@assemblyltd/payload-chunked-upload/-/payload-chunked-upload-0.1.0.tgz","fileCount":22,"integrity":"sha512-8IGrRyNMf94c3h6IqEJhw5dSxze2g5HLrYvA31vmhzDoH7PGfXfdGZzoDQJ6j630YjJmAOTLcrfwYFUp+veQJg==","signatures":[{"sig":"MEUCIFExcMNwjU1sEprzJr8/tu/HZj3/I3rfmeTnfwiDN42FAiEA/B7UHyF7dgfTQB56F43EEV7a32hmQRoqGL8dk95M+3k=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":52904},"main":"./dist/index.js","type":"module","_from":"file:assemblyltd-payload-chunked-upload-0.1.0.tgz","types":"./dist/index.d.ts","engines":{"node":">=18.17.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./client":{"types":"./dist/client/ChunkedUploadProvider.d.ts","import":"./dist/client/ChunkedUploadProvider.js"}},"scripts":{"dev":"tsc --watch","build":"tsc","clean":"rm -rf dist"},"_npmUser":{"name":"assemblyltd","email":"info@assembly.com.hk"},"_resolved":"/private/var/folders/hk/bph6ytd56_9dv61npzpfr4v00000gn/T/f6d384c82b5621335fe4018e2571fc58/assemblyltd-payload-chunked-upload-0.1.0.tgz","_integrity":"sha512-8IGrRyNMf94c3h6IqEJhw5dSxze2g5HLrYvA31vmhzDoH7PGfXfdGZzoDQJ6j630YjJmAOTLcrfwYFUp+veQJg==","_npmVersion":"11.6.2","description":"Payload CMS plugin that splits large file uploads into chunks on the client and reassembles them server-side. Bypasses Cloudflare's 100 MB per-request body limit.","directories":{},"_nodeVersion":"25.2.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"next":"15.3.0","react":"19.1.0","sonner":"1.7.4","payload":"3.84.1","typescript":"5.7.3","@types/node":"22.5.4","@types/react":"19.1.0","@payloadcms/ui":"3.84.1"},"peerDependencies":{"next":"^15.0.0","react":"^18.0.0 || ^19.0.0","sonner":"^1.0.0 || ^2.0.0","payload":"^3.0.0","@payloadcms/ui":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/payload-chunked-upload_0.1.0_1780444018584_0.8740519784861549","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@assemblyltd/payload-chunked-upload","version":"0.1.1","keywords":["payload","payloadcms","plugin","upload","chunked","tus","cloudflare"],"license":"MIT","_id":"@assemblyltd/payload-chunked-upload@0.1.1","maintainers":[{"name":"assemblyltd","email":"info@assembly.com.hk"}],"dist":{"shasum":"4ea7b34473f8ef9f87aea2ff46e996bfcaef4e86","tarball":"https://registry.npmjs.org/@assemblyltd/payload-chunked-upload/-/payload-chunked-upload-0.1.1.tgz","fileCount":22,"integrity":"sha512-OFaVv0EDCEWvol18ePy1/T/XIMSqmX13LOPLZDoNcKFEQbtlA3J0EQ69tziT/mid6Py+/5mYb5vskbUZgZOtuA==","signatures":[{"sig":"MEYCIQDSFH5R0JxnZUK2LXTxCvLfHecxhBvB5k5an1hCFBvPpgIhAKPEbXKnX5KfCkH/aVCWJii4unC1nYY1ZgU+FDitx4sl","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":53002},"main":"./dist/index.js","type":"module","_from":"file:assemblyltd-payload-chunked-upload-0.1.1.tgz","types":"./dist/index.d.ts","engines":{"node":">=18.17.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./client":{"types":"./dist/client/ChunkedUploadProvider.d.ts","import":"./dist/client/ChunkedUploadProvider.js"}},"scripts":{"dev":"tsc --watch","build":"tsc","clean":"rm -rf dist"},"_npmUser":{"name":"assemblyltd","email":"info@assembly.com.hk"},"_resolved":"/private/var/folders/hk/bph6ytd56_9dv61npzpfr4v00000gn/T/a54f13f3b55208af06c02c1b94576545/assemblyltd-payload-chunked-upload-0.1.1.tgz","_integrity":"sha512-OFaVv0EDCEWvol18ePy1/T/XIMSqmX13LOPLZDoNcKFEQbtlA3J0EQ69tziT/mid6Py+/5mYb5vskbUZgZOtuA==","_npmVersion":"11.6.2","description":"Payload CMS plugin that splits large file uploads into chunks on the client and reassembles them server-side. Bypasses Cloudflare's 100 MB per-request body limit.","directories":{},"_nodeVersion":"25.2.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"next":"15.3.0","react":"19.1.0","sonner":"1.7.4","payload":"3.84.1","typescript":"5.7.3","@types/node":"22.5.4","@types/react":"19.1.0","@payloadcms/ui":"3.84.1"},"peerDependencies":{"next":"^15.0.0","react":"^18.0.0 || ^19.0.0","sonner":"^1.0.0 || ^2.0.0","payload":"^3.0.0","@payloadcms/ui":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/payload-chunked-upload_0.1.1_1780448224749_0.22505206075896478","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@assemblyltd/payload-chunked-upload","version":"0.1.2","keywords":["payload","payloadcms","plugin","upload","chunked","tus","cloudflare"],"license":"MIT","_id":"@assemblyltd/payload-chunked-upload@0.1.2","maintainers":[{"name":"assemblyltd","email":"info@assembly.com.hk"}],"dist":{"shasum":"6507215ecd530e43c027dabcd1c0d09e6df57e99","tarball":"https://registry.npmjs.org/@assemblyltd/payload-chunked-upload/-/payload-chunked-upload-0.1.2.tgz","fileCount":22,"integrity":"sha512-4fLU/RjG6xGH+mRhdFGrX4tVqdq4tsIdyH9N1HSV0LFvRLqM/S2Z0uSFcIl0kYRiS0BQLmDyAJLhDi31b7pjMA==","signatures":[{"sig":"MEQCIEULCnnNmgc+NXErUChBmOOLtek8SDDBzwr27uCWi9utAiAcgx8R1hAhqxjuGcQ8G7BXnva4Cu5kelyYGmGZ3Ui2KQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":57236},"main":"./dist/index.js","type":"module","_from":"file:assemblyltd-payload-chunked-upload-0.1.2.tgz","types":"./dist/index.d.ts","engines":{"node":">=18.17.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./client":{"types":"./dist/client/ChunkedUploadProvider.d.ts","import":"./dist/client/ChunkedUploadProvider.js"}},"scripts":{"dev":"tsc --watch","build":"tsc","clean":"rm -rf dist"},"_npmUser":{"name":"assemblyltd","email":"info@assembly.com.hk"},"_resolved":"/private/var/folders/hk/bph6ytd56_9dv61npzpfr4v00000gn/T/652ac5d2b07ab89e5b3f4ba9ab9d327d/assemblyltd-payload-chunked-upload-0.1.2.tgz","_integrity":"sha512-4fLU/RjG6xGH+mRhdFGrX4tVqdq4tsIdyH9N1HSV0LFvRLqM/S2Z0uSFcIl0kYRiS0BQLmDyAJLhDi31b7pjMA==","_npmVersion":"11.6.2","description":"Payload CMS plugin that splits large file uploads into chunks on the client and reassembles them server-side. Bypasses Cloudflare's 100 MB per-request body limit.","directories":{},"_nodeVersion":"25.2.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"next":"15.3.0","react":"19.1.0","sonner":"1.7.4","payload":"3.84.1","typescript":"5.7.3","@types/node":"22.5.4","@types/react":"19.1.0","@payloadcms/ui":"3.84.1"},"peerDependencies":{"next":"^15.0.0","react":"^18.0.0 || ^19.0.0","sonner":"^1.0.0 || ^2.0.0","payload":"^3.0.0","@payloadcms/ui":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/payload-chunked-upload_0.1.2_1780449780587_0.02291354404088275","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@assemblyltd/payload-chunked-upload","version":"0.1.3","keywords":["payload","payloadcms","plugin","upload","chunked","tus","cloudflare"],"license":"MIT","_id":"@assemblyltd/payload-chunked-upload@0.1.3","maintainers":[{"name":"assemblyltd","email":"info@assembly.com.hk"}],"dist":{"shasum":"9ba2f202e949f05e30a9ba0a812400b6fb65f5ce","tarball":"https://registry.npmjs.org/@assemblyltd/payload-chunked-upload/-/payload-chunked-upload-0.1.3.tgz","fileCount":22,"integrity":"sha512-SdlmHN75Vx+fLsDf5+rm7oKtkuH4Tmj3ypxHX218vzmtE551mJa8Gmfgk0LhqPhY8snGkentsRPL99Se0rXe1g==","signatures":[{"sig":"MEQCIGslKVg1WwsCbYVsgZa5Y4reHGgfKSeFAgHcMQfo9lZVAiA6WxvZ9GWtBGrdRbdgXxBZ8m/qxC3fBkxWMqTZ4+7iXQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":58052},"main":"./dist/index.js","type":"module","_from":"file:assemblyltd-payload-chunked-upload-0.1.3.tgz","types":"./dist/index.d.ts","engines":{"node":">=18.17.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./client":{"types":"./dist/client/ChunkedUploadProvider.d.ts","import":"./dist/client/ChunkedUploadProvider.js"}},"scripts":{"dev":"tsc --watch","build":"tsc","clean":"rm -rf dist"},"_npmUser":{"name":"assemblyltd","email":"info@assembly.com.hk"},"_resolved":"/private/var/folders/hk/bph6ytd56_9dv61npzpfr4v00000gn/T/1215c1c70fac15c065c24002c5a60e3b/assemblyltd-payload-chunked-upload-0.1.3.tgz","_integrity":"sha512-SdlmHN75Vx+fLsDf5+rm7oKtkuH4Tmj3ypxHX218vzmtE551mJa8Gmfgk0LhqPhY8snGkentsRPL99Se0rXe1g==","_npmVersion":"11.6.2","description":"Payload CMS plugin that splits large file uploads into chunks on the client and reassembles them server-side. Bypasses Cloudflare's 100 MB per-request body limit.","directories":{},"_nodeVersion":"25.2.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"next":"15.3.0","react":"19.1.0","sonner":"1.7.4","payload":"3.84.1","typescript":"5.7.3","@types/node":"22.5.4","@types/react":"19.1.0","@payloadcms/ui":"3.84.1"},"peerDependencies":{"next":"^15.0.0 || ^16.0.0","react":"^18.0.0 || ^19.0.0","sonner":"^1.0.0 || ^2.0.0","payload":"^3.0.0","@payloadcms/ui":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/payload-chunked-upload_0.1.3_1780454338547_0.6476787230512027","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"name":"@assemblyltd/payload-chunked-upload","version":"0.1.4","description":"Payload CMS plugin that splits large file uploads into chunks on the client and reassembles them server-side. Bypasses Cloudflare's 100 MB per-request body limit.","license":"MIT","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./client":{"types":"./dist/client/ChunkedUploadProvider.d.ts","import":"./dist/client/ChunkedUploadProvider.js"},"./client/progress":{"types":"./dist/client/ChunkedUploadProgress.d.ts","import":"./dist/client/ChunkedUploadProgress.js"}},"keywords":["payload","payloadcms","plugin","upload","chunked","tus","cloudflare"],"peerDependencies":{"@payloadcms/ui":"^3.0.0","next":"^15.0.0 || ^16.0.0","payload":"^3.0.0","react":"^18.0.0 || ^19.0.0","sonner":"^1.0.0 || ^2.0.0"},"devDependencies":{"@payloadcms/ui":"3.84.1","@types/node":"22.5.4","@types/react":"19.1.0","next":"15.3.0","payload":"3.84.1","react":"19.1.0","sonner":"1.7.4","typescript":"5.7.3"},"publishConfig":{"access":"public"},"engines":{"node":">=18.17.0"},"scripts":{"build":"tsc","dev":"tsc --watch","clean":"rm -rf dist"},"_id":"@assemblyltd/payload-chunked-upload@0.1.4","_integrity":"sha512-p/V0NCOD/uszBWnm6d4/SndwSyMQzJ1sSzvVG1cHQ7QjUoeu1ULf+FDx8JbjGcbKGFjQizbi9ixR5zgTCHeg+Q==","_resolved":"/private/var/folders/hk/bph6ytd56_9dv61npzpfr4v00000gn/T/88466dd400a4e0d2bae950e739ec65ef/assemblyltd-payload-chunked-upload-0.1.4.tgz","_from":"file:assemblyltd-payload-chunked-upload-0.1.4.tgz","_nodeVersion":"25.2.1","_npmVersion":"11.6.2","dist":{"integrity":"sha512-p/V0NCOD/uszBWnm6d4/SndwSyMQzJ1sSzvVG1cHQ7QjUoeu1ULf+FDx8JbjGcbKGFjQizbi9ixR5zgTCHeg+Q==","shasum":"0bd244a58e27ca31bb000020aad8fa5e1df24c07","tarball":"https://registry.npmjs.org/@assemblyltd/payload-chunked-upload/-/payload-chunked-upload-0.1.4.tgz","fileCount":30,"unpackedSize":80611,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIH8DTCEINzquj/l3bBxu+/0T9Gt5SPWeFe+VBIpSb43TAiAMZhDd3CwnVqMepvBBE6ehO9Hr39T/e4jN5Usu9JfCpA=="}]},"_npmUser":{"name":"assemblyltd","email":"info@assembly.com.hk"},"directories":{},"maintainers":[{"name":"assemblyltd","email":"info@assembly.com.hk"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/payload-chunked-upload_0.1.4_1780467523388_0.22338341461080513"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-02T23:46:58.340Z","modified":"2026-06-03T06:18:43.656Z","0.1.0":"2026-06-02T23:46:58.810Z","0.1.1":"2026-06-03T00:57:04.891Z","0.1.2":"2026-06-03T01:23:00.749Z","0.1.3":"2026-06-03T02:38:58.686Z","0.1.4":"2026-06-03T06:18:43.552Z"},"license":"MIT","keywords":["payload","payloadcms","plugin","upload","chunked","tus","cloudflare"],"description":"Payload CMS plugin that splits large file uploads into chunks on the client and reassembles them server-side. Bypasses Cloudflare's 100 MB per-request body limit.","maintainers":[{"name":"assemblyltd","email":"info@assembly.com.hk"}],"readme":"# @assemblyltd/payload-chunked-upload\n\nPayload CMS 3.x plugin that splits large file uploads into chunks on the client and reassembles them server-side. Bypasses Cloudflare's 100 MB per-request body limit.\n\n## Why\n\nCloudflare's free / Pro plans cap a single HTTP request body at **100 MB**. Direct uploads of large files (sales brochures, hi-res images, mp4s) through a Payload admin sitting behind Cloudflare get rejected at the edge before the request reaches the origin.\n\nThis plugin makes the editor's file picker split files into ≤25 MB chunks, POST each separately (each one well below the cap), and reassemble them server-side before handing the buffer to Payload's normal upload pipeline (Sharp resize, `imageSizes`, write to `staticDir`, all hooks).\n\n## Install\n\n```sh\npnpm add @assemblyltd/payload-chunked-upload\n```\n\n## Usage\n\n```ts\nimport { buildConfig } from 'payload'\nimport { chunkedUploadPlugin } from '@assemblyltd/payload-chunked-upload'\n\nexport default buildConfig({\n  collections: [Media /* must have type: 'upload' */],\n  plugins: [\n    chunkedUploadPlugin({\n      collections: ['media'],\n    }),\n  ],\n})\n```\n\nThat's it. The plugin:\n\n1. Registers a client React provider via `admin.components.providers` that calls `setUploadHandler` for each listed collection\n2. Adds a root `endpoints` entry at `/api/uploads/chunk` (auth-gated, streams chunk bodies to disk)\n3. Injects an `upload.handlers` entry into each listed collection that reads the form envelope's `clientUploadContext`, reassembles chunks from disk, and returns the buffer for Payload's pipeline\n4. Injects an inline progress bar into each listed collection's `admin.components.edit.beforeDocumentControls` slot — editors see live percentage / chunk count / MB-uploaded right above the Save button, not in a corner toast (`0.1.4+`)\n5. Schedules a background cleanup loop in `onInit` to sweep abandoned chunk sessions\n\nAfter installing or upgrading, regenerate the host's import map so Payload can resolve the plugin's admin components:\n\n```sh\npnpm payload generate:importmap\n```\n\n## Options\n\n| option | type | default | description |\n|--------|------|---------|-------------|\n| `collections` | `string[]` | — (required) | Upload-enabled collection slugs to attach the chunked handler to |\n| `chunkSizeBytes` | `number` | `25 MiB` | Per-chunk size. Keep below the smallest body limit you traverse (Cloudflare free/Pro: 100 MB) |\n| `maxChunks` | `number` | `400` | Per-session chunk cap. With defaults, caps total file size at ~10 GiB |\n| `endpointPath` | `string` | `'/uploads/chunk'` | Mounted under Payload's `/api/` prefix |\n| `tempDir` | `string` | `os.tmpdir() + '/payload-chunks'` | Where chunks are staged between client upload and server-side reassembly |\n| `cleanupIntervalMs` | `number \\| false` | `30 min` | Background cleanup interval. `false` to disable |\n| `sessionTtlMs` | `number` | `60 min` | Sessions older than this get swept by the cleanup loop |\n| `progressBar` | `boolean` | `true` | Inject the inline progress bar above the Save button. Set to `false` to keep only the success / error toast (e.g., if you ship your own progress UI) |\n\n## How it works\n\n1. Editor picks a file in the admin\n2. The plugin's client provider has registered a handler with Payload's `useUploadHandlers().setUploadHandler({ collectionSlug, handler })`\n3. Payload's `<Form>` sees the registered handler and calls it BEFORE submitting\n4. The handler slices the `File` into chunks and POSTs each to `/api/uploads/chunk` with `X-Upload-{Session,Index,Total,Filename,Mimetype}` headers\n5. The plugin's endpoint streams each chunk body to `<tempDir>/<session>/<index>.bin` (no full-chunk buffering in memory)\n6. After the final chunk lands, the handler returns `{ sessionId, total, mimetype }` as the `clientUploadContext`\n7. Payload's `<Form>` submits a tiny JSON envelope (no file bytes) to the collection's create endpoint\n8. Payload's `addDataAndFileToRequest` sees the envelope and invokes the collection's `upload.handlers[]`\n9. The plugin's collection handler reassembles the chunks into a Buffer and returns it as a `Response`\n10. Payload feeds `req.file.data` from that Response and runs the rest of the upload pipeline unchanged\n\nChunks are sequential. Each chunk is retried up to 3 times with exponential backoff (250ms, 500ms) on network errors and 5xx. 4xx errors are permanent and surface immediately.\n\n## Caveats\n\n- **Next.js 16+ middleware silently truncates request bodies at 10 MB.** If the host app has any `middleware.ts` whose matcher covers `/api/<endpointPath>` (default `/api/uploads/chunk`), Next will cap each chunk body at 10 MB regardless of how big the client sent — assembled file ends up corrupt and Sharp fails with \"premature end of data segment\". Fix: exclude the chunk endpoint from your middleware matcher, e.g. `matcher: ['/((?!_next|api/uploads/chunk).*)']`. The endpoint requires `req.user` internally, so middleware-level auth gating on it is redundant. Alternatively bump the global cap via [`middlewareClientMaxBodySize`](https://nextjs.org/docs/app/api-reference/config/next-config-js/middlewareClientMaxBodySize) in `next.config.js`, but that's coarser. Pre-Next-16 hosts are unaffected.\n- **Realistic per-upload memory ceiling is far below the chunk cap.** The 10 GiB ceiling (400 chunks × 25 MiB) is a per-session protocol cap, not an effective limit. Server-side, `assembleSession` concatenates all chunks into a single `Buffer`, hands it to Payload, then Payload's pipeline runs (Sharp resize, `imageSizes`, hooks) — peak memory ≈ 3–5× the file size for raster uploads. On a 4 GiB Lightsail instance, comfortable ceiling is **~500 MiB raster / ~2 GiB PDF or video** (PDFs and MP4s bypass Sharp entirely). Tune `maxChunks` per deployment.\n- **Sharp memory pressure on huge rasters**: a 500 MiB JPG can decode to multiple GiB. Sharp's default `limitInputPixels: 268MP` errors out on monsters instead of OOMing — keep it on. Consider rejecting raster uploads >100 MiB at the application layer if your instance is small.\n- **Single-instance only by default**: chunks land on local disk. For multi-instance deployments, point `tempDir` at a shared volume (NFS, EFS) — but each session must hit the same instance for assembly. Sticky sessions or a session-routing layer needed.\n- **No resume on failure (v0.1)**: if the client connection drops mid-upload, the editor retries from chunk 0. Chunks already on disk are swept by the cleanup loop within `sessionTtlMs`.\n- **Auth gating**: the chunk endpoint requires `req.user` (any authenticated Payload user). Same auth surface as the admin itself.\n\n## Interoperability with other upload-handler plugins\n\nThe collection-level handler runs on **both** the upload path AND the file-serve path (Payload calls `upload.handlers` from both). This plugin's handler:\n\n- **Serve path** (no `clientUploadContext` in params): returns `void`. Default file serving — or any other handler's serve logic — runs.\n- **Upload path with our envelope shape** (`clientUploadContext` matches `{sessionId, total, mimetype}`): assembles + returns the `Response` with the buffer.\n- **Upload path with a DIFFERENT envelope shape**: returns `void`. Another plugin's handler is responsible for that envelope. The combination is safe — both plugins coexist as long as their `clientUploadContext` shapes don't collide.\n\n## Development\n\n```sh\npnpm install\npnpm build    # tsc → dist/\npnpm dev      # tsc --watch\n```\n\nTo test against a host project (e.g., a Payload site sitting next to this repo), use `pnpm link --global` here and `pnpm link --global @assemblyltd/payload-chunked-upload` in the host.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}