@exogee/graphweaver-mikroorm 2.21.0 → 2.21.2

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/database.d.ts CHANGED
@@ -26,10 +26,10 @@ declare class DatabaseImplementation {
26
26
  get em(): EntityManager;
27
27
  transactional<T>(callback: () => Promise<T>, isolationLevel?: IsolationLevel): Promise<T>;
28
28
  isolatedTest(test: () => any): () => Promise<void>;
29
- get rawConnection(): import("@mikro-orm/postgresql").PostgreSqlConnection | import("@mikro-orm/postgresql").MySqlConnection | import("@mikro-orm/sqlite").SqliteConnection;
29
+ get rawConnection(): import("@mikro-orm/postgresql").PostgreSqlConnection | import("@mikro-orm/knex").MySqlConnection | import("@mikro-orm/sqlite").SqliteConnection;
30
30
  private getEnvironmentOverrides;
31
31
  private getConnectionInfo;
32
- getRepository: <T extends AnyEntity<T>>(entityName: EntityName<T>) => import("@mikro-orm/core").GetRepository<T, import("@mikro-orm/postgresql").EntityRepository<T>>;
32
+ getRepository: <T extends AnyEntity<T>>(entityName: EntityName<T>) => import("@mikro-orm/core").GetRepository<T, import("@mikro-orm/knex").EntityRepository<T>>;
33
33
  connect: (connectionOptions?: ConnectionOptions) => Promise<MikroORM<IDatabaseDriver<Connection>, import("@mikro-orm/core").EntityManager<IDatabaseDriver<Connection>>>>;
34
34
  close: () => Promise<void>;
35
35
  }
@@ -7,12 +7,13 @@ export declare class SchemaEntityFile extends BaseFile {
7
7
  protected readonly platform: Platform;
8
8
  protected readonly databaseType: DatabaseType;
9
9
  protected readonly entityLookup: Map<string, EntityMetadata<any>>;
10
+ protected readonly clientGeneratedPrimaryKeys: boolean;
10
11
  protected readonly coreImports: Set<string>;
11
12
  protected readonly scalarImports: Set<string>;
12
13
  protected readonly entityImports: Set<string>;
13
14
  protected readonly enumImports: Set<string>;
14
15
  readonly errors: string[];
15
- constructor(meta: EntityMetadata, namingStrategy: NamingStrategy, platform: Platform, databaseType: DatabaseType, entityLookup: Map<string, EntityMetadata<any>>);
16
+ constructor(meta: EntityMetadata, namingStrategy: NamingStrategy, platform: Platform, databaseType: DatabaseType, entityLookup: Map<string, EntityMetadata<any>>, clientGeneratedPrimaryKeys: boolean);
16
17
  getBasePath(): string;
17
18
  getBaseName(): string;
18
19
  generate(): string;
@@ -44,13 +44,14 @@ const friendlyNameForDatabaseType = (type) => {
44
44
  throw new Error("Unimplemented database type: " + type);
45
45
  };
46
46
  class SchemaEntityFile extends import_base_file.BaseFile {
47
- constructor(meta, namingStrategy, platform, databaseType, entityLookup) {
47
+ constructor(meta, namingStrategy, platform, databaseType, entityLookup, clientGeneratedPrimaryKeys) {
48
48
  super(meta, namingStrategy, platform);
49
49
  this.meta = meta;
50
50
  this.namingStrategy = namingStrategy;
51
51
  this.platform = platform;
52
52
  this.databaseType = databaseType;
53
53
  this.entityLookup = entityLookup;
54
+ this.clientGeneratedPrimaryKeys = clientGeneratedPrimaryKeys;
54
55
  this.coreImports = /* @__PURE__ */ new Set();
55
56
  this.scalarImports = /* @__PURE__ */ new Set();
56
57
  this.entityImports = /* @__PURE__ */ new Set();
@@ -110,7 +111,7 @@ class SchemaEntityFile extends import_base_file.BaseFile {
110
111
  this.coreImports.add("Entity");
111
112
  file += `@Entity<${this.meta.className}>(${this.quote(this.meta.className)}, {
112
113
  provider: new MikroBackendProvider(Orm${this.meta.className}, connection, { backendDisplayName: '${friendlyNameForDatabaseType(this.databaseType)}'})`;
113
- if (props.length === 1 && props[0].primary) {
114
+ if (props.length === 1 && props[0].primary || this.clientGeneratedPrimaryKeys) {
114
115
  file += `,
115
116
  apiOptions: { clientGeneratedPrimaryKeys: true },
116
117
  })
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/introspection/files/schema-entity-file.ts"],
4
- "sourcesContent": ["import type {\n\tDictionary,\n\tEntityMetadata,\n\tEntityProperty,\n\tNamingStrategy,\n\tPlatform,\n} from '@mikro-orm/core';\nimport { ReferenceKind, Utils } from '@mikro-orm/core';\nimport pluralize from 'pluralize';\nimport { identifierForEnumValue, pascalToCamelCaseString, pascalToKebabCaseString } from '../utils';\nimport { BaseFile } from './base-file';\nimport { DatabaseType } from '../../database';\nimport { isEntityWithSinglePrimaryKey } from '../generate';\n\nconst friendlyNameForDatabaseType = (type: DatabaseType) => {\n\tif (type === 'mssql') return 'SQL Server';\n\tif (type === 'mysql') return 'MySQL';\n\tif (type === 'postgresql') return 'PostgreSQL';\n\tif (type === 'sqlite') return 'SQLite';\n\n\tthrow new Error('Unimplemented database type: ' + type);\n};\n\nexport class SchemaEntityFile extends BaseFile {\n\tprotected readonly coreImports = new Set<string>();\n\tprotected readonly scalarImports = new Set<string>();\n\tprotected readonly entityImports = new Set<string>();\n\tprotected readonly enumImports = new Set<string>();\n\tpublic readonly errors: string[] = [];\n\n\tconstructor(\n\t\tprotected readonly meta: EntityMetadata,\n\t\tprotected readonly namingStrategy: NamingStrategy,\n\t\tprotected readonly platform: Platform,\n\t\tprotected readonly databaseType: DatabaseType,\n\t\tprotected readonly entityLookup: Map<string, EntityMetadata<any>>\n\t) {\n\t\tsuper(meta, namingStrategy, platform);\n\t}\n\n\tgetBasePath() {\n\t\treturn `backend/schema/`;\n\t}\n\n\tgetBaseName() {\n\t\tconst fileName = pascalToKebabCaseString(this.meta.className);\n\t\treturn `${fileName}.ts`;\n\t}\n\n\tgenerate(): string {\n\t\tconst enumDefinitions: string[] = [];\n\t\tlet classBody = '';\n\t\tconst generatedPropertyNames = new Set<string>();\n\t\tconst props = Object.values(this.meta.properties);\n\t\tprops.forEach((prop) => {\n\t\t\tconst relatedEntity = this.entityLookup.get(prop.type);\n\t\t\tif (relatedEntity) {\n\t\t\t\t// These are not supported yet, just skip them.\n\t\t\t\tif (!isEntityWithSinglePrimaryKey(relatedEntity)) {\n\t\t\t\t\tthis.errors.push(\n\t\t\t\t\t\t` - Warning: Composite primary keys are not supported. ${this.meta.className} entity references ${prop.type} entity with composite primary key.`\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (generatedPropertyNames.has(prop.name)) {\n\t\t\t\tthis.errors.push(\n\t\t\t\t\t` - Warning: Property ${prop.name} on ${this.meta.className} entity is not unique. Additional instances of this property were ignored.`\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tgeneratedPropertyNames.add(prop.name);\n\n\t\t\tconst decorator = this.getPropertyDecorator(prop);\n\t\t\tconst definition = this.getPropertyDefinition(prop);\n\n\t\t\tif (classBody && !classBody.endsWith('\\n\\n')) {\n\t\t\t\tclassBody += '\\n';\n\t\t\t}\n\n\t\t\tclassBody += decorator;\n\t\t\tclassBody += definition;\n\n\t\t\tif (props[props.length - 1] !== prop) classBody += '\\n';\n\n\t\t\tif (prop.enum) {\n\t\t\t\tconst enumClassName = this.namingStrategy.getClassName(\n\t\t\t\t\tthis.meta.collection + '_' + prop.fieldNames[0],\n\t\t\t\t\t'_'\n\t\t\t\t);\n\t\t\t\tenumDefinitions.push(this.getEnumClassDefinition(enumClassName));\n\t\t\t}\n\t\t});\n\n\t\tlet file = '';\n\n\t\tif (enumDefinitions.length) {\n\t\t\tfile += enumDefinitions.join('\\n');\n\t\t\tfile += '\\n\\n';\n\t\t}\n\n\t\tthis.coreImports.add('Entity');\n\n\t\tfile += `@Entity<${this.meta.className}>(${this.quote(this.meta.className)}, {\\n\\tprovider: new MikroBackendProvider(Orm${this.meta.className}, connection, { backendDisplayName: '${friendlyNameForDatabaseType(this.databaseType)}'})`;\n\n\t\tif (props.length === 1 && props[0].primary) {\n\t\t\t// Special case. If there's a single primary key field in this entity, right now that requires that it's a client side generated primary key.\n\t\t\t// There's no reason this has to be the case, but it's a current limitation, so we should generate a working project for them.\n\t\t\t// We should be able to remove this in the future and allow users to use it both ways.\n\t\t\tfile += `,\\n\\tapiOptions: { clientGeneratedPrimaryKeys: true },\\n})\\n`;\n\t\t} else {\n\t\t\tfile += `\\n})\\n`;\n\t\t}\n\n\t\tfile += `export class ${this.meta.className} {\\n`;\n\t\tfile += `${classBody}}\\n`;\n\t\tconst imports = [\n\t\t\t`import { ${[...this.coreImports].sort().join(', ')} } from '@exogee/graphweaver';`,\n\t\t];\n\n\t\tif (this.scalarImports.size > 0) {\n\t\t\timports.push(\n\t\t\t\t`import { ${[...this.scalarImports]\n\t\t\t\t\t.sort()\n\t\t\t\t\t.join(', ')} } from '@exogee/graphweaver-scalars';`\n\t\t\t);\n\t\t}\n\n\t\timports.push(`import { MikroBackendProvider } from '@exogee/graphweaver-mikroorm';`);\n\n\t\tconst entityImports = [...this.entityImports].filter((e) => e !== this.meta.className);\n\t\tentityImports.sort().forEach((entity) => {\n\t\t\timports.push(`import { ${entity} } from './${pascalToKebabCaseString(entity)}';`);\n\t\t});\n\n\t\timports.push(\n\t\t\t`import { ${this.enumImports.size > 0 ? [...this.enumImports].sort().join(', ') + ', ' : ''}${\n\t\t\t\tthis.meta.className\n\t\t\t} as Orm${this.meta.className} } from '../entities';`,\n\t\t\t`import { connection } from '../database';`\n\t\t);\n\n\t\tfile = `${imports.join('\\n')}\\n\\n${file}`;\n\n\t\treturn file;\n\t}\n\n\tprotected getTypescriptPropertyType(prop: EntityProperty): string {\n\t\tif ([ReferenceKind.ONE_TO_ONE, ReferenceKind.MANY_TO_ONE].includes(prop.kind)) {\n\t\t\treturn prop.type.charAt(0).toUpperCase() + prop.type.slice(1);\n\t\t}\n\n\t\tif (['jsonb', 'json', 'any'].includes(prop.columnTypes?.[0])) {\n\t\t\treturn `Record<string, unknown>`;\n\t\t}\n\n\t\tif (prop.columnTypes?.[0] === 'date') {\n\t\t\treturn 'Date';\n\t\t}\n\n\t\tif (prop.type === 'unknown') {\n\t\t\t//fallback to string if unknown\n\t\t\treturn 'string';\n\t\t}\n\n\t\tif (prop.type === 'bigint') {\n\t\t\treturn 'string';\n\t\t}\n\n\t\treturn prop.runtimeType;\n\t}\n\n\tprotected getPropertyDefinition(prop: EntityProperty): string {\n\t\tconst padding = '\\t';\n\n\t\tif ([ReferenceKind.ONE_TO_MANY, ReferenceKind.MANY_TO_MANY].includes(prop.kind)) {\n\t\t\tthis.entityImports.add(prop.type);\n\t\t\treturn `${padding}${prop.name}!: ${prop.type}[];\\n`;\n\t\t}\n\n\t\t// string defaults are usually things like SQL functions, but can be also enums, for that `useDefault` should be true\n\t\tconst isEnumOrNonStringDefault = prop.enum || typeof prop.default !== 'string';\n\t\tconst useDefault = prop.default != null && isEnumOrNonStringDefault;\n\t\tconst optional = prop.nullable ? '?' : useDefault ? '' : '!';\n\n\t\tconst file = `${prop.name}${optional}: ${this.getTypescriptPropertyType(prop)}`;\n\n\t\tif (!useDefault) {\n\t\t\treturn `${padding + file};\\n`;\n\t\t}\n\n\t\tif (prop.enum && typeof prop.default === 'string') {\n\t\t\treturn `${padding}${file} = ${prop.runtimeType}.${identifierForEnumValue(prop.default)};\\n`;\n\t\t}\n\n\t\treturn `${padding}${prop.name} = ${prop.default};\\n`;\n\t}\n\n\tprotected getEnumClassDefinition(enumClassName: string): string {\n\t\tthis.coreImports.add('graphweaverMetadata');\n\t\tthis.enumImports.add(enumClassName);\n\t\treturn `graphweaverMetadata.collectEnumInformation({ target: ${enumClassName}, name: ${this.quote(enumClassName)} });`;\n\t}\n\n\tprivate getGraphQLPropertyType(prop: EntityProperty): string {\n\t\tif (prop.primary) {\n\t\t\tthis.coreImports.add('ID');\n\t\t\treturn 'ID';\n\t\t}\n\n\t\tif (prop.runtimeType === 'Date') {\n\t\t\tthis.scalarImports.add('ISODateStringScalar');\n\t\t\treturn 'ISODateStringScalar';\n\t\t}\n\n\t\tif (prop.columnTypes?.[0] === 'date') {\n\t\t\tthis.scalarImports.add('DateScalar');\n\t\t\treturn 'DateScalar';\n\t\t}\n\n\t\tif (prop.runtimeType === 'unknown') {\n\t\t\treturn 'String';\n\t\t}\n\n\t\tif (prop.runtimeType === 'bigint') {\n\t\t\tthis.scalarImports.add('GraphQLBigInt');\n\t\t\treturn 'GraphQLBigInt';\n\t\t}\n\n\t\tif (prop.runtimeType === 'Buffer') {\n\t\t\tthis.scalarImports.add('GraphQLByte');\n\t\t\treturn 'GraphQLByte';\n\t\t}\n\n\t\tif (['jsonb', 'json', 'any'].includes(prop.columnTypes?.[0])) {\n\t\t\tthis.scalarImports.add('GraphQLJSON');\n\t\t\treturn `GraphQLJSON`;\n\t\t}\n\n\t\tif (prop.runtimeType?.includes('[]')) {\n\t\t\treturn `[${prop.type.charAt(0).toUpperCase() + prop.type.slice(1).replace('[]', '')}]`;\n\t\t}\n\n\t\tif ([ReferenceKind.ONE_TO_ONE, ReferenceKind.MANY_TO_ONE].includes(prop.kind)) {\n\t\t\treturn prop.type.charAt(0).toUpperCase() + prop.type.slice(1);\n\t\t}\n\n\t\tif ([ReferenceKind.MANY_TO_MANY, ReferenceKind.ONE_TO_MANY].includes(prop.kind)) {\n\t\t\treturn `[${prop.type.charAt(0).toUpperCase() + prop.type.slice(1).replace('[]', '')}]`;\n\t\t}\n\n\t\tif (prop.pivotTable) {\n\t\t\treturn `[${prop.type.charAt(0).toUpperCase() + prop.type.slice(1)}]`;\n\t\t}\n\n\t\tconst lastChanceType = prop.runtimeType ?? prop.type;\n\n\t\tif (!lastChanceType) {\n\t\t\tconsole.error(`Property is malformed, it has no type or runtimeType:`, prop);\n\t\t\tthrow new Error(`Property ${prop.name} on ${prop.entity} entity has no type or runtimeType.`);\n\t\t}\n\n\t\treturn lastChanceType.charAt(0).toUpperCase() + lastChanceType.slice(1);\n\t}\n\n\tprivate getPropertyDecorator(prop: EntityProperty): string {\n\t\tconst padding = '\\t';\n\t\tconst options = {} as Dictionary;\n\t\tlet decorator = this.getDecoratorType(prop);\n\n\t\tif (prop.kind === ReferenceKind.MANY_TO_MANY) {\n\t\t\tthis.getManyToManyDecoratorOptions(options, prop);\n\t\t} else if (prop.kind === ReferenceKind.ONE_TO_MANY) {\n\t\t\tthis.getOneToManyDecoratorOptions(options, prop);\n\t\t} else if (prop.kind !== ReferenceKind.SCALAR) {\n\t\t\tthis.getForeignKeyDecoratorOptions(options, prop);\n\t\t}\n\n\t\tthis.getCommonDecoratorOptions(options, prop);\n\t\tdecorator = [decorator].map((d) => padding + d).join('\\n');\n\n\t\tif (!Utils.hasObjectKeys(options)) {\n\t\t\treturn `${decorator}(() => ${this.getGraphQLPropertyType(prop)})\\n`;\n\t\t}\n\n\t\treturn `${decorator}(() => ${this.getGraphQLPropertyType(prop)}, { ${Object.entries(options)\n\t\t\t.map(([opt, val]) => `${opt}: ${JSON.stringify(val).replaceAll('\"', '')}`)\n\t\t\t.join(', ')} })\\n`;\n\t}\n\n\tprotected getCommonDecoratorOptions(options: Dictionary, prop: EntityProperty): void {\n\t\t// Owning side: use the FK's nullability\n\t\t// Non-owning side of 1:1 is always nullable because we aren't guaranteed to have a row for every single\n\t\t// entity created on the non-owning side of the relationship.\n\t\tif (\n\t\t\t(prop.nullable && !prop.mappedBy) ||\n\t\t\t(prop.mappedBy && prop.kind === ReferenceKind.ONE_TO_ONE)\n\t\t) {\n\t\t\toptions.nullable = true;\n\t\t}\n\n\t\tif (prop.primary) {\n\t\t\toptions.primaryKeyField = true;\n\t\t}\n\n\t\t// If there's a property called 'name' it should be the summary field. If not, and there's a field called 'title'\n\t\t// then it should be the summary field.\n\t\tif (prop.name === 'name') {\n\t\t\toptions.adminUIOptions = { summaryField: true };\n\t\t} else if (prop.name === 'title' && !this.meta.props.find((prop) => prop.name === 'name')) {\n\t\t\toptions.adminUIOptions = { summaryField: true };\n\t\t}\n\t}\n\n\tprotected getManyToManyDecoratorOptions(options: Dictionary, prop: EntityProperty) {\n\t\tthis.entityImports.add(prop.type);\n\t\toptions.relatedField = this.quote(pluralize(pascalToCamelCaseString(this.meta.className)));\n\t}\n\n\tprotected getOneToManyDecoratorOptions(options: Dictionary, prop: EntityProperty) {\n\t\tthis.entityImports.add(prop.type);\n\t\toptions.relatedField = this.quote(prop.mappedBy);\n\t}\n\n\tprotected getForeignKeyDecoratorOptions(options: Dictionary, prop: EntityProperty) {\n\t\tthis.entityImports.add(prop.type);\n\n\t\tconst relatedEntity = this.entityLookup.get(prop.type);\n\t\tif (!relatedEntity) {\n\t\t\tthrow new Error(\n\t\t\t\t`Internal Error: Related entity ${prop.type} should exist but could not be found in the entity lookup.`\n\t\t\t);\n\t\t}\n\t\tif (!isEntityWithSinglePrimaryKey(relatedEntity)) {\n\t\t\tthrow new Error(`Composite primary keys are not supported.`);\n\t\t}\n\t\tconst [primaryKey] = relatedEntity.getPrimaryProps();\n\n\t\toptions.id = `(entity) => entity.${prop.name}?.${primaryKey.name}`;\n\t}\n\n\tprotected getDecoratorType(prop: EntityProperty): string {\n\t\tif ([ReferenceKind.ONE_TO_ONE, ReferenceKind.MANY_TO_ONE].includes(prop.kind)) {\n\t\t\tthis.coreImports.add('RelationshipField');\n\t\t\treturn `@RelationshipField<${this.meta.className}>`;\n\t\t}\n\n\t\tif ([ReferenceKind.ONE_TO_MANY, ReferenceKind.MANY_TO_MANY].includes(prop.kind)) {\n\t\t\tthis.coreImports.add('RelationshipField');\n\t\t\treturn `@RelationshipField<${prop.type}>`;\n\t\t}\n\n\t\tthis.coreImports.add('Field');\n\t\treturn '@Field';\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type {\n\tDictionary,\n\tEntityMetadata,\n\tEntityProperty,\n\tNamingStrategy,\n\tPlatform,\n} from '@mikro-orm/core';\nimport { ReferenceKind, Utils } from '@mikro-orm/core';\nimport pluralize from 'pluralize';\nimport { identifierForEnumValue, pascalToCamelCaseString, pascalToKebabCaseString } from '../utils';\nimport { BaseFile } from './base-file';\nimport { DatabaseType } from '../../database';\nimport { isEntityWithSinglePrimaryKey } from '../generate';\n\nconst friendlyNameForDatabaseType = (type: DatabaseType) => {\n\tif (type === 'mssql') return 'SQL Server';\n\tif (type === 'mysql') return 'MySQL';\n\tif (type === 'postgresql') return 'PostgreSQL';\n\tif (type === 'sqlite') return 'SQLite';\n\n\tthrow new Error('Unimplemented database type: ' + type);\n};\n\nexport class SchemaEntityFile extends BaseFile {\n\tprotected readonly coreImports = new Set<string>();\n\tprotected readonly scalarImports = new Set<string>();\n\tprotected readonly entityImports = new Set<string>();\n\tprotected readonly enumImports = new Set<string>();\n\tpublic readonly errors: string[] = [];\n\n\tconstructor(\n\t\tprotected readonly meta: EntityMetadata,\n\t\tprotected readonly namingStrategy: NamingStrategy,\n\t\tprotected readonly platform: Platform,\n\t\tprotected readonly databaseType: DatabaseType,\n\t\tprotected readonly entityLookup: Map<string, EntityMetadata<any>>,\n\t\tprotected readonly clientGeneratedPrimaryKeys: boolean,\n\t) {\n\t\tsuper(meta, namingStrategy, platform);\n\t}\n\n\tgetBasePath() {\n\t\treturn `backend/schema/`;\n\t}\n\n\tgetBaseName() {\n\t\tconst fileName = pascalToKebabCaseString(this.meta.className);\n\t\treturn `${fileName}.ts`;\n\t}\n\n\tgenerate(): string {\n\t\tconst enumDefinitions: string[] = [];\n\t\tlet classBody = '';\n\t\tconst generatedPropertyNames = new Set<string>();\n\t\tconst props = Object.values(this.meta.properties);\n\t\tprops.forEach((prop) => {\n\t\t\tconst relatedEntity = this.entityLookup.get(prop.type);\n\t\t\tif (relatedEntity) {\n\t\t\t\t// These are not supported yet, just skip them.\n\t\t\t\tif (!isEntityWithSinglePrimaryKey(relatedEntity)) {\n\t\t\t\t\tthis.errors.push(\n\t\t\t\t\t\t` - Warning: Composite primary keys are not supported. ${this.meta.className} entity references ${prop.type} entity with composite primary key.`\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (generatedPropertyNames.has(prop.name)) {\n\t\t\t\tthis.errors.push(\n\t\t\t\t\t` - Warning: Property ${prop.name} on ${this.meta.className} entity is not unique. Additional instances of this property were ignored.`\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tgeneratedPropertyNames.add(prop.name);\n\n\t\t\tconst decorator = this.getPropertyDecorator(prop);\n\t\t\tconst definition = this.getPropertyDefinition(prop);\n\n\t\t\tif (classBody && !classBody.endsWith('\\n\\n')) {\n\t\t\t\tclassBody += '\\n';\n\t\t\t}\n\n\t\t\tclassBody += decorator;\n\t\t\tclassBody += definition;\n\n\t\t\tif (props[props.length - 1] !== prop) classBody += '\\n';\n\n\t\t\tif (prop.enum) {\n\t\t\t\tconst enumClassName = this.namingStrategy.getClassName(\n\t\t\t\t\tthis.meta.collection + '_' + prop.fieldNames[0],\n\t\t\t\t\t'_'\n\t\t\t\t);\n\t\t\t\tenumDefinitions.push(this.getEnumClassDefinition(enumClassName));\n\t\t\t}\n\t\t});\n\n\t\tlet file = '';\n\n\t\tif (enumDefinitions.length) {\n\t\t\tfile += enumDefinitions.join('\\n');\n\t\t\tfile += '\\n\\n';\n\t\t}\n\n\t\tthis.coreImports.add('Entity');\n\n\t\tfile += `@Entity<${this.meta.className}>(${this.quote(this.meta.className)}, {\\n\\tprovider: new MikroBackendProvider(Orm${this.meta.className}, connection, { backendDisplayName: '${friendlyNameForDatabaseType(this.databaseType)}'})`;\n\n\t\tif ((props.length === 1 && props[0].primary) || this.clientGeneratedPrimaryKeys) {\n\t\t\t// Special case. If there's a single primary key field in this entity, right now that requires that it's a client side generated primary key.\n\t\t\t// There's no reason this has to be the case, but it's a current limitation, so we should generate a working project for them.\n\t\t\t// We should be able to remove this in the future and allow users to use it both ways.\n\t\t\tfile += `,\\n\\tapiOptions: { clientGeneratedPrimaryKeys: true },\\n})\\n`;\n\t\t} else {\n\t\t\tfile += `\\n})\\n`;\n\t\t}\n\n\t\tfile += `export class ${this.meta.className} {\\n`;\n\t\tfile += `${classBody}}\\n`;\n\t\tconst imports = [\n\t\t\t`import { ${[...this.coreImports].sort().join(', ')} } from '@exogee/graphweaver';`,\n\t\t];\n\n\t\tif (this.scalarImports.size > 0) {\n\t\t\timports.push(\n\t\t\t\t`import { ${[...this.scalarImports]\n\t\t\t\t\t.sort()\n\t\t\t\t\t.join(', ')} } from '@exogee/graphweaver-scalars';`\n\t\t\t);\n\t\t}\n\n\t\timports.push(`import { MikroBackendProvider } from '@exogee/graphweaver-mikroorm';`);\n\n\t\tconst entityImports = [...this.entityImports].filter((e) => e !== this.meta.className);\n\t\tentityImports.sort().forEach((entity) => {\n\t\t\timports.push(`import { ${entity} } from './${pascalToKebabCaseString(entity)}';`);\n\t\t});\n\n\t\timports.push(\n\t\t\t`import { ${this.enumImports.size > 0 ? [...this.enumImports].sort().join(', ') + ', ' : ''}${\n\t\t\t\tthis.meta.className\n\t\t\t} as Orm${this.meta.className} } from '../entities';`,\n\t\t\t`import { connection } from '../database';`\n\t\t);\n\n\t\tfile = `${imports.join('\\n')}\\n\\n${file}`;\n\n\t\treturn file;\n\t}\n\n\tprotected getTypescriptPropertyType(prop: EntityProperty): string {\n\t\tif ([ReferenceKind.ONE_TO_ONE, ReferenceKind.MANY_TO_ONE].includes(prop.kind)) {\n\t\t\treturn prop.type.charAt(0).toUpperCase() + prop.type.slice(1);\n\t\t}\n\n\t\tif (['jsonb', 'json', 'any'].includes(prop.columnTypes?.[0])) {\n\t\t\treturn `Record<string, unknown>`;\n\t\t}\n\n\t\tif (prop.columnTypes?.[0] === 'date') {\n\t\t\treturn 'Date';\n\t\t}\n\n\t\tif (prop.type === 'unknown') {\n\t\t\t//fallback to string if unknown\n\t\t\treturn 'string';\n\t\t}\n\n\t\tif (prop.type === 'bigint') {\n\t\t\treturn 'string';\n\t\t}\n\n\t\treturn prop.runtimeType;\n\t}\n\n\tprotected getPropertyDefinition(prop: EntityProperty): string {\n\t\tconst padding = '\\t';\n\n\t\tif ([ReferenceKind.ONE_TO_MANY, ReferenceKind.MANY_TO_MANY].includes(prop.kind)) {\n\t\t\tthis.entityImports.add(prop.type);\n\t\t\treturn `${padding}${prop.name}!: ${prop.type}[];\\n`;\n\t\t}\n\n\t\t// string defaults are usually things like SQL functions, but can be also enums, for that `useDefault` should be true\n\t\tconst isEnumOrNonStringDefault = prop.enum || typeof prop.default !== 'string';\n\t\tconst useDefault = prop.default != null && isEnumOrNonStringDefault;\n\t\tconst optional = prop.nullable ? '?' : useDefault ? '' : '!';\n\n\t\tconst file = `${prop.name}${optional}: ${this.getTypescriptPropertyType(prop)}`;\n\n\t\tif (!useDefault) {\n\t\t\treturn `${padding + file};\\n`;\n\t\t}\n\n\t\tif (prop.enum && typeof prop.default === 'string') {\n\t\t\treturn `${padding}${file} = ${prop.runtimeType}.${identifierForEnumValue(prop.default)};\\n`;\n\t\t}\n\n\t\treturn `${padding}${prop.name} = ${prop.default};\\n`;\n\t}\n\n\tprotected getEnumClassDefinition(enumClassName: string): string {\n\t\tthis.coreImports.add('graphweaverMetadata');\n\t\tthis.enumImports.add(enumClassName);\n\t\treturn `graphweaverMetadata.collectEnumInformation({ target: ${enumClassName}, name: ${this.quote(enumClassName)} });`;\n\t}\n\n\tprivate getGraphQLPropertyType(prop: EntityProperty): string {\n\t\tif (prop.primary) {\n\t\t\tthis.coreImports.add('ID');\n\t\t\treturn 'ID';\n\t\t}\n\n\t\tif (prop.runtimeType === 'Date') {\n\t\t\tthis.scalarImports.add('ISODateStringScalar');\n\t\t\treturn 'ISODateStringScalar';\n\t\t}\n\n\t\tif (prop.columnTypes?.[0] === 'date') {\n\t\t\tthis.scalarImports.add('DateScalar');\n\t\t\treturn 'DateScalar';\n\t\t}\n\n\t\tif (prop.runtimeType === 'unknown') {\n\t\t\treturn 'String';\n\t\t}\n\n\t\tif (prop.runtimeType === 'bigint') {\n\t\t\tthis.scalarImports.add('GraphQLBigInt');\n\t\t\treturn 'GraphQLBigInt';\n\t\t}\n\n\t\tif (prop.runtimeType === 'Buffer') {\n\t\t\tthis.scalarImports.add('GraphQLByte');\n\t\t\treturn 'GraphQLByte';\n\t\t}\n\n\t\tif (['jsonb', 'json', 'any'].includes(prop.columnTypes?.[0])) {\n\t\t\tthis.scalarImports.add('GraphQLJSON');\n\t\t\treturn `GraphQLJSON`;\n\t\t}\n\n\t\tif (prop.runtimeType?.includes('[]')) {\n\t\t\treturn `[${prop.type.charAt(0).toUpperCase() + prop.type.slice(1).replace('[]', '')}]`;\n\t\t}\n\n\t\tif ([ReferenceKind.ONE_TO_ONE, ReferenceKind.MANY_TO_ONE].includes(prop.kind)) {\n\t\t\treturn prop.type.charAt(0).toUpperCase() + prop.type.slice(1);\n\t\t}\n\n\t\tif ([ReferenceKind.MANY_TO_MANY, ReferenceKind.ONE_TO_MANY].includes(prop.kind)) {\n\t\t\treturn `[${prop.type.charAt(0).toUpperCase() + prop.type.slice(1).replace('[]', '')}]`;\n\t\t}\n\n\t\tif (prop.pivotTable) {\n\t\t\treturn `[${prop.type.charAt(0).toUpperCase() + prop.type.slice(1)}]`;\n\t\t}\n\n\t\tconst lastChanceType = prop.runtimeType ?? prop.type;\n\n\t\tif (!lastChanceType) {\n\t\t\tconsole.error(`Property is malformed, it has no type or runtimeType:`, prop);\n\t\t\tthrow new Error(`Property ${prop.name} on ${prop.entity} entity has no type or runtimeType.`);\n\t\t}\n\n\t\treturn lastChanceType.charAt(0).toUpperCase() + lastChanceType.slice(1);\n\t}\n\n\tprivate getPropertyDecorator(prop: EntityProperty): string {\n\t\tconst padding = '\\t';\n\t\tconst options = {} as Dictionary;\n\t\tlet decorator = this.getDecoratorType(prop);\n\n\t\tif (prop.kind === ReferenceKind.MANY_TO_MANY) {\n\t\t\tthis.getManyToManyDecoratorOptions(options, prop);\n\t\t} else if (prop.kind === ReferenceKind.ONE_TO_MANY) {\n\t\t\tthis.getOneToManyDecoratorOptions(options, prop);\n\t\t} else if (prop.kind !== ReferenceKind.SCALAR) {\n\t\t\tthis.getForeignKeyDecoratorOptions(options, prop);\n\t\t}\n\n\t\tthis.getCommonDecoratorOptions(options, prop);\n\t\tdecorator = [decorator].map((d) => padding + d).join('\\n');\n\n\t\tif (!Utils.hasObjectKeys(options)) {\n\t\t\treturn `${decorator}(() => ${this.getGraphQLPropertyType(prop)})\\n`;\n\t\t}\n\n\t\treturn `${decorator}(() => ${this.getGraphQLPropertyType(prop)}, { ${Object.entries(options)\n\t\t\t.map(([opt, val]) => `${opt}: ${JSON.stringify(val).replaceAll('\"', '')}`)\n\t\t\t.join(', ')} })\\n`;\n\t}\n\n\tprotected getCommonDecoratorOptions(options: Dictionary, prop: EntityProperty): void {\n\t\t// Owning side: use the FK's nullability\n\t\t// Non-owning side of 1:1 is always nullable because we aren't guaranteed to have a row for every single\n\t\t// entity created on the non-owning side of the relationship.\n\t\tif (\n\t\t\t(prop.nullable && !prop.mappedBy) ||\n\t\t\t(prop.mappedBy && prop.kind === ReferenceKind.ONE_TO_ONE)\n\t\t) {\n\t\t\toptions.nullable = true;\n\t\t}\n\n\t\tif (prop.primary) {\n\t\t\toptions.primaryKeyField = true;\n\t\t}\n\n\t\t// If there's a property called 'name' it should be the summary field. If not, and there's a field called 'title'\n\t\t// then it should be the summary field.\n\t\tif (prop.name === 'name') {\n\t\t\toptions.adminUIOptions = { summaryField: true };\n\t\t} else if (prop.name === 'title' && !this.meta.props.find((prop) => prop.name === 'name')) {\n\t\t\toptions.adminUIOptions = { summaryField: true };\n\t\t}\n\t}\n\n\tprotected getManyToManyDecoratorOptions(options: Dictionary, prop: EntityProperty) {\n\t\tthis.entityImports.add(prop.type);\n\t\toptions.relatedField = this.quote(pluralize(pascalToCamelCaseString(this.meta.className)));\n\t}\n\n\tprotected getOneToManyDecoratorOptions(options: Dictionary, prop: EntityProperty) {\n\t\tthis.entityImports.add(prop.type);\n\t\toptions.relatedField = this.quote(prop.mappedBy);\n\t}\n\n\tprotected getForeignKeyDecoratorOptions(options: Dictionary, prop: EntityProperty) {\n\t\tthis.entityImports.add(prop.type);\n\n\t\tconst relatedEntity = this.entityLookup.get(prop.type);\n\t\tif (!relatedEntity) {\n\t\t\tthrow new Error(\n\t\t\t\t`Internal Error: Related entity ${prop.type} should exist but could not be found in the entity lookup.`\n\t\t\t);\n\t\t}\n\t\tif (!isEntityWithSinglePrimaryKey(relatedEntity)) {\n\t\t\tthrow new Error(`Composite primary keys are not supported.`);\n\t\t}\n\t\tconst [primaryKey] = relatedEntity.getPrimaryProps();\n\n\t\toptions.id = `(entity) => entity.${prop.name}?.${primaryKey.name}`;\n\t}\n\n\tprotected getDecoratorType(prop: EntityProperty): string {\n\t\tif ([ReferenceKind.ONE_TO_ONE, ReferenceKind.MANY_TO_ONE].includes(prop.kind)) {\n\t\t\tthis.coreImports.add('RelationshipField');\n\t\t\treturn `@RelationshipField<${this.meta.className}>`;\n\t\t}\n\n\t\tif ([ReferenceKind.ONE_TO_MANY, ReferenceKind.MANY_TO_MANY].includes(prop.kind)) {\n\t\t\tthis.coreImports.add('RelationshipField');\n\t\t\treturn `@RelationshipField<${prop.type}>`;\n\t\t}\n\n\t\tthis.coreImports.add('Field');\n\t\treturn '@Field';\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["prop", "pluralize"]
7
7
  }
@@ -6,7 +6,10 @@ export declare class IntrospectionError extends Error {
6
6
  constructor(title?: string, message?: string);
7
7
  }
8
8
  export declare const isEntityWithSinglePrimaryKey: (meta?: EntityMetadata) => boolean;
9
- export declare const generate: (databaseType: DatabaseType, options: ConnectionOptions) => Promise<{
9
+ export interface APIOptions {
10
+ clientGeneratedPrimaryKeys?: boolean;
11
+ }
12
+ export declare const generate: (databaseType: DatabaseType, options: ConnectionOptions, apiOptions?: APIOptions) => Promise<{
10
13
  path: string;
11
14
  name: string;
12
15
  contents: string;
@@ -189,7 +189,7 @@ const isEntityWithSinglePrimaryKey = (meta) => {
189
189
  if (!meta) return false;
190
190
  return meta.primaryKeys.length === 1;
191
191
  };
192
- const generate = async (databaseType, options) => {
192
+ const generate = async (databaseType, options, apiOptions) => {
193
193
  try {
194
194
  await openConnection(databaseType, options);
195
195
  const database = import_database.ConnectionManager.database(CONNECTION_MANAGER_ID);
@@ -227,7 +227,8 @@ const generate = async (databaseType, options) => {
227
227
  namingStrategy,
228
228
  platform,
229
229
  databaseType,
230
- entityLookup
230
+ entityLookup,
231
+ apiOptions?.clientGeneratedPrimaryKeys ?? false
231
232
  );
232
233
  source.push(dataEntityFile, schemaEntityFile);
233
234
  summaryOfEntities.push({
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/introspection/generate.ts"],
4
- "sourcesContent": ["import { DatabaseSchema, AbstractSqlPlatform } from '@mikro-orm/knex';\nimport {\n\tEntityMetadata,\n\tEntityProperty,\n\tNamingStrategy,\n\tReferenceKind,\n\tUtils,\n} from '@mikro-orm/core';\nimport pluralize from 'pluralize';\n\nimport { ConnectionManager, ConnectionOptions, DatabaseType } from '../database';\nimport {\n\tDataEntityFile,\n\tDataEntityIndexFile,\n\tDataSourceIndexFile,\n\tSchemaEntityFile,\n\tSchemaIndexFile,\n\tDatabaseFile,\n} from './files';\nimport { pascalToCamelCaseString } from './utils';\n\nconst CONNECTION_MANAGER_ID = 'generate';\n\nexport class IntrospectionError extends Error {\n\tprotected type: string;\n\tconstructor(\n\t\tprotected title = '',\n\t\tmessage = ''\n\t) {\n\t\tsuper(message);\n\t\tthis.type = 'IntrospectionError';\n\t\tthis.title = title;\n\t\tthis.message = message;\n\t}\n}\n\nconst hasErrorMessage = (error: any): error is { message: string } => error.message;\n\nconst generateBidirectionalRelations = (metadata: EntityMetadata[]) => {\n\tconst nonPrimaryKeyReferenceErrors: string[] = [];\n\n\tfor (const meta of metadata.filter((m) => !m.pivotTable)) {\n\t\tfor (const prop of meta.relations) {\n\t\t\tif (!prop.name.includes('Inverse')) {\n\t\t\t\tconst targetMeta = metadata.find((m) => m.className === prop.type);\n\t\t\t\tconst referencedTablePrimaryKeys = Utils.flatten(\n\t\t\t\t\t(targetMeta?.getPrimaryProps() ?? []).map((pk) => pk.fieldNames)\n\t\t\t\t);\n\n\t\t\t\t// Check any props that actually have fields in the database to store keys in for references to non-primary keys.\n\t\t\t\tif (prop.fieldNames?.length) {\n\t\t\t\t\tfor (const referencedColumn of prop.referencedColumnNames) {\n\t\t\t\t\t\tif (!referencedTablePrimaryKeys.includes(referencedColumn)) {\n\t\t\t\t\t\t\tnonPrimaryKeyReferenceErrors.push(\n\t\t\t\t\t\t\t\t` - Relationship between ${meta.className}.${prop.fieldNames.join(', ')} and ${targetMeta?.className}.${referencedColumn} is not supported.`\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst newProp = {\n\t\t\t\t\tname: prop.name + 'Inverse',\n\t\t\t\t\ttype: meta.className,\n\t\t\t\t\tjoinColumns: prop.fieldNames,\n\t\t\t\t\treferencedTableName: meta.tableName,\n\t\t\t\t\treferencedColumnNames: referencedTablePrimaryKeys,\n\t\t\t\t\tmappedBy: prop.name,\n\t\t\t\t} as EntityProperty;\n\n\t\t\t\t// Add reference to the inverse entity\n\t\t\t\tconst inverseMeta = metadata.find((m) => m.className === meta.className);\n\t\t\t\tconst inverseProp = inverseMeta?.props.find((p) => p.name === newProp.mappedBy);\n\t\t\t\tif (inverseProp) inverseProp.inversedBy = newProp.name;\n\n\t\t\t\tif (prop.kind === ReferenceKind.MANY_TO_ONE) {\n\t\t\t\t\tconst name = pascalToCamelCaseString(meta.className);\n\t\t\t\t\tnewProp.name = pluralize(name);\n\t\t\t\t\tnewProp.kind = ReferenceKind.ONE_TO_MANY;\n\t\t\t\t} else if (prop.kind === ReferenceKind.ONE_TO_ONE && !prop.mappedBy) {\n\t\t\t\t\tnewProp.kind = ReferenceKind.ONE_TO_ONE;\n\t\t\t\t\tnewProp.nullable = true;\n\t\t\t\t} else if (prop.kind === ReferenceKind.MANY_TO_MANY && !prop.mappedBy) {\n\t\t\t\t\tconst name = pascalToCamelCaseString(meta.className);\n\t\t\t\t\tnewProp.name = pluralize(name);\n\t\t\t\t\tnewProp.kind = ReferenceKind.MANY_TO_MANY;\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\ttargetMeta?.addProperty(newProp);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { errors: nonPrimaryKeyReferenceErrors };\n};\n\nconst detectManyToManyRelations = (metadata: EntityMetadata[]) => {\n\tfor (const meta of metadata) {\n\t\tif (\n\t\t\tmeta.compositePK && // needs to have composite PK\n\t\t\tmeta.primaryKeys.length === meta.relations.length && // all relations are PKs\n\t\t\tmeta.relations.length === 2 && // there are exactly two relation properties\n\t\t\tmeta.relations.length === meta.props.length && // all properties are relations\n\t\t\tmeta.relations.every((prop) => prop.kind === ReferenceKind.MANY_TO_ONE) // all relations are m:1\n\t\t) {\n\t\t\tmeta.pivotTable = true;\n\t\t\tconst owner = metadata.find((m) => m.className === meta.relations[0].type);\n\t\t\tif (!owner) throw new Error('No Owner');\n\t\t\tconst name = pascalToCamelCaseString(meta.relations?.[1]?.type);\n\t\t\towner.addProperty({\n\t\t\t\tname: pluralize(name),\n\t\t\t\tkind: ReferenceKind.MANY_TO_MANY,\n\t\t\t\tpivotTable: meta.tableName,\n\t\t\t\ttype: meta.relations[1].type,\n\t\t\t\tjoinColumns: meta.relations[0].fieldNames,\n\t\t\t\tinverseJoinColumns: meta.relations[1].fieldNames,\n\t\t\t} as EntityProperty);\n\t\t}\n\t}\n};\n\nconst generateIdentifiedReferences = (metadata: EntityMetadata[]): void => {\n\tfor (const meta of metadata.filter((m) => !m.pivotTable)) {\n\t\tfor (const prop of meta.relations) {\n\t\t\tif ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind)) {\n\t\t\t\tconst name = pascalToCamelCaseString(prop.type);\n\t\t\t\tprop.name = pluralize.singular(name);\n\t\t\t\tprop.ref = true;\n\t\t\t}\n\t\t}\n\t}\n};\n\nconst generateSingularTypeReferences = (metadata: EntityMetadata[]): void => {\n\tfor (const meta of metadata.filter((m) => !m.pivotTable)) {\n\t\tmeta.className = pluralize.singular(meta.className);\n\t\tfor (const prop of meta.relations) {\n\t\t\tprop.type = pluralize.singular(prop.type);\n\t\t}\n\t}\n};\n\n// Convert properties like FirstName to firstName\nconst normalisePropertyNames = (metadata: EntityMetadata[]): void => {\n\tfor (const meta of metadata.filter((m) => !m.pivotTable)) {\n\t\tconst props = Object.values(meta.properties);\n\t\tprops.forEach((prop) => {\n\t\t\tprop.name = pascalToCamelCaseString(prop.name).replace(/\\W/g, '_');\n\t\t});\n\t}\n};\n\nconst convertSchemaToMetadata = async (\n\tschema: DatabaseSchema,\n\tplatform: AbstractSqlPlatform,\n\tnamingStrategy: NamingStrategy\n) => {\n\tconst helper = platform.getSchemaHelper();\n\n\tif (!helper) throw new Error('cannot connect to database');\n\n\tconst metadata = schema\n\t\t.getTables()\n\t\t.sort((a, b) => a.name.localeCompare(b.name))\n\t\t.map((table) => table.getEntityDeclaration(namingStrategy, helper, 'never'));\n\n\tif (metadata.length === 0) {\n\t\tthrow new IntrospectionError(\n\t\t\t`Warning: No tables found, this database is empty.`,\n\t\t\t`Make sure you have tables in this database and then try again.`\n\t\t);\n\t}\n\n\tnormalisePropertyNames(metadata);\n\tdetectManyToManyRelations(metadata);\n\tgenerateIdentifiedReferences(metadata);\n\tconst { errors } = generateBidirectionalRelations(metadata);\n\tgenerateSingularTypeReferences(metadata);\n\n\treturn { metadata, errors };\n};\n\nconst openConnection = async (type: DatabaseType, options: ConnectionOptions) => {\n\t// eslint-disable-next-line @typescript-eslint/no-require-imports\n\tconst module = require(`@mikro-orm/${type}`);\n\tconst PLATFORMS = {\n\t\tmssql: 'MsSqlDriver',\n\t\tmysql: 'MySqlDriver',\n\t\tpostgresql: 'PostgreSqlDriver',\n\t\tsqlite: 'SqliteDriver',\n\t};\n\tawait ConnectionManager.connect(CONNECTION_MANAGER_ID, {\n\t\tmikroOrmConfig: {\n\t\t\tdriver: module[PLATFORMS[type]],\n\t\t\t...options.mikroOrmConfig,\n\t\t},\n\t});\n};\n\nconst closeConnection = async () => {\n\tconsole.log('Closing database connection...');\n\tawait ConnectionManager.close(CONNECTION_MANAGER_ID);\n\tconsole.log('Database connection closed.');\n};\n\ntype File =\n\t| DataEntityFile\n\t| SchemaEntityFile\n\t| SchemaIndexFile\n\t| DataEntityIndexFile\n\t| DataSourceIndexFile\n\t| DatabaseFile;\n\nexport const isEntityWithSinglePrimaryKey = (meta?: EntityMetadata) => {\n\tif (!meta) return false;\n\treturn meta.primaryKeys.length === 1;\n};\n\nexport const generate = async (databaseType: DatabaseType, options: ConnectionOptions) => {\n\ttry {\n\t\tawait openConnection(databaseType, options);\n\n\t\tconst database = ConnectionManager.database(CONNECTION_MANAGER_ID);\n\t\tif (!database)\n\t\t\tthrow new IntrospectionError(\n\t\t\t\t`Warning: Unable to connect to database.`,\n\t\t\t\t'Please check the connection settings and try again'\n\t\t\t);\n\n\t\tconst config = database.em.config;\n\t\tconst driver = database.em.getDriver();\n\t\tconst platform = driver.getPlatform();\n\t\tconst namingStrategy = config.getNamingStrategy();\n\t\tconst connection = driver.getConnection();\n\n\t\tconsole.log('Fetching database schema...');\n\t\tconst schema = await DatabaseSchema.create(connection, platform, config);\n\t\tconsole.log('Building metadata...');\n\t\tconst { metadata, errors } = await convertSchemaToMetadata(schema, platform, namingStrategy);\n\n\t\t// Build a lookup for efficient cross-referencing later.\n\t\tconst entityLookup = new Map<string, EntityMetadata<any>>();\n\t\tfor (const meta of metadata) {\n\t\t\tentityLookup.set(meta.className, meta);\n\t\t}\n\n\t\tconst source: File[] = [];\n\n\t\tconst summaryOfEntities: { name: string; entityFilePath: string; schemaFilePath: string }[] =\n\t\t\t[];\n\n\t\tfor (const meta of metadata) {\n\t\t\tif (!meta.pivotTable && isEntityWithSinglePrimaryKey(meta)) {\n\t\t\t\tconst dataEntityFile = new DataEntityFile(\n\t\t\t\t\tmeta,\n\t\t\t\t\tnamingStrategy,\n\t\t\t\t\tplatform,\n\t\t\t\t\tdatabaseType,\n\t\t\t\t\tentityLookup\n\t\t\t\t);\n\t\t\t\tconst schemaEntityFile = new SchemaEntityFile(\n\t\t\t\t\tmeta,\n\t\t\t\t\tnamingStrategy,\n\t\t\t\t\tplatform,\n\t\t\t\t\tdatabaseType,\n\t\t\t\t\tentityLookup\n\t\t\t\t);\n\t\t\t\tsource.push(dataEntityFile, schemaEntityFile);\n\t\t\t\tsummaryOfEntities.push({\n\t\t\t\t\tname: meta.className,\n\t\t\t\t\tentityFilePath: `${dataEntityFile.getBasePath()}${dataEntityFile.getBaseName()}`,\n\t\t\t\t\tschemaFilePath: `${schemaEntityFile.getBasePath()}${schemaEntityFile.getBaseName()}`,\n\t\t\t\t});\n\t\t\t} else if (meta.primaryKeys.length > 1) {\n\t\t\t\terrors.push(\n\t\t\t\t\t`Entity ${meta.className} has either more than one primary key. We have skipped it and relations to it because Graphweaver does not support entities with multiple primary keys yet.`\n\t\t\t\t);\n\t\t\t} else if (meta.primaryKeys.length === 0) {\n\t\t\t\terrors.push(\n\t\t\t\t\t`Entity ${meta.className} has no primary key. We have skipped it and relations to it because Graphweaver does not support entities with no primary key yet.`\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Export all the entities from the data source directory\n\t\tsource.push(new DataEntityIndexFile(metadata, databaseType));\n\t\t// Export the data source from the entities directory\n\t\tsource.push(new DataSourceIndexFile(databaseType));\n\t\t// Export the data source from the entities directory\n\t\tsource.push(new SchemaIndexFile(metadata));\n\t\t// Export the database connection to its own file\n\t\tsource.push(new DatabaseFile(databaseType, options));\n\n\t\tconst files = source.map((file) => {\n\t\t\treturn {\n\t\t\t\tpath: file.getBasePath(),\n\t\t\t\tname: file.getBaseName(),\n\t\t\t\tcontents: file.generate(),\n\t\t\t\tneedOverwriteWarning: !![DatabaseFile, SchemaIndexFile].some((cls) => file instanceof cls),\n\t\t\t\terrors: 'errors' in file ? file.errors : [],\n\t\t\t};\n\t\t});\n\n\t\tawait closeConnection();\n\n\t\tconsole.log('\\nImport Summary:');\n\t\tconsole.table(summaryOfEntities);\n\t\tconsole.log(\n\t\t\t`\\nImported ${summaryOfEntities.length} entities, creating the above files in your Graphweaver project. \\n`\n\t\t);\n\n\t\tfor (const file of files) {\n\t\t\terrors.push(...file.errors);\n\t\t}\n\n\t\tif (errors.length) {\n\t\t\tconsole.log(`\\nWarning ${errors.length} errors detected:\\n`);\n\t\t\tconsole.log(errors.join('\\n'));\n\t\t}\n\n\t\treturn files;\n\t} catch (err) {\n\t\tif (err instanceof IntrospectionError) throw err;\n\n\t\tconsole.error('Got error during introspection:');\n\t\tconsole.error(err);\n\n\t\tthrow new IntrospectionError(\n\t\t\t`Warning: Unable to connect to database.`,\n\t\t\thasErrorMessage(err) ? err.message : 'Please check the connection settings and try again'\n\t\t);\n\t}\n};\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { DatabaseSchema, AbstractSqlPlatform } from '@mikro-orm/knex';\nimport {\n\tEntityMetadata,\n\tEntityProperty,\n\tNamingStrategy,\n\tReferenceKind,\n\tUtils,\n} from '@mikro-orm/core';\nimport pluralize from 'pluralize';\n\nimport { ConnectionManager, ConnectionOptions, DatabaseType } from '../database';\nimport {\n\tDataEntityFile,\n\tDataEntityIndexFile,\n\tDataSourceIndexFile,\n\tSchemaEntityFile,\n\tSchemaIndexFile,\n\tDatabaseFile,\n} from './files';\nimport { pascalToCamelCaseString } from './utils';\n\nconst CONNECTION_MANAGER_ID = 'generate';\n\nexport class IntrospectionError extends Error {\n\tprotected type: string;\n\tconstructor(\n\t\tprotected title = '',\n\t\tmessage = ''\n\t) {\n\t\tsuper(message);\n\t\tthis.type = 'IntrospectionError';\n\t\tthis.title = title;\n\t\tthis.message = message;\n\t}\n}\n\nconst hasErrorMessage = (error: any): error is { message: string } => error.message;\n\nconst generateBidirectionalRelations = (metadata: EntityMetadata[]) => {\n\tconst nonPrimaryKeyReferenceErrors: string[] = [];\n\n\tfor (const meta of metadata.filter((m) => !m.pivotTable)) {\n\t\tfor (const prop of meta.relations) {\n\t\t\tif (!prop.name.includes('Inverse')) {\n\t\t\t\tconst targetMeta = metadata.find((m) => m.className === prop.type);\n\t\t\t\tconst referencedTablePrimaryKeys = Utils.flatten(\n\t\t\t\t\t(targetMeta?.getPrimaryProps() ?? []).map((pk) => pk.fieldNames)\n\t\t\t\t);\n\n\t\t\t\t// Check any props that actually have fields in the database to store keys in for references to non-primary keys.\n\t\t\t\tif (prop.fieldNames?.length) {\n\t\t\t\t\tfor (const referencedColumn of prop.referencedColumnNames) {\n\t\t\t\t\t\tif (!referencedTablePrimaryKeys.includes(referencedColumn)) {\n\t\t\t\t\t\t\tnonPrimaryKeyReferenceErrors.push(\n\t\t\t\t\t\t\t\t` - Relationship between ${meta.className}.${prop.fieldNames.join(', ')} and ${targetMeta?.className}.${referencedColumn} is not supported.`\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst newProp = {\n\t\t\t\t\tname: prop.name + 'Inverse',\n\t\t\t\t\ttype: meta.className,\n\t\t\t\t\tjoinColumns: prop.fieldNames,\n\t\t\t\t\treferencedTableName: meta.tableName,\n\t\t\t\t\treferencedColumnNames: referencedTablePrimaryKeys,\n\t\t\t\t\tmappedBy: prop.name,\n\t\t\t\t} as EntityProperty;\n\n\t\t\t\t// Add reference to the inverse entity\n\t\t\t\tconst inverseMeta = metadata.find((m) => m.className === meta.className);\n\t\t\t\tconst inverseProp = inverseMeta?.props.find((p) => p.name === newProp.mappedBy);\n\t\t\t\tif (inverseProp) inverseProp.inversedBy = newProp.name;\n\n\t\t\t\tif (prop.kind === ReferenceKind.MANY_TO_ONE) {\n\t\t\t\t\tconst name = pascalToCamelCaseString(meta.className);\n\t\t\t\t\tnewProp.name = pluralize(name);\n\t\t\t\t\tnewProp.kind = ReferenceKind.ONE_TO_MANY;\n\t\t\t\t} else if (prop.kind === ReferenceKind.ONE_TO_ONE && !prop.mappedBy) {\n\t\t\t\t\tnewProp.kind = ReferenceKind.ONE_TO_ONE;\n\t\t\t\t\tnewProp.nullable = true;\n\t\t\t\t} else if (prop.kind === ReferenceKind.MANY_TO_MANY && !prop.mappedBy) {\n\t\t\t\t\tconst name = pascalToCamelCaseString(meta.className);\n\t\t\t\t\tnewProp.name = pluralize(name);\n\t\t\t\t\tnewProp.kind = ReferenceKind.MANY_TO_MANY;\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\ttargetMeta?.addProperty(newProp);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { errors: nonPrimaryKeyReferenceErrors };\n};\n\nconst detectManyToManyRelations = (metadata: EntityMetadata[]) => {\n\tfor (const meta of metadata) {\n\t\tif (\n\t\t\tmeta.compositePK && // needs to have composite PK\n\t\t\tmeta.primaryKeys.length === meta.relations.length && // all relations are PKs\n\t\t\tmeta.relations.length === 2 && // there are exactly two relation properties\n\t\t\tmeta.relations.length === meta.props.length && // all properties are relations\n\t\t\tmeta.relations.every((prop) => prop.kind === ReferenceKind.MANY_TO_ONE) // all relations are m:1\n\t\t) {\n\t\t\tmeta.pivotTable = true;\n\t\t\tconst owner = metadata.find((m) => m.className === meta.relations[0].type);\n\t\t\tif (!owner) throw new Error('No Owner');\n\t\t\tconst name = pascalToCamelCaseString(meta.relations?.[1]?.type);\n\t\t\towner.addProperty({\n\t\t\t\tname: pluralize(name),\n\t\t\t\tkind: ReferenceKind.MANY_TO_MANY,\n\t\t\t\tpivotTable: meta.tableName,\n\t\t\t\ttype: meta.relations[1].type,\n\t\t\t\tjoinColumns: meta.relations[0].fieldNames,\n\t\t\t\tinverseJoinColumns: meta.relations[1].fieldNames,\n\t\t\t} as EntityProperty);\n\t\t}\n\t}\n};\n\nconst generateIdentifiedReferences = (metadata: EntityMetadata[]): void => {\n\tfor (const meta of metadata.filter((m) => !m.pivotTable)) {\n\t\tfor (const prop of meta.relations) {\n\t\t\tif ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind)) {\n\t\t\t\tconst name = pascalToCamelCaseString(prop.type);\n\t\t\t\tprop.name = pluralize.singular(name);\n\t\t\t\tprop.ref = true;\n\t\t\t}\n\t\t}\n\t}\n};\n\nconst generateSingularTypeReferences = (metadata: EntityMetadata[]): void => {\n\tfor (const meta of metadata.filter((m) => !m.pivotTable)) {\n\t\tmeta.className = pluralize.singular(meta.className);\n\t\tfor (const prop of meta.relations) {\n\t\t\tprop.type = pluralize.singular(prop.type);\n\t\t}\n\t}\n};\n\n// Convert properties like FirstName to firstName\nconst normalisePropertyNames = (metadata: EntityMetadata[]): void => {\n\tfor (const meta of metadata.filter((m) => !m.pivotTable)) {\n\t\tconst props = Object.values(meta.properties);\n\t\tprops.forEach((prop) => {\n\t\t\tprop.name = pascalToCamelCaseString(prop.name).replace(/\\W/g, '_');\n\t\t});\n\t}\n};\n\nconst convertSchemaToMetadata = async (\n\tschema: DatabaseSchema,\n\tplatform: AbstractSqlPlatform,\n\tnamingStrategy: NamingStrategy\n) => {\n\tconst helper = platform.getSchemaHelper();\n\n\tif (!helper) throw new Error('cannot connect to database');\n\n\tconst metadata = schema\n\t\t.getTables()\n\t\t.sort((a, b) => a.name.localeCompare(b.name))\n\t\t.map((table) => table.getEntityDeclaration(namingStrategy, helper, 'never'));\n\n\tif (metadata.length === 0) {\n\t\tthrow new IntrospectionError(\n\t\t\t`Warning: No tables found, this database is empty.`,\n\t\t\t`Make sure you have tables in this database and then try again.`\n\t\t);\n\t}\n\n\tnormalisePropertyNames(metadata);\n\tdetectManyToManyRelations(metadata);\n\tgenerateIdentifiedReferences(metadata);\n\tconst { errors } = generateBidirectionalRelations(metadata);\n\tgenerateSingularTypeReferences(metadata);\n\n\treturn { metadata, errors };\n};\n\nconst openConnection = async (type: DatabaseType, options: ConnectionOptions) => {\n\t// eslint-disable-next-line @typescript-eslint/no-require-imports\n\tconst module = require(`@mikro-orm/${type}`);\n\tconst PLATFORMS = {\n\t\tmssql: 'MsSqlDriver',\n\t\tmysql: 'MySqlDriver',\n\t\tpostgresql: 'PostgreSqlDriver',\n\t\tsqlite: 'SqliteDriver',\n\t};\n\tawait ConnectionManager.connect(CONNECTION_MANAGER_ID, {\n\t\tmikroOrmConfig: {\n\t\t\tdriver: module[PLATFORMS[type]],\n\t\t\t...options.mikroOrmConfig,\n\t\t},\n\t});\n};\n\nconst closeConnection = async () => {\n\tconsole.log('Closing database connection...');\n\tawait ConnectionManager.close(CONNECTION_MANAGER_ID);\n\tconsole.log('Database connection closed.');\n};\n\ntype File =\n\t| DataEntityFile\n\t| SchemaEntityFile\n\t| SchemaIndexFile\n\t| DataEntityIndexFile\n\t| DataSourceIndexFile\n\t| DatabaseFile;\n\nexport const isEntityWithSinglePrimaryKey = (meta?: EntityMetadata) => {\n\tif (!meta) return false;\n\treturn meta.primaryKeys.length === 1;\n};\n\nexport interface APIOptions {\n\tclientGeneratedPrimaryKeys?: boolean;\n}\n\nexport const generate = async (databaseType: DatabaseType, options: ConnectionOptions, apiOptions?: APIOptions) => {\n\ttry {\n\t\tawait openConnection(databaseType, options);\n\n\t\tconst database = ConnectionManager.database(CONNECTION_MANAGER_ID);\n\t\tif (!database)\n\t\t\tthrow new IntrospectionError(\n\t\t\t\t`Warning: Unable to connect to database.`,\n\t\t\t\t'Please check the connection settings and try again'\n\t\t\t);\n\n\t\tconst config = database.em.config;\n\t\tconst driver = database.em.getDriver();\n\t\tconst platform = driver.getPlatform();\n\t\tconst namingStrategy = config.getNamingStrategy();\n\t\tconst connection = driver.getConnection();\n\n\t\tconsole.log('Fetching database schema...');\n\t\tconst schema = await DatabaseSchema.create(connection, platform, config);\n\t\tconsole.log('Building metadata...');\n\t\tconst { metadata, errors } = await convertSchemaToMetadata(schema, platform, namingStrategy);\n\n\t\t// Build a lookup for efficient cross-referencing later.\n\t\tconst entityLookup = new Map<string, EntityMetadata<any>>();\n\t\tfor (const meta of metadata) {\n\t\t\tentityLookup.set(meta.className, meta);\n\t\t}\n\n\t\tconst source: File[] = [];\n\n\t\tconst summaryOfEntities: { name: string; entityFilePath: string; schemaFilePath: string }[] =\n\t\t\t[];\n\n\t\tfor (const meta of metadata) {\n\t\t\tif (!meta.pivotTable && isEntityWithSinglePrimaryKey(meta)) {\n\t\t\t\tconst dataEntityFile = new DataEntityFile(\n\t\t\t\t\tmeta,\n\t\t\t\t\tnamingStrategy,\n\t\t\t\t\tplatform,\n\t\t\t\t\tdatabaseType,\n\t\t\t\t\tentityLookup\n\t\t\t\t);\n\t\t\t\tconst schemaEntityFile = new SchemaEntityFile(\n\t\t\t\t\tmeta,\n\t\t\t\t\tnamingStrategy,\n\t\t\t\t\tplatform,\n\t\t\t\t\tdatabaseType,\n\t\t\t\t\tentityLookup,\n\t\t\t\t\tapiOptions?.clientGeneratedPrimaryKeys ?? false\n\t\t\t\t);\n\t\t\t\tsource.push(dataEntityFile, schemaEntityFile);\n\t\t\t\tsummaryOfEntities.push({\n\t\t\t\t\tname: meta.className,\n\t\t\t\t\tentityFilePath: `${dataEntityFile.getBasePath()}${dataEntityFile.getBaseName()}`,\n\t\t\t\t\tschemaFilePath: `${schemaEntityFile.getBasePath()}${schemaEntityFile.getBaseName()}`,\n\t\t\t\t});\n\t\t\t} else if (meta.primaryKeys.length > 1) {\n\t\t\t\terrors.push(\n\t\t\t\t\t`Entity ${meta.className} has either more than one primary key. We have skipped it and relations to it because Graphweaver does not support entities with multiple primary keys yet.`\n\t\t\t\t);\n\t\t\t} else if (meta.primaryKeys.length === 0) {\n\t\t\t\terrors.push(\n\t\t\t\t\t`Entity ${meta.className} has no primary key. We have skipped it and relations to it because Graphweaver does not support entities with no primary key yet.`\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Export all the entities from the data source directory\n\t\tsource.push(new DataEntityIndexFile(metadata, databaseType));\n\t\t// Export the data source from the entities directory\n\t\tsource.push(new DataSourceIndexFile(databaseType));\n\t\t// Export the data source from the entities directory\n\t\tsource.push(new SchemaIndexFile(metadata));\n\t\t// Export the database connection to its own file\n\t\tsource.push(new DatabaseFile(databaseType, options));\n\n\t\tconst files = source.map((file) => {\n\t\t\treturn {\n\t\t\t\tpath: file.getBasePath(),\n\t\t\t\tname: file.getBaseName(),\n\t\t\t\tcontents: file.generate(),\n\t\t\t\tneedOverwriteWarning: !![DatabaseFile, SchemaIndexFile].some((cls) => file instanceof cls),\n\t\t\t\terrors: 'errors' in file ? file.errors : [],\n\t\t\t};\n\t\t});\n\n\t\tawait closeConnection();\n\n\t\tconsole.log('\\nImport Summary:');\n\t\tconsole.table(summaryOfEntities);\n\t\tconsole.log(\n\t\t\t`\\nImported ${summaryOfEntities.length} entities, creating the above files in your Graphweaver project. \\n`\n\t\t);\n\n\t\tfor (const file of files) {\n\t\t\terrors.push(...file.errors);\n\t\t}\n\n\t\tif (errors.length) {\n\t\t\tconsole.log(`\\nWarning ${errors.length} errors detected:\\n`);\n\t\t\tconsole.log(errors.join('\\n'));\n\t\t}\n\n\t\treturn files;\n\t} catch (err) {\n\t\tif (err instanceof IntrospectionError) throw err;\n\n\t\tconsole.error('Got error during introspection:');\n\t\tconsole.error(err);\n\n\t\tthrow new IntrospectionError(\n\t\t\t`Warning: Unable to connect to database.`,\n\t\t\thasErrorMessage(err) ? err.message : 'Please check the connection settings and try again'\n\t\t);\n\t}\n};\n"],
5
+ "mappings": "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",
6
6
  "names": ["pluralize", "module"]
7
7
  }
@@ -1,5 +1,6 @@
1
1
  import { ConnectionOptions, DatabaseType } from '../database';
2
- export declare const introspection: (databaseType: DatabaseType, options: ConnectionOptions) => Promise<{
2
+ import { APIOptions } from './generate';
3
+ export declare const introspection: (databaseType: DatabaseType, options: ConnectionOptions, apiOptions?: APIOptions) => Promise<{
3
4
  path: string;
4
5
  name: string;
5
6
  contents: string;
@@ -22,7 +22,7 @@ __export(introspection_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(introspection_exports);
24
24
  var import_generate = require("./generate");
25
- const introspection = async (databaseType, options) => (0, import_generate.generate)(databaseType, options);
25
+ const introspection = async (databaseType, options, apiOptions) => (0, import_generate.generate)(databaseType, options, apiOptions);
26
26
  // Annotate the CommonJS export names for ESM import in node:
27
27
  0 && (module.exports = {
28
28
  introspection
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/introspection/index.ts"],
4
- "sourcesContent": ["import { ConnectionOptions, DatabaseType } from '../database';\nimport { generate } from './generate';\n\nexport const introspection = async (databaseType: DatabaseType, options: ConnectionOptions) =>\n\tgenerate(databaseType, options);\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,sBAAyB;AAElB,MAAM,gBAAgB,OAAO,cAA4B,gBAC/D,0BAAS,cAAc,OAAO;",
4
+ "sourcesContent": ["import { ConnectionOptions, DatabaseType } from '../database';\nimport { generate, APIOptions } from './generate';\n\nexport const introspection = async (databaseType: DatabaseType, options: ConnectionOptions, apiOptions?: APIOptions) =>\n\tgenerate(databaseType, options, apiOptions);\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,sBAAqC;AAE9B,MAAM,gBAAgB,OAAO,cAA4B,SAA4B,mBAC3F,0BAAS,cAAc,SAAS,UAAU;",
6
6
  "names": []
7
7
  }
@@ -3,5 +3,5 @@ interface AssignOptions {
3
3
  create?: boolean;
4
4
  update?: boolean;
5
5
  }
6
- export declare const assign: <T extends AnyEntity<T>>(entity: T, data: EntityData<T>, options?: AssignOptions, visited?: Set<Partial<any>>, em?: import("@mikro-orm/postgresql").EntityManager<import("@mikro-orm/postgresql").PostgreSqlDriver> | import("@mikro-orm/postgresql").EntityManager<import("@mikro-orm/mysql").MySqlDriver> | import("@mikro-orm/postgresql").EntityManager<import("@mikro-orm/sqlite").SqliteDriver>) => Promise<T>;
6
+ export declare const assign: <T extends AnyEntity<T>>(entity: T, data: EntityData<T>, options?: AssignOptions, visited?: Set<Partial<any>>, em?: import("@mikro-orm/knex").EntityManager<import("@mikro-orm/postgresql").PostgreSqlDriver> | import("@mikro-orm/knex").EntityManager<import("@mikro-orm/mysql").MySqlDriver> | import("@mikro-orm/knex").EntityManager<import("@mikro-orm/sqlite").SqliteDriver>) => Promise<T>;
7
7
  export {};
@@ -23,6 +23,7 @@ __export(assign_exports, {
23
23
  module.exports = __toCommonJS(assign_exports);
24
24
  var import_core = require("@mikro-orm/core");
25
25
  var import_logger = require("@exogee/logger");
26
+ var import_graphweaver = require("@exogee/graphweaver");
26
27
  var import_database = require("../database");
27
28
  var import_generate = require("../introspection/generate");
28
29
  const assign = async (entity, data, options, visited = /* @__PURE__ */ new Set(), em = import_database.ConnectionManager.default.em) => {
@@ -50,6 +51,8 @@ const assign = async (entity, data, options, visited = /* @__PURE__ */ new Set()
50
51
  }
51
52
  const [relatedPrimaryKeyField] = relatedEntity?.primaryKeys ?? [];
52
53
  const visitedEntities = /* @__PURE__ */ new Set();
54
+ const relatedGwMetadata = import_graphweaver.graphweaverMetadata.getEntityMetadataByDataEntity(propertyMetadata.entity());
55
+ const clientGeneratedPrimaryKeys = relatedGwMetadata?.apiOptions?.clientGeneratedPrimaryKeys ?? false;
53
56
  for (const subvalue of value) {
54
57
  let entity2;
55
58
  if (subvalue[relatedPrimaryKeyField]) {
@@ -70,9 +73,9 @@ const assign = async (entity, data, options, visited = /* @__PURE__ */ new Set()
70
73
  }) ?? void 0;
71
74
  }
72
75
  }
73
- if (!entity2) {
76
+ if (!entity2 && !clientGeneratedPrimaryKeys) {
74
77
  throw new Error(
75
- `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.`
78
+ `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[relatedPrimaryKeyField]} could not be found.`
76
79
  );
77
80
  }
78
81
  }
@@ -83,7 +86,8 @@ const assign = async (entity, data, options, visited = /* @__PURE__ */ new Set()
83
86
  data: subvalue,
84
87
  options,
85
88
  visited,
86
- em
89
+ em,
90
+ clientGeneratedPrimaryKeys
87
91
  });
88
92
  entityPropertyValue.add(newEntity);
89
93
  visitedEntities.add(newEntity);
@@ -124,6 +128,8 @@ const assign = async (entity, data, options, visited = /* @__PURE__ */ new Set()
124
128
  `Trying to merge to related property ${property} on entity ${metadata.name} which is not initialised.`
125
129
  );
126
130
  }
131
+ const relatedGwMetadata = import_graphweaver.graphweaverMetadata.getEntityMetadataByDataEntity(propertyMetadata.entity());
132
+ const clientGeneratedPrimaryKeys = relatedGwMetadata?.apiOptions?.clientGeneratedPrimaryKeys ?? false;
127
133
  const newEntity = await createOrAssignEntity({
128
134
  entity: entityPropertyValue?.unwrap(),
129
135
  entityType: propertyMetadata.type,
@@ -131,7 +137,8 @@ const assign = async (entity, data, options, visited = /* @__PURE__ */ new Set()
131
137
  data: value,
132
138
  options,
133
139
  visited,
134
- em
140
+ em,
141
+ clientGeneratedPrimaryKeys
135
142
  });
136
143
  relatedEntity[property] = import_core.Reference.create(newEntity);
137
144
  }
@@ -149,12 +156,23 @@ const createOrAssignEntity = ({
149
156
  data,
150
157
  options,
151
158
  visited,
152
- em
159
+ em,
160
+ clientGeneratedPrimaryKeys
153
161
  }) => {
154
- const create = options?.create ?? true;
155
- const update = options?.update ?? true;
156
- if (data[primaryKeyField]) {
157
- if (!update) {
162
+ const createAllowed = options?.create ?? true;
163
+ const updateAllowed = options?.update ?? true;
164
+ const hasPrimaryKey = data[primaryKeyField] !== void 0;
165
+ const createEntity = () => {
166
+ if (!createAllowed) {
167
+ throw new Error(
168
+ `Creates are disabled, but value ${JSON.stringify(data)} was passed.`
169
+ );
170
+ }
171
+ const newEntity = em.create(entityType, {});
172
+ return assign(newEntity, data, options, visited);
173
+ };
174
+ const updateEntity = () => {
175
+ if (!updateAllowed) {
158
176
  throw new Error(
159
177
  `Updates are disabled, but update value ${JSON.stringify(
160
178
  data
@@ -169,17 +187,14 @@ const createOrAssignEntity = ({
169
187
  );
170
188
  }
171
189
  return assign(entity, data, options, visited);
172
- } else {
173
- if (!create) {
174
- throw new Error(
175
- `Creates are disabled, but update value ${JSON.stringify(
176
- data
177
- )} was passed which does not have an ID property.`
178
- );
190
+ };
191
+ if (hasPrimaryKey) {
192
+ if (!entity && clientGeneratedPrimaryKeys) {
193
+ return createEntity();
179
194
  }
180
- const entity2 = em.create(entityType, {});
181
- return assign(entity2, data, options, visited);
195
+ return updateEntity();
182
196
  }
197
+ return createEntity();
183
198
  };
184
199
  // Annotate the CommonJS export names for ESM import in node:
185
200
  0 && (module.exports = {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/provider/assign.ts"],
4
- "sourcesContent": ["import {\n\tAnyEntity,\n\tEntityData,\n\tEntityManager,\n\tEntityProperty,\n\tReference,\n\tReferenceKind,\n\tUtils,\n\twrap,\n} from '@mikro-orm/core';\nimport { logger } from '@exogee/logger';\n\nimport { ConnectionManager } from '../database';\nimport { isEntityWithSinglePrimaryKey } from '../introspection/generate';\n\ninterface AssignOptions {\n\t// Whether this assign should be allowed to create new entities.\n\t// If false and a create is attempted, assign will throw.\n\t// Defaults to true if not specified.\n\tcreate?: boolean;\n\n\t// Whether this assign should be allowed update existing entities.\n\t// If false and an update is attempted, assign will throw.\n\t// Defaults to true if not specified.\n\tupdate?: boolean;\n}\n\nexport const assign = async <T extends AnyEntity<T>>(\n\tentity: T,\n\tdata: EntityData<T>,\n\toptions?: AssignOptions,\n\tvisited = new Set<AnyEntity<any>>(),\n\tem = ConnectionManager.default.em\n) => {\n\tif (visited.has(entity)) return entity;\n\tvisited.add(entity);\n\n\t// We'll need the metadata for this entity to be able to traverse the properties later.\n\tconst metadata = wrap(entity, true).__meta!;\n\n\tfor (const [property, value] of Object.entries(data)) {\n\t\tconst entityPropertyValue = entity[property as keyof T];\n\n\t\t// We're going to need the metadata for this property so we can ensure it exists and so that we can\n\t\t// navigate to related entities.\n\t\tconst propertyMetadata = (metadata.properties as any)[property] as\n\t\t\t| EntityProperty<T>\n\t\t\t| undefined;\n\n\t\tif (\n\t\t\tpropertyMetadata?.kind === ReferenceKind.MANY_TO_MANY ||\n\t\t\tpropertyMetadata?.kind === ReferenceKind.ONE_TO_MANY\n\t\t) {\n\t\t\tif (!Array.isArray(value))\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Value is not an array while trying to assign to collection property ${property} on entity ${metadata.name}`\n\t\t\t\t);\n\n\t\t\t// Ensure the entity has a loaded collection at the same place.\n\t\t\tif (!Utils.isCollection<T, any>(entityPropertyValue)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Tried to merge array into non-collection property ${property} on entity ${metadata.name}`\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst relatedEntity = em.getMetadata().find(propertyMetadata.entity());\n\t\t\tif (!isEntityWithSinglePrimaryKey(relatedEntity)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Entity ${propertyMetadata.entity()} has multiple primary keys, which is not yet supported.`\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst [relatedPrimaryKeyField] = relatedEntity?.primaryKeys ?? [];\n\n\t\t\tconst visitedEntities = new Set<T>();\n\n\t\t\tfor (const subvalue of value) {\n\t\t\t\tlet entity: T | undefined;\n\n\t\t\t\tif (subvalue[relatedPrimaryKeyField]) {\n\t\t\t\t\t// Get the current entity from the ORM if there's an ID.\n\t\t\t\t\tentity = em\n\t\t\t\t\t\t.getUnitOfWork()\n\t\t\t\t\t\t.getById(propertyMetadata.type, subvalue[relatedPrimaryKeyField]);\n\n\t\t\t\t\tif (!entity) {\n\t\t\t\t\t\t// There are two cases here: either the user is trying to assign properties to the entity as well as changing members of a collection,\n\t\t\t\t\t\t// or they're just changing members of a collection.\n\t\t\t\t\t\t// For the former we actually need the entity from the DB, while for the latter we can let it slide and just pass an ID entity on down.\n\t\t\t\t\t\tconst subvalueKeys = Object.keys(subvalue);\n\t\t\t\t\t\tif (subvalueKeys.length === 1 && subvalueKeys[0] === relatedPrimaryKeyField) {\n\t\t\t\t\t\t\t// It's just the ID.\n\t\t\t\t\t\t\tentity = em.getReference(\n\t\t\t\t\t\t\t\tpropertyMetadata.type,\n\t\t\t\t\t\t\t\tsubvalue[relatedPrimaryKeyField]\n\t\t\t\t\t\t\t) as T;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tlogger.warn(\n\t\t\t\t\t\t\t\t`Doing a full database fetch for ${propertyMetadata.type} with id ${subvalue[relatedPrimaryKeyField]}, this should ideally be prefetched into the Unit of Work before calling assign() for performance`\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t// We should be prefetching for performance in most cases here but if we don't have it we can load it now.\n\t\t\t\t\t\t\t// From base resolver a reason this would be needed is when you're switching collection values from one entity to another, e.g.\n\t\t\t\t\t\t\t// Business unit 1 -> Business unit 2. In this scenario we prefetch the one that's currently on the entity, but the one we're changing\n\t\t\t\t\t\t\t// to is not in the unit of work.\n\t\t\t\t\t\t\tentity =\n\t\t\t\t\t\t\t\t((await em.findOne<any>(propertyMetadata.type, {\n\t\t\t\t\t\t\t\t\t[relatedPrimaryKeyField]: subvalue[relatedPrimaryKeyField],\n\t\t\t\t\t\t\t\t})) as T | null) ?? undefined;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!entity) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`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.`\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst newEntity = await createOrAssignEntity<T>({\n\t\t\t\t\tentity,\n\t\t\t\t\tentityType: propertyMetadata.type,\n\t\t\t\t\tprimaryKeyField: relatedPrimaryKeyField,\n\t\t\t\t\tdata: subvalue,\n\t\t\t\t\toptions,\n\t\t\t\t\tvisited,\n\t\t\t\t\tem,\n\t\t\t\t});\n\n\t\t\t\t// Ok, now we've got the created or updated entity, ensure it's in the collection\n\t\t\t\t// so its foreign keys are set correctly. If it's already in the collection this is a noop.\n\t\t\t\tentityPropertyValue.add(newEntity);\n\n\t\t\t\t// We need to keep track of the fact that this entity belongs here so it doesn't get removed in the cleanup step down below.\n\t\t\t\tvisitedEntities.add(newEntity);\n\t\t\t}\n\n\t\t\t// Ok, at this point we know what IDs we visited. If anything is left in the collection that has an ID and has not been visited\n\t\t\t// it needs to be removed from the collection, because this is the canonical list of everything that's in the collection now.\n\t\t\t// ------------\n\t\t\t// \u2757\uD83D\uDC3B WARNING BEAR TRAP \uD83D\uDC3B\u2757: If you're looking at this going, \"But I just want to pass in the items I want to update and for it not to\n\t\t\t// mess with the rest of the collection\", this is here because without this behaviour, there's no way to remove items from\n\t\t\t// Many to Many properties. Consider the case of tags on an entity, when we pass ['a', 'b', 'c'] as the list of tags, that\n\t\t\t// means we need to remove anything that isn't 'a', 'b', or 'c' because it's not in the array.\n\t\t\tentityPropertyValue.remove(\n\t\t\t\tentityPropertyValue.getItems().filter((entity) => !visitedEntities.has(entity))\n\t\t\t);\n\t\t} else if (\n\t\t\tpropertyMetadata?.kind == ReferenceKind.MANY_TO_ONE ||\n\t\t\tpropertyMetadata?.kind === ReferenceKind.ONE_TO_ONE\n\t\t) {\n\t\t\tif (value === null) {\n\t\t\t\t// If the value is null, unset the reference\n\t\t\t\t(entity as any)[property] = null;\n\t\t\t} else {\n\t\t\t\tconst valueKeys = Object.keys(value as any);\n\t\t\t\tconst relatedEntity = em.getMetadata().find(propertyMetadata.entity());\n\t\t\t\tif (!relatedEntity) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Could not find entity ${propertyMetadata.entity()} in MikroORM metadata.`\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (!isEntityWithSinglePrimaryKey(relatedEntity)) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Entity ${propertyMetadata.entity()} has ${relatedEntity.primaryKeys.length} primary keys, but we only support 1.`\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst relatedPrimaryKeyField = relatedEntity.primaryKeys[0];\n\n\t\t\t\tif (valueKeys.length === 1 && valueKeys[0] === relatedPrimaryKeyField) {\n\t\t\t\t\t// Ok, this is just the ID, set the reference and move on.\n\t\t\t\t\tentity[property as keyof T] = em.getReference(\n\t\t\t\t\t\tpropertyMetadata.type,\n\t\t\t\t\t\t(value as any)[relatedPrimaryKeyField]\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tif (entityPropertyValue && !Reference.isReference(entityPropertyValue)) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Trying to merge to related property ${property} on entity ${metadata.name} which is not a reference.`\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (Reference.isReference(entityPropertyValue) && !entityPropertyValue.isInitialized()) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Trying to merge to related property ${property} on entity ${metadata.name} which is not initialised.`\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst newEntity = await createOrAssignEntity<T>({\n\t\t\t\t\t\tentity: (entityPropertyValue as Reference<T>)?.unwrap(),\n\t\t\t\t\t\tentityType: propertyMetadata.type,\n\t\t\t\t\t\tprimaryKeyField: relatedPrimaryKeyField,\n\t\t\t\t\t\tdata: value as EntityData<T>,\n\t\t\t\t\t\toptions,\n\t\t\t\t\t\tvisited,\n\t\t\t\t\t\tem,\n\t\t\t\t\t});\n\n\t\t\t\t\t(relatedEntity as any)[property] = Reference.create(newEntity);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// Ok, we're a simple scalar.\n\t\t\t(entity as any)[property] = value;\n\t\t}\n\t}\n\n\treturn entity;\n};\n\nconst createOrAssignEntity = <T extends AnyEntity<T>>({\n\tentity,\n\tentityType,\n\tprimaryKeyField,\n\tdata,\n\toptions,\n\tvisited,\n\tem,\n}: {\n\tentity?: T;\n\tentityType: string;\n\tprimaryKeyField: string;\n\tdata: EntityData<T>;\n\toptions?: AssignOptions;\n\tvisited: Set<AnyEntity<any>>;\n\tem: EntityManager;\n}) => {\n\tconst create = options?.create ?? true;\n\tconst update = options?.update ?? true;\n\n\tif ((data as any)[primaryKeyField]) {\n\t\tif (!update) {\n\t\t\tthrow new Error(\n\t\t\t\t`Updates are disabled, but update value ${JSON.stringify(\n\t\t\t\t\tdata\n\t\t\t\t)} was passed which has an ID property.`\n\t\t\t);\n\t\t}\n\n\t\tif (!entity) {\n\t\t\tthrow new Error(\n\t\t\t\t`Tried to update with data ${JSON.stringify(\n\t\t\t\t\tdata\n\t\t\t\t)} but entity could not be located to update.`\n\t\t\t);\n\t\t}\n\n\t\t// Ok, we need to recurse here.\n\t\treturn assign(entity, data, options, visited);\n\t} else {\n\t\tif (!create) {\n\t\t\tthrow new Error(\n\t\t\t\t`Creates are disabled, but update value ${JSON.stringify(\n\t\t\t\t\tdata\n\t\t\t\t)} was passed which does not have an ID property.`\n\t\t\t);\n\t\t}\n\n\t\t// We don't want Mikro to manage the data merging here, we'll do it in the next line.\n\t\tconst entity = em.create<T>(entityType, {} as any);\n\t\treturn assign(entity, data, options, visited);\n\t}\n};\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tAnyEntity,\n\tEntityData,\n\tEntityManager,\n\tEntityProperty,\n\tReference,\n\tReferenceKind,\n\tUtils,\n\twrap,\n} from '@mikro-orm/core';\nimport { logger } from '@exogee/logger';\nimport { graphweaverMetadata } from '@exogee/graphweaver';\n\nimport { ConnectionManager } from '../database';\nimport { isEntityWithSinglePrimaryKey } from '../introspection/generate';\n\ninterface AssignOptions {\n\t// Whether this assign should be allowed to create new entities.\n\t// If false and a create is attempted, assign will throw.\n\t// Defaults to true if not specified.\n\tcreate?: boolean;\n\n\t// Whether this assign should be allowed update existing entities.\n\t// If false and an update is attempted, assign will throw.\n\t// Defaults to true if not specified.\n\tupdate?: boolean;\n}\n\nexport const assign = async <T extends AnyEntity<T>>(\n\tentity: T,\n\tdata: EntityData<T>,\n\toptions?: AssignOptions,\n\tvisited = new Set<AnyEntity<any>>(),\n\tem = ConnectionManager.default.em\n) => {\n\tif (visited.has(entity)) return entity;\n\tvisited.add(entity);\n\n\t// We'll need the metadata for this entity to be able to traverse the properties later.\n\tconst metadata = wrap(entity, true).__meta!;\n\n\tfor (const [property, value] of Object.entries(data)) {\n\t\tconst entityPropertyValue = entity[property as keyof T];\n\n\t\t// We're going to need the metadata for this property so we can ensure it exists and so that we can\n\t\t// navigate to related entities.\n\t\tconst propertyMetadata = (metadata.properties as any)[property] as\n\t\t\t| EntityProperty<T>\n\t\t\t| undefined;\n\n\t\tif (\n\t\t\tpropertyMetadata?.kind === ReferenceKind.MANY_TO_MANY ||\n\t\t\tpropertyMetadata?.kind === ReferenceKind.ONE_TO_MANY\n\t\t) {\n\t\t\tif (!Array.isArray(value))\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Value is not an array while trying to assign to collection property ${property} on entity ${metadata.name}`\n\t\t\t\t);\n\n\t\t\t// Ensure the entity has a loaded collection at the same place.\n\t\t\tif (!Utils.isCollection<T, any>(entityPropertyValue)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Tried to merge array into non-collection property ${property} on entity ${metadata.name}`\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst relatedEntity = em.getMetadata().find(propertyMetadata.entity());\n\t\t\tif (!isEntityWithSinglePrimaryKey(relatedEntity)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Entity ${propertyMetadata.entity()} has multiple primary keys, which is not yet supported.`\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst [relatedPrimaryKeyField] = relatedEntity?.primaryKeys ?? [];\n\n\t\t\tconst visitedEntities = new Set<T>();\n\n\t\t\tconst relatedGwMetadata = graphweaverMetadata.getEntityMetadataByDataEntity(propertyMetadata.entity());\n\t\t\tconst clientGeneratedPrimaryKeys = relatedGwMetadata?.apiOptions?.clientGeneratedPrimaryKeys ?? false;\n\n\t\t\tfor (const subvalue of value) {\n\t\t\t\tlet entity: T | undefined;\n\n\t\t\t\tif (subvalue[relatedPrimaryKeyField]) {\n\t\t\t\t\t// Get the current entity from the ORM if there's an ID.\n\t\t\t\t\tentity = em\n\t\t\t\t\t\t.getUnitOfWork()\n\t\t\t\t\t\t.getById(propertyMetadata.type, subvalue[relatedPrimaryKeyField]);\n\n\t\t\t\t\tif (!entity) {\n\t\t\t\t\t\t// There are two cases here: either the user is trying to assign properties to the entity as well as changing members of a collection,\n\t\t\t\t\t\t// or they're just changing members of a collection.\n\t\t\t\t\t\t// For the former we actually need the entity from the DB, while for the latter we can let it slide and just pass an ID entity on down.\n\t\t\t\t\t\tconst subvalueKeys = Object.keys(subvalue);\n\t\t\t\t\t\tif (subvalueKeys.length === 1 && subvalueKeys[0] === relatedPrimaryKeyField) {\n\t\t\t\t\t\t\t// It's just the ID.\n\t\t\t\t\t\t\tentity = em.getReference(\n\t\t\t\t\t\t\t\tpropertyMetadata.type,\n\t\t\t\t\t\t\t\tsubvalue[relatedPrimaryKeyField]\n\t\t\t\t\t\t\t) as T;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tlogger.warn(\n\t\t\t\t\t\t\t\t`Doing a full database fetch for ${propertyMetadata.type} with id ${subvalue[relatedPrimaryKeyField]}, this should ideally be prefetched into the Unit of Work before calling assign() for performance`\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t// We should be prefetching for performance in most cases here but if we don't have it we can load it now.\n\t\t\t\t\t\t\t// From base resolver a reason this would be needed is when you're switching collection values from one entity to another, e.g.\n\t\t\t\t\t\t\t// Business unit 1 -> Business unit 2. In this scenario we prefetch the one that's currently on the entity, but the one we're changing\n\t\t\t\t\t\t\t// to is not in the unit of work.\n\t\t\t\t\t\t\tentity =\n\t\t\t\t\t\t\t\t((await em.findOne<any>(propertyMetadata.type, {\n\t\t\t\t\t\t\t\t\t[relatedPrimaryKeyField]: subvalue[relatedPrimaryKeyField],\n\t\t\t\t\t\t\t\t})) as T | null) ?? undefined;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!entity && !clientGeneratedPrimaryKeys) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`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[relatedPrimaryKeyField]} could not be found.`\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst newEntity = await createOrAssignEntity<T>({\n\t\t\t\t\tentity,\n\t\t\t\t\tentityType: propertyMetadata.type,\n\t\t\t\t\tprimaryKeyField: relatedPrimaryKeyField,\n\t\t\t\t\tdata: subvalue,\n\t\t\t\t\toptions,\n\t\t\t\t\tvisited,\n\t\t\t\t\tem,\n\t\t\t\t\tclientGeneratedPrimaryKeys,\n\t\t\t\t});\n\n\t\t\t\t// Ok, now we've got the created or updated entity, ensure it's in the collection\n\t\t\t\t// so its foreign keys are set correctly. If it's already in the collection this is a noop.\n\t\t\t\tentityPropertyValue.add(newEntity);\n\n\t\t\t\t// We need to keep track of the fact that this entity belongs here so it doesn't get removed in the cleanup step down below.\n\t\t\t\tvisitedEntities.add(newEntity);\n\t\t\t}\n\n\t\t\t// Ok, at this point we know what IDs we visited. If anything is left in the collection that has an ID and has not been visited\n\t\t\t// it needs to be removed from the collection, because this is the canonical list of everything that's in the collection now.\n\t\t\t// ------------\n\t\t\t// \u2757\uD83D\uDC3B WARNING BEAR TRAP \uD83D\uDC3B\u2757: If you're looking at this going, \"But I just want to pass in the items I want to update and for it not to\n\t\t\t// mess with the rest of the collection\", this is here because without this behaviour, there's no way to remove items from\n\t\t\t// Many to Many properties. Consider the case of tags on an entity, when we pass ['a', 'b', 'c'] as the list of tags, that\n\t\t\t// means we need to remove anything that isn't 'a', 'b', or 'c' because it's not in the array.\n\t\t\tentityPropertyValue.remove(\n\t\t\t\tentityPropertyValue.getItems().filter((entity) => !visitedEntities.has(entity))\n\t\t\t);\n\t\t} else if (\n\t\t\tpropertyMetadata?.kind == ReferenceKind.MANY_TO_ONE ||\n\t\t\tpropertyMetadata?.kind === ReferenceKind.ONE_TO_ONE\n\t\t) {\n\t\t\tif (value === null) {\n\t\t\t\t// If the value is null, unset the reference\n\t\t\t\t(entity as any)[property] = null;\n\t\t\t} else {\n\t\t\t\tconst valueKeys = Object.keys(value as any);\n\t\t\t\tconst relatedEntity = em.getMetadata().find(propertyMetadata.entity());\n\t\t\t\tif (!relatedEntity) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Could not find entity ${propertyMetadata.entity()} in MikroORM metadata.`\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (!isEntityWithSinglePrimaryKey(relatedEntity)) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Entity ${propertyMetadata.entity()} has ${relatedEntity.primaryKeys.length} primary keys, but we only support 1.`\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst relatedPrimaryKeyField = relatedEntity.primaryKeys[0];\n\n\t\t\t\tif (valueKeys.length === 1 && valueKeys[0] === relatedPrimaryKeyField) {\n\t\t\t\t\t// Ok, this is just the ID, set the reference and move on.\n\t\t\t\t\tentity[property as keyof T] = em.getReference(\n\t\t\t\t\t\tpropertyMetadata.type,\n\t\t\t\t\t\t(value as any)[relatedPrimaryKeyField]\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tif (entityPropertyValue && !Reference.isReference(entityPropertyValue)) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Trying to merge to related property ${property} on entity ${metadata.name} which is not a reference.`\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (Reference.isReference(entityPropertyValue) && !entityPropertyValue.isInitialized()) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Trying to merge to related property ${property} on entity ${metadata.name} which is not initialised.`\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst relatedGwMetadata = graphweaverMetadata.getEntityMetadataByDataEntity(propertyMetadata.entity());\n\t\t\t\t\tconst clientGeneratedPrimaryKeys = relatedGwMetadata?.apiOptions?.clientGeneratedPrimaryKeys ?? false;\n\n\t\t\t\t\tconst newEntity = await createOrAssignEntity<T>({\n\t\t\t\t\t\tentity: (entityPropertyValue as Reference<T>)?.unwrap(),\n\t\t\t\t\t\tentityType: propertyMetadata.type,\n\t\t\t\t\t\tprimaryKeyField: relatedPrimaryKeyField,\n\t\t\t\t\t\tdata: value as EntityData<T>,\n\t\t\t\t\t\toptions,\n\t\t\t\t\t\tvisited,\n\t\t\t\t\t\tem,\n\t\t\t\t\t\tclientGeneratedPrimaryKeys,\n\t\t\t\t\t});\n\n\t\t\t\t\t(relatedEntity as any)[property] = Reference.create(newEntity);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// Ok, we're a simple scalar.\n\t\t\t(entity as any)[property] = value;\n\t\t}\n\t}\n\n\treturn entity;\n};\n\nconst createOrAssignEntity = <T extends AnyEntity<T>>({\n\tentity,\n\tentityType,\n\tprimaryKeyField,\n\tdata,\n\toptions,\n\tvisited,\n\tem,\n\tclientGeneratedPrimaryKeys,\n}: {\n\tentity?: T;\n\tentityType: string;\n\tprimaryKeyField: string;\n\tdata: EntityData<T>;\n\toptions?: AssignOptions;\n\tvisited: Set<AnyEntity<any>>;\n\tem: EntityManager;\n\tclientGeneratedPrimaryKeys?: boolean;\n}) => {\n\tconst createAllowed = options?.create ?? true;\n\tconst updateAllowed = options?.update ?? true;\n\tconst hasPrimaryKey = (data as any)[primaryKeyField] !== undefined;\n\tconst createEntity = () => {\n\t\tif (!createAllowed) {\n\t\t\tthrow new Error(\n\t\t\t\t`Creates are disabled, but value ${JSON.stringify(data)} was passed.`\n\t\t\t);\n\t\t}\n\n\t\tconst newEntity = em.create<T>(entityType, {} as any);\n\t\treturn assign(newEntity, data, options, visited);\n\t};\n\tconst updateEntity = () => {\n\t\tif (!updateAllowed) {\n\t\t\tthrow new Error(\n\t\t\t\t`Updates are disabled, but update value ${JSON.stringify(\n\t\t\t\t\tdata\n\t\t\t\t)} was passed which has an ID property.`\n\t\t\t);\n\t\t}\n\n\t\tif (!entity) {\n\t\t\tthrow new Error(\n\t\t\t\t`Tried to update with data ${JSON.stringify(\n\t\t\t\t\tdata\n\t\t\t\t)} but entity could not be located to update.`\n\t\t\t);\n\t\t}\n\n\t\treturn assign(entity, data, options, visited);\n\t};\n\n\tif (hasPrimaryKey) {\n\t\tif (!entity && clientGeneratedPrimaryKeys) {\n\t\t\treturn createEntity();\n\t\t}\n\n\t\treturn updateEntity();\n\t}\n\n\treturn createEntity();\n};\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBASO;AACP,oBAAuB;AACvB,yBAAoC;AAEpC,sBAAkC;AAClC,sBAA6C;AActC,MAAM,SAAS,OACrB,QACA,MACA,SACA,UAAU,oBAAI,IAAoB,GAClC,KAAK,kCAAkB,QAAQ,OAC3B;AACJ,MAAI,QAAQ,IAAI,MAAM,EAAG,QAAO;AAChC,UAAQ,IAAI,MAAM;AAGlB,QAAM,eAAW,kBAAK,QAAQ,IAAI,EAAE;AAEpC,aAAW,CAAC,UAAU,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AACrD,UAAM,sBAAsB,OAAO,QAAmB;AAItD,UAAM,mBAAoB,SAAS,WAAmB,QAAQ;AAI9D,QACC,kBAAkB,SAAS,0BAAc,gBACzC,kBAAkB,SAAS,0BAAc,aACxC;AACD,UAAI,CAAC,MAAM,QAAQ,KAAK;AACvB,cAAM,IAAI;AAAA,UACT,uEAAuE,QAAQ,cAAc,SAAS,IAAI;AAAA,QAC3G;AAGD,UAAI,CAAC,kBAAM,aAAqB,mBAAmB,GAAG;AACrD,cAAM,IAAI;AAAA,UACT,qDAAqD,QAAQ,cAAc,SAAS,IAAI;AAAA,QACzF;AAAA,MACD;AAEA,YAAM,gBAAgB,GAAG,YAAY,EAAE,KAAK,iBAAiB,OAAO,CAAC;AACrE,UAAI,KAAC,8CAA6B,aAAa,GAAG;AACjD,cAAM,IAAI;AAAA,UACT,UAAU,iBAAiB,OAAO,CAAC;AAAA,QACpC;AAAA,MACD;AACA,YAAM,CAAC,sBAAsB,IAAI,eAAe,eAAe,CAAC;AAEhE,YAAM,kBAAkB,oBAAI,IAAO;AAEnC,YAAM,oBAAoB,uCAAoB,8BAA8B,iBAAiB,OAAO,CAAC;AACrG,YAAM,6BAA6B,mBAAmB,YAAY,8BAA8B;AAEhG,iBAAW,YAAY,OAAO;AAC7B,YAAIA;AAEJ,YAAI,SAAS,sBAAsB,GAAG;AAErC,UAAAA,UAAS,GACP,cAAc,EACd,QAAQ,iBAAiB,MAAM,SAAS,sBAAsB,CAAC;AAEjE,cAAI,CAACA,SAAQ;AAIZ,kBAAM,eAAe,OAAO,KAAK,QAAQ;AACzC,gBAAI,aAAa,WAAW,KAAK,aAAa,CAAC,MAAM,wBAAwB;AAE5E,cAAAA,UAAS,GAAG;AAAA,gBACX,iBAAiB;AAAA,gBACjB,SAAS,sBAAsB;AAAA,cAChC;AAAA,YACD,OAAO;AACN,mCAAO;AAAA,gBACN,mCAAmC,iBAAiB,IAAI,YAAY,SAAS,sBAAsB,CAAC;AAAA,cACrG;AAMA,cAAAA,UACG,MAAM,GAAG,QAAa,iBAAiB,MAAM;AAAA,gBAC9C,CAAC,sBAAsB,GAAG,SAAS,sBAAsB;AAAA,cAC1D,CAAC,KAAmB;AAAA,YACtB;AAAA,UACD;AAEA,cAAI,CAACA,WAAU,CAAC,4BAA4B;AAC3C,kBAAM,IAAI;AAAA,cACT,wCAAwC,iBAAiB,IAAI,iBAAiB,SAAS,IAAI,wDAAwD,iBAAiB,IAAI,eAAe,SAAS,sBAAsB,CAAC;AAAA,YACxN;AAAA,UACD;AAAA,QACD;AAEA,cAAM,YAAY,MAAM,qBAAwB;AAAA,UAC/C,QAAAA;AAAA,UACA,YAAY,iBAAiB;AAAA,UAC7B,iBAAiB;AAAA,UACjB,MAAM;AAAA,UACN;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACD,CAAC;AAID,4BAAoB,IAAI,SAAS;AAGjC,wBAAgB,IAAI,SAAS;AAAA,MAC9B;AASA,0BAAoB;AAAA,QACnB,oBAAoB,SAAS,EAAE,OAAO,CAACA,YAAW,CAAC,gBAAgB,IAAIA,OAAM,CAAC;AAAA,MAC/E;AAAA,IACD,WACC,kBAAkB,QAAQ,0BAAc,eACxC,kBAAkB,SAAS,0BAAc,YACxC;AACD,UAAI,UAAU,MAAM;AAEnB,QAAC,OAAe,QAAQ,IAAI;AAAA,MAC7B,OAAO;AACN,cAAM,YAAY,OAAO,KAAK,KAAY;AAC1C,cAAM,gBAAgB,GAAG,YAAY,EAAE,KAAK,iBAAiB,OAAO,CAAC;AACrE,YAAI,CAAC,eAAe;AACnB,gBAAM,IAAI;AAAA,YACT,yBAAyB,iBAAiB,OAAO,CAAC;AAAA,UACnD;AAAA,QACD;AACA,YAAI,KAAC,8CAA6B,aAAa,GAAG;AACjD,gBAAM,IAAI;AAAA,YACT,UAAU,iBAAiB,OAAO,CAAC,QAAQ,cAAc,YAAY,MAAM;AAAA,UAC5E;AAAA,QACD;AACA,cAAM,yBAAyB,cAAc,YAAY,CAAC;AAE1D,YAAI,UAAU,WAAW,KAAK,UAAU,CAAC,MAAM,wBAAwB;AAEtE,iBAAO,QAAmB,IAAI,GAAG;AAAA,YAChC,iBAAiB;AAAA,YAChB,MAAc,sBAAsB;AAAA,UACtC;AAAA,QACD,OAAO;AACN,cAAI,uBAAuB,CAAC,sBAAU,YAAY,mBAAmB,GAAG;AACvE,kBAAM,IAAI;AAAA,cACT,uCAAuC,QAAQ,cAAc,SAAS,IAAI;AAAA,YAC3E;AAAA,UACD;AAEA,cAAI,sBAAU,YAAY,mBAAmB,KAAK,CAAC,oBAAoB,cAAc,GAAG;AACvF,kBAAM,IAAI;AAAA,cACT,uCAAuC,QAAQ,cAAc,SAAS,IAAI;AAAA,YAC3E;AAAA,UACD;AAEA,gBAAM,oBAAoB,uCAAoB,8BAA8B,iBAAiB,OAAO,CAAC;AACrG,gBAAM,6BAA6B,mBAAmB,YAAY,8BAA8B;AAEhG,gBAAM,YAAY,MAAM,qBAAwB;AAAA,YAC/C,QAAS,qBAAsC,OAAO;AAAA,YACtD,YAAY,iBAAiB;AAAA,YAC7B,iBAAiB;AAAA,YACjB,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACD,CAAC;AAED,UAAC,cAAsB,QAAQ,IAAI,sBAAU,OAAO,SAAS;AAAA,QAC9D;AAAA,MACD;AAAA,IACD,OAAO;AAEN,MAAC,OAAe,QAAQ,IAAI;AAAA,IAC7B;AAAA,EACD;AAEA,SAAO;AACR;AAEA,MAAM,uBAAuB,CAAyB;AAAA,EACrD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,MASM;AACL,QAAM,gBAAgB,SAAS,UAAU;AACzC,QAAM,gBAAgB,SAAS,UAAU;AACzC,QAAM,gBAAiB,KAAa,eAAe,MAAM;AACzD,QAAM,eAAe,MAAM;AAC1B,QAAI,CAAC,eAAe;AACnB,YAAM,IAAI;AAAA,QACT,mCAAmC,KAAK,UAAU,IAAI,CAAC;AAAA,MACxD;AAAA,IACD;AAEA,UAAM,YAAY,GAAG,OAAU,YAAY,CAAC,CAAQ;AACpD,WAAO,OAAO,WAAW,MAAM,SAAS,OAAO;AAAA,EAChD;AACA,QAAM,eAAe,MAAM;AAC1B,QAAI,CAAC,eAAe;AACnB,YAAM,IAAI;AAAA,QACT,0CAA0C,KAAK;AAAA,UAC9C;AAAA,QACD,CAAC;AAAA,MACF;AAAA,IACD;AAEA,QAAI,CAAC,QAAQ;AACZ,YAAM,IAAI;AAAA,QACT,6BAA6B,KAAK;AAAA,UACjC;AAAA,QACD,CAAC;AAAA,MACF;AAAA,IACD;AAEA,WAAO,OAAO,QAAQ,MAAM,SAAS,OAAO;AAAA,EAC7C;AAEA,MAAI,eAAe;AAClB,QAAI,CAAC,UAAU,4BAA4B;AAC1C,aAAO,aAAa;AAAA,IACrB;AAEA,WAAO,aAAa;AAAA,EACrB;AAEA,SAAO,aAAa;AACrB;",
6
6
  "names": ["entity"]
7
7
  }
@@ -19,7 +19,7 @@ export declare class MikroBackendProvider<D> implements BackendProvider<D> {
19
19
  private get database();
20
20
  get transactional(): <T>(callback: () => Promise<T>, isolationLevel?: IsolationLevel) => Promise<T>;
21
21
  withTransaction<T>(callback: () => Promise<T>): Promise<T>;
22
- get em(): import("@mikro-orm/postgresql").EntityManager<import("@mikro-orm/postgresql").PostgreSqlDriver> | import("@mikro-orm/postgresql").EntityManager<import("@mikro-orm/mysql").MySqlDriver> | import("@mikro-orm/postgresql").EntityManager<import("@mikro-orm/sqlite").SqliteDriver>;
22
+ get em(): import("@mikro-orm/knex").EntityManager<import("@mikro-orm/postgresql").PostgreSqlDriver> | import("@mikro-orm/knex").EntityManager<import("@mikro-orm/mysql").MySqlDriver> | import("@mikro-orm/knex").EntityManager<import("@mikro-orm/sqlite").SqliteDriver>;
23
23
  constructor(mikroType: new () => D, connection: ConnectionOptions, transactionIsolationLevel?: IsolationLevel);
24
24
  constructor(mikroType: new () => D, connection: ConnectionOptions, additionalOptions?: AdditionalOptions);
25
25
  private getDbType;
@@ -28,15 +28,14 @@ export declare class MikroBackendProvider<D> implements BackendProvider<D> {
28
28
  private mapAndAssignKeys;
29
29
  private applyExternalIdFields;
30
30
  visitPathForPopulate: (entityName: string, updateArgBranch: any, populateBranch?: string) => Set<string>;
31
+ private flushOnBatchInserts;
31
32
  find(filter: Filter<D>, pagination?: PaginationOptions, entityMetadata?: EntityMetadata, trace?: TraceOptions): Promise<D[]>;
32
33
  findOne(filter: Filter<D>, entityMetadata?: EntityMetadata, trace?: TraceOptions): Promise<D | null>;
33
34
  findByRelatedId(entity: any, relatedField: string, relatedFieldIds: string[], filter?: any, trace?: TraceOptions): Promise<D[]>;
34
35
  updateOne(id: string | number, updateArgs: Partial<D & {
35
36
  version?: number;
36
37
  }>, trace?: TraceOptions): Promise<D>;
37
- updateMany(updateItems: (Partial<D> & {
38
- id: string;
39
- })[], trace?: TraceOptions): Promise<D[]>;
38
+ updateMany(updateItems: Partial<D>[], trace?: TraceOptions): Promise<D[]>;
40
39
  createOrUpdateMany(items: Partial<D>[], trace?: TraceOptions): Promise<D[]>;
41
40
  createOne(createArgs: Partial<D>, trace?: TraceOptions): Promise<D>;
42
41
  createMany(createItems: Partial<D>[], trace?: TraceOptions): Promise<D[]>;
@@ -251,6 +251,12 @@ class MikroBackendProvider {
251
251
  if (driver.startsWith("SqliteDriver")) return "sqlite";
252
252
  throw new Error(`This driver (${driver}) is not supported!`);
253
253
  }
254
+ // Some connections (ex. sqlite) require an explicit flush during batch inserts
255
+ // to retrieve user defined primary keys correctly.
256
+ flushOnBatchInserts() {
257
+ const driver = this.em.getDriver();
258
+ return driver.constructor.name === "SqliteDriver";
259
+ }
254
260
  async find(filter, pagination, entityMetadata, trace) {
255
261
  trace?.span.updateName(`Mikro-Orm - Find ${this.entityType.name}`);
256
262
  import_logger.logger.trace(
@@ -389,11 +395,13 @@ class MikroBackendProvider {
389
395
  "Running update many with args"
390
396
  );
391
397
  const meta = this.database.em.getMetadata().get(this.entityType.name);
398
+ const primaryKeyField = meta.primaryKeys[0];
392
399
  const entities = await this.database.transactional(async () => {
393
400
  return Promise.all(
394
401
  updateItems.map(async (item) => {
395
- if (!item?.id) throw new Error("You must pass an ID for this entity to update it.");
396
- const entity = await this.database.em.findOneOrFail(this.entityType, item.id, {
402
+ const { [primaryKeyField]: primaryKey } = item;
403
+ if (!primaryKey) throw new Error("You must pass an ID for this entity to update it.");
404
+ const entity = await this.database.em.findOneOrFail(this.entityType, { [primaryKeyField]: primaryKey }, {
397
405
  populate: [...this.visitPathForPopulate(this.entityType.name, item)]
398
406
  });
399
407
  for (const key of meta.primaryKeys) {
@@ -414,19 +422,33 @@ class MikroBackendProvider {
414
422
  { items: (0, import_utils.sanitiseFilterForLogging)(items), entity: this.entityType.name },
415
423
  "Running create or update many with args"
416
424
  );
425
+ const meta = this.database.em.getMetadata().get(this.entityType.name);
426
+ const primaryKeyField = meta.primaryKeys[0];
427
+ const gwMetadata = import_graphweaver.graphweaverMetadata.getEntityMetadataByDataEntity(this.entityType);
428
+ const clientGeneratedPrimaryKeys = gwMetadata?.apiOptions?.clientGeneratedPrimaryKeys ?? false;
417
429
  const entities = await this.database.transactional(async () => {
418
430
  return Promise.all(
419
431
  items.map(async (item) => {
420
432
  let entity;
421
- const { id } = item;
422
- if (id) {
423
- entity = await this.database.em.findOneOrFail(this.entityType, id, {
433
+ const { [primaryKeyField]: primaryKey } = item;
434
+ if (primaryKey) {
435
+ entity = await this.database.em.findOne(this.entityType, { [primaryKeyField]: primaryKey }, {
424
436
  populate: [
425
437
  ...this.visitPathForPopulate(this.entityType.name, item)
426
438
  ]
427
439
  });
428
- import_logger.logger.trace({ item, entity: this.entityType.name }, "Running update with item");
429
- await this.mapAndAssignKeys(entity, this.entityType, item);
440
+ if (entity) {
441
+ import_logger.logger.trace({ item, entity: this.entityType.name }, "Running update with item");
442
+ await this.mapAndAssignKeys(entity, this.entityType, item);
443
+ } else if (clientGeneratedPrimaryKeys) {
444
+ entity = new this.entityType();
445
+ await this.mapAndAssignKeys(entity, this.entityType, item);
446
+ import_logger.logger.trace({ item, entity: this.entityType.name }, "Running create with client-generated key");
447
+ } else {
448
+ throw new Error(
449
+ `Entity ${this.entityType.name} with primary key '${primaryKey}' not found and clientGeneratedPrimaryKeys is not enabled.`
450
+ );
451
+ }
430
452
  } else {
431
453
  entity = new this.entityType();
432
454
  await this.mapAndAssignKeys(entity, this.entityType, item);
@@ -471,14 +493,17 @@ class MikroBackendProvider {
471
493
  "Running create with args"
472
494
  );
473
495
  const entities = await this.database.transactional(async () => {
474
- return Promise.all(
475
- createItems.map(async (item) => {
476
- const entity = new this.entityType();
477
- await this.mapAndAssignKeys(entity, this.entityType, item);
478
- this.database.em.persist(entity);
479
- return entity;
480
- })
481
- );
496
+ const result = [];
497
+ for (const item of createItems) {
498
+ const entity = new this.entityType();
499
+ await this.mapAndAssignKeys(entity, this.entityType, item);
500
+ this.database.em.persist(entity);
501
+ result.push(entity);
502
+ }
503
+ if (this.flushOnBatchInserts()) {
504
+ await this.database.em.flush();
505
+ }
506
+ return result;
482
507
  });
483
508
  import_logger.logger.trace({ entity: this.entityType.name, entities }, "created items");
484
509
  return entities;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/provider/provider.ts"],
4
- "sourcesContent": ["import {\n\tAggregationType,\n\tBackendProvider,\n\tgraphweaverMetadata,\n\tGraphweaverPluginNextFunction,\n\tGraphweaverRequestEvent,\n\tSort,\n\ttrace as startTrace,\n\tTraceMethod,\n\ttraceSync,\n} from '@exogee/graphweaver';\nimport type {\n\tAggregationResult,\n\tBackendProviderConfig,\n\tEntityMetadata,\n\tFieldMetadata,\n\tFilter,\n\tPaginationOptions,\n\tTraceOptions,\n} from '@exogee/graphweaver';\nimport { logger, safeErrorLog } from '@exogee/logger';\nimport {\n\tAutoPath,\n\tLoadStrategy,\n\tPopulateHint,\n\tReference,\n\tRequestContext,\n\tsql,\n} from '@mikro-orm/core';\nimport { pluginManager, apolloPluginManager } from '@exogee/graphweaver-server';\n\nimport {\n\tLockMode,\n\tQueryFlag,\n\tReferenceKind,\n\tConnectionManager,\n\texternalIdFieldMap,\n\tAnyEntity,\n\tIsolationLevel,\n\tConnectionOptions,\n\tconnectToDatabase,\n\tDatabaseType,\n} from '..';\n\nimport { OptimisticLockError, sanitiseFilterForLogging } from '../utils';\nimport { assign } from './assign';\n\ntype PostgresError = {\n\tcode: string;\n\troutine: string;\n};\n\nconst objectOperations = new Set(['_and', '_or', '_not']);\nconst mikroObjectOperations = new Set(['$and', '$or', '$not']);\nconst nullBooleanOperations = new Set(['null', 'notnull']);\n\nconst appendPath = (path: string, newPath: string) =>\n\tpath.length ? `${path}.${newPath}` : newPath;\n\nexport const gqlToMikro = (filter: any, databaseType?: DatabaseType): any => {\n\tif (Array.isArray(filter)) {\n\t\treturn filter.map((element) => gqlToMikro(element, databaseType));\n\t} else if (typeof filter === 'object' && filter !== null) {\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], databaseType);\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], databaseType);\n\t\t\t} else if (key.indexOf('_') >= 0) {\n\t\t\t\tconst [newKey, operator] = key.split('_');\n\t\t\t\tlet newValue;\n\t\t\t\tif (nullBooleanOperations.has(operator) && typeof filter[key] === 'boolean') {\n\t\t\t\t\t// { firstName_null: true } => { firstName: { $eq: null } } or { firstName_null: false } => { firstName: { $ne: null } }\n\t\t\t\t\t// { firstName_notnull: true } => { firstName: { $ne: null } } or { firstName_notnull: false } => { firstName: { $eq: null } }\n\t\t\t\t\tnewValue =\n\t\t\t\t\t\t(filter[key] && operator === 'null') || (!filter[key] && operator === 'notnull')\n\t\t\t\t\t\t\t? { $eq: null }\n\t\t\t\t\t\t\t: { $ne: null };\n\t\t\t\t} else if (operator === 'ilike' && databaseType !== 'postgresql') {\n\t\t\t\t\tlogger.warn(\n\t\t\t\t\t\t`The $ilike operator is not supported by ${databaseType} databases. Operator coerced to $like.`\n\t\t\t\t\t);\n\t\t\t\t\tnewValue = { $like: filter[key] };\n\t\t\t\t} else {\n\t\t\t\t\t// { firstName_in: ['k', 'b'] } => { firstName: { $in: ['k', 'b'] } }\n\t\t\t\t\tnewValue = { [`$${operator}`]: gqlToMikro(filter[key], databaseType) };\n\t\t\t\t\t// They can construct multiple filters for the same key. In that case we need\n\t\t\t\t\t// to append them all into an object.\n\t\t\t\t}\n\n\t\t\t\tif (typeof filter[newKey] !== 'undefined') {\n\t\t\t\t\tif (typeof filter[newKey] !== 'object') {\n\t\t\t\t\t\tif (typeof newValue === 'object' && '$eq' in newValue) {\n\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t`property ${newKey} on filter is ambiguous. There are two values for this property: ${filter[newKey]} and ${newValue.$eq}`\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfilter[newKey] = { ...{ $eq: filter[newKey] }, ...newValue };\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (newValue && typeof newValue === 'object' && '$eq' in newValue) {\n\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t`property ${newKey} on filter is ambiguous. There are two values for this property: ${JSON.stringify(\n\t\t\t\t\t\t\t\t\tfilter[newKey]\n\t\t\t\t\t\t\t\t)} and ${JSON.stringify(newValue)}`\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfilter[newKey] = { ...filter[newKey], ...newValue };\n\t\t\t\t\t}\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\nexport interface AdditionalOptions {\n\ttransactionIsolationLevel?: IsolationLevel;\n\tbackendDisplayName?: string;\n}\n\nexport class MikroBackendProvider<D> implements BackendProvider<D> {\n\tprivate _backendId: string;\n\n\tprivate connection: ConnectionOptions;\n\n\tpublic entityType: new () => D;\n\tpublic connectionManagerId?: string;\n\tprivate transactionIsolationLevel!: IsolationLevel;\n\n\t// This is an optional setting that allows you to control how this provider is displayed in the Admin UI.\n\t// If you do not set a value, it will default to 'REST (hostname of baseUrl)'. Entities are grouped by\n\t// their backend's display name, so if you want to group them in a more specific way, this is the way to do it.\n\tpublic readonly backendDisplayName?: string;\n\n\tpublic readonly supportsInFilter = true;\n\n\t// Default backend provider config\n\tpublic readonly backendProviderConfig: BackendProviderConfig = {\n\t\tfilter: true,\n\t\tpagination: false,\n\t\torderBy: false,\n\t\tsupportedAggregationTypes: new Set<AggregationType>([AggregationType.COUNT]),\n\t\tsupportsPseudoCursorPagination: true,\n\t};\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\tpublic constructor(\n\t\tmikroType: new () => D,\n\t\tconnection: ConnectionOptions,\n\t\ttransactionIsolationLevel?: IsolationLevel\n\t);\n\tpublic constructor(\n\t\tmikroType: new () => D,\n\t\tconnection: ConnectionOptions,\n\t\tadditionalOptions?: AdditionalOptions\n\t);\n\tpublic constructor(\n\t\tmikroType: new () => D,\n\t\tconnection: ConnectionOptions,\n\t\toptionsOrIsolationLevel: AdditionalOptions | IsolationLevel = {\n\t\t\ttransactionIsolationLevel: IsolationLevel.REPEATABLE_READ,\n\t\t}\n\t) {\n\t\tconst options =\n\t\t\ttypeof optionsOrIsolationLevel === 'object'\n\t\t\t\t? optionsOrIsolationLevel\n\t\t\t\t: {\n\t\t\t\t\t\ttransactionIsolationLevel: optionsOrIsolationLevel,\n\t\t\t\t\t};\n\n\t\tthis.entityType = mikroType;\n\t\tthis.connectionManagerId = connection.connectionManagerId;\n\t\tthis._backendId = `mikro-orm-${connection.connectionManagerId || ''}`;\n\t\tthis.transactionIsolationLevel =\n\t\t\toptions.transactionIsolationLevel ?? IsolationLevel.REPEATABLE_READ;\n\t\tthis.backendDisplayName = options.backendDisplayName;\n\t\tthis.connection = connection;\n\t\tthis.addRequestContext();\n\t\tthis.connectToDatabase();\n\t}\n\tprivate getDbType(): DatabaseType {\n\t\tconst driver = this.em.getDriver().constructor.name;\n\t\t// This used to import the actual drivers, but since they're optional it makes more sense\n\t\t// to just use the strings. Using startsWith to handle ESBuild minification that may rename classes.\n\t\tif (driver.startsWith('MsSqlDriver')) return 'mssql';\n\t\tif (driver.startsWith('MySqlDriver')) return 'mysql';\n\t\tif (driver.startsWith('PostgreSqlDriver')) return 'postgresql';\n\t\tif (driver.startsWith('SqliteDriver')) return 'sqlite';\n\n\t\tthrow new Error(`This driver (${driver}) is not supported!`);\n\t}\n\n\tprivate connectToDatabase = async () => {\n\t\tconst connectionManagerId = this.connectionManagerId;\n\t\tif (!connectionManagerId) {\n\t\t\tthrow new Error('Expected connectionManagerId to be defined when calling addRequestContext.');\n\t\t}\n\n\t\tapolloPluginManager.addPlugin(connectionManagerId, connectToDatabase(this.connection));\n\t};\n\n\tprivate addRequestContext = () => {\n\t\tconst connectionManagerId = this.connectionManagerId;\n\t\tif (!connectionManagerId) {\n\t\t\tthrow new Error('Expected connectionManagerId to be defined when calling addRequestContext.');\n\t\t}\n\n\t\tconst connectionPlugin = {\n\t\t\tname: connectionManagerId,\n\t\t\tevent: GraphweaverRequestEvent.OnRequest,\n\t\t\tnext: async (_: GraphweaverRequestEvent, _next: GraphweaverPluginNextFunction) => {\n\t\t\t\tlogger.trace(`Graphweaver OnRequest plugin called`);\n\n\t\t\t\tconst connection = await ConnectionManager.awaitableDatabase(connectionManagerId);\n\n\t\t\t\tif (!connection) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`No database connection found for connectionManagerId: ${connectionManagerId} after waiting for connection. This should not happen.`\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn RequestContext.create(connection.orm.em, _next, {});\n\t\t\t},\n\t\t};\n\t\tpluginManager.addPlugin(connectionPlugin);\n\t};\n\n\tprivate mapAndAssignKeys = (result: D, entityType: new () => D, inputArgs: Partial<D>) => {\n\t\t// Clean the input and remove any GraphQL classes from the object\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]) {\n\t\t\t\t\tconst keys = Object.keys(partialFilterObj[from]);\n\t\t\t\t\tif (keys.length > 1) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Expected precisely 1 key 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][keys[0]];\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\tif (Array.isArray(values[rootLevelKey])) {\n\t\t\t\t\tfor (const field of values[rootLevelKey]) {\n\t\t\t\t\t\tmapFieldNames(field);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tmapFieldNames(values[rootLevelKey]);\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]?.kind === ReferenceKind.ONE_TO_ONE ||\n\t\t\t\tproperties[key]?.kind === ReferenceKind.ONE_TO_MANY ||\n\t\t\t\tproperties[key]?.kind === ReferenceKind.MANY_TO_ONE ||\n\t\t\t\tproperties[key]?.kind === ReferenceKind.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\t@TraceMethod()\n\tpublic async find(\n\t\tfilter: Filter<D>,\n\t\tpagination?: PaginationOptions,\n\t\tentityMetadata?: EntityMetadata,\n\t\ttrace?: TraceOptions\n\t): Promise<D[]> {\n\t\t// If we have a span, update the name\n\t\ttrace?.span.updateName(`Mikro-Orm - Find ${this.entityType.name}`);\n\n\t\tlogger.trace(\n\t\t\t{ filter: sanitiseFilterForLogging(filter), entity: this.entityType.name },\n\t\t\t'Running find with 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\tconst where = traceSync((trace?: TraceOptions) => {\n\t\t\ttrace?.span.updateName('Convert filter to Mikro-Orm format');\n\t\t\treturn filter ? gqlToMikro(JSON.parse(JSON.stringify(filter)), this.getDbType()) : undefined;\n\t\t})();\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 = where\n\t\t\t? this.applyExternalIdFields(this.entityType, where)\n\t\t\t: {};\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.em.createQueryBuilder(this.entityType);\n\t\tif (Object.keys(whereWithAppliedExternalIdFields).length > 0) {\n\t\t\tquery.andWhere(whereWithAppliedExternalIdFields);\n\t\t}\n\n\t\t// If we have specified a limit, offset or order then update the query\n\t\tif (pagination?.limit) query.limit(pagination.limit);\n\t\tif (pagination?.offset) query.offset(pagination.offset);\n\t\tif (pagination?.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\ttry {\n\t\t\tconst result = await startTrace(async (trace?: TraceOptions) => {\n\t\t\t\ttrace?.span.updateName('Mikro-Orm - Fetch Data');\n\t\t\t\treturn query.getResult();\n\t\t\t})();\n\n\t\t\tlogger.trace(`find ${this.entityType.name} result: ${result.length} rows`);\n\n\t\t\treturn result;\n\t\t} catch (err) {\n\t\t\tsafeErrorLog(logger, err, `find ${this.entityType.name} error`);\n\n\t\t\tif ((err as PostgresError)?.routine === 'InitializeSessionUserId') {\n\t\t\t\t// Throw if the user credentials are incorrect\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'Database connection failed, please check you are using the correct user credentials for the database.'\n\t\t\t\t);\n\t\t\t} else if ((err as PostgresError)?.code === 'ECONNREFUSED') {\n\t\t\t\t// Throw if the database address or port is incorrect\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'Database connection failed, please check you are using the correct address and port for the database.'\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t}\n\t}\n\n\t@TraceMethod()\n\tpublic async findOne(\n\t\tfilter: Filter<D>,\n\t\tentityMetadata?: EntityMetadata,\n\t\ttrace?: TraceOptions\n\t): Promise<D | null> {\n\t\ttrace?.span.updateName(`Mikro-Orm - FindOne ${this.entityType.name}`);\n\t\tlogger.trace(\n\t\t\t{ entity: this.entityType.name, filter: sanitiseFilterForLogging(filter) },\n\t\t\t'Running findOne with filter'\n\t\t);\n\n\t\tconst metadata = this.em.getMetadata().get(this.entityType.name);\n\t\tlet primaryKeyField = metadata.primaryKeys[0];\n\n\t\tif (!primaryKeyField && entityMetadata) {\n\t\t\t// When using virtual entities, MikroORM will have no primary keys.\n\t\t\t// In this scenario we actually know what the primary key is from\n\t\t\t// the GraphQL metadata, so we can go ahead and use it.\n\t\t\tprimaryKeyField = graphweaverMetadata.primaryKeyFieldForEntity(entityMetadata);\n\t\t}\n\n\t\tif (!primaryKeyField || metadata.primaryKeys.length > 1) {\n\t\t\tthrow new Error(\n\t\t\t\t`Entity ${this.entityType.name} has ${metadata.primaryKeys.length} primary keys. We only support entities with a single primary key at this stage.`\n\t\t\t);\n\t\t}\n\n\t\tconst [result] = await this.find(filter, {\n\t\t\torderBy: { [primaryKeyField]: Sort.DESC },\n\t\t\toffset: 0,\n\t\t\tlimit: 1,\n\t\t});\n\n\t\tlogger.trace({ result, entity: this.entityType.name }, 'findOne result');\n\n\t\treturn result;\n\t}\n\n\t@TraceMethod()\n\tpublic async findByRelatedId(\n\t\tentity: any,\n\t\trelatedField: string,\n\t\trelatedFieldIds: string[],\n\t\tfilter?: any,\n\t\ttrace?: TraceOptions\n\t): Promise<D[]> {\n\t\ttrace?.span.updateName(`Mikro-Orm - findByRelatedId ${this.entityType.name}`);\n\t\tlogger.trace(\n\t\t\t{\n\t\t\t\tentity: this.entityType.name,\n\t\t\t\trelatedField,\n\t\t\t\trelatedFieldIds,\n\t\t\t\tfilter: sanitiseFilterForLogging(filter),\n\t\t\t},\n\t\t\t'Running findByRelatedId'\n\t\t);\n\n\t\t// Any is the actual type from MikroORM, sorry folks.\n\t\tlet queryFilter: any = { [relatedField]: { $in: relatedFieldIds } };\n\n\t\tif (filter) {\n\t\t\t// JSON.parse(JSON.stringify()) is needed. See https://exogee.atlassian.net/browse/EXOGW-419\n\t\t\tconst gqlToMikroFilter = JSON.parse(JSON.stringify([gqlToMikro(filter, this.getDbType())]));\n\t\t\t// Since the user has supplied a filter, we need to and it in.\n\t\t\tqueryFilter = { $and: [queryFilter, ...gqlToMikroFilter] };\n\t\t}\n\n\t\tconst populate = [relatedField as AutoPath<typeof entity, PopulateHint>];\n\t\tconst result = await this.database.em.find(entity, queryFilter, {\n\t\t\t// We only need one result per entity.\n\t\t\tflags: [QueryFlag.DISTINCT],\n\n\t\t\t// We do want to populate the relation, however, see below.\n\t\t\tpopulate,\n\n\t\t\t// We'd love to use the default joined loading strategy, but it doesn't work with the populateWhere option.\n\t\t\tstrategy: LoadStrategy.SELECT_IN,\n\n\t\t\t// This tells MikroORM we only need to load the related entities if they match the filter specified above.\n\t\t\tpopulateWhere: PopulateHint.INFER,\n\t\t});\n\n\t\treturn result as D[];\n\t}\n\n\t@TraceMethod()\n\tpublic async updateOne(\n\t\tid: string | number,\n\t\tupdateArgs: Partial<D & { version?: number }>,\n\t\ttrace?: TraceOptions\n\t): Promise<D> {\n\t\ttrace?.span.updateName(`Mikro-Orm - updateOne ${this.entityType.name}`);\n\n\t\tlogger.trace(\n\t\t\t{\n\t\t\t\tid,\n\t\t\t\tupdateArgs: sanitiseFilterForLogging(updateArgs),\n\t\t\t\tentity: this.entityType.name,\n\t\t\t},\n\t\t\t'Running update with args'\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\tconst { version, ...updateArgsWithoutVersion } = updateArgs;\n\n\t\t// If a version has been sent, let's check it\n\t\tif (version) {\n\t\t\ttry {\n\t\t\t\tawait this.database.em.lock(entity, LockMode.OPTIMISTIC, 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\t// For an update we also want to go ahead and remove the primary key if it's autoincremented, as\n\t\t// users should not be able to change the primary key. There are also scenarios like\n\t\t// GENERATED ALWAYS AS IDENTITY where even supplying the primary key in the update query will\n\t\t// cause an error.\n\t\tconst meta = this.database.em.getMetadata().get(this.entityType.name);\n\t\tfor (const key of meta.primaryKeys) {\n\t\t\tif (meta.properties[key].autoincrement) delete (updateArgsWithoutVersion as any)[key];\n\t\t}\n\n\t\tawait this.mapAndAssignKeys(entity, this.entityType, updateArgsWithoutVersion as Partial<D>);\n\t\tawait this.database.em.persistAndFlush(entity);\n\n\t\tlogger.trace(`update ${this.entityType.name} entity`, entity);\n\n\t\treturn entity;\n\t}\n\n\t@TraceMethod()\n\tpublic async updateMany(\n\t\tupdateItems: (Partial<D> & { id: string })[],\n\t\ttrace?: TraceOptions\n\t): Promise<D[]> {\n\t\ttrace?.span.updateName(`Mikro-Orm - updateMany ${this.entityType.name}`);\n\t\tlogger.trace(\n\t\t\t{ updateItems: sanitiseFilterForLogging(updateItems), entity: this.entityType.name },\n\t\t\t'Running update many with args'\n\t\t);\n\n\t\tconst meta = this.database.em.getMetadata().get(this.entityType.name);\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\n\t\t\t\t\t// For an update we also want to go ahead and remove the primary key if it's autoincremented, as\n\t\t\t\t\t// users should not be able to change the primary key. There are also scenarios like\n\t\t\t\t\t// GENERATED ALWAYS AS IDENTITY where even supplying the primary key in the update query will\n\t\t\t\t\t// cause an error.\n\t\t\t\t\tfor (const key of meta.primaryKeys) {\n\t\t\t\t\t\tif (meta.properties[key].autoincrement) delete (item as any)[key];\n\t\t\t\t\t}\n\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({ entity: this.entityType.name, entities }, 'updated items');\n\n\t\treturn entities;\n\t}\n\n\t@TraceMethod()\n\tpublic async createOrUpdateMany(items: Partial<D>[], trace?: TraceOptions): Promise<D[]> {\n\t\ttrace?.span.updateName(`Mikro-Orm - createOrUpdateMany ${this.entityType.name}`);\n\t\tlogger.trace(\n\t\t\t{ items: sanitiseFilterForLogging(items), entity: this.entityType.name },\n\t\t\t'Running create or update many with args'\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({ item, entity: this.entityType.name }, 'Running update with item');\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({ item, entity: this.entityType.name }, 'Running create with item');\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(\n\t\t\t{ entity: this.entityType.name, entities: sanitiseFilterForLogging(entities) },\n\t\t\t'created or updated items'\n\t\t);\n\n\t\treturn entities;\n\t}\n\n\t@TraceMethod()\n\tpublic async createOne(createArgs: Partial<D>, trace?: TraceOptions): Promise<D> {\n\t\ttrace?.span.updateName(`Mikro-Orm - createOne ${this.entityType.name}`);\n\t\tlogger.trace(\n\t\t\t{ createArgs: sanitiseFilterForLogging(createArgs), entity: this.entityType.name },\n\t\t\t'Running create with args'\n\t\t);\n\n\t\tconst entity = new this.entityType();\n\t\tawait this.mapAndAssignKeys(entity, this.entityType, createArgs);\n\t\tawait this.database.em.persistAndFlush(entity as Partial<D>);\n\n\t\tlogger.trace(\n\t\t\t{ entity: this.entityType.name, result: sanitiseFilterForLogging(entity) },\n\t\t\t'create result'\n\t\t);\n\n\t\treturn entity;\n\t}\n\n\t@TraceMethod()\n\tpublic async createMany(createItems: Partial<D>[], trace?: TraceOptions): Promise<D[]> {\n\t\ttrace?.span.updateName(`Mikro-Orm - createMany ${this.entityType.name}`);\n\t\treturn this._createMany(createItems);\n\t}\n\n\tpublic async createTraces(createItems: Partial<D>[]): Promise<D[]> {\n\t\treturn this._createMany(createItems);\n\t}\n\n\tprivate async _createMany(createItems: Partial<D>[]) {\n\t\tlogger.trace(\n\t\t\t{ createItems: sanitiseFilterForLogging(createItems), entity: this.entityType.name },\n\t\t\t'Running create with args'\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 as Partial<D>);\n\t\t\t\t\treturn entity;\n\t\t\t\t})\n\t\t\t);\n\t\t});\n\n\t\tlogger.trace({ entity: this.entityType.name, entities }, 'created items');\n\n\t\treturn entities;\n\t}\n\n\t@TraceMethod()\n\tpublic async deleteOne(filter: Filter<D>, trace?: TraceOptions): Promise<boolean> {\n\t\ttrace?.span.updateName(`Mikro-Orm - deleteOne ${this.entityType.name}`);\n\t\tlogger.trace(\n\t\t\t{ filter: sanitiseFilterForLogging(filter), entity: this.entityType.name },\n\t\t\t'Running delete with filter.'\n\t\t);\n\t\tconst where = filter\n\t\t\t? gqlToMikro(JSON.parse(JSON.stringify(filter)), this.getDbType())\n\t\t\t: undefined;\n\t\tconst whereWithAppliedExternalIdFields =\n\t\t\twhere && this.applyExternalIdFields(this.entityType, where);\n\n\t\tconst deletedRows = await this.database.em.nativeDelete(\n\t\t\tthis.entityType,\n\t\t\twhereWithAppliedExternalIdFields\n\t\t);\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\t@TraceMethod()\n\tpublic async deleteMany(filter: Filter<D>, trace?: TraceOptions): Promise<boolean> {\n\t\ttrace?.span.updateName(`Mikro-Orm - deleteMany ${this.entityType.name}`);\n\t\tlogger.trace(\n\t\t\t{ filter: sanitiseFilterForLogging(filter), entity: this.entityType.name },\n\t\t\t'Running delete'\n\t\t);\n\n\t\tconst deletedRows = await this.database.transactional<number>(async () => {\n\t\t\tconst where = filter\n\t\t\t\t? gqlToMikro(JSON.parse(JSON.stringify(filter)), this.getDbType())\n\t\t\t\t: undefined;\n\t\t\tconst whereWithAppliedExternalIdFields =\n\t\t\t\twhere && this.applyExternalIdFields(this.entityType, where);\n\n\t\t\tconst toDelete = await this.database.em.count(\n\t\t\t\tthis.entityType,\n\t\t\t\twhereWithAppliedExternalIdFields\n\t\t\t);\n\t\t\tconst deletedCount = await this.database.em.nativeDelete(\n\t\t\t\tthis.entityType,\n\t\t\t\twhereWithAppliedExternalIdFields\n\t\t\t);\n\n\t\t\tif (deletedCount !== toDelete) {\n\t\t\t\tthrow new Error('We did not delete any 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 true;\n\t}\n\n\tpublic foreignKeyForRelationshipField?(field: FieldMetadata, dataEntity: D) {\n\t\tconst value = dataEntity[field.name as keyof D];\n\n\t\tif (Reference.isReference(value)) {\n\t\t\tconst { properties } = this.database.em.getMetadata().get(this.entityType);\n\t\t\tconst property = properties[field.name];\n\t\t\tconst [primaryKey] = property.targetMeta?.primaryKeys ?? [];\n\t\t\tif (!primaryKey) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Could not determine primary key for ${field.name} on ${this.entityType.name}`\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst foreignKey = (value.unwrap() as any)[primaryKey];\n\t\t\tif (foreignKey === undefined || foreignKey === null) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Could not read foreign key from reference: ${value.unwrap()} with primary key name ${primaryKey}`\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn foreignKey;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t@TraceMethod()\n\tpublic async aggregate(\n\t\tfilter: Filter<D>,\n\t\trequestedAggregations: Set<AggregationType>,\n\t\ttrace?: TraceOptions\n\t): Promise<AggregationResult> {\n\t\ttrace?.span.updateName(`Mikro-Orm - aggregate ${this.entityType.name}`);\n\t\tlogger.trace(\n\t\t\t{ filter: sanitiseFilterForLogging(filter), entity: this.entityType.name },\n\t\t\t'Running aggregate with 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\n\t\t\t? gqlToMikro(JSON.parse(JSON.stringify(filter)), this.getDbType())\n\t\t\t: 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 = where\n\t\t\t? this.applyExternalIdFields(this.entityType, where)\n\t\t\t: {};\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.em.createQueryBuilder(this.entityType);\n\n\t\tif (Object.keys(whereWithAppliedExternalIdFields).length > 0) {\n\t\t\tquery.andWhere(whereWithAppliedExternalIdFields);\n\t\t}\n\n\t\tconst result: AggregationResult = {};\n\n\t\ttry {\n\t\t\tif (requestedAggregations.has(AggregationType.COUNT)) {\n\t\t\t\tconst meta = this.database.em.getMetadata().get(this.entityType.name);\n\t\t\t\tif (meta.primaryKeys.length) {\n\t\t\t\t\t// It's a standard entity with primary keys, we can do a full distinct\n\t\t\t\t\t// on these keys.\n\t\t\t\t\tresult.count = await query.getCount(meta.primaryKeys, true);\n\t\t\t\t} else {\n\t\t\t\t\t// It's either a virtual entity, or it's an entity without primary keys.\n\t\t\t\t\t// We just need to count * as a fallback, no distinct.\n\t\t\t\t\tconst [firstRow] = await query.select(sql`count(*)`.as('count')).execute();\n\t\t\t\t\tresult.count = firstRow.count;\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tsafeErrorLog(logger, err, `find ${this.entityType.name} error`);\n\n\t\t\tif ((err as PostgresError)?.routine === 'InitializeSessionUserId') {\n\t\t\t\t// Throw if the user credentials are incorrect\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'Database connection failed, please check you are using the correct user credentials for the database.'\n\t\t\t\t);\n\t\t\t} else if ((err as PostgresError)?.code === 'ECONNREFUSED') {\n\t\t\t\t// Throw if the database address or port is incorrect\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'Database connection failed, please check you are using the correct address and port for the database.'\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tAggregationType,\n\tBackendProvider,\n\tgraphweaverMetadata,\n\tGraphweaverPluginNextFunction,\n\tGraphweaverRequestEvent,\n\tSort,\n\ttrace as startTrace,\n\tTraceMethod,\n\ttraceSync,\n} from '@exogee/graphweaver';\nimport type {\n\tAggregationResult,\n\tBackendProviderConfig,\n\tEntityMetadata,\n\tFieldMetadata,\n\tFilter,\n\tPaginationOptions,\n\tTraceOptions,\n} from '@exogee/graphweaver';\nimport { logger, safeErrorLog } from '@exogee/logger';\nimport {\n\tAutoPath,\n\tLoadStrategy,\n\tPopulateHint,\n\tReference,\n\tRequestContext,\n\tsql,\n} from '@mikro-orm/core';\nimport { pluginManager, apolloPluginManager } from '@exogee/graphweaver-server';\n\nimport {\n\tLockMode,\n\tQueryFlag,\n\tReferenceKind,\n\tConnectionManager,\n\texternalIdFieldMap,\n\tAnyEntity,\n\tIsolationLevel,\n\tConnectionOptions,\n\tconnectToDatabase,\n\tDatabaseType,\n} from '..';\n\nimport { OptimisticLockError, sanitiseFilterForLogging } from '../utils';\nimport { assign } from './assign';\n\ntype PostgresError = {\n\tcode: string;\n\troutine: string;\n};\n\nconst objectOperations = new Set(['_and', '_or', '_not']);\nconst mikroObjectOperations = new Set(['$and', '$or', '$not']);\nconst nullBooleanOperations = new Set(['null', 'notnull']);\n\nconst appendPath = (path: string, newPath: string) =>\n\tpath.length ? `${path}.${newPath}` : newPath;\n\nexport const gqlToMikro = (filter: any, databaseType?: DatabaseType): any => {\n\tif (Array.isArray(filter)) {\n\t\treturn filter.map((element) => gqlToMikro(element, databaseType));\n\t} else if (typeof filter === 'object' && filter !== null) {\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], databaseType);\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], databaseType);\n\t\t\t} else if (key.indexOf('_') >= 0) {\n\t\t\t\tconst [newKey, operator] = key.split('_');\n\t\t\t\tlet newValue;\n\t\t\t\tif (nullBooleanOperations.has(operator) && typeof filter[key] === 'boolean') {\n\t\t\t\t\t// { firstName_null: true } => { firstName: { $eq: null } } or { firstName_null: false } => { firstName: { $ne: null } }\n\t\t\t\t\t// { firstName_notnull: true } => { firstName: { $ne: null } } or { firstName_notnull: false } => { firstName: { $eq: null } }\n\t\t\t\t\tnewValue =\n\t\t\t\t\t\t(filter[key] && operator === 'null') || (!filter[key] && operator === 'notnull')\n\t\t\t\t\t\t\t? { $eq: null }\n\t\t\t\t\t\t\t: { $ne: null };\n\t\t\t\t} else if (operator === 'ilike' && databaseType !== 'postgresql') {\n\t\t\t\t\tlogger.warn(\n\t\t\t\t\t\t`The $ilike operator is not supported by ${databaseType} databases. Operator coerced to $like.`\n\t\t\t\t\t);\n\t\t\t\t\tnewValue = { $like: filter[key] };\n\t\t\t\t} else {\n\t\t\t\t\t// { firstName_in: ['k', 'b'] } => { firstName: { $in: ['k', 'b'] } }\n\t\t\t\t\tnewValue = { [`$${operator}`]: gqlToMikro(filter[key], databaseType) };\n\t\t\t\t\t// They can construct multiple filters for the same key. In that case we need\n\t\t\t\t\t// to append them all into an object.\n\t\t\t\t}\n\n\t\t\t\tif (typeof filter[newKey] !== 'undefined') {\n\t\t\t\t\tif (typeof filter[newKey] !== 'object') {\n\t\t\t\t\t\tif (typeof newValue === 'object' && '$eq' in newValue) {\n\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t`property ${newKey} on filter is ambiguous. There are two values for this property: ${filter[newKey]} and ${newValue.$eq}`\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfilter[newKey] = { ...{ $eq: filter[newKey] }, ...newValue };\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (newValue && typeof newValue === 'object' && '$eq' in newValue) {\n\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t`property ${newKey} on filter is ambiguous. There are two values for this property: ${JSON.stringify(\n\t\t\t\t\t\t\t\t\tfilter[newKey]\n\t\t\t\t\t\t\t\t)} and ${JSON.stringify(newValue)}`\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfilter[newKey] = { ...filter[newKey], ...newValue };\n\t\t\t\t\t}\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\nexport interface AdditionalOptions {\n\ttransactionIsolationLevel?: IsolationLevel;\n\tbackendDisplayName?: string;\n}\n\nexport class MikroBackendProvider<D> implements BackendProvider<D> {\n\tprivate _backendId: string;\n\n\tprivate connection: ConnectionOptions;\n\n\tpublic entityType: new () => D;\n\tpublic connectionManagerId?: string;\n\tprivate transactionIsolationLevel!: IsolationLevel;\n\n\t// This is an optional setting that allows you to control how this provider is displayed in the Admin UI.\n\t// If you do not set a value, it will default to 'REST (hostname of baseUrl)'. Entities are grouped by\n\t// their backend's display name, so if you want to group them in a more specific way, this is the way to do it.\n\tpublic readonly backendDisplayName?: string;\n\n\tpublic readonly supportsInFilter = true;\n\n\t// Default backend provider config\n\tpublic readonly backendProviderConfig: BackendProviderConfig = {\n\t\tfilter: true,\n\t\tpagination: false,\n\t\torderBy: false,\n\t\tsupportedAggregationTypes: new Set<AggregationType>([AggregationType.COUNT]),\n\t\tsupportsPseudoCursorPagination: true,\n\t};\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\tpublic constructor(\n\t\tmikroType: new () => D,\n\t\tconnection: ConnectionOptions,\n\t\ttransactionIsolationLevel?: IsolationLevel\n\t);\n\tpublic constructor(\n\t\tmikroType: new () => D,\n\t\tconnection: ConnectionOptions,\n\t\tadditionalOptions?: AdditionalOptions\n\t);\n\tpublic constructor(\n\t\tmikroType: new () => D,\n\t\tconnection: ConnectionOptions,\n\t\toptionsOrIsolationLevel: AdditionalOptions | IsolationLevel = {\n\t\t\ttransactionIsolationLevel: IsolationLevel.REPEATABLE_READ,\n\t\t}\n\t) {\n\t\tconst options =\n\t\t\ttypeof optionsOrIsolationLevel === 'object'\n\t\t\t\t? optionsOrIsolationLevel\n\t\t\t\t: {\n\t\t\t\t\t\ttransactionIsolationLevel: optionsOrIsolationLevel,\n\t\t\t\t\t};\n\n\t\tthis.entityType = mikroType;\n\t\tthis.connectionManagerId = connection.connectionManagerId;\n\t\tthis._backendId = `mikro-orm-${connection.connectionManagerId || ''}`;\n\t\tthis.transactionIsolationLevel =\n\t\t\toptions.transactionIsolationLevel ?? IsolationLevel.REPEATABLE_READ;\n\t\tthis.backendDisplayName = options.backendDisplayName;\n\t\tthis.connection = connection;\n\t\tthis.addRequestContext();\n\t\tthis.connectToDatabase();\n\t}\n\tprivate getDbType(): DatabaseType {\n\t\tconst driver = this.em.getDriver().constructor.name;\n\t\t// This used to import the actual drivers, but since they're optional it makes more sense\n\t\t// to just use the strings. Using startsWith to handle ESBuild minification that may rename classes.\n\t\tif (driver.startsWith('MsSqlDriver')) return 'mssql';\n\t\tif (driver.startsWith('MySqlDriver')) return 'mysql';\n\t\tif (driver.startsWith('PostgreSqlDriver')) return 'postgresql';\n\t\tif (driver.startsWith('SqliteDriver')) return 'sqlite';\n\n\t\tthrow new Error(`This driver (${driver}) is not supported!`);\n\t}\n\n\tprivate connectToDatabase = async () => {\n\t\tconst connectionManagerId = this.connectionManagerId;\n\t\tif (!connectionManagerId) {\n\t\t\tthrow new Error('Expected connectionManagerId to be defined when calling addRequestContext.');\n\t\t}\n\n\t\tapolloPluginManager.addPlugin(connectionManagerId, connectToDatabase(this.connection));\n\t};\n\n\tprivate addRequestContext = () => {\n\t\tconst connectionManagerId = this.connectionManagerId;\n\t\tif (!connectionManagerId) {\n\t\t\tthrow new Error('Expected connectionManagerId to be defined when calling addRequestContext.');\n\t\t}\n\n\t\tconst connectionPlugin = {\n\t\t\tname: connectionManagerId,\n\t\t\tevent: GraphweaverRequestEvent.OnRequest,\n\t\t\tnext: async (_: GraphweaverRequestEvent, _next: GraphweaverPluginNextFunction) => {\n\t\t\t\tlogger.trace(`Graphweaver OnRequest plugin called`);\n\n\t\t\t\tconst connection = await ConnectionManager.awaitableDatabase(connectionManagerId);\n\n\t\t\t\tif (!connection) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`No database connection found for connectionManagerId: ${connectionManagerId} after waiting for connection. This should not happen.`\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn RequestContext.create(connection.orm.em, _next, {});\n\t\t\t},\n\t\t};\n\t\tpluginManager.addPlugin(connectionPlugin);\n\t};\n\n\tprivate mapAndAssignKeys = (result: D, entityType: new () => D, inputArgs: Partial<D>) => {\n\t\t// Clean the input and remove any GraphQL classes from the object\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]) {\n\t\t\t\t\tconst keys = Object.keys(partialFilterObj[from]);\n\t\t\t\t\tif (keys.length > 1) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Expected precisely 1 key 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][keys[0]];\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\tif (Array.isArray(values[rootLevelKey])) {\n\t\t\t\t\tfor (const field of values[rootLevelKey]) {\n\t\t\t\t\t\tmapFieldNames(field);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tmapFieldNames(values[rootLevelKey]);\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]?.kind === ReferenceKind.ONE_TO_ONE ||\n\t\t\t\tproperties[key]?.kind === ReferenceKind.ONE_TO_MANY ||\n\t\t\t\tproperties[key]?.kind === ReferenceKind.MANY_TO_ONE ||\n\t\t\t\tproperties[key]?.kind === ReferenceKind.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\t// Some connections (ex. sqlite) require an explicit flush during batch inserts \n\t// to retrieve user defined primary keys correctly.\n\tprivate flushOnBatchInserts() {\n\t\tconst driver = this.em.getDriver();\n\t\treturn driver.constructor.name === 'SqliteDriver';\n\t};\n\n\t@TraceMethod()\n\tpublic async find(\n\t\tfilter: Filter<D>,\n\t\tpagination?: PaginationOptions,\n\t\tentityMetadata?: EntityMetadata,\n\t\ttrace?: TraceOptions\n\t): Promise<D[]> {\n\t\t// If we have a span, update the name\n\t\ttrace?.span.updateName(`Mikro-Orm - Find ${this.entityType.name}`);\n\n\t\tlogger.trace(\n\t\t\t{ filter: sanitiseFilterForLogging(filter), entity: this.entityType.name },\n\t\t\t'Running find with 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\tconst where = traceSync((trace?: TraceOptions) => {\n\t\t\ttrace?.span.updateName('Convert filter to Mikro-Orm format');\n\t\t\treturn filter ? gqlToMikro(JSON.parse(JSON.stringify(filter)), this.getDbType()) : undefined;\n\t\t})();\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 = where\n\t\t\t? this.applyExternalIdFields(this.entityType, where)\n\t\t\t: {};\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.em.createQueryBuilder(this.entityType);\n\t\tif (Object.keys(whereWithAppliedExternalIdFields).length > 0) {\n\t\t\tquery.andWhere(whereWithAppliedExternalIdFields);\n\t\t}\n\n\t\t// If we have specified a limit, offset or order then update the query\n\t\tif (pagination?.limit) query.limit(pagination.limit);\n\t\tif (pagination?.offset) query.offset(pagination.offset);\n\t\tif (pagination?.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\ttry {\n\t\t\tconst result = await startTrace(async (trace?: TraceOptions) => {\n\t\t\t\ttrace?.span.updateName('Mikro-Orm - Fetch Data');\n\t\t\t\treturn query.getResult();\n\t\t\t})();\n\n\t\t\tlogger.trace(`find ${this.entityType.name} result: ${result.length} rows`);\n\n\t\t\treturn result;\n\t\t} catch (err) {\n\t\t\tsafeErrorLog(logger, err, `find ${this.entityType.name} error`);\n\n\t\t\tif ((err as PostgresError)?.routine === 'InitializeSessionUserId') {\n\t\t\t\t// Throw if the user credentials are incorrect\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'Database connection failed, please check you are using the correct user credentials for the database.'\n\t\t\t\t);\n\t\t\t} else if ((err as PostgresError)?.code === 'ECONNREFUSED') {\n\t\t\t\t// Throw if the database address or port is incorrect\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'Database connection failed, please check you are using the correct address and port for the database.'\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t}\n\t}\n\n\t@TraceMethod()\n\tpublic async findOne(\n\t\tfilter: Filter<D>,\n\t\tentityMetadata?: EntityMetadata,\n\t\ttrace?: TraceOptions\n\t): Promise<D | null> {\n\t\ttrace?.span.updateName(`Mikro-Orm - FindOne ${this.entityType.name}`);\n\t\tlogger.trace(\n\t\t\t{ entity: this.entityType.name, filter: sanitiseFilterForLogging(filter) },\n\t\t\t'Running findOne with filter'\n\t\t);\n\n\t\tconst metadata = this.em.getMetadata().get(this.entityType.name);\n\t\tlet primaryKeyField = metadata.primaryKeys[0];\n\n\t\tif (!primaryKeyField && entityMetadata) {\n\t\t\t// When using virtual entities, MikroORM will have no primary keys.\n\t\t\t// In this scenario we actually know what the primary key is from\n\t\t\t// the GraphQL metadata, so we can go ahead and use it.\n\t\t\tprimaryKeyField = graphweaverMetadata.primaryKeyFieldForEntity(entityMetadata);\n\t\t}\n\n\t\tif (!primaryKeyField || metadata.primaryKeys.length > 1) {\n\t\t\tthrow new Error(\n\t\t\t\t`Entity ${this.entityType.name} has ${metadata.primaryKeys.length} primary keys. We only support entities with a single primary key at this stage.`\n\t\t\t);\n\t\t}\n\n\t\tconst [result] = await this.find(filter, {\n\t\t\torderBy: { [primaryKeyField]: Sort.DESC },\n\t\t\toffset: 0,\n\t\t\tlimit: 1,\n\t\t});\n\n\t\tlogger.trace({ result, entity: this.entityType.name }, 'findOne result');\n\n\t\treturn result;\n\t}\n\n\t@TraceMethod()\n\tpublic async findByRelatedId(\n\t\tentity: any,\n\t\trelatedField: string,\n\t\trelatedFieldIds: string[],\n\t\tfilter?: any,\n\t\ttrace?: TraceOptions\n\t): Promise<D[]> {\n\t\ttrace?.span.updateName(`Mikro-Orm - findByRelatedId ${this.entityType.name}`);\n\t\tlogger.trace(\n\t\t\t{\n\t\t\t\tentity: this.entityType.name,\n\t\t\t\trelatedField,\n\t\t\t\trelatedFieldIds,\n\t\t\t\tfilter: sanitiseFilterForLogging(filter),\n\t\t\t},\n\t\t\t'Running findByRelatedId'\n\t\t);\n\n\t\t// Any is the actual type from MikroORM, sorry folks.\n\t\tlet queryFilter: any = { [relatedField]: { $in: relatedFieldIds } };\n\n\t\tif (filter) {\n\t\t\t// JSON.parse(JSON.stringify()) is needed. See https://exogee.atlassian.net/browse/EXOGW-419\n\t\t\tconst gqlToMikroFilter = JSON.parse(JSON.stringify([gqlToMikro(filter, this.getDbType())]));\n\t\t\t// Since the user has supplied a filter, we need to and it in.\n\t\t\tqueryFilter = { $and: [queryFilter, ...gqlToMikroFilter] };\n\t\t}\n\n\t\tconst populate = [relatedField as AutoPath<typeof entity, PopulateHint>];\n\t\tconst result = await this.database.em.find(entity, queryFilter, {\n\t\t\t// We only need one result per entity.\n\t\t\tflags: [QueryFlag.DISTINCT],\n\n\t\t\t// We do want to populate the relation, however, see below.\n\t\t\tpopulate,\n\n\t\t\t// We'd love to use the default joined loading strategy, but it doesn't work with the populateWhere option.\n\t\t\tstrategy: LoadStrategy.SELECT_IN,\n\n\t\t\t// This tells MikroORM we only need to load the related entities if they match the filter specified above.\n\t\t\tpopulateWhere: PopulateHint.INFER,\n\t\t});\n\n\t\treturn result as D[];\n\t}\n\n\t@TraceMethod()\n\tpublic async updateOne(\n\t\tid: string | number,\n\t\tupdateArgs: Partial<D & { version?: number }>,\n\t\ttrace?: TraceOptions\n\t): Promise<D> {\n\t\ttrace?.span.updateName(`Mikro-Orm - updateOne ${this.entityType.name}`);\n\n\t\tlogger.trace(\n\t\t\t{\n\t\t\t\tid,\n\t\t\t\tupdateArgs: sanitiseFilterForLogging(updateArgs),\n\t\t\t\tentity: this.entityType.name,\n\t\t\t},\n\t\t\t'Running update with args'\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\tconst { version, ...updateArgsWithoutVersion } = updateArgs;\n\n\t\t// If a version has been sent, let's check it\n\t\tif (version) {\n\t\t\ttry {\n\t\t\t\tawait this.database.em.lock(entity, LockMode.OPTIMISTIC, 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\t// For an update we also want to go ahead and remove the primary key if it's autoincremented, as\n\t\t// users should not be able to change the primary key. There are also scenarios like\n\t\t// GENERATED ALWAYS AS IDENTITY where even supplying the primary key in the update query will\n\t\t// cause an error.\n\t\tconst meta = this.database.em.getMetadata().get(this.entityType.name);\n\t\tfor (const key of meta.primaryKeys) {\n\t\t\tif (meta.properties[key].autoincrement) delete (updateArgsWithoutVersion as any)[key];\n\t\t}\n\n\t\tawait this.mapAndAssignKeys(entity, this.entityType, updateArgsWithoutVersion as Partial<D>);\n\t\tawait this.database.em.persistAndFlush(entity);\n\n\t\tlogger.trace(`update ${this.entityType.name} entity`, entity);\n\n\t\treturn entity;\n\t}\n\n\t@TraceMethod()\n\tpublic async updateMany(\n\t\tupdateItems: Partial<D>[],\n\t\ttrace?: TraceOptions\n\t): Promise<D[]> {\n\t\ttrace?.span.updateName(`Mikro-Orm - updateMany ${this.entityType.name}`);\n\t\tlogger.trace(\n\t\t\t{ updateItems: sanitiseFilterForLogging(updateItems), entity: this.entityType.name },\n\t\t\t'Running update many with args'\n\t\t);\n\n\t\tconst meta = this.database.em.getMetadata().get(this.entityType.name);\n\t\tconst primaryKeyField = meta.primaryKeys[0];\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\tconst { [primaryKeyField]: primaryKey } = item as any;\n\t\t\t\t\tif (!primaryKey) 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, { [primaryKeyField]: primaryKey } as any, {\n\t\t\t\t\t\tpopulate: [...this.visitPathForPopulate(this.entityType.name, item)] as `${string}.`[],\n\t\t\t\t\t});\n\n\t\t\t\t\t// For an update we also want to go ahead and remove the primary key if it's autoincremented, as\n\t\t\t\t\t// users should not be able to change the primary key. There are also scenarios like\n\t\t\t\t\t// GENERATED ALWAYS AS IDENTITY where even supplying the primary key in the update query will\n\t\t\t\t\t// cause an error.\n\t\t\t\t\tfor (const key of meta.primaryKeys) {\n\t\t\t\t\t\tif (meta.properties[key].autoincrement) delete (item as any)[key];\n\t\t\t\t\t}\n\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({ entity: this.entityType.name, entities }, 'updated items');\n\n\t\treturn entities;\n\t}\n\n\t@TraceMethod()\n\tpublic async createOrUpdateMany(items: Partial<D>[], trace?: TraceOptions): Promise<D[]> {\n\t\ttrace?.span.updateName(`Mikro-Orm - createOrUpdateMany ${this.entityType.name}`);\n\t\tlogger.trace(\n\t\t\t{ items: sanitiseFilterForLogging(items), entity: this.entityType.name },\n\t\t\t'Running create or update many with args'\n\t\t);\n\n\t\tconst meta = this.database.em.getMetadata().get(this.entityType.name);\n\t\tconst primaryKeyField = meta.primaryKeys[0];\n\t\tconst gwMetadata = graphweaverMetadata.getEntityMetadataByDataEntity(this.entityType);\n\t\tconst clientGeneratedPrimaryKeys = gwMetadata?.apiOptions?.clientGeneratedPrimaryKeys ?? false;\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 { [primaryKeyField]: primaryKey } = item as any;\n\n\t\t\t\t\tif (primaryKey) {\n\t\t\t\t\t\tentity = await this.database.em.findOne(this.entityType, { [primaryKeyField]: primaryKey }, {\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\n\t\t\t\t\t\tif (entity) {\n\t\t\t\t\t\t\tlogger.trace({ item, entity: this.entityType.name }, 'Running update with item');\n\t\t\t\t\t\t\tawait this.mapAndAssignKeys(entity, this.entityType, item);\n\t\t\t\t\t\t} else if (clientGeneratedPrimaryKeys) {\n\t\t\t\t\t\t\tentity = new this.entityType();\n\t\t\t\t\t\t\tawait this.mapAndAssignKeys(entity, this.entityType, item);\n\t\t\t\t\t\t\tlogger.trace({ item, entity: this.entityType.name }, 'Running create with client-generated key');\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t`Entity ${this.entityType.name} with primary key '${primaryKey}' not found and clientGeneratedPrimaryKeys is not enabled.`\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\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({ item, entity: this.entityType.name }, 'Running create with item');\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(\n\t\t\t{ entity: this.entityType.name, entities: sanitiseFilterForLogging(entities) },\n\t\t\t'created or updated items'\n\t\t);\n\n\t\treturn entities;\n\t}\n\n\t@TraceMethod()\n\tpublic async createOne(createArgs: Partial<D>, trace?: TraceOptions): Promise<D> {\n\t\ttrace?.span.updateName(`Mikro-Orm - createOne ${this.entityType.name}`);\n\t\tlogger.trace(\n\t\t\t{ createArgs: sanitiseFilterForLogging(createArgs), entity: this.entityType.name },\n\t\t\t'Running create with args'\n\t\t);\n\n\t\tconst entity = new this.entityType();\n\t\tawait this.mapAndAssignKeys(entity, this.entityType, createArgs);\n\t\tawait this.database.em.persistAndFlush(entity as Partial<D>);\n\n\t\tlogger.trace(\n\t\t\t{ entity: this.entityType.name, result: sanitiseFilterForLogging(entity) },\n\t\t\t'create result'\n\t\t);\n\n\t\treturn entity;\n\t}\n\n\t@TraceMethod()\n\tpublic async createMany(createItems: Partial<D>[], trace?: TraceOptions): Promise<D[]> {\n\t\ttrace?.span.updateName(`Mikro-Orm - createMany ${this.entityType.name}`);\n\t\treturn this._createMany(createItems);\n\t}\n\n\tpublic async createTraces(createItems: Partial<D>[]): Promise<D[]> {\n\t\treturn this._createMany(createItems);\n\t}\n\n\tprivate async _createMany(createItems: Partial<D>[]) {\n\t\tlogger.trace(\n\t\t\t{ createItems: sanitiseFilterForLogging(createItems), entity: this.entityType.name },\n\t\t\t'Running create with args'\n\t\t);\n\n\t\tconst entities = await this.database.transactional<D[]>(async () => {\n\t\t\tconst result: D[] = [];\n\t\t\tfor (const item of createItems) {\n\t\t\t\tconst entity = new this.entityType();\n\t\t\t\tawait this.mapAndAssignKeys(entity, this.entityType, item);\n\t\t\t\tthis.database.em.persist(entity as Partial<D>);\n\t\t\t\tresult.push(entity);\n\t\t\t}\n\n\t\t\tif (this.flushOnBatchInserts()) {\n\t\t\t\tawait this.database.em.flush();\n\t\t\t}\n\n\t\t\treturn result;\n\t\t});\n\n\t\tlogger.trace({ entity: this.entityType.name, entities }, 'created items');\n\n\t\treturn entities;\n\t}\n\n\t@TraceMethod()\n\tpublic async deleteOne(filter: Filter<D>, trace?: TraceOptions): Promise<boolean> {\n\t\ttrace?.span.updateName(`Mikro-Orm - deleteOne ${this.entityType.name}`);\n\t\tlogger.trace(\n\t\t\t{ filter: sanitiseFilterForLogging(filter), entity: this.entityType.name },\n\t\t\t'Running delete with filter.'\n\t\t);\n\t\tconst where = filter\n\t\t\t? gqlToMikro(JSON.parse(JSON.stringify(filter)), this.getDbType())\n\t\t\t: undefined;\n\t\tconst whereWithAppliedExternalIdFields =\n\t\t\twhere && this.applyExternalIdFields(this.entityType, where);\n\n\t\tconst deletedRows = await this.database.em.nativeDelete(\n\t\t\tthis.entityType,\n\t\t\twhereWithAppliedExternalIdFields\n\t\t);\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\t@TraceMethod()\n\tpublic async deleteMany(filter: Filter<D>, trace?: TraceOptions): Promise<boolean> {\n\t\ttrace?.span.updateName(`Mikro-Orm - deleteMany ${this.entityType.name}`);\n\t\tlogger.trace(\n\t\t\t{ filter: sanitiseFilterForLogging(filter), entity: this.entityType.name },\n\t\t\t'Running delete'\n\t\t);\n\n\t\tconst deletedRows = await this.database.transactional<number>(async () => {\n\t\t\tconst where = filter\n\t\t\t\t? gqlToMikro(JSON.parse(JSON.stringify(filter)), this.getDbType())\n\t\t\t\t: undefined;\n\t\t\tconst whereWithAppliedExternalIdFields =\n\t\t\t\twhere && this.applyExternalIdFields(this.entityType, where);\n\n\t\t\tconst toDelete = await this.database.em.count(\n\t\t\t\tthis.entityType,\n\t\t\t\twhereWithAppliedExternalIdFields\n\t\t\t);\n\t\t\tconst deletedCount = await this.database.em.nativeDelete(\n\t\t\t\tthis.entityType,\n\t\t\t\twhereWithAppliedExternalIdFields\n\t\t\t);\n\n\t\t\tif (deletedCount !== toDelete) {\n\t\t\t\tthrow new Error('We did not delete any 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 true;\n\t}\n\n\tpublic foreignKeyForRelationshipField?(field: FieldMetadata, dataEntity: D) {\n\t\tconst value = dataEntity[field.name as keyof D];\n\n\t\tif (Reference.isReference(value)) {\n\t\t\tconst { properties } = this.database.em.getMetadata().get(this.entityType);\n\t\t\tconst property = properties[field.name];\n\t\t\tconst [primaryKey] = property.targetMeta?.primaryKeys ?? [];\n\t\t\tif (!primaryKey) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Could not determine primary key for ${field.name} on ${this.entityType.name}`\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst foreignKey = (value.unwrap() as any)[primaryKey];\n\t\t\tif (foreignKey === undefined || foreignKey === null) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Could not read foreign key from reference: ${value.unwrap()} with primary key name ${primaryKey}`\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn foreignKey;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t@TraceMethod()\n\tpublic async aggregate(\n\t\tfilter: Filter<D>,\n\t\trequestedAggregations: Set<AggregationType>,\n\t\ttrace?: TraceOptions\n\t): Promise<AggregationResult> {\n\t\ttrace?.span.updateName(`Mikro-Orm - aggregate ${this.entityType.name}`);\n\t\tlogger.trace(\n\t\t\t{ filter: sanitiseFilterForLogging(filter), entity: this.entityType.name },\n\t\t\t'Running aggregate with 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\n\t\t\t? gqlToMikro(JSON.parse(JSON.stringify(filter)), this.getDbType())\n\t\t\t: 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 = where\n\t\t\t? this.applyExternalIdFields(this.entityType, where)\n\t\t\t: {};\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.em.createQueryBuilder(this.entityType);\n\n\t\tif (Object.keys(whereWithAppliedExternalIdFields).length > 0) {\n\t\t\tquery.andWhere(whereWithAppliedExternalIdFields);\n\t\t}\n\n\t\tconst result: AggregationResult = {};\n\n\t\ttry {\n\t\t\tif (requestedAggregations.has(AggregationType.COUNT)) {\n\t\t\t\tconst meta = this.database.em.getMetadata().get(this.entityType.name);\n\t\t\t\tif (meta.primaryKeys.length) {\n\t\t\t\t\t// It's a standard entity with primary keys, we can do a full distinct\n\t\t\t\t\t// on these keys.\n\t\t\t\t\tresult.count = await query.getCount(meta.primaryKeys, true);\n\t\t\t\t} else {\n\t\t\t\t\t// It's either a virtual entity, or it's an entity without primary keys.\n\t\t\t\t\t// We just need to count * as a fallback, no distinct.\n\t\t\t\t\tconst [firstRow] = await query.select(sql`count(*)`.as('count')).execute();\n\t\t\t\t\tresult.count = firstRow.count;\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tsafeErrorLog(logger, err, `find ${this.entityType.name} error`);\n\n\t\t\tif ((err as PostgresError)?.routine === 'InitializeSessionUserId') {\n\t\t\t\t// Throw if the user credentials are incorrect\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'Database connection failed, please check you are using the correct user credentials for the database.'\n\t\t\t\t);\n\t\t\t} else if ((err as PostgresError)?.code === 'ECONNREFUSED') {\n\t\t\t\t// Throw if the database address or port is incorrect\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'Database connection failed, please check you are using the correct address and port for the database.'\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["trace", "startTrace"]
7
7
  }
package/package.json CHANGED
@@ -1,8 +1,12 @@
1
1
  {
2
2
  "name": "@exogee/graphweaver-mikroorm",
3
- "version": "2.21.0",
3
+ "version": "2.21.2",
4
4
  "description": "MikroORM backend for @exogee/graphweaver",
5
5
  "license": "Apache-2.0",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/exogee-technology/graphweaver.git"
9
+ },
6
10
  "sideEffects": false,
7
11
  "main": "lib/index.js",
8
12
  "source": "src/index.ts",
@@ -13,16 +17,16 @@
13
17
  "lib"
14
18
  ],
15
19
  "dependencies": {
16
- "@apollo/server": "5.2.0",
17
- "@aws-sdk/client-secrets-manager": "3.971.0",
20
+ "@apollo/server": "5.4.0",
21
+ "@aws-sdk/client-secrets-manager": "3.986.0",
18
22
  "dataloader": "2.2.3",
19
23
  "decimal.js": "10.6.0",
20
24
  "dotenv": "17.2.3",
21
25
  "pluralize": "8.0.0",
22
26
  "reflect-metadata": "0.2.2",
23
- "@exogee/graphweaver": "2.21.0",
24
- "@exogee/logger": "2.21.0",
25
- "@exogee/graphweaver-server": "2.21.0"
27
+ "@exogee/logger": "2.21.2",
28
+ "@exogee/graphweaver": "2.21.2",
29
+ "@exogee/graphweaver-server": "2.21.2"
26
30
  },
27
31
  "peerDependencies": {
28
32
  "@mikro-orm/core": "6",