metal-orm 1.0.14 → 1.0.16

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 (129) hide show
  1. package/README.md +69 -67
  2. package/dist/decorators/index.cjs +1983 -224
  3. package/dist/decorators/index.cjs.map +1 -1
  4. package/dist/decorators/index.d.cts +6 -6
  5. package/dist/decorators/index.d.ts +6 -6
  6. package/dist/decorators/index.js +1982 -224
  7. package/dist/decorators/index.js.map +1 -1
  8. package/dist/index.cjs +5284 -3751
  9. package/dist/index.cjs.map +1 -1
  10. package/dist/index.d.cts +524 -169
  11. package/dist/index.d.ts +524 -169
  12. package/dist/index.js +5197 -3736
  13. package/dist/index.js.map +1 -1
  14. package/dist/{select-CCp1oz9p.d.cts → select-BKZrMRCQ.d.cts} +555 -94
  15. package/dist/{select-CCp1oz9p.d.ts → select-BKZrMRCQ.d.ts} +555 -94
  16. package/package.json +1 -1
  17. package/src/codegen/naming-strategy.ts +64 -0
  18. package/src/codegen/typescript.ts +19 -21
  19. package/src/core/ast/adapters.ts +21 -0
  20. package/src/core/ast/aggregate-functions.ts +13 -13
  21. package/src/core/ast/builders.ts +56 -43
  22. package/src/core/ast/expression-builders.ts +34 -34
  23. package/src/core/ast/expression-nodes.ts +18 -16
  24. package/src/core/ast/expression-visitor.ts +122 -69
  25. package/src/core/ast/expression.ts +6 -4
  26. package/src/core/ast/join-metadata.ts +15 -0
  27. package/src/core/ast/join-node.ts +22 -20
  28. package/src/core/ast/join.ts +5 -5
  29. package/src/core/ast/query.ts +52 -88
  30. package/src/core/ast/types.ts +20 -0
  31. package/src/core/ast/window-functions.ts +55 -55
  32. package/src/core/ddl/dialects/base-schema-dialect.ts +20 -6
  33. package/src/core/ddl/dialects/mssql-schema-dialect.ts +32 -8
  34. package/src/core/ddl/dialects/mysql-schema-dialect.ts +21 -10
  35. package/src/core/ddl/dialects/postgres-schema-dialect.ts +52 -7
  36. package/src/core/ddl/dialects/sqlite-schema-dialect.ts +23 -9
  37. package/src/core/ddl/introspect/catalogs/index.ts +1 -0
  38. package/src/core/ddl/introspect/catalogs/postgres.ts +143 -0
  39. package/src/core/ddl/introspect/context.ts +9 -0
  40. package/src/core/ddl/introspect/functions/postgres.ts +26 -0
  41. package/src/core/ddl/introspect/mssql.ts +149 -149
  42. package/src/core/ddl/introspect/mysql.ts +99 -99
  43. package/src/core/ddl/introspect/postgres.ts +245 -154
  44. package/src/core/ddl/introspect/registry.ts +26 -0
  45. package/src/core/ddl/introspect/run-select.ts +25 -0
  46. package/src/core/ddl/introspect/sqlite.ts +7 -7
  47. package/src/core/ddl/introspect/types.ts +23 -19
  48. package/src/core/ddl/introspect/utils.ts +1 -1
  49. package/src/core/ddl/naming-strategy.ts +10 -0
  50. package/src/core/ddl/schema-dialect.ts +41 -0
  51. package/src/core/ddl/schema-diff.ts +211 -179
  52. package/src/core/ddl/schema-generator.ts +17 -90
  53. package/src/core/ddl/schema-introspect.ts +25 -32
  54. package/src/core/ddl/schema-plan-executor.ts +17 -0
  55. package/src/core/ddl/schema-types.ts +46 -39
  56. package/src/core/ddl/sql-writing.ts +170 -0
  57. package/src/core/dialect/abstract.ts +172 -126
  58. package/src/core/dialect/base/cte-compiler.ts +33 -0
  59. package/src/core/dialect/base/function-table-formatter.ts +132 -0
  60. package/src/core/dialect/base/groupby-compiler.ts +21 -0
  61. package/src/core/dialect/base/join-compiler.ts +26 -0
  62. package/src/core/dialect/base/orderby-compiler.ts +21 -0
  63. package/src/core/dialect/base/pagination-strategy.ts +32 -0
  64. package/src/core/dialect/base/returning-strategy.ts +56 -0
  65. package/src/core/dialect/base/sql-dialect.ts +181 -204
  66. package/src/core/dialect/dialect-factory.ts +91 -0
  67. package/src/core/dialect/mssql/functions.ts +101 -0
  68. package/src/core/dialect/mssql/index.ts +128 -126
  69. package/src/core/dialect/mysql/functions.ts +101 -0
  70. package/src/core/dialect/mysql/index.ts +20 -18
  71. package/src/core/dialect/postgres/functions.ts +95 -0
  72. package/src/core/dialect/postgres/index.ts +30 -28
  73. package/src/core/dialect/sqlite/functions.ts +115 -0
  74. package/src/core/dialect/sqlite/index.ts +30 -28
  75. package/src/core/driver/database-driver.ts +11 -0
  76. package/src/core/driver/mssql-driver.ts +20 -0
  77. package/src/core/driver/mysql-driver.ts +20 -0
  78. package/src/core/driver/postgres-driver.ts +20 -0
  79. package/src/core/driver/sqlite-driver.ts +20 -0
  80. package/src/core/execution/db-executor.ts +63 -0
  81. package/src/core/execution/executors/mssql-executor.ts +39 -0
  82. package/src/core/execution/executors/mysql-executor.ts +47 -0
  83. package/src/core/execution/executors/postgres-executor.ts +32 -0
  84. package/src/core/execution/executors/sqlite-executor.ts +31 -0
  85. package/src/core/functions/datetime.ts +132 -0
  86. package/src/core/functions/numeric.ts +179 -0
  87. package/src/core/functions/standard-strategy.ts +47 -0
  88. package/src/core/functions/text.ts +147 -0
  89. package/src/core/functions/types.ts +18 -0
  90. package/src/core/hydration/types.ts +57 -0
  91. package/src/decorators/bootstrap.ts +10 -0
  92. package/src/decorators/column.ts +13 -4
  93. package/src/decorators/relations.ts +15 -0
  94. package/src/index.ts +37 -19
  95. package/src/orm/entity-context.ts +30 -0
  96. package/src/orm/entity-meta.ts +2 -2
  97. package/src/orm/entity-metadata.ts +8 -6
  98. package/src/orm/entity.ts +72 -41
  99. package/src/orm/execute.ts +42 -25
  100. package/src/orm/execution-context.ts +12 -0
  101. package/src/orm/hydration-context.ts +14 -0
  102. package/src/orm/hydration.ts +25 -17
  103. package/src/orm/identity-map.ts +4 -0
  104. package/src/orm/interceptor-pipeline.ts +29 -0
  105. package/src/orm/lazy-batch.ts +50 -6
  106. package/src/orm/orm-session.ts +234 -0
  107. package/src/orm/orm.ts +58 -0
  108. package/src/orm/query-logger.ts +1 -1
  109. package/src/orm/relation-change-processor.ts +48 -3
  110. package/src/orm/relations/belongs-to.ts +45 -44
  111. package/src/orm/relations/has-many.ts +44 -43
  112. package/src/orm/relations/has-one.ts +140 -0
  113. package/src/orm/relations/many-to-many.ts +46 -45
  114. package/src/orm/transaction-runner.ts +1 -1
  115. package/src/orm/unit-of-work.ts +66 -61
  116. package/src/query-builder/delete.ts +22 -5
  117. package/src/query-builder/hydration-manager.ts +2 -1
  118. package/src/query-builder/hydration-planner.ts +8 -7
  119. package/src/query-builder/insert.ts +22 -5
  120. package/src/query-builder/relation-conditions.ts +9 -8
  121. package/src/query-builder/relation-service.ts +3 -2
  122. package/src/query-builder/select.ts +575 -64
  123. package/src/query-builder/update.ts +22 -5
  124. package/src/schema/column.ts +246 -246
  125. package/src/schema/relation.ts +35 -1
  126. package/src/schema/table.ts +28 -28
  127. package/src/schema/types.ts +41 -31
  128. package/src/orm/db-executor.ts +0 -11
  129. package/src/orm/orm-context.ts +0 -159
@@ -1,11 +1,12 @@
1
1
  import { ColumnDef } from './column.js';
2
2
  import { TableDef } from './table.js';
3
- import {
4
- RelationDef,
5
- HasManyRelation,
6
- BelongsToRelation,
7
- BelongsToManyRelation
8
- } from './relation.js';
3
+ import {
4
+ RelationDef,
5
+ HasManyRelation,
6
+ HasOneRelation,
7
+ BelongsToRelation,
8
+ BelongsToManyRelation
9
+ } from './relation.js';
9
10
 
10
11
  /**
11
12
  * Maps a ColumnDef to its TypeScript type representation
@@ -26,11 +27,12 @@ export type InferRow<TTable extends TableDef> = {
26
27
  [K in keyof TTable['columns']]: ColumnToTs<TTable['columns'][K]>;
27
28
  };
28
29
 
29
- type RelationResult<T extends RelationDef> =
30
- T extends HasManyRelation<infer TTarget> ? InferRow<TTarget>[] :
31
- T extends BelongsToRelation<infer TTarget> ? InferRow<TTarget> | null :
32
- T extends BelongsToManyRelation<infer TTarget> ? (InferRow<TTarget> & { _pivot?: any })[] :
33
- never;
30
+ type RelationResult<T extends RelationDef> =
31
+ T extends HasManyRelation<infer TTarget> ? InferRow<TTarget>[] :
32
+ T extends HasOneRelation<infer TTarget> ? InferRow<TTarget> | null :
33
+ T extends BelongsToRelation<infer TTarget> ? InferRow<TTarget> | null :
34
+ T extends BelongsToManyRelation<infer TTarget> ? (InferRow<TTarget> & { _pivot?: any })[] :
35
+ never;
34
36
 
35
37
  /**
36
38
  * Maps relation names to the expected row results
@@ -48,11 +50,17 @@ export interface HasManyCollection<TChild> {
48
50
  clear(): void;
49
51
  }
50
52
 
51
- export interface BelongsToReference<TParent> {
52
- load(): Promise<TParent | null>;
53
- get(): TParent | null;
54
- set(data: Partial<TParent> | TParent | null): TParent | null;
55
- }
53
+ export interface BelongsToReference<TParent> {
54
+ load(): Promise<TParent | null>;
55
+ get(): TParent | null;
56
+ set(data: Partial<TParent> | TParent | null): TParent | null;
57
+ }
58
+
59
+ export interface HasOneReference<TChild> {
60
+ load(): Promise<TChild | null>;
61
+ get(): TChild | null;
62
+ set(data: Partial<TChild> | TChild | null): TChild | null;
63
+ }
56
64
 
57
65
  export interface ManyToManyCollection<TTarget> {
58
66
  load(): Promise<TTarget[]>;
@@ -62,18 +70,20 @@ export interface ManyToManyCollection<TTarget> {
62
70
  syncByIds(ids: (number | string)[]): Promise<void>;
63
71
  }
64
72
 
65
- export type Entity<
66
- TTable extends TableDef,
67
- TRow = InferRow<TTable>
68
- > = TRow & {
69
- [K in keyof RelationMap<TTable>]:
70
- TTable['relations'][K] extends HasManyRelation<infer TTarget>
71
- ? HasManyCollection<Entity<TTarget>>
72
- : TTable['relations'][K] extends BelongsToManyRelation<infer TTarget>
73
- ? ManyToManyCollection<Entity<TTarget>>
74
- : TTable['relations'][K] extends BelongsToRelation<infer TTarget>
75
- ? BelongsToReference<Entity<TTarget>>
76
- : never;
77
- } & {
78
- $load<K extends keyof RelationMap<TTable>>(relation: K): Promise<RelationMap<TTable>[K]>;
79
- };
73
+ export type Entity<
74
+ TTable extends TableDef,
75
+ TRow = InferRow<TTable>
76
+ > = TRow & {
77
+ [K in keyof RelationMap<TTable>]:
78
+ TTable['relations'][K] extends HasManyRelation<infer TTarget>
79
+ ? HasManyCollection<Entity<TTarget>>
80
+ : TTable['relations'][K] extends HasOneRelation<infer TTarget>
81
+ ? HasOneReference<Entity<TTarget>>
82
+ : TTable['relations'][K] extends BelongsToManyRelation<infer TTarget>
83
+ ? ManyToManyCollection<Entity<TTarget>>
84
+ : TTable['relations'][K] extends BelongsToRelation<infer TTarget>
85
+ ? BelongsToReference<Entity<TTarget>>
86
+ : never;
87
+ } & {
88
+ $load<K extends keyof RelationMap<TTable>>(relation: K): Promise<RelationMap<TTable>[K]>;
89
+ };
@@ -1,11 +0,0 @@
1
- export type QueryResult = {
2
- columns: string[];
3
- values: unknown[][];
4
- };
5
-
6
- export interface DbExecutor {
7
- executeSql(sql: string, params?: unknown[]): Promise<QueryResult[]>;
8
- beginTransaction?(): Promise<void>;
9
- commitTransaction?(): Promise<void>;
10
- rollbackTransaction?(): Promise<void>;
11
- }
@@ -1,159 +0,0 @@
1
- import type { Dialect } from '../core/dialect/abstract.js';
2
- import type { RelationDef } from '../schema/relation.js';
3
- import type { TableDef } from '../schema/table.js';
4
- import type { DbExecutor, QueryResult } from './db-executor.js';
5
- import { DomainEventBus, DomainEventHandler as DomainEventHandlerFn, addDomainEvent } from './domain-event-bus.js';
6
- import { IdentityMap } from './identity-map.js';
7
- import { RelationChangeProcessor } from './relation-change-processor.js';
8
- import { runInTransaction } from './transaction-runner.js';
9
- import { UnitOfWork } from './unit-of-work.js';
10
- import {
11
- EntityStatus,
12
- HasDomainEvents,
13
- RelationChange,
14
- RelationChangeEntry,
15
- RelationKey,
16
- TrackedEntity
17
- } from './runtime-types.js';
18
- import { createQueryLoggingExecutor, QueryLogger } from './query-logger.js';
19
-
20
- export interface OrmInterceptor {
21
- beforeFlush?(ctx: OrmContext): Promise<void> | void;
22
- afterFlush?(ctx: OrmContext): Promise<void> | void;
23
- }
24
-
25
- export type DomainEventHandler = DomainEventHandlerFn<OrmContext>;
26
-
27
- export interface OrmContextOptions {
28
- dialect: Dialect;
29
- executor: DbExecutor;
30
- interceptors?: OrmInterceptor[];
31
- domainEventHandlers?: Record<string, DomainEventHandler[]>;
32
- queryLogger?: QueryLogger;
33
- }
34
-
35
- export class OrmContext {
36
- private readonly identityMap = new IdentityMap();
37
- private readonly executorWithLogging: DbExecutor;
38
- private readonly unitOfWork: UnitOfWork;
39
- private readonly relationChanges: RelationChangeProcessor;
40
- private readonly interceptors: OrmInterceptor[];
41
- private readonly domainEvents: DomainEventBus<OrmContext>;
42
-
43
- constructor(private readonly options: OrmContextOptions) {
44
- this.interceptors = [...(options.interceptors ?? [])];
45
- this.executorWithLogging = createQueryLoggingExecutor(options.executor, options.queryLogger);
46
- this.unitOfWork = new UnitOfWork(
47
- options.dialect,
48
- this.executorWithLogging,
49
- this.identityMap,
50
- () => this
51
- );
52
- this.relationChanges = new RelationChangeProcessor(
53
- this.unitOfWork,
54
- options.dialect,
55
- this.executorWithLogging
56
- );
57
- this.domainEvents = new DomainEventBus<OrmContext>(options.domainEventHandlers);
58
- }
59
-
60
- get dialect(): Dialect {
61
- return this.options.dialect;
62
- }
63
-
64
- get executor(): DbExecutor {
65
- return this.executorWithLogging;
66
- }
67
-
68
- get identityBuckets(): Map<string, Map<string, TrackedEntity>> {
69
- return this.unitOfWork.identityBuckets;
70
- }
71
-
72
- get tracked(): TrackedEntity[] {
73
- return this.unitOfWork.getTracked();
74
- }
75
-
76
- getEntity(table: TableDef, pk: string | number): any | undefined {
77
- return this.unitOfWork.getEntity(table, pk);
78
- }
79
-
80
- setEntity(table: TableDef, pk: string | number, entity: any): void {
81
- this.unitOfWork.setEntity(table, pk, entity);
82
- }
83
-
84
- trackNew(table: TableDef, entity: any, pk?: string | number): void {
85
- this.unitOfWork.trackNew(table, entity, pk);
86
- }
87
-
88
- trackManaged(table: TableDef, pk: string | number, entity: any): void {
89
- this.unitOfWork.trackManaged(table, pk, entity);
90
- }
91
-
92
- markDirty(entity: any): void {
93
- this.unitOfWork.markDirty(entity);
94
- }
95
-
96
- markRemoved(entity: any): void {
97
- this.unitOfWork.markRemoved(entity);
98
- }
99
-
100
- registerRelationChange(
101
- root: any,
102
- relationKey: RelationKey,
103
- rootTable: TableDef,
104
- relationName: string,
105
- relation: RelationDef,
106
- change: RelationChange<any>
107
- ): void {
108
- const entry: RelationChangeEntry = {
109
- root,
110
- relationKey,
111
- rootTable,
112
- relationName,
113
- relation,
114
- change
115
- };
116
- this.relationChanges.registerChange(entry);
117
- }
118
-
119
- registerInterceptor(interceptor: OrmInterceptor): void {
120
- this.interceptors.push(interceptor);
121
- }
122
-
123
- registerDomainEventHandler(name: string, handler: DomainEventHandler): void {
124
- this.domainEvents.register(name, handler);
125
- }
126
-
127
- async saveChanges(): Promise<void> {
128
- await runInTransaction(this.executor, async () => {
129
- for (const interceptor of this.interceptors) {
130
- await interceptor.beforeFlush?.(this);
131
- }
132
-
133
- await this.unitOfWork.flush();
134
- await this.relationChanges.process();
135
- await this.unitOfWork.flush();
136
-
137
- for (const interceptor of this.interceptors) {
138
- await interceptor.afterFlush?.(this);
139
- }
140
- });
141
-
142
- await this.domainEvents.dispatch(this.unitOfWork.getTracked(), this);
143
- }
144
-
145
- getEntitiesForTable(table: TableDef): TrackedEntity[] {
146
- return this.unitOfWork.getEntitiesForTable(table);
147
- }
148
- }
149
-
150
- export { addDomainEvent };
151
- export { EntityStatus };
152
- export type {
153
- QueryResult,
154
- DbExecutor,
155
- RelationKey,
156
- RelationChange,
157
- HasDomainEvents
158
- };
159
- export type { QueryLogEntry, QueryLogger } from './query-logger.js';