Skip to content

Releases: arkstack-hq/arkormx

2.0.4

24 Apr 08:15

Choose a tag to compare

This release introduces configurable inferred model table casing, with a new snake_case default.

Highlights

  • Added user-configurable table name casing for inferred model tables.
  • Changed the default inferred table casing from camelCase to snake_case.
  • Limited case options to modes supported by the string helper pipeline for consistent behavior.

Added

  • New runtime config option under naming:
    • modelTableCase

Supported values:

  • snake
  • camel
  • kebab
  • studly

Changed

  • Model.getTable now resolves inferred table names using the configured naming.modelTableCase.
  • If no explicit table is set on a model, inferred names now default to snake plural form.

Compatibility Notes

  • Models with an explicit table value are unchanged.
  • Existing projects that relied on inferred camelCase table names should set naming.modelTableCase to camel to preserve previous behavior.

Example Config

export default defineConfig({
  naming: {
    modelTableCase: 'camel',
  },
})

Validation

  • Added regression coverage for:
    • snake_case default inference
    • camel override via runtime config
  • Targeted runtime configuration test suite passes.

Full Changelog: 2.0.2...2.0.4

2.0.2

24 Apr 07:50

Choose a tag to compare

This patch release adds first-class direct raw query support through the DB facade, enabling SQL execution without creating a table-scoped query builder first.

Highlights

  • Added DB.raw for direct raw SQL queries from the DB facade
  • Added transaction-scoped raw query support through db.raw inside DB.transaction
  • Added adapter-level rawQuery contract for consistent raw execution across adapters
  • Added Kysely adapter rawQuery implementation with structured error context and inspection metadata
  • Added regression tests for success, transaction routing, and unsupported-adapter behavior

Added

  • Static DB.raw(sql, bindings?) returning an ArkormCollection
  • Instance db.raw(sql, bindings?) for transaction-scoped use
  • RawQuerySpec in adapter types to standardize raw SQL + bindings payload
  • Optional adapter rawQuery capability hook in the DatabaseAdapter interface

Behavior

  • Raw queries now work directly via DB.raw once an adapter is configured
  • Raw queries inside DB.transaction correctly execute on the transaction adapter
  • If no adapter is configured, DB.raw throws an adapter-not-configured error
  • If the active adapter does not implement rawQuery, DB.raw throws an unsupported feature error

Adapter Support

  • KyselyDatabaseAdapter now supports rawQuery execution and returns row arrays
  • Raw query failures in Kysely are wrapped in QueryExecutionException with adapter inspection details

Tests

  • Added base DB facade regression coverage for:
    • Direct DB.raw success path
    • Transaction-scoped db.raw routing
    • Unsupported adapter feature rejection

Notes

  • This is a backward-compatible patch release focused on raw-query ergonomics and adapter parity.
  • No breaking changes introduced in v2.0.2.

Full Changelog: 2.0.0...2.0.2

2.0.0

24 Apr 06:52

Choose a tag to compare

Arkorm 2.0.0 marks the completion of the adapter-first migration (Phase 1 - Phase 7).
The runtime is now fully adapter-first by default, with Prisma support retained as an explicit compatibility path for the 2.x line.

Highlights

  • Completed the full migration from delegate-shaped internals to adapter-first execution.
  • Established Arkorm-owned query and relation planning as the primary runtime model.
  • Added and matured SQL-backed execution through the Kysely adapter.
  • Kept Prisma available as a compatibility adapter during 2.x, with clear capability boundaries.
  • Finalized docs, tests, and merge-readiness criteria for the 2.0 baseline.

What Is New In 2.0.0

Adapter-first architecture is now baseline

  • Model and query execution now run through Arkorm adapter contracts.
  • Core internals no longer rely on Prisma delegate semantics in normal runtime paths.
  • Adapter capabilities define supported advanced features explicitly.

Query and typing surface modernization

  • Core typing now uses neutral query-schema contracts.
  • Delegate-shaped helper names remain only as compatibility aliases in 2.x.
  • Arkorm-owned specs now drive relation filtering, aggregation, and eager loading behavior.

Relation execution and eager loading

  • Set-based eager loading is fully integrated for core relation types.
  • Constrained eager loading is compiled into Arkorm relation load plans.
  • Model.load and QueryBuilder.with share the same adapter-first relation planning path.

Kysely/Postgres execution maturity

  • Core CRUD, pagination, relation filters, and relation aggregates are SQL-backed on Kysely.
  • Postgres conflict-handling and RETURNING-aware mutation paths are supported.
  • Query-shape and parity regressions were expanded to protect adapter-first behavior.

Prisma compatibility in 2.x

  • Prisma remains supported as a compatibility adapter.
  • Unsupported compatibility edges now fail explicitly instead of silently degrading.
  • Delegate-first APIs are deprecated compatibility surfaces, with removal targeted for 3.0.

Migration Notes

If you are upgrading from 1.x

  • Move runtime bootstrap to adapter-first configuration.
  • Prefer one top-level adapter for application runtime.
  • Keep Prisma only where compatibility behavior is intentionally required.
  • Treat deprecated delegate-first APIs as transitional and avoid them in new code.

If you are already on 2.0.0-next.x

  • 2.0.0 consolidates and stabilizes the completed Phase 1 - Phase 7 migration work.
  • Adapter-first behavior should now be considered the default contract for new development.

Compatibility and Deprecations

  • Prisma compatibility adapter remains supported through the 2.x line.
  • Deprecated delegate-first APIs and delegate-shaped aliases remain compatibility-only in 2.x.
  • Removal target for those deprecated compatibility surfaces is Arkorm 3.0.

Validation and Quality

  • Regression and parity coverage now verify adapter-first behavior across Prisma compatibility and Kysely paths.
  • Relation execution, eager loading, relation filters, and aggregates are covered through focused integration scenarios.
  • Full-suite validation has been maintained as part of the migration closeout.

Thank You

Thank you to everyone who tested migration paths, reported edge cases, and helped validate the adapter-first architecture across real workflows.

Full Changelog: 1.3.2...2.0.0

2.0.0-next.27

24 Apr 05:04
73fd19b

Choose a tag to compare

2.0.0-next.27 Pre-release
Pre-release

This release advances the Phase 7 adapter-first migration across items #4 through #11. The core runtime and type system now treat adapters and neutral query-schema contracts as the primary model, while Prisma-shaped behavior is kept only as an explicit compatibility layer during the 2.x transition window.

What's Changed

  • Replaced Prisma-shaped core generic constraints with adapter-native query schema contracts across Model, QueryBuilder, ModelStatic, DB, and the shared core/model type helpers.
  • Introduced neutral QuerySchema* and AttributeQuerySchema helpers as the primary public typing surface, while keeping older delegate-shaped names available as deprecated compatibility aliases.
  • Moved transaction typing and runtime flow to adapter-first contracts, including neutral TransactionContext, TransactionOptions, and runtime client handling instead of Prisma-specific callback assumptions.
  • Updated transaction execution so adapter-backed transactions propagate through runtime storage and keep Model.query() and DB.table() inside the active transaction scope.
  • Centralized compatibility fallback behavior in the runtime compatibility layer instead of rebuilding delegate resolution paths in multiple runtime entry points.
  • Removed the remaining runtime dependency on Model.getDelegate() for relation execution, eager loading fallback paths, relation filters, relation aggregates, and Model.load(...).
  • Added adapter-owned relation loading for the Kysely path, including nested eager-load execution through adapter.loadRelations(...) without reintroducing delegate-based runtime behavior.
  • Isolated the remaining Prisma compatibility gaps behind explicit capability flags and targeted unsupported-feature errors instead of allowing them to leak as implicit runtime behavior.
  • Unified constrained eager loading, relation aggregates, and relation filters around Arkorm-owned relation specs by compiling with({...}) callbacks into RelationLoadPlan structures and reusing the same path in Model.load(...).
  • Renamed remaining non-compatibility delegate-oriented internals to table terminology in model generation, schema sync helpers, and bundled stubs, while preserving legacy delegate parsing only where compatibility still requires it.

Documentation

  • Updated the migration plan, roadmap, README, and versioned guides to reflect the adapter-first runtime as the real primary path.
  • Updated the upgrade guidance so normal model overrides now use table terminology instead of teaching delegate as the default pattern.
  • Clarified that Model.setClient(...), Model.getDelegate(...), direct delegate-map helpers, and the static delegate alias remain compatibility-only during the 2.x window.

Compatibility Notes

  • Prisma compatibility remains available, but it is now more explicitly scoped.
  • Direct Prisma include-style relation plans still work through the compatibility adapter where supported.
  • Adapter-owned relation batch loading, raw SQL predicate paths, and similar unsupported compatibility surfaces now fail explicitly instead of falling back silently.
  • Deprecated delegate-shaped aliases such as PrismaDelegateLike remain temporarily available so existing integrations can continue compiling during the migration window.

Testing

  • Added and expanded regression coverage for adapter-first relation execution, Kysely-owned eager loading, constrained eager-load planning, Prisma compatibility boundaries, and CLI/model-generation terminology updates.
  • Current repo validation remains green under the full test suite via pnpm test:all.

Migration Impact

If you are already on the next line, this release continues the same migration direction:

  • Prefer adapter-backed setup and execution paths.
  • Treat delegate-first APIs as compatibility-only.
  • Use neutral query-schema and table terminology in new code.
  • Expect unsupported Prisma-compatibility edge cases to fail explicitly rather than degrade silently.

Full Changelog: 2.0.0-next.26...2.0.0-next.27

2.0.0-next.26

23 Apr 01:57

Choose a tag to compare

2.0.0-next.26 Pre-release
Pre-release

Highlights

  • Moved Arkorm core further from Prisma-shaped internals to adapter-native contracts
  • Made transaction handling adapter-first, including transaction-scoped adapter propagation
  • Isolated Prisma compatibility behavior behind dedicated helper layers instead of spreading it through core runtime classes
  • Reduced delegate-first Model APIs to compatibility-only transition members
  • Renamed table-backed relation internals away from delegate terminology where runtime behavior already uses tables
  • Proved normal runtime queries no longer depend on Model.getDelegate

What’s Changed

  • Added adapter-native ModelQuerySchemaLike as the primary query-shape contract in the core type system
  • Switched Model, QueryBuilder, ModelStatic, DB, and model typing helpers to compile against adapter-native schema types instead of PrismaDelegateLike-first generics
  • Introduced neutral transaction contracts with RuntimeClientLike, TransactionContext, and TransactionOptions
  • Updated Model.transaction to prefer adapter-backed transactions and keep Model.query and DB.table inside the active transaction scope
  • Centralized Prisma compatibility adapter and query-schema fallback in runtime-compatibility helpers
  • Made Model.getDelegate a thin deprecated compatibility wrapper instead of a runtime control path
  • Marked Model.setClient, Model.getDelegate, Model.delegate, and direct delegate-map bootstrapping as compatibility-only migration APIs rather than supported primary runtime setup
  • Renamed throughDelegate to throughTable across through and pivot relation code where the runtime contract is already table-backed
  • Added regression coverage proving adapter-backed runtime queries do not go through Model.getDelegate
  • Updated the migration plan and roadmap to reflect the completed early Phase 7 items

Compatibility Notes

  • Prisma compatibility remains supported during the 2.x transition window
  • Deprecated delegate-first APIs still exist for migration support, but they no longer shape the primary runtime surface

Full Changelog: 2.0.0-next.25...2.0.0-next.26

2.0.0-next.25

18 Apr 17:35

Choose a tag to compare

2.0.0-next.25 Pre-release
Pre-release

What's Changed

Fix query delete behavior when no rows match

QueryBuilder.delete() no longer throws when a constrained delete finds no matching row. It now returns null, which fixes cases like User.query().whereNot({ id: demoUser.id }).delete() behaving as an unexpected failure instead of a no-op.

Add explicit throwing delete variant

Added QueryBuilder.deleteOrFail() for callers that need the previous fail-fast behavior. This preserves a strict path for workflows that expect a deleted model instance or an error.

Keep model instance deletes strict

Model.delete() and Model.forceDelete() now delegate to deleteOrFail(), so deleting a concrete model instance still throws if the underlying row cannot be found. The nullable behavior is limited to query-builder deletes.

Add regression coverage

Added base and Postgres query-builder tests covering:

  • non-unique constrained deletes that match no rows now returning null
  • row-count stability when the delete is a no-op
  • deleteOrFail() continuing to throw Record not found for delete operation.

Full Changelog: 2.0.0-next.23...2.0.0-next.25

2.0.0-next.23

10 Apr 13:09

Choose a tag to compare

2.0.0-next.23 Pre-release
Pre-release

What's Changed

Added nested eager loading support

Arkorm eager loading now supports dotted child relation paths such as with(['requester', 'pocket', 'consents', 'consents.user']) and load(['consents.user']). Parent relations are loaded first, then child relations are eager loaded onto the resolved related models.

Eager loading now fails fast on invalid relations

Invalid eager-loaded relation names are no longer silently ignored. Arkorm now throws RelationResolutionException for both direct missing relations and nested missing relation paths during with(...) and load(...).

Added regression coverage

Base relationship tests now cover nested eager loading through both query-time and instance-time APIs, along with failure cases for undefined eager-loaded relationships.

Full Changelog: 2.0.0-next.21...2.0.0-next.23

2.0.0-next.21

09 Apr 18:22

Choose a tag to compare

2.0.0-next.21 Pre-release
Pre-release

What's Changed

BelongsToMany write helpers

BelongsToManyRelation now supports storage-oriented helpers for many-to-many relationships, including make(), create(), save(), attach(), detach(), and sync(). These helpers work through the adapter layer rather than assuming Prisma-only behavior, so non-Prisma adapters can manage pivot rows directly as part of normal relationship workflows.

Relationship typing fixes

The model attribute typing work was tightened so relationship-aware getAttribute() and setAttribute() keep strong inference without breaking Model.query() usage or causing circular type expansion in relation-heavy models and tests. This restores stable typing for eager-loaded relationships and declared model properties while preserving the newer relationship payload inference.

Pivot reconciliation improvements

Many-to-many pivot operations now support:

  • attaching multiple related records
  • detaching one, many, or all related records
  • syncing relationship membership in one operation
  • updating pivot attributes during sync
  • transaction-backed reconciliation through the active adapter

This closes the gap between read-side belongs-to-many ergonomics and write-side behavior.

Non-Prisma adapter coverage

PostgreSQL integration coverage was expanded for the Kysely adapter path to verify belongs-to-many write helpers end to end against a non-Prisma adapter. This includes create/save/attach/detach/sync behavior on real pivot tables, not just the Prisma-compatible runtime path.

Test and fixture cleanup

The base relationship fixtures and specs were updated to match the new typing and write-helper behavior, including fixes for prior core-fixtures and relationships.spec errors. Additional regression coverage now verifies pivot payload handling and membership changes after detach/sync operations.

Fixes

  • Fixed missing storage methods on BelongsToManyRelation.
  • Fixed relation typing regressions that caused circular references and broken query() inference.
  • Fixed adapter-backed pivot deletion behavior for composite-key pivot tables in the Kysely/Postgres path.

Tests

  • Added base relationship coverage for belongs-to-many write helpers.
  • Added base coverage for detach() and sync().
  • Added PostgreSQL Kysely integration coverage for many-to-many write helpers on the non-Prisma adapter path.

Full Changelog: 2.0.0-next.20...2.0.0-next.21

2.0.0-next.20

09 Apr 13:50

Choose a tag to compare

2.0.0-next.20 Pre-release
Pre-release

What’s Changed

Typed getAttribute() / setAttribute() inference

  • Improved getAttribute() so it now infers the return type from declared model properties, not just schema/generic attributes.
  • Improved setAttribute() so writes against declared model properties are type-checked consistently with getAttribute() reads.

Declared property support

  • Models with explicit declarations like declare name: string now get strongly typed attribute access:
    • user.getAttribute('name') resolves to string
    • user.setAttribute('name', value) enforces string

Relationship-aware attribute access

  • Extended attribute typing to relationship method keys when the relationship has been loaded onto the model.
  • getAttribute() now resolves the expected relationship payload type from the relationship method’s getResults() contract:
    • single-result relations resolve to RelatedModel | null
    • multi-result relations resolve to ArkormCollection<RelatedModel>
  • setAttribute() mirrors that behavior for assigning eager-loaded relationship payloads.

Type utilities

  • Added internal model relationship typing helpers to derive:
    • which model method names represent relationships
    • what resolved payload type each relationship exposes

Test coverage

  • Added type-level regression coverage for:
    • generic attribute inference
    • declared property inference
    • relationship payload inference for hasOne and hasMany
    • typed setAttribute() parity with getAttribute()

Developer Impact

  • Better IDE autocomplete and stronger compile-time guarantees when reading or assigning model attributes.
  • Less need for manual casts around eager-loaded relationships and declared model fields.

Full Changelog: 2.0.0-next.17...2.0.0-next.20

2.0.0-next.17

09 Apr 06:44

Choose a tag to compare

2.0.0-next.17 Pre-release
Pre-release

What’s Changed

PostgreSQL enum naming

  • Fixed generated PostgreSQL enum type names for non-Prisma migration flows to include the table name, so a users.status enum now becomes users_status_enum instead of the globally-colliding status_enum.
  • Added regression coverage to ensure multiple tables can declare same-named enum columns without type-name conflicts.

Many-to-many relation ergonomics

  • Added Laravel-style pivot helpers to belongs-to-many relations, including withPivot, withTimestamps, as, using, wherePivot, wherePivotNotIn, wherePivotBetween, wherePivotNotBetween, wherePivotNull, and wherePivotNotNull.
  • Extended relation metadata and eager-loading behavior so pivot fields and aliases are preserved consistently across relation loading.
  • Improved pivot hydration so executing terminal operations from relation queries still keeps pivot payloads attached.

Query debugging and inspection

  • Added query inspection support for adapters that can expose compiled queries.
  • Added QueryBuilder inspection support for select, single-record select, count, and exists flows.
  • Added structured query execution error wrapping through QueryExecutionException so adapter failures surface consistent Arkorm error context.
  • Included compiled SQL and bound parameters in wrapped Kysely execution errors when available.
  • Added runtime debug configuration with support for either a boolean flag or a custom callback handler.
  • Enabled structured debug events around database activity, including before, after, and error phases for adapter-backed operations.

Adapter improvements

  • Enhanced the Kysely adapter to centralize compiled-query handling for inspection, debug logging, and execution error reporting.
  • Enhanced the Prisma adapter to emit structured debug events and wrap raw delegate execution failures in Arkorm exceptions.
  • Preserved the current Prisma boundary where SQL inspection is unavailable rather than returning guessed or partial SQL.

What's Changed

Full Changelog: 2.0.0-next.2...2.0.0-next.17