Minor Changes
-
#978
27e6d58Thanks @ascorbic! - Enforces the sandboxed plugin bundle size caps from RFC 0001 §"Bundle size limits" in both thebundleandpublishCLI flows: total decompressed ≤ 256 KB, per-file decompressed ≤ 128 KB, and at most 20 files per bundle. The previous bundle command capped only the total at 5 MB; the publish command now also re-validates the decompressed tarball before signing the release record so a publisher hits the same cap locally that aggregators enforce at ingest. Bundles between 256 KB and the old 5 MB ceiling will now be rejected — usually a sign the plugin is bundling host-provided dependencies or assets that belong in a CDN rather than the plugin payload. -
#942
7c536e5Thanks @MA2153! - Adds per-field allowed MIME types forfileandimagefields. Field-levelallowedTypesis now honored end-to-end: it filters the media picker, widens upload acceptance for that field (so e.g. a zip-only field can accept zip uploads even though the global allowlist excludes them), and validates referenced media against the destination field on content save. The schema editor in admin gains an "Allowed types" control with curated presets and freeform entry.Behavior change: the
imagebuilder'sallowedTypesoption was previously accepted but read by nothing. It is now load-bearing — a code-first schema that already passedallowedTypes(e.g.["image/png"]) will now actually narrow the picker and gate uploads. Most users will see no change; if you set this option intending the old (silent) behavior, drop it.Behavior change: updating a field via the admin schema editor now explicitly clears its validation when the form contains no validation settings, instead of leaving an existing
validationvalue intact. This only affects fields with pre-existing validation that is not expressible in the editor UI.
Patch Changes
-
#893
f8ee1edThanks @j-liszt! - Enhances Passkey authentication with polymorphic algorithm support. Adds support for RS256 (RSA) alongside the existing ES256 (ECDSA) implementation, ensuring full compatibility with Windows Hello, hardware security keys, and FIDO2 standards. Includes a database migration to track and persist credential algorithms for future-proof authentication.Note for standalone
@emdash-cms/authconsumers: If yourcredentialstable already exists, you must manually runALTER TABLE credentials ADD COLUMN algorithm INTEGER NOT NULL DEFAULT -7to support this update. TheDEFAULT -7value ensures that existing rows (which are all ES256) continue to work seamlessly without requiring any data backfill. -
#976
4c11017Thanks @ask-bonk! - Fixes migration016_api_tokensfailing withtable "_emdash_api_tokens" already existsafter a partially-applied previous attempt. Ifup()crashed mid-way (D1 subrequest limit, isolate cancellation, transient connection error), the migration record never got recorded and Kysely re-ran the migration from the top on the next request, blocking every subsequent boot.up()now usesIF NOT EXISTSon every CREATE so a retry skips already-applied steps and finishes the remainder. Resolves the "table already exists" error reported on fresh Cloudflare Workers + D1 deploys. -
#939
f1d4c0bThanks @schiste! - Make the MCP menu write tools locale-aware by exposinglocaleonmenu_create,
menu_update,menu_delete, andmenu_set_items, exposingtranslationOfon
menu_create, and teachinghandleMenuSetItems()to target the requested locale
and tag inserted menu items with that menu's locale.All seven menu-name lookups (
handleMenuUpdate,handleMenuDelete,
handleMenuSetItems,handleMenuItemCreate,handleMenuItemUpdate,
handleMenuItemDelete,handleMenuItemReorder) now fail loud with the new
AMBIGUOUS_LOCALEerror code (HTTP 400) when called with anamethat exists
in multiple locales and nolocaleis provided. Previously the lookup silently
picked an arbitrary translation, which could rewrite or delete the wrong
locale's menu on multi-locale installs. The error message lists the available
locales so callers can recover. Single-locale installs and callers that already
passlocaleare unaffected.The
translationOf→localerequirement is now enforced inside
handleMenuCreate(returnsVALIDATION_ERROR), so REST/SDK callers get the
same guard the MCP boundary already provided. -
d273e9aThanks @ascorbic! - Refactors the plugin manifest types to re-export from@emdash-cms/plugin-types. The capability vocabulary (PluginCapability,CAPABILITY_RENAMES,normalizeCapability,isDeprecatedCapability) and manifest shape (ManifestHookEntry,ManifestRouteEntry,PluginStorageConfig,StorageCollectionConfig) now live in the shared package so the registry CLI can write the same types core reads. Existing imports fromemdash's plugin types module continue to work unchanged. -
#943
514d32dThanks @Rimander! - Fixes seed menu items losing theirtranslation_groupacross export/apply by adding optionalid,locale, andtranslationOffields toSeedMenuItem. The export emits stable seed IDs andtranslationOfreferences; the apply resolves them to the anchor'stranslation_group, matching the existing pattern for content entries, taxonomies, and terms. -
#948
8116949Thanks @ascorbic! - Adds always-ondb.*andcache.*Server-Timing fields so render-phase performance is diagnosable in production. Each request now emitsdb.total(cumulative DB ms),db.count(query count),db.first/db.last(first/last query offset from request start), andcache.hit/cache.miss(request-scoped cache stats). The Kysely log hook is now always installed so counters work without settingEMDASH_QUERY_LOG. -
#946
c4ee7adThanks @LeanderG! - Fixes Postgres rate-limit queries by quoting the reservedwindowcolumn name. -
Updated dependencies [
7f6b6ea,131bea6,f8ee1ed,54b5aa1,c630e31,7c536e5,7aa1897,943df46,0b8a319,13ff061,49b66d9,1b2fa77,530b013,af15975,a4968c1,f80fb58]:- @emdash-cms/admin@0.11.0
- @emdash-cms/auth@0.11.0
- @emdash-cms/plugin-types@0.0.1
- @emdash-cms/auth-atproto@0.2.3
- @emdash-cms/gutenberg-to-portable-text@0.11.0