37075 Commits

Author SHA1 Message Date
Niels Kaspers 9d5a027191 fix(review-workflows): implement incremental loading in assignee dropdown (#25967)
* fix(review-workflows): fetch all users in assignee dropdown

The AssigneeSelect component passed no pagination params to
useAdminUsers, which defaults to pageSize 10. Users with more than
10 admin accounts could not see or select all assignees.

Pass pageSize: 100 so the dropdown lists all available users.

Fixes #25945

* fix(review-workflows): incremental loading + preserve current assignee

Replaces the fixed pageSize:100 fetch with the same incremental Combobox
pattern used by the admin-users filter (Filters.tsx): grow pageSize on
onLoadMore, debounce server-side search via _q, and reset both on close.

Also keeps the currently assigned user in the option list when they fall
outside the loaded page or active search, so the Combobox never loses
its value.

* fix(review-workflows): improve assignee dropdown pagination search

---------

Co-authored-by: Bassel Kanso <basselkanso82@gmail.com>
2026-04-30 18:01:57 +00:00
Pierre Wizla 036b2c988c chore(ci): send Slack notification when flag: documentation label is added (#26057)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-30 08:34:23 -07:00
Andrei L 90623baa6f fix(admin): clean up lazy component registration warnings (#25015)
* fix(admin): don't warn when Component is missing in addMenuLink/addSettingsLink

* fix: add some missing StrapiApp types

* fix(admin): clean up lazy component registrations

---------

Co-authored-by: Bassel Kanso <basselkanso82@gmail.com>
2026-04-30 16:27:48 +03:00
Ziyi fa6299100d feat(content-manager): add Zod 4 foundation utilities (#25574) 2026-04-30 14:55:04 +02:00
Adrien L 8156393f8f Merge pull request #26170 from strapi/main 2026-04-30 14:28:15 +02:00
Boaz Poolman ec72af97f0 Fix polymorphic relations in the document service API (#26099)
* chore: remove early exit for morph relation types

* fix: issues with creating morphToOne relations

* chore: add tests

* test: add polymorphic relations tests

---------

Co-authored-by: Ben Irvin <ben@innerdvations.com>
2026-04-30 11:58:02 +02:00
Adrien L a881d63f0d chore: release 5.44.0 2026-04-30 10:59:03 +02:00
Marion Kamoike-Bouguet c45dc921b1 CI: reduce stale issue threshold from 1 year to 90 days (#26158)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 10:31:43 +02:00
guoyangzhen 36b6d68198 fix: prevent trailing ? in URL when params is empty object (#25724) (#25900)
Co-authored-by: Adrien Lepoutre <3693028+Adzouz@users.noreply.github.com>
2026-04-30 09:29:38 +02:00
Ben Irvin cd710a10e9 ci: do not fail fast on api or cli tests (#26159) 2026-04-29 16:31:08 +00:00
Nico André 52b8fd9e3d feat(admin): api token supports admin permissions and admin user ownership (#25657) 2026-04-29 17:57:36 +02:00
Ben Irvin 2933c695b3 chore: stop tracking vscode settings (#26160) 2026-04-29 17:26:49 +02:00
Adzouz 11554fe43e release: 5.44.0 v5.44.0 2026-04-29 13:06:31 +00:00
Boaz Poolman 9413a069c5 Merge pull request #25447 from strapi/feature/extended-ctb-api-for-plugins
enhancement: extended ctb api for plugins
2026-04-29 11:55:09 +02:00
Ziyi a33f5f5990 fix(document-service): discard-draft 500 on self-referential manyToMany relations (#26152) 2026-04-29 11:53:47 +02:00
markkaylor 403491df80 fix(upload): sharp concurrency and cache leads to OOM (#26046)
Co-authored-by: Ben Irvin <ben@innerdvations.com>
2026-04-29 10:01:23 +02:00
Adrien L f7d4979d69 fix(content-manager): prevent crash on detached DZ component (#26148)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 09:32:21 +02:00
akash-dabhi-qed 4d3719a327 fix: contain absolute descendants in OverflowingItem (#26133)
Co-authored-by: Adrien Lepoutre <3693028+Adzouz@users.noreply.github.com>
2026-04-28 11:50:23 +02:00
Ben Irvin fed8b43872 chore(deps): bump and dedupe pinned subdeps (#26139)
* chore: bump braces-expansion

* chore: upgrade glob

* chore: dedupe

* chore: upgrade picomatch
2026-04-28 10:04:50 +02:00
DMehaffy 19fef31e08 chore(examples): migration performance benchmark harness + mariadb/sqlite + anti-pattern schemas (#26036)
* chore(examples): add mariadb + sqlite + podman support to complex

Extends the complex example's DB tooling to cover all Strapi-supported
database dialects and both container runtimes, as groundwork for a
migration performance benchmark harness:

- New compose.js runtime shim auto-detects podman compose / podman-compose
  / docker compose / docker-compose and the matching container CLI; all
  existing db-* scripts now go through it so podman-only environments
  work without installing docker
- New db-mariadb.js mirrors db-mysql.js using mariadb-dump / mariadb CLIs
  and adds a mariadb:11 service on port 3307 to docker-compose.dev.yml
- New db-sqlite.js handles file-based snapshot/restore/wipe/check via
  fs.copy / better-sqlite3
- db-utils.js falls back to `<runtime> ps --filter name=` for container
  lookup since podman-compose doesn't support `ps -q`
- develop-with-db.js and the v4 templates (develop-with-db.js,
  seed-with-db.js) handle mariadb + sqlite (sqlite skips compose)
- setup-v4-project.js includes better-sqlite3 in v4 deps, database.js
  template covers all 4 clients, and compose.js is copied into the
  v4 scaffold scripts dir (dep of db-utils.js)

All four DBs smoke-tested locally against podman: start/check/snapshot/
restore/wipe cycle works for mariadb; cp-based snapshot cycle works
for sqlite.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore(examples): add migration perf benchmark harness

Three new scripts enable per-migration timing and baseline-vs-candidate
comparison reports for v4→v5 migrations in the complex example:

- bench-hook.js: Node --require preload that intercepts require('umzug')
  and subscribes to Umzug's native `migrating`/`migrated` events for
  sub-ms timing. Captures every migration that runs (including dynamically
  registered ones like discard-drafts and EE-only release migrations)
  without hardcoding names. Dumps to a JSON file on process exit; self-
  disables when STRAPI_BENCH_HOOK_OUTPUT is unset.
- bench.js: orchestrator with `run`, `seed`, and `suite` subcommands.
  `run` restores a snapshot, spawns Strapi in migrate-then-exit mode
  with the hook preload, collects row counts, and writes a result JSON
  with baseline/candidate attribution, env capture (node, CPU, memory,
  DB version, host type), and config (multiplier, seed/hook modes).
  `seed` wipes the DB, runs the v4 seed via seed-with-db.js, then
  snapshots. First iteration supports --strapi-source=local only;
  experimental/pinned are stubbed with a clear error.
- bench-compare.js: takes N labels and emits both a clipboard-friendly
  markdown report (stdout + results/compare-*.md) and a self-contained
  HTML report (results/compare-*.html) with inline SVG bar charts,
  per-DB grid, sortable tables, collapsible raw JSON, and a light/dark
  adaptive theme via prefers-color-scheme. No CDN deps.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore(examples): bench harness smoke-test fixes

Fixes discovered during the end-to-end smoke test on the existing 6
content types at multiplier=1:

- bench-hook.js: switch from subclass-based wrapping to in-place
  Umzug.prototype.up patching. The subclass approach replaced the module
  export at require time, but Node's module cache hands out the original
  class on subsequent requires, so listeners weren't attached on all
  instances. In-place prototype patching works for every instance
  regardless of how Umzug was imported.
- bench-hook.js: flush incrementally after each recorded migration.
  Strapi's shutdown path can bypass process.on('exit') handlers under
  some conditions (signal or explicit exit from deep inside), causing
  fully-collected timing data to be lost. Writing after each recording
  makes the benchmark resilient to any exit path.
- bench.js: compile TypeScript configs via @strapi/typescript-utils
  before createStrapi().load(). The examples/complex project has .ts
  config files; the Strapi CLI compiles them to dist/ before boot but
  our direct node -e loader skipped this, producing
  "db.config.connection undefined" failures.
- bench.js: propagate STRAPI_BENCH_HOOK_DEBUG to the Strapi child so
  debug output is visible when tracing hook behavior.
- bench-compare.js: rework the SVG chart. Dynamic label column sized
  to the longest migration name (up to 420px), 80px reserved on the
  right for value labels so they never clip, inlined monospace font
  (SVG text doesn't reliably inherit CSS variables from the surrounding
  stylesheet), and `dominant-baseline="middle"` for proper vertical
  centering.

Verified: full pipeline (setup:v4 → seed → snapshot → bench:run →
bench:compare) works against postgres at multiplier=1. Ran a baseline
vs cherry-picked PR #25988 comparison — captured all 7 v4→v5 migrations,
produced both markdown and HTML reports with correct test-setup
attribution and delta coloring.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(examples): run ANALYZE before db:check to get fresh row counts

pg_stat_user_tables.n_live_tup and information_schema.tables.table_rows
are approximate and can lag behind reality by minutes or hours depending
on autovacuum / ANALYZE cadence. For a benchmark harness that publishes
row-count numbers in its reports, stale counts are misleading.

Trigger a refresh via ANALYZE (postgres) / ANALYZE TABLE per-table
(mysql/mariadb) before each db:check invocation. Best-effort on the
mysql/mariadb side — fall through to stale stats if ANALYZE fails rather
than error the whole command.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(examples): add hc-m2m-source/target anti-pattern schemas

First anti-pattern schema pair for migration benchmark stress-testing.
A high-cardinality many-to-many relation that forces the v4→v5
discard-drafts migration's copyRelationTableRows code path to span
multiple chunks (>1000 rows) — the same scenario PR #25988's caching
fixes target.

- src/api/hc-m2m-source: collection type with DP and a manyToMany
  relation to hc-m2m-target (owning side)
- src/api/hc-m2m-target: collection type with DP and the inverse
  manyToMany back to source
- setup-v4-project.js: include both in the v4 scaffold CONTENT_TYPES
- seed-v4.js: seedHcM2m() method that creates sources + targets and
  fans out 10 targets-per-source via the M2M relation. BASE counts at
  m=1 are tiny (15 pub + 5 draft per side) but at m=100 produce ~2K
  sources × ~2K targets × 10 = 20K join rows, crossing the 1000-row
  chunk boundary multiple times

Intentionally NOT a realistic content-type design — this is a
stress-test fixture. See the description in schema.json.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(examples): render multiplier x db matrix in bench-compare

Rework bench-compare to index results by (label, multiplier, dbEngine)
triples pulled from each result JSON's own fields, rather than parsing
labels out of filenames. Lets the same canonical baseline/candidate
label span any number of (multiplier, db) combinations and produces:

- A speedup matrix at the top: rows = multipliers, cols = databases,
  cells = "baseline -> candidate (delta%)". Missing cells render as
  "-" so partial data still produces a useful report.
- A data-availability matrix listing what ran vs what's still missing.
- Per-(db, multiplier) detail sections as collapsible details in
  HTML, all expanded in markdown.

Also:
- New flag syntax: --baseline <label> / --candidate <label>, with
  positional args kept for backward compat.
- Legacy labels that embedded the multiplier (e.g. "baseline-m100")
  are normalized to their base form ("baseline"), letting older
  result files keep working.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(examples): force TCP for mysql/mariadb CLI in containers

The mysql/mariadb CLI tools default to connecting via unix socket at
/var/run/mysqld/mysqld.sock, which isn't populated in the official
mysql:8 / mariadb:11 container images. Every invocation (check,
snapshot, restore, wipe, readiness probe, version probe) needs an
explicit -h 127.0.0.1 to force TCP via the container's loopback.

Without this fix, bench:seed and bench:run error out with
"Can't connect to local MySQL server through socket" on anything
requiring the CLI inside the container (pg_stat-style row-count
queries, snapshot restore, etc.).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* enhancement(examples): parallelize entity creation in seed-v4

Replace sequential for-loops of `await entityService.create(...)` with
a `concurrentMap(count, concurrency, taskFn)` helper that runs N tasks
in flight at once. At SEED_CONCURRENCY=5 (default), a seed that was
strictly serial now fans out into 5 parallel creates.

Concurrency chosen conservatively: Strapi v4's default knex pool is
`{min: 2, max: 10}`, and entity-heavy creates (components + DZs +
localizations) can use multiple connections per call. 5 keeps us well
under the pool ceiling. Tune via `SEED_CONCURRENCY=<n>` env var if
you've also raised the pool max.

Applied to: seedBasic, seedBasicDp, updateComponentRelations,
seedBasicDpI18n, seedRelation, seedRelationDp, seedRelationDpI18n,
seedHcM2m (all entity-creation loops plus their follow-up
self-reference update loops).

Not yet done: incremental seeding (restore previous snapshot + seed
delta) — a separate optimization tracked as a follow-up.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(examples): update complex README for new bench tooling + DBs

README was documenting just the original 6-type, postgres+mysql
workflow. Updated to cover everything this branch adds:

- 8 content types (added hc-m2m-source/target anti-patterns)
- 4 supported databases (added mariadb + sqlite)
- Container runtime auto-detection (podman compose / podman-compose /
  docker compose / docker-compose) with STRAPI_BENCH_RUNTIME override
- Benchmark harness workflow (bench:seed / bench:run / bench:compare /
  bench:suite) for reviewing migration-performance PRs
- SEED_CONCURRENCY, STRAPI_BENCH_HOOK_OUTPUT, STRAPI_BENCH_HOOK_DEBUG,
  and the existing port-override env vars
- MariaDB port default 3307 to avoid colliding with MySQL on 3306

Also collapsed the redundant per-DB command sections (postgres and
mysql both had identical copy-pasted blocks) into a single
'yarn db:<op>:<db>' table since the commands are symmetric across
all four dialects.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(examples): align better-sqlite3 version with monorepo convention

I picked `11.3.0` arbitrarily. Every other example and tests/app-template
use `12.8.0`, and the root yarn.lock already resolves that version.
Without alignment CI's `yarn install --immutable` fails with 'lockfile
would have been modified', cascading every subsequent job (build, pretty,
commitlint, aggregate_test_result) to red.

Bumping to `12.8.0` to match, regenerating yarn.lock.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: throw instead of return to fail fast

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Ben Irvin <ben@innerdvations.com>
2026-04-27 18:28:08 +02:00
dependabot[bot] d66f95aa58 chore(deps): bump @xmldom/xmldom from 0.8.12 to 0.8.13 (#26098)
Bumps [@xmldom/xmldom](https://github.com/xmldom/xmldom) from 0.8.12 to 0.8.13.
- [Release notes](https://github.com/xmldom/xmldom/releases)
- [Changelog](https://github.com/xmldom/xmldom/blob/master/CHANGELOG.md)
- [Commits](https://github.com/xmldom/xmldom/compare/0.8.12...0.8.13)

---
updated-dependencies:
- dependency-name: "@xmldom/xmldom"
  dependency-version: 0.8.13
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Ben Irvin <ben.irvin@strapi.io>
2026-04-27 18:07:24 +02:00
Ben Irvin 416f2f138f chore: upgrade contributor docs dependencies (#26073) 2026-04-27 17:57:37 +02:00
Nico André f78edc3bc9 chore: release v5.43.0 update develop (#26100) 2026-04-24 17:17:47 +02:00
Kellen Bolger f36d919a6d fix(review-workflows): pass locale params to useDocument in StageSelect and AssigneeSelect (#26104)
StageSelect and AssigneeSelect were calling unstable_useDocument without
the query params (which carry the active locale). This caused both
components to always fetch and display data from the default locale,
regardless of which locale the editor had open.

As a result, when viewing a non-default locale entry, the displayed
review stage and assignee reflected the default locale's values. After
updating the stage or assignee for a non-default locale, the cache
invalidation triggered a refetch that still omitted the locale param,
so the panel appeared unchanged even though the backend had been
updated correctly.

Passing params to unstable_useDocument aligns the document fetch with
the locale already used by the mutations (useUpdateStageMutation,
useUpdateAssigneeMutation) and the stages query (useGetStagesQuery),
ensuring the panel reads from and reflects the correct locale.
2026-04-24 16:09:52 +01:00
nclsndr 765bd19a3a Merge branch 'develop' of github.com:strapi/strapi 2026-04-24 15:40:44 +02:00
Ben Irvin ac6cd0063c chore(deps): bump multiple dependencies (#26103)
dotenv: 16.4.5 → 16.6.1
fs-extra: 11.2.0 → 11.3.4
semver: 7.5.4 → 7.7.4
typescript: 5.4.4 → 5.4.5
esbuild-loader: 4.3.0 → 4.4.3
esbuild-register: 3.5.0 → 3.6.0
grant: ^5.4.8 → 5.4.24 (pinned)
markdown-it: ^13.0.2 → 14.1.1
2026-04-24 13:11:54 +01:00
Leonid Vinogradov 6e10c0c439 enhancement(i18n): improve Russian translations of tours section in admin package (#25221) 2026-04-24 10:36:37 +01:00
Jamie Howard 62a6230772 test: relations available status (#26051) 2026-04-24 10:39:17 +02:00
Filip Ónodi 4ccaab3c74 enhancement(translations): update czech translations (#25824)
Co-authored-by: Bassel Kanso <basselkanso82@gmail.com>
2026-04-24 11:11:48 +03:00
Ziyi 7f7c1c3403 fix(database): make 5.0.0-02-created-document-id migration idempotent (#26045)
Previously the migration could leave the DB in an unbootable state after
a statement_timeout or process kill: the document_id column existed but
the migration was not recorded, and the retry crashed with PG 42701
"column already exists". Additionally, when hasColumn returned true
the migration early-exited via continue, silently skipping the backfill
and leaving rows with NULL document_id.

- Swallow duplicate-column errors (PG 42701, MySQL 1060, generic
  /duplicate column/i) around ALTER TABLE ADD COLUMN to tolerate
  catalog drift / operator-applied partial fixes.
- Always run the document_id backfill when the column exists; the
  backfill already uses WHERE document_id IS NULL so it is a no-op on
  fully-populated tables and recovery on partially-populated ones.
- Add unit tests covering fresh run, column-already-exists,
  PG 42701, MySQL 1060, and non-duplicate errors.

Fixes CMS-689
2026-04-24 09:12:57 +02:00
otociulis e95b505aad fix(openapi): documentation plugin generates OpenAPI with incorrect ID parameter (#26067) 2026-04-23 19:50:43 +03:00
akash-dabhi-qed 7c3fcff48d fix: prevent browser defaults for Ctrl+I and other modifier shortcuts in Firefox (#26050) 2026-04-23 17:04:22 +03:00
Ziyi ab7d9c38ec fix(document-service): preserve self-referential relations during publish and discard (#25890)
* fix(document-service): preserve self-referential relations during publish/discard

* test(document-service): convert self-referential API test to TypeScript

* fix(document-service): use JoinTable type and tighten Record types in self-referential-relations

* test(document-service): remove weak load() happy-path unit test

* fix(document-service): skip mappedBy attrs, deduplicate and idempotent-insert self-refs

* test(document-service): fix missing dialect and trx mocks in self-referential-relations tests

* fix(tests): use count assertions for CM API self-referential relation tests
2026-04-23 13:32:04 +02:00
Ayoub Hidri d8c286c9e5 fix(types): align Service.Generic index signature with Controller.Generic (#25475)
Co-authored-by: Bassel Kanso <basselkanso82@gmail.com>
2026-04-23 13:02:36 +03:00
Ziyi c01c77524a docs: add AGENTS.md universal agent guide (#26018)
* docs: init AGENTS.md
2026-04-23 11:59:26 +02:00
Nico André ae8061604b release: 5.43.0 2026-04-23 11:08:58 +02:00
Rowan-Paul deafc2d9be Fix drag-and-drop preview in dynamic zones (#25123)
* fix: keep temp key stable for drag-and-drop

* fix: fix generating unique temp key for new items

* fix: fix retry loop and failing test
2026-04-23 08:13:14 +01:00
Laurens Kling 104969fd8f fix(document-service): support delete selection params (#25097)
* feat: allow selectionParams in documents.delete

* fix(document-service): preserve locale-scoped delete lookup with selection params

---------

Co-authored-by: Bassel Kanso <basselkanso82@gmail.com>
2026-04-23 10:12:13 +03:00
nclsndr 14628987b5 release: 5.43.0 v5.43.0 2026-04-22 14:30:40 +00:00
Jamie Howard 601154b254 fix(content-manager): optimize document layout hooks (#26005)
* fix(content-manager): reduce duplicate config/document queries

* chore(content-manager): usePersistentPartialQueryParams hydration state
2026-04-22 14:30:48 +01:00
Nico André 460ab0f90b chore(scripts/release): fix experimental peer dependencies install (#26083) 2026-04-22 12:35:19 +02:00
DMehaffy f81ca93887 fix(content-manager): prevent duplicate React key in homepage recent-documents widget (#26084) 2026-04-22 10:34:51 +03:00
Simon Norris df2c928d0e feat: deploy to cloud homepage widget (#25774)
Co-authored-by: mathildeleg <82765709+mathildeleg@users.noreply.github.com>
2026-04-21 17:09:51 +02:00
Bassel Kanso e66251a30c fix(i18n): preserve non-localized media when creating a locale (#26031) 2026-04-21 14:00:24 +03:00
Leonid Vinogradov 030ca0078e enhancement: add ESM syntax support for Vite .mts config file (#25238) 2026-04-21 10:22:26 +00:00
Adrien L eeac518671 fix: add responseType to getFetchClient for non-JSON responses (#25974) 2026-04-21 11:48:15 +02:00
Paul Bratslavsky f4857d5346 chore: update main README content (#25618)
* chore: update readme.md file

* chore: pdate README.md based on feedback

---------

Co-authored-by: Nico André <nicolas.andre@strapi.io>
2026-04-21 09:20:44 +02:00
Ben Irvin 6722bec700 security: upgrade to axios 1.15.1 (#26072)
* security: upgrade to axios 1.15.1

* chore: update follow-redirects

* chore: update pinned lodash

* fix: mime type typings
2026-04-20 21:19:33 +02:00
Ben Irvin ff000af696 enhancement(data-transfer): improve progress UX (#25921)
* enhancement: update progress per chunk

* fix: check stageprogress exists to make ts happy

* chore: split progress tracker into two methods

* test: fix lint

* enhancement: display readable times

* fix: speed indication for assets

* fix: restore speed indicator and fix double counting

* chore: clean up code

* fix: data transfer memory leak

* fix: yarn.lock

* chore: fix memory logging

* ci: complex project remote transfer

* enhancement: optimized transfer mode

* test(cli): data transfer and env passthrough

* chore: only send one message warning of legacy mode

* enhancement: show transfer totals and estimated time

* test(cli): fix deterministic transfer test files

* fix: push and pull shared utils backwards compatibility

* fix(data-transfer): extract legacy asset chunk parsing and tighten transfer logging/test coverage

* enhancement: checksum negotiation

* enhancement: show skipped file warnings on client

* fix: transfer diagnostics

* test: fix open handle

* fix: clear stall timeout for assets

* chore: fix misleading comments and variables

* test: fix misleading test

* test: fix typo

* test: make checks deterministic, less flaky

* enhancement(data-transfer): speed up asset totals; widen assets start reply window on remote pull

* fix(data-transfer): harden WebSocket JSON serialization for transfer frames

* fix(data-transfer): more transfer hardening

* test: fix test imports

* fix: entities batching

* enhancement(data-transfer): better estimates and totals

* chore: fix linting

* fix: broken merge
2026-04-20 18:57:28 +02:00
Ben Irvin e94abcb823 test(e2e): fixes for race conditions and file resets (#26019) 2026-04-20 18:38:46 +02:00