Dyrected
Start Here

Changelog

Release notes and version history for the Dyrected platform.

Release notes and version history across all Dyrected packages.

v2.20.0

  • feat(auth): polymorphic email transport, custom templates cascade, headless tokens, and admin template management

    • Polymorphic email delivery: support both direct HTML and external template IDs with dynamic variables (Postmark, Seamailer, SendGrid) without serializing payloads into fake HTML.
    • Multi-tier template cascade: DB overrides (__email_templates) -> Collection config (collection.auth.email.templates) -> Global config (config.email.templates) -> Core defaults.
    • Collection action URLs: configure auth.urls.invite and auth.urls.resetPassword per collection to keep end-users from being routed to /admin.
    • Token lifecycle & safety: hardened password safety checks for null/empty passwords returning 401 PASSWORD_NOT_SET, protected against double-acceptance, and added token superseding with invitedAt.
    • Headless tokens & token verification: support sendEmail: false, createInviteToken, createPasswordResetToken, and GET /api/collections/:slug/tokens/verify (SDK client.collection(slug).verifyToken(token, type)).
    • Admin UI template editor: live CodeMirror HTML editor, desktop/mobile iframe preview, variable chip insertion, external template ID mode, test email dispatch dialog, and revert-to-default capability. (@dyrected/admin, @dyrected/core, @dyrected/sdk)

v2.19.0

  • Add built-in Trash & Retention system and audit/roles field helpers across core, admin, SDK, and framework integrations:

    • Core Trash & Retention: Move deleted documents to internal __trash collection with deterministic IDs, freeing unique keys and keeping read paths clean. Configurable retention periods with automatic dyrected:trash-purge task runner integration.
    • Audit & Schema Field Helpers: Add defineCreatedAtField, defineUpdatedAtField, defineCreatedByField, defineUpdatedByField, and defineRolesField (with customizable adminRole authorization).
    • Admin UI: Add collection-level and global /trash views, 8-second undo toast on delete, media library trash support, empty trash confirmation dialog, and conflict drawer for "Restore with changes".
    • Ecosystem: Add client.trash() in @dyrected/sdk, useTrash in @dyrected/react and @dyrected/vue, dyrected doctor trash & retention diagnostics in @dyrected/cli, and secret-protected cron endpoints in @dyrected/next.

v2.18.1

  • Fix operational workspace view action resolution and optional field null validation.

    • Workspace view actions (@dyrected/core): Support operational view actions defined inside config.admin.navigation (such as defineWorkspace views targeting a collection via view.collection, item.collection, or addToCollection). runViewAction and action route registration now search both collection.views and all matching workspace views, preventing Action "<action>" was not found in view "<viewSlug>" errors.
    • Optional field null validation (@dyrected/admin): Updated buildSchemaShape so optional fields accept null (.nullable().optional().or(z.literal(""))), resolving spurious Expected string, received null validation errors when saving existing records with null database values. (@dyrected/admin, @dyrected/core)

v2.18.0

  • Add transactional write hooks and exact money handling. Collections can define hooks.beforeCommit, which runs inside the write transaction with a writable tx so secondary writes commit or roll back with the document. Workflow transitions can define onTransition, run inside the transition transaction and given an optional request input. Fields accept immutable: true, which rejects any update that changes the value. The new money field (defineMoneyField) stores integer minor units, validates them on write, maps to BIGINT in SQL adapters, and is edited and displayed in major units in the Admin.

  • Add view filter builder to navigation customizer. Enables configuring visual and raw JSON where-clause filters for collection subviews directly from the admin UI with schema field introspection, operator presets, and type coercion. (@dyrected/admin)

  • Fix collection-level actions not appearing in the admin, and fix invite and password-reset links. /api/schemas now includes root-level collection.actions, so displayAction items on a detail view resolve instead of showing "Action not found". Invite and reset emails now link to the admin UI instead of the site URL. The base URL comes from the new admin.adminUrl option, then the DYRECTED_ADMIN_URL env var, then the page the admin is running on, then /admin, and relative values resolve against the request origin. The invite dialog's "Copy" field now shows the full invite link with its token. (@dyrected/admin, @dyrected/core)

  • Fix bugs found by running the adapter contract suite against live databases. Postgres atomic increment/decrement no longer fails with "multiple assignments to same column data", and conditional where updates by id no longer collide on parameter numbers. MySQL and Postgres unique and compound indexes on collections with long names are now created (over-long index names are shortened with a stable hash instead of being silently rejected, which left unique unenforced). MongoDB compound indexes no longer fail when sparse is unset. The money field also gets its numeric list filter in the Admin.

  • Close the remaining P0 integrity gaps. findOne now accepts a where filter (with lock: "for-update") in addition to an id. The MongoDB adapter now generates string IDs like the SQL adapters, enforces unique fields and collection indexes, throws DuplicateKeyError on duplicate keys, and supports atomic increment/decrement and conditional where updates. MySQL promoted select, radio, relationship and email columns use bounded VARCHAR types. The adapter contract suite gains concurrency tests for unique inserts and conditional debits.

  • Add a background task runner and Nuxt import aliases. defineTask and createTaskRunner (exported from @dyrected/core) run cron-scheduled jobs from the tasks config, with a per-task database lock so each scheduled run happens once across instances, a lockTimeout that aborts overrunning runs, and runDue() for platform crons. @dyrected/nuxt registers #dyrected and #dyrected/server aliases anchored to the project root (fixing ~ resolving to app/ in Nuxt 4), can start the runner with the new runTasks option, and no longer blocks dev server boot while validating the config. (@dyrected/core, @dyrected/nuxt)

  • Make boolean filters behave the same on every adapter. The strings "true"/"false" are now coerced to booleans for fields declared as boolean (coerceBooleanWhere), where they previously matched nothing on SQLite and MongoDB and returned the wrong rows on Postgres for promoted columns. The shorthand { flag: false } form also works on SQLite now.

  • Make groupBy aggregates return the same keys and values on every adapter. Group keys are normalized by field type ("true"/"false" for booleans, "1" for numbers, ISO strings for dates, __unassigned__ for null), MySQL treats JSON null as SQL NULL and avg returns double precision, and Postgres and MySQL return promoted date columns as ISO strings. MySQL now accepts ISO timestamps written to promoted date and datetime columns, which previously failed.

  • Fix aggregate bugs found on live databases. MySQL no longer fails on distinct aggregates (it has no DISTINCT for JSON_ARRAYAGG, so values are de-duplicated in the adapter), groups by numeric columns now use keys like "1" instead of "1.0000", and filters on unpromoted boolean fields now match. MongoDB grouped aggregates now honour each aggregate's where. (@dyrected/db-mongodb, @dyrected/db-mysql)

  • client.collection(slug).transition(id, name, opts) now accepts an optional input object. It is sent with the transition request and passed to the transition's server-side onTransition handler, for example an amount the handler needs to act on. (@dyrected/sdk)


v2.17.0

  • Operational views and dynamic navigation

    • Workspaces: add defineWorkspace and DefineWorkspaceOptions for standalone operational workspaces, collection placement, groups, ordering (order, position, before, after), addToCollection, and role-based access. Reserved route slugs are validated at config load.
    • Navigation APIs: serve /api/admin/navigation (compiled tree, pruned per user role) and /api/admin/navigation/badges (batched aggregates, invalidated on mutations).
    • Badges: support static text badges, aggregate count badges with variants, and per-view badges. Metrics gain countDistinct and string-based aggregates, with improved Postgres casting.
    • Admin: add an inline navigation customizer with auto-generated slugs, a Lucide icon picker, and permanent view deletion. Pinned items now sit under the dashboard, and preference events no longer dispatch during render.
    • Database adapters: add collection database indexes and the aggregate improvements above to the SQLite, MySQL, and Postgres adapters.
    • CLI: add dyrected nav pull and dyrected nav push to sync UI-configured navigation with dyrected.config.ts, and keep navigation in sync during sync:schema.
    • SDK: resolve relative base URLs server-side.
    • Knowledge: add KYC review, order fulfillment, and support desk workspace recipes.
    • Docs: add the "Workspaces and navigation" guide and remove legacy list-view-v1 content.

v2.16.0

  • Align drawer saves with edit-page mutation pipeline and parent query invalidation:

    • Unify drawer mutations across JoinField and DetailRepeatComponent via a shared drawerSavePipeline.
    • Support password changes (oldPassword, newPassword, confirmPassword) from drawers using client.changePassword(...).
    • Immediately seed React Query document detail caches upon mutation for zero-flicker UI updates.
    • Optimistically update parent join lists and caches (["join", target, onField, parentDocId]).
    • Thoroughly invalidate parent document queries (detail and entry), parent collection list queries, and relation join queries so parent pages update immediately without manual page reload.
    • Trigger parent query invalidations when executing custom actions in drawer views via onActionSuccess.
    • Provide standardized success and error notifications matching edit-page conventions. (@dyrected/admin)
  • Schema Integrity, Physical Indexes & Atomic Concurrency

    • add duplicate key error handling, auto-migration for index creation, and expanded column lengths.
    • add production concurrency and fintech readiness specification with database adapter and documentation updates.

v2.15.0

  • Detail View drawers, workflow actions, and list config improvements:

    • Join field rows (on the edit page) and detail-repeat rows (on the read-only Detail View) now open into a side drawer showing that row's own collection's Detail View config when it has one (falling back to the edit form otherwise), with a view/edit toggle and prev/next navigation between the already-loaded rows.
    • Auto-generated Detail View schemas now render join fields as a table instead of badge pills, and table-layout repeat fields no longer duplicate field labels already shown in the column header.
    • New collection.actions (defineAction/displayAction) let a collection define workflow actions that run against a single document independent of any view, rendered in the Detail View's header toolbar and/or inline via displayAction(name) — backed by a new view-less POST /api/collections/:slug/actions/:action route and a client.collection(slug).runCollectionAction() SDK method.
    • New collection.admin.filter / sort / metrics / groupBy apply directly to a collection's default list view, without needing to define a separate views array and mark it as the default.
    • Inline-editable Detail View fields now show their edit affordance by default on mobile instead of only on hover. (@dyrected/admin, @dyrected/core, @dyrected/sdk)
    • Respect error.statusCode from throwing defineAction handlers in the collection action runner instead of always returning HTTP 500, matching the workflow-transition error path. Single-row failures now return the thrown status (e.g. 400 for validation failures) with an { error: true, message } body, and bulk runs report the per-row status.
    • Surface the server's error message in DyrectedError for string and bare { error } response bodies, so admin action toasts show the actual validation message instead of a bare status code. (@dyrected/core, @dyrected/sdk)

v2.14.0

  • Auth: configurable session token lifetime and reusable server auth helpers

    Session JWTs are no longer fixed at 7 days. Set auth.tokenExpiration on any auth collection using jose setExpirationTime values:

    auth: {
      tokenExpiration: "12h",
    }

    The configured lifetime applies to login, first-user registration, invite acceptance, token refresh, and external-provider admin SSO. Password-reset (1h) and invite (7d) purpose tokens stay fixed.

    Reusable auth helpers from @dyrected/core/server

    The same token, session, password, and email helpers Dyrected uses internally are now exported for custom endpoints and hooks:

    • Tokens: signCollectionToken, verifyCollectionToken, decodeCollectionToken, resolveSessionTokenExpiry
    • Sessions: issueAuthSessionToken, getAuthSession, revokeAuthSession, revokeAllAuthSessions
    • Passwords: hashPassword, verifyPassword
    • Email: sendEmail, buildResetPasswordEmail, buildInviteEmail, buildWelcomeEmail, buildPasswordChangedEmail

    Admin: resizable navigation sidebar

    The desktop admin menu can now be resized by dragging its right edge, mirroring the AI assistant panel. Double-click resets to the default width. The width persists to the layout:admin:sidebar-width global preference with localStorage as the instant cache and offline fallback. (@dyrected/admin, @dyrected/core)


v2.13.6

  • Type Safety: Enforce Required Field Properties

    Added compile-time type safety for field configuration to catch configuration errors at build time instead of runtime:

    Field Type Improvements:

    • JoinField: collection and on are now required
    • RelationshipField: relationTo is now required
    • ImageField: relationTo is now required
    • ObjectField: fields is now required
    • ArrayField: fields is now required
    • BlocksField: Requires either blocks or blockReferences

    Action & Workflow Improvements:

    • ActionConfig: Now enforces that either mutation or handler (or both) is provided via union type
    • ViewLayout Types: Layout-specific types enforce required fields:
      • Kanban views require groupBy
      • Calendar views require dateField
      • Gantt views require startDateField and endDateField

    DefaultValue Type Safety:

    • defaultValue now matches the field's value type (e.g., multiSelect requires string[], not string)

    Collection Slug Inference (NEW):

    • Added ExtractCollectionSlugs<T> helper type to extract valid collection slugs from config
    • Added defineTypedRelationshipField<ValidSlugs>() - type-safe relationship fields
    • Added defineTypedImageField<ValidSlugs>() - type-safe image fields
    • Added defineTypedJoinField<ValidSlugs>() - type-safe join fields
    • These builders validate relationTo and collection against available slugs at compile time
    type ValidSlugs = ExtractCollectionSlugs<typeof collections>;
    
    // ✅ Valid - 'posts' exists in collections
    defineTypedRelationshipField<ValidSlugs>({
      name: "author",
      relationTo: "users", // Type-checked!
    });
    
    // ❌ Invalid - 'potss' doesn't exist
    defineTypedRelationshipField<ValidSlugs>({
      name: "author",
      relationTo: "potss", // TypeScript error!
    });

    Documentation:

    • Added guidance that workflow transition from/to fields should reference defined state names
    • Clarified that select/multiSelect/radio fields should include options configuration

    Bug Fixes:

    • Fixed r.map is not a function runtime error in admin collections by enforcing multiSelect defaultValue types
    • Fixed admins and investors collections to use correct array-typed defaultValues

    These changes improve developer experience by surfacing configuration issues at compile time through TypeScript's type system, reducing debugging time and preventing production issues. (@dyrected/admin, @dyrected/core)


v2.13.5

    • Normalize role and roles fields across core auth middleware and admin auth to allow interchangeable use.
    • Return collection slug in GET /me response to ensure user context collection is always populated.
    • Fix route access guard in EditEntryPage to check canCreate on creation routes instead of incorrectly checking canRead.
    • Synchronize token authentication with the client on startup and invalidate schemas cache on login/logout so permission rules refresh immediately.
    • Fix TypeScript type-narrowing on uploaded file preview in EditEntryPage. (@dyrected/admin, @dyrected/core)

v2.13.4

  • Resolve Rolldown CommonJS interop error in lazy-loaded RichTextEditor chunk by shimming use-sync-external-store to native React 18/19 hooks, and inject a browser window.require fallback for react and react-dom in @dyrected/admin and @dyrected/vue. (@dyrected/admin, @dyrected/core, @dyrected/vue)

v2.13.3

    • Bundle all admin UI implementation dependencies into pre-compiled ESM to eliminate Vite runtime dependency discovery and page reloads.
    • Lazy-load AI SDK dependencies and add @vercel/oidc browser shim to eliminate Vite CommonJS export errors.
    • Hide AI lip trigger when no AI config is specified.
    • Fix relative ESM import extension for loadConfig and add jiti dependency to @dyrected/nuxt. (@dyrected/admin, @dyrected/core, @dyrected/nuxt)

v2.13.1

    • MySQL Adapter Feature Parity & Resilience (@dyrected/db-mysql):

    • Concurrent Schema Migration Safety: Added in-memory tableLocks mutex and lifecycle table cache to prevent concurrent requests from firing duplicate ALTER TABLE queries during initialization.

    • Duplicate Field Tolerance: Caught ER_DUP_FIELDNAME (errno 1060) and duplicate column errors silently during concurrent column promotion.

    • AI Chat Storage Provisioning: Auto-created _dyrected_ai_threads and _dyrected_ai_messages internal tables with indexes and cascading foreign keys on boot, bringing MySQL to parity with Postgres.

    • Promoted Field Types & Backfilling: Added DATETIME(3) column type support for date/datetime promoted fields and added automatic backfill from JSON data into newly promoted SQL columns.

    • Connection Resilience & Retries: Added default keep-alive (enableKeepAlive: true, 10000ms), connection timeout (20000ms), exponential backoff retries on pool initialization, and exposed poolOptions in MysqlAdapterConfig.

    • Global Pool Caching: Cached MySQL connection pool on globalThis (getSharedMysqlClientCache) and exported closeAllMysqlClients() to prevent connection exhaustion during Next.js/Nuxt HMR.

    • Column Inspection Caching: Replaced repetitive SHOW COLUMNS queries on every CRUD/aggregate call with an in-memory tableColumnsCache.

    • Configurable Superuser Role (@dyrected/core, @dyrected/admin):

      • Added adminRole?: string to AuthConfig interface.
      • Added getAdminRoleForCollection and isUserAdmin helper utilities in @dyrected/core.
      • Updated /first-user setup endpoint to inspect the collection's configured adminRole and roles field options, automatically selecting the appropriate superuser role instead of hardcoding 'admin'.
      • Decoupled hardcoded 'admin' checks across routes, controllers, and Admin UI to recognize configured admin roles alongside 'super_admin' and 'admin'.
    • Nuxt Config Loading via jiti (@dyrected/nuxt):

      • Replaced the static top-level ESM import in the generated Nitro plugin with dynamic loadDyrectedConfig (via jiti with esmResolve: true), natively supporting extensionless TypeScript imports and path aliases at initial boot.
    • Safe Package Publishing & Workspace Protocol Protection (dyrected, scripts/publish-packages.mjs):

      • Replaced native npm publish with pnpm publish --no-git-checks so internal workspace:^ dependencies are automatically resolved into concrete published semver versions.
      • Added an automated pre-publish assertion (assertNoRawWorkspaceDeps) that verifies package tarballs before upload and immediately aborts if any raw "workspace:" string is present in the distribution manifest.

v2.13.0

    • Core Client/Server Clean Decoupling & Schema Serialization:

    • Decoupled server-only AI services (ai.service, ai-tools, rag.service, embedding.service, ai-rate-limit, observability) strictly into @dyrected/core/server.

    • Cleaned the @dyrected/core root entry point to be 100% browser-safe, eliminating pino logger and Node.js built-ins (os, fs, stream) from client bundles and Next.js Turbopack applications.

    • Hardened /api/schemas serialization to forward shared, siteId, and collection-level ai configuration, plus field constraints (unique, min, max, step, minLength, maxLength, pattern, allowedTypes, maxSize, virtual, promoted, ai).

    • Added public AI readiness flags on the schema payload (ai: { enabled: boolean, provider?: string, model?: string }).

    • First-Class Typed SDK AI Module (@dyrected/sdk):

      • Implemented typed client.ai namespace on DyrectedClient:
        • client.ai.createThread(input?): Create a persistent conversation thread.
        • client.ai.listThreads(): Retrieve all conversation threads.
        • client.ai.getThread(id): Retrieve a single thread by ID.
        • client.ai.deleteThread(id): Delete a thread and cascade its messages.
        • client.ai.postMessage(threadId, input): Post a prompt and receive assistant response.
        • client.ai.listMessages(threadId): Fetch full history for a thread.
        • client.ai.getAction(actionId): Fetch details of a pending human-in-the-loop action proposal.
        • client.ai.executeAction(actionId): Approve and execute a sensitive action proposal.
        • client.ai.rejectAction(actionId, input?): Reject a pending action proposal with feedback.
        • client.ai.searchRAG(input): Semantic vector search across indexed collections.
        • client.ai.reindexRAG(input?): Trigger manual document vector indexing.
        • client.ai.chat(messages, options?): Stream raw chat responses from /api/ai/chat.
      • Replaced ad-hoc qs stringification with pure JSON payload transmission for delete-many and folder actions.
    • Admin Sidebar Restructuring, Workspace Switcher & Dashboard AI (@dyrected/admin):

      • Moved the sidebar collapse toggle to the top-right of the logo row ([Logo] Dyrected ... [collapse button]).
      • Added a compact WorkspaceSwitcher (h-8, ~32px) directly underneath the logo row, with support for user-restricted site lists and dynamic switching.
      • Added setSiteId to DyrectedContext and DyrectedProvider with immediate TanStack Query cache invalidation and localStorage persistence.
      • Added an interactive AI Assistant Spotlight Card and Ask AI Assistant quick action button on the Dashboard.
      • Added an AI Assistant navigation item (Sparkles icon with ⌘J shortcut badge) in the sidebar.
      • Positioned Setup on the bottom-left and the ThemeSelector on the bottom-right of the sidebar footer.
    • CLI Recursive Layout Flattening (@dyrected/cli):

      • Updated packages/cli/src/utils/type-generator.ts to recursively flatten row layout containers into generated TypeScript interfaces so child fields are never omitted.
    • Documentation Updates (apps/docs):

      • Documented OpenRouter and custom OpenAI-compatible provider configuration in ai.mdx.
      • Added multi-tenant architecture docs: overview, header-scoped tenanting, row-level tenanting, and dynamic schemas.
      • Added AI privacy and field-level PII scrubber documentation in ai-privacy.mdx. (@dyrected/admin, dyrected, @dyrected/core, @dyrected/sdk)
    • OpenAPI & Swagger AI Surface:

    • Integrated all /api/ai/* endpoints into the live OpenAPI 3.0 specification generator (/api/openapi.json) and Swagger UI documentation (/api/docs).

    • Added full request/response schemas for /api/ai/chat, /api/ai/threads, /api/ai/threads/{threadId}, /api/ai/threads/{threadId}/messages, /api/ai/actions/{actionId}, /api/ai/actions/{actionId}/execute, /api/ai/actions/{actionId}/reject, /api/ai/rag/reindex, and /api/ai/rag/search.

    • Added unit test coverage for AI OpenAPI route definitions in packages/core/src/__tests__/openapi.test.ts.

    • AI Core Prompt Architecture & Safety:

      • Streamlined buildDyrectedSystemPrompt with dual-mode communication (editorial partner by default, developer mode opt-in).
      • Enforced proactive mutation proposals (proposeCreateDocument, proposeUpdateDocument, proposeUpdateGlobal) without asking passive permission for content rewrites.
      • Added automatic provider auto-detection across OPENAI_API_KEY, GEMINI_API_KEY, OPENROUTER_API_KEY, and AGENTROUTER_API_KEY.
    • Admin Assistant UI & Streaming Enhancements:

      • Added live animated streaming carets and streaming status banners with instant abort (stop()) support.
      • Upgraded TypingDots with contextual status states ("Thinking...", "Synthesizing data...", "Drafting response...").
      • Deduplicated tool execution parts and action proposal keys to eliminate React duplicate key warnings.
    • Comprehensive Documentation Suite (apps/docs):

      • Added model-content/configuration/ai.mdx: Complete guide to configuring AI, setting brand voice directives, and collection prompts.
      • Added editor-experience/ai-assistant.mdx: Guide to the embedded Lip Trigger assistant drawer, live diff viewers, and human-in-the-loop proposals.
      • Added deliver-content/ai-agent-api.mdx: Programmatic AIAgent guide for Server-Sent Events (SSE) streaming and Telegram/WhatsApp webhooks.
      • Added deliver-content/rest-api/ai-endpoints.mdx: Complete REST API reference for all AI endpoints.
      • Added examples-and-recipes/library/chat-to-order-proposal.mdx: Recipe for parsing unstructured customer chat logs into structured database orders.
      • Added examples-and-recipes/library/custom-ai-tools.mdx: Recipe for extending Dyrected AI with custom server-side functions and Zod schemas. (@dyrected/admin, @dyrected/core)

v2.12.0

    • Digital Asset Management (DAM): Added folder hierarchy tree with desktop sticky sidebar and mobile pill carousel, Move to Folder modal, in-place asset replacement, MIME type filter chips, and full-width MediaLibraryDialog.
    • Focal Point & Smart Cropping: Integrated focal point picker in Media Inspector with automatic CSS object-position calculations in <DyrectedMedia> and dynamic CDN crop parameters in Cloudinary/API transformations.
    • Spreadsheet Grid Cell Editors: Added full in-cell editing for select, multi-select, link, date/datetime, media/image, and relationship pickers.
    • Action Dialog & Form Engine Parity: Added async hook support, setValue(fieldName, value) sibling mutation support, functional defaultValue: ({ doc, docs, user }) => ... serialization/client-evaluation, and unified document context across action dialog modals and collection forms.
    • Sticky Table Headers & Mobile Scroll Container: Consolidated table view scrolling into a single unified scroll container with pinned sticky header rows and sticky selection checkbox columns for smooth vertical and horizontal navigation on desktop and mobile. (@dyrected/admin, @dyrected/core, @dyrected/sdk, @dyrected/storage-cloudinary)
  • Add expr expression builder with expr.ifElse, concise shorthands (expr.empty, expr.notEmpty, expr.equals), and fluent transforms (.slugify(), .lower(), .upper(), .trim()). Improve dyrected upgrade CLI command with sanitized environment execution and streamlined manifest updates. (dyrected, @dyrected/core)


v2.11.0

  • Support dynamic and JEXL defaultValue evaluation, admin.hooks.onChange live reactivity, admin.hooks.options cascading dropdowns, and admin.condition visibility inside ActionFormDialog and FormEngine. (@dyrected/admin, @dyrected/core)

    • Fix Admin UI session staleness and authentication desynchronization:
    • Add proactive background token refresh timer scheduled 5 minutes before JWT expiration.
    • Refresh token on browser tab focus and visibilitychange when returning to an open dashboard.
    • Dispatch dyrected:auth-unauthorized and support onAuthError callback in @dyrected/sdk on 401 responses.
    • Automatically attempt token refresh on 401s in Admin UI, falling back to instant login gate transition if session is expired or revoked.
    • Fix user state leak bug in DyrectedProvider that prevented logout and login page rendering.
    • Call backend POST /api/collections/:slug/logout to revoke server session in __auth_sessions during logout.
    • Allow operational view component slots (afterViewHeader, beforeViewHeader, beforeViewContent, afterViewContent) to resolve components registered under either components.collectionView or components.collectionList.
    • Enhance action and confirmation dialogs for mobile and tall content:
      • Render as a mobile bottom-sheet (max-sm:bottom-0, slide from bottom, top grab handle) on small viewports.
      • Constrain all fields and custom modal components within the device viewport width (w-full min-w-0 overflow-x-hidden).
      • Enable independent vertical scrolling (overflow-y-auto) with fixed, docked headers and action footer buttons.
    • Add operational view Refresh button in ViewHeader and mobile action menu:
      • Refetches both collection/view data and summary metrics in the background.
      • Keeps current datasets and stats on screen while displaying spinning and pulsing refetch indicators.
    • Update back button navigation on document edit and global editor pages to use browser history when available, preserving active operational view filters, sorting, and pagination. (@dyrected/admin, dyrected, @dyrected/sdk)

v2.10.1

    • Support submitLabel on operational view actions to customize the modal submit/run button text.
    • Automatically prefill action modal forms with the target document's current field values when executing row actions.
    • Normalize logical operators (AND/and, OR/or) case-insensitively in where-sanitizer.
    • Apply schema default values on create() before persisting to the database.
    • Strictly type operational view filters as WhereClause | string.
    • Add thorough JSDoc documentation across all operational view types and interfaces.
    • Add architecture specs for npx dyrected doctor diagnostics and multi-adapter automatic field promotion. (@dyrected/admin, dyrected, @dyrected/core)
    • Added type-safe when declarative condition and expression builder to @dyrected/sdk and @dyrected/core.
    • Added framework parity for useDyPath() and useDyPathHelper() in @dyrected/vue and auto-imported in @dyrected/nuxt.
    • Enhanced CLI upgrade command to automatically refresh .dyrected/ai-rules.md with the latest canonical rules when upgrading packages.
    • Added Marketing Site Page Builder Architecture, Array Field Object Shape Contract, and Type Synchronization Workflow to @dyrected/knowledge prompt templates and AI rules.
    • Added /docs/[...slug] legacy catch-all redirect route in documentation.

v2.10.0

    • Aggregate Engine Expansion (countDistinct, distinct, groupBy):

    • Added support for countDistinct ({ countDistinct: "fieldName" }) to count unique non-null values in a single database query.

    • Added support for distinct ({ distinct: "fieldName" }) to extract unique non-null values without loading full documents.

    • Added grouped aggregation support via groupBy parameter (?groupBy=<field> or { groupBy: "field", aggregates: { ... } }) returning per-group metric breakdowns with automatic "__unassigned__" sentinel handling for missing/null values.

    • Implemented cross-adapter parity for all aggregation operations across PostgreSQL, SQLite, MySQL, and MongoDB.

    • Updated live OpenAPI specification (/api/openapi.json) and Swagger documentation with complete aggregate schemas and response types.

    • Grouped Views & Admin UI Performance Optimization:

      • Replaced client-side document group extraction with native single-query database aggregations in grouped Table, Kanban, and Spreadsheet views, eliminating $N+1$ query waterfalls and reducing database roundtrips.
      • Deduplicated schema queries across AdminShell, OperationalViewRoute, and dashboard pages by utilizing cached context schemas.
      • Added defaultView collection configuration support with automated route redirection and clean sidebar submenu rendering.
    • Filter Join Operator: Support AND / OR toggle in toolbar and URL parameters (joinOperator=and|or) for inter-column filter combinations in operational views.
    • Action Dialog Document Context: Pass target document/row context (doc, docs, record, row, data, formData) into action form dialogs, FieldRenderer, and custom field components.
    • View Features & Action Ordering: Properly serialize and respect view.features (edit, delete, duplicate) and custom actionOrder in operational view action menus and table columns. (@dyrected/admin, @dyrected/core)

v2.9.0

  • Promote operational table to canonical list view:

    • Default view synthesis in getSchemas: resolveSchemas (DyrectedProvider) now synthesizes a list view (layout: table, columns from admin.defaultColumns or first 5 display fields) for collections without explicit views, so every collection has a table workspace and CollectionRoute can render without redirect.
    • Standardized preference keys: Column, view-mode, and toolbar keys now use layout:collections:${slug}:list for the default view and layout:collections:${slug}:view:${viewSlug}[:variant|:mode|:toolbar] for named views (variant suffix for cards/kanban). Reads fall back to legacy keys (view-pref:, view-mode:, view-columns:, view-toolbar:) and migrate on next save.
    • CollectionRoute (Option B): /collections/:slug now renders OperationalViewPage directly with the first (synthesized) view instead of CollectionListPage (list-view-v1). list-view-v1.tsx is deprecated (kept for reference). Media collections still render MediaPage.
    • URL compat shim: Legacy ?where=<json> (FilterBuilder) and ?search=<term> params are merged into the view's filter (mergeFilters / contains on first searchable field) so old shared links keep working.
    • Slot aliasing: admin.components.beforeList → beforeViewHeader, beforeListTable → beforeViewContent, afterListTable/afterList → afterViewContent are now rendered via AdminComponentSlot with a stubbed CollectionListSlotProps so existing collectionList slot consumers continue to mount inside operational views. collectionView slots remain primary.

    list-view-v1.tsx is marked @deprecated and will be removed in a future minor. (@dyrected/admin)

  • Operational Views: defineView / defineAction configuration helpers, view-aware admin sidebar and routing, table, kanban, calendar, cards (with multi-image carousels and edge-to-edge covers), and spreadsheet layouts, summary metric stat cards backed by the aggregation engine, an actions runner that resolves declarative mutations (now(), input.*, doc.*) or self-hosted handlers through the lifecycle-hook pipeline, and 4 new recipes in @dyrected/knowledge. (@dyrected/admin, @dyrected/core, @dyrected/sdk)

    • Where Operator Aliases (greater_than, less_than, etc.): Added support for verbose operator names in parseSqlWhere and parseMongoWhere (greater_than, less_than, greater_than_equal, greater_than_or_equal, less_than_equal, less_than_or_equal, like), resolving HTTP 500 errors on Detail View adjacent record navigation queries (Previous / Next document buttons).
    • Core Jexl Pre-bundling: Pre-bundled jexl into @dyrected/core to prevent Vite and browser runtime CJS default export errors across consumer applications.
    • Public/Default Preferences Read: Allowed GET /api/preferences/:key to use optionalAuth, enabling unauthenticated clients (e.g. login screen, theme initialization) to retrieve global preferences and default fallback values without throwing 401 Unauthorized errors. Mutations (PUT, DELETE) remain protected.
    • Media Library Clipboard Paste & Progress Indication: Added global clipboard paste support (⌘V / Ctrl+V) to MediaLibraryDialog with auto-switch to the Upload tab, live upload progress display, toast feedback notifications, and discoverability shortcut badges. (@dyrected/admin, @dyrected/core)

v2.8.3

    • Lazy Database Connections: Removed eager initialization in constructors for @dyrected/db-postgres, @dyrected/db-mysql, and @dyrected/db-mongodb. Network sockets, connection pools, and database creation queries are now deferred until the first actual query or explicit lifecycle call, preventing hanging sockets and timers when loading dyrected.config.ts during static builds (nuxt build, next build, type-generation, or CI pipelines).
    • Graceful Disconnect & Teardown: Added disconnect(): Promise<void> to DatabaseAdapter interface across all database adapters (@dyrected/db-postgres, @dyrected/db-mysql, @dyrected/db-mongodb, @dyrected/db-sqlite) and exported closeAllPostgresClients() from @dyrected/db-postgres.
    • Nuxt Lifecycle Teardown: Added a close hook in @dyrected/nuxt to automatically call disconnect() on active database adapters and flush cached client connection pools when Nuxt finishes building or shuts down.

v2.8.2

  • Enhance Detail Views with inline editing, custom component resolution, and dynamic presentation options:

    • Custom Component Resolution: Resolve custom Detail View components directly from runtime DyrectedContext and <DyrectedAdmin :components="..." /> in Vue/Nuxt and React/Next.js.
    • Inline Field Editing: Support editable: true on displayField() with interactive inputs, immediate SDK mutations, and save/cancel micro-interactions.
    • Dynamic Badge Presentation: Support badgeColors with named palettes, hex codes, Tailwind classes, and wildcards on displayField and displaySection.
    • Media Previews: Render uploads and media relationships seamlessly in Detail Views using DyrectedMedia with aspect ratio, alignment, and object-fit constraints.
    • Adjacent Record Stepper: Add header and footer stepper controls to navigate smoothly between previous and next records in the active collection.
    • JEXL Visibility Context: Pass full document properties to visibility evaluation context for robust conditional rendering. (@dyrected/admin, @dyrected/core, @dyrected/nuxt, @dyrected/vue)

v2.8.1

    • Detail View Inline Editing (editable: true): Added interactive inline editing directly within the Detail View screen. Editors can toggle simple fields (such as internal notes, tags, status choices, quantities, and dates) into editable form inputs with single-click save and cancel controls, updating records immediately via the client SDK without navigating away from the detail screen.
    • Dynamic Badge & Tag Color Palettes (badgeColors): Introduced the badgeColors resolution engine in Admin Detail Views. Supports 20+ named color palettes (emerald, amber, rose, sky, indigo, purple, violet, zinc, etc.), custom hex codes with automated background tints, raw Tailwind classes, and wildcard (*) fallback mappings.
    • Section Badges and Palette Styling: Added badge and badgeColor configuration options to displaySection(), allowing section headers to display contextual status or count badges.
    • Human-Readable Option Resolution: Enhanced select and radio field presentation in Detail Views to resolve raw value identifiers to their human-readable schema option labels.
    • Rich Media & Thumbnail Previews: Upload fields and media relationship documents in Detail Views now render responsive image cards, video players, and file download links instead of raw relationship identifiers.
    • Star Rating & Color Swatch Displays: Added visual star rating scales and interactive color swatch previews with hex copy utilities to Detail Views.
    • Auth Bootstrap & External Token Resolution: Fixed an issue where incoming redirect tokens (dyrectedExternalToken) caused the admin loading splash to hang indefinitely when external auth was not explicitly configured in the schema. Added cookie session support (__dyrected_token / dyrected_token) and optimistic JWT payload decoding so authenticated dashboards mount instantly without redundant roundtrips.
    • Detail View Adjacent Record Navigation: Added subtle Previous and Next record traversal in the Detail View. Includes a top-header stepper (< / >), a responsive bottom footer bar with previous/next document titles and directional arrows, and keyboard shortcuts (J for next, K for previous).
    • Direct Media URL Resolution & Unified DyrectedMedia: Standardized media URL handling across @dyrected/admin so that media objects with a populated url property use the target URL directly rather than reconstructing fallback paths. Centralized avatar, image, HTML5 video, YouTube/Vimeo embed, audio, and file download renderers into a universal <DyrectedMedia /> component.
    • Upload & Image Field Relationship Population (depth >= 1): Fixed PopulationService in @dyrected/core to populate upload and image field types (defaulting to the target upload collection or media) when queries specify depth >= 1. Added automatic bare-ID media resolution fallback to <DyrectedMedia /> in @dyrected/admin so that media assets display immediately even if received as unpopulated IDs.
    • Interactive Relationship Badge Links (DetailRelationshipLink): Relationship and author fields in Detail Views now render interactive linked badges featuring avatar images or initial icons, document titles, and direct navigation links to the target record. If received as an unpopulated ID string, the component automatically resolves the record title and avatar asynchronously.
    • Tag and Array Badge Rendering: Array fields, multiSelect lists, and JSON string arrays (such as Tags: ["insights", "operations"]) now automatically parse and render individual badge pills with support for badgeColors palettes, avoiding raw JSON string outputs.
    • Comprehensive Detail Reference & Type Definitions: Added complete JSDoc annotations and automated contract generation in @dyrected/knowledge for all 9 Detail View helper functions (displayField, displaySection, displayTabs, displayTab, displayGrid, displayRepeat, displayComputed, displayText, displayDivider, displayCustom) and their configuration options. (@dyrected/admin, @dyrected/core)

v2.8.0

  • Detail View System:

    • Added read-only Detail View pages and configurable layout renderers for collections (/collections/:slug/:id) and globals (/globals/:slug).
    • Added layout configuration helpers in @dyrected/core: defineDetailView, defineSection, defineFieldCard, defineRepeatCard, defineTab, defineTabs, defineComputedCard, defineDivider, defineInfoText, and defineFieldGrid.
    • Added support for dynamic conditional visibility on detail cards, sections, and tabs using boolean values or JEXL expressions evaluated against { doc, user }.
    • Added type-aware formatters and display variants including currency, percentages, progress bars, star ratings, tags, avatars, color swatches, and relations.
    • Added custom component slot support for detail views in both React and Vue runtimes.
  • Collection Aggregations System:

    • Added POST /api/collections/:slug/aggregate endpoint to @dyrected/core and integrated it into the OpenAPI specification generator.
    • Added collection aggregate() method to @dyrected/sdk.
    • Implemented database aggregation queries across all adapters: @dyrected/db-postgres, @dyrected/db-mysql (with IF() conditional aggregation), @dyrected/db-mongodb, and @dyrected/db-sqlite.
    • Added comprehensive security checks and access control gates for collection aggregations.
  • Knowledge & Documentation Runtime:

    • Added runtime-aware documentation manifest generator in @dyrected/knowledge.
    • Synchronized OpenAPI endpoints, recipes, and LLM reference indexes.

v2.7.1

    • Scoped split-pane edit page width calculation exclusively to desktop screen breakpoints, preventing form compression on mobile viewports
    • Replaced zero-based index array warnings with human-readable collection and field slug names in CLI sync:schema outputs
    • Added direct documentation links to CLI schema sync warning messages and core config validation outputs
    • Added comprehensive built-in Jexl helper utility functions (slugify, lower, upper, trim, capitalize, truncate, readingTime, wordCount, replace, startsWith, endsWith, now, today, formatDate, addDays, diffDays, isPast, isFuture, includes, join, first, last, compact, unique, length, round, clamp, default, coalesce, isEmpty, get) across @dyrected/core, @dyrected/admin, and CLI declarative validation (@dyrected/admin, dyrected, @dyrected/core)
    • Isolated server observability and logger runtime dependencies under @dyrected/core/server to prevent Node core modules (fs, worker_threads, stream) and Pino from leaking into frontend client bundles.
    • Added browser fallback module configurations for Next.js (withDyrected) and Nuxt module Vite build hooks to ensure clean client component compilation across Turbopack and Vite. (@dyrected/core, @dyrected/next, @dyrected/nuxt)

v2.7.0

  • Add controlled admin theme support so host apps can drive the admin theme and receive theme changes back through the public admin API. This also fixes the admin theme provider initialization so it does not access refs during render. (@dyrected/admin)

    • Added dark mode SVG logo asset and theme-aware fallback rendering in admin-shell
    • Migrated Nuxt example component config access to useRuntimeConfig
    • Transitioned default live preview mode to postMessage across prompt templates, skills, documentation, and recipes
    • Updated Dyrected configuration, environment integration, and content modeling rules for rich text and tabbed admin layouts
    • Modularized and consolidated prompt generation logic, AI rules, and shared rule templates (@dyrected/admin, dyrected)
  • @dyrected/[email protected]

  • @dyrected/[email protected] (@dyrected/next)

  • @dyrected/[email protected] (@dyrected/next)


v2.6.4

  • Improve admin safety and auth onboarding across admin, core, and SDK.

    • add a professional invite dialog in admin with copyable invite URLs and role selection for new invites
    • support invite acceptance directly from admin invite links
    • pre-create pending invited users in auth collections so they appear in admin lists before acceptance
    • let invite and reset emails use clickable URLs with stronger email-client-safe HTML and visible link fallbacks
    • expand dashboard "Needs attention" checks with backend health and invite-related signals
    • replace browser delete alerts with admin dialogs, including typed confirmation before deleting auth users (@dyrected/admin, @dyrected/core, @dyrected/sdk)
  • Add Cloud-safe declarative hooks, broader declarative-expression validation, and clearer config diagnostics across core, admin, Nuxt, SDK, and CLI.

    • add declarative string hook support for collection/global beforeRead, afterRead, and beforeChange, field beforeChange, and field admin.hooks.onChange
    • preserve supported declarative hook strings during sync:schema, strip function hooks from Cloud payloads intentionally, and warn with exact schema paths
    • validate declarative access rules, string access policies, declarative hooks, admin.condition, and admin.previewUrl early with exact config paths and cleaner diagnostics
    • expose config diagnostics from /api/schemas so admin surfaces can consume them, and improve admin dashboard attention signals around config issues
    • improve Nuxt startup and reload reporting for invalid declarative config with formatted diagnostics instead of noisy raw errors
    • document the Cloud-safe access and hooks model more clearly, including synced string policies, createdByCurrentUser vs isOwner, declarative hook contexts, and short notes about early validation for access, hooks, preview, and admin.condition

v2.6.3

  • Polish the admin editing experience with better loading and layout behavior.

    • replace branded and text-only loading states with skeleton loaders across bootstrap, collections, globals, dashboard, and media views
    • add professional not-found states for missing collections, globals, routes, and missing edit entries after loading resolves
    • keep the desktop sidebar pinned to the viewport while the main content scrolls independently
    • remove the nested media-page scroll container so the page uses a single parent scroll area
    • debounce admin list and media search while keeping existing results mounted so only the results region refreshes during server-side search
    • add a draggable desktop split view for resizing the live preview and form editor on collection edit pages
    • make rich text editor prose respect dark mode typography tokens
    • use configured global admin.icon values in the global edit header
    • @dyrected/[email protected]
    • @dyrected/[email protected] (@dyrected/admin)
  • @dyrected/[email protected]

  • @dyrected/[email protected] (dyrected, @dyrected/next)

  • @dyrected/[email protected] (@dyrected/next)


v2.6.2

  • Add controlled theme props to DyrectedAdmin across the admin and framework wrappers:

    • theme sets the preferred admin theme to system, light, or dark.
    • systemTheme supplies the currently resolved system theme for React and Next hosts.
    • onThemeChange lets embedded admin theme controls update host-managed theme state in React and Next.
    • Nuxt and Vue wrappers expose the same controlled theme surface through theme, system-theme, and on-theme-change.

    This makes it possible for host apps to keep one shared dark and light mode preference while the embedded admin stays in sync.

  • Dogfood the public admin controller APIs inside the built-in UI:

    • Move MediaLibraryDialog onto useMediaLibrary for internal library loading, paging, and selection state.
    • Use the public field/form APIs inside the built-in form renderer so nested field state flows through useField and useDyrectedForm.
    • Replace manual nested path string building in array, block, form, and nested-editor internals with the exported path helpers.
    • Align internal nested field targeting with full field paths, improving consistency with the public custom-field contract. (@dyrected/admin)
  • Implemented the framework-level public API first, which was the right prerequisite for docs. Added a framework-level public API across the admin, React, and Vue packages.

    • @dyrected/admin now ships a side-effect-free public entrypoint for controllers, helpers, and React admin primitives, without pulling in the admin app entry or its CSS.
    • @dyrected/react now exposes the intended top-level admin and media hooks, and re-exports the form, field, and theme React APIs from the admin public surface.
    • @dyrected/vue now exposes first-class composables for admin schemas, media flows, forms, fields, and theming, and includes a Vue module shim so plain TypeScript validation works. (@dyrected/admin, @dyrected/react, @dyrected/vue)
  • Add a reusable public form and field API foundation to @dyrected/admin:

    • Introduce framework-agnostic form and field controllers:
      • createDyrectedFormController
      • createDyrectedFieldController
    • Add React adapters for the shared controller layer:
      • DyrectedFormProvider
      • DyrectedFieldPathProvider
      • useDyrectedForm
      • useField
    • Publish custom field component prop/context types so host apps can build admin.component field overrides against a stable contract.
    • Export form utility helpers (buildSchemaShape, buildDefaultValues, getFlatErrors, formatPath, resolveContainerPath) for advanced custom form surfaces.
    • Keep the existing admin form engine on react-hook-form internally while syncing its state into the shared controller layer so public consumers and built-in forms use the same source of truth. (@dyrected/admin)
  • Add a reusable public media API foundation to @dyrected/admin:

    • Introduce framework-agnostic media controllers for uploads, URL imports, and media library state:
      • createMediaUploadController
      • createMediaURLController
      • createMediaLibraryController
    • Refactor the React media hooks to become adapters over the shared controller layer:
      • useMediaUpload
      • useMediaURL
      • useMediaLibrary
    • Keep useAddMediaFromUrl as a backward-compatible alias while shifting the preferred public naming to useMediaURL.
    • Export the new media controllers, React hooks, and supporting media utilities from @dyrected/admin so host apps can build custom media interfaces without reimplementing ingestion logic.
    • Preserve the existing admin media experience by keeping MediaLibraryDialog, MediaPicker, and MediaPage on the same controller-backed upload and URL import pipeline. (@dyrected/admin)
  • Extend the public admin API with theme controller support and field-path ergonomics:

    • Introduce createAdminThemeController as a framework-agnostic theme state foundation for React, Vue, and other host apps.
    • Export the public React theme adapter surface:
      • AdminThemeProvider
      • AdminThemedRoot
      • useAdminTheme
    • Export pure theme helpers:
      • resolveAdminTheme
      • adminThemeClassName
      • getSystemAdminTheme
    • Add higher-level nested field path helpers for custom field authors:
      • normalizeFieldPath
      • getFieldPathSegments
      • joinFieldPath
      • getParentFieldPath
    • Extend useField with object/array convenience helpers so nested custom fields can work with child and item paths without hand-building dot-path strings.
    • Document the controller-first public API pattern in packages/admin/docs/public-controller-pattern.md. (@dyrected/admin)
  • Refine workflow action behavior in the admin collection editor:

    • Prefer Save draft as the primary workflow button when an entry is currently in a published workflow state.
    • Keep unpublish-style workflow transitions out of the primary button and available from the workflow dropdown instead.
    • Preserve normal forward workflow transitions as the primary action for non-published entries.
    • Remove the workflow comment dialog's effect-based local state reset to satisfy React Hooks lint rules without changing the required-comment flow. (@dyrected/admin)
  • Overhaul media library upload experience with a unified media ingestion pipeline and non-technical storage notices:

    • Add multi-file drag-and-drop dropzone with live byte-level upload progress queue in MediaLibraryDialog.
    • Unify file ingestion across MediaLibraryDialog, MediaPicker, and MediaPage using useMediaUpload.
    • Add client-side Canvas API image compression (compressImage) capping long edges to 2048px before network transfer.
    • Add safe upload collection resolution (resolveActiveMediaCollection) falling back to "media" for non-upload collections.
    • Optimize URL media import pipeline with 0-byte bandwidth transfer for YouTube/Vimeo embeds and direct remote video CDN links, with client-side fetch and CORS fallbacks for direct images.
    • Add semantic source classification and visual badges (getMediaSourceInfo) for internal vs external media items across grid, list, and detail views.
    • Add non-technical, user-friendly StorageNotConfiguredNotice banner on MediaPage and MediaLibraryDialog when media storage is not configured.
    • Add "Media storage is not set up" alert item to the Dashboard "Needs attention" section when an upload collection exists without a configured storage provider.
    • Catch Storage not configured errors gracefully across upload forms and format them into clear instructions asking the user to contact their developer. (@dyrected/admin)
  • Rewrite the public API docs around end-user goals instead of internal architecture.

    • Rework the overview for hooks and composables so it starts from the jobs developers are trying to get done, such as media uploads, media picking, document editing, custom fields, and theme-aware shells.
    • Add focused documentation pages for media, form and field, and theme APIs in apps/docs, with practical guidance for custom components, dashboards, and host apps rather than framing them only as admin internals.
    • Keep the lower-level controller layer documented only as supporting context, while steering most readers toward the public React hooks in @dyrected/react and Vue composables in @dyrected/vue.
    • @dyrected/[email protected]
    • @dyrected/[email protected] (@dyrected/admin)
  • @dyrected/[email protected]

  • @dyrected/[email protected] (dyrected)

  • Rewrite the public API docs around end-user goals instead of internal architecture.

    • Rework the overview for hooks and composables so it starts from the jobs developers are trying to get done, such as media uploads, media picking, document editing, custom fields, and theme-aware shells.
    • Add focused documentation pages for media, form and field, and theme APIs in apps/docs, with practical guidance for custom components, dashboards, and host apps rather than framing them only as admin internals.
    • Keep the lower-level controller layer documented only as supporting context, while steering most readers toward the public React hooks in @dyrected/react and Vue composables in @dyrected/vue. (@dyrected/react, @dyrected/vue)

v2.6.1

  • Improve workflow editing UX in the Admin for workflow-enabled and drafts: true collections. Editors now get faster transition actions in the entry header and list view, clearer live-vs-draft status messaging, desktop labels for header action buttons, and a manual "save draft" fallback alongside workflow transitions.

    Add workflow-aware draft autosave config to collection admin options with admin.autosave and admin.autosaveDelayMs. Workflow-enabled collections now default to autosaving draft revisions without changing the published snapshot, while projects can still disable autosave per collection when they need explicit manual saves. (@dyrected/admin, @dyrected/core)


v2.6.0

  • Add typed collection search config and backend-powered admin search across core, admin, and SDK.

    Improve admin document titles and list cell rendering for relationship, object, and array values, including nested relation title chains and nested field admin.useAsTitle.

    Add join-field admin actions to show or hide Create new and View all, with View all opening the related collection list pre-filtered by the join relationship. (@dyrected/admin, @dyrected/core, @dyrected/sdk)


v2.5.65

    • Keep the edit-form change-password section inside the default tab when a collection has multiple tabs.
    • Populate nested join fields when the requested depth budget allows it, while leaving them unpopulated when depth is exhausted.
    • Reuse a shared Postgres client per connection URL so repeated adapter construction in dev servers does not exhaust database connections. (@dyrected/admin, @dyrected/core, @dyrected/db-postgres)

v2.5.64


v2.5.63

  • Fix workflow and draft handling across the admin UI and core collection APIs.

    • stop showing the admin publishing status column for collections that only define a user status field
    • show workflow state labels and colors consistently in admin list and edit views
    • return published workflow documents correctly in public reads, including legacy entries without a materialized published snapshot
    • materialize workflow metadata on update responses so the admin can keep draft and transition state in sync
    • improve the example auth roles setup and docs so custom auth roles fields use the expected array-backed shape (@dyrected/admin, @dyrected/core)

v2.5.62

  • Use server-backed logout and clear revoked stored admin sessions

    The admin provider still treated logout as a purely client-side action after Dyrected auth moved to revocable server-backed sessions. Logging out from the admin cleared local storage, but it did not call the server logout route, so the current session stayed valid until expiry. The provider also kept dead tokens in local storage when bootstrapping me() failed, which caused repeated failed auth requests on reload after a session had already been revoked.

    The admin provider now calls the collection logout route before clearing local state, so admin logout actually revokes the current session. It also clears persisted auth state only on real stale-auth failures during bootstrap (401 / 404), so revoked or invalid stored sessions are cleaned up automatically without treating unrelated network errors as a logout. (@dyrected/admin)

  • Fix token-mode live preview never showing the draft

    In previewMode: "token", the preview pane minted a valid token but discarded it before it reached the iframe, so the frame kept loading published content and never reflected edits. The mint effect depended on the data object, so it re-ran on every parent render; its cleanup cancelled the in-flight mint, and the if (cancelled) return guard then skipped applying the token. The constant re-runs also cleared the debounce timer, so minting eventually stopped firing on edits.

    The effect now depends on a stable serialized key of the draft instead of the object, so it only re-runs on a real edit — cancellation now means "the draft changed again," and a successful mint is applied to the iframe as intended. (@dyrected/admin)

  • Type the SDK client and framework hooks against your generated schema automatically

    Previously the framework hooks were loosely typed: React's client came through context as DyrectedClient<BaseSchema>, and the Vue composables took an untyped collection: string with a hand-annotated <T = any> result. You got no slug autocomplete and no document types unless you passed a generic at every call site.

    Now dyrected generate:types emits a module augmentation that registers your schema globally:

    // dyrected-types.ts (generated)
    declare module "@dyrected/sdk" {
      interface Register {
        schema: DyrectedSchema;
      }
    }

    Once that generated file is part of your compilation, the SDK client and every framework hook (React, Vue, and Nuxt via auto-import) are typed against your schema with no per-call generics:

    // Vue
    const { docs } = useDyrectedCollection("posts"); // "posts" autocompleted, docs: Post[]
    
    // React
    const { client } = useDyrected();
    const { docs } = await client.collection("posts").find().exec(); // typed

    The mechanism is a new Register seam in @dyrected/sdk; DyrectedClient and createClient now default their schema type parameter to the registered schema, falling back to BaseSchema until the generated types are present. Existing code that passed an explicit schema generic is unchanged.

    Note for Vue: useDyrected, useDyrectedCollection, and useDyrectedGlobal now take a collection/global slug as their first type parameter. To override the inferred document type, pass both — useDyrectedCollection<"posts", CustomPost>("posts").

    Generated types now land in your app's source directory. generate:types (and sync:schema) write dyrected-types.ts into src/ (Vite/Next) or app/ (Nuxt) instead of the project root. This is required for the schema augmentation to take effect: TypeScript only applies a declare module augmentation when the file is inside the program's include globs, and a dyrected-types.ts at a Nuxt project root is silently ignored. Your dyrected.config.ts stays at the project root. Pass --output to override the location.

    Generator correctness fixes:

    • Auth collections no longer emit a duplicate roles property. When your collection declares its own roles field (e.g. a select/radio with options), that definition wins — you get the enum union "admin" | "editor" | "viewer" instead of a conflicting second roles?: string[] declaration (which was a TypeScript error).
    • multiSelect fields now generate an array of the option literals — ("admin" | "editor")[] — instead of a loose string[], so multi-valued fields like roles stay typed as their allowed values.
    • The SDK's schema-generic constraint was loosened to a SchemaShape bound so a generated DyrectedSchema (built from named interfaces, which lack an implicit index signature) satisfies it. Previously the augmentation silently fell back to BaseSchema.

    The Nuxt composables (useDyrectedDoc, useDyrectedCollection, useDyrectedGlobal) now return a properly typed AsyncData<...> instead of any — their data is typed as your document/global shape — and are constrained to your schema's slugs. (dyrected, @dyrected/react, @dyrected/sdk, @dyrected/vue)

  • Add built-in API rate limiting, proxy-aware client IP resolution, and revocable auth sessions

    Dyrected auth and request protection were missing three production layers that Payload already treats as part of the core server contract: app-level request throttling, correct client-IP handling behind proxies, and a way to revoke JWT sessions immediately instead of waiting for expiry.

    createDyrectedApp now mounts an in-process API rate limiter with Payload-style defaults for /api routes, including configurable max, window, paths, skip, and trustProxy options. Client IP resolution now understands common provider headers and trusted X-Forwarded-For chains so production deployments behind a reverse proxy count the right caller instead of the proxy hop.

    Auth collections also move from purely stateless login tokens to JWTs backed by hidden __auth_sessions records. New tokens carry a session id, auth middleware validates that the backing session is still active, logout can revoke the current session immediately, ?allSessions=true can revoke every session for the account, and password reset / password change now invalidate active sessions as a security boundary. Refreshing a token keeps the same underlying session instead of creating a second one silently.

    The docs and OpenAPI surface were updated to match the new behavior, especially around built-in rate limiting, trusted proxy setup, logout semantics, and session revocation. (@dyrected/core)

  • Point package-distributed documentation references at the canonical /docs tree

    The docs site no longer maintains a separate /new-docs content tree and route. The new authored docs set now lives directly under the canonical /docs path, and the knowledge generator, published references, and package JSDoc links were updated to match.

    For @dyrected/core, this updates JSDoc @see links so generated API references and editor tooling point at the current docs URLs instead of the removed /new-docs paths.

    For @dyrected/knowledge, this refreshes generated references, prompt artifacts, LLM indexes, and skill outputs so published knowledge bundles link to the canonical docs paths and no longer depend on removed legacy recipe/reference pages. (@dyrected/core)

  • Add definePublishingWorkflow to map your own role names onto the publishing workflow

    publishingWorkflow() hardcoded the role names editor, publisher, and admin, so a project whose roles are named differently (e.g. writer, managing-editor) got no capabilities and couldn't move documents through the flow.

    definePublishingWorkflow({ editors, publishers }) builds the same draft → in review → published workflow but maps your role values onto its two capability tiers — editors may edit and submit, publishers may also publish and unpublish. publishingWorkflow() is now a shorthand for definePublishingWorkflow() with the conventional defaults, so existing usage is unchanged.

    workflow: definePublishingWorkflow({
      editors: ["writer"],
      publishers: ["managing-editor", "admin"],
    });
    ``` (`@dyrected/core`)
    
  • Fix drafts: true documents disappearing from the Admin list

    The publishing workflow synthesized from drafts: true (simplePublishingWorkflow) defined no role→capability mappings, so canViewWorkflowDraft returned false for everyone — including admins and editors. Every draft document was then filtered out of collection reads, leaving the Admin list empty.

    canViewWorkflowDraft now treats a workflow with no roles (the drafts: true case) as ungated: any authenticated user can view drafts, so they show up in the Admin regardless of what a project names its roles. Unauthenticated/public readers still only ever see published content, so drafts never leak to the live site. Workflows that define explicit roles keep their existing capability-based gating. (@dyrected/core)

  • Add Payload-style logger config and first-class observability to Dyrected core

    Dyrected now supports a root logger config shaped like Payload's Pino-based logger surface, plus a new top-level observability config for request logging, redaction, sampling, tracing, metrics, and Dyrected-managed transports.

    Request logging is now structured instead of ad hoc string output. Successful requests are sampled, 4xx requests log at warn, 5xx requests log at error, and request ids, site/workspace ids, and trace correlation fields are included when available.

    Body logging is opt-in and bounded. Dyrected only attempts to capture JSON request bodies, redacts common secret fields and headers before logging, truncates oversized payloads, and falls back to metadata-only logging when a body cannot be parsed safely after capture.

    Core services and request paths now use structured logger helpers instead of direct console.* calls. This includes auth, audit-failure reporting, email delivery failures, router warnings, workflow hook isolation, and request error handling.

    OpenTelemetry tracing and metrics are now available behind explicit config. Dyrected can create request spans, emit request and failure metrics, export telemetry through OTLP, and expose a Prometheus scrape route only when configured. Audit logging remains a separate feature and is not merged with runtime observability. (@dyrected/core)


v2.5.61

  • Admin: brand accent color, wired page metadata, and list export

    • Add admin.branding.accentColor — a second brand color for links, navigation accents, and focus rings (mapped to the --intelligence token) alongside primaryColor. Branding colors now also apply correctly in dark mode.
    • Wire admin.meta.titleSuffix into the browser tab title (it now reflects the current page and updates on navigation) and admin.branding.favicon into the page favicon. Both restore the host page's title/icon when the embedded admin unmounts.
    • Add an Export Selected bulk action on collection lists (export just the selected rows to CSV), and quote/escape CSV export values per RFC 4180 so values containing commas, quotes, or newlines no longer break columns.

    Breaking (shipped as patch): removed the no-op basename prop from AdminUIProps and the @dyrected/vue / @dyrected/nuxt wrappers, and stopped the CLI from scaffolding it. The admin routes internally with a hash router, so the panel's location is determined by the route of the page you render it in. If your app passes basename, remove it — it had no effect.

  • Fix audit log and drafts/workflow panels not appearing in the Admin

    Three related fixes so audit: true and drafts: true surface their Admin UI as intended:

    • Audit log button never showed. The /api/schemas response hand-serialized each collection and omitted the audit and drafts flags, so the Admin's schema.audit was always undefined and the audit-history button never rendered regardless of config. Both flags are now included in the serialized schema.
    • Workflow/version panel hidden for existing documents. Setting drafts: true synthesizes a publishing workflow via normalizeConfig, but the panel only appears when a document carries __workflow metadata — which documents created before the workflow existed (e.g. seeded content) don't have. materializeWorkflowDocument now treats such legacy documents as already-published live content: it surfaces them with the workflow's published state (keeping them visible to the public) so the workflow panel appears. New documents are unaffected.
    • Live/Draft badge missing on workflow collections. The header publishing badge only rendered for collections without a workflow, and read the raw status field. It now derives from the workflow state when a workflow is present (a state flagged published shows "Live", otherwise "Draft"), so collections using drafts: true — including ones with no status field — show the correct badge. (@dyrected/admin, @dyrected/core)
  • Server-side (token) live preview now works end to end

    previewMode: "token" was previously a config value with backend endpoints but no admin integration. It's now wired up for server-rendered and statically generated frontends that can't receive postMessage.

    • @dyrected/admin: in token mode the live-preview pane mints a short-lived token from the current draft (debounced) and loads the frontend iframe at previewUrl?dyPreview=<token>, reloading on change. Click-to-edit and live-as-you-type remain postMessage-only.
    • @dyrected/sdk: new createPreviewToken({ collectionSlug, documentId?, data }) to mint a token, plus getPreviewToken(search) and PREVIEW_TOKEN_PARAM helpers for reading the dyPreview token from a request's query string. @dyrected/react and @dyrected/vue re-export the helpers; @dyrected/nuxt auto-imports getPreviewToken.
    • @dyrected/core: the server now logs a startup warning when DYRECTED_JWT_SECRET is unset, since token-mode preview signs with it.

    Token mode is refresh-based (a mint + iframe reload per change) and embeds the draft in the signed token — see the Live Preview → Server-side docs for the security notes (set DYRECTED_JWT_SECRET) and the large-document URL-length caveat.

  • Vue bridge shares the host app context, CLI sync respects DYRECTED_URL

    • @dyrected/vue: custom Vue components in the admin (custom field inputs and dashboard/list slots) now share the host app's context instead of each mounting an isolated Vue app. They can use the host app's plugins, provide/inject, Pinia, and i18n, and many custom components no longer spin up one full Vue app per instance.
    • dyrected (CLI): sync:schema now honors DYRECTED_URL (and the NEXT_PUBLIC_ / NUXT_PUBLIC_ / VITE_ variants) from your environment. Previously the --url option's hardcoded default masked the env fallback, so it always synced to Dyrected Cloud regardless of your configured URL.
    • @dyrected/admin: fix the admin browser-title helper resolving a collection's label — it read a non-existent collection.label (collections use labels.singular / labels.plural), which broke the package build. Also corrected the misleading AdminComponents JSDoc (fields is keyed by the field's admin.component string, not field type; collectionList injects list slots rather than replacing the list view). (@dyrected/admin, dyrected, @dyrected/vue)

> For earlier release notes (v0.x), see the full CHANGELOG.md on GitHub.

On this page

Dyrected| Cloud

Get your backend ready in minutes

Use a managed database, storage, APIs, and admin dashboard without setting up the infrastructure yourself.

Set Up My Backend