Skip to content

emdash

v@emdash-cms/[email protected] Breaking

This release includes 3 breaking changes for platform teams planning a safe upgrade.

Published 15d Productivity & Wikis
✓ No known CVEs patched
Read the diff → Tool health → What is this tool? →

✓ No known CVEs patched in this version

Topics

astro cms emdash typescript

Affected surfaces

breaking_upgrade auth

Summary

AI summary

Updates Minor Changes, Patch Changes, and https://github.com/ascorbic across a mixed release.

Changes in this release

Breaking Medium

POST /menus/:name/items no longer accepts unknown keys silently; returns 400 with unrecognized key errors.

POST /menus/:name/items no longer accepts unknown keys silently; returns 400 with unrecognized key errors.

Source: granite4.1:8b-q6_K@2026-05-19

Confidence: high

Breaking Medium

Legacy query-string item writes removed; use PUT /menus/:name/items/:id and DELETE /menus/:name/items/:id instead.

Legacy query-string item writes removed; use PUT /menus/:name/items/:id and DELETE /menus/:name/items/:id instead.

Source: granite4.1:8b-q6_K@2026-05-19

Confidence: high

Breaking Medium

Menu and menu-item API responses now camelCase, breaking clients expecting snake_case keys.

Menu and menu-item API responses now camelCase, breaking clients expecting snake_case keys.

Source: granite4.1:8b-q6_K@2026-05-19

Confidence: high

Feature Medium

Adds experimental decentralized plugin registry support via `experimental.registry.aggregatorUrl` config.

Adds experimental decentralized plugin registry support via `experimental.registry.aggregatorUrl` config.

Source: granite4.1:8b-q6_K@2026-05-19

Confidence: high

Feature Medium

Experimental config includes `policy.minimumReleaseAge` and `policy.minimumReleaseAgeExclude` for release gating.

Experimental config includes `policy.minimumReleaseAge` and `policy.minimumReleaseAgeExclude` for release gating.

Source: granite4.1:8b-q6_K@2026-05-19

Confidence: high

Feature Medium

Adds Indonesian translations for SEO settings labels, replacing

Adds Indonesian translations for SEO settings labels, replacing

Source: granite4.1:8b-q6_K@2026-05-19

Confidence: low

Bugfix Medium

Admin collection list pagination denominator now uses total filtered count, preventing incremental growth.

Admin collection list pagination denominator now uses total filtered count, preventing incremental growth.

Source: granite4.1:8b-q6_K@2026-05-19

Confidence: low

Bugfix Medium

Image collapsing media picker adds onError handler and fallback placeholder for missing images.

Image collapsing media picker adds onError handler and fallback placeholder for missing images.

Source: granite4.1:8b-q6_K@2026-05-19

Confidence: low

Bugfix Medium

Slash command menu initial selection no longer overridden by stationary pointer; fixes keyboard default handling.

Slash command menu initial selection no longer overridden by stationary pointer; fixes keyboard default handling.

Source: granite4.1:8b-q6_K@2026-05-19

Confidence: low

Refactor Medium

Menus refactored to standard repository pattern with new MenuRepository.

Menus refactored to standard repository pattern with new MenuRepository.

Source: granite4.1:8b-q6_K@2026-05-19

Confidence: low

Full changelog

Minor Changes

  • #1052 0d5843f Thanks @Rimander! - Fixes menu REST API consistency:

    • POST /menus/:name/items no longer accepts unknown keys silently. Sending custom_url (snake_case) or url used to return 201 with custom_url: null because Zod's default .strip() quietly dropped them. The schemas now use .strict() and return 400 VALIDATION_ERROR with Unrecognized key: "custom_url". The documented camelCase keys (customUrl, sortOrder, referenceCollection, etc.) are unchanged and persist as before. The type field is now validated against the canonical enum ("custom" | "page" | "post" | "taxonomy" | "collection"); previously any string passed.
    • Moves per-item writes to PUT and DELETE /menus/:name/items/:id (path-style). Every other EmDash resource (content, taxonomies, redirects, sections, widget-areas) addresses items by URL path; menus were the lone outlier requiring ?id=<id> in the query string. The legacy query-string form is removed (it was undocumented and only used by the admin, which is updated in this PR). Callers should use PUT /menus/:name/items/:id / DELETE /menus/:name/items/:id.
    • Menu and menu-item API responses are now camelCase, aligning with the rest of EmDash's REST surface (content, taxonomies, redirects, …). created_atcreatedAt, updated_atupdatedAt, menu_idmenuId, parent_idparentId, sort_ordersortOrder, reference_collectionreferenceCollection, reference_idreferenceId, custom_urlcustomUrl, title_attrtitleAttr, css_classescssClasses, translation_grouptranslationGroup. Breaking for direct REST consumers that depend on snake_case keys in the response body. The admin UI is already updated.
    • Refactors menus to the standard repository pattern. Adds MenuRepository next to ContentRepository, TaxonomyRepository, RedirectRepository, MediaRepository, CommentRepository. Handlers become thin orchestrators; the repository is now the single place where snake_case rows become camelCase entities.

    These changes do not touch any database schema or migration. Existing data is preserved.

  • #1011 dbaea9c Thanks @ascorbic! - Adds experimental support for the decentralized plugin registry (see RFC #694). Configure with experimental.registry.aggregatorUrl in astro.config.mjs; the admin UI then uses the registry instead of the centralized marketplace for browse and install. Marketplace behavior is unchanged when the option is not set.

    The experimental config accepts a policy.minimumReleaseAge duration (e.g. "48h") that holds back releases below that age from install and update prompts, with a policy.minimumReleaseAgeExclude allowlist for trusted publishers or specific packages. The minimum-release-age check is enforced both client-side (for UX) and server-side (in the install endpoint), so stale browser tabs and deep links still hit the gate.

Patch Changes

  • #751 05440b1 Thanks @edrpls! - Fix the admin collection list pagination denominator so it no longer grows in increments of 5 as the user pages forward.

    The GET /_emdash/api/content/{collection} response now includes a total field with the full filtered row count (independent of limit). The admin uses it as the pagination denominator, so a 143-entry collection reads 1/8 on page 1 instead of 1/5 → 5/10 → 10/15 → … as successive API pages load.

    The total field is optional; pre-upgrade clients that ignore it still work, and the admin falls back to the loaded-item count when an older server doesn't return it.

    Also handles the edge case where the current page exceeds totalPages after filtering or deletion — the admin clamps the active page so the table doesn't render empty while waiting for a refetch.

  • #1050 484e7ab Thanks @wojtekpiskorz! - Fixes broken image collapsing media picker container — adds onError handler and fallback placeholder so Change/Remove buttons remain accessible when referenced image is missing from storage

  • #1013 0cd8c6d Thanks @ascorbic! - Fixes the slash command menu's initial selection getting overridden when the menu opens under a stationary pointer. The menu items previously reacted to mouseenter unconditionally, so an item rendered beneath the cursor would steal selection from the keyboard default before any user interaction. Mouse-hover-selects still works, but only after the user actually moves the pointer over the menu.

  • #1020 d014b48 Thanks @ahliweb! - Adds missing Indonesian (id) translations for SEO settings labels and replaces "Edit" with "Sunting" and "Tagline" with "Slogan" across the admin UI.

  • Updated dependencies []:

Breaking Changes

  • `POST /menus/:name/items` no longer accepts unknown keys silently; now returns 400 `VALIDATION_ERROR` for unrecognized keys.
  • Per‑item writes moved to path‑style endpoints: `PUT /menus/:name/items/:id` and `DELETE /menus/:name/items/:id`; legacy query‑string form removed.
  • Menu and menu‑item API responses switched from snake_case to camelCase (e.g., `created_at` → `createdAt`).

Weekly OSS security release digest.

The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.

No spam, unsubscribe anytime.

Share this release

Track emdash

Get notified when new releases ship.

Sign up free

About emdash

All releases →

Related context

Related tools

Earlier breaking changes

Beta — feedback welcome: [email protected]