Skip to content

feat(plugin-import-export): give import/export hooks access to the triggering document - #17797

Draft
nathanlentz wants to merge 5 commits into
mainfrom
feat/import-export-hooks-doc-access
Draft

feat(plugin-import-export): give import/export hooks access to the triggering document#17797
nathanlentz wants to merge 5 commits into
mainfrom
feat/import-export-hooks-doc-access

Conversation

@nathanlentz

@nathanlentz nathanlentz commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

What

Adds importDoc and exportDoc to the collection-level before/after hooks so custom fields added with overrideCollection can influence every processed row. Saved documents also provide the ID needed to associate queued work with its import or export.

Addresses #16961.

Behavior

  • Synchronous and queued imports pass a saved import document. Queued exports read the saved export document once when the job starts.
  • Synchronous exports run in beforeOperation; downloads and previews use submitted form values. These paths omit id, createdAt, and updatedAt.
  • The same document object is reused across batches. Hooks should treat it as read-only. Queued document values reflect processing start, while built-in queued export options retain their queue-time values.
  • Both preview forms forward custom fields and refresh after those values change. Previews use the current form even on a saved document's edit view, and omit its saved ID.
  • ImportDoc and ExportDoc are exported from @payloadcms/plugin-import-export/types. An ID identifies persistence, not authorization for actions performed by a hook.

Updated against current main, including migration to the shared integration-test fixture. Tests retain coverage of synchronous, queued, download, and preview paths, row transformations, and shared document identity across batches.

Validation

  • Full plugin integration suite: 256 passed, 5 skipped.
  • Next.js custom-field preview browser tests: 2 passed.
  • Plugin build, including TypeScript declarations: passed.
  • Focused lint and formatting: passed; the existing default-config-export lint warning remains.
  • TanStack browser validation stopped before tests because the dependency bundler reported a missing AWS SDK fromTokenFile export. Standalone test-suite type checking also reports existing workspace/config errors; the hook test file has no remaining type errors.

The PR remains a draft pending refreshed CI.

…iggering document

The collection-level import/export hooks received no reference to the document
that started the run, so a field added to the imports/exports collection via
`overrideCollection` could not be read while processing. That also left no way
to correlate a running job with its document in jobs mode.

Adds `importDoc` to `ImportBeforeHook`/`ImportAfterHook` and `exportDoc` to
`ExportBeforeHook`/`ExportAfterHook`, covering all seven hook contexts:

- import jobs and sync, which already held the saved document
- export jobs, which now reads the document back — the job input schema is a
  fixed whitelist, so fields added via `overrideCollection` do not survive
  serialization
- export sync, download, and both preview endpoints, which pass the submitted
  form data

`id` is optional on both types because only the export jobs path has a saved
document when the hooks run. Export sync runs in `beforeOperation`, and the
download and preview paths never persist one. On those, every user-authored
field is present but `id`, `createdAt` and `updatedAt` are not, and the values
are unvalidated request input — both documented.

The document is read once when the run starts and passed unchanged to every
batch, so it is a snapshot rather than live state. A long run would otherwise
add a database read per batch to observe a change nothing needs.

Closes #16961
…w endpoints

The preview components built their request bodies from a fixed list of built-in
fields, so a field added to an imports/exports collection via
`overrideCollection` never reached the collection-level hooks. Both now forward
the whole form, and re-fetch when a custom value changes.

The endpoints drop `id`, `createdAt` and `updatedAt` from the incoming body, so
an `id` on `exportDoc`/`importDoc` means the document really is saved rather
than something a caller can put on a request.

Adds coverage for the queued-import, synchronous-export and download after
hooks, for document identity across batches, and for two cases where a form
value changes the rows that get written. The new tests clean up the import and
export documents and the job records they create.
…ming

Cleanup no longer catches deletion failures, so a delete that does not succeed
fails the test rather than passing quietly. Job records are tracked per test: a
snapshot of the existing payload-jobs IDs is taken before each test and only the
records added on top of it are removed, instead of deleting every job record.

Splits the download test so each one checks a single hook, routes the repeated
post-and-export setup through helpers, and renames `withBatchRefField` and
`generatedKeys` to describe what they actually do.
@github-actions

Copy link
Copy Markdown
Contributor

📦 esbuild Bundle Analysis for payload

This analysis was generated by esbuild-bundle-analyzer. 🤖
This PR introduced no changes to the esbuild bundle! 🙌

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant