Releases: arkstack-hq/arkormx
2.0.0-next.23
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
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()andsync(). - 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
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 withgetAttribute()reads.
Declared property support
- Models with explicit declarations like
declare name: stringnow get strongly typed attribute access:user.getAttribute('name')resolves tostringuser.setAttribute('name', value)enforcesstring
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’sgetResults()contract:- single-result relations resolve to
RelatedModel | null - multi-result relations resolve to
ArkormCollection<RelatedModel>
- single-result relations resolve to
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
hasOneandhasMany - typed
setAttribute()parity withgetAttribute()
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
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
- Add 'next' branch to CI workflow triggers by @3m1n3nc3 in #2
- Update deploy-docs.yml by @3m1n3nc3 in #3
Full Changelog: 2.0.0-next.2...2.0.0-next.17
2.0.0-next.9
What's Changed
This release improves the DB facade so DB.table(...) can now reuse persisted table metadata from .arkormx/column-mappings.json when explicit table metadata is not provided.
Added
DB.table(...)now falls back to persisted table metadata by default.- Raw table queries can now automatically pick up:
- persisted column mappings
- persisted primary key generation metadata
- persisted managed timestamp metadata
- Added
persistedMetadatacontrols toDatabaseTableOptionsfor:- disabling persisted metadata fallback
- overriding persisted metadata lookup options such as custom
cwd, configured path, and strictness
Improved
DB.table(...)now behaves more likeModelfor adapter-backed metadata resolution.- Explicit
DB.table(..., options)metadata still wins over persisted metadata when both are present. - Raw table inserts can now inherit persisted generated key and timestamp behavior without requiring duplicate manual config.
Testing
- Added DB facade coverage for persisted metadata fallback.
- Added DB facade coverage for explicit override and opt-out behavior.
- Verified the full test suite passes after the change.
Full Changelog: 2.0.0-next.8...2.0.0-next.9
2.0.0-next.8
What's New
This release introduces a new DB facade for adapter-first, raw table access without needing a Model class. It is designed for cases where you want Arkorm's query builder ergonomics without model hydration, relations, scopes, or lifecycle behavior.
Added
- Added
DB.table(...)for querying tables directly through Arkorm's existing query builder pipeline. - Added table-level metadata support for raw queries, including custom primary keys, column mappings, soft delete config, generated primary keys, and managed timestamps.
- Added
DB.transaction(...)for transaction-scoped raw table access, with support for reusing the transaction adapter inside the callback. - Exported the new DB facade and related DB table option types from the public package surface.
Improved
- Reused the existing
QueryBuilderinternals through a lightweight table-backed shim instead of introducing a parallel query system. - Ensured raw table writes can participate in the same generated primary key and managed timestamp behaviors already implemented for non-Prisma adapter flows.
- Preserved adapter-first usage patterns while making transaction-scoped raw queries much easier to express.
Documentation
- Added archived documentation for
DB.table(...)in the query builder guide. - Added archived documentation for
DB.transaction(...)in the transactions guide.
Full Changelog: 2.0.0-next.7...2.0.0-next.8
2.0.0-next.7
What's New
This release improves timestamp handling for non-Prisma adapters by bringing createdAt and updatedAt behavior into Arkorm's persisted metadata and runtime write pipeline.
Timestamp metadata for non-Prisma models
- Added persisted timestamp column metadata so adapter-backed models can understand timestamp behavior outside Prisma.
- Model metadata now exposes managed timestamp columns declared through migrations.
Runtime timestamp fallback
- Non-Prisma inserts now auto-fill missing managed timestamp fields when the schema declares them.
createdAtis populated when the column is configured withdefault: 'now()'.updatedAtis populated on insert and refreshed automatically on update when the column is marked as managed.
Scope of behavior
- Plain
timestamp()columns are not auto-managed unless they explicitly carry timestamp behavior metadata. timestamps()remains the intended convention for managedcreatedAt/updatedAtcolumns.
Full Changelog: 2.0.0-next.6...2.0.0-next.7
2.0.0-next.6
What's New
This release improves primary key handling across Arkorm's migration, metadata, and persistence layers, especially for non-Prisma adapters.
Primary Key Generation
- Added primary key generation metadata to schema column definitions.
table.uuid('id').primary()andtable.id('id', 'string').primary()now carry explicit generation hints.- Prisma schema generation now uses that metadata to emit sensible defaults like
@default(uuid()). - Kysely-backed schema execution now applies native database defaults such as
gen_random_uuid()andgen_random_uuid()::text.
Non-Prisma Adapter Support
- Non-Prisma insert paths now auto-fill missing UUID-backed primary keys before persistence when the database does not generate them.
- Model metadata now exposes persisted primary key generation details so query execution can make the right decision at runtime.
- Persisted migration metadata now stores primary key generation configuration alongside column mappings and enums.
Full Changelog: 2.0.0-next.5...2.0.0-next.6
2.0.0-next.5
What's Changed
This release fixes adapter-backed models:sync so persisted column mappings are applied to generated model declarations.
models:syncnow prefers persisted logical attribute names over physical column names when adapter introspection returns mapped database columns- Persisted enum typing now follows the remapped attribute name as well
- Added regression coverage for mapped column sync output such as
account_type -> accountType - Bumped the package version to
2.0.0-next.5
Highlights
The main fix is for adapter-backed model syncing. When persisted metadata says a physical column like account_type maps to a logical model attribute like accountType, Arkorm now generates:
declare accountType: 'personal' | 'family' | 'business' | nullinstead of generating the physical column name in the model declaration.
Full Changelog: 2.0.0-next.4...2.0.0-next.5
What's Changed
- Add 'next' branch to CI workflow triggers by @3m1n3nc3 in #2
- Update deploy-docs.yml by @3m1n3nc3 in #3
New Contributors
Full Changelog: 2.0.0-next.2...2.0.0-next.55
2.0.0-next.22
What's Changed
Added string matching query helpers
Arkorm now includes whereLike(), whereStartsWith(), and whereEndsWith() on both QueryBuilder and relationship queries. These helpers provide a fluent way to express common string filters without dropping down to manual where objects.
Extended relation query ergonomics
The new string filter helpers are also available when chaining relationship queries, so relation calls such as user.posts().whereStartsWith(...) and similar patterns now work consistently with top-level model queries.
Improved in-memory test adapter parity
The base in-memory test runtime was updated to evaluate contains, startsWith, and endsWith filters correctly. This keeps test behavior aligned with the real adapter implementations and closes a gap where those clauses previously fell through in base tests.
Enabled raw where support for the Kysely adapter
The Kysely adapter now supports whereRaw() and orWhereRaw() conditions through parameterized raw SQL bindings. This allows patterns such as:
UserModel.query().whereRaw(
'LOWER("email") = ? OR LOWER("email") LIKE ?',
[`${normalized.cashtagLocalPart}@`, `%${normalized.cashtagLocalPart}@%`],
)to run on the Kysely-backed adapter path.
Preserved Prisma compatibility boundaries
Raw where support remains unavailable on the Prisma compatibility adapter. The new raw SQL support is scoped to the Kysely adapter, while the new string helper methods continue to work across supported adapter paths because they compile down to existing generic comparison operators.
Tests
- Added base query-builder coverage for
whereLike(),whereStartsWith(), andwhereEndsWith() - Added relationship-level coverage for the new string helper methods
- Added PostgreSQL Kysely coverage for parameterized raw where clauses using
LOWER(...)andLIKE
Fixes
- Fixed base in-memory filtering so
contains,startsWith, andendsWithbehave like the real adapters - Fixed the Kysely adapter limitation that rejected raw where clauses even though the query builder exposed
whereRaw()