metal-orm 1.0.16 → 1.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -40
- package/dist/decorators/index.cjs +344 -69
- package/dist/decorators/index.cjs.map +1 -1
- package/dist/decorators/index.d.cts +1 -1
- package/dist/decorators/index.d.ts +1 -1
- package/dist/decorators/index.js +344 -69
- package/dist/decorators/index.js.map +1 -1
- package/dist/index.cjs +567 -181
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +66 -30
- package/dist/index.d.ts +66 -30
- package/dist/index.js +559 -181
- package/dist/index.js.map +1 -1
- package/dist/{select-BKZrMRCQ.d.cts → select-BuMpVcVt.d.cts} +265 -74
- package/dist/{select-BKZrMRCQ.d.ts → select-BuMpVcVt.d.ts} +265 -74
- package/package.json +5 -1
- package/src/codegen/naming-strategy.ts +15 -10
- package/src/core/ast/aggregate-functions.ts +50 -4
- package/src/core/ast/builders.ts +23 -3
- package/src/core/ast/expression-builders.ts +36 -16
- package/src/core/ast/expression-nodes.ts +17 -9
- package/src/core/ast/join-node.ts +5 -3
- package/src/core/ast/join.ts +16 -16
- package/src/core/ast/query.ts +44 -29
- package/src/core/ddl/dialects/mssql-schema-dialect.ts +18 -0
- package/src/core/ddl/dialects/mysql-schema-dialect.ts +11 -0
- package/src/core/ddl/dialects/postgres-schema-dialect.ts +9 -0
- package/src/core/ddl/dialects/sqlite-schema-dialect.ts +9 -0
- package/src/core/ddl/introspect/functions/postgres.ts +2 -6
- package/src/core/dialect/abstract.ts +12 -8
- package/src/core/dialect/base/sql-dialect.ts +58 -46
- package/src/core/dialect/mssql/functions.ts +24 -15
- package/src/core/dialect/mssql/index.ts +53 -28
- package/src/core/dialect/postgres/functions.ts +33 -24
- package/src/core/dialect/sqlite/functions.ts +19 -12
- package/src/core/dialect/sqlite/index.ts +22 -13
- package/src/core/functions/datetime.ts +2 -1
- package/src/core/functions/numeric.ts +2 -1
- package/src/core/functions/standard-strategy.ts +52 -12
- package/src/core/functions/text.ts +2 -1
- package/src/core/functions/types.ts +8 -8
- package/src/index.ts +5 -4
- package/src/orm/domain-event-bus.ts +43 -25
- package/src/orm/entity-meta.ts +40 -0
- package/src/orm/execution-context.ts +6 -0
- package/src/orm/hydration-context.ts +6 -4
- package/src/orm/orm-session.ts +35 -24
- package/src/orm/orm.ts +10 -10
- package/src/orm/query-logger.ts +15 -0
- package/src/orm/runtime-types.ts +60 -2
- package/src/orm/transaction-runner.ts +7 -0
- package/src/orm/unit-of-work.ts +1 -0
- package/src/query-builder/column-selector.ts +9 -7
- package/src/query-builder/insert-query-state.ts +13 -3
- package/src/query-builder/query-ast-service.ts +59 -38
- package/src/query-builder/relation-conditions.ts +38 -34
- package/src/query-builder/relation-manager.ts +8 -3
- package/src/query-builder/relation-service.ts +59 -46
- package/src/query-builder/select-helpers.ts +50 -0
- package/src/query-builder/select-query-state.ts +19 -7
- package/src/query-builder/select.ts +339 -167
- package/src/query-builder/update-query-state.ts +31 -9
- package/src/schema/column.ts +75 -39
- package/src/schema/types.ts +17 -6
package/README.md
CHANGED
|
@@ -105,9 +105,10 @@ If you like explicit model classes, you can add a thin decorator layer on top of
|
|
|
105
105
|
- `@HasMany({ target, foreignKey, ... })`
|
|
106
106
|
- `@HasOne({ target, foreignKey, ... })`
|
|
107
107
|
- `@BelongsTo({ target, foreignKey, ... })`
|
|
108
|
-
|
|
109
|
-
- `bootstrapEntities()` scans metadata, builds `TableDef`s, wires relations with the same `hasOne` / `hasMany` / `belongsTo` / `belongsToMany` helpers you would use manually, and returns the resulting tables.
|
|
110
|
-
- `selectFromEntity(MyEntity)` lets you start a `SelectQueryBuilder` directly from the class.
|
|
108
|
+
- `@BelongsToMany({ target, pivotTable, ... })`
|
|
109
|
+
- `bootstrapEntities()` scans metadata, builds `TableDef`s, wires relations with the same `hasOne` / `hasMany` / `belongsTo` / `belongsToMany` helpers you would use manually, and returns the resulting tables.
|
|
110
|
+
- `selectFromEntity(MyEntity)` lets you start a `SelectQueryBuilder` directly from the class.
|
|
111
|
+
- **Generate entities from an existing DB**: `node scripts/generate-entities.mjs --dialect=postgres --url=$DATABASE_URL --schema=public --out=src/entities.ts` introspects your schema and spits out `@Entity` / `@Column` classes you can immediately `bootstrapEntities()` with.
|
|
111
112
|
|
|
112
113
|
You don’t have to use decorators, but when you do, you’re still on the same AST + dialect + runtime foundation.
|
|
113
114
|
|
|
@@ -325,16 +326,12 @@ const orm = new Orm({
|
|
|
325
326
|
const session = new OrmSession({ orm, executor });
|
|
326
327
|
|
|
327
328
|
// 2) Load entities with lazy relations
|
|
328
|
-
const [user] = await new SelectQueryBuilder(users)
|
|
329
|
-
.
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
.includeLazy('posts') // HasMany as a lazy collection
|
|
335
|
-
.includeLazy('roles') // BelongsToMany as a lazy collection
|
|
336
|
-
.where(eq(users.columns.id, 1))
|
|
337
|
-
.execute(session);
|
|
329
|
+
const [user] = await new SelectQueryBuilder(users)
|
|
330
|
+
.selectColumns('id', 'name', 'email')
|
|
331
|
+
.includeLazy('posts') // HasMany as a lazy collection
|
|
332
|
+
.includeLazy('roles') // BelongsToMany as a lazy collection
|
|
333
|
+
.where(eq(users.columns.id, 1))
|
|
334
|
+
.execute(session);
|
|
338
335
|
|
|
339
336
|
// user is an Entity<typeof users>
|
|
340
337
|
// scalar props are normal:
|
|
@@ -355,10 +352,11 @@ await session.commit();
|
|
|
355
352
|
What the runtime gives you:
|
|
356
353
|
|
|
357
354
|
- [Identity map](https://en.wikipedia.org/wiki/Identity_map_pattern) (per context).
|
|
358
|
-
- [Unit of Work](https://en.wikipedia.org/wiki/Unit_of_work) style change tracking on scalar properties.
|
|
359
|
-
- Relation tracking (add/remove/sync on collections).
|
|
360
|
-
- Cascades on relations: `'all' | 'persist' | 'remove' | 'link'`.
|
|
361
|
-
- Single flush: `session.commit()` figures out inserts, updates, deletes, and pivot changes.
|
|
355
|
+
- [Unit of Work](https://en.wikipedia.org/wiki/Unit_of_work) style change tracking on scalar properties.
|
|
356
|
+
- Relation tracking (add/remove/sync on collections).
|
|
357
|
+
- Cascades on relations: `'all' | 'persist' | 'remove' | 'link'`.
|
|
358
|
+
- Single flush: `session.commit()` figures out inserts, updates, deletes, and pivot changes.
|
|
359
|
+
- Column pickers to stay DRY: `selectColumns` on the root table, `selectRelationColumns` / `includePick` on relations, and `selectColumnsDeep` or the `sel`/`esel` helpers to build typed selection maps without repeating `table.columns.*`.
|
|
362
360
|
|
|
363
361
|
<a id="level-3"></a>
|
|
364
362
|
### Level 3: Decorator entities ✨
|
|
@@ -370,11 +368,11 @@ Finally, you can describe your models with decorators and still use the same run
|
|
|
370
368
|
```ts
|
|
371
369
|
import mysql from 'mysql2/promise';
|
|
372
370
|
import { Orm, OrmSession, MySqlDialect, col, createMysqlExecutor } from 'metal-orm';
|
|
373
|
-
import {
|
|
374
|
-
Entity,
|
|
375
|
-
Column,
|
|
376
|
-
PrimaryKey,
|
|
377
|
-
HasMany,
|
|
371
|
+
import {
|
|
372
|
+
Entity,
|
|
373
|
+
Column,
|
|
374
|
+
PrimaryKey,
|
|
375
|
+
HasMany,
|
|
378
376
|
BelongsTo,
|
|
379
377
|
bootstrapEntities,
|
|
380
378
|
selectFromEntity,
|
|
@@ -432,24 +430,23 @@ const orm = new Orm({
|
|
|
432
430
|
});
|
|
433
431
|
const session = new OrmSession({ orm, executor });
|
|
434
432
|
|
|
435
|
-
// 3) Query starting from the entity class
|
|
436
|
-
const [user] = await selectFromEntity(User)
|
|
437
|
-
.
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
- You
|
|
452
|
-
- You like decorators for explicit mapping but still want AST-first SQL and a disciplined runtime.
|
|
433
|
+
// 3) Query starting from the entity class
|
|
434
|
+
const [user] = await selectFromEntity(User)
|
|
435
|
+
.selectColumns('id', 'name')
|
|
436
|
+
.includeLazy('posts')
|
|
437
|
+
.where(/* same eq()/and() API as before */)
|
|
438
|
+
.execute(session);
|
|
439
|
+
|
|
440
|
+
user.posts.add({ title: 'From decorators' });
|
|
441
|
+
await session.commit();
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
Tip: to keep selections terse, use `selectColumns`/`selectRelationColumns` or the `sel`/`esel` helpers instead of spelling `table.columns.*` over and over.
|
|
445
|
+
|
|
446
|
+
This level is nice when:
|
|
447
|
+
|
|
448
|
+
- You want classes as your domain model, but don't want a separate schema DSL.
|
|
449
|
+
- You like decorators for explicit mapping but still want AST-first SQL and a disciplined runtime.
|
|
453
450
|
|
|
454
451
|
---
|
|
455
452
|
|