Convert the docs Docusaurus config files to TypeScript to match the
modern Docusaurus scaffold and give editors correct per-file types:
- docusaurus.config.js -> .ts (typed Config / Preset options, ESM)
- sidebars.js -> .ts (typed SidebarsConfig)
- remark-design-system-links.js -> .ts (typed Transformer<Root>)
- babel.config.js: ESM export, @docusaurus/babel preset (3.x split)
- add docs/tsconfig.json extending @docusaurus/tsconfig (editor-only,
not used by docusaurus build)
- add @docusaurus/babel, @docusaurus/tsconfig, @types/mdast deps
Also adds "docs" to the root jsconfig.json excludes, since docs is a
standalone Docusaurus project that now owns its own config.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Ben Irvin <ben.irvin@strapi.io>
* fix(i18n): preserve non-localized field inheritance across unsaved locale revisits
* fix(content-manager): sort availableLocales with the default locale first
* fix(content-manager): align non-localized prefill filter with server semantics
* fix(i18n): e2e tests
* fix: add missing translation, remove non existing ones and translate existing ones
* chore: reverse changes in admin/es
* fix: fix tab issue in i18n/admin/src/translations/en.json
* fix(i18n): restore author es.json after merge conflict resolution
Remove AI translation keys that were incorrectly merged into i18n es.json;
keep the author's intended i18n plugin Spanish changes from the original PR.
* fix(i18n): align locale hint key and trim translation scope
Use the canonical name.description hint id in CreateLocale, restore
develop ES strings instead of rewritten copy, migrate hint text to the
new key for locales that only had the legacy id, and drop the EN
locales.label entry that changed the picker label and broke E2E tests.
---------
Co-authored-by: Ben Irvin <ben@innerdvations.com>
* Use query builder init in deleteMany
* test(api): deleteMany respects filters combined with relation
* fix(database): pick filter params in deleteMany init
Apply _q, where, and filters through init like count instead of where-only
or full findMany params, avoiding populate/pagination surprises. Expand API
and unit tests for relation filters, count parity, and ignored param keys.
* chore(database): clarify deleteMany relation cleanup TODO
Replace the vague bulk-query TODO with a concrete note that deleteMany
still skips per-row deleteRelations unlike single delete().
---------
Co-authored-by: Ben Irvin <ben.irvin@strapi.io>
Co-authored-by: Ben Irvin <ben@innerdvations.com>
* fix(homepage): homepage count-documents slow on large D&P tables
* chore: add api test
* test(homepage): add i18n count-documents document_id semantics tests
Assert per-document_id buckets for never-published multi-locale drafts,
partial locale publish states, and mutually exclusive published vs modified.
---------
Co-authored-by: Ben Irvin <ben@innerdvations.com>
* chore: fix dependabot cooldown config for github-actions
Remove unsupported semver cooldown fields from the github-actions
ecosystem entry; only default-days is valid for that ecosystem.
* chore: comments
* feat(admin): add documentation helper link in HeaderLayout
Revival of #23328 (by @Mcastres), rebased on develop with review feedback
addressed and additional improvements:
- Replace hand-rolled find with react-router matchRoutes for proper path
matching and specificity ranking
- Update doc URLs to canonical docs.strapi.io paths (drop redirected
/user-docs/* and /dev-docs/* entries)
- Restore section anchors that were lost during doc-site reorganization
(#providers, #email-templates, #advanced-settings, profile, rbac)
- Align array path entries with actual registered admin routes (rename
/plugins/content-type-builder, /plugins/content-releases, settings
prefix for purchase-content-releases and list-plugins, drop dead
/marketplace external link)
- Add opt-out flag admin.flags.docLinks for white-label deployments
(requested by @derrickmehaffy)
- Memoize getMatchingDocLink result per pathname
- Place doc link button next to primary action via gap on parent Flex
(per @remidej review)
- Drop async from getMatchingDocLink, derive docLink synchronously from
pathname (per @remidej review)
Closes#23328
Co-authored-by: Maxime Castres <17828745+Mcastres@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore(admin): move DocLink type to getMatchingDocLink module
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(admin): add docLinks flag to EE Window strapi type
The EE admin custom.d.ts redeclares window.strapi.flags and was missing
the docLinks property, causing test:ts:front to fail with TS2339 in
HeaderLayout.tsx.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* test: add getMachingDocLink tests
---------
Co-authored-by: Maxime Castres <17828745+Mcastres@users.noreply.github.com>
Co-authored-by: Ben Irvin <ben@innerdvations.com>
Replace GitHub's npm_and_yarn mega-PR with per-family security groups,
re-enable throttled version updates with cooldowns, and expand dependency
families for webpack, vite, rollup, and related tooling.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix: unable to access content manager page with required and private field
* fix: unable to access content manager page with required and private field
* test(content-manager): cover private field exclusion in validation populate
Extend getPopulateForValidation tests for top-level scalars, media, and
dynamic zones so private required attributes stay out of query fields.
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: Ben Irvin <ben@innerdvations.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
* feat(provider-amazon-ses): replace node-ses with AWS SDK SESClient
Signed-off-by: Sjouke de Vries <info@sdvservices.nl>
* feat(provider-amazon-ses): harden AWS SDK v3 provider implementation
Extract config and send mapping to utils, create SESClient once in init,
and preserve legacy providerOptions (key, secret, amazon → endpoint/region).
Add Vitest config for unit tests.
Co-authored-by: Cursor <cursoragent@cursor.com>
* docs(provider-amazon-ses): expand configuration examples for IAM and legacy
Adapted from https://github.com/strapi/strapi/pull/25354 (addresses #22600).
Co-authored-by: Frank Navarrete <hippiewho@yahoo.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
* test(provider-amazon-ses): add legacy and send coverage from community PR
Port init and send scenarios from https://github.com/strapi/strapi/pull/25354
to Vitest (*.vitest.test.ts).
Co-authored-by: Frank Navarrete <hippiewho@yahoo.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
* chore: yarn.lock
* test: add backwards compatibility coverage
* chore: remove author info from package.json and update test script names for consistency
---------
Signed-off-by: Sjouke de Vries <info@sdvservices.nl>
Co-authored-by: Ben Irvin <ben@innerdvations.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Frank Navarrete <hippiewho@yahoo.com>
Co-authored-by: Jamie Howard <jhoward1994@gmail.com>
Co-authored-by: Jamie Howard <48524071+jhoward1994@users.noreply.github.com>
* Run batches of document_id creation
* fix(core): use better caching in discard-draft
* fix(core): improve batch sizing & document_id loop efficiency // more caching improvements
* fix(core): componentHierarchyCaches moved back outside the loop
* test(migrations): add new tests and update existing
---------
Co-authored-by: Ben Irvin <ben.irvin@strapi.io>
Co-authored-by: Ben Irvin <ben@innerdvations.com>
* fix(admin): redirect active tab to login on session expiry
Two complementary changes that close the gap between server-side session
invalidation and client-side UX, fixes#26163:
1. **Active-tab redirect on 401.** baseQuery's 401 handler now invokes a
session-expired callback in addition to dispatching `logoutAction`.
AuthProvider registers `clearStateAndLogout` as that callback so the
tab that originated the failing request is navigated to /auth/login —
not just other tabs (which already react via the `storage` event).
2. **JWT-exp idle timer.** AuthProvider schedules a one-shot timer at the
access token's `exp` claim. While the user is active, every API call
that hits a 401 transparently refreshes the token (existing behavior in
getFetchClient.withTokenRefresh), which updates Redux and reschedules
the timer to the new exp. If no API activity occurs during the access
token lifespan, the timer fires and the user is logged out — matching
the configured server-side idle behavior without a separate activity
tracker.
The mechanism is wired through a new `setOnSessionExpired` /
`triggerSessionExpired` pair in getFetchClient.ts (mirroring the existing
`setOnTokenUpdate` registry), keeping the React layer as the only place
that owns navigation.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(admin): extract idle-session logout into testable hook
Per review feedback, move the JWT exp decoding into utils/jwt.ts and
the one-shot logout effect into a useIdleSessionLogout hook so both
have unit coverage. Hardens the decoder with type checks, base64url
padding, and a Number.isFinite guard on exp.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(admin): gate expiresIn deprecation on user auth options
getTokenOptions merges defaultJwtOptions, so options.expiresIn is always
set even when the project never configured admin.auth.options.expiresIn.
That made the bootstrap deprecation warn on every startup.
Read raw admin.auth.options via a small helper next to the token service
and cover it with unit tests.
Refs https://github.com/strapi/strapi/issues/25989
* chore: prettier
---------
Co-authored-by: Ben Irvin <ben@innerdvations.com>
* fix: move session-manager jwt check from register to bootstrap
* fix: drop serveAdminPanel guard from session-manager bootstrap
detached-admin deployments still need jwt validation at startup.
the move from register to bootstrap alone is sufficient to fix
cli commands like ts:generate-types since they never call bootstrap.
---------
Co-authored-by: Jamie Howard <48524071+jhoward1994@users.noreply.github.com>
* Filter for published results when requesting localizations
* fix(graphql): inherit publication state for i18n localizations
---------
Co-authored-by: Bassel Kanso <basselkanso82@gmail.com>
The discard-drafts migration crashes when processing morphToMany
relations because it accesses `joinTable.inverseJoinColumn.name`
in 7 locations without checking if `inverseJoinColumn` exists.
Morph join tables (polymorphic relations) use `morphColumn` instead
of `inverseJoinColumn`. Accessing `.name` on `undefined` throws:
`TypeError: Cannot read properties of undefined (reading 'name')`
This affects any v4→v5 migration on projects with morphToMany
relations (e.g., polymorphic content types, dynamic zones with
relations).
The fix adds a null guard before each access, skipping morph tables
which don't need the draft/published copy logic handled by these
functions.
Fixes#25542