Skip to content

v0.0.2-alpha.57

Pre-release
Pre-release

Choose a tag to compare

@mobeenabdullah mobeenabdullah released this 13 Aug 02:48
· 668 commits to main since this release
03edc5c

Released 19 packages at 0.0.2-alpha.57 in lockstep. Every package below ships at this version.

What's changed

Patch Changes

  • #714 5673fff Thanks @mobeenabdullah! - The admin now ships with rounded corners and the Geist typeface. Corner radius comes from a single --radius knob, so changing that one declaration re-rounds the whole panel, and a plugin built against the published Tailwind preset re-rounds with it.

  • #699 6936078 Thanks @mobeenabdullah! - Add an experimental BreakpointDialog to @nextlyhq/ui, with the validation behind it. The style compiler discards a breakpoint it cannot use rather than raising, so a bad definition is lost silently and surfaces later as stale styles; the dialog refuses to save any set that would lose one.

  • #728 38e5e6b Thanks @mobeenabdullah! - move the breakpoint editor into the builder, where its rules can be derived

    lib/breakpoints.ts and breakpoint-dialog.tsx restated the style compiler's
    breakpoint drop rules because @nextlyhq/ui is the block-agnostic layer and
    cannot depend on @nextlyhq/blocks-engine. Two implementations of one rule
    agree the day they are written and drift silently after.

    They now live in @nextlyhq/builder, which already depends on the engine and
    imports MAX_BREAKPOINTS_PER_AXIS and the breakpoint types from it rather than
    mirroring them.

    Breaking, and deliberate: the @nextlyhq/ui/breakpoints subpath is removed,
    along with BreakpointDialog and the breakpoint types from the root barrel.
    Nothing in this repository imported them, and every affected export was
    @experimental.

  • #683 5bfac2f Thanks @mobeenabdullah! - Add the builder's host-canvas coordinate mapping: one module converts between the canvas frame and the host page, including the scaled border inset that places the frame's content origin. A sibling test scans for cross-frame rectangle reads elsewhere in the package, recognising a bounded set of spellings; it narrows the paths taken by accident rather than enforcing single ownership.

  • #717 5a05e7b Thanks @mobeenabdullah! - Add an experimental ColorPicker to @nextlyhq/ui, with the pointer-to-colour geometry behind it on the server-safe @nextlyhq/ui/color entry. The picker knows nothing about design tokens: a swatch carries an opaque value it hands back untouched, so a host storing a token reference keeps it rather than receiving the colour that token happened to resolve to.

  • #713 dbd95b3 Thanks @mobeenabdullah! - Erase a recipient from the email delivery log.

    Deleting a user left their delivery rows behind carrying a keyed hash of their
    address, which an install holds the key for, so the table went on answering
    "was this person written to, and when" for an account that no longer exists.
    eraseRecipientDeliveries overwrites that hash with a value no address can
    produce, keeping the row, its status and its timing so aggregate questions
    still have an answer. deleteUser calls it inside its existing transaction, so
    a failed erasure takes the deletion with it rather than leaving the two out of
    step.

    The erasure takes an ADDRESS rather than a user id, because most recipients
    never had an account: a password reset to an address that never registered, a
    CC, a BCC added by a beforeSend filter. Those people can ask to be erased too
    and no account deletion will ever fire for them, so it is callable directly.

    EmailDeliveryRecord.recipientHash is now string | null, where null means
    erased.

  • #734 193d5ec Thanks @mobeenabdullah! - Advertise the Node range this project actually supports. Every package declared
    >=20.0.0 while the repository requires ^20.19.0 || ^22.12.0 || >=24.0.0, so
    installs on 20.6-20.18 or on 23.x succeeded without warning and failed later at
    runtime. Release preflight now derives the expected range from the root manifest
    and rejects a package that disagrees, so the two cannot drift apart again.

  • #722 696281d Thanks @mobeenabdullah! - Field group instances now report their stored type through nextly/field-group-type, a new entry point that reads whichever spelling a document carries and writes the current one. The admin editor uses it, so content saved before and after the storage rename stays readable and selectable in both.

  • #700 cf04a67 Thanks @mobeenabdullah! - Correct the frame content origin to include the iframe's padding, and measure that inset in one place.

    An iframe's nested viewport begins at the content box, so padding displaces it exactly as a border does. Callers built the inset from clientLeft/clientTop, which report the border alone, so every frame-local point mapped toward the border by the scaled padding. frameInsetOf is now exported as the single reader, and both the README recipe and the FrameGeometry documentation name it instead of restating arithmetic three call sites had already got wrong.

  • #689 213a860 Thanks @mobeenabdullah! - Admin list pages now attach their pagination to the table it belongs to, instead of leaving it floating a row below the table on some pages and attached on others. Applies to users, plugins, roles and webhook endpoints.

  • #725 73885c6 Thanks @mobeenabdullah! - The field-group storage migration can now report what it would rename without changing any content or recording that a run happened, and refuses to run for real unless the caller states that a restorable backup exists. A preview still claims the migration lock, so it needs a role that can write to Nextly's own lock table.

  • #719 f61172e Thanks @mobeenabdullah! - A stylesheet stored for a page is no longer reused when a block migration has
    since turned one of its nodes into one that renders nothing. The rules compiled
    for that node, and any image the rules fetched, were still being served for
    markup no visitor receives.

  • #730 6683ef3 Thanks @mobeenabdullah! - Plugin icons now resolve through one shared rule, so the same plugin shows the same icon everywhere in the admin, and a plugin can ship its own logo image instead of naming a built-in glyph.

    The SEO plugin now describes itself in the plugins list instead of showing a bare package name.

    A styling fixture used only by the end-to-end suite no longer appears as an installed plugin, and no longer injects a showcase section into the Posts collection list, in a normal development server.

  • #740 db7122d Thanks @mobeenabdullah! - @nextlyhq/plugin-sdk now exports pluginAdminSlug, PLUGIN_CATEGORIES and isPluginCategory (experimental), so a plugin author can derive a plugin's admin slug and check a category against the vocabulary definePlugin accepts, rather than reimplementing either. They are also on nextly and nextly/config for host apps.

    The admin uses those exports instead of its own copies. It previously derived a plugin's URL slug with its own implementation of core's algorithm, so a plugin page could be linked at one slug and routed at another the moment either side changed, and it kept its own list of valid categories, so it could reject a category definePlugin accepts.

    Nothing changes in the admin UI. The plugin directory that consumes these is not built yet; this is the groundwork it needs.

  • #727 53fca3e Thanks @mobeenabdullah! - On desktop, the Plugins item in the admin sidebar now opens the plugins page when you click it, instead of only expanding the sub-sidebar and leaving you to find the page yourself. On mobile it still opens the panel, as every sidebar section with a panel does, and Installed Plugins is the first entry inside it. The item also stays visible when no plugins are installed, so a new project can reach the plugins page at all.

    Users who can read a plugin's collections but cannot manage settings keep the sub-sidebar, since the plugins page itself is settings-guarded.

    The secondary sidebar now closes when the category it is showing stops being one of the sidebar's destinations, so a slow or failing permissions load no longer leaves an empty panel open beside the page.

  • #671 75054a8 Thanks @mobeenabdullah! - Relationship expansion can now be told WHICH collections a trusted read may
    reach, judged per expansion target.

    overrideAccess says the caller is trusted. It said nothing about the
    collection a relationship points at — which the caller never named and may not
    serve to the same audience — so a trusted read spread that trust into every
    target it populated. A caller serving one fixed audience can now state its
    trusted set, and anything outside it is read as that audience would read it.

    Absent the new option nothing changes, so the Direct API keeps its semantics: a
    caller that has already decided who is asking is not narrowed by a default it
    never chose.

  • #724 35ff30a Thanks @mobeenabdullah! - A page whose stylesheet is reused now keeps it when a block migration turns a
    condition-gated node into one that renders nothing. Those nodes never had rules
    in the shared sheet, so withholding it cost every other block on the page its
    styling.

  • #673 67082d1 Thanks @mobeenabdullah! - Check the built server-safe entry points against what the build recorded, and stop publishing the
    bundler metafiles those checks read.

    The gate reads two records the build already wrote — the module specifiers surviving in each
    artifact and every chunk reachable from it, and the bundler's own metafile of what it inlined. A
    bundled dependency leaves no import to find, so the text alone cannot answer what an artifact
    reaches. The metafiles are build inputs to that check rather than something a consumer needs, so
    they are excluded from the published files.

  • #702 8011731 Thanks @mobeenabdullah! - fix(ui): ignore a dispatched event that is not a keystroke

    The shortcut manager listens on document, so every event dispatched anywhere on
    the page reaches it — including synthetic ones from code outside the application.
    A password manager typing into a credential field dispatches a keydown carrying
    no key, and the manager spread it as a string, crashing the page with
    TypeError: key is not iterable. It now ignores an event it cannot read as a
    keystroke, and leaves it propagating to whichever listener does understand it.

  • #697 ca1cc48 Thanks @mobeenabdullah! - Carry a trusted write's bound into a Single's upload expansion. A Single holding uploads and no relationship field returned whole media rows in its write response, because the bound reached only the relationship expansion beside it, which returns early for such a document.

  • #705 ecefaa2 Thanks @mobeenabdullah! - A field group instance now reports its type whichever spelling the stored document uses, so content written before and after the storage rename both read. A where filter on the type keeps working under either spelling, and version snapshots keep recording the type of components nested inside a dynamic zone. Reading that type is one shared call rather than a key spelled out at each site, which is what keeps the rename a change in a single place.

  • #716 cf48bd7 Thanks @mobeenabdullah! - A version snapshot now records each field group instance under one spelling of its type key. An entry captured before the storage rename, restored, and captured again previously kept its old key alongside the new one, so the snapshot announced the same instance's type twice.

  • #731 298d41e Thanks @mobeenabdullah! - Page builder inspector: keep the open panel tab in sync when the selected block changes type, so the inspector no longer shows a tab the block does not have.

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/builder
  • @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/ui
  • create-nextly-app
  • nextly