Skip to content

emdash

v@emdash-cms/[email protected] Feature

This release adds 2 notable features for engineering teams evaluating rollout.

Published 5h 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

Summary

AI summary

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

Changes in this release

Feature Medium

Adds custom fields to bylines via /byline-schema admin screen.

Adds custom fields to bylines via /byline-schema admin screen.

Source: llm_adapter@2026-06-03

Confidence: high

Feature Medium

Introduces first-class HTML block in admin editor for raw HTML editing.

Introduces first-class HTML block in admin editor for raw HTML editing.

Source: llm_adapter@2026-06-03

Confidence: high

Feature Medium

Adds search to byline picker and removes 100‑byline cap.

Adds search to byline picker and removes 100‑byline cap.

Source: llm_adapter@2026-06-03

Confidence: high

Feature Medium

Enables server‑side search for admin content list across large collections.

Enables server‑side search for admin content list across large collections.

Source: llm_adapter@2026-06-03

Confidence: high

Feature Medium

Adds search and filtering to media library by filename and MIME type.

Adds search and filtering to media library by filename and MIME type.

Source: llm_adapter@2026-06-03

Confidence: high

Feature Low

Pins rich‑text editor formatting toolbar to top while scrolling long posts.

Pins rich‑text editor formatting toolbar to top while scrolling long posts.

Source: llm_adapter@2026-06-03

Confidence: high

Dependency Low

Updated dependencies: @emdash-cms/[email protected], @emdash-cms/[email protected].

Updated dependencies: @emdash-cms/[email protected], @emdash-cms/[email protected].

Source: llm_adapter@2026-06-03

Confidence: high

Performance Medium

Debounces byline search box (300 ms) to improve responsiveness.

Debounces byline search box (300 ms) to improve responsiveness.

Source: llm_adapter@2026-06-03

Confidence: high

Bugfix Medium

Fixes content entity editor block menu actions (Duplicate / Delete) failing with NodeSelection.

Fixes content entity editor block menu actions (Duplicate / Delete) failing with NodeSelection.

Source: llm_adapter@2026-06-03

Confidence: high

Bugfix Medium

Makes taxonomy terms locale‑aware in the content editor.

Makes taxonomy terms locale‑aware in the content editor.

Source: llm_adapter@2026-06-03

Confidence: high

Full changelog

Minor Changes

  • #1258 28432b9 Thanks @MohamedH1998! - Adds custom fields to bylines. Sites can define site-specific byline metadata (Twitter handle, pronouns, company, localised job title, etc.) via the new /byline-schema admin screen, accessed from the Byline schema link button at the top of the Bylines admin page (admin-only).

    Per-field translatable flag picks whether values are stored per-locale (one value per locale row in a translation_group) or shared across every locale variant of the same byline identity. Schema management is gated by schema:manage; value editing by bylines:manage.

    Custom-field values can be set at both create and update time. POST and PUT on /_emdash/api/admin/bylines accept the same customFields map; the row write and the custom-field writes share a single transaction on Node/PG so a partial failure rolls both back. On D1 (no transactions), a retry POST is treated as completing an abandoned create iff three checks all pass: (a) every fixed column on the existing row matches the new payload (displayName, bio, avatarMediaId, websiteUrl, userId, isGuest, effective locale — null-vs-undefined normalised); (b) the existing row's translationGroup matches what a fresh create with the same input would produce (sourceGroup when translationOf is present, existing.id when it isn't); (c) every custom-field value already stored on the row appears in the input payload with an equal value (subset-match, so partial mid-loop crashes can be completed). The recovery branch is conservative on every axis: any fixed-column mismatch, any translation-group mismatch, any overlapping custom-field value mismatch, an input that omits a key the existing row stores, or an input with no custom fields at all → standard CONFLICT. Validation runs before any DB write so a bad value (unknown slug, type mismatch, select-choice miss, non-URL or non-http(s) URL for a url field) returns 400 VALIDATION_ERROR without leaving partial state behind. In the admin, registered fields render inline with Name, Bio, etc. — no separate section header — and are available in the New byline dialog as well as edit.

    BylineSummary gains an optional customFields: Record<string, CustomFieldValue> property. Existing object-literal consumers stay source-compatible because the property is optional and runtime always returns {} when no fields are registered.

    Hydration is symmetric with writes: rows are only applied to a byline when they live in the table matching the field's current translatable flag, so stale rows from a translatable flip can't leak into hydrated output. Schema mutations on /byline-schema invalidate the same byline-fields query the byline form reads, so newly-registered fields appear in the editor without a page reload. url field values are parsed with new URL(...) AND restricted to http: / https: schemes at write time so they can't ship javascript: / data: / mailto: payloads to link rendering. The BylineFieldEditor "Save" button stays disabled until a select field has at least one option; and select-option lists are accumulated on a null-prototype object so option values that collide with Object.prototype keys render correctly.

    The field-definitions cache uses parity on options.byline_fields_version as a dirty bit: schema mutations flip the counter to odd before the write lands and to a new even value after, with the cache treating any odd version as "bypass the global holder, read fresh from the DB". markVersionDirty is parity-aware (ensures odd, no-op if already odd) so a crashed prior attempt's leftover dirty state can't get inverted. markVersionClean is always-advance (+2 when starting even, +1 when starting odd) so two concurrent mutators can't collapse on the same even key and pin the cache on a partial-set snapshot — every committed mutation produces an observable counter change for cache readers. Idempotent-retry exits (FIELD_EXISTS on create, FIELD_NOT_FOUND on update/delete, no-op input on update) call markVersionClean too, which doubles as both the dirty-crash recovery and the false-clean recovery. All version writes use INSERT … ON CONFLICT DO UPDATE so a missing options row can't silently turn invalidation into a no-op.

    Implements #1174. Builds on the bylines-i18n foundation from #1146.

  • #1215 590b2f9 Thanks @scottbuscemi! - First-class HTML block in the admin editor. The existing htmlBlock Portable Text type (produced by the WordPress and Contentful importers) is now a fully editable block in the rich-text editor. Authors can insert an HTML block via the /html slash command and edit raw HTML in a textarea. Imported htmlBlock content that previously fell through to an opaque pluginBlock placeholder is now rendered in the same editable UI. The inline (visual-editing) editor preserves HTML blocks as read-only placeholders to prevent data loss.

Patch Changes

  • #1297 cccf4f2 Thanks @emdashbot! - Fix content entity editor block menu actions (Duplicate / Delete) not working when the drag handle sets a NodeSelection (#1261).

  • #1225 886f2d1 Thanks @scottbuscemi! - Add search to the byline picker on content entities and remove the effective 100-byline cap. The picker now performs a debounced server-side search via the bylines API instead of rendering a fixed dropdown of the first 100 results, so bylines beyond the first page can be found and credited. Credited bylines from the saved entry are also resolved from the entry itself, so a credit that falls outside the initial list still renders its name instead of disappearing.

  • #1222 a5dafb3 Thanks @scottbuscemi! - Fixes the byline search box reloading the whole page on every keystroke. The search term is now debounced (300ms) before it feeds the bylines query, and the full-page loader only takes over when there is no data yet (isLoading && !data) instead of on every new query key. Typing now stays responsive and keeps the input focused, matching the behaviour of the users page. The load-more snapshot and its filter-match check both use the debounced search value so appended pages are no longer discarded.

  • #1226 9422d6a Thanks @scottbuscemi! - Make content list search work on large collections (#1219). The admin content list previously filtered only the rows already loaded on the current page, so an entry far back in a big collection could not be found until you navigated near it. The list endpoint now accepts a q parameter and performs a case-insensitive substring search across the collection's title/name/slug columns server-side (LIKE wildcards in the query are escaped), and the admin search box drives that query (debounced) instead of filtering in memory. Also adds locale-aware composite indexes (idx_{table}_loc_upd / idx_{table}_loc_crt) so locale-filtered content lists stay index-served on large, i18n-enabled tables.

  • #1224 67f5992 Thanks @scottbuscemi! - Fix taxonomy terms not being locale-aware in the content editor (#1218). Term assignments are stored against the per-locale content row while the term's translation_group spans every locale, so resolving terms for an entry must scope to the entry's locale. The content terms endpoint (/content/:collection/:id/terms/:taxonomy) now derives the entry's locale server-side and passes it to getTermsForEntry, and the admin TaxonomySidebar threads the entry locale through its fetch/save calls (and into its React Query keys, so switching translations refetches). Previously a localized post showed and applied every locale variant of a tag instead of just the variant for its own locale.

  • #1227 a40e455 Thanks @scottbuscemi! - Add search and filtering to the media library (#1221). The media list endpoint now accepts a q parameter for a case-insensitive filename substring search (which also matches extensions, with LIKE wildcards escaped), alongside the existing mimeType filter. The Media Library page gains a filename search box and a type filter (images / video / audio / documents), and the media picker in the content editor now searches the local library by filename too. Previously neither surface could search or filter local media, which made large libraries hard to navigate.

  • #1223 34afc14 Thanks @scottbuscemi! - The rich-text editor formatting toolbar now stays pinned to the top of the editing area while scrolling through long posts, instead of scrolling out of view. The toolbar uses position: sticky and the editor wrapper switched from overflow-hidden to overflow-clip so corners stay clipped without creating a nested scroll container that would break sticky positioning. Distraction-free / minimal editors (e.g. Widgets) are unaffected since they don't render the toolbar.

  • #1309 019d9e4 Thanks @ahliweb! - Fix the remaining Indonesian admin translations.

  • #1310 ba0f3d4 Thanks @emdashbot! - Fix "Add Content" in the menu editor: the admin was sending the raw collection slug (e.g. pages) as the menu item type, which the API's menuItemTypeEnum rejects with a 400. Map the picker's collection to the correct enum value (pagespage, postspost, everything else → collection) so picking a page or post actually adds it to the menu. (#1173)

  • #1290 aacdf20 Thanks @SL33PiNg! - i18n(th): translate remaining untranslated Thai (ไทย) admin UI strings, including the newly-added plugin registry and Portable Text HTML-block strings

  • #1245 7d55db6 Thanks @SL33PiNg! - Adds Thai (ไทย) locale to the admin UI.

  • Updated dependencies [69bdc97]:

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]