* chore(deps): bump msw to 1.3.5 and typedoc to 0.25.13
Widens TypeScript peer ranges in msw (>= 4.4.x) and typedoc (adds 5.4.x),
unblocking a future bump to typescript 5.6 required by react-intl 7.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore(deps): bump msw to 2.13.4 across admin test suites
Migrates 8 workspaces (admin, content-manager, content-releases, upload,
review-workflows, plugin-i18n, plugin-documentation, plugin-users-permissions)
from msw 1.3.5 to 2.13.4; bumps email's unused dep for consistency.
Handler changes:
- rest.X((req, res, ctx) => res(ctx.json(X))) → http.X(() => HttpResponse.json(X))
- res(ctx.status(N)) → new HttpResponse(null, { status: N })
- res.once(...) → http.X(path, handler, { once: true })
- res.networkError(...) → HttpResponse.error()
- await req.json<T>() / casts → http.METHOD<Params, Body>(...) generics
- RequestHandler → HttpHandler
- Empty 200 responses use HttpResponse.json({}) to avoid cross-realm
SyntaxError instanceof check in getFetchClient.ts
Jest setup (per msw frequent-issues guide):
- jest-preset.front.js: customExportConditions: [''] so msw/node resolves
under jsdom; .mjs swc transform; ESM allow-list for msw deps
(rettime, @open-draft, outvariant, until-async, etc.)
- packages/admin-test-utils/src/environment.ts: polyfill Node fetch +
streams + BroadcastChannel + URL into jsdom global. Blob/File/FormData
intentionally left as jsdom's — Strapi app code threads them through
jsdom-only APIs (FileReader, Image, HTMLFormElement) where realm matters.
Comment in env.ts documents the trade-off.
Verified vs develop+msw@1.3.5 baseline: 0 net regressions across all 7
workspaces with msw test files; TypeScript clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Revert "chore(deps): bump typedoc to 0.25.13"
The typedoc bump was bundled with the msw 1.3.5 bump in 39d169cfbb but
isn't required for the msw v2 migration. Reverting the docs/ and
core/types typedoc dep back to 0.25.10 to keep this branch focused on
the msw upgrade.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore(tests): type msw handler params via generics
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore(tests): address review feedback on msw v2 migration
- env.ts: snapshot jsdom globals in setup(), restore in teardown() so
per-test mutations cannot leak across files in a Jest worker.
- env.ts: collapse polyfill list and value map into a single NODE_GLOBALS
source of truth; document the fetch trade-off (Node undici vs jsdom).
- handlers: replace `<never, Body>` generics with `<Record<string, never>,
Body>` (msw v2 convention; `{}` blocked by ban-types).
- email: drop unused msw devDep entirely (zero source usage in workspace).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore(tests): use realm-agnostic SyntaxError check; drop URL polyfill
Two follow-ups to the msw v2 migration:
- `getFetchClient.responseInterceptor` now matches `error?.name === 'SyntaxError'`
rather than `instanceof SyntaxError`. Constructor identity differs across JS realms
(under jsdom + Node fetch, an empty 200 throws a Node-realm `SyntaxError` that
fails the jsdom-realm `instanceof` check; the same is true in browsers when the
Response originates from a service worker / iframe). Name comparison is realm-
agnostic. With this in place, empty 200 handlers can return `new HttpResponse()`
again (closer to v1's `res(ctx.status(200))`) instead of the `HttpResponse.json({})`
workaround.
- Drop `URL` / `URLSearchParams` from the env.ts polyfill list. jsdom already
provides browser-spec versions, and Node's `URL.createObjectURL` only accepts
Node-realm `Blob` — replacing it broke the "from computer" upload path in
`LogoInput.tsx`. MSW v2's interceptor doesn't require these to come from Node.
env.ts comments restructured: all polyfill rationale lives in one top-of-file block
so the body is short and the trade-offs are documented in one place.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore(tests): switch content-type-builder jest env to shared polyfilled env
`aiClient.test.ts` constructs `new Response(...)` which jsdom does not provide
spec-compliantly. Align CTB with the other admin test suites by using
`@strapi/admin-test-utils/environment`, which polyfills Node's
`fetch`/`Request`/`Response`/streams into the jsdom global.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(tests): make msw v2 + undici body + jsdom realms work together
Three regressions surfaced by running the full front test suite under
jsdom + Node's undici fetch polyfill:
1. `TypeError: Body is unusable: Body has already been read` in every
handler doing `await request.json()`. MSW v2's `RequestHandler.run()`
calls `request.clone()` before invoking the resolver (to keep a copy
for post-hoc logging). Under Node's undici, `Request.clone()` tees the
underlying `ReadableStream` and locks the original body, so the
resolver's `.json()` throws. Fix in `environment.ts`: wrap the global
`Request` constructor to stash the stringified body on every instance
and patch `Request.prototype.json` / `.text` to return the stash when
present. Handlers now get the body regardless of how many times msw
clones internally.
2. `expect.any(Array)` and `toStrictEqual` failing with "serializes to
the same string" against msw response bodies. `Response.prototype.json`
runs Node's `JSON.parse`, so the resulting objects carry Node-realm
`Object`/`Array` prototypes; jsdom's `instanceof`/strict-equality
matchers reject them. Patch `Response.prototype.json` to parse with
the jsdom-realm `JSON`.
3. `useWidgets > should handle network errors gracefully` expected the
toast text "Network error", which msw v1's `res.networkError('Network
error')` surfaced verbatim. v2's `HttpResponse.error()` drops the
custom message and fetch throws `TypeError: Failed to fetch`; update
the assertion accordingly.
Also: `UIDInput` uses `jest.useFakeTimers()`. Adding `doNotFake:
['queueMicrotask', 'setImmediate']` keeps per-test runtime at ~1s
instead of ~10s (plain fake timers stall undici's internal microtasks
between request emission and handler resolution), and an `afterEach`
restores real timers so a failing test cannot leak fake timers into
the next one.
Verified with `nx run-many --target=test:front --parallel=1` across all
12 projects — all suites green.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* test(admin): assert toast container in Widgets error tests
Replace text-match (`findByText('Server error' | 'Failed to fetch')`) with
`[data-sonner-toast]` container assertion. Decouples the test from toast
copy and from msw v1/v2 network-error message differences.
Addresses @jhoward1994's review comment on PR #26065.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* test(admin): assert toast text, scope msw handlers, use jsdom env
- Widgets tests: match actual toast text (Server error / fetch failure
regex) instead of data-sonner-toast container.
- ConfirmBulkActionDialog: mark msw runtime handlers { once: true } so
they do not leak across cases.
- content-type-builder: jest testEnvironment back to jsdom.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore(tests): split jest env patches into modules
Refactor packages/admin-test-utils/src/environment.ts by extracting
the msw v2 + undici body + jsdom realm shims into dedicated modules
under src/patches/ (node-globals, request-body-stash,
response-json-realm, types).
Co-Authored-By: Jamie Howard <jhoward1994@gmail.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore: initiate moving CM to own package
* chore: refactor to handle routes
* chore: init review-workflows-package
* chore: fix build
* chore: refactor review-workflows fe
* chore: fix unit suite
* chore: spelling mistake
Co-authored-by: Jamie Howard <48524071+jhoward1994@users.noreply.github.com>
---------
Co-authored-by: Jamie Howard <48524071+jhoward1994@users.noreply.github.com>
* chore(helper-plugin)!: move useRBAC
* chore: get tests working
* chore!: remove auth
* chore!: remove usePersistentState
* fix: refactor building admin package so it shares modules with different entries
* fix: session vs local
* feat: return metadata on content manager endpoints (#19361)
* feat: return metadata on content manager endpoints
* feat: return meta
* fix: cm tests
* feat: fix cm metadata api tests (#19375)
* feat: return metadata on content manager endpoints
* feat: return meta
* fix: cm tests
* fix: admin test
* chore(cm): refactor CM (#19341)
* chore(cm): refactor EditView
comes with a host of new re-usable APIs!
* feat(cm): add useDocument hook
* feat(cm): add useDocumentOperations hook
* feat(cm): initialise EditView header
* feat(cm): add useDocumentLayout hook
* fix: listView from layout refactor
* chore(cm): refactor editview form input renderer
* chore: fix lint & ts
* fix: re-add custom fields
* test: fix admin/CM unit tests
* docs(cm): add docs at a high level of how the CM works
* test: add useDocumentRBAC tests
* chore: pr amends
* feat: add addEditViewSidePanel API to strapi (#19398)
* feat: add addEditViewSidePanel API to strapi
fix: don't pass all the query params to the create route
* chore: pr amends
* fix: return available status when content type doesnt have i18n enabled (#19419)
* fix: return available status when content type doesnt have i18n enabled
* chore: remove comment
* fix(cm): list view & build process
* feat: save and publish
* feat: update contract
* feat: dp tests
* chore: use document from create and update
* feat: save and publish single types
* feat: return metadata on content manager endpoints (#19361)
* feat: return metadata on content manager endpoints
* feat: return meta
* fix: cm tests
* feat: fix cm metadata api tests (#19375)
* feat: return metadata on content manager endpoints
* feat: return meta
* fix: cm tests
* fix: admin test
* chore(cm): refactor CM (#19341)
* chore(cm): refactor EditView
comes with a host of new re-usable APIs!
* feat(cm): add useDocument hook
* feat(cm): add useDocumentOperations hook
* feat(cm): initialise EditView header
* feat(cm): add useDocumentLayout hook
* fix: listView from layout refactor
* chore(cm): refactor editview form input renderer
* chore: fix lint & ts
* fix: re-add custom fields
* test: fix admin/CM unit tests
* docs(cm): add docs at a high level of how the CM works
* test: add useDocumentRBAC tests
* chore: pr amends
* feat: add addEditViewSidePanel API to strapi (#19398)
* feat: add addEditViewSidePanel API to strapi
fix: don't pass all the query params to the create route
* chore: pr amends
* fix: return available status when content type doesnt have i18n enabled (#19419)
* fix: return available status when content type doesnt have i18n enabled
* chore: remove comment
* fix(cm): list view & build process
* feat: add publish & update action (#19423)
* feat: return metadata on content manager endpoints (#19361)
* feat: return metadata on content manager endpoints
* feat: return meta
* fix: cm tests
* feat: fix cm metadata api tests (#19375)
* feat: return metadata on content manager endpoints
* feat: return meta
* fix: cm tests
* fix: admin test
* chore(cm): refactor CM (#19341)
* chore(cm): refactor EditView
comes with a host of new re-usable APIs!
* feat(cm): add useDocument hook
* feat(cm): add useDocumentOperations hook
* feat(cm): initialise EditView header
* feat(cm): add useDocumentLayout hook
* fix: listView from layout refactor
* chore(cm): refactor editview form input renderer
* chore: fix lint & ts
* fix: re-add custom fields
* test: fix admin/CM unit tests
* docs(cm): add docs at a high level of how the CM works
* test: add useDocumentRBAC tests
* chore: pr amends
* feat: add addEditViewSidePanel API to strapi (#19398)
* feat: add addEditViewSidePanel API to strapi
fix: don't pass all the query params to the create route
* chore: pr amends
* fix: return available status when content type doesnt have i18n enabled (#19419)
* fix: return available status when content type doesnt have i18n enabled
* chore: remove comment
* feat: add publish & update action
* feat: add published disabled state
* test: fix suite
* test: add unit for Panels
* fix(cm): status not state for redirect
* fix(cm): list view status & component main field property
* chore: pr feedback
* chore: apply suggestions
Co-authored-by: markkaylor <mark.kaylor@strapi.io>
---------
Co-authored-by: Marc Roig <marc12info@gmail.com>
Co-authored-by: markkaylor <mark.kaylor@strapi.io>
* feat: test single types
* feat: wrap single type publish into a transaction
* feat(cm): add unpublish & delete actions, also re-enable single-types (#19459)
* fix: delete url was wrong way round
* feat: compute modified status
* fix(cm): reimplement ListSettingsView (#19432)
* chore: PR feedback
* feat: discard endpoint
* feat: discard draft api tests
* feat: unpublish and discard
* chore: pr comments
* chore: update sanitizer
* feat(cm): add publish and save (#19500)
* feat(cm): add publish and save
* test(cm): fix unit for useDocumentActions
* Update packages/core/content-manager/server/src/controllers/collection-types.ts
Co-authored-by: Jamie Howard <48524071+jhoward1994@users.noreply.github.com>
* Update packages/core/content-manager/shared/contracts/single-types-v5.ts
Co-authored-by: Jamie Howard <48524071+jhoward1994@users.noreply.github.com>
* feat(document-service): map document ID to entry ID (#19248)
* feat: use document service in content manager
* feat: update contracts with meta information
* chore: group metadata types into a single type
* feat: metadata information in single types
* chore: change meta contract to return documents instead of strings
* fix: remove unused type
* fix: ignore doc id if entry is null
* fix: update contract metadata
* feat: document metadata service
* feat: locale and status filtering
* chore: add comment
* chore: refactor metadata service
* chore: refactor entity manager exists to handle single types
* feat: refactor single type controllers to use documents
* feat: get locale param from in cm endpoints
* Revert "feat: get locale param from in cm endpoints"
This reverts commit 856c38588b.
* feat: get locale param from cm endpoints
* Update packages/plugins/i18n/server/src/controllers/validate-locale-creation.ts
Co-authored-by: Ben Irvin <ben@innerdvations.com>
* fix: entity manager unit tests
* chore: unit test document metadata
* feat: prevent empty string locale filtering
* fix: cm contract import
* chore: test new d&p cm features
* fix: search content manager api test
* fix: cm tests
* fix: cm tests
* fix: cm tests
* fix(content-manager): access to non default locale documents (#19190)
* fix(content-manager): access to non default locale documents
* chore(content-manager): revert route construction
* fix(content-manager): api tests for number of draft relations
* test(content-manager): counting number of draft relations for non default locales
* chore(content-manager): remove default locale from entity manager countDraftRelations
* chore: basic relations testing for document service
* chore(e2e): disable edit view tests (#19235)
* feat: get relation ids
* chore: clean functions into other folders
* chore: rename files
* fix: group document ids by its uid
* feat: id mapper
* chore: improve typings
* chore: rename transform functions
* fix: id-transform tests
* chore: simplify function return value
* chore: improve comments
* fix: api tests
* fix: single types unit test
* fix: skip relations test
* fix: exclude fields
* fix: short hand ifs
* fix: merge conflict
* fix: transform output of find one
* Update packages/core/core/src/services/document-service/transform/utils.ts
Co-authored-by: Ben Irvin <ben.irvin@strapi.io>
* feat[Document Service]: Param transformation (#19373)
* fix(core): wip param transformation
* feat(core): wip param transformation based on relational status
* feat(core): wip populate and filter transformation based on relational status
* chore(core): simplify fields and sort
* chore(core): clean up
* feat(core): wip filter transformation with traverseQueryFilters
* feat(core): reorganise and PR feedback
* fix(core): filters traversal logic
* feat(core): populate relational transformations
* chore(core): reintroduce populate transformation
* fix(core): enforce that fields must include id
* fix(core): enforce that fields must include id
* fix(core): filter and sort transformation
* chore(core): typos
* chore(core): further filters test cases
* feat(core): support object based sorts
* chore(core): fields test naming
* feat(core): handle logical operators in filters
* fix: skip conditions test
* fix(core): switchIdForDocumentId (#19497)
* fix: uniqueness test
* fix: available status should be an array
* fix: available statuses
* fix: skip uniqueness folder
* fix: skip uniqueness test errors
* fix: skip failing test
---------
Co-authored-by: Ben Irvin <ben@innerdvations.com>
Co-authored-by: Jamie Howard <48524071+jhoward1994@users.noreply.github.com>
Co-authored-by: Josh <37798644+joshuaellis@users.noreply.github.com>
Co-authored-by: Jamie Howard <jamie.howard@strapi.io>
Co-authored-by: Ben Irvin <ben.irvin@strapi.io>
* chore: re-implement edit configuration (#19488)
* chore: re-implement edit configuration
* chore: cleanups
* test: fix unit tests
* feat(cm): add discard changes action (#19509)
* feat(cm): add discard changes action
* feat(cm): add discard when unpublishing
* test(e2e): fix editview e2e
* test(e2e): fix uniqueness partially
* test(unit): fix unit tests for actions & add for discard
* chore: bump playwright
* fix(webkit): add shim for requestIdCallback
* chore: pr amends
* feat: return status on available locales
* feat: add document-actions to list-view (#19523)
* fix(cm): add gap and alignment for edit-view heading with super long names
* fix(cm): list view status'
* feat: add list-view actions
* fix: conditions for actions to be enabled
* fix: stay on draft tab when published
* fix: stop propogation on list-view row click
* test(e2e): fix editview tests
* chore: update spelling error
Co-authored-by: Jamie Howard <48524071+jhoward1994@users.noreply.github.com>
---------
Co-authored-by: Jamie Howard <48524071+jhoward1994@users.noreply.github.com>
* feat: test document metadata
* chore: remove unnecessary unit test
* fix: return modified on published documents
* chore: init split single-type collection-type in document service
* Fix/fields test case (#19481)
* Update packages/core/content-manager/server/src/services/document-metadata.ts
Co-authored-by: Jamie Howard <48524071+jhoward1994@users.noreply.github.com>
* fix: pretty
* chore: refactor middlewares
* feat: send empty object if locale does not exist on document
* feat: single types
* chore: add tests to middlewares
* feat: update locale using query params (#19546)
* feat: return available locales when not finding locale
* chore: update typings
* feat: add clone action (#19526)
* feat: add clone action
* test(e2e): add auto clone tests
* chore: pr amends
* feat: add information to header actions menu (#19548)
* feat: add information to header actions menu
* fix: dont use non-null-assertion
* feat: manage relations on publish (#19427)
---------
Co-authored-by: Ben Irvin <ben@innerdvations.com>
Co-authored-by: Jamie Howard <48524071+jhoward1994@users.noreply.github.com>
Co-authored-by: Josh <37798644+joshuaellis@users.noreply.github.com>
Co-authored-by: Jamie Howard <jamie.howard@strapi.io>
* feat: v5 i18n relations (#19504)
Co-authored-by: Ben Irvin <ben@innerdvations.com>
Co-authored-by: Jamie Howard <48524071+jhoward1994@users.noreply.github.com>
Co-authored-by: Josh <37798644+joshuaellis@users.noreply.github.com>
Co-authored-by: Jamie Howard <jamie.howard@strapi.io>
* fix: locale test api
* chore: refactor i18n (#19555)
* chore: remove types package, should be using strapi
* chore: refactor i18n settings page
* feat: add i18n to CM
* feat(i18n): add delete locale action (#19562)
* chore: pr amends
Co-authored-by: Simone <startae14@gmail.com>
---------
Co-authored-by: Simone <startae14@gmail.com>
* feat(cm): re-implement validation (#19578)
* feat: re-implement validation in the CM
feat: add blocker
feat: handle validation errors from the API
chore: reimplement useFieldHint
test(unit): fix fe tests
chore: fix bad logical operator
* chore: await notifications to leave before trying to go to other pages
* fix: validation issues & blocker showing up incorrectly
* fix: broken publish behaviour
* fix(content-manager): uid availability and generation (#19518)
* fix(content-manager): uid availability and generation
* fix(content-manager): pass locale as is from UID service
* fix(content-manager): match UIDs based on startsWith
---------
Co-authored-by: Marc Roig <marc12info@gmail.com>
Co-authored-by: markkaylor <mark.kaylor@strapi.io>
Co-authored-by: Jamie Howard <48524071+jhoward1994@users.noreply.github.com>
Co-authored-by: Ben Irvin <ben@innerdvations.com>
Co-authored-by: Jamie Howard <jamie.howard@strapi.io>
Co-authored-by: Ben Irvin <ben.irvin@strapi.io>
Co-authored-by: Alexandre Bodin <bodin.alex@gmail.com>
Co-authored-by: Alexandre BODIN <alexandrebodin@users.noreply.github.com>
Co-authored-by: Simone <startae14@gmail.com>
* added first draft for releases scheduling
* update: scheduled date is made Date or nullable, tests updated for scheduling fields
* fix: pass scheduled date null on edit unchecking the option
* fix: dirty check added for disabling save button
* timezone hook added to generate list of timezone options
* update: timezone added in payload to save in DB
* update: removed grouping and sorting of timezones, keeping simple UTC+/-HH:00 <timezone> format
* fix: removing unnecessary code
* update: creating new release should show schedule by default
* minor change
* tests: queryByRole replaced with getByRole query
* update: use date-fns format functions instead of manually formattingdates, future flag added on front for Scheduling till beta release, test cases updated
* fix: comment added
* minor change
* fix: reverting merging change
* fix: scheduledAt and timezone types updated to be null instead of undefined to keep it consistent
* fix: converted utc to zoned time to update correct time on editing the release
* fix: handled validation on submit, always enable submit, timezone list updated based on selected date
* update: default timezone set, tests updated
* update: selecting date during DST updates the timezone selected and list, TS errors fixed
* fix: timezone display value updated
* fix: e2e tests
* update: e2e added for scheduling info
* fix: minor change
* fix: schema validation reverted, tests updated for findBy
* feat(admin): add Auth feature
* refactor: authentication to use redux-toolkit
* chore(admin): convert admin data-fetching to use redux-toolkit-query
* chore: add docs
* fix: default logo would not show on login page
* fix: app flashes on logout
* fix: logout should work across browsers
* refactor(admin): move to use slice over reducer
* refactor(admin): theme into redux
* refactor(admin): remove Admin context
* chore: move api tokens context to its edit view
* chore: move injection zones up to appropriate folders
we never use shared anyway.
* chore: move Configuration to single feature file
* refactor(admin): move language to redux
* chore: add tests for redux slice
* test(content-manager): fix wysiwyg by silencing the warnings
* test(admin): add a harness – finally
* chore: remove prop-types as dep of helper-plugin
* test(content-manager): fix console errors in EditSettingsView
* test(content-manager): fix ListViewSettings
* test: fix useAdminRolePermissions
* chore: convert more tests
* test: more fe tests
* test: more fe tests
* test(ctb): fix tests
* chore: throw error in env
* chore: fix act finals
* chore: remove resetHandlers and use once
* chore: throw all the time for warnings and errors
* overwrite the Authorization header when passed as config
* replace axios call with fetchClient and remove axios cancel from the admin
* replace axios call in the UseCasePage form
* replace axios with useFetchClient inside the App component for the analytics call
* replace axios calls with the post useFetchClient inside the AuthPage
* remove axios instances inside the CollectionTypeFormWrapper and the SingleTypeFormWrapper
* Replace axios call with useFetchClient inside the Register component
* replace axios call with useFetchClient sinde the urlToFile utils
* remove axios instances inside the useFetchContentTypeLayout
* remove axios instances inside the ComponentSettingsView component
* update test urlToFile
* remove axios as dependency in admin and remove cancel token from ListView
* remove axios dependency from the admin
* revert dependency
* replace the downloadFile axios call with getFetchClient
* remove console log
* fix issue if preferedLanguage is null
* replace axios call with getFetchClient inside the urlToAssets utility
* revert back cancel token inside CollectionTypeFormWrapper
* revert cancel token logic
* add the logic to handle paths without prepending slash
* remove tip for the relative path
* move the fetchMarketplaceProviders util inside the useFetchMarketplaceProviders file
* use fetch instead of useFetchClient for external calls
* remove the control of the preferedLanguage inside the Profile page
* move up useFetchClient call
* refactor normalize url
* add mock getFetchClient in FromComputerForm test
* fix check full url
* refactor fetch
* cleanup code
* fix comments
* fix review comments
* refaactor fetch calls and fix types and format code
* add more info in the documentation
* fix unit tests marketplace and add a constants file shared between the two hooks
* change the import order
* refactor hooks returining type
* move whatwg-fetch import inside the admin-test-util and small refactoring
* fix test, remove comments and remove only