@exogee/graphweaver-mikroorm 0.1.16 → 0.1.17
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/base-resolver/provider.d.ts +2 -2
- package/lib/base-resolver/provider.js +3 -3
- package/lib/base-resolver/provider.js.map +2 -2
- package/lib/database.d.ts +2 -1
- package/lib/database.js +5 -0
- package/lib/database.js.map +2 -2
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/index.js.map +2 -2
- package/lib/plugins/clear-database-context.d.ts +2 -0
- package/lib/plugins/clear-database-context.js +41 -0
- package/lib/plugins/clear-database-context.js.map +7 -0
- package/lib/plugins/connect-to-database.d.ts +3 -0
- package/lib/plugins/connect-to-database.js +43 -0
- package/lib/plugins/connect-to-database.js.map +7 -0
- package/lib/plugins/index.d.ts +2 -0
- package/lib/plugins/index.js +32 -0
- package/lib/plugins/index.js.map +7 -0
- package/package.json +4 -3
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BackendProvider, PaginationOptions, Filter, GraphQLEntity, BaseDataEntity } from '@exogee/graphweaver';
|
|
2
|
-
import { IsolationLevel } from '..';
|
|
2
|
+
import { IsolationLevel, ConnectionOptions } from '..';
|
|
3
3
|
export declare const gqlToMikro: (filter: any) => any;
|
|
4
4
|
export declare class MikroBackendProvider<D extends BaseDataEntity, G extends GraphQLEntity<D>> implements BackendProvider<D, G> {
|
|
5
5
|
private _backendId;
|
|
@@ -13,7 +13,7 @@ export declare class MikroBackendProvider<D extends BaseDataEntity, G extends Gr
|
|
|
13
13
|
withTransaction<T>(callback: () => Promise<T>): Promise<T>;
|
|
14
14
|
get em(): import("@mikro-orm/postgresql").EntityManager<import("@mikro-orm/postgresql").PostgreSqlDriver> | import("@mikro-orm/postgresql").EntityManager<import("@mikro-orm/mysql").MySqlDriver>;
|
|
15
15
|
private getRepository;
|
|
16
|
-
constructor(mikroType: new () => D,
|
|
16
|
+
constructor(mikroType: new () => D, connection: ConnectionOptions, transactionIsolationLevel?: IsolationLevel);
|
|
17
17
|
private mapAndAssignKeys;
|
|
18
18
|
private applyExternalIdFields;
|
|
19
19
|
visitPathForPopulate: (entityName: string, updateArgBranch: any, populateBranch?: string) => Set<string>;
|
|
@@ -74,7 +74,7 @@ const gqlToMikro = (filter) => {
|
|
|
74
74
|
return filter;
|
|
75
75
|
};
|
|
76
76
|
class MikroBackendProvider {
|
|
77
|
-
constructor(mikroType,
|
|
77
|
+
constructor(mikroType, connection, transactionIsolationLevel = import__.IsolationLevel.REPEATABLE_READ) {
|
|
78
78
|
this.supportsInFilter = true;
|
|
79
79
|
this.getRepository = () => {
|
|
80
80
|
const repository = this.database.em.getRepository(this.entityType);
|
|
@@ -155,8 +155,8 @@ class MikroBackendProvider {
|
|
|
155
155
|
return collectedPaths;
|
|
156
156
|
};
|
|
157
157
|
this.entityType = mikroType;
|
|
158
|
-
this.connectionManagerId = connectionManagerId;
|
|
159
|
-
this._backendId = `mikro-orm-${connectionManagerId || ""}`;
|
|
158
|
+
this.connectionManagerId = connection.connectionManagerId;
|
|
159
|
+
this._backendId = `mikro-orm-${connection.connectionManagerId || ""}`;
|
|
160
160
|
this.transactionIsolationLevel = transactionIsolationLevel;
|
|
161
161
|
}
|
|
162
162
|
get backendId() {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/base-resolver/provider.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n\tBackendProvider,\n\tPaginationOptions,\n\tSort,\n\tFilter,\n\tGraphQLEntity,\n\tBaseDataEntity,\n} from '@exogee/graphweaver';\nimport { logger } from '@exogee/logger';\n\nimport {\n\tFilterQuery,\n\tLockMode,\n\tQueryFlag,\n\tReferenceType,\n\tUtils,\n\tConnectionManager,\n\texternalIdFieldMap,\n\tAnyEntity,\n\tIsolationLevel,\n} from '..';\nimport { OptimisticLockError } from '../utils/errors';\nimport { assign } from './assign';\n\nimport type { SqlEntityRepository } from '@mikro-orm/postgresql';\n\nconst objectOperations = new Set(['_and', '_or', '_not']);\nconst mikroObjectOperations = new Set(['$and', '$or', '$not']);\nconst nonJoinKeys = new Set([\n\t'$and',\n\t'$gt',\n\t'$gte',\n\t'$in',\n\t'$lt',\n\t'$lte',\n\t'$ne',\n\t'$nin',\n\t'$not',\n\t'$or',\n\t'$like',\n\t'$ilike',\n\t'$null',\n\t'$notnull',\n\t'id', // @todo: remove this? Why is it here?\n]);\n\nconst appendPath = (path: string, newPath: string) =>\n\tpath.length ? `${path}.${newPath}` : newPath;\n\nexport const gqlToMikro: (filter: any) => any = (filter: any) => {\n\tif (Array.isArray(filter)) {\n\t\treturn filter.map((element) => gqlToMikro(element));\n\t} else if (typeof filter === 'object') {\n\t\tfor (const key of Object.keys(filter)) {\n\t\t\t// A null here is a user-specified value and is valid to filter on\n\t\t\tif (filter[key] === null) continue;\n\n\t\t\tif (objectOperations.has(key)) {\n\t\t\t\t// { _not: '1' } => { $not: '1' }\n\t\t\t\tfilter[key.replace('_', '$')] = gqlToMikro(filter[key]);\n\t\t\t\tdelete filter[key];\n\t\t\t} else if (typeof filter[key] === 'object' && !Array.isArray(filter[key])) {\n\t\t\t\t// Recurse over nested filters only (arrays are an argument to a filter, not a nested filter)\n\t\t\t\tfilter[key] = gqlToMikro(filter[key]);\n\t\t\t} else if (key.indexOf('_') >= 0) {\n\t\t\t\t// { firstName_in: ['k', 'b'] } => { firstName: { $in: ['k', 'b'] } }\n\t\t\t\tconst [newKey, operator] = key.split('_');\n\t\t\t\tconst newValue = { [`$${operator}`]: gqlToMikro(filter[key]) };\n\n\t\t\t\t// They can construct multiple filters for the same key. In that case we need\n\t\t\t\t// to append them all into an object.\n\t\t\t\tif (typeof filter[newKey] !== 'undefined') {\n\t\t\t\t\tfilter[newKey] = { ...filter[newKey], ...newValue };\n\t\t\t\t} else {\n\t\t\t\t\tfilter[newKey] = newValue;\n\t\t\t\t}\n\n\t\t\t\tdelete filter[key];\n\t\t\t}\n\t\t}\n\t}\n\treturn filter;\n};\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport class MikroBackendProvider<D extends BaseDataEntity, G extends GraphQLEntity<D>>\n\timplements BackendProvider<D, G>\n{\n\tprivate _backendId: string;\n\n\tpublic entityType: new () => D;\n\tpublic connectionManagerId?: string;\n\tprivate transactionIsolationLevel!: IsolationLevel;\n\n\tpublic readonly supportsInFilter = true;\n\n\tget backendId() {\n\t\treturn this._backendId;\n\t}\n\n\tprivate get database() {\n\t\t// If we have a connection manager ID then use that else fallback to the Database\n\t\tif (!this.connectionManagerId) return ConnectionManager.default;\n\t\treturn ConnectionManager.database(this.connectionManagerId) || ConnectionManager.default;\n\t}\n\n\t// This is exposed for use in the RLS package\n\tpublic get transactional() {\n\t\treturn this.database.transactional;\n\t}\n\n\tpublic async withTransaction<T>(callback: () => Promise<T>) {\n\t\treturn this.database.transactional<T>(callback, this.transactionIsolationLevel);\n\t}\n\n\t// This is exposed for use in the RLS package\n\tpublic get em() {\n\t\treturn this.database.em;\n\t}\n\n\tprivate getRepository: () => SqlEntityRepository<D> = () => {\n\t\tconst repository = this.database.em.getRepository<D>(this.entityType);\n\t\tif (!repository) throw new Error('Could not find repository for ' + this.entityType.name);\n\n\t\treturn repository as SqlEntityRepository<D>;\n\t};\n\n\tpublic constructor(\n\t\tmikroType: new () => D,\n\t\tconnectionManagerId?: string,\n\t\ttransactionIsolationLevel: IsolationLevel = IsolationLevel.REPEATABLE_READ\n\t) {\n\t\tthis.entityType = mikroType;\n\t\tthis.connectionManagerId = connectionManagerId;\n\t\tthis._backendId = `mikro-orm-${connectionManagerId || ''}`;\n\t\tthis.transactionIsolationLevel = transactionIsolationLevel;\n\t}\n\n\tprivate mapAndAssignKeys = (result: D, entityType: new () => D, inputArgs: Partial<G>) => {\n\t\t// Clean the input and remove any GraphQL classes from the object\n\t\t// const cleanInput = JSON.parse(JSON.stringify(inputArgs));\n\t\tconst assignmentObj = this.applyExternalIdFields(entityType, inputArgs);\n\t\treturn assign(result, assignmentObj, undefined, undefined, this.database.em);\n\t};\n\n\tprivate applyExternalIdFields = (target: AnyEntity | string, values: any) => {\n\t\tconst targetName = typeof target === 'string' ? target : target.name;\n\t\tconst map = externalIdFieldMap.get(targetName);\n\n\t\tconst mapFieldNames = (partialFilterObj: any) => {\n\t\t\tfor (const [from, to] of Object.entries(map || {})) {\n\t\t\t\tif (partialFilterObj[from] && typeof partialFilterObj[from].id !== 'undefined') {\n\t\t\t\t\tif (Object.keys(partialFilterObj[from]).length > 1) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Expected precisely 1 key called 'id' in queryObj.${from} on ${target}, got ${JSON.stringify(\n\t\t\t\t\t\t\t\tpartialFilterObj[from],\n\t\t\t\t\t\t\t\tnull,\n\t\t\t\t\t\t\t\t4\n\t\t\t\t\t\t\t)}`\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tpartialFilterObj[to] = partialFilterObj[from].id;\n\t\t\t\t\tdelete partialFilterObj[from];\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\t// Check for and/or/etc at the root level and handle correctly\n\t\tfor (const rootLevelKey of Object.keys(values)) {\n\t\t\tif (mikroObjectOperations.has(rootLevelKey)) {\n\t\t\t\tfor (const field of values[rootLevelKey]) {\n\t\t\t\t\tmapFieldNames(field);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Map the rest of the field names as well\n\t\tmapFieldNames(values);\n\n\t\t// Traverse the nested entities\n\t\tconst { properties } = this.database.em.getMetadata().get(targetName);\n\t\tObject.values(properties)\n\t\t\t.filter((property) => typeof property.entity !== 'undefined' && values[property.name])\n\t\t\t.forEach((property) => {\n\t\t\t\tif (Array.isArray(values[property.name])) {\n\t\t\t\t\tvalues[property.name].forEach((value: any) =>\n\t\t\t\t\t\tthis.applyExternalIdFields(property.type, value)\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tvalues[property.name] = this.applyExternalIdFields(property.type, values[property.name]);\n\t\t\t\t}\n\t\t\t});\n\n\t\treturn values;\n\t};\n\n\t// Check if we have any keys that are a collection of entities\n\tpublic visitPathForPopulate = (entityName: string, updateArgBranch: any, populateBranch = '') => {\n\t\tconst { properties } = this.database.em.getMetadata().get(entityName);\n\t\tconst collectedPaths = populateBranch ? new Set<string>([populateBranch]) : new Set<string>([]);\n\n\t\tfor (const [key, value] of Object.entries(updateArgBranch ?? {})) {\n\t\t\tif (\n\t\t\t\t// If it's a relationship, go ahead and and '.' it in, recurse.\n\t\t\t\tproperties[key]?.reference === ReferenceType.ONE_TO_ONE ||\n\t\t\t\tproperties[key]?.reference === ReferenceType.ONE_TO_MANY ||\n\t\t\t\tproperties[key]?.reference === ReferenceType.MANY_TO_ONE ||\n\t\t\t\tproperties[key]?.reference === ReferenceType.MANY_TO_MANY\n\t\t\t) {\n\t\t\t\tif (Array.isArray(value)) {\n\t\t\t\t\t// In the case where the array is empty we also need to make sure we load the collection.\n\t\t\t\t\tcollectedPaths.add(appendPath(populateBranch, key));\n\n\t\t\t\t\tfor (const entry of value) {\n\t\t\t\t\t\t// Recurse\n\t\t\t\t\t\tconst newPaths = this.visitPathForPopulate(\n\t\t\t\t\t\t\tproperties[key].type,\n\t\t\t\t\t\t\tentry,\n\t\t\t\t\t\t\tappendPath(populateBranch, key)\n\t\t\t\t\t\t);\n\t\t\t\t\t\tnewPaths.forEach((path) => collectedPaths.add(path));\n\t\t\t\t\t}\n\t\t\t\t} else if (typeof value === 'object') {\n\t\t\t\t\t// Recurse\n\t\t\t\t\tconst newPaths = this.visitPathForPopulate(\n\t\t\t\t\t\tproperties[key].type,\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t\tappendPath(populateBranch, key)\n\t\t\t\t\t);\n\t\t\t\t\tnewPaths.forEach((path) => collectedPaths.add(path));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn collectedPaths;\n\t};\n\n\tprivate applyWhereClause(where: any) {\n\t\tconst query = this.getRepository().createQueryBuilder();\n\t\tconst joinKeysUsed = new Map<string, number>();\n\n\t\tif (where) {\n\t\t\tconst visit = (current: any, table = 'e0') => {\n\t\t\t\tif (Array.isArray(current)) {\n\t\t\t\t\tfor (const element of current) {\n\t\t\t\t\t\tvisit(element, table);\n\t\t\t\t\t}\n\t\t\t\t} else if (typeof current === 'object') {\n\t\t\t\t\tfor (const key of Object.keys(current)) {\n\t\t\t\t\t\tconst shouldJoin =\n\t\t\t\t\t\t\tcurrent[key] !== null &&\n\t\t\t\t\t\t\ttypeof current[key] === 'object' &&\n\t\t\t\t\t\t\tObject.keys(current[key]).filter((key) => !nonJoinKeys.has(key)).length > 0;\n\n\t\t\t\t\t\t// Only join if it's not $and, $or, $not, and if it's one of those object operations\n\t\t\t\t\t\t// pass the parent and current table on down without any change.\n\t\t\t\t\t\tif (mikroObjectOperations.has(key)) {\n\t\t\t\t\t\t\tvisit(current[key], table);\n\t\t\t\t\t\t} else if (shouldJoin) {\n\t\t\t\t\t\t\t// Otherwise ensure we've actually got a full on nested object,\n\t\t\t\t\t\t\t// not just a filter property.\n\t\t\t\t\t\t\tconst keyUseCount = joinKeysUsed.has(key) ? (joinKeysUsed.get(key) ?? 0) + 1 : 1;\n\t\t\t\t\t\t\tconst joinKey = joinKeysUsed.has(key) ? `${key}${keyUseCount}` : key;\n\t\t\t\t\t\t\tquery.leftJoin(`${table}.${key}`, joinKey);\n\t\t\t\t\t\t\t// Certain filters can result in the same table being joined\n\t\t\t\t\t\t\t// on different criteria - keep track and avoid using the same alias\n\t\t\t\t\t\t\tjoinKeysUsed.set(joinKey, keyUseCount);\n\t\t\t\t\t\t\tvisit(current[key], key);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Filter out empty objects\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tcurrent[key] !== null &&\n\t\t\t\t\t\t\ttypeof current[key] === 'object' &&\n\t\t\t\t\t\t\tObject.keys(current[key]).length === 0\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tdelete current[key];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tvisit(where);\n\n\t\t\tif (Object.keys(where).length > 0) {\n\t\t\t\tquery.andWhere(where);\n\t\t\t}\n\t\t}\n\n\t\treturn query;\n\t}\n\n\tpublic async find(\n\t\tfilter: Filter<G>,\n\t\tpagination?: PaginationOptions,\n\t\tadditionalOptionsForBackend?: any // @todo: Create a type for this\n\t): Promise<D[]> {\n\t\tlogger.trace(`Running find ${this.entityType.name} with filter`, {\n\t\t\tfilter: JSON.stringify(filter),\n\t\t});\n\n\t\t// Strip custom types out of the equation.\n\t\t// This query only works if we JSON.parse(JSON.stringify(filter)):\n\t\t//\n\t\t// query {\n\t\t// drivers (filter: { region: { name: \"North Shore\" }}) {\n\t\t// id\n\t\t// }\n\t\t// }\n\t\tconst where = filter ? gqlToMikro(JSON.parse(JSON.stringify(filter))) : undefined;\n\n\t\t// Convert from: { account: {id: '6' }}\n\t\t// to { accountId: '6' }\n\t\t// This conversion only works on root level objects\n\t\tconst whereWithAppliedExternalIdFields =\n\t\t\twhere && this.applyExternalIdFields(this.entityType, where);\n\n\t\t// Regions need some fancy handling with Query Builder. Process the where further\n\t\t// and return a Query Builder instance.\n\t\tconst query = this.applyWhereClause(whereWithAppliedExternalIdFields);\n\n\t\t// If we have specified a limit, offset or order then update the query\n\t\tpagination?.limit && query.limit(pagination.limit);\n\t\tpagination?.offset && query.offset(pagination.offset);\n\t\tpagination?.orderBy && query.orderBy({ ...pagination.orderBy });\n\n\t\t// Certain query filters can result in duplicate records once all joins are resolved\n\t\t// These duplicates can be discarded as related entities are returned to the\n\t\t// API consumer via field resolvers\n\t\tquery.setFlag(QueryFlag.DISTINCT);\n\n\t\t// 1:1 relations that aren't on the owning side need to get populated so the references get set.\n\t\t// This method is protected, but we need to use it from here, hence the `as any`.\n\t\tconst driver = this.database.em.getDriver();\n\t\tconst meta = this.database.em.getMetadata().get(this.entityType.name);\n\t\tquery.populate((driver as any).autoJoinOneToOneOwner(meta, []));\n\n\t\tif (additionalOptionsForBackend?.populate) {\n\t\t\tquery.populate(additionalOptionsForBackend.populate);\n\t\t}\n\n\t\tconst result = await query.getResult();\n\t\tlogger.trace(`find ${this.entityType.name} result: ${result.length} rows`);\n\n\t\treturn result;\n\t}\n\n\tpublic async findOne(filter: Filter<G>): Promise<D | null> {\n\t\tlogger.trace(`Running findOne ${this.entityType.name} with filter ${filter}`);\n\n\t\tconst [result] = await this.find(filter, { orderBy: { id: Sort.DESC }, offset: 0, limit: 1 });\n\n\t\tlogger.trace(`findOne ${this.entityType.name} result`, { result });\n\n\t\treturn result;\n\t}\n\n\tpublic async findByRelatedId(\n\t\tentity: any,\n\t\trelatedField: string,\n\t\trelatedFieldIds: string[],\n\t\tfilter?: any\n\t): Promise<D[]> {\n\t\tconst queryFilter = {\n\t\t\t$and: [{ [relatedField]: { $in: relatedFieldIds } }, ...[filter ?? []]],\n\t\t};\n\n\t\tconst populate = [relatedField as `${string}.`];\n\t\tconst result = await this.database.em.find(entity, queryFilter, {\n\t\t\tpopulate,\n\t\t});\n\n\t\treturn result as D[];\n\t}\n\n\tpublic async updateOne(id: string, updateArgs: Partial<G & { version?: number }>): Promise<D> {\n\t\tlogger.trace(`Running update ${this.entityType.name} with args`, {\n\t\t\tid,\n\t\t\tupdateArgs: JSON.stringify(updateArgs),\n\t\t});\n\n\t\tconst entity = await this.database.em.findOne(this.entityType, id, {\n\t\t\t// This is an optimisation so that assign() doesn't have to go fetch everything one at a time.\n\t\t\tpopulate: [...this.visitPathForPopulate(this.entityType.name, updateArgs)] as `${string}.`[],\n\t\t});\n\n\t\tif (entity === null) {\n\t\t\tthrow new Error(`Unable to locate ${this.entityType.name} with ID: '${id}' for updating.`);\n\t\t}\n\n\t\t// If a version has been sent, let's check it\n\t\tif (updateArgs?.version) {\n\t\t\ttry {\n\t\t\t\tawait this.database.em.lock(entity, LockMode.OPTIMISTIC, updateArgs.version);\n\t\t\t\tdelete updateArgs.version;\n\t\t\t} catch (err) {\n\t\t\t\tthrow new OptimisticLockError((err as Error)?.message, { entity });\n\t\t\t}\n\t\t}\n\n\t\tawait this.mapAndAssignKeys(entity, this.entityType, updateArgs);\n\t\tawait this.getRepository().persistAndFlush(entity);\n\n\t\tlogger.trace(`update ${this.entityType.name} entity`, entity);\n\n\t\treturn entity;\n\t}\n\n\tpublic async updateMany(updateItems: (Partial<G> & { id: string })[]): Promise<D[]> {\n\t\tlogger.trace(`Running update many ${this.entityType.name} with args`, {\n\t\t\tupdateItems: JSON.stringify(updateItems),\n\t\t});\n\n\t\tconst entities = await this.database.transactional<D[]>(async () => {\n\t\t\treturn Promise.all<D>(\n\t\t\t\tupdateItems.map(async (item) => {\n\t\t\t\t\tif (!item?.id) throw new Error('You must pass an ID for this entity to update it.');\n\n\t\t\t\t\t// Find the entity in the database\n\t\t\t\t\tconst entity = await this.database.em.findOneOrFail(this.entityType, item.id, {\n\t\t\t\t\t\tpopulate: [...this.visitPathForPopulate(this.entityType.name, item)] as `${string}.`[],\n\t\t\t\t\t});\n\t\t\t\t\tawait this.mapAndAssignKeys(entity, this.entityType, item);\n\t\t\t\t\tthis.database.em.persist(entity);\n\t\t\t\t\treturn entity;\n\t\t\t\t})\n\t\t\t);\n\t\t});\n\n\t\tlogger.trace(`updated ${this.entityType.name} items `, entities);\n\n\t\treturn entities;\n\t}\n\n\tpublic async createOrUpdateMany(items: Partial<G>[]): Promise<D[]> {\n\t\tlogger.trace(`Running create or update many for ${this.entityType.name} with args`, {\n\t\t\titems: JSON.stringify(items),\n\t\t});\n\n\t\tconst entities = await this.database.transactional<D[]>(async () => {\n\t\t\treturn Promise.all<D>(\n\t\t\t\titems.map(async (item) => {\n\t\t\t\t\tlet entity;\n\t\t\t\t\tconst { id } = item as any;\n\t\t\t\t\tif (id) {\n\t\t\t\t\t\tentity = await this.database.em.findOneOrFail(this.entityType, id, {\n\t\t\t\t\t\t\tpopulate: [\n\t\t\t\t\t\t\t\t...this.visitPathForPopulate(this.entityType.name, item),\n\t\t\t\t\t\t\t] as `${string}.`[],\n\t\t\t\t\t\t});\n\t\t\t\t\t\tlogger.trace(`Running update on ${this.entityType.name} with item`, {\n\t\t\t\t\t\t\titem: JSON.stringify(item),\n\t\t\t\t\t\t});\n\t\t\t\t\t\tawait this.mapAndAssignKeys(entity, this.entityType, item);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tentity = new this.entityType();\n\t\t\t\t\t\tawait this.mapAndAssignKeys(entity, this.entityType, item);\n\t\t\t\t\t\tlogger.trace(`Running create on ${this.entityType.name} with item`, {\n\t\t\t\t\t\t\titem: JSON.stringify(item),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tthis.database.em.persist(entity);\n\t\t\t\t\treturn entity;\n\t\t\t\t})\n\t\t\t);\n\t\t});\n\n\t\tlogger.trace(`created or updated ${this.entityType.name} items `, entities);\n\n\t\treturn entities;\n\t}\n\n\tpublic async createOne(createArgs: Partial<G>): Promise<D> {\n\t\tlogger.trace(`Running create ${this.entityType.name} with args`, {\n\t\t\tcreateArgs: JSON.stringify(createArgs),\n\t\t});\n\n\t\tconst entity = new this.entityType();\n\t\tawait this.mapAndAssignKeys(entity, this.entityType, createArgs);\n\t\tawait this.getRepository().persistAndFlush(entity);\n\n\t\tlogger.trace(`create ${this.entityType.name} result`, entity);\n\n\t\treturn entity;\n\t}\n\n\tpublic async createMany(createItems: Partial<G>[]): Promise<D[]> {\n\t\tlogger.trace(`Running create ${this.entityType.name} with args`, {\n\t\t\tcreateArgs: JSON.stringify(createItems),\n\t\t});\n\n\t\tconst entities = await this.database.transactional<D[]>(async () => {\n\t\t\treturn Promise.all<D>(\n\t\t\t\tcreateItems.map(async (item) => {\n\t\t\t\t\tconst entity = new this.entityType();\n\t\t\t\t\tawait this.mapAndAssignKeys(entity, this.entityType, item);\n\t\t\t\t\tthis.database.em.persist(entity);\n\t\t\t\t\treturn entity;\n\t\t\t\t})\n\t\t\t);\n\t\t});\n\n\t\tlogger.trace(`created ${this.entityType.name} items `, entities);\n\n\t\treturn entities;\n\t}\n\n\tpublic async deleteOne(filter: Filter<G>): Promise<boolean> {\n\t\tlogger.trace(`Running delete ${this.entityType.name} with filter ${filter}`);\n\t\tconst where = filter ? gqlToMikro(JSON.parse(JSON.stringify(filter))) : undefined;\n\t\tconst whereWithAppliedExternalIdFields =\n\t\t\twhere && this.applyExternalIdFields(this.entityType, where);\n\n\t\tconst deletedRows = await this.getRepository().nativeDelete(whereWithAppliedExternalIdFields);\n\n\t\tif (deletedRows > 1) {\n\t\t\tthrow new Error('Multiple deleted rows');\n\t\t}\n\n\t\tlogger.trace(`delete ${this.entityType.name} result: deleted ${deletedRows} row(s)`);\n\n\t\treturn deletedRows === 1;\n\t}\n\n\tpublic async deleteMany(ids: string[]): Promise<boolean> {\n\t\tlogger.trace(`Running delete ${this.entityType.name} with ids ${ids}`);\n\n\t\tconst deletedRows = await this.database.transactional<number>(async () => {\n\t\t\tconst deletedCount = await this.getRepository().nativeDelete({\n\t\t\t\tid: { $in: ids },\n\t\t\t} as FilterQuery<any>); // We can remove this cast when Typescript knows that T has an `id` property.\n\n\t\t\tif (deletedCount !== ids.length) {\n\t\t\t\tthrow new Error('We did not delete all the rows, rolling back');\n\t\t\t}\n\n\t\t\treturn deletedCount;\n\t\t});\n\n\t\tlogger.trace(`delete ${this.entityType.name} result: deleted ${deletedRows} row(s)`);\n\n\t\treturn deletedRows === ids.length;\n\t}\n\n\tpublic getRelatedEntityId(entity: any, relatedIdField: string) {\n\t\tif (typeof entity === 'string') {\n\t\t\treturn entity;\n\t\t}\n\t\tif (entity.id) {\n\t\t\treturn entity.id;\n\t\t}\n\t\t// No need to unwrap in Mikroorm version 5\n\t\tthrow new Error(`Unknown entity without an id: ${JSON.stringify(entity)}`);\n\t}\n\n\tpublic isCollection(entity: any) {\n\t\treturn Utils.isCollection(entity);\n\t}\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import {\n\tBackendProvider,\n\tPaginationOptions,\n\tSort,\n\tFilter,\n\tGraphQLEntity,\n\tBaseDataEntity,\n} from '@exogee/graphweaver';\nimport { logger } from '@exogee/logger';\n\nimport {\n\tFilterQuery,\n\tLockMode,\n\tQueryFlag,\n\tReferenceType,\n\tUtils,\n\tConnectionManager,\n\texternalIdFieldMap,\n\tAnyEntity,\n\tIsolationLevel,\n\tConnectionOptions,\n} from '..';\nimport { OptimisticLockError } from '../utils/errors';\nimport { assign } from './assign';\n\nimport type { SqlEntityRepository } from '@mikro-orm/postgresql';\n\nconst objectOperations = new Set(['_and', '_or', '_not']);\nconst mikroObjectOperations = new Set(['$and', '$or', '$not']);\nconst nonJoinKeys = new Set([\n\t'$and',\n\t'$gt',\n\t'$gte',\n\t'$in',\n\t'$lt',\n\t'$lte',\n\t'$ne',\n\t'$nin',\n\t'$not',\n\t'$or',\n\t'$like',\n\t'$ilike',\n\t'$null',\n\t'$notnull',\n\t'id', // @todo: remove this? Why is it here?\n]);\n\nconst appendPath = (path: string, newPath: string) =>\n\tpath.length ? `${path}.${newPath}` : newPath;\n\nexport const gqlToMikro: (filter: any) => any = (filter: any) => {\n\tif (Array.isArray(filter)) {\n\t\treturn filter.map((element) => gqlToMikro(element));\n\t} else if (typeof filter === 'object') {\n\t\tfor (const key of Object.keys(filter)) {\n\t\t\t// A null here is a user-specified value and is valid to filter on\n\t\t\tif (filter[key] === null) continue;\n\n\t\t\tif (objectOperations.has(key)) {\n\t\t\t\t// { _not: '1' } => { $not: '1' }\n\t\t\t\tfilter[key.replace('_', '$')] = gqlToMikro(filter[key]);\n\t\t\t\tdelete filter[key];\n\t\t\t} else if (typeof filter[key] === 'object' && !Array.isArray(filter[key])) {\n\t\t\t\t// Recurse over nested filters only (arrays are an argument to a filter, not a nested filter)\n\t\t\t\tfilter[key] = gqlToMikro(filter[key]);\n\t\t\t} else if (key.indexOf('_') >= 0) {\n\t\t\t\t// { firstName_in: ['k', 'b'] } => { firstName: { $in: ['k', 'b'] } }\n\t\t\t\tconst [newKey, operator] = key.split('_');\n\t\t\t\tconst newValue = { [`$${operator}`]: gqlToMikro(filter[key]) };\n\n\t\t\t\t// They can construct multiple filters for the same key. In that case we need\n\t\t\t\t// to append them all into an object.\n\t\t\t\tif (typeof filter[newKey] !== 'undefined') {\n\t\t\t\t\tfilter[newKey] = { ...filter[newKey], ...newValue };\n\t\t\t\t} else {\n\t\t\t\t\tfilter[newKey] = newValue;\n\t\t\t\t}\n\n\t\t\t\tdelete filter[key];\n\t\t\t}\n\t\t}\n\t}\n\treturn filter;\n};\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport class MikroBackendProvider<D extends BaseDataEntity, G extends GraphQLEntity<D>>\n\timplements BackendProvider<D, G>\n{\n\tprivate _backendId: string;\n\n\tpublic entityType: new () => D;\n\tpublic connectionManagerId?: string;\n\tprivate transactionIsolationLevel!: IsolationLevel;\n\n\tpublic readonly supportsInFilter = true;\n\n\tget backendId() {\n\t\treturn this._backendId;\n\t}\n\n\tprivate get database() {\n\t\t// If we have a connection manager ID then use that else fallback to the Database\n\t\tif (!this.connectionManagerId) return ConnectionManager.default;\n\t\treturn ConnectionManager.database(this.connectionManagerId) || ConnectionManager.default;\n\t}\n\n\t// This is exposed for use in the RLS package\n\tpublic get transactional() {\n\t\treturn this.database.transactional;\n\t}\n\n\tpublic async withTransaction<T>(callback: () => Promise<T>) {\n\t\treturn this.database.transactional<T>(callback, this.transactionIsolationLevel);\n\t}\n\n\t// This is exposed for use in the RLS package\n\tpublic get em() {\n\t\treturn this.database.em;\n\t}\n\n\tprivate getRepository: () => SqlEntityRepository<D> = () => {\n\t\tconst repository = this.database.em.getRepository<D>(this.entityType);\n\t\tif (!repository) throw new Error('Could not find repository for ' + this.entityType.name);\n\n\t\treturn repository as SqlEntityRepository<D>;\n\t};\n\n\tpublic constructor(\n\t\tmikroType: new () => D,\n\t\tconnection: ConnectionOptions,\n\t\ttransactionIsolationLevel: IsolationLevel = IsolationLevel.REPEATABLE_READ\n\t) {\n\t\tthis.entityType = mikroType;\n\t\tthis.connectionManagerId = connection.connectionManagerId;\n\t\tthis._backendId = `mikro-orm-${connection.connectionManagerId || ''}`;\n\t\tthis.transactionIsolationLevel = transactionIsolationLevel;\n\t}\n\n\tprivate mapAndAssignKeys = (result: D, entityType: new () => D, inputArgs: Partial<G>) => {\n\t\t// Clean the input and remove any GraphQL classes from the object\n\t\t// const cleanInput = JSON.parse(JSON.stringify(inputArgs));\n\t\tconst assignmentObj = this.applyExternalIdFields(entityType, inputArgs);\n\t\treturn assign(result, assignmentObj, undefined, undefined, this.database.em);\n\t};\n\n\tprivate applyExternalIdFields = (target: AnyEntity | string, values: any) => {\n\t\tconst targetName = typeof target === 'string' ? target : target.name;\n\t\tconst map = externalIdFieldMap.get(targetName);\n\n\t\tconst mapFieldNames = (partialFilterObj: any) => {\n\t\t\tfor (const [from, to] of Object.entries(map || {})) {\n\t\t\t\tif (partialFilterObj[from] && typeof partialFilterObj[from].id !== 'undefined') {\n\t\t\t\t\tif (Object.keys(partialFilterObj[from]).length > 1) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Expected precisely 1 key called 'id' in queryObj.${from} on ${target}, got ${JSON.stringify(\n\t\t\t\t\t\t\t\tpartialFilterObj[from],\n\t\t\t\t\t\t\t\tnull,\n\t\t\t\t\t\t\t\t4\n\t\t\t\t\t\t\t)}`\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tpartialFilterObj[to] = partialFilterObj[from].id;\n\t\t\t\t\tdelete partialFilterObj[from];\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\t// Check for and/or/etc at the root level and handle correctly\n\t\tfor (const rootLevelKey of Object.keys(values)) {\n\t\t\tif (mikroObjectOperations.has(rootLevelKey)) {\n\t\t\t\tfor (const field of values[rootLevelKey]) {\n\t\t\t\t\tmapFieldNames(field);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Map the rest of the field names as well\n\t\tmapFieldNames(values);\n\n\t\t// Traverse the nested entities\n\t\tconst { properties } = this.database.em.getMetadata().get(targetName);\n\t\tObject.values(properties)\n\t\t\t.filter((property) => typeof property.entity !== 'undefined' && values[property.name])\n\t\t\t.forEach((property) => {\n\t\t\t\tif (Array.isArray(values[property.name])) {\n\t\t\t\t\tvalues[property.name].forEach((value: any) =>\n\t\t\t\t\t\tthis.applyExternalIdFields(property.type, value)\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tvalues[property.name] = this.applyExternalIdFields(property.type, values[property.name]);\n\t\t\t\t}\n\t\t\t});\n\n\t\treturn values;\n\t};\n\n\t// Check if we have any keys that are a collection of entities\n\tpublic visitPathForPopulate = (entityName: string, updateArgBranch: any, populateBranch = '') => {\n\t\tconst { properties } = this.database.em.getMetadata().get(entityName);\n\t\tconst collectedPaths = populateBranch ? new Set<string>([populateBranch]) : new Set<string>([]);\n\n\t\tfor (const [key, value] of Object.entries(updateArgBranch ?? {})) {\n\t\t\tif (\n\t\t\t\t// If it's a relationship, go ahead and and '.' it in, recurse.\n\t\t\t\tproperties[key]?.reference === ReferenceType.ONE_TO_ONE ||\n\t\t\t\tproperties[key]?.reference === ReferenceType.ONE_TO_MANY ||\n\t\t\t\tproperties[key]?.reference === ReferenceType.MANY_TO_ONE ||\n\t\t\t\tproperties[key]?.reference === ReferenceType.MANY_TO_MANY\n\t\t\t) {\n\t\t\t\tif (Array.isArray(value)) {\n\t\t\t\t\t// In the case where the array is empty we also need to make sure we load the collection.\n\t\t\t\t\tcollectedPaths.add(appendPath(populateBranch, key));\n\n\t\t\t\t\tfor (const entry of value) {\n\t\t\t\t\t\t// Recurse\n\t\t\t\t\t\tconst newPaths = this.visitPathForPopulate(\n\t\t\t\t\t\t\tproperties[key].type,\n\t\t\t\t\t\t\tentry,\n\t\t\t\t\t\t\tappendPath(populateBranch, key)\n\t\t\t\t\t\t);\n\t\t\t\t\t\tnewPaths.forEach((path) => collectedPaths.add(path));\n\t\t\t\t\t}\n\t\t\t\t} else if (typeof value === 'object') {\n\t\t\t\t\t// Recurse\n\t\t\t\t\tconst newPaths = this.visitPathForPopulate(\n\t\t\t\t\t\tproperties[key].type,\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t\tappendPath(populateBranch, key)\n\t\t\t\t\t);\n\t\t\t\t\tnewPaths.forEach((path) => collectedPaths.add(path));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn collectedPaths;\n\t};\n\n\tprivate applyWhereClause(where: any) {\n\t\tconst query = this.getRepository().createQueryBuilder();\n\t\tconst joinKeysUsed = new Map<string, number>();\n\n\t\tif (where) {\n\t\t\tconst visit = (current: any, table = 'e0') => {\n\t\t\t\tif (Array.isArray(current)) {\n\t\t\t\t\tfor (const element of current) {\n\t\t\t\t\t\tvisit(element, table);\n\t\t\t\t\t}\n\t\t\t\t} else if (typeof current === 'object') {\n\t\t\t\t\tfor (const key of Object.keys(current)) {\n\t\t\t\t\t\tconst shouldJoin =\n\t\t\t\t\t\t\tcurrent[key] !== null &&\n\t\t\t\t\t\t\ttypeof current[key] === 'object' &&\n\t\t\t\t\t\t\tObject.keys(current[key]).filter((key) => !nonJoinKeys.has(key)).length > 0;\n\n\t\t\t\t\t\t// Only join if it's not $and, $or, $not, and if it's one of those object operations\n\t\t\t\t\t\t// pass the parent and current table on down without any change.\n\t\t\t\t\t\tif (mikroObjectOperations.has(key)) {\n\t\t\t\t\t\t\tvisit(current[key], table);\n\t\t\t\t\t\t} else if (shouldJoin) {\n\t\t\t\t\t\t\t// Otherwise ensure we've actually got a full on nested object,\n\t\t\t\t\t\t\t// not just a filter property.\n\t\t\t\t\t\t\tconst keyUseCount = joinKeysUsed.has(key) ? (joinKeysUsed.get(key) ?? 0) + 1 : 1;\n\t\t\t\t\t\t\tconst joinKey = joinKeysUsed.has(key) ? `${key}${keyUseCount}` : key;\n\t\t\t\t\t\t\tquery.leftJoin(`${table}.${key}`, joinKey);\n\t\t\t\t\t\t\t// Certain filters can result in the same table being joined\n\t\t\t\t\t\t\t// on different criteria - keep track and avoid using the same alias\n\t\t\t\t\t\t\tjoinKeysUsed.set(joinKey, keyUseCount);\n\t\t\t\t\t\t\tvisit(current[key], key);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Filter out empty objects\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tcurrent[key] !== null &&\n\t\t\t\t\t\t\ttypeof current[key] === 'object' &&\n\t\t\t\t\t\t\tObject.keys(current[key]).length === 0\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tdelete current[key];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tvisit(where);\n\n\t\t\tif (Object.keys(where).length > 0) {\n\t\t\t\tquery.andWhere(where);\n\t\t\t}\n\t\t}\n\n\t\treturn query;\n\t}\n\n\tpublic async find(\n\t\tfilter: Filter<G>,\n\t\tpagination?: PaginationOptions,\n\t\tadditionalOptionsForBackend?: any // @todo: Create a type for this\n\t): Promise<D[]> {\n\t\tlogger.trace(`Running find ${this.entityType.name} with filter`, {\n\t\t\tfilter: JSON.stringify(filter),\n\t\t});\n\n\t\t// Strip custom types out of the equation.\n\t\t// This query only works if we JSON.parse(JSON.stringify(filter)):\n\t\t//\n\t\t// query {\n\t\t// drivers (filter: { region: { name: \"North Shore\" }}) {\n\t\t// id\n\t\t// }\n\t\t// }\n\t\tconst where = filter ? gqlToMikro(JSON.parse(JSON.stringify(filter))) : undefined;\n\n\t\t// Convert from: { account: {id: '6' }}\n\t\t// to { accountId: '6' }\n\t\t// This conversion only works on root level objects\n\t\tconst whereWithAppliedExternalIdFields =\n\t\t\twhere && this.applyExternalIdFields(this.entityType, where);\n\n\t\t// Regions need some fancy handling with Query Builder. Process the where further\n\t\t// and return a Query Builder instance.\n\t\tconst query = this.applyWhereClause(whereWithAppliedExternalIdFields);\n\n\t\t// If we have specified a limit, offset or order then update the query\n\t\tpagination?.limit && query.limit(pagination.limit);\n\t\tpagination?.offset && query.offset(pagination.offset);\n\t\tpagination?.orderBy && query.orderBy({ ...pagination.orderBy });\n\n\t\t// Certain query filters can result in duplicate records once all joins are resolved\n\t\t// These duplicates can be discarded as related entities are returned to the\n\t\t// API consumer via field resolvers\n\t\tquery.setFlag(QueryFlag.DISTINCT);\n\n\t\t// 1:1 relations that aren't on the owning side need to get populated so the references get set.\n\t\t// This method is protected, but we need to use it from here, hence the `as any`.\n\t\tconst driver = this.database.em.getDriver();\n\t\tconst meta = this.database.em.getMetadata().get(this.entityType.name);\n\t\tquery.populate((driver as any).autoJoinOneToOneOwner(meta, []));\n\n\t\tif (additionalOptionsForBackend?.populate) {\n\t\t\tquery.populate(additionalOptionsForBackend.populate);\n\t\t}\n\n\t\tconst result = await query.getResult();\n\t\tlogger.trace(`find ${this.entityType.name} result: ${result.length} rows`);\n\n\t\treturn result;\n\t}\n\n\tpublic async findOne(filter: Filter<G>): Promise<D | null> {\n\t\tlogger.trace(`Running findOne ${this.entityType.name} with filter ${filter}`);\n\n\t\tconst [result] = await this.find(filter, { orderBy: { id: Sort.DESC }, offset: 0, limit: 1 });\n\n\t\tlogger.trace(`findOne ${this.entityType.name} result`, { result });\n\n\t\treturn result;\n\t}\n\n\tpublic async findByRelatedId(\n\t\tentity: any,\n\t\trelatedField: string,\n\t\trelatedFieldIds: string[],\n\t\tfilter?: any\n\t): Promise<D[]> {\n\t\tconst queryFilter = {\n\t\t\t$and: [{ [relatedField]: { $in: relatedFieldIds } }, ...[filter ?? []]],\n\t\t};\n\n\t\tconst populate = [relatedField as `${string}.`];\n\t\tconst result = await this.database.em.find(entity, queryFilter, {\n\t\t\tpopulate,\n\t\t});\n\n\t\treturn result as D[];\n\t}\n\n\tpublic async updateOne(id: string, updateArgs: Partial<G & { version?: number }>): Promise<D> {\n\t\tlogger.trace(`Running update ${this.entityType.name} with args`, {\n\t\t\tid,\n\t\t\tupdateArgs: JSON.stringify(updateArgs),\n\t\t});\n\n\t\tconst entity = await this.database.em.findOne(this.entityType, id, {\n\t\t\t// This is an optimisation so that assign() doesn't have to go fetch everything one at a time.\n\t\t\tpopulate: [...this.visitPathForPopulate(this.entityType.name, updateArgs)] as `${string}.`[],\n\t\t});\n\n\t\tif (entity === null) {\n\t\t\tthrow new Error(`Unable to locate ${this.entityType.name} with ID: '${id}' for updating.`);\n\t\t}\n\n\t\t// If a version has been sent, let's check it\n\t\tif (updateArgs?.version) {\n\t\t\ttry {\n\t\t\t\tawait this.database.em.lock(entity, LockMode.OPTIMISTIC, updateArgs.version);\n\t\t\t\tdelete updateArgs.version;\n\t\t\t} catch (err) {\n\t\t\t\tthrow new OptimisticLockError((err as Error)?.message, { entity });\n\t\t\t}\n\t\t}\n\n\t\tawait this.mapAndAssignKeys(entity, this.entityType, updateArgs);\n\t\tawait this.getRepository().persistAndFlush(entity);\n\n\t\tlogger.trace(`update ${this.entityType.name} entity`, entity);\n\n\t\treturn entity;\n\t}\n\n\tpublic async updateMany(updateItems: (Partial<G> & { id: string })[]): Promise<D[]> {\n\t\tlogger.trace(`Running update many ${this.entityType.name} with args`, {\n\t\t\tupdateItems: JSON.stringify(updateItems),\n\t\t});\n\n\t\tconst entities = await this.database.transactional<D[]>(async () => {\n\t\t\treturn Promise.all<D>(\n\t\t\t\tupdateItems.map(async (item) => {\n\t\t\t\t\tif (!item?.id) throw new Error('You must pass an ID for this entity to update it.');\n\n\t\t\t\t\t// Find the entity in the database\n\t\t\t\t\tconst entity = await this.database.em.findOneOrFail(this.entityType, item.id, {\n\t\t\t\t\t\tpopulate: [...this.visitPathForPopulate(this.entityType.name, item)] as `${string}.`[],\n\t\t\t\t\t});\n\t\t\t\t\tawait this.mapAndAssignKeys(entity, this.entityType, item);\n\t\t\t\t\tthis.database.em.persist(entity);\n\t\t\t\t\treturn entity;\n\t\t\t\t})\n\t\t\t);\n\t\t});\n\n\t\tlogger.trace(`updated ${this.entityType.name} items `, entities);\n\n\t\treturn entities;\n\t}\n\n\tpublic async createOrUpdateMany(items: Partial<G>[]): Promise<D[]> {\n\t\tlogger.trace(`Running create or update many for ${this.entityType.name} with args`, {\n\t\t\titems: JSON.stringify(items),\n\t\t});\n\n\t\tconst entities = await this.database.transactional<D[]>(async () => {\n\t\t\treturn Promise.all<D>(\n\t\t\t\titems.map(async (item) => {\n\t\t\t\t\tlet entity;\n\t\t\t\t\tconst { id } = item as any;\n\t\t\t\t\tif (id) {\n\t\t\t\t\t\tentity = await this.database.em.findOneOrFail(this.entityType, id, {\n\t\t\t\t\t\t\tpopulate: [\n\t\t\t\t\t\t\t\t...this.visitPathForPopulate(this.entityType.name, item),\n\t\t\t\t\t\t\t] as `${string}.`[],\n\t\t\t\t\t\t});\n\t\t\t\t\t\tlogger.trace(`Running update on ${this.entityType.name} with item`, {\n\t\t\t\t\t\t\titem: JSON.stringify(item),\n\t\t\t\t\t\t});\n\t\t\t\t\t\tawait this.mapAndAssignKeys(entity, this.entityType, item);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tentity = new this.entityType();\n\t\t\t\t\t\tawait this.mapAndAssignKeys(entity, this.entityType, item);\n\t\t\t\t\t\tlogger.trace(`Running create on ${this.entityType.name} with item`, {\n\t\t\t\t\t\t\titem: JSON.stringify(item),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tthis.database.em.persist(entity);\n\t\t\t\t\treturn entity;\n\t\t\t\t})\n\t\t\t);\n\t\t});\n\n\t\tlogger.trace(`created or updated ${this.entityType.name} items `, entities);\n\n\t\treturn entities;\n\t}\n\n\tpublic async createOne(createArgs: Partial<G>): Promise<D> {\n\t\tlogger.trace(`Running create ${this.entityType.name} with args`, {\n\t\t\tcreateArgs: JSON.stringify(createArgs),\n\t\t});\n\n\t\tconst entity = new this.entityType();\n\t\tawait this.mapAndAssignKeys(entity, this.entityType, createArgs);\n\t\tawait this.getRepository().persistAndFlush(entity);\n\n\t\tlogger.trace(`create ${this.entityType.name} result`, entity);\n\n\t\treturn entity;\n\t}\n\n\tpublic async createMany(createItems: Partial<G>[]): Promise<D[]> {\n\t\tlogger.trace(`Running create ${this.entityType.name} with args`, {\n\t\t\tcreateArgs: JSON.stringify(createItems),\n\t\t});\n\n\t\tconst entities = await this.database.transactional<D[]>(async () => {\n\t\t\treturn Promise.all<D>(\n\t\t\t\tcreateItems.map(async (item) => {\n\t\t\t\t\tconst entity = new this.entityType();\n\t\t\t\t\tawait this.mapAndAssignKeys(entity, this.entityType, item);\n\t\t\t\t\tthis.database.em.persist(entity);\n\t\t\t\t\treturn entity;\n\t\t\t\t})\n\t\t\t);\n\t\t});\n\n\t\tlogger.trace(`created ${this.entityType.name} items `, entities);\n\n\t\treturn entities;\n\t}\n\n\tpublic async deleteOne(filter: Filter<G>): Promise<boolean> {\n\t\tlogger.trace(`Running delete ${this.entityType.name} with filter ${filter}`);\n\t\tconst where = filter ? gqlToMikro(JSON.parse(JSON.stringify(filter))) : undefined;\n\t\tconst whereWithAppliedExternalIdFields =\n\t\t\twhere && this.applyExternalIdFields(this.entityType, where);\n\n\t\tconst deletedRows = await this.getRepository().nativeDelete(whereWithAppliedExternalIdFields);\n\n\t\tif (deletedRows > 1) {\n\t\t\tthrow new Error('Multiple deleted rows');\n\t\t}\n\n\t\tlogger.trace(`delete ${this.entityType.name} result: deleted ${deletedRows} row(s)`);\n\n\t\treturn deletedRows === 1;\n\t}\n\n\tpublic async deleteMany(ids: string[]): Promise<boolean> {\n\t\tlogger.trace(`Running delete ${this.entityType.name} with ids ${ids}`);\n\n\t\tconst deletedRows = await this.database.transactional<number>(async () => {\n\t\t\tconst deletedCount = await this.getRepository().nativeDelete({\n\t\t\t\tid: { $in: ids },\n\t\t\t} as FilterQuery<any>); // We can remove this cast when Typescript knows that T has an `id` property.\n\n\t\t\tif (deletedCount !== ids.length) {\n\t\t\t\tthrow new Error('We did not delete all the rows, rolling back');\n\t\t\t}\n\n\t\t\treturn deletedCount;\n\t\t});\n\n\t\tlogger.trace(`delete ${this.entityType.name} result: deleted ${deletedRows} row(s)`);\n\n\t\treturn deletedRows === ids.length;\n\t}\n\n\tpublic getRelatedEntityId(entity: any, relatedIdField: string) {\n\t\tif (typeof entity === 'string') {\n\t\t\treturn entity;\n\t\t}\n\t\tif (entity.id) {\n\t\t\treturn entity.id;\n\t\t}\n\t\t// No need to unwrap in Mikroorm version 5\n\t\tthrow new Error(`Unknown entity without an id: ${JSON.stringify(entity)}`);\n\t}\n\n\tpublic isCollection(entity: any) {\n\t\treturn Utils.isCollection(entity);\n\t}\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yBAOO;AACP,oBAAuB;AAEvB,eAWO;AACP,oBAAoC;AACpC,oBAAuB;AAIvB,MAAM,mBAAmB,oBAAI,IAAI,CAAC,QAAQ,OAAO,MAAM,CAAC;AACxD,MAAM,wBAAwB,oBAAI,IAAI,CAAC,QAAQ,OAAO,MAAM,CAAC;AAC7D,MAAM,cAAc,oBAAI,IAAI;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,CAAC;AAED,MAAM,aAAa,CAAC,MAAc,YACjC,KAAK,SAAS,GAAG,QAAQ,YAAY;AAE/B,MAAM,aAAmC,CAAC,WAAgB;AAChE,MAAI,MAAM,QAAQ,MAAM,GAAG;AAC1B,WAAO,OAAO,IAAI,CAAC,YAAY,WAAW,OAAO,CAAC;AAAA,EACnD,WAAW,OAAO,WAAW,UAAU;AACtC,eAAW,OAAO,OAAO,KAAK,MAAM,GAAG;AAEtC,UAAI,OAAO,SAAS;AAAM;AAE1B,UAAI,iBAAiB,IAAI,GAAG,GAAG;AAE9B,eAAO,IAAI,QAAQ,KAAK,GAAG,KAAK,WAAW,OAAO,IAAI;AACtD,eAAO,OAAO;AAAA,MACf,WAAW,OAAO,OAAO,SAAS,YAAY,CAAC,MAAM,QAAQ,OAAO,IAAI,GAAG;AAE1E,eAAO,OAAO,WAAW,OAAO,IAAI;AAAA,MACrC,WAAW,IAAI,QAAQ,GAAG,KAAK,GAAG;AAEjC,cAAM,CAAC,QAAQ,QAAQ,IAAI,IAAI,MAAM,GAAG;AACxC,cAAM,WAAW,EAAE,CAAC,IAAI,aAAa,WAAW,OAAO,IAAI,EAAE;AAI7D,YAAI,OAAO,OAAO,YAAY,aAAa;AAC1C,iBAAO,UAAU,EAAE,GAAG,OAAO,SAAS,GAAG,SAAS;AAAA,QACnD,OAAO;AACN,iBAAO,UAAU;AAAA,QAClB;AAEA,eAAO,OAAO;AAAA,MACf;AAAA,IACD;AAAA,EACD;AACA,SAAO;AACR;AAGO,MAAM,qBAEb;AAAA,EAwCQ,YACN,WACA,YACA,4BAA4C,wBAAe,iBAC1D;AArCF,SAAgB,mBAAmB;AA0BnC,SAAQ,gBAA8C,MAAM;AAC3D,YAAM,aAAa,KAAK,SAAS,GAAG,cAAiB,KAAK,UAAU;AACpE,UAAI,CAAC;AAAY,cAAM,IAAI,MAAM,mCAAmC,KAAK,WAAW,IAAI;AAExF,aAAO;AAAA,IACR;AAaA,SAAQ,mBAAmB,CAAC,QAAW,YAAyB,cAA0B;AAGzF,YAAM,gBAAgB,KAAK,sBAAsB,YAAY,SAAS;AACtE,iBAAO,sBAAO,QAAQ,eAAe,QAAW,QAAW,KAAK,SAAS,EAAE;AAAA,IAC5E;AAEA,SAAQ,wBAAwB,CAAC,QAA4B,WAAgB;AAC5E,YAAM,aAAa,OAAO,WAAW,WAAW,SAAS,OAAO;AAChE,YAAM,MAAM,4BAAmB,IAAI,UAAU;AAE7C,YAAM,gBAAgB,CAAC,qBAA0B;AAChD,mBAAW,CAAC,MAAM,EAAE,KAAK,OAAO,QAAQ,OAAO,CAAC,CAAC,GAAG;AACnD,cAAI,iBAAiB,SAAS,OAAO,iBAAiB,MAAM,OAAO,aAAa;AAC/E,gBAAI,OAAO,KAAK,iBAAiB,KAAK,EAAE,SAAS,GAAG;AACnD,oBAAM,IAAI;AAAA,gBACT,oDAAoD,WAAW,eAAe,KAAK;AAAA,kBAClF,iBAAiB;AAAA,kBACjB;AAAA,kBACA;AAAA,gBACD;AAAA,cACD;AAAA,YACD;AAEA,6BAAiB,MAAM,iBAAiB,MAAM;AAC9C,mBAAO,iBAAiB;AAAA,UACzB;AAAA,QACD;AAAA,MACD;AAGA,iBAAW,gBAAgB,OAAO,KAAK,MAAM,GAAG;AAC/C,YAAI,sBAAsB,IAAI,YAAY,GAAG;AAC5C,qBAAW,SAAS,OAAO,eAAe;AACzC,0BAAc,KAAK;AAAA,UACpB;AAAA,QACD;AAAA,MACD;AAEA,oBAAc,MAAM;AAGpB,YAAM,EAAE,WAAW,IAAI,KAAK,SAAS,GAAG,YAAY,EAAE,IAAI,UAAU;AACpE,aAAO,OAAO,UAAU,EACtB,OAAO,CAAC,aAAa,OAAO,SAAS,WAAW,eAAe,OAAO,SAAS,KAAK,EACpF,QAAQ,CAAC,aAAa;AACtB,YAAI,MAAM,QAAQ,OAAO,SAAS,KAAK,GAAG;AACzC,iBAAO,SAAS,MAAM;AAAA,YAAQ,CAAC,UAC9B,KAAK,sBAAsB,SAAS,MAAM,KAAK;AAAA,UAChD;AAAA,QACD,OAAO;AACN,iBAAO,SAAS,QAAQ,KAAK,sBAAsB,SAAS,MAAM,OAAO,SAAS,KAAK;AAAA,QACxF;AAAA,MACD,CAAC;AAEF,aAAO;AAAA,IACR;AAGA,SAAO,uBAAuB,CAAC,YAAoB,iBAAsB,iBAAiB,OAAO;AAtMlG;AAuME,YAAM,EAAE,WAAW,IAAI,KAAK,SAAS,GAAG,YAAY,EAAE,IAAI,UAAU;AACpE,YAAM,iBAAiB,iBAAiB,oBAAI,IAAY,CAAC,cAAc,CAAC,IAAI,oBAAI,IAAY,CAAC,CAAC;AAE9F,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,4CAAmB,CAAC,CAAC,GAAG;AACjE,cAEC,gBAAW,SAAX,mBAAiB,eAAc,uBAAc,gBAC7C,gBAAW,SAAX,mBAAiB,eAAc,uBAAc,iBAC7C,gBAAW,SAAX,mBAAiB,eAAc,uBAAc,iBAC7C,gBAAW,SAAX,mBAAiB,eAAc,uBAAc,cAC5C;AACD,cAAI,MAAM,QAAQ,KAAK,GAAG;AAEzB,2BAAe,IAAI,WAAW,gBAAgB,GAAG,CAAC;AAElD,uBAAW,SAAS,OAAO;AAE1B,oBAAM,WAAW,KAAK;AAAA,gBACrB,WAAW,KAAK;AAAA,gBAChB;AAAA,gBACA,WAAW,gBAAgB,GAAG;AAAA,cAC/B;AACA,uBAAS,QAAQ,CAAC,SAAS,eAAe,IAAI,IAAI,CAAC;AAAA,YACpD;AAAA,UACD,WAAW,OAAO,UAAU,UAAU;AAErC,kBAAM,WAAW,KAAK;AAAA,cACrB,WAAW,KAAK;AAAA,cAChB;AAAA,cACA,WAAW,gBAAgB,GAAG;AAAA,YAC/B;AACA,qBAAS,QAAQ,CAAC,SAAS,eAAe,IAAI,IAAI,CAAC;AAAA,UACpD;AAAA,QACD;AAAA,MACD;AAEA,aAAO;AAAA,IACR;AAvGC,SAAK,aAAa;AAClB,SAAK,sBAAsB,WAAW;AACtC,SAAK,aAAa,aAAa,WAAW,uBAAuB;AACjE,SAAK,4BAA4B;AAAA,EAClC;AAAA,EAxCA,IAAI,YAAY;AACf,WAAO,KAAK;AAAA,EACb;AAAA,EAEA,IAAY,WAAW;AAEtB,QAAI,CAAC,KAAK;AAAqB,aAAO,2BAAkB;AACxD,WAAO,2BAAkB,SAAS,KAAK,mBAAmB,KAAK,2BAAkB;AAAA,EAClF;AAAA,EAGA,IAAW,gBAAgB;AAC1B,WAAO,KAAK,SAAS;AAAA,EACtB;AAAA,EAEA,MAAa,gBAAmB,UAA4B;AAC3D,WAAO,KAAK,SAAS,cAAiB,UAAU,KAAK,yBAAyB;AAAA,EAC/E;AAAA,EAGA,IAAW,KAAK;AACf,WAAO,KAAK,SAAS;AAAA,EACtB;AAAA,EAuHQ,iBAAiB,OAAY;AACpC,UAAM,QAAQ,KAAK,cAAc,EAAE,mBAAmB;AACtD,UAAM,eAAe,oBAAI,IAAoB;AAE7C,QAAI,OAAO;AACV,YAAM,QAAQ,CAAC,SAAc,QAAQ,SAAS;AAnPjD;AAoPI,YAAI,MAAM,QAAQ,OAAO,GAAG;AAC3B,qBAAW,WAAW,SAAS;AAC9B,kBAAM,SAAS,KAAK;AAAA,UACrB;AAAA,QACD,WAAW,OAAO,YAAY,UAAU;AACvC,qBAAW,OAAO,OAAO,KAAK,OAAO,GAAG;AACvC,kBAAM,aACL,QAAQ,SAAS,QACjB,OAAO,QAAQ,SAAS,YACxB,OAAO,KAAK,QAAQ,IAAI,EAAE,OAAO,CAACA,SAAQ,CAAC,YAAY,IAAIA,IAAG,CAAC,EAAE,SAAS;AAI3E,gBAAI,sBAAsB,IAAI,GAAG,GAAG;AACnC,oBAAM,QAAQ,MAAM,KAAK;AAAA,YAC1B,WAAW,YAAY;AAGtB,oBAAM,cAAc,aAAa,IAAI,GAAG,MAAK,kBAAa,IAAI,GAAG,MAApB,YAAyB,KAAK,IAAI;AAC/E,oBAAM,UAAU,aAAa,IAAI,GAAG,IAAI,GAAG,MAAM,gBAAgB;AACjE,oBAAM,SAAS,GAAG,SAAS,OAAO,OAAO;AAGzC,2BAAa,IAAI,SAAS,WAAW;AACrC,oBAAM,QAAQ,MAAM,GAAG;AAAA,YACxB;AAGA,gBACC,QAAQ,SAAS,QACjB,OAAO,QAAQ,SAAS,YACxB,OAAO,KAAK,QAAQ,IAAI,EAAE,WAAW,GACpC;AACD,qBAAO,QAAQ;AAAA,YAChB;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAEA,YAAM,KAAK;AAEX,UAAI,OAAO,KAAK,KAAK,EAAE,SAAS,GAAG;AAClC,cAAM,SAAS,KAAK;AAAA,MACrB;AAAA,IACD;AAEA,WAAO;AAAA,EACR;AAAA,EAEA,MAAa,KACZ,QACA,YACA,6BACe;AACf,yBAAO,MAAM,gBAAgB,KAAK,WAAW,oBAAoB;AAAA,MAChE,QAAQ,KAAK,UAAU,MAAM;AAAA,IAC9B,CAAC;AAUD,UAAM,QAAQ,SAAS,WAAW,KAAK,MAAM,KAAK,UAAU,MAAM,CAAC,CAAC,IAAI;AAKxE,UAAM,mCACL,SAAS,KAAK,sBAAsB,KAAK,YAAY,KAAK;AAI3D,UAAM,QAAQ,KAAK,iBAAiB,gCAAgC;AAGpE,8CAAY,UAAS,MAAM,MAAM,WAAW,KAAK;AACjD,8CAAY,WAAU,MAAM,OAAO,WAAW,MAAM;AACpD,8CAAY,YAAW,MAAM,QAAQ,EAAE,GAAG,WAAW,QAAQ,CAAC;AAK9D,UAAM,QAAQ,mBAAU,QAAQ;AAIhC,UAAM,SAAS,KAAK,SAAS,GAAG,UAAU;AAC1C,UAAM,OAAO,KAAK,SAAS,GAAG,YAAY,EAAE,IAAI,KAAK,WAAW,IAAI;AACpE,UAAM,SAAU,OAAe,sBAAsB,MAAM,CAAC,CAAC,CAAC;AAE9D,QAAI,2EAA6B,UAAU;AAC1C,YAAM,SAAS,4BAA4B,QAAQ;AAAA,IACpD;AAEA,UAAM,SAAS,MAAM,MAAM,UAAU;AACrC,yBAAO,MAAM,QAAQ,KAAK,WAAW,gBAAgB,OAAO,aAAa;AAEzE,WAAO;AAAA,EACR;AAAA,EAEA,MAAa,QAAQ,QAAsC;AAC1D,yBAAO,MAAM,mBAAmB,KAAK,WAAW,oBAAoB,QAAQ;AAE5E,UAAM,CAAC,MAAM,IAAI,MAAM,KAAK,KAAK,QAAQ,EAAE,SAAS,EAAE,IAAI,wBAAK,KAAK,GAAG,QAAQ,GAAG,OAAO,EAAE,CAAC;AAE5F,yBAAO,MAAM,WAAW,KAAK,WAAW,eAAe,EAAE,OAAO,CAAC;AAEjE,WAAO;AAAA,EACR;AAAA,EAEA,MAAa,gBACZ,QACA,cACA,iBACA,QACe;AACf,UAAM,cAAc;AAAA,MACnB,MAAM,CAAC,EAAE,CAAC,eAAe,EAAE,KAAK,gBAAgB,EAAE,GAAG,GAAG,CAAC,0BAAU,CAAC,CAAC,CAAC;AAAA,IACvE;AAEA,UAAM,WAAW,CAAC,YAA4B;AAC9C,UAAM,SAAS,MAAM,KAAK,SAAS,GAAG,KAAK,QAAQ,aAAa;AAAA,MAC/D;AAAA,IACD,CAAC;AAED,WAAO;AAAA,EACR;AAAA,EAEA,MAAa,UAAU,IAAY,YAA2D;AAC7F,yBAAO,MAAM,kBAAkB,KAAK,WAAW,kBAAkB;AAAA,MAChE;AAAA,MACA,YAAY,KAAK,UAAU,UAAU;AAAA,IACtC,CAAC;AAED,UAAM,SAAS,MAAM,KAAK,SAAS,GAAG,QAAQ,KAAK,YAAY,IAAI;AAAA,MAElE,UAAU,CAAC,GAAG,KAAK,qBAAqB,KAAK,WAAW,MAAM,UAAU,CAAC;AAAA,IAC1E,CAAC;AAED,QAAI,WAAW,MAAM;AACpB,YAAM,IAAI,MAAM,oBAAoB,KAAK,WAAW,kBAAkB,mBAAmB;AAAA,IAC1F;AAGA,QAAI,yCAAY,SAAS;AACxB,UAAI;AACH,cAAM,KAAK,SAAS,GAAG,KAAK,QAAQ,kBAAS,YAAY,WAAW,OAAO;AAC3E,eAAO,WAAW;AAAA,MACnB,SAAS,KAAP;AACD,cAAM,IAAI,kCAAqB,2BAAe,SAAS,EAAE,OAAO,CAAC;AAAA,MAClE;AAAA,IACD;AAEA,UAAM,KAAK,iBAAiB,QAAQ,KAAK,YAAY,UAAU;AAC/D,UAAM,KAAK,cAAc,EAAE,gBAAgB,MAAM;AAEjD,yBAAO,MAAM,UAAU,KAAK,WAAW,eAAe,MAAM;AAE5D,WAAO;AAAA,EACR;AAAA,EAEA,MAAa,WAAW,aAA4D;AACnF,yBAAO,MAAM,uBAAuB,KAAK,WAAW,kBAAkB;AAAA,MACrE,aAAa,KAAK,UAAU,WAAW;AAAA,IACxC,CAAC;AAED,UAAM,WAAW,MAAM,KAAK,SAAS,cAAmB,YAAY;AACnE,aAAO,QAAQ;AAAA,QACd,YAAY,IAAI,OAAO,SAAS;AAC/B,cAAI,EAAC,6BAAM;AAAI,kBAAM,IAAI,MAAM,mDAAmD;AAGlF,gBAAM,SAAS,MAAM,KAAK,SAAS,GAAG,cAAc,KAAK,YAAY,KAAK,IAAI;AAAA,YAC7E,UAAU,CAAC,GAAG,KAAK,qBAAqB,KAAK,WAAW,MAAM,IAAI,CAAC;AAAA,UACpE,CAAC;AACD,gBAAM,KAAK,iBAAiB,QAAQ,KAAK,YAAY,IAAI;AACzD,eAAK,SAAS,GAAG,QAAQ,MAAM;AAC/B,iBAAO;AAAA,QACR,CAAC;AAAA,MACF;AAAA,IACD,CAAC;AAED,yBAAO,MAAM,WAAW,KAAK,WAAW,eAAe,QAAQ;AAE/D,WAAO;AAAA,EACR;AAAA,EAEA,MAAa,mBAAmB,OAAmC;AAClE,yBAAO,MAAM,qCAAqC,KAAK,WAAW,kBAAkB;AAAA,MACnF,OAAO,KAAK,UAAU,KAAK;AAAA,IAC5B,CAAC;AAED,UAAM,WAAW,MAAM,KAAK,SAAS,cAAmB,YAAY;AACnE,aAAO,QAAQ;AAAA,QACd,MAAM,IAAI,OAAO,SAAS;AACzB,cAAI;AACJ,gBAAM,EAAE,GAAG,IAAI;AACf,cAAI,IAAI;AACP,qBAAS,MAAM,KAAK,SAAS,GAAG,cAAc,KAAK,YAAY,IAAI;AAAA,cAClE,UAAU;AAAA,gBACT,GAAG,KAAK,qBAAqB,KAAK,WAAW,MAAM,IAAI;AAAA,cACxD;AAAA,YACD,CAAC;AACD,iCAAO,MAAM,qBAAqB,KAAK,WAAW,kBAAkB;AAAA,cACnE,MAAM,KAAK,UAAU,IAAI;AAAA,YAC1B,CAAC;AACD,kBAAM,KAAK,iBAAiB,QAAQ,KAAK,YAAY,IAAI;AAAA,UAC1D,OAAO;AACN,qBAAS,IAAI,KAAK,WAAW;AAC7B,kBAAM,KAAK,iBAAiB,QAAQ,KAAK,YAAY,IAAI;AACzD,iCAAO,MAAM,qBAAqB,KAAK,WAAW,kBAAkB;AAAA,cACnE,MAAM,KAAK,UAAU,IAAI;AAAA,YAC1B,CAAC;AAAA,UACF;AACA,eAAK,SAAS,GAAG,QAAQ,MAAM;AAC/B,iBAAO;AAAA,QACR,CAAC;AAAA,MACF;AAAA,IACD,CAAC;AAED,yBAAO,MAAM,sBAAsB,KAAK,WAAW,eAAe,QAAQ;AAE1E,WAAO;AAAA,EACR;AAAA,EAEA,MAAa,UAAU,YAAoC;AAC1D,yBAAO,MAAM,kBAAkB,KAAK,WAAW,kBAAkB;AAAA,MAChE,YAAY,KAAK,UAAU,UAAU;AAAA,IACtC,CAAC;AAED,UAAM,SAAS,IAAI,KAAK,WAAW;AACnC,UAAM,KAAK,iBAAiB,QAAQ,KAAK,YAAY,UAAU;AAC/D,UAAM,KAAK,cAAc,EAAE,gBAAgB,MAAM;AAEjD,yBAAO,MAAM,UAAU,KAAK,WAAW,eAAe,MAAM;AAE5D,WAAO;AAAA,EACR;AAAA,EAEA,MAAa,WAAW,aAAyC;AAChE,yBAAO,MAAM,kBAAkB,KAAK,WAAW,kBAAkB;AAAA,MAChE,YAAY,KAAK,UAAU,WAAW;AAAA,IACvC,CAAC;AAED,UAAM,WAAW,MAAM,KAAK,SAAS,cAAmB,YAAY;AACnE,aAAO,QAAQ;AAAA,QACd,YAAY,IAAI,OAAO,SAAS;AAC/B,gBAAM,SAAS,IAAI,KAAK,WAAW;AACnC,gBAAM,KAAK,iBAAiB,QAAQ,KAAK,YAAY,IAAI;AACzD,eAAK,SAAS,GAAG,QAAQ,MAAM;AAC/B,iBAAO;AAAA,QACR,CAAC;AAAA,MACF;AAAA,IACD,CAAC;AAED,yBAAO,MAAM,WAAW,KAAK,WAAW,eAAe,QAAQ;AAE/D,WAAO;AAAA,EACR;AAAA,EAEA,MAAa,UAAU,QAAqC;AAC3D,yBAAO,MAAM,kBAAkB,KAAK,WAAW,oBAAoB,QAAQ;AAC3E,UAAM,QAAQ,SAAS,WAAW,KAAK,MAAM,KAAK,UAAU,MAAM,CAAC,CAAC,IAAI;AACxE,UAAM,mCACL,SAAS,KAAK,sBAAsB,KAAK,YAAY,KAAK;AAE3D,UAAM,cAAc,MAAM,KAAK,cAAc,EAAE,aAAa,gCAAgC;AAE5F,QAAI,cAAc,GAAG;AACpB,YAAM,IAAI,MAAM,uBAAuB;AAAA,IACxC;AAEA,yBAAO,MAAM,UAAU,KAAK,WAAW,wBAAwB,oBAAoB;AAEnF,WAAO,gBAAgB;AAAA,EACxB;AAAA,EAEA,MAAa,WAAW,KAAiC;AACxD,yBAAO,MAAM,kBAAkB,KAAK,WAAW,iBAAiB,KAAK;AAErE,UAAM,cAAc,MAAM,KAAK,SAAS,cAAsB,YAAY;AACzE,YAAM,eAAe,MAAM,KAAK,cAAc,EAAE,aAAa;AAAA,QAC5D,IAAI,EAAE,KAAK,IAAI;AAAA,MAChB,CAAqB;AAErB,UAAI,iBAAiB,IAAI,QAAQ;AAChC,cAAM,IAAI,MAAM,8CAA8C;AAAA,MAC/D;AAEA,aAAO;AAAA,IACR,CAAC;AAED,yBAAO,MAAM,UAAU,KAAK,WAAW,wBAAwB,oBAAoB;AAEnF,WAAO,gBAAgB,IAAI;AAAA,EAC5B;AAAA,EAEO,mBAAmB,QAAa,gBAAwB;AAC9D,QAAI,OAAO,WAAW,UAAU;AAC/B,aAAO;AAAA,IACR;AACA,QAAI,OAAO,IAAI;AACd,aAAO,OAAO;AAAA,IACf;AAEA,UAAM,IAAI,MAAM,iCAAiC,KAAK,UAAU,MAAM,GAAG;AAAA,EAC1E;AAAA,EAEO,aAAa,QAAa;AAChC,WAAO,eAAM,aAAa,MAAM;AAAA,EACjC;AACD;",
|
|
6
6
|
"names": ["key"]
|
|
7
7
|
}
|
package/lib/database.d.ts
CHANGED
|
@@ -32,8 +32,9 @@ declare class DatabaseImplementation {
|
|
|
32
32
|
declare class ConnectionsManager {
|
|
33
33
|
private connections;
|
|
34
34
|
constructor();
|
|
35
|
+
getConnections(): DatabaseImplementation[];
|
|
35
36
|
get default(): DatabaseImplementation;
|
|
36
|
-
connect: (id
|
|
37
|
+
connect: (id?: string, connectionOptions?: ConnectionOptions) => Promise<DatabaseImplementation | undefined>;
|
|
37
38
|
database(id: string): DatabaseImplementation | undefined;
|
|
38
39
|
}
|
|
39
40
|
export declare const ConnectionManager: ConnectionsManager;
|
package/lib/database.js
CHANGED
|
@@ -174,6 +174,8 @@ class DatabaseImplementation {
|
|
|
174
174
|
class ConnectionsManager {
|
|
175
175
|
constructor() {
|
|
176
176
|
this.connect = async (id, connectionOptions) => {
|
|
177
|
+
if (!id)
|
|
178
|
+
throw new Error("Error: No id attached to connection.");
|
|
177
179
|
if (this.connections.has(id))
|
|
178
180
|
return this.connections.get(id);
|
|
179
181
|
const database = new DatabaseImplementation();
|
|
@@ -184,6 +186,9 @@ class ConnectionsManager {
|
|
|
184
186
|
};
|
|
185
187
|
this.connections = /* @__PURE__ */ new Map();
|
|
186
188
|
}
|
|
189
|
+
getConnections() {
|
|
190
|
+
return Array.from(this.connections.values());
|
|
191
|
+
}
|
|
187
192
|
get default() {
|
|
188
193
|
const [defaultConnection] = [...this.connections];
|
|
189
194
|
if (!defaultConnection)
|
package/lib/database.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/database.ts"],
|
|
4
|
-
"sourcesContent": ["import 'reflect-metadata';\nimport './utils/change-tracker';\n\nimport {\n\tAnyEntity,\n\tConnection,\n\tEntityName,\n\tIDatabaseDriver,\n\tMikroORM,\n\tOptions,\n\tReflectMetadataProvider,\n} from '@mikro-orm/core';\nimport { logger } from '@exogee/logger';\n\nimport type { EntityManager as PgEntityManager, PostgreSqlDriver } from '@mikro-orm/postgresql';\nimport type { EntityManager as MyEntityManager, MySqlDriver } from '@mikro-orm/mysql';\ntype EntityManager = PgEntityManager<PostgreSqlDriver> | MyEntityManager<MySqlDriver>;\n\nexport interface ConnectionOptions {\n\tmikroOrmConfig?: Options;\n\tsecretArn?: string;\n\tconnectionManagerId?: string;\n}\n\nexport enum IsolationLevel {\n\tSERIALIZABLE = 'SERIALIZABLE',\n\tREPEATABLE_READ = 'REPEATABLE READ',\n\tREAD_COMMITTED = 'READ COMMITTED',\n\tREAD_UNCOMMITTED = 'READ UNCOMMITTED',\n}\n\nconst NumericIsolationLevels = {\n\t[IsolationLevel.SERIALIZABLE]: 4,\n\t[IsolationLevel.REPEATABLE_READ]: 3,\n\t[IsolationLevel.READ_COMMITTED]: 2,\n\t[IsolationLevel.READ_UNCOMMITTED]: 1,\n};\n\nclass DatabaseImplementation {\n\tprivate cachedOrm?: MikroORM<IDatabaseDriver<Connection>>;\n\tprivate transactionalEm?: EntityManager;\n\tprivate transactionInProgressIsolationLevel?: IsolationLevel;\n\n\tpublic get orm() {\n\t\tif (!this.cachedOrm) {\n\t\t\tconst error = new Error('Tried to get the ORM before it was connected.');\n\t\t\tlogger.error(error);\n\t\t\tthrow error;\n\t\t}\n\n\t\treturn this.cachedOrm;\n\t}\n\n\tpublic get em() {\n\t\treturn this.transactionalEm || (this.orm.em as EntityManager);\n\t}\n\n\tpublic async transactional<T>(\n\t\tcallback: () => Promise<T>,\n\t\tisolationLevel: IsolationLevel = IsolationLevel.READ_COMMITTED\n\t) {\n\t\tlogger.trace('Database::transactional() enter');\n\n\t\tif (\n\t\t\tthis.transactionInProgressIsolationLevel &&\n\t\t\tNumericIsolationLevels[this.transactionInProgressIsolationLevel] <\n\t\t\t\tNumericIsolationLevels[isolationLevel]\n\t\t) {\n\t\t\tconst error = new Error(\n\t\t\t\t`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.`\n\t\t\t);\n\t\t\tlogger.error(error);\n\t\t\tthrow error;\n\t\t}\n\n\t\tif (this.transactionalEm) {\n\t\t\t// Transaction is already in progress that is isolated enough. Run the callback without starting a new one.\n\t\t\tlogger.trace(\n\t\t\t\t'Transaction already in progress with sufficient isolation, proceeding without new transaction.'\n\t\t\t);\n\n\t\t\treturn callback();\n\t\t} else {\n\t\t\t// Ok, start a new one.\n\t\t\tlogger.trace('Starting transaction');\n\n\t\t\treturn this.em.transactional(async (em) => {\n\t\t\t\tthis.transactionalEm = em;\n\t\t\t\tthis.transactionInProgressIsolationLevel = isolationLevel;\n\t\t\t\tawait em.execute(`SET SESSION TRANSACTION ISOLATION LEVEL ${isolationLevel}`);\n\t\t\t\tlet result: T;\n\t\t\t\ttry {\n\t\t\t\t\tresult = await callback();\n\t\t\t\t} finally {\n\t\t\t\t\tdelete this.transactionalEm;\n\t\t\t\t\tdelete this.transactionInProgressIsolationLevel;\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t});\n\t\t}\n\t}\n\n\tpublic isolatedTest(test: () => any) {\n\t\treturn async () => {\n\t\t\ttry {\n\t\t\t\tawait this.transactional(async () => {\n\t\t\t\t\tawait test();\n\t\t\t\t\tthrow new Error('Rollback transaction for test');\n\t\t\t\t}, IsolationLevel.SERIALIZABLE);\n\t\t\t} catch (error) {\n\t\t\t\t// Only need to care if this isn't our rollback from above.\n\t\t\t\t// Otherwise just gobble it.\n\t\t\t\tif ((error as Error).message !== 'Rollback transaction for test') {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\n\tpublic get rawConnection() {\n\t\treturn this.em.getDriver().getConnection();\n\t}\n\n\tprivate getConnectionInfo = async (connectionOptions?: ConnectionOptions): Promise<Options> => {\n\t\tlogger.trace('Database::getConnectionInfo() - Enter');\n\n\t\t// We have some defaults\n\t\tconst defaults: Options = {\n\t\t\thost: 'localhost',\n\t\t\tport: 5432,\n\t\t\tdbName: 'graphweaver',\n\t\t};\n\n\t\t// If we've been passed a secret then we need to get all this\n\t\t// info from Secrets Manager.\n\t\t/* let secret = {};\n\t\tconst secretArn = connectionOptions?.secretArn || process.env.DATABASE_SECRET_ARN;\n\n\t\tif (secretArn) {\n\t\t\tconst SecretsManager = new AWS.SecretsManager();\n\t\t\tlogger.trace('Fetching database connection info from Secrets Manager');\n\n\t\t\tconst result = await SecretsManager.getSecretValue({\n\t\t\t\tSecretId: secretArn,\n\t\t\t}).promise();\n\n\t\t\tlogger.trace('Got result from Secrets Manager');\n\n\t\t\tif (result.SecretString) {\n\t\t\t\tlogger.trace('Parsing result');\n\n\t\t\t\t// We only want certain properties from this secret.\n\t\t\t\tconst { host, port, username: user, password, dbname: dbName } = JSON.parse(\n\t\t\t\t\tresult.SecretString\n\t\t\t\t) as {\n\t\t\t\t\thost: string;\n\t\t\t\t\tport: number;\n\t\t\t\t\tusername: string;\n\t\t\t\t\tpassword: string;\n\t\t\t\t\tdbname: string;\n\t\t\t\t};\n\n\t\t\t\tsecret = { host, port, user, password, dbName };\n\t\t\t}\n\t\t} */\n\n\t\t// And finally we can override all of this with environment variables if needed.\n\t\tconst environmentOverrides: Options = {\n\t\t\thost: process.env.DATABASE_HOST,\n\t\t\tport: process.env.DATABASE_PORT ? parseInt(process.env.DATABASE_PORT) : undefined,\n\t\t\tuser: process.env.DATABASE_USERNAME,\n\t\t\tpassword: process.env.DATABASE_PASSWORD,\n\t\t\tdbName: process.env.DATABASE_NAME,\n\t\t};\n\n\t\t// Create a function we can use to filter out undefined values in the object.\n\t\tconst filterUndefined = (obj?: Options) => {\n\t\t\tif (!obj) return {};\n\n\t\t\tfor (const key of Object.keys(obj) as Array<keyof Options>) {\n\t\t\t\tif (obj[key] === undefined) delete obj[key];\n\t\t\t}\n\n\t\t\treturn obj;\n\t\t};\n\n\t\t// Apply each in order so the correct value wins.\n\t\treturn {\n\t\t\t...defaults,\n\t\t\t//...filterUndefined(secret),\n\t\t\t...filterUndefined(environmentOverrides),\n\t\t\t...filterUndefined(connectionOptions?.mikroOrmConfig),\n\t\t};\n\t};\n\n\tpublic getRepository = <T extends AnyEntity<T>>(entityName: EntityName<T>) =>\n\t\tthis.em.getRepository(entityName);\n\n\tpublic connect = async (connectionOptions?: ConnectionOptions) => {\n\t\tlogger.trace('Database::connect() - Enter');\n\n\t\tif (this.cachedOrm) {\n\t\t\tlogger.trace('Returning cached ORM');\n\t\t\treturn this.cachedOrm;\n\t\t}\n\n\t\tlogger.trace('Creating new ORM');\n\t\tlogger.trace('Getting connection info');\n\t\tconst params = await this.getConnectionInfo(connectionOptions);\n\n\t\tlogger.trace('Initialising ORM');\n\n\t\tlogger.trace(`${params.entities?.length}x entities`);\n\n\t\tconst orm = await MikroORM.init({\n\t\t\tvalidateRequired: false, // Since v5, new entities are validated on runtime (just before executing insert queries), based on the entity metadata\n\n\t\t\timplicitTransactions: false,\n\t\t\tmetadataProvider: ReflectMetadataProvider,\n\t\t\tdiscovery: {\n\t\t\t\tdisableDynamicFileAccess: true,\n\t\t\t\trequireEntitiesArray: false,\n\t\t\t\twarnWhenNoEntities: false,\n\t\t\t},\n\t\t\tallowGlobalContext: true,\n\n\t\t\t// Ensure we only ever create one connection to the database.\n\t\t\tpool: {\n\t\t\t\tmin: 1,\n\t\t\t\tmax: 1,\n\t\t\t},\n\t\t\t...params,\n\t\t});\n\n\t\tlogger.trace('Creating connection to %s on %s', params.dbName, params.host);\n\t\tawait orm.connect();\n\n\t\tlogger.trace('Caching connection');\n\t\tthis.cachedOrm = orm;\n\t\treturn orm;\n\t};\n\n\tpublic close = async () => {\n\t\tlogger.trace('Closing database connection');\n\n\t\tawait this.orm.close();\n\t\tdelete this.cachedOrm;\n\t};\n}\n\nclass ConnectionsManager {\n\tprivate connections: Map<string, DatabaseImplementation>;\n\n\tconstructor() {\n\t\tthis.connections = new Map<string, DatabaseImplementation>();\n\t}\n\n\tget default(): DatabaseImplementation {\n\t\tconst [defaultConnection] = [...this.connections];\n\t\tif (!defaultConnection)\n\t\t\tthrow new Error(\n\t\t\t\t'Error: No database connections. There should be at least one database connection.'\n\t\t\t);\n\t\tconst [_, databaseConnection] = defaultConnection;\n\t\treturn databaseConnection;\n\t}\n\n\tpublic connect = async (id
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import 'reflect-metadata';\nimport './utils/change-tracker';\n\nimport {\n\tAnyEntity,\n\tConnection,\n\tEntityName,\n\tIDatabaseDriver,\n\tMikroORM,\n\tOptions,\n\tReflectMetadataProvider,\n} from '@mikro-orm/core';\nimport { logger } from '@exogee/logger';\n\nimport type { EntityManager as PgEntityManager, PostgreSqlDriver } from '@mikro-orm/postgresql';\nimport type { EntityManager as MyEntityManager, MySqlDriver } from '@mikro-orm/mysql';\ntype EntityManager = PgEntityManager<PostgreSqlDriver> | MyEntityManager<MySqlDriver>;\n\nexport interface ConnectionOptions {\n\tmikroOrmConfig?: Options;\n\tsecretArn?: string;\n\tconnectionManagerId?: string;\n}\n\nexport enum IsolationLevel {\n\tSERIALIZABLE = 'SERIALIZABLE',\n\tREPEATABLE_READ = 'REPEATABLE READ',\n\tREAD_COMMITTED = 'READ COMMITTED',\n\tREAD_UNCOMMITTED = 'READ UNCOMMITTED',\n}\n\nconst NumericIsolationLevels = {\n\t[IsolationLevel.SERIALIZABLE]: 4,\n\t[IsolationLevel.REPEATABLE_READ]: 3,\n\t[IsolationLevel.READ_COMMITTED]: 2,\n\t[IsolationLevel.READ_UNCOMMITTED]: 1,\n};\n\nclass DatabaseImplementation {\n\tprivate cachedOrm?: MikroORM<IDatabaseDriver<Connection>>;\n\tprivate transactionalEm?: EntityManager;\n\tprivate transactionInProgressIsolationLevel?: IsolationLevel;\n\n\tpublic get orm() {\n\t\tif (!this.cachedOrm) {\n\t\t\tconst error = new Error('Tried to get the ORM before it was connected.');\n\t\t\tlogger.error(error);\n\t\t\tthrow error;\n\t\t}\n\n\t\treturn this.cachedOrm;\n\t}\n\n\tpublic get em() {\n\t\treturn this.transactionalEm || (this.orm.em as EntityManager);\n\t}\n\n\tpublic async transactional<T>(\n\t\tcallback: () => Promise<T>,\n\t\tisolationLevel: IsolationLevel = IsolationLevel.READ_COMMITTED\n\t) {\n\t\tlogger.trace('Database::transactional() enter');\n\n\t\tif (\n\t\t\tthis.transactionInProgressIsolationLevel &&\n\t\t\tNumericIsolationLevels[this.transactionInProgressIsolationLevel] <\n\t\t\t\tNumericIsolationLevels[isolationLevel]\n\t\t) {\n\t\t\tconst error = new Error(\n\t\t\t\t`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.`\n\t\t\t);\n\t\t\tlogger.error(error);\n\t\t\tthrow error;\n\t\t}\n\n\t\tif (this.transactionalEm) {\n\t\t\t// Transaction is already in progress that is isolated enough. Run the callback without starting a new one.\n\t\t\tlogger.trace(\n\t\t\t\t'Transaction already in progress with sufficient isolation, proceeding without new transaction.'\n\t\t\t);\n\n\t\t\treturn callback();\n\t\t} else {\n\t\t\t// Ok, start a new one.\n\t\t\tlogger.trace('Starting transaction');\n\n\t\t\treturn this.em.transactional(async (em) => {\n\t\t\t\tthis.transactionalEm = em;\n\t\t\t\tthis.transactionInProgressIsolationLevel = isolationLevel;\n\t\t\t\tawait em.execute(`SET SESSION TRANSACTION ISOLATION LEVEL ${isolationLevel}`);\n\t\t\t\tlet result: T;\n\t\t\t\ttry {\n\t\t\t\t\tresult = await callback();\n\t\t\t\t} finally {\n\t\t\t\t\tdelete this.transactionalEm;\n\t\t\t\t\tdelete this.transactionInProgressIsolationLevel;\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t});\n\t\t}\n\t}\n\n\tpublic isolatedTest(test: () => any) {\n\t\treturn async () => {\n\t\t\ttry {\n\t\t\t\tawait this.transactional(async () => {\n\t\t\t\t\tawait test();\n\t\t\t\t\tthrow new Error('Rollback transaction for test');\n\t\t\t\t}, IsolationLevel.SERIALIZABLE);\n\t\t\t} catch (error) {\n\t\t\t\t// Only need to care if this isn't our rollback from above.\n\t\t\t\t// Otherwise just gobble it.\n\t\t\t\tif ((error as Error).message !== 'Rollback transaction for test') {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\n\tpublic get rawConnection() {\n\t\treturn this.em.getDriver().getConnection();\n\t}\n\n\tprivate getConnectionInfo = async (connectionOptions?: ConnectionOptions): Promise<Options> => {\n\t\tlogger.trace('Database::getConnectionInfo() - Enter');\n\n\t\t// We have some defaults\n\t\tconst defaults: Options = {\n\t\t\thost: 'localhost',\n\t\t\tport: 5432,\n\t\t\tdbName: 'graphweaver',\n\t\t};\n\n\t\t// If we've been passed a secret then we need to get all this\n\t\t// info from Secrets Manager.\n\t\t/* let secret = {};\n\t\tconst secretArn = connectionOptions?.secretArn || process.env.DATABASE_SECRET_ARN;\n\n\t\tif (secretArn) {\n\t\t\tconst SecretsManager = new AWS.SecretsManager();\n\t\t\tlogger.trace('Fetching database connection info from Secrets Manager');\n\n\t\t\tconst result = await SecretsManager.getSecretValue({\n\t\t\t\tSecretId: secretArn,\n\t\t\t}).promise();\n\n\t\t\tlogger.trace('Got result from Secrets Manager');\n\n\t\t\tif (result.SecretString) {\n\t\t\t\tlogger.trace('Parsing result');\n\n\t\t\t\t// We only want certain properties from this secret.\n\t\t\t\tconst { host, port, username: user, password, dbname: dbName } = JSON.parse(\n\t\t\t\t\tresult.SecretString\n\t\t\t\t) as {\n\t\t\t\t\thost: string;\n\t\t\t\t\tport: number;\n\t\t\t\t\tusername: string;\n\t\t\t\t\tpassword: string;\n\t\t\t\t\tdbname: string;\n\t\t\t\t};\n\n\t\t\t\tsecret = { host, port, user, password, dbName };\n\t\t\t}\n\t\t} */\n\n\t\t// And finally we can override all of this with environment variables if needed.\n\t\tconst environmentOverrides: Options = {\n\t\t\thost: process.env.DATABASE_HOST,\n\t\t\tport: process.env.DATABASE_PORT ? parseInt(process.env.DATABASE_PORT) : undefined,\n\t\t\tuser: process.env.DATABASE_USERNAME,\n\t\t\tpassword: process.env.DATABASE_PASSWORD,\n\t\t\tdbName: process.env.DATABASE_NAME,\n\t\t};\n\n\t\t// Create a function we can use to filter out undefined values in the object.\n\t\tconst filterUndefined = (obj?: Options) => {\n\t\t\tif (!obj) return {};\n\n\t\t\tfor (const key of Object.keys(obj) as Array<keyof Options>) {\n\t\t\t\tif (obj[key] === undefined) delete obj[key];\n\t\t\t}\n\n\t\t\treturn obj;\n\t\t};\n\n\t\t// Apply each in order so the correct value wins.\n\t\treturn {\n\t\t\t...defaults,\n\t\t\t//...filterUndefined(secret),\n\t\t\t...filterUndefined(environmentOverrides),\n\t\t\t...filterUndefined(connectionOptions?.mikroOrmConfig),\n\t\t};\n\t};\n\n\tpublic getRepository = <T extends AnyEntity<T>>(entityName: EntityName<T>) =>\n\t\tthis.em.getRepository(entityName);\n\n\tpublic connect = async (connectionOptions?: ConnectionOptions) => {\n\t\tlogger.trace('Database::connect() - Enter');\n\n\t\tif (this.cachedOrm) {\n\t\t\tlogger.trace('Returning cached ORM');\n\t\t\treturn this.cachedOrm;\n\t\t}\n\n\t\tlogger.trace('Creating new ORM');\n\t\tlogger.trace('Getting connection info');\n\t\tconst params = await this.getConnectionInfo(connectionOptions);\n\n\t\tlogger.trace('Initialising ORM');\n\n\t\tlogger.trace(`${params.entities?.length}x entities`);\n\n\t\tconst orm = await MikroORM.init({\n\t\t\tvalidateRequired: false, // Since v5, new entities are validated on runtime (just before executing insert queries), based on the entity metadata\n\n\t\t\timplicitTransactions: false,\n\t\t\tmetadataProvider: ReflectMetadataProvider,\n\t\t\tdiscovery: {\n\t\t\t\tdisableDynamicFileAccess: true,\n\t\t\t\trequireEntitiesArray: false,\n\t\t\t\twarnWhenNoEntities: false,\n\t\t\t},\n\t\t\tallowGlobalContext: true,\n\n\t\t\t// Ensure we only ever create one connection to the database.\n\t\t\tpool: {\n\t\t\t\tmin: 1,\n\t\t\t\tmax: 1,\n\t\t\t},\n\t\t\t...params,\n\t\t});\n\n\t\tlogger.trace('Creating connection to %s on %s', params.dbName, params.host);\n\t\tawait orm.connect();\n\n\t\tlogger.trace('Caching connection');\n\t\tthis.cachedOrm = orm;\n\t\treturn orm;\n\t};\n\n\tpublic close = async () => {\n\t\tlogger.trace('Closing database connection');\n\n\t\tawait this.orm.close();\n\t\tdelete this.cachedOrm;\n\t};\n}\n\nclass ConnectionsManager {\n\tprivate connections: Map<string, DatabaseImplementation>;\n\n\tconstructor() {\n\t\tthis.connections = new Map<string, DatabaseImplementation>();\n\t}\n\n\tgetConnections() {\n\t\treturn Array.from(this.connections.values());\n\t}\n\n\tget default(): DatabaseImplementation {\n\t\tconst [defaultConnection] = [...this.connections];\n\t\tif (!defaultConnection)\n\t\t\tthrow new Error(\n\t\t\t\t'Error: No database connections. There should be at least one database connection.'\n\t\t\t);\n\t\tconst [_, databaseConnection] = defaultConnection;\n\t\treturn databaseConnection;\n\t}\n\n\tpublic connect = async (id?: string, connectionOptions?: ConnectionOptions) => {\n\t\tif (!id) throw new Error('Error: No id attached to connection.');\n\n\t\tif (this.connections.has(id)) return this.connections.get(id);\n\t\tconst database = new DatabaseImplementation();\n\t\tif (connectionOptions) await database.connect(connectionOptions);\n\t\tlogger.trace(`Saving database connection with id \"${id}\".`);\n\t\tthis.connections.set(id, database);\n\t};\n\n\tpublic database(id: string) {\n\t\tlogger.trace(`Finding database connection for id \"${id}\"`);\n\t\treturn this.connections.get(id);\n\t}\n}\nexport const ConnectionManager = new ConnectionsManager();\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["IsolationLevel"]
|
|
7
7
|
}
|
package/lib/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export * from './decorators';
|
|
|
5
5
|
export * from './database';
|
|
6
6
|
export * from './types';
|
|
7
7
|
export * from './utils/authentication-context';
|
|
8
|
+
export * from './plugins';
|
|
8
9
|
export type { AnyEntity, ChangeSet, EntityData, EntityName, EventArgs, EventSubscriber, FilterQuery, FlushEventArgs, Loaded, QueryOrderMap, } from '@mikro-orm/core';
|
|
9
10
|
export type { LoadedReference } from '@mikro-orm/core';
|
|
10
11
|
export { ChangeSetType, Collection, DatabaseObjectNotFoundException, EntityManager, EntityRepository, LockMode, PrimaryKeyType, QueryFlag, QueryOrder, Reference, ReferenceType, Subscriber, UniqueConstraintViolationException, Utils, wrap, } from '@mikro-orm/core';
|
package/lib/index.js
CHANGED
|
@@ -50,6 +50,7 @@ __reExport(src_exports, require("./decorators"), module.exports);
|
|
|
50
50
|
__reExport(src_exports, require("./database"), module.exports);
|
|
51
51
|
__reExport(src_exports, require("./types"), module.exports);
|
|
52
52
|
__reExport(src_exports, require("./utils/authentication-context"), module.exports);
|
|
53
|
+
__reExport(src_exports, require("./plugins"), module.exports);
|
|
53
54
|
var import_core = require("@mikro-orm/core");
|
|
54
55
|
dotenv.config({
|
|
55
56
|
path: `.env.${(process.env.NODE_ENV || "development").toLowerCase()}`
|
package/lib/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["import 'reflect-metadata';\n\nimport * as dotenv from 'dotenv';\ndotenv.config({\n\tpath: `.env.${(process.env.NODE_ENV || 'development').toLowerCase()}`,\n}); // TODO: The path to .env file in pnpm workspaces seems to use the workspace package.json path. Need to ensure it uses the local version (if required)\n\nexport * from './base-resolver';\nexport * from './entities';\nexport * from './decorators';\nexport * from './database';\nexport * from './types';\nexport * from './utils/authentication-context';\n\n// Re-export from Mikro so things that depend on database entities can access helpers such as\n// Reference.isReference().\nexport type {\n\tAnyEntity,\n\tChangeSet,\n\tEntityData,\n\tEntityName,\n\tEventArgs,\n\tEventSubscriber,\n\tFilterQuery,\n\tFlushEventArgs,\n\tLoaded,\n\tQueryOrderMap,\n} from '@mikro-orm/core';\nexport type { LoadedReference } from '@mikro-orm/core';\nexport {\n\tChangeSetType,\n\tCollection,\n\tDatabaseObjectNotFoundException,\n\tEntityManager,\n\tEntityRepository,\n\tLockMode,\n\tPrimaryKeyType,\n\tQueryFlag,\n\tQueryOrder,\n\tReference,\n\tReferenceType,\n\tSubscriber,\n\tUniqueConstraintViolationException,\n\tUtils,\n\twrap,\n} from '@mikro-orm/core';\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,8BAAO;AAEP,aAAwB;AAKxB,wBAAc,4BAPd;AAQA,wBAAc,uBARd;AASA,wBAAc,yBATd;AAUA,wBAAc,uBAVd;AAWA,wBAAc,oBAXd;AAYA,wBAAc,2CAZd;
|
|
4
|
+
"sourcesContent": ["import 'reflect-metadata';\n\nimport * as dotenv from 'dotenv';\ndotenv.config({\n\tpath: `.env.${(process.env.NODE_ENV || 'development').toLowerCase()}`,\n}); // TODO: The path to .env file in pnpm workspaces seems to use the workspace package.json path. Need to ensure it uses the local version (if required)\n\nexport * from './base-resolver';\nexport * from './entities';\nexport * from './decorators';\nexport * from './database';\nexport * from './types';\nexport * from './utils/authentication-context';\nexport * from './plugins';\n\n// Re-export from Mikro so things that depend on database entities can access helpers such as\n// Reference.isReference().\nexport type {\n\tAnyEntity,\n\tChangeSet,\n\tEntityData,\n\tEntityName,\n\tEventArgs,\n\tEventSubscriber,\n\tFilterQuery,\n\tFlushEventArgs,\n\tLoaded,\n\tQueryOrderMap,\n} from '@mikro-orm/core';\nexport type { LoadedReference } from '@mikro-orm/core';\nexport {\n\tChangeSetType,\n\tCollection,\n\tDatabaseObjectNotFoundException,\n\tEntityManager,\n\tEntityRepository,\n\tLockMode,\n\tPrimaryKeyType,\n\tQueryFlag,\n\tQueryOrder,\n\tReference,\n\tReferenceType,\n\tSubscriber,\n\tUniqueConstraintViolationException,\n\tUtils,\n\twrap,\n} from '@mikro-orm/core';\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,8BAAO;AAEP,aAAwB;AAKxB,wBAAc,4BAPd;AAQA,wBAAc,uBARd;AASA,wBAAc,yBATd;AAUA,wBAAc,uBAVd;AAWA,wBAAc,oBAXd;AAYA,wBAAc,2CAZd;AAaA,wBAAc,sBAbd;AA8BA,kBAgBO;AA3CP,OAAO,OAAO;AAAA,EACb,MAAM,SAAS,QAAQ,IAAI,YAAY,eAAe,YAAY;AACnE,CAAC;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var clear_database_context_exports = {};
|
|
20
|
+
__export(clear_database_context_exports, {
|
|
21
|
+
ClearDatabaseContext: () => ClearDatabaseContext
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(clear_database_context_exports);
|
|
24
|
+
var import_logger = require("@exogee/logger");
|
|
25
|
+
var import_database = require("../database");
|
|
26
|
+
const ClearDatabaseContext = {
|
|
27
|
+
async requestDidStart() {
|
|
28
|
+
try {
|
|
29
|
+
for (const connection of import_database.ConnectionManager.getConnections()) {
|
|
30
|
+
connection.em.clear();
|
|
31
|
+
}
|
|
32
|
+
} catch (err) {
|
|
33
|
+
import_logger.logger.trace("failed to clear default database.");
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
38
|
+
0 && (module.exports = {
|
|
39
|
+
ClearDatabaseContext
|
|
40
|
+
});
|
|
41
|
+
//# sourceMappingURL=clear-database-context.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/plugins/clear-database-context.ts"],
|
|
4
|
+
"sourcesContent": ["import { ApolloServerPlugin } from '@apollo/server';\nimport { logger } from '@exogee/logger';\n\nimport { ConnectionManager } from '../database';\n\nexport const ClearDatabaseContext: ApolloServerPlugin = {\n\t// We need to ensure the Entity Manager is clear on each request\n\tasync requestDidStart() {\n\t\ttry {\n\t\t\tfor (const connection of ConnectionManager.getConnections()) {\n\t\t\t\tconnection.em.clear();\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tlogger.trace('failed to clear default database.');\n\t\t}\n\t},\n};\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,oBAAuB;AAEvB,sBAAkC;AAE3B,MAAM,uBAA2C;AAAA,EAEvD,MAAM,kBAAkB;AACvB,QAAI;AACH,iBAAW,cAAc,kCAAkB,eAAe,GAAG;AAC5D,mBAAW,GAAG,MAAM;AAAA,MACrB;AAAA,IACD,SAAS,KAAP;AACD,2BAAO,MAAM,mCAAmC;AAAA,IACjD;AAAA,EACD;AACD;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var connect_to_database_exports = {};
|
|
20
|
+
__export(connect_to_database_exports, {
|
|
21
|
+
connectToDatabase: () => connectToDatabase
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(connect_to_database_exports);
|
|
24
|
+
var import_database = require("../database");
|
|
25
|
+
const connectToDatabase = (options) => {
|
|
26
|
+
return {
|
|
27
|
+
serverWillStart: async () => {
|
|
28
|
+
if (Array.isArray(options)) {
|
|
29
|
+
for (const option of options) {
|
|
30
|
+
if (option.connectionManagerId)
|
|
31
|
+
await import_database.ConnectionManager.connect(option.connectionManagerId, option);
|
|
32
|
+
}
|
|
33
|
+
} else {
|
|
34
|
+
await import_database.ConnectionManager.connect(options.connectionManagerId, options);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
40
|
+
0 && (module.exports = {
|
|
41
|
+
connectToDatabase
|
|
42
|
+
});
|
|
43
|
+
//# sourceMappingURL=connect-to-database.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/plugins/connect-to-database.ts"],
|
|
4
|
+
"sourcesContent": ["import { ApolloServerPlugin } from '@apollo/server';\nimport { ConnectionManager, ConnectionOptions } from '../database';\n\nexport const connectToDatabase = (\n\toptions: ConnectionOptions[] | ConnectionOptions\n): ApolloServerPlugin => {\n\treturn {\n\t\tserverWillStart: async () => {\n\t\t\tif (Array.isArray(options)) {\n\t\t\t\tfor (const option of options) {\n\t\t\t\t\tif (option.connectionManagerId)\n\t\t\t\t\t\tawait ConnectionManager.connect(option.connectionManagerId, option);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tawait ConnectionManager.connect(options.connectionManagerId, options);\n\t\t\t}\n\t\t},\n\t};\n};\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,sBAAqD;AAE9C,MAAM,oBAAoB,CAChC,YACwB;AACxB,SAAO;AAAA,IACN,iBAAiB,YAAY;AAC5B,UAAI,MAAM,QAAQ,OAAO,GAAG;AAC3B,mBAAW,UAAU,SAAS;AAC7B,cAAI,OAAO;AACV,kBAAM,kCAAkB,QAAQ,OAAO,qBAAqB,MAAM;AAAA,QACpE;AAAA,MACD,OAAO;AACN,cAAM,kCAAkB,QAAQ,QAAQ,qBAAqB,OAAO;AAAA,MACrE;AAAA,IACD;AAAA,EACD;AACD;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var plugins_exports = {};
|
|
20
|
+
__export(plugins_exports, {
|
|
21
|
+
ClearDatabaseContext: () => import_clear_database_context.ClearDatabaseContext,
|
|
22
|
+
connectToDatabase: () => import_connect_to_database.connectToDatabase
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(plugins_exports);
|
|
25
|
+
var import_clear_database_context = require("./clear-database-context");
|
|
26
|
+
var import_connect_to_database = require("./connect-to-database");
|
|
27
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
28
|
+
0 && (module.exports = {
|
|
29
|
+
ClearDatabaseContext,
|
|
30
|
+
connectToDatabase
|
|
31
|
+
});
|
|
32
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/plugins/index.ts"],
|
|
4
|
+
"sourcesContent": ["export { ClearDatabaseContext } from './clear-database-context';\nexport { connectToDatabase } from './connect-to-database';\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oCAAqC;AACrC,iCAAkC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exogee/graphweaver-mikroorm",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.17",
|
|
4
4
|
"description": "MikroORM backend for @exogee/graphweaver",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -12,13 +12,14 @@
|
|
|
12
12
|
"lib"
|
|
13
13
|
],
|
|
14
14
|
"dependencies": {
|
|
15
|
+
"@apollo/server": "4.2.2",
|
|
15
16
|
"dataloader": "2.2.2",
|
|
16
17
|
"decimal.js": "10.3.1",
|
|
17
18
|
"dotenv": "16.0.0",
|
|
18
19
|
"graphql": "16.6.0",
|
|
19
20
|
"reflect-metadata": "0.1.13",
|
|
20
|
-
"@exogee/graphweaver": "0.1.
|
|
21
|
-
"@exogee/logger": "0.1.
|
|
21
|
+
"@exogee/graphweaver": "0.1.17",
|
|
22
|
+
"@exogee/logger": "0.1.17"
|
|
22
23
|
},
|
|
23
24
|
"devDependencies": {
|
|
24
25
|
"@mikro-orm/core": "5.4.2",
|