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.
Files changed (64) hide show
  1. package/README.md +37 -40
  2. package/dist/decorators/index.cjs +344 -69
  3. package/dist/decorators/index.cjs.map +1 -1
  4. package/dist/decorators/index.d.cts +1 -1
  5. package/dist/decorators/index.d.ts +1 -1
  6. package/dist/decorators/index.js +344 -69
  7. package/dist/decorators/index.js.map +1 -1
  8. package/dist/index.cjs +567 -181
  9. package/dist/index.cjs.map +1 -1
  10. package/dist/index.d.cts +66 -30
  11. package/dist/index.d.ts +66 -30
  12. package/dist/index.js +559 -181
  13. package/dist/index.js.map +1 -1
  14. package/dist/{select-BKZrMRCQ.d.cts → select-BuMpVcVt.d.cts} +265 -74
  15. package/dist/{select-BKZrMRCQ.d.ts → select-BuMpVcVt.d.ts} +265 -74
  16. package/package.json +5 -1
  17. package/src/codegen/naming-strategy.ts +15 -10
  18. package/src/core/ast/aggregate-functions.ts +50 -4
  19. package/src/core/ast/builders.ts +23 -3
  20. package/src/core/ast/expression-builders.ts +36 -16
  21. package/src/core/ast/expression-nodes.ts +17 -9
  22. package/src/core/ast/join-node.ts +5 -3
  23. package/src/core/ast/join.ts +16 -16
  24. package/src/core/ast/query.ts +44 -29
  25. package/src/core/ddl/dialects/mssql-schema-dialect.ts +18 -0
  26. package/src/core/ddl/dialects/mysql-schema-dialect.ts +11 -0
  27. package/src/core/ddl/dialects/postgres-schema-dialect.ts +9 -0
  28. package/src/core/ddl/dialects/sqlite-schema-dialect.ts +9 -0
  29. package/src/core/ddl/introspect/functions/postgres.ts +2 -6
  30. package/src/core/dialect/abstract.ts +12 -8
  31. package/src/core/dialect/base/sql-dialect.ts +58 -46
  32. package/src/core/dialect/mssql/functions.ts +24 -15
  33. package/src/core/dialect/mssql/index.ts +53 -28
  34. package/src/core/dialect/postgres/functions.ts +33 -24
  35. package/src/core/dialect/sqlite/functions.ts +19 -12
  36. package/src/core/dialect/sqlite/index.ts +22 -13
  37. package/src/core/functions/datetime.ts +2 -1
  38. package/src/core/functions/numeric.ts +2 -1
  39. package/src/core/functions/standard-strategy.ts +52 -12
  40. package/src/core/functions/text.ts +2 -1
  41. package/src/core/functions/types.ts +8 -8
  42. package/src/index.ts +5 -4
  43. package/src/orm/domain-event-bus.ts +43 -25
  44. package/src/orm/entity-meta.ts +40 -0
  45. package/src/orm/execution-context.ts +6 -0
  46. package/src/orm/hydration-context.ts +6 -4
  47. package/src/orm/orm-session.ts +35 -24
  48. package/src/orm/orm.ts +10 -10
  49. package/src/orm/query-logger.ts +15 -0
  50. package/src/orm/runtime-types.ts +60 -2
  51. package/src/orm/transaction-runner.ts +7 -0
  52. package/src/orm/unit-of-work.ts +1 -0
  53. package/src/query-builder/column-selector.ts +9 -7
  54. package/src/query-builder/insert-query-state.ts +13 -3
  55. package/src/query-builder/query-ast-service.ts +59 -38
  56. package/src/query-builder/relation-conditions.ts +38 -34
  57. package/src/query-builder/relation-manager.ts +8 -3
  58. package/src/query-builder/relation-service.ts +59 -46
  59. package/src/query-builder/select-helpers.ts +50 -0
  60. package/src/query-builder/select-query-state.ts +19 -7
  61. package/src/query-builder/select.ts +339 -167
  62. package/src/query-builder/update-query-state.ts +31 -9
  63. package/src/schema/column.ts +75 -39
  64. 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
- - `@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.
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
- .select({
330
- id: users.columns.id,
331
- name: users.columns.name,
332
- email: users.columns.email,
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
- .select({
438
- id: User.prototype.id, // or map to columns by name/alias as you prefer
439
- name: User.prototype.name,
440
- })
441
- .includeLazy('posts')
442
- .where(/* same eq()/and() API as before */)
443
- .execute(session);
444
-
445
- user.posts.add({ title: 'From decorators' });
446
- await session.commit();
447
- ```
448
-
449
- This level is nice when:
450
-
451
- - You want classes as your domain model, but don’t want a separate schema DSL.
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