v0.0.2-alpha.54
Pre-releaseReleased 18 packages at 0.0.2-alpha.54 in lockstep. Every package below ships at this version.
What's changed
Patch Changes
-
#581
8e75d40Thanks @mobeenabdullah! - Typecheck the block renderer’s own tests, and give block authors a typed defineBlock.The package excluded test files from tsc, so its tests had never been typechecked. Adding a tests project surfaced eleven errors, nine of which shared one cause: the engine types a slot’s output as unknown because it carries no React types, so a block author could not place it in their own JSX without annotating every render by hand.
@nextlyhq/blocks-react now exports its own defineBlock, which names the context and the slot return type. This is the same service the plugin SDK performs for plugin authors, offered to anyone rendering with this package directly.
-
#586
8e81c4fThanks @mobeenabdullah! - Field access rules can ask what the caller is granted, and custom CSS is now a privilege.A field's
access.create/access.read/access.updatefunction now receives
permissionsandrolesalongsidereq, so a field can be gated on a permission
rather than only on a role. Collection-level access already received these; field
level did not, so "only these people may write this field" was not expressible.
The grants are resolved once per operation and only when a rule actually runs, so
an entity with no field rules makes no extra lookup. A rule that cannot read the
grants denies rather than opens.permissionsuses the sameresource:actionspelling collection-level access
uses. Note this differs from theaction-resourceform the database and the
admin's permission matrix show for the same row.The page builder's per-page and per-block custom CSS now requires a new
write-builder-custom-csspermission. Without it the CSS already on a page stays
visible and keeps applying, but cannot be changed — the field is dropped from the
write rather than the write being rejected, so everything else on the page saves
normally. Grant it to any role that should keep authoring custom CSS. -
#578
a363c67Thanks @mobeenabdullah! - Add nine core block primitives.Heading, text, list, quote, image, button, spacer, divider and embed join the containers already in the library, which is enough to build a real page. Each is a single element with no wrapper, no default padding and no hardcoded colour: styling belongs to the style system.
The accessibility contracts are part of the blocks rather than left to the author. A heading renders the level the author chose rather than one derived from nesting, so the page outline does not change when a block moves. A button renders an anchor when it has a destination and a button when it does not. An image always emits alt text, empty when it is decorative. A quote keeps its attribution outside the quotation. An embed is sandboxed, carries a title, and does not leak the page path to the embedded party.
-
#585
c2ca409Thanks @mobeenabdullah! - Let each block claim its own DOM id at render, instead of reserving ids in advance.Which node ends up writing an id is only knowable once a block has run: one that throws, or returns something with no host root, is replaced by a placeholder that emits no id at all. Reserving ids before rendering therefore meant a block that later failed had already taken the id, and the healthy node that wanted it rendered without one in exchange for nothing.
Node ids are still made unique before rendering. Those are React keys, and a duplicate makes React reuse one block’s instance for another, which is a wrong page rather than a missing anchor.
-
#394
2892263Thanks @faisal-rx! - Fix localized entities breaking schema applies and singles reads: SQLite/MySQL schema syncs no longer fail once a_localestable exists, singles created in another dev worker resolve without a restart, enabling Internationalization without alocalizationconfig is rejected with a clear error (and the builder switch explains it), and adding thelocalizationblock to nextly.config now takes effect without a manual restart in dev.Collection and single tables created on SQLite or MySQL from now on also get the indexes Postgres and the Schema Builder already created for them, including the unique index on
slug. Creating an entry with an explicit slug that another entry already uses now fails with a duplicate error on those dialects instead of being accepted silently. Tables created before this release keep the shape they were created with and are not backfilled, so an existing collection continues to allow duplicate slugs until its table is rebuilt. -
#595
8b7ce78Thanks @mobeenabdullah! - Report the class library slot that was dropped when the same class is listed twice. Only the first of two entries claiming one id or one name is written, and the warning explaining that named the entry rather than the slot — so a library built by reference, with one object in two slots, reported nothing at all and left an editor with no position to repair. -
#584
f7229c8Thanks @mobeenabdullah! - Refuse a plugin permission that collides with one a collection or single already owns, including for Schema Builder entities the config cannot see and for declarations that differ only in letter case. Honouring such a declaration hands the plugin a permission the role presets grant to editors, so the collection quietly stops being editable by them. An application already running such a plugin can set NEXTLY_ALLOW_PLUGIN_PERMISSION_OVERRIDE=1 to keep booting with a warning while it is fixed. -
#576
8ff9c59Thanks @mobeenabdullah! - Resolve a scoped preview link by the entry it names.A preview grant that names an entry is now read by that id and confirmed to live at the requested path, instead of resolving the path by slug and comparing ids afterwards. A slug is not unique, so the old order could find a different document, reject it, and fall back to published, showing an editor live content at a link they were given for a draft.
When the named entry is gone or lives at another path, the request holds no draft authorization for that path and resolves published-only, so the widened lifecycle scope cannot surface a row the grant never named.
-
#583
e7e51d9Thanks @mobeenabdullah! - Add the admin side of shareable preview links.A
previewLinkApiservice and ausePreviewLinkhook mint a link for one entry and put it on the clipboard. This is distinct from the Preview button beside it: Preview opens the entry using the editor’s own session and can include unsaved changes, while a preview LINK goes to someone with no session at all, so it carries its own signed authorization and shows only what was saved.The link is minted per click rather than cached, because it carries an expiry and a cached value would be handed out after it stopped working. When the browser refuses clipboard access, which happens on an insecure origin, the link is shown rather than a copy being claimed that never happened.
-
#580
fdefbe2Thanks @mobeenabdullah! - Add endpoints for minting and revoking preview links.POST /api/nextly/preview-linksmints a link scoped to one entry, gated onupdatefor that collection rather than onpublish: someone who can edit an entry already sees its draft, so sharing a link to it grants nothing new, while requiringpublishwould break the workflow where an editor who cannot publish shows a draft to a reviewer.POST /api/nextly/preview-links/revokeinvalidates every link ever issued, including sessions already in flight. It is gated onmanage settings, because the generation it moves is site-wide.The mint returns a token rather than a URL, since where the preview route is mounted is the application’s decision.
-
#579
5bf444eThanks @mobeenabdullah! - Stop shipping CSS compiled for blocks that render a placeholder.A node that resolves to a placeholder emits only a hidden marker, so every rule compiled for the markup it would have rendered matches nothing and ships anyway, carrying whatever those rules referenced. The stylesheet is now compiled from a tree with those nodes removed, while the render keeps them so their placeholders still appear.
-
#594
5a0c8f6Thanks @mobeenabdullah! - Add the stylesheet a whole site shares, compiled once from its design tokens, self-hosted fonts, named classes and block-type defaults, and named by a hash of the bytes it produced. Every page of a site repeats those rules today; a shared sheet is written once and cached until something in it actually changes. A token stored without any values is now reported and skipped rather than ending the compile, which would otherwise have taken down every page on the site. -
a323af5Thanks @mobeenabdullah! - Hold a conditionally-shown block's own styles out of the page stylesheet, returned separately so a reader can add back only the blocks it kept. A page's CSS is compiled when the document is saved and a condition is decided when the page is read, so one stylesheet otherwise carries rules — and any image URLs inside them — for blocks the reader removes. A page with no conditional blocks compiles exactly as before.
Packages
@nextlyhq/adapter-drizzle@nextlyhq/adapter-mysql@nextlyhq/adapter-postgres@nextlyhq/adapter-sqlite@nextlyhq/admin@nextlyhq/admin-css@nextlyhq/blocks-engine@nextlyhq/blocks-react@nextlyhq/plugin-form-builder@nextlyhq/plugin-page-builder@nextlyhq/plugin-sdk@nextlyhq/plugin-seo@nextlyhq/storage-s3@nextlyhq/storage-uploadthing@nextlyhq/storage-vercel-blob@nextlyhq/uicreate-nextly-appnextly