@exogee/graphweaver-mikroorm 0.1.0-alpha.0

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/lib/index.js ADDED
@@ -0,0 +1,1002 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
+ mod
23
+ ));
24
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
25
+ var __decorateClass = (decorators, target, key, kind) => {
26
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
27
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
28
+ if (decorator = decorators[i])
29
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
30
+ if (kind && result)
31
+ __defProp(target, key, result);
32
+ return result;
33
+ };
34
+
35
+ // ../../packages/mikroorm/src/index.ts
36
+ var src_exports = {};
37
+ __export(src_exports, {
38
+ AuditChange: () => AuditChange,
39
+ AuditRelatedEntityChange: () => AuditRelatedEntityChange,
40
+ AuthenticationContext: () => AuthenticationContext,
41
+ BaseEntity: () => BaseEntity,
42
+ ChangeSetType: () => import_core10.ChangeSetType,
43
+ Collection: () => import_core10.Collection,
44
+ Database: () => Database,
45
+ DatabaseObjectNotFoundException: () => import_core10.DatabaseObjectNotFoundException,
46
+ DateType: () => DateType,
47
+ EntityManager: () => import_core10.EntityManager,
48
+ EntityRepository: () => import_core10.EntityRepository,
49
+ IsolationLevel: () => IsolationLevel,
50
+ LockMode: () => import_core10.LockMode,
51
+ MikroBackendProvider: () => MikroBackendProvider,
52
+ PrimaryKeyType: () => import_core10.PrimaryKeyType,
53
+ QueryFlag: () => import_core10.QueryFlag,
54
+ QueryOrder: () => import_core10.QueryOrder,
55
+ Reference: () => import_core10.Reference,
56
+ ReferenceType: () => import_core10.ReferenceType,
57
+ SqlEntityManager: () => import_postgresql2.SqlEntityManager,
58
+ SqlEntityRepository: () => import_postgresql2.SqlEntityRepository,
59
+ Subscriber: () => import_core10.Subscriber,
60
+ Time: () => Time,
61
+ TimeType: () => TimeType,
62
+ UniqueConstraintViolationException: () => import_core10.UniqueConstraintViolationException,
63
+ Utils: () => import_core10.Utils,
64
+ checkDatabase: () => checkDatabase,
65
+ clearDatabaseContext: () => clearDatabaseContext,
66
+ getDbSchema: () => getDbSchema,
67
+ gqlToMikro: () => gqlToMikro,
68
+ mapAndAssignKeys: () => mapAndAssignKeys,
69
+ visitPathForPopulate: () => visitPathForPopulate,
70
+ wrap: () => import_core10.wrap
71
+ });
72
+ module.exports = __toCommonJS(src_exports);
73
+ var import_reflect_metadata3 = require("reflect-metadata");
74
+ var dotenv = __toESM(require("dotenv"));
75
+
76
+ // ../../packages/mikroorm/src/base-resolver/provider.ts
77
+ var import_logger4 = require("@exogee/logger");
78
+
79
+ // ../../packages/mikroorm/src/utils/errors.ts
80
+ var import_apollo_server_core = require("apollo-server-core");
81
+ var OptimisticLockError = class extends import_apollo_server_core.ApolloError {
82
+ constructor(message, extensions) {
83
+ super(message, "OPTIMISTIC_LOCK_ERROR", extensions);
84
+ }
85
+ };
86
+
87
+ // ../../packages/mikroorm/src/base-resolver/assign.ts
88
+ var import_core7 = require("@mikro-orm/core");
89
+ var import_logger3 = require("@exogee/logger");
90
+
91
+ // ../../packages/mikroorm/src/database.ts
92
+ var import_reflect_metadata2 = require("reflect-metadata");
93
+
94
+ // ../../packages/mikroorm/src/utils/change-tracker.ts
95
+ var import_core5 = require("@mikro-orm/core");
96
+
97
+ // ../../packages/mikroorm/src/entities/audit-change.ts
98
+ var import_core3 = require("@mikro-orm/core");
99
+
100
+ // ../../packages/mikroorm/src/entities/audit-related-entity-change.ts
101
+ var import_core2 = require("@mikro-orm/core");
102
+
103
+ // ../../packages/mikroorm/src/entities/base-entity.ts
104
+ var import_core = require("@mikro-orm/core");
105
+ var BaseEntity = class {
106
+ isReference(_, dataField) {
107
+ return import_core.Reference.isReference(dataField);
108
+ }
109
+ isCollection(fieldName, dataField) {
110
+ return import_core.Utils.isCollection(dataField);
111
+ }
112
+ };
113
+
114
+ // ../../packages/mikroorm/src/entities/audit-related-entity-change.ts
115
+ var AuditRelatedEntityChange = class extends BaseEntity {
116
+ };
117
+ __decorateClass([
118
+ (0, import_core2.PrimaryKey)({ type: import_core2.BigIntType })
119
+ ], AuditRelatedEntityChange.prototype, "id", 2);
120
+ __decorateClass([
121
+ (0, import_core2.ManyToOne)(() => AuditChange, { onDelete: "cascade", wrappedReference: true })
122
+ ], AuditRelatedEntityChange.prototype, "change", 2);
123
+ __decorateClass([
124
+ (0, import_core2.Property)({ type: "string" })
125
+ ], AuditRelatedEntityChange.prototype, "relatedEntityType", 2);
126
+ __decorateClass([
127
+ (0, import_core2.Property)({ type: "string" })
128
+ ], AuditRelatedEntityChange.prototype, "relatedEntityId", 2);
129
+ AuditRelatedEntityChange = __decorateClass([
130
+ (0, import_core2.Entity)(),
131
+ (0, import_core2.Index)({ properties: ["relatedEntityType", "relatedEntityId"] })
132
+ ], AuditRelatedEntityChange);
133
+
134
+ // ../../packages/mikroorm/src/entities/audit-change.ts
135
+ var AuditChange = class extends BaseEntity {
136
+ constructor() {
137
+ super(...arguments);
138
+ this.createdAt = new Date();
139
+ }
140
+ };
141
+ __decorateClass([
142
+ (0, import_core3.PrimaryKey)({ type: import_core3.BigIntType })
143
+ ], AuditChange.prototype, "id", 2);
144
+ __decorateClass([
145
+ (0, import_core3.Enum)({ items: () => import_core3.ChangeSetType, type: "string" })
146
+ ], AuditChange.prototype, "type", 2);
147
+ __decorateClass([
148
+ (0, import_core3.Property)({ type: "string" })
149
+ ], AuditChange.prototype, "entityId", 2);
150
+ __decorateClass([
151
+ (0, import_core3.Property)({ type: "string" })
152
+ ], AuditChange.prototype, "entityType", 2);
153
+ __decorateClass([
154
+ (0, import_core3.Property)({ type: "string" })
155
+ ], AuditChange.prototype, "createdBy", 2);
156
+ __decorateClass([
157
+ (0, import_core3.Property)({ type: "date" })
158
+ ], AuditChange.prototype, "createdAt", 2);
159
+ __decorateClass([
160
+ (0, import_core3.Property)({ type: "json", nullable: true })
161
+ ], AuditChange.prototype, "data", 2);
162
+ __decorateClass([
163
+ (0, import_core3.OneToMany)(() => AuditRelatedEntityChange, "change")
164
+ ], AuditChange.prototype, "relatedEntityChanges", 2);
165
+ AuditChange = __decorateClass([
166
+ (0, import_core3.Entity)(),
167
+ (0, import_core3.Index)({ properties: ["entityType", "entityId"] })
168
+ ], AuditChange);
169
+
170
+ // ../../packages/mikroorm/src/utils/authentication-context.ts
171
+ var import_logger = require("@exogee/logger");
172
+ var AuthenticationContextImplementation = class {
173
+ clear() {
174
+ this.currentUserLogin = void 0;
175
+ }
176
+ set(user) {
177
+ import_logger.logger.trace(`Setting AuthenticationContext.currentUser to ${user}`);
178
+ this.currentUserLogin = user;
179
+ }
180
+ get currentUser() {
181
+ if (!this.currentUserLogin)
182
+ throw new Error("Attempted to access AuthenticationContext before it has been set");
183
+ return this.currentUserLogin;
184
+ }
185
+ };
186
+ var AuthenticationContext = new AuthenticationContextImplementation();
187
+
188
+ // ../../packages/mikroorm/src/utils/tracked-entity.ts
189
+ var import_core4 = require("@mikro-orm/core");
190
+ var TrackedEntity = class extends BaseEntity {
191
+ get relatedTrackedEntities() {
192
+ return void 0;
193
+ }
194
+ };
195
+ __decorateClass([
196
+ (0, import_core4.PrimaryKey)({ type: import_core4.BigIntType })
197
+ ], TrackedEntity.prototype, "id", 2);
198
+
199
+ // ../../packages/mikroorm/src/utils/untracked-property.ts
200
+ var import_reflect_metadata = require("reflect-metadata");
201
+ var untrackedPropertyMetadataKey = Symbol("UntrackedProperty");
202
+ function isUntrackedProperty(target, propertyKey) {
203
+ return Reflect.getMetadata(untrackedPropertyMetadataKey, target, propertyKey);
204
+ }
205
+
206
+ // ../../packages/mikroorm/src/utils/change-tracker.ts
207
+ var ChangeTracker = class {
208
+ async afterFlush({ uow, em }) {
209
+ const changesets = uow.getChangeSets().filter((cs) => cs.entity instanceof TrackedEntity);
210
+ const trx = em.getTransactionContext();
211
+ for (const cs of changesets) {
212
+ let change;
213
+ const data = dataForChangeSet(cs);
214
+ if (data || cs.type === import_core5.ChangeSetType.DELETE) {
215
+ const changeData = {
216
+ type: cs.type,
217
+ entityId: cs.entity.id,
218
+ entityType: cs.name,
219
+ createdAt: new Date(),
220
+ createdBy: AuthenticationContext.currentUser,
221
+ data
222
+ };
223
+ change = await em.getDriver().nativeInsert(AuditChange.name, changeData, trx);
224
+ }
225
+ const entity = cs.entity;
226
+ const relatedEntities = entity.relatedTrackedEntities;
227
+ if (relatedEntities) {
228
+ for (const re of relatedEntities) {
229
+ const relatedEntityData = {
230
+ change: change == null ? void 0 : change.insertId,
231
+ relatedEntityId: re.id,
232
+ relatedEntityType: re.entityType
233
+ };
234
+ await em.getDriver().nativeInsert(AuditRelatedEntityChange.name, relatedEntityData, trx);
235
+ }
236
+ }
237
+ }
238
+ }
239
+ };
240
+ ChangeTracker = __decorateClass([
241
+ (0, import_core5.Subscriber)()
242
+ ], ChangeTracker);
243
+ var dataForChangeSet = (cs) => {
244
+ if (cs.payload && cs.type !== import_core5.ChangeSetType.DELETE) {
245
+ const entries = Object.entries(cs.payload).filter(([k]) => !isUntrackedProperty(cs.entity, k)).map(([k]) => processPayloadEntry(k, cs.type, cs.entity, cs.originalEntity));
246
+ const id = cs.type === import_core5.ChangeSetType.CREATE ? { to: cs.entity.id } : void 0;
247
+ if (entries.length || id)
248
+ return { ...Object.fromEntries(entries), id };
249
+ }
250
+ return void 0;
251
+ };
252
+ var processPayloadEntry = (key, changeSetType, updatedEntity, originalEntity) => {
253
+ let from = originalEntity ? originalEntity[key] : null;
254
+ if (!from && changeSetType === import_core5.ChangeSetType.CREATE)
255
+ from = void 0;
256
+ let to = updatedEntity[key] ?? null;
257
+ if (import_core5.Reference.isReference(to)) {
258
+ const relatedToEntity = to;
259
+ if (from) {
260
+ const id = import_core5.Reference.isReference(from) ? from.getProperty("id") : from;
261
+ from = {
262
+ reference: {
263
+ type: relatedToEntity.constructor.name,
264
+ id
265
+ }
266
+ };
267
+ }
268
+ to = {
269
+ reference: {
270
+ type: relatedToEntity.constructor.name,
271
+ id: relatedToEntity.unwrap().id
272
+ }
273
+ };
274
+ }
275
+ return [key, { from, to }];
276
+ };
277
+
278
+ // ../../packages/mikroorm/src/database.ts
279
+ var import_core6 = require("@mikro-orm/core");
280
+ var import_postgresql = require("@mikro-orm/postgresql");
281
+ var import_logger2 = require("@exogee/logger");
282
+ var FakeEntity = class {
283
+ };
284
+ FakeEntity = __decorateClass([
285
+ (0, import_core6.Entity)()
286
+ ], FakeEntity);
287
+ var IsolationLevel = /* @__PURE__ */ ((IsolationLevel2) => {
288
+ IsolationLevel2["SERIALIZABLE"] = "SERIALIZABLE";
289
+ IsolationLevel2["REPEATABLE_READ"] = "REPEATABLE READ";
290
+ IsolationLevel2["READ_COMMITTED"] = "READ COMMITTED";
291
+ IsolationLevel2["READ_UNCOMMITTED"] = "READ UNCOMMITTED";
292
+ return IsolationLevel2;
293
+ })(IsolationLevel || {});
294
+ var NumericIsolationLevels = {
295
+ ["SERIALIZABLE" /* SERIALIZABLE */]: 4,
296
+ ["REPEATABLE READ" /* REPEATABLE_READ */]: 3,
297
+ ["READ COMMITTED" /* READ_COMMITTED */]: 2,
298
+ ["READ UNCOMMITTED" /* READ_UNCOMMITTED */]: 1
299
+ };
300
+ var DatabaseImplementation = class {
301
+ constructor() {
302
+ this.getConnectionInfo = async (connectionOptions) => {
303
+ import_logger2.logger.trace("Database::getConnectionInfo() - Enter");
304
+ const defaults = {
305
+ host: "localhost",
306
+ port: 5432,
307
+ dbName: "graphweaver"
308
+ };
309
+ const environmentOverrides = {
310
+ host: process.env.DATABASE_HOST,
311
+ port: process.env.DATABASE_PORT ? parseInt(process.env.DATABASE_PORT) : void 0,
312
+ user: process.env.DATABASE_USERNAME,
313
+ password: process.env.DATABASE_PASSWORD,
314
+ dbName: process.env.DATABASE_NAME
315
+ };
316
+ const filterUndefined = (obj) => {
317
+ if (!obj)
318
+ return {};
319
+ for (const key of Object.keys(obj)) {
320
+ if (obj[key] === void 0)
321
+ delete obj[key];
322
+ }
323
+ return obj;
324
+ };
325
+ return {
326
+ ...defaults,
327
+ ...filterUndefined(environmentOverrides),
328
+ ...filterUndefined(connectionOptions == null ? void 0 : connectionOptions.overrides)
329
+ };
330
+ };
331
+ this.getRepository = (entityName) => this.em.getRepository(entityName);
332
+ this.connect = async (connectionOptions) => {
333
+ var _a;
334
+ import_logger2.logger.trace("Database::connect() - Enter");
335
+ if (this.cachedOrm) {
336
+ import_logger2.logger.trace("Returning cached ORM");
337
+ return this.cachedOrm;
338
+ }
339
+ import_logger2.logger.trace("Creating new ORM");
340
+ import_logger2.logger.trace("Getting connection info");
341
+ const params = await this.getConnectionInfo(connectionOptions);
342
+ import_logger2.logger.trace("Initialising ORM");
343
+ import_logger2.logger.trace(`${(_a = params.entities) == null ? void 0 : _a.length}x entities`);
344
+ const orm = await import_core6.MikroORM.init({
345
+ driver: import_postgresql.PostgreSqlDriver,
346
+ ...params,
347
+ implicitTransactions: false,
348
+ metadataProvider: import_core6.ReflectMetadataProvider,
349
+ discovery: { disableDynamicFileAccess: true },
350
+ allowGlobalContext: true,
351
+ pool: {
352
+ min: 1,
353
+ max: 1
354
+ }
355
+ });
356
+ import_logger2.logger.trace("Creating connection to %s on %s", params.dbName, params.host);
357
+ await orm.connect();
358
+ import_logger2.logger.trace("Caching connection");
359
+ this.cachedOrm = orm;
360
+ return orm;
361
+ };
362
+ this.close = async () => {
363
+ import_logger2.logger.trace("Closing database connection");
364
+ await this.orm.close();
365
+ delete this.cachedOrm;
366
+ };
367
+ }
368
+ get orm() {
369
+ if (!this.cachedOrm) {
370
+ const error = new Error("Tried to get the ORM before it was connected.");
371
+ import_logger2.logger.error(error);
372
+ throw error;
373
+ }
374
+ return this.cachedOrm;
375
+ }
376
+ get em() {
377
+ return this.transactionalEm || this.orm.em;
378
+ }
379
+ async transactional(callback, isolationLevel = "READ COMMITTED" /* READ_COMMITTED */) {
380
+ import_logger2.logger.trace("Database::transactional() enter");
381
+ if (this.transactionInProgressIsolationLevel && NumericIsolationLevels[this.transactionInProgressIsolationLevel] < NumericIsolationLevels[isolationLevel]) {
382
+ const error = new Error(
383
+ `Transaction in progress is ${this.transactionInProgressIsolationLevel} isolation level, but ${isolationLevel} was requested, which is more restrictive. Since we can't upgrade, this is an error.`
384
+ );
385
+ import_logger2.logger.error(error);
386
+ throw error;
387
+ }
388
+ if (this.transactionalEm) {
389
+ import_logger2.logger.trace(
390
+ "Transaction already in progress with sufficient isolation, proceeding without new transaction."
391
+ );
392
+ return callback();
393
+ } else {
394
+ import_logger2.logger.trace("Starting transaction");
395
+ return this.em.transactional(async (em) => {
396
+ this.transactionalEm = em;
397
+ this.transactionInProgressIsolationLevel = isolationLevel;
398
+ await em.execute(`SET TRANSACTION ISOLATION LEVEL ${isolationLevel}`);
399
+ let result;
400
+ try {
401
+ result = await callback();
402
+ } finally {
403
+ delete this.transactionalEm;
404
+ delete this.transactionInProgressIsolationLevel;
405
+ }
406
+ return result;
407
+ });
408
+ }
409
+ }
410
+ isolatedTest(test) {
411
+ return async () => {
412
+ try {
413
+ await this.transactional(async () => {
414
+ await test();
415
+ throw new Error("Rollback transaction for test");
416
+ }, "SERIALIZABLE" /* SERIALIZABLE */);
417
+ } catch (error) {
418
+ if (error.message !== "Rollback transaction for test") {
419
+ throw error;
420
+ }
421
+ }
422
+ };
423
+ }
424
+ get rawConnection() {
425
+ return this.em.getDriver().getConnection();
426
+ }
427
+ };
428
+ var Database = new DatabaseImplementation();
429
+ var checkDatabase = async () => {
430
+ await Database.connect();
431
+ const rows = await Database.rawConnection.execute('select 1 = 1 as "ok";');
432
+ return rows[0].ok;
433
+ };
434
+ var getDbSchema = async () => {
435
+ await Database.connect();
436
+ const result = (await Database.orm.getSchemaGenerator().generate()).replace("set names 'utf8';\n", "").replace("set session_replication_role = 'replica';\n", "").replace("set session_replication_role = 'origin';\n", "");
437
+ await Database.close();
438
+ return result;
439
+ };
440
+ var clearDatabaseContext = async (req, res, next, connectionOptions) => {
441
+ await Database.connect(connectionOptions);
442
+ Database.em.clear();
443
+ return next ? next() : void 0;
444
+ };
445
+
446
+ // ../../packages/mikroorm/src/base-resolver/assign.ts
447
+ var assign = async (entity, data, options, visited = /* @__PURE__ */ new Set()) => {
448
+ if (visited.has(entity))
449
+ return entity;
450
+ visited.add(entity);
451
+ const metadata = (0, import_core7.wrap)(entity, true).__meta;
452
+ for (const [property, value] of Object.entries(data)) {
453
+ const entityPropertyValue = entity[property];
454
+ const propertyMetadata = metadata.properties[property];
455
+ if ((propertyMetadata == null ? void 0 : propertyMetadata.reference) === import_core7.ReferenceType.MANY_TO_MANY || (propertyMetadata == null ? void 0 : propertyMetadata.reference) === import_core7.ReferenceType.ONE_TO_MANY) {
456
+ if (!Array.isArray(value))
457
+ throw new Error(
458
+ `Value is not an array while trying to assign to collection property ${property} on entity ${metadata.name}`
459
+ );
460
+ if (!(entityPropertyValue instanceof import_core7.Collection)) {
461
+ throw new Error(
462
+ `Tried to merge array into non-collection property ${property} on entity ${metadata.name}`
463
+ );
464
+ }
465
+ const visitedEntities = /* @__PURE__ */ new Set();
466
+ for (const subvalue of value) {
467
+ let entity2;
468
+ if (subvalue.id) {
469
+ entity2 = Database.em.getUnitOfWork().getById(propertyMetadata.type, subvalue.id);
470
+ if (!entity2) {
471
+ if (Object.keys(subvalue).length === 1) {
472
+ entity2 = Database.em.getReference(propertyMetadata.type, subvalue.id);
473
+ } else {
474
+ import_logger3.logger.warn(
475
+ `Doing a full database fetch for ${propertyMetadata.type} with id ${subvalue.id}, this should ideally be prefetched into the Unit of Work before calling assign() for performance`
476
+ );
477
+ entity2 = await Database.em.findOne(propertyMetadata.type, {
478
+ id: subvalue.id
479
+ }) ?? void 0;
480
+ }
481
+ }
482
+ if (!entity2) {
483
+ throw new Error(
484
+ `Attempted to assign as an update to '${propertyMetadata.name}' property of ${metadata.name} Entity, but even after a full fetch to the database ${propertyMetadata.type} with ID of ${subvalue.id} could not be found.`
485
+ );
486
+ }
487
+ }
488
+ const newEntity = await createOrAssignEntity({
489
+ entity: entity2,
490
+ entityType: propertyMetadata.type,
491
+ data: subvalue,
492
+ options,
493
+ visited
494
+ });
495
+ entityPropertyValue.add(newEntity);
496
+ visitedEntities.add(newEntity);
497
+ }
498
+ entityPropertyValue.remove(
499
+ ...entityPropertyValue.getItems().filter((entity2) => !visitedEntities.has(entity2))
500
+ );
501
+ } else if ((propertyMetadata == null ? void 0 : propertyMetadata.reference) == import_core7.ReferenceType.MANY_TO_ONE || (propertyMetadata == null ? void 0 : propertyMetadata.reference) === import_core7.ReferenceType.ONE_TO_ONE) {
502
+ if (value === null) {
503
+ entity[property] = null;
504
+ } else {
505
+ const valueKeys = Object.keys(value);
506
+ if (valueKeys.length === 1 && valueKeys[0] === "id") {
507
+ entity[property] = Database.em.getReference(
508
+ propertyMetadata.type,
509
+ value.id
510
+ );
511
+ } else {
512
+ if (entityPropertyValue && !import_core7.Reference.isReference(entityPropertyValue)) {
513
+ throw new Error(
514
+ `Trying to merge to related property ${property} on entity ${metadata.name} which is not a reference.`
515
+ );
516
+ }
517
+ if (entityPropertyValue && !entityPropertyValue.isInitialized()) {
518
+ throw new Error(
519
+ `Trying to merge to related property ${property} on entity ${metadata.name} which is not initialised.`
520
+ );
521
+ }
522
+ const newEntity = await createOrAssignEntity({
523
+ entity: entityPropertyValue == null ? void 0 : entityPropertyValue.unwrap(),
524
+ entityType: propertyMetadata.type,
525
+ data: value,
526
+ options,
527
+ visited
528
+ });
529
+ entity[property] = import_core7.Reference.create(newEntity);
530
+ }
531
+ }
532
+ } else {
533
+ entity[property] = value;
534
+ }
535
+ }
536
+ return entity;
537
+ };
538
+ var createOrAssignEntity = ({
539
+ entity,
540
+ entityType,
541
+ data,
542
+ options,
543
+ visited
544
+ }) => {
545
+ const create = (options == null ? void 0 : options.create) ?? true;
546
+ const update = (options == null ? void 0 : options.update) ?? true;
547
+ if (data.id) {
548
+ if (!update) {
549
+ throw new Error(
550
+ `Updates are disabled, but update value ${JSON.stringify(
551
+ data
552
+ )} was passed which has an ID property.`
553
+ );
554
+ }
555
+ if (!entity) {
556
+ throw new Error(
557
+ `Tried to update with data ${JSON.stringify(
558
+ data
559
+ )} but entity could not be located to update.`
560
+ );
561
+ }
562
+ return assign(entity, data, options, visited);
563
+ } else {
564
+ if (!create) {
565
+ throw new Error(
566
+ `Creates are disabled, but update value ${JSON.stringify(
567
+ data
568
+ )} was passed which does not have an ID property.`
569
+ );
570
+ }
571
+ const entity2 = Database.em.create(entityType, {});
572
+ return assign(entity2, data, options, visited);
573
+ }
574
+ };
575
+
576
+ // ../../packages/mikroorm/src/base-resolver/provider.ts
577
+ var objectOperations = /* @__PURE__ */ new Set(["_and", "_or", "_not"]);
578
+ var mikroObjectOperations = /* @__PURE__ */ new Set(["$and", "$or", "$not"]);
579
+ var nonJoinKeys = /* @__PURE__ */ new Set([
580
+ "$and",
581
+ "$gt",
582
+ "$gte",
583
+ "$in",
584
+ "$lt",
585
+ "$lte",
586
+ "$ne",
587
+ "$nin",
588
+ "$not",
589
+ "$or",
590
+ "$like",
591
+ "$ilike",
592
+ "$null",
593
+ "$notnull",
594
+ "id"
595
+ ]);
596
+ var appendPath = (path, newPath) => path.length ? `${path}.${newPath}` : newPath;
597
+ var visitPathForPopulate = (entityName, updateArgBranch, populateBranch = "") => {
598
+ var _a, _b, _c, _d;
599
+ const { properties } = Database.em.getMetadata().get(entityName);
600
+ const collectedPaths = populateBranch ? /* @__PURE__ */ new Set([populateBranch]) : /* @__PURE__ */ new Set([]);
601
+ for (const [key, value] of Object.entries(updateArgBranch ?? {})) {
602
+ if (((_a = properties[key]) == null ? void 0 : _a.reference) === import_core10.ReferenceType.ONE_TO_ONE || ((_b = properties[key]) == null ? void 0 : _b.reference) === import_core10.ReferenceType.ONE_TO_MANY || ((_c = properties[key]) == null ? void 0 : _c.reference) === import_core10.ReferenceType.MANY_TO_ONE || ((_d = properties[key]) == null ? void 0 : _d.reference) === import_core10.ReferenceType.MANY_TO_MANY) {
603
+ if (Array.isArray(value)) {
604
+ collectedPaths.add(appendPath(populateBranch, key));
605
+ for (const entry of value) {
606
+ const newPaths = visitPathForPopulate(
607
+ properties[key].type,
608
+ entry,
609
+ appendPath(populateBranch, key)
610
+ );
611
+ newPaths.forEach((path) => collectedPaths.add(path));
612
+ }
613
+ } else if (typeof value === "object") {
614
+ const newPaths = visitPathForPopulate(
615
+ properties[key].type,
616
+ value,
617
+ appendPath(populateBranch, key)
618
+ );
619
+ newPaths.forEach((path) => collectedPaths.add(path));
620
+ }
621
+ }
622
+ }
623
+ return collectedPaths;
624
+ };
625
+ var gqlToMikro = (filter) => {
626
+ if (Array.isArray(filter)) {
627
+ return filter.map((element) => gqlToMikro(element));
628
+ } else if (typeof filter === "object") {
629
+ for (const key of Object.keys(filter)) {
630
+ if (filter[key] === null)
631
+ continue;
632
+ if (objectOperations.has(key)) {
633
+ filter[key.replace("_", "$")] = gqlToMikro(filter[key]);
634
+ delete filter[key];
635
+ } else if (typeof filter[key] === "object" && !Array.isArray(filter[key])) {
636
+ filter[key] = gqlToMikro(filter[key]);
637
+ } else if (key.indexOf("_") >= 0) {
638
+ const [newKey, operator] = key.split("_");
639
+ const newValue = { [`$${operator}`]: gqlToMikro(filter[key]) };
640
+ if (typeof filter[newKey] !== "undefined") {
641
+ filter[newKey] = { ...filter[newKey], ...newValue };
642
+ } else {
643
+ filter[newKey] = newValue;
644
+ }
645
+ delete filter[key];
646
+ }
647
+ }
648
+ }
649
+ return filter;
650
+ };
651
+ var mapAndAssignKeys = (result, entityType, inputArgs) => {
652
+ const cleanInput = JSON.parse(JSON.stringify(inputArgs));
653
+ return assign(result, cleanInput);
654
+ };
655
+ var MikroBackendProvider = class {
656
+ constructor(mikroType) {
657
+ this.backendId = "mikro-orm";
658
+ this.supportsInFilter = true;
659
+ this.getRepository = () => {
660
+ const repository = Database.em.getRepository(this.entityType);
661
+ if (!repository)
662
+ throw new Error("Could not find repository for " + this.entityType.name);
663
+ return repository;
664
+ };
665
+ this.entityType = mikroType;
666
+ }
667
+ applyWhereClause(where) {
668
+ const query = this.getRepository().createQueryBuilder();
669
+ const joinKeysUsed = /* @__PURE__ */ new Map();
670
+ if (where) {
671
+ const visit = (current, table = "e0") => {
672
+ if (Array.isArray(current)) {
673
+ for (const element of current) {
674
+ visit(element, table);
675
+ }
676
+ } else if (typeof current === "object") {
677
+ for (const key of Object.keys(current)) {
678
+ const shouldJoin = current[key] !== null && typeof current[key] === "object" && Object.keys(current[key]).filter((key2) => !nonJoinKeys.has(key2)).length > 0;
679
+ if (mikroObjectOperations.has(key)) {
680
+ visit(current[key], table);
681
+ } else if (shouldJoin) {
682
+ const keyUseCount = joinKeysUsed.has(key) ? (joinKeysUsed.get(key) ?? 0) + 1 : 1;
683
+ const joinKey = joinKeysUsed.has(key) ? `${key}${keyUseCount}` : key;
684
+ query.leftJoin(`${table}.${key}`, joinKey);
685
+ joinKeysUsed.set(joinKey, keyUseCount);
686
+ visit(current[key], key);
687
+ }
688
+ if (current[key] !== null && typeof current[key] === "object" && Object.keys(current[key]).length === 0) {
689
+ delete current[key];
690
+ }
691
+ }
692
+ }
693
+ };
694
+ visit(where);
695
+ if (Object.keys(where).length > 0) {
696
+ query.andWhere(where);
697
+ }
698
+ }
699
+ return query;
700
+ }
701
+ async find(filter, pagination, additionalOptionsForBackend) {
702
+ import_logger4.logger.trace(`Running find ${this.entityType.name} with filter`, {
703
+ filter: JSON.stringify(filter)
704
+ });
705
+ const where = filter ? gqlToMikro(JSON.parse(JSON.stringify(filter))) : void 0;
706
+ const query = this.applyWhereClause(where);
707
+ (pagination == null ? void 0 : pagination.limit) && query.limit(pagination.limit);
708
+ (pagination == null ? void 0 : pagination.offset) && query.offset(pagination.offset);
709
+ (pagination == null ? void 0 : pagination.orderBy) && query.orderBy({ ...pagination.orderBy });
710
+ query.setFlag(import_core10.QueryFlag.DISTINCT);
711
+ const driver = Database.em.getDriver();
712
+ const meta = Database.em.getMetadata().get(this.entityType.name);
713
+ query.populate(driver.autoJoinOneToOneOwner(meta, []));
714
+ if (additionalOptionsForBackend == null ? void 0 : additionalOptionsForBackend.populate) {
715
+ query.populate(additionalOptionsForBackend.populate);
716
+ }
717
+ const result = await query.getResult();
718
+ import_logger4.logger.trace(`find ${this.entityType.name} result: ${result.length} rows`);
719
+ return result;
720
+ }
721
+ async findOne(id) {
722
+ import_logger4.logger.trace(`Running findOne ${this.entityType.name} with ID ${id}`);
723
+ const result = await Database.em.findOne(this.entityType, id);
724
+ import_logger4.logger.trace(`findOne ${this.entityType.name} result`, { result });
725
+ return result;
726
+ }
727
+ async findByRelatedId(entity, relatedField, relatedFieldIds, filter) {
728
+ const queryFilter = {
729
+ $and: [{ [relatedField]: { $in: relatedFieldIds } }, ...[filter ?? []]]
730
+ };
731
+ const populate = [relatedField];
732
+ const result = await Database.em.find(entity, queryFilter, { populate });
733
+ return result;
734
+ }
735
+ async updateOne(id, updateArgs) {
736
+ import_logger4.logger.trace(`Running update ${this.entityType.name} with args`, {
737
+ id,
738
+ updateArgs: JSON.stringify(updateArgs)
739
+ });
740
+ const entity = await Database.em.findOne(this.entityType, id, {
741
+ populate: [...visitPathForPopulate(this.entityType.name, updateArgs)]
742
+ });
743
+ if (entity === null) {
744
+ throw new Error(`Unable to locate ${this.entityType.name} with ID: '${id}' for updating.`);
745
+ }
746
+ if (updateArgs == null ? void 0 : updateArgs.version) {
747
+ try {
748
+ await Database.em.lock(entity, import_core10.LockMode.OPTIMISTIC, updateArgs.version);
749
+ delete updateArgs.version;
750
+ } catch (err) {
751
+ throw new OptimisticLockError(err == null ? void 0 : err.message, { entity });
752
+ }
753
+ }
754
+ await mapAndAssignKeys(entity, this.entityType, updateArgs);
755
+ await this.getRepository().persistAndFlush(entity);
756
+ import_logger4.logger.trace(`update ${this.entityType.name} entity`, entity);
757
+ return entity;
758
+ }
759
+ async updateMany(updateItems) {
760
+ import_logger4.logger.trace(`Running update many ${this.entityType.name} with args`, {
761
+ updateItems: JSON.stringify(updateItems)
762
+ });
763
+ const entities = await Database.transactional(async () => {
764
+ return Promise.all(
765
+ updateItems.map(async (item) => {
766
+ if (!(item == null ? void 0 : item.id))
767
+ throw new Error("You must pass an ID for this entity to update it.");
768
+ const entity = await Database.em.findOneOrFail(this.entityType, item.id, {
769
+ populate: [...visitPathForPopulate(this.entityType.name, item)]
770
+ });
771
+ await mapAndAssignKeys(entity, this.entityType, item);
772
+ Database.em.persist(entity);
773
+ return entity;
774
+ })
775
+ );
776
+ });
777
+ import_logger4.logger.trace(`updated ${this.entityType.name} items `, entities);
778
+ return entities;
779
+ }
780
+ async createOrUpdateMany(items) {
781
+ import_logger4.logger.trace(`Running create or update many for ${this.entityType.name} with args`, {
782
+ items: JSON.stringify(items)
783
+ });
784
+ const entities = await Database.transactional(async () => {
785
+ return Promise.all(
786
+ items.map(async (item) => {
787
+ let entity;
788
+ const { id } = item;
789
+ if (id) {
790
+ entity = await Database.em.findOneOrFail(this.entityType, id, {
791
+ populate: [...visitPathForPopulate(this.entityType.name, item)]
792
+ });
793
+ import_logger4.logger.trace(`Running update on ${this.entityType.name} with item`, {
794
+ item: JSON.stringify(item)
795
+ });
796
+ await mapAndAssignKeys(entity, this.entityType, item);
797
+ } else {
798
+ entity = new this.entityType();
799
+ await mapAndAssignKeys(entity, this.entityType, item);
800
+ import_logger4.logger.trace(`Running create on ${this.entityType.name} with item`, {
801
+ item: JSON.stringify(item)
802
+ });
803
+ }
804
+ Database.em.persist(entity);
805
+ return entity;
806
+ })
807
+ );
808
+ });
809
+ import_logger4.logger.trace(`created or updated ${this.entityType.name} items `, entities);
810
+ return entities;
811
+ }
812
+ async createOne(createArgs) {
813
+ import_logger4.logger.trace(`Running create ${this.entityType.name} with args`, {
814
+ createArgs: JSON.stringify(createArgs)
815
+ });
816
+ const entity = new this.entityType();
817
+ await mapAndAssignKeys(entity, this.entityType, createArgs);
818
+ await this.getRepository().persistAndFlush(entity);
819
+ import_logger4.logger.trace(`create ${this.entityType.name} result`, entity);
820
+ return entity;
821
+ }
822
+ async createMany(createItems) {
823
+ import_logger4.logger.trace(`Running create ${this.entityType.name} with args`, {
824
+ createArgs: JSON.stringify(createItems)
825
+ });
826
+ const entities = await Database.transactional(async () => {
827
+ return Promise.all(
828
+ createItems.map(async (item) => {
829
+ const entity = new this.entityType();
830
+ await mapAndAssignKeys(entity, this.entityType, item);
831
+ Database.em.persist(entity);
832
+ return entity;
833
+ })
834
+ );
835
+ });
836
+ import_logger4.logger.trace(`created ${this.entityType.name} items `, entities);
837
+ return entities;
838
+ }
839
+ async deleteOne(id) {
840
+ import_logger4.logger.trace(`Running delete ${this.entityType.name} with id ${id}`);
841
+ const deletedRows = await this.getRepository().nativeDelete({
842
+ id
843
+ });
844
+ if (deletedRows > 1) {
845
+ throw new Error("Multiple deleted rows");
846
+ }
847
+ import_logger4.logger.trace(`delete ${this.entityType.name} result: deleted ${deletedRows} row(s)`);
848
+ return deletedRows === 1;
849
+ }
850
+ async deleteMany(ids) {
851
+ import_logger4.logger.trace(`Running delete ${this.entityType.name} with ids ${ids}`);
852
+ const deletedRows = await Database.transactional(async () => {
853
+ const deletedCount = await this.getRepository().nativeDelete({
854
+ id: { $in: ids }
855
+ });
856
+ if (deletedCount !== ids.length) {
857
+ throw new Error("We did not delete all the rows, rolling back");
858
+ }
859
+ return deletedCount;
860
+ });
861
+ import_logger4.logger.trace(`delete ${this.entityType.name} result: deleted ${deletedRows} row(s)`);
862
+ return deletedRows === ids.length;
863
+ }
864
+ getRelatedEntityId(entity, relatedIdField) {
865
+ if (typeof entity.unwrap !== "function") {
866
+ throw new Error("Could not unwrap related entity");
867
+ }
868
+ return entity.unwrap().id;
869
+ }
870
+ isCollection(entity) {
871
+ return import_core10.Utils.isCollection(entity);
872
+ }
873
+ };
874
+
875
+ // ../../packages/mikroorm/src/types/date-type.ts
876
+ var import_core8 = require("@mikro-orm/core");
877
+ var DatePattern = /^\d{4}-\d{1,2}-\d{1,2}$/;
878
+ var DateType = class extends import_core8.Type {
879
+ convertToDatabaseValue(value, platform) {
880
+ if (!value)
881
+ return value;
882
+ if (typeof value === "string") {
883
+ const [date] = value.split("T");
884
+ const [year, month, day] = date.split("-");
885
+ return new Date(`${year}-${month}-${day}T00:00:00Z`);
886
+ }
887
+ throw import_core8.ValidationError.invalidType(DateType, value, "JS");
888
+ }
889
+ convertToJSValue(value, platform) {
890
+ if (!value)
891
+ return value;
892
+ if (typeof value === "string" && DatePattern.test(value)) {
893
+ return value;
894
+ }
895
+ throw import_core8.ValidationError.invalidType(DateType, value, "database");
896
+ }
897
+ getColumnType(prop, platform) {
898
+ return "date";
899
+ }
900
+ toJSON(value, platform) {
901
+ if (!value)
902
+ return value;
903
+ if (value instanceof Date) {
904
+ return `${value.getFullYear()}-${value.getMonth() + 1}-${value.getDate()}`;
905
+ } else if (typeof value === "string") {
906
+ return value;
907
+ }
908
+ throw import_core8.ValidationError.invalidType(DateType, value, "JS");
909
+ }
910
+ };
911
+
912
+ // ../../packages/mikroorm/src/types/time-type.ts
913
+ var import_core9 = require("@mikro-orm/core");
914
+ var TimePattern = /^\d{2}:\d{2}:\d{2}$/;
915
+ var Time = class {
916
+ constructor(hour = 0, minute = 0, second = 0) {
917
+ this.hour = hour;
918
+ this.minute = minute;
919
+ this.second = second;
920
+ if (hour > 23 || hour < 0)
921
+ throw new Error(`Invalid time '${hour}:${minute}:${second}`);
922
+ if (minute > 59 || minute < 0)
923
+ throw new Error(`Invalid time '${hour}:${minute}:${second}`);
924
+ if (second > 59 || second < 0)
925
+ throw new Error(`Invalid time '${hour}:${minute}:${second}`);
926
+ }
927
+ toString() {
928
+ return `${this.hour.toString().padStart(2, "0")}:${this.minute.toString().padStart(2, "0")}:${this.second.toString().padStart(2, "0")}`;
929
+ }
930
+ };
931
+ var TimeType = class extends import_core9.Type {
932
+ convertToDatabaseValue(value, platform) {
933
+ if (!value)
934
+ return value;
935
+ if (value instanceof Time)
936
+ return value;
937
+ throw import_core9.ValidationError.invalidType(TimeType, value, "JS");
938
+ }
939
+ convertToJSValue(value, platform) {
940
+ if (!value)
941
+ return value;
942
+ if (typeof value === "string" && TimePattern.test(value)) {
943
+ const [hour, minute, second] = value.split(":");
944
+ return new Time(+hour, +minute, +second);
945
+ }
946
+ throw import_core9.ValidationError.invalidType(TimeType, value, "database");
947
+ }
948
+ getColumnType(prop, platform) {
949
+ return "time";
950
+ }
951
+ toJSON(value, platform) {
952
+ if (!value)
953
+ return value;
954
+ if (value instanceof Time)
955
+ return Time.toString();
956
+ throw import_core9.ValidationError.invalidType(TimeType, value, "JS");
957
+ }
958
+ };
959
+
960
+ // ../../packages/mikroorm/src/index.ts
961
+ var import_core10 = require("@mikro-orm/core");
962
+ var import_postgresql2 = require("@mikro-orm/postgresql");
963
+ dotenv.config({
964
+ path: `.env.${(process.env.NODE_ENV || "development").toLowerCase()}`
965
+ });
966
+ // Annotate the CommonJS export names for ESM import in node:
967
+ 0 && (module.exports = {
968
+ AuditChange,
969
+ AuditRelatedEntityChange,
970
+ AuthenticationContext,
971
+ BaseEntity,
972
+ ChangeSetType,
973
+ Collection,
974
+ Database,
975
+ DatabaseObjectNotFoundException,
976
+ DateType,
977
+ EntityManager,
978
+ EntityRepository,
979
+ IsolationLevel,
980
+ LockMode,
981
+ MikroBackendProvider,
982
+ PrimaryKeyType,
983
+ QueryFlag,
984
+ QueryOrder,
985
+ Reference,
986
+ ReferenceType,
987
+ SqlEntityManager,
988
+ SqlEntityRepository,
989
+ Subscriber,
990
+ Time,
991
+ TimeType,
992
+ UniqueConstraintViolationException,
993
+ Utils,
994
+ checkDatabase,
995
+ clearDatabaseContext,
996
+ getDbSchema,
997
+ gqlToMikro,
998
+ mapAndAssignKeys,
999
+ visitPathForPopulate,
1000
+ wrap
1001
+ });
1002
+ //# sourceMappingURL=index.js.map