@tstdl/base 0.91.50 → 0.91.52

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 (164) hide show
  1. package/ai/data-extracting.d.ts +1 -0
  2. package/ai/data-extracting.js +62 -0
  3. package/authentication/server/authentication.api-controller.js +4 -4
  4. package/cancellation/token.d.ts +1 -2
  5. package/cancellation/token.js +1 -1
  6. package/core.d.ts +1 -1
  7. package/core.js +1 -1
  8. package/document-management/api/document-management.api.d.ts +753 -0
  9. package/document-management/api/document-management.api.js +222 -0
  10. package/document-management/api/index.d.ts +1 -0
  11. package/document-management/api/index.js +1 -0
  12. package/document-management/drizzle/0000_wakeful_firebrand.sql +228 -0
  13. package/document-management/drizzle/meta/0000_snapshot.json +1538 -0
  14. package/document-management/drizzle/meta/_journal.json +13 -0
  15. package/document-management/drizzle.config.d.ts +2 -0
  16. package/document-management/drizzle.config.js +11 -0
  17. package/document-management/index.d.ts +5 -0
  18. package/document-management/index.js +5 -0
  19. package/document-management/localizations/english.d.ts +2 -0
  20. package/document-management/localizations/english.js +9 -0
  21. package/document-management/localizations/german.d.ts +2 -0
  22. package/document-management/localizations/german.js +9 -0
  23. package/document-management/localizations/index.d.ts +5 -0
  24. package/document-management/localizations/index.js +9 -0
  25. package/document-management/localizations/localization.d.ts +9 -0
  26. package/document-management/localizations/localization.js +2 -0
  27. package/document-management/models/document-category.model.d.ts +4 -0
  28. package/document-management/models/document-category.model.js +18 -0
  29. package/document-management/models/document-collection-document.model.d.ts +7 -0
  30. package/document-management/models/document-collection-document.model.js +33 -0
  31. package/document-management/models/document-collection.model.d.ts +3 -0
  32. package/document-management/models/document-collection.model.js +14 -0
  33. package/document-management/models/document-file.model.d.ts +7 -0
  34. package/document-management/models/document-file.model.js +33 -0
  35. package/document-management/models/document-property-value.model.d.ts +21 -0
  36. package/document-management/models/document-property-value.model.js +58 -0
  37. package/document-management/models/document-property.model.d.ts +11 -0
  38. package/document-management/models/document-property.model.js +30 -0
  39. package/document-management/models/document-request-collection.model.d.ts +6 -0
  40. package/document-management/models/document-request-collection.model.js +28 -0
  41. package/document-management/models/document-request-file.model.d.ts +11 -0
  42. package/document-management/models/document-request-file.model.js +56 -0
  43. package/document-management/models/document-request-template.d.ts +10 -0
  44. package/document-management/models/document-request-template.js +39 -0
  45. package/document-management/models/document-request.model.d.ts +9 -0
  46. package/document-management/models/document-request.model.js +37 -0
  47. package/document-management/models/document-requests-template.d.ts +5 -0
  48. package/document-management/models/document-requests-template.js +23 -0
  49. package/document-management/models/document-type-property.model.d.ts +6 -0
  50. package/document-management/models/document-type-property.model.js +28 -0
  51. package/document-management/models/document-type.model.d.ts +7 -0
  52. package/document-management/models/document-type.model.js +32 -0
  53. package/document-management/models/document.model.d.ts +9 -0
  54. package/document-management/models/document.model.js +44 -0
  55. package/document-management/models/index.d.ts +15 -0
  56. package/document-management/models/index.js +15 -0
  57. package/document-management/models/schemas.d.ts +33 -0
  58. package/document-management/models/schemas.js +34 -0
  59. package/document-management/models/service-models/categories-and-types.view-model.d.ts +6 -0
  60. package/document-management/models/service-models/categories-and-types.view-model.js +24 -0
  61. package/document-management/models/service-models/document-folders.view-model.d.ts +22 -0
  62. package/document-management/models/service-models/document-folders.view-model.js +56 -0
  63. package/document-management/models/service-models/document-requests-template.view-model.d.ts +8 -0
  64. package/document-management/models/service-models/document-requests-template.view-model.js +26 -0
  65. package/document-management/models/service-models/document.service-model.d.ts +262 -0
  66. package/document-management/models/service-models/document.service-model.js +50 -0
  67. package/document-management/models/service-models/document.view-model.d.ts +33 -0
  68. package/document-management/models/service-models/document.view-model.js +99 -0
  69. package/document-management/models/service-models/index.d.ts +8 -0
  70. package/document-management/models/service-models/index.js +8 -0
  71. package/document-management/models/service-models/normalized-document-collection-view.model.d.ts +73 -0
  72. package/document-management/models/service-models/normalized-document-collection-view.model.js +110 -0
  73. package/document-management/models/service-models/normalized-requests-template-data.model.d.ts +16 -0
  74. package/document-management/models/service-models/normalized-requests-template-data.model.js +13 -0
  75. package/document-management/models/service-models/stats.view-model.d.ts +6 -0
  76. package/document-management/models/service-models/stats.view-model.js +32 -0
  77. package/document-management/module.d.ts +11 -0
  78. package/document-management/module.js +27 -0
  79. package/document-management/services/document-management.service.d.ts +65 -0
  80. package/document-management/services/document-management.service.js +376 -0
  81. package/document-management/services/index.d.ts +1 -0
  82. package/document-management/services/index.js +1 -0
  83. package/examples/document-management/main.d.ts +1 -0
  84. package/examples/document-management/main.js +30 -0
  85. package/examples/orm/drizzle.config.js +2 -1
  86. package/examples/orm/schemas.d.ts +1 -1
  87. package/examples/orm/user.model.d.ts +1 -2
  88. package/examples/orm/user.model.js +0 -1
  89. package/http/server/node/node-http-server.js +5 -5
  90. package/injector/injector.d.ts +4 -1
  91. package/injector/injector.js +4 -1
  92. package/injector/interfaces.d.ts +3 -3
  93. package/json-path/json-path.d.ts +2 -0
  94. package/json-path/json-path.js +7 -0
  95. package/message-bus/message-bus.d.ts +4 -6
  96. package/orm/database-schema.d.ts +3 -0
  97. package/orm/database-schema.js +6 -2
  98. package/orm/database.d.ts +6 -0
  99. package/orm/database.js +14 -0
  100. package/orm/decorators.d.ts +25 -2
  101. package/orm/decorators.js +15 -0
  102. package/orm/drizzle/index.d.ts +1 -0
  103. package/orm/drizzle/index.js +1 -0
  104. package/orm/drizzle/schema-converter.d.ts +37 -8
  105. package/orm/drizzle/schema-converter.js +121 -40
  106. package/orm/entity.d.ts +15 -12
  107. package/orm/entity.js +24 -11
  108. package/orm/index.d.ts +3 -2
  109. package/orm/index.js +3 -2
  110. package/orm/module.d.ts +6 -0
  111. package/orm/module.js +15 -0
  112. package/orm/query-converter.d.ts +5 -0
  113. package/orm/query-converter.js +114 -0
  114. package/orm/query.d.ts +15 -13
  115. package/orm/repository.d.ts +90 -31
  116. package/orm/repository.js +357 -55
  117. package/orm/schemas/index.d.ts +3 -0
  118. package/orm/schemas/index.js +3 -0
  119. package/orm/schemas/json.d.ts +9 -0
  120. package/orm/schemas/json.js +19 -0
  121. package/orm/schemas/numeric-date.d.ts +8 -0
  122. package/orm/schemas/numeric-date.js +13 -0
  123. package/orm/schemas/timestamp.d.ts +10 -0
  124. package/orm/schemas/timestamp.js +20 -0
  125. package/orm/transaction.d.ts +29 -0
  126. package/orm/transaction.js +73 -0
  127. package/orm/types.d.ts +15 -8
  128. package/orm/types.js +3 -2
  129. package/package.json +23 -12
  130. package/{rxjs → rxjs-utils}/reject-error.d.ts +1 -1
  131. package/{rxjs → rxjs-utils}/retry-backoff.d.ts +2 -2
  132. package/{rxjs → rxjs-utils}/slow-array.d.ts +7 -7
  133. package/{rxjs → rxjs-utils}/slow-array.js +2 -2
  134. package/{rxjs → rxjs-utils}/start-with-provider.d.ts +1 -1
  135. package/{rxjs → rxjs-utils}/teardown.d.ts +1 -1
  136. package/{rxjs → rxjs-utils}/untrack.d.ts +1 -1
  137. package/schema/decorators/types.d.ts +2 -2
  138. package/schema/schemas/number.d.ts +1 -1
  139. package/signals/pipe.d.ts +1 -1
  140. package/signals/pipe.js +1 -2
  141. package/sse/server-sent-events.d.ts +54 -0
  142. package/sse/server-sent-events.js +54 -0
  143. package/types.d.ts +5 -1
  144. package/utils/comparison.d.ts +2 -1
  145. package/utils/comparison.js +4 -3
  146. package/utils/compression.d.ts +4 -4
  147. package/utils/compression.js +35 -43
  148. package/utils/object/dereference.d.ts +6 -4
  149. package/utils/object/dereference.js +20 -8
  150. package/utils/object/object.d.ts +2 -0
  151. package/utils/object/object.js +20 -0
  152. /package/{rxjs → rxjs-utils}/cast.d.ts +0 -0
  153. /package/{rxjs → rxjs-utils}/cast.js +0 -0
  154. /package/{rxjs → rxjs-utils}/index.d.ts +0 -0
  155. /package/{rxjs → rxjs-utils}/index.js +0 -0
  156. /package/{rxjs → rxjs-utils}/noop.d.ts +0 -0
  157. /package/{rxjs → rxjs-utils}/noop.js +0 -0
  158. /package/{rxjs → rxjs-utils}/reject-error.js +0 -0
  159. /package/{rxjs → rxjs-utils}/retry-backoff.js +0 -0
  160. /package/{rxjs → rxjs-utils}/start-with-provider.js +0 -0
  161. /package/{rxjs → rxjs-utils}/teardown.js +0 -0
  162. /package/{rxjs → rxjs-utils}/timing.d.ts +0 -0
  163. /package/{rxjs → rxjs-utils}/timing.js +0 -0
  164. /package/{rxjs → rxjs-utils}/untrack.js +0 -0
package/orm/repository.js CHANGED
@@ -5,22 +5,77 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
6
  return c > 3 && r && Object.defineProperty(target, key, r), r;
7
7
  };
8
- import { drizzle } from 'drizzle-orm/node-postgres';
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ import { count, eq, inArray, sql } from 'drizzle-orm';
12
+ import { PgTransaction as DrizzlePgTransaction } from 'drizzle-orm/pg-core';
9
13
  import { NotFoundError } from '../errors/not-found.error.js';
10
- import { NotImplementedError } from '../errors/not-implemented.error.js';
11
- import { NotSupportedError } from '../errors/not-supported.error.js';
12
14
  import { Singleton } from '../injector/decorators.js';
13
- import { inject } from '../injector/inject.js';
14
- import { injectionToken } from '../injector/token.js';
15
- import { assertDefinedPass, isUndefined } from '../utils/type-guards.js';
16
- import { count, eq, inArray, sql, SQL } from 'drizzle-orm';
17
- import { getDrizzleTableFromType } from './drizzle/schema-converter.js';
15
+ import { inject, injectArgument } from '../injector/inject.js';
16
+ import { Schema } from '../schema/schema.js';
17
+ import { toArray } from '../utils/array/array.js';
18
+ import { fromDeepObjectEntries } from '../utils/object/object.js';
19
+ import { assertDefinedPass, assertNotNullPass, isNotNull, isUndefined } from '../utils/type-guards.js';
20
+ import { Database } from './database.js';
21
+ import { getColumnDefinitions, getDrizzleTableFromType } from './drizzle/schema-converter.js';
22
+ import { convertQuery } from './query-converter.js';
23
+ import { DrizzleTransaction } from './transaction.js';
18
24
  export const repositoryType = Symbol('repositoryType');
19
- export const entityType = injectionToken('Entity type');
25
+ export class EntityRepositoryConfig {
26
+ schema;
27
+ }
28
+ const TRANSACTION_TIMESTAMP = sql `transaction_timestamp()`;
20
29
  let EntityRepository = class EntityRepository {
21
- type = inject(entityType);
22
- schema = getDrizzleTableFromType('', this.type);
23
- database = drizzle('');
30
+ #repositoryConstructor;
31
+ #withTransactionCache = new WeakMap();
32
+ type;
33
+ table;
34
+ columnDefinitions;
35
+ columnDefinitionsMap;
36
+ session;
37
+ isInTransaction;
38
+ get tx() {
39
+ return this.session;
40
+ }
41
+ constructor(type, table, columnDefinitions, columnDefinitionsMap, session) {
42
+ this.#repositoryConstructor = new.target;
43
+ this.type = type ?? injectArgument(this);
44
+ this.table = table ?? getDrizzleTableFromType(this.type, inject(EntityRepositoryConfig).schema);
45
+ this.columnDefinitions = columnDefinitions ?? getColumnDefinitions(this.table);
46
+ this.columnDefinitionsMap = columnDefinitionsMap ?? new Map(this.columnDefinitions.map((column) => [column.objectPath.path, column]));
47
+ this.session = session ?? inject(Database);
48
+ this.isInTransaction = this.session instanceof DrizzlePgTransaction;
49
+ }
50
+ withOptionalTransaction(transaction) {
51
+ if (isUndefined(transaction)) {
52
+ return this;
53
+ }
54
+ return this.withTransaction(transaction);
55
+ }
56
+ withTransaction(transaction) {
57
+ if (this.#withTransactionCache.has(transaction)) {
58
+ return this.#withTransactionCache.get(transaction);
59
+ }
60
+ const repositoryWithTransaction = new this.#repositoryConstructor(this.type, this.table, this.columnDefinitions, this.columnDefinitionsMap, transaction.transaction);
61
+ this.#withTransactionCache.set(transaction, repositoryWithTransaction);
62
+ return repositoryWithTransaction;
63
+ }
64
+ async startTransaction(config) {
65
+ return DrizzleTransaction.create(this.session, config);
66
+ }
67
+ async useTransaction(transaction, handler) {
68
+ if (isUndefined(transaction)) {
69
+ return this.transaction(handler);
70
+ }
71
+ const repository = this.withTransaction(transaction);
72
+ return transaction.use(async () => handler(repository, transaction));
73
+ }
74
+ async transaction(handler, config) {
75
+ const transaction = await DrizzleTransaction.create(this.session, config);
76
+ const repository = this.withTransaction(transaction);
77
+ return transaction.use(async () => handler(repository, transaction));
78
+ }
24
79
  async load(id) {
25
80
  const entity = await this.tryLoad(id);
26
81
  if (isUndefined(entity)) {
@@ -29,7 +84,7 @@ let EntityRepository = class EntityRepository {
29
84
  return entity;
30
85
  }
31
86
  async tryLoad(id) {
32
- return this.tryLoadByQuery(eq(this.schema.id, id));
87
+ return this.tryLoadByQuery(eq(this.table.id, id));
33
88
  }
34
89
  async loadByQuery(query, options) {
35
90
  const entity = await this.tryLoadByQuery(query, options);
@@ -39,90 +94,337 @@ let EntityRepository = class EntityRepository {
39
94
  return entity;
40
95
  }
41
96
  async tryLoadByQuery(query, options) {
42
- if (!(query instanceof SQL)) {
43
- throw new NotSupportedError();
44
- }
45
- const dbQuery = this.database.select()
46
- .from(this.schema)
47
- .where(query)
97
+ const sqlQuery = this.convertQuery(query);
98
+ const dbQuery = this.session.select()
99
+ .from(this.table)
100
+ .where(sqlQuery)
48
101
  .offset(options?.offset);
49
- const [entity] = (await dbQuery);
50
- return entity;
102
+ const [row] = await dbQuery;
103
+ if (isUndefined(row)) {
104
+ return undefined;
105
+ }
106
+ return this.mapToEntity(row);
51
107
  }
52
108
  async loadMany(ids, options) {
53
- return this.loadManyByQuery(inArray(this.schema.id, ids), options);
109
+ return this.loadManyByQuery(inArray(this.table.id, ids), options);
54
110
  }
55
111
  async *loadManyCursor(ids, options) {
56
112
  const entities = await this.loadMany(ids, options);
57
113
  yield* entities;
58
114
  }
59
115
  async loadManyByQuery(query, options) {
60
- if (!(query instanceof SQL)) {
61
- throw new NotSupportedError();
62
- }
63
- const dbQuery = this.database.select()
64
- .from(this.schema)
65
- .where(query)
116
+ const sqlQuery = this.convertQuery(query);
117
+ const rows = await this.session.select()
118
+ .from(this.table)
119
+ .where(sqlQuery)
66
120
  .offset(options?.offset)
67
121
  .limit(options?.limit);
68
- return dbQuery;
122
+ return rows.map((entity) => this.mapToEntity(entity));
69
123
  }
70
124
  async *loadManyByQueryCursor(query, options) {
71
125
  const entities = await this.loadManyByQuery(query, options);
72
126
  yield* entities;
73
127
  }
74
128
  async loadAll(options) {
75
- return this.loadManyByQuery(undefined, options);
129
+ return this.loadManyByQuery({}, options);
76
130
  }
77
131
  async *loadAllCursor(options) {
78
132
  const entities = await this.loadAll(options);
79
133
  yield* entities;
80
134
  }
81
135
  async count() {
82
- const dbQuery = this.database
136
+ const dbQuery = this.session
83
137
  .select({ count: count() })
84
- .from(this.schema);
138
+ .from(this.table);
85
139
  const [result] = await dbQuery;
86
140
  return assertDefinedPass(result).count;
87
141
  }
88
142
  async countByQuery(query) {
89
- if (!(query instanceof SQL)) {
90
- throw new NotSupportedError();
91
- }
92
- const dbQuery = this.database
143
+ const sqlQuery = this.convertQuery(query);
144
+ const dbQuery = this.session
93
145
  .select({ count: count() })
94
- .from(this.schema)
95
- .where(query);
146
+ .from(this.table)
147
+ .where(sqlQuery);
96
148
  const [result] = await dbQuery;
97
149
  return assertDefinedPass(result).count;
98
150
  }
99
151
  async has(id) {
100
- return this.hasByQuery(eq(this.schema.id, id));
152
+ return this.hasByQuery(eq(this.table.id, id));
101
153
  }
102
154
  async hasByQuery(query) {
103
- // SELECT EXISTS(SELECT 1 FROM contact WHERE id=12) as exists
104
- if (!(query instanceof SQL)) {
105
- throw new NotSupportedError();
106
- }
107
- const dbQuery = this.database
108
- .select({
109
- exists: sql `SELECT EXISTS(SELECT 1 FROM ${this.schema} WHERE ${query})`
110
- })
111
- .from(this.schema)
112
- .where(query);
155
+ const sqlQuery = this.convertQuery(query);
156
+ const dbQuery = this.session
157
+ .select({ exists: sql `SELECT EXISTS(SELECT 1 FROM ${this.table} WHERE ${sqlQuery})` })
158
+ .from(this.table);
113
159
  const [result] = await dbQuery;
114
160
  return assertDefinedPass(result).exists;
115
161
  }
116
162
  async hasAll(ids) {
117
- const result = await this.database.execute(sql `SELECT array_agg(id) @> ${ids} AS contains FROM ${this.schema};`);
118
- return assertDefinedPass(result.rows[0]).contains;
163
+ const result = await this.session
164
+ .select({ contains: sql `array_agg(${this.table.id}) @> ${ids}`.as('contains') })
165
+ .from(this.table);
166
+ return assertDefinedPass(result[0]).contains;
167
+ }
168
+ async insert(entity) {
169
+ const columns = this.mapToInsertColumns(entity);
170
+ const [row] = await this.session
171
+ .insert(this.table)
172
+ .values(columns)
173
+ .returning();
174
+ return this.mapToEntity(row);
175
+ }
176
+ async insertMany(entities) {
177
+ const columns = entities.map((entity) => this.mapToInsertColumns(entity));
178
+ const rows = await this.session.insert(this.table).values(columns).returning();
179
+ return rows.map((row) => this.mapToEntity(row));
180
+ }
181
+ async upsert(target, entity, update) {
182
+ const targetColumns = toArray(target).map((path) => {
183
+ const columnName = assertDefinedPass(this.columnDefinitionsMap.get(path), `Could not map ${path} to column.`).name;
184
+ return this.table[columnName];
185
+ });
186
+ const columns = this.mapToInsertColumns(entity);
187
+ const mappedUpdate = this.mapUpdate(update ?? entity);
188
+ const [row] = await this.session
189
+ .insert(this.table)
190
+ .values(columns)
191
+ .onConflictDoUpdate({
192
+ target: targetColumns,
193
+ set: mappedUpdate
194
+ })
195
+ .returning();
196
+ return this.mapToEntity(row);
197
+ }
198
+ async upsertMany(target, entities, update) {
199
+ const targetColumns = toArray(target).map((path) => {
200
+ const columnName = assertDefinedPass(this.columnDefinitionsMap.get(path), `Could not map ${path} to column.`).name;
201
+ return this.table[columnName];
202
+ });
203
+ const columns = entities.map((entity) => this.mapToColumns(entity));
204
+ const mappedUpdate = this.mapUpdate(update);
205
+ const rows = await this.session
206
+ .insert(this.table)
207
+ .values(columns)
208
+ .onConflictDoUpdate({
209
+ target: targetColumns,
210
+ set: mappedUpdate
211
+ })
212
+ .returning();
213
+ return rows.map((row) => this.mapToEntity(row));
214
+ }
215
+ async update(id, update) {
216
+ const entity = await this.tryUpdate(id, update);
217
+ if (isUndefined(entity)) {
218
+ throw new NotFoundError(`${this.type.entityName} ${id} not found.`);
219
+ }
220
+ return entity;
221
+ }
222
+ async tryUpdate(id, update) {
223
+ const mappedUpdate = this.mapUpdate(update);
224
+ const [row] = await this.session
225
+ .update(this.table)
226
+ .set(mappedUpdate)
227
+ .where(eq(this.table.id, id))
228
+ .returning();
229
+ if (isUndefined(row)) {
230
+ return undefined;
231
+ }
232
+ return this.mapToEntity(row);
233
+ }
234
+ async updateByQuery(query, update) {
235
+ const entity = await this.tryUpdateByQuery(query, update);
236
+ if (isUndefined(entity)) {
237
+ throw new NotFoundError(`${this.type.entityName} not found.`);
238
+ }
239
+ return entity;
240
+ }
241
+ async tryUpdateByQuery(query, update) {
242
+ const mappedUpdate = this.mapUpdate(update);
243
+ const idQuery = this.getIdLimitQuery(query);
244
+ const [row] = await this.session
245
+ .with(idQuery)
246
+ .update(this.table)
247
+ .set(mappedUpdate)
248
+ .where(inArray(this.table.id, idQuery))
249
+ .returning();
250
+ if (isUndefined(row)) {
251
+ return undefined;
252
+ }
253
+ return this.mapToEntity(row);
254
+ }
255
+ async updateMany(ids, update) {
256
+ return this.updateManyByQuery(inArray(this.table.id, ids), update);
119
257
  }
120
- async insert(_entity) {
121
- // await this.database.insert(this.schema).values([entity as T]);
122
- throw new NotImplementedError();
258
+ async updateManyByQuery(query, update) {
259
+ const sqlQuery = this.convertQuery(query);
260
+ const mappedUpdate = this.mapUpdate(update);
261
+ const rows = await this.session
262
+ .update(this.table)
263
+ .set(mappedUpdate)
264
+ .where(sqlQuery)
265
+ .returning();
266
+ return rows.map((entity) => this.mapToEntity(entity));
267
+ }
268
+ async delete(id, metadataUpdate) {
269
+ const entity = await this.tryDelete(id, metadataUpdate);
270
+ if (isUndefined(entity)) {
271
+ throw new NotFoundError(`${this.type.entityName} ${id} not found.`);
272
+ }
273
+ return entity;
274
+ }
275
+ async tryDelete(id, metadataUpdate) {
276
+ const [row] = await this.session
277
+ .update(this.table)
278
+ .set({
279
+ deleteTimestamp: TRANSACTION_TIMESTAMP,
280
+ attributes: this.getAttributesUpdate(metadataUpdate?.attributes)
281
+ })
282
+ .where(eq(this.table.id, id))
283
+ .returning();
284
+ if (isUndefined(row)) {
285
+ return undefined;
286
+ }
287
+ return this.mapToEntity(row);
288
+ }
289
+ async deleteByQuery(query, metadataUpdate) {
290
+ const entity = await this.tryDeleteByQuery(query, metadataUpdate);
291
+ if (isUndefined(entity)) {
292
+ throw new NotFoundError(`${this.type.entityName} not found.`);
293
+ }
294
+ return entity;
295
+ }
296
+ async tryDeleteByQuery(query, metadataUpdate) {
297
+ const idQuery = this.getIdLimitQuery(query);
298
+ const [row] = await this.session
299
+ .update(this.table)
300
+ .set({
301
+ deleteTimestamp: TRANSACTION_TIMESTAMP,
302
+ attributes: this.getAttributesUpdate(metadataUpdate?.attributes)
303
+ })
304
+ .where(inArray(this.table.id, idQuery))
305
+ .returning();
306
+ if (isUndefined(row)) {
307
+ return undefined;
308
+ }
309
+ return this.mapToEntity(row);
310
+ }
311
+ async deleteMany(ids, metadataUpdate) {
312
+ return this.deleteManyByQuery(inArray(this.table.id, ids), metadataUpdate);
313
+ }
314
+ async deleteManyByQuery(query, metadataUpdate) {
315
+ const sqlQuery = this.convertQuery(query);
316
+ const rows = await this.session
317
+ .update(this.table)
318
+ .set({
319
+ deleteTimestamp: TRANSACTION_TIMESTAMP,
320
+ attributes: this.getAttributesUpdate(metadataUpdate?.attributes)
321
+ })
322
+ .where(sqlQuery)
323
+ .returning();
324
+ return rows.map((row) => this.mapToEntity(row));
325
+ }
326
+ async hardDelete(id) {
327
+ const result = await this.tryHardDelete(id);
328
+ if (!result) {
329
+ throw new NotFoundError(`${this.type.entityName} ${id} not found.`);
330
+ }
331
+ }
332
+ async tryHardDelete(id) {
333
+ const result = await this.session.delete(this.table).where(eq(this.table.id, id));
334
+ console.log({ deleteResult: result });
335
+ return isNotNull(result.rowCount) && (result.rowCount > 0);
336
+ }
337
+ async hardDeleteByQuery(query) {
338
+ const idQuery = this.getIdLimitQuery(query);
339
+ const result = await this.session
340
+ .with(idQuery)
341
+ .delete(this.table)
342
+ .where(inArray(this.table.id, idQuery));
343
+ console.log({ deleteResult: result });
344
+ return isNotNull(result.rowCount) && (result.rowCount > 0);
345
+ }
346
+ async hardDeleteMany(ids) {
347
+ return this.hardDeleteManyByQuery(inArray(this.table.id, ids));
348
+ }
349
+ async hardDeleteManyByQuery(query) {
350
+ const sqlQuery = this.convertQuery(query);
351
+ const result = await this.session.delete(this.table).where(sqlQuery);
352
+ console.log({ deleteResult: result });
353
+ return assertNotNullPass(result.rowCount);
354
+ }
355
+ convertQuery(query) {
356
+ return convertQuery(query, this.table, this.columnDefinitionsMap);
357
+ }
358
+ mapToEntity(columns) {
359
+ const entries = this.columnDefinitions.map((def) => [def.objectPath, columns[def.name]]);
360
+ const obj = fromDeepObjectEntries(entries);
361
+ return Schema.parse(this.type, obj);
362
+ }
363
+ mapToColumns(obj) {
364
+ const columns = {};
365
+ for (const def of this.columnDefinitions) {
366
+ columns[def.name] = def.dereferenceObjectPath(obj);
367
+ }
368
+ return columns;
369
+ }
370
+ mapToInsertColumns(obj) {
371
+ const mapped = this.mapToColumns(obj);
372
+ return {
373
+ ...mapped,
374
+ revision: 1,
375
+ revisionTimestamp: TRANSACTION_TIMESTAMP,
376
+ createTimestamp: TRANSACTION_TIMESTAMP
377
+ };
378
+ }
379
+ mapUpdate(update) {
380
+ const mappedUpdate = {};
381
+ for (const column of this.columnDefinitions) {
382
+ const value = column.dereferenceObjectPath(update);
383
+ if (isUndefined(value)) {
384
+ continue;
385
+ }
386
+ mappedUpdate[column.name] = value;
387
+ }
388
+ return {
389
+ ...mappedUpdate,
390
+ attributes: this.getAttributesUpdate(update.metadata?.attributes),
391
+ revision: sql `${this.table.revision} + 1`,
392
+ revisionTimestamp: sql `transaction_timestamp()`
393
+ };
394
+ }
395
+ getIdLimitQuery(query) {
396
+ const sqlQuery = this.convertQuery(query);
397
+ return this.session.$with('id').as(this.session.select({ id: this.table.id })
398
+ .from(this.table)
399
+ .where(sqlQuery)
400
+ .limit(1));
401
+ }
402
+ getAttributesUpdate(attributes) {
403
+ if (isUndefined(attributes)) {
404
+ return undefined;
405
+ }
406
+ return sql `${this.table.attributes} || '${JSON.stringify(attributes)}'::jsonb`;
123
407
  }
124
408
  };
125
409
  EntityRepository = __decorate([
126
- Singleton()
410
+ Singleton({
411
+ provider: {
412
+ useFactory: () => new EntityRepository()
413
+ }
414
+ }),
415
+ __metadata("design:paramtypes", [Object, Object, Array, Map, Object])
127
416
  ], EntityRepository);
128
417
  export { EntityRepository };
418
+ export function injectRepository(type) {
419
+ return inject((EntityRepository), type);
420
+ }
421
+ export function getRepository(type, config) {
422
+ const className = `${type.name}Service`;
423
+ const entityRepositoryClass = {
424
+ [className]: class extends EntityRepository {
425
+ }
426
+ }[className];
427
+ const injectorDecorator = Singleton({ providers: [{ provide: EntityRepositoryConfig, useValue: config }] });
428
+ injectorDecorator(entityRepositoryClass);
429
+ return entityRepositoryClass;
430
+ }
@@ -1 +1,4 @@
1
+ export * from './json.js';
2
+ export * from './numeric-date.js';
3
+ export * from './timestamp.js';
1
4
  export * from './uuid.js';
@@ -1 +1,4 @@
1
+ export * from './json.js';
2
+ export * from './numeric-date.js';
3
+ export * from './timestamp.js';
1
4
  export * from './uuid.js';
@@ -0,0 +1,9 @@
1
+ import { type Decorator } from '../../reflection/index.js';
2
+ import { ObjectSchema, type ObjectSchemaOptions, type SchemaPropertyDecoratorOptions } from '../../schema/index.js';
3
+ export type JsonSchemaOptions = Pick<ObjectSchemaOptions, 'factory'>;
4
+ export declare class JsonSchema extends ObjectSchema {
5
+ readonly name = "Json";
6
+ constructor(options?: JsonSchemaOptions);
7
+ }
8
+ export declare function json(options?: JsonSchemaOptions): JsonSchema;
9
+ export declare function Json(options?: JsonSchemaOptions & SchemaPropertyDecoratorOptions): Decorator<'class' | 'property' | 'accessor'>;
@@ -0,0 +1,19 @@
1
+ import { createDecorator } from '../../reflection/index.js';
2
+ import { any, Class, ObjectSchema, Property } from '../../schema/index.js';
3
+ export class JsonSchema extends ObjectSchema {
4
+ name = 'Json';
5
+ constructor(options) {
6
+ super({}, { ...options, unknownPropertiesKey: any(), unknownProperties: any() });
7
+ }
8
+ }
9
+ export function json(options) {
10
+ return new JsonSchema(options);
11
+ }
12
+ export function Json(options) {
13
+ return createDecorator({ class: true, property: true, accessor: true }, (data, metadata, args) => {
14
+ if (data.type == 'class') {
15
+ return Class({ schema: json({ factory: { type: data.constructor } }) })(args[0]);
16
+ }
17
+ return Property(json({ factory: { type: metadata.type } }), options)(args[0], args[1], args[2]);
18
+ });
19
+ }
@@ -0,0 +1,8 @@
1
+ import { NumberSchema, type NumberSchemaOptions, type SchemaPropertyDecorator, type SchemaPropertyDecoratorOptions, type SimpleSchemaOptions } from '../../schema/index.js';
2
+ export type NumericDateSchemaOptions = SimpleSchemaOptions & Pick<NumberSchemaOptions, 'minimum' | 'maximum'>;
3
+ export declare class NumericDateSchema extends NumberSchema {
4
+ readonly name = "NumericDate";
5
+ constructor(options?: NumericDateSchemaOptions);
6
+ }
7
+ export declare function numericDate(options?: NumericDateSchemaOptions): NumericDateSchema;
8
+ export declare function NumericDate(options?: NumericDateSchemaOptions & SchemaPropertyDecoratorOptions): SchemaPropertyDecorator;
@@ -0,0 +1,13 @@
1
+ import { NumberSchema, Property } from '../../schema/index.js';
2
+ export class NumericDateSchema extends NumberSchema {
3
+ name = 'NumericDate';
4
+ constructor(options) {
5
+ super({ ...options, integer: true });
6
+ }
7
+ }
8
+ export function numericDate(options) {
9
+ return new NumericDateSchema(options);
10
+ }
11
+ export function NumericDate(options) {
12
+ return Property(numericDate(options), options);
13
+ }
@@ -0,0 +1,10 @@
1
+ import type { JsonPath } from '../../json-path/json-path.js';
2
+ import { NumberSchema, type NumberSchemaOptions, type SchemaPropertyDecorator, type SchemaPropertyDecoratorOptions, type SchemaTestOptions, type SchemaTestResult, type SimpleSchemaOptions } from '../../schema/index.js';
3
+ export type TimestampSchemaOptions = SimpleSchemaOptions & Pick<NumberSchemaOptions, 'minimum' | 'maximum'>;
4
+ export declare class TimestampSchema extends NumberSchema {
5
+ readonly name = "Timestamp";
6
+ constructor(options?: TimestampSchemaOptions);
7
+ _test(value: any, path: JsonPath, options: SchemaTestOptions): SchemaTestResult<number>;
8
+ }
9
+ export declare function timestamp(options?: TimestampSchemaOptions): TimestampSchema;
10
+ export declare function Timestamp(options?: TimestampSchemaOptions & SchemaPropertyDecoratorOptions): SchemaPropertyDecorator;
@@ -0,0 +1,20 @@
1
+ import { NumberSchema, Property } from '../../schema/index.js';
2
+ import { isDate } from '../../utils/type-guards.js';
3
+ export class TimestampSchema extends NumberSchema {
4
+ name = 'Timestamp';
5
+ constructor(options) {
6
+ super({ ...options, integer: true });
7
+ }
8
+ _test(value, path, options) {
9
+ if (isDate(value)) {
10
+ return super._test(value.getTime(), path, options);
11
+ }
12
+ return super._test(value, path, options);
13
+ }
14
+ }
15
+ export function timestamp(options) {
16
+ return new TimestampSchema(options);
17
+ }
18
+ export function Timestamp(options) {
19
+ return Property(timestamp(options), options);
20
+ }
@@ -0,0 +1,29 @@
1
+ import { DeferredPromise } from '../promise/deferred-promise.js';
2
+ import type { PgTransaction as DrizzlePgTransaction, PgTransactionConfig } from 'drizzle-orm/pg-core';
3
+ import type { Database } from './database.js';
4
+ type PgTransaction = DrizzlePgTransaction<any, any, any>;
5
+ export type TransactionConfig = PgTransactionConfig;
6
+ export declare abstract class Transaction {
7
+ #private;
8
+ readonly afterCommit$: import("rxjs").Observable<void>;
9
+ manualCommit: boolean;
10
+ withManualCommit(): void;
11
+ /**
12
+ * Enters automatic transaction handling. Transaction will be commited when all use-calls are done or rolled back when one throws.
13
+ */
14
+ use<T>(handler: () => Promise<T>): Promise<T>;
15
+ commit(): Promise<void>;
16
+ rollback(): void;
17
+ protected abstract _commit(): Promise<void>;
18
+ protected abstract _rollback(): void;
19
+ }
20
+ export declare class DrizzleTransaction extends Transaction {
21
+ readonly transaction: PgTransaction;
22
+ readonly deferPromise: DeferredPromise<void>;
23
+ readonly pgTransactionPromise: Promise<void>;
24
+ constructor(transaction: PgTransaction, pgTransactionPromise: Promise<void>);
25
+ static create(session: Database | PgTransaction, config?: TransactionConfig): Promise<DrizzleTransaction>;
26
+ protected _commit(): Promise<void>;
27
+ protected _rollback(): void;
28
+ }
29
+ export {};