chore(order): dml (#10292)

* ../../core/types/src/dml/index.ts

* ../../core/types/src/dml/index.ts

* fix: relationships mapping

* handle nullable foreign keys types

* handle nullable foreign keys types

* handle nullable foreign keys types

* continue to update product category repository

* fix all product category repositories issues

* fix product category service types

* fix product module service types

* fix product module service types

* fix repository template type

* refactor: use a singleton DMLToMikroORM factory instance

Since the MikroORM MetadataStorage is global, we will also have to turn DML
to MikroORM entities conversion use a global bucket as well

* refactor: update product module to use DML in tests

* wip: tests

* WIP product linkable fixes

* continue type fixing and start test fixing

* test: fix more tests

* fix repository

* fix pivot table computaion + fix mikro orm repository

* fix many to many management and configuration

* fix many to many management and configuration

* fix many to many management and configuration

* update product tag relation configuration

* Introduce experimental dml hooks to fix some issues with categories

* more fixes

* fix product tests

* add missing id prefixes

* fix product category handle management

* test: fix more failing tests

* test: make it all green

* test: fix breaking tests

* fix: build issues

* fix: build issues

* fix: more breaking tests

* refactor: fix issues after merge

* refactor: fix issues after merge

* refactor: surpress types error

* test: fix DML failing tests

* improve many to many inference + tests

* Wip fix columns from product entity

* remove product model before create hook and manage handle validation and transformation at the service level

* test: fix breaking unit tests

* fix: product module service to not update handle on product update

* fix define link and joiner config

* test: fix joiner config test

* test: fix joiner config test

* fix joiner config primary keys

* Fix joiner config builder

* Fix joiner config builder

* test: remove only modifier from test

* refactor: remove hooks usage from product collection

* refactor: remove hooks usage from product-option

* refactor: remove hooks usage for computing category handle

* refactor: remove hooks usage from productCategory model

* refactor: remove hooks from DML

* refactor: remove cruft

* order dml

* cleanup

* re add foerign key indexes

* wip

* chore: remove unused types

* wip

* changes

* rm raw

* autoincrement

* wip

* rel

* refactor: cleanup

* migration and models configuration adjustments

* cleanup

* number searchable

* fix random ordering

* fix

* test: fix product-category tests

* test: update breaking DML tests

* test: array assertion to not care about ordering

* fix: temporarily apply id ordering for products

* types

* wip

* WIP type improvements

* update order models

* partially fix types temporarely

* rel

* fix: recursive type issue

* improve type inference breaks

* improve type inference breaks

* update models

* rm nullable

* default value

* repository

* update default value handling

* fix unit tests

* WIP

* toMikroORM

* fix relations

* cascades

* fix

* experimental dml hooks

* rm migration

* serial

* nullable autoincrement

* fix model

* model changes

* fix one to one DML

* order test

* fix addresses

* fix unit tests

* Re align dml entity name inference

* update model table name config

* update model table name config

* revert

* update return relation

* WIP

* hasOne

* models

* fix

* model

* initial commit

* cart service

* order module

* utils unit test

* index engine

* changeset

* merge

* fix hasOne with fk

* update

* free text filter per entity

* tests

* prod category

* property string many to many

* fix big number

* link modules migration set names

* merge

* shipping option rules

* serializer

* unit test

* fix test mikro orm init

* fix test mikro orm init

* Maintain merge object properties

* fix test mikro orm init

* prevent unit test from connecting to db

* wip

* fix test

* fix test

* link test

* schema

* models

* auto increment

* hook

* model hooks

* order

* wip

* orm version

* request return field

* fix return configuration on order model

* workflows

* core flows

* unit test

* test

* base repo

* test

* base repo

* test fix

* inventory move

* locking inventory

* test

* free text fix

* rm timeout mock

* migrate fulfillment values

* v6.4.3

* cleanup

* link-modules update sql

* revert test

* remove fake timers

---------

Co-authored-by: adrien2p <adrien.deperetti@gmail.com>
Co-authored-by: Harminder Virk <virk.officials@gmail.com>
Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>
This commit is contained in:
authored and GitHub committed 2025-01-21 08:04:47 -05:00
1 parent 05c8a67d8e
commit cc73802ab3
178 files changed
+5731 -7120

No files matched your search

File diff suppressed because it is too large. Load diff
@@ -6,6 +6,7 @@ import {
import { DmlEntity, DMLEntitySchemaBuilder } from "./entity"
import { createBigNumberProperties } from "./helpers/entity-builder/create-big-number-properties"
import { createDefaultProperties } from "./helpers/entity-builder/create-default-properties"
import { FloatProperty } from "./properties"
import { ArrayProperty } from "./properties/array"
import { AutoIncrementProperty } from "./properties/autoincrement"
import { BigNumberProperty } from "./properties/big-number"
@@ -21,7 +22,6 @@ import { HasMany } from "./relations/has-many"
import { HasOne } from "./relations/has-one"
import { HasOneWithForeignKey } from "./relations/has-one-fk"
import { ManyToMany } from "./relations/many-to-many"
import { FloatProperty } from "./properties"
/**
* The implicit properties added by EntityBuilder in every schema
@@ -128,7 +128,7 @@ export class EntityBuilder {
): DmlEntity<DMLEntitySchemaBuilder<Schema>, TConfig> {
this.#disallowImplicitProperties(schema)
return new DmlEntity<Schema, TConfig>(nameOrConfig, {
return new DmlEntity(nameOrConfig, {
...schema,
...createBigNumberProperties(schema),
...createDefaultProperties(),
+9 -12
View File
@@ -1,21 +1,19 @@
import {
IDmlEntity,
DMLSchema,
EntityIndex,
CheckConstraint,
DMLSchema,
EntityCascades,
QueryCondition,
IDmlEntityConfig,
EntityIndex,
ExtractEntityRelations,
IDmlEntity,
IDmlEntityConfig,
InferDmlEntityNameFromConfig,
QueryCondition,
} from "@medusajs/types"
import { isObject, isString, toCamelCase, upperCaseFirst } from "../common"
import { transformIndexWhere } from "./helpers/entity-builder/build-indexes"
import { DMLSchemaWithBigNumber } from "./helpers/entity-builder/create-big-number-properties"
import { DMLSchemaDefaults } from "./helpers/entity-builder/create-default-properties"
import { BelongsTo } from "./relations/belongs-to"
import {
DMLSchemaDefaults,
DMLSchemaWithBigNumber,
} from "./helpers/entity-builder"
const IsDmlEntity = Symbol.for("isDmlEntity")
@@ -68,7 +66,7 @@ function extractNameAndTableName<const Config extends IDmlEntityConfig>(
* name, its schema and relationships.
*/
export class DmlEntity<
Schema extends DMLSchema,
const Schema extends DMLSchema,
const TConfig extends IDmlEntityConfig
> implements IDmlEntity<Schema, TConfig>
{
@@ -79,6 +77,7 @@ export class DmlEntity<
readonly #tableName: string
#cascades: EntityCascades<string[], string[]> = {}
#indexes: EntityIndex<Schema>[] = []
#checks: CheckConstraint<Schema>[] = []
@@ -251,8 +250,6 @@ export class DmlEntity<
return this
}
/**
*/
checks(checks: CheckConstraint<Schema>[]) {
this.#checks = checks
return this
@@ -8,15 +8,18 @@ import type {
} from "@medusajs/types"
import { Entity, Filter } from "@mikro-orm/core"
import {
mikroOrmFreeTextSearchFilterOptionsFactory,
mikroOrmSoftDeletableFilterOptions,
} from "../../dal"
import { DmlEntity } from "../entity"
import { IdProperty } from "../properties/id"
import { DuplicateIdPropertyError } from "../errors"
import { applyChecks } from "./mikro-orm/apply-checks"
import { mikroOrmSoftDeletableFilterOptions } from "../../dal"
import { defineProperty } from "./entity-builder/define-property"
import { IdProperty } from "../properties/id"
import { applySearchable } from "./entity-builder/apply-searchable"
import { parseEntityName } from "./entity-builder/parse-entity-name"
import { defineProperty } from "./entity-builder/define-property"
import { defineRelationship } from "./entity-builder/define-relationship"
import { parseEntityName } from "./entity-builder/parse-entity-name"
import { applyChecks } from "./mikro-orm/apply-checks"
import { applyEntityIndexes, applyIndexes } from "./mikro-orm/apply-indexes"
/**
@@ -48,8 +51,16 @@ function createMikrORMEntity() {
function createEntity<T extends DmlEntity<any, any>>(entity: T): Infer<T> {
class MikroORMEntity {}
const { schema, cascades, indexes: entityIndexes, checks } = entity.parse()
const {
schema,
cascades,
indexes: entityIndexes = [],
//params,
checks,
} = entity.parse()
const { modelName, tableName } = parseEntityName(entity)
if (ENTITIES[modelName]) {
return ENTITIES[modelName] as Infer<T>
}
@@ -102,6 +113,9 @@ function createMikrORMEntity() {
/**
* Converting class to a MikroORM entity
*/
Filter(mikroOrmFreeTextSearchFilterOptionsFactory(modelName))(
MikroORMEntity
)
const RegisteredEntity = Entity({ tableName })(
Filter(mikroOrmSoftDeletableFilterOptions)(MikroORMEntity)
) as Infer<T>
@@ -12,7 +12,6 @@ import {
PrimaryKey,
Property,
Utils,
t as mikroOrmType,
} from "@mikro-orm/core"
import { generateEntityId, isDefined } from "../../../common"
import { MikroOrmBigNumberProperty } from "../../../dal"
@@ -122,7 +121,8 @@ export function defineProperty(
) {
const field = property.parse(propertyName)
/**
* Here we initialize nullable properties with a null value
* Here we initialize all properties with their default values on before create
* which means when persist is called but not necessarely flush
*/
if (isDefined(field.defaultValue) || field.nullable) {
const defaultValueSetterHookName = `${field.fieldName}_setDefaultValueOnBeforeCreate`
@@ -274,11 +274,12 @@ export function defineProperty(
: Property
Prop({
columnType: "serial",
type: mikroOrmType.integer,
nullable: true,
autoincrement: true,
type: "number",
runtimeType: "number",
nullable: field.nullable,
fieldName: field.fieldName,
serializer: Number,
serializer: (value) => (value == null ? value : Number(value)),
})(MikroORMEntity.prototype, field.fieldName)
return
}
@@ -290,13 +291,14 @@ export function defineProperty(
Property({
columnType: "real",
type: "number",
runtimeType: "number",
nullable: field.nullable,
fieldName: field.fieldName,
/**
* Applying number serializer to convert value back to a
* JavaScript number
*/
serializer: Number,
serializer: (value) => (value == null ? value : Number(value)),
/**
* MikroORM does not ignore undefined values for default when generating
* the database schema SQL. Conditionally add it here to prevent undefined
@@ -162,7 +162,7 @@ export function defineHasOneRelationship(
entity: relatedModelName,
...(relationship.nullable ? { nullable: relationship.nullable } : {}),
...(mappedBy ? { mappedBy } : {}),
onDelete: shouldRemoveRelated ? "cascade" : undefined,
deleteRule: shouldRemoveRelated ? "cascade" : undefined,
} as OneToOneOptions<any, any>
if (shouldRemoveRelated && !isOthersideBelongsTo) {
@@ -322,7 +322,7 @@ export function defineBelongsToRelationship(
/**
* In DML the relationships are cascaded from parent to child. A belongsTo
* relationship is always a child, therefore we look at the parent and
* define a onDelete: cascade when we are included in the delete
* define a deleteRule: cascade when we are included in the delete
* list of parent cascade.
*/
const shouldCascade = !!relationCascades.delete?.includes(mappedBy)
@@ -435,27 +435,33 @@ export function defineBelongsToRelationship(
if (DmlManyToMany.isManyToMany(otherSideRelation)) {
Property({
type: relatedModelName,
type: "string",
columnType: "text",
fieldName: foreignKeyName,
nullable: relationship.nullable,
})(MikroORMEntity.prototype, foreignKeyName)
ManyToOne({
const conf = {
entity: relatedModelName,
nullable: relationship.nullable,
persist: false,
onDelete: shouldCascade || detachCascade ? "cascade" : undefined,
})(MikroORMEntity.prototype, relationship.name)
}
if (shouldCascade || detachCascade) {
conf["deleteRule"] = "cascade"
}
ManyToOne(conf)(MikroORMEntity.prototype, relationship.name)
} else {
ManyToOne({
const conf = {
entity: relatedModelName,
columnType: "text",
mapToPk: true,
fieldName: foreignKeyName,
nullable: relationship.nullable,
onDelete: shouldCascade ? "cascade" : undefined,
})(MikroORMEntity.prototype, foreignKeyName)
}
if (shouldCascade) {
conf["deleteRule"] = "cascade"
}
ManyToOne(conf)(MikroORMEntity.prototype, foreignKeyName)
ManyToOne({
entity: relatedModelName,
@@ -486,7 +492,6 @@ export function defineBelongsToRelationship(
const foreignKeyName =
relationship.options.foreignKeyName ??
camelToSnakeCase(`${relationship.name}Id`)
Property({
columnType: "text",
type: "string",
@@ -504,10 +509,10 @@ export function defineBelongsToRelationship(
fieldName: foreignKeyName,
owner: true,
// orphanRemoval: true,
onDelete: shouldCascade ? "cascade" : undefined,
}
if (shouldCascade) {
oneToOneOptions.deleteRule = "cascade"
oneToOneOptions.cascade = [Cascade.PERSIST, "soft-remove"] as any
}
@@ -741,8 +746,15 @@ export function defineManyToManyRelationship(
: {}),
...(pivotEntityName ? { pivotEntity: pivotEntityName } : {}),
...({ [mappedByProp]: mappedByPropValue } as any),
[joinColumnProp]: joinColumn ?? joinColumns,
[inverseJoinColumnProp]: inverseJoinColumn ?? inverseJoinColumns,
} as any
if (joinColumn || joinColumns) {
manytoManyOptions[joinColumnProp] = joinColumn ?? joinColumns
}
if (inverseJoinColumn || inverseJoinColumns) {
manytoManyOptions[inverseJoinColumnProp] =
inverseJoinColumn ?? inverseJoinColumns
}
ManyToMany(manytoManyOptions)(MikroORMEntity.prototype, relationship.name)
+2
View File
@@ -4,3 +4,5 @@ export * from "./helpers/entity-builder/index"
export * from "./helpers/create-mikro-orm-entity"
export * from "./relations/index"
export * from "./properties/index"
export * from "./helpers/entity-builder/index"
@@ -1,15 +1,16 @@
import { EntityConstructor } from "@medusajs/types"
import { MetadataStorage, MikroORM } from "@mikro-orm/core"
import { defineConfig } from "@mikro-orm/postgresql"
import { join } from "path"
import { createDatabase, dropDatabase } from "pg-god"
import { FileSystem } from "../../../common"
import { CustomTsMigrationGenerator, mikroOrmSerializer } from "../../../dal"
import { model } from "../../entity-builder"
import {
mikroORMEntityBuilder,
toMikroOrmEntities,
} from "../../helpers/create-mikro-orm-entity"
import { createDatabase, dropDatabase } from "pg-god"
import { CustomTsMigrationGenerator, mikroOrmSerializer } from "../../../dal"
import { EntityConstructor } from "@medusajs/types"
import { pgGodCredentials } from "../utils"
import { FileSystem } from "../../../common"
import { join } from "path"
export const fileSystem = new FileSystem(
join(__dirname, "../../integration-tests-migrations-enum")
@@ -40,19 +41,20 @@ describe("EntityBuilder", () => {
await createDatabase({ databaseName: dbName }, pgGodCredentials)
orm = await MikroORM.init({
entities: [User],
tsNode: true,
dbName,
password: pgGodCredentials.password,
host: pgGodCredentials.host,
user: pgGodCredentials.user,
type: "postgresql",
migrations: {
generator: CustomTsMigrationGenerator,
path: fileSystem.basePath,
},
})
orm = await MikroORM.init(
defineConfig({
entities: [User],
tsNode: true,
dbName,
password: pgGodCredentials.password,
host: pgGodCredentials.host,
user: pgGodCredentials.user,
migrations: {
generator: CustomTsMigrationGenerator,
path: fileSystem.basePath,
},
})
)
const migrator = orm.getMigrator()
await migrator.createMigration()
@@ -1,19 +1,20 @@
import { EntityConstructor } from "@medusajs/types"
import {
CheckConstraintViolationException,
MetadataStorage,
MikroORM,
} from "@mikro-orm/core"
import { defineConfig } from "@mikro-orm/postgresql"
import { join } from "path"
import { createDatabase, dropDatabase } from "pg-god"
import { FileSystem } from "../../../common"
import { CustomTsMigrationGenerator, mikroOrmSerializer } from "../../../dal"
import { model } from "../../entity-builder"
import {
mikroORMEntityBuilder,
toMikroOrmEntities,
} from "../../helpers/create-mikro-orm-entity"
import { createDatabase, dropDatabase } from "pg-god"
import { CustomTsMigrationGenerator, mikroOrmSerializer } from "../../../dal"
import { EntityConstructor } from "@medusajs/types"
import { pgGodCredentials } from "../utils"
import { FileSystem } from "../../../common"
import { join } from "path"
export const fileSystem = new FileSystem(
join(__dirname, "../../integration-tests-migrations-enum")
@@ -43,19 +44,20 @@ describe("EntityBuilder | enum", () => {
await createDatabase({ databaseName: dbName }, pgGodCredentials)
orm = await MikroORM.init({
entities: [User],
tsNode: true,
dbName,
password: pgGodCredentials.password,
host: pgGodCredentials.host,
user: pgGodCredentials.user,
type: "postgresql",
migrations: {
generator: CustomTsMigrationGenerator,
path: fileSystem.basePath,
},
})
orm = await MikroORM.init(
defineConfig({
entities: [User],
tsNode: true,
dbName,
password: pgGodCredentials.password,
host: pgGodCredentials.host,
user: pgGodCredentials.user,
migrations: {
generator: CustomTsMigrationGenerator,
path: fileSystem.basePath,
},
})
)
const migrator = orm.getMigrator()
await migrator.createMigration()
@@ -1,15 +1,16 @@
import { EntityConstructor } from "@medusajs/types"
import { MetadataStorage, MikroORM } from "@mikro-orm/core"
import { defineConfig } from "@mikro-orm/postgresql"
import { join } from "path"
import { createDatabase, dropDatabase } from "pg-god"
import { FileSystem } from "../../../common"
import { CustomTsMigrationGenerator, mikroOrmSerializer } from "../../../dal"
import { model } from "../../entity-builder"
import {
mikroORMEntityBuilder,
toMikroOrmEntities,
} from "../../helpers/create-mikro-orm-entity"
import { createDatabase, dropDatabase } from "pg-god"
import { CustomTsMigrationGenerator, mikroOrmSerializer } from "../../../dal"
import { EntityConstructor } from "@medusajs/types"
import { pgGodCredentials } from "../utils"
import { FileSystem } from "../../../common"
import { join } from "path"
export const fileSystem = new FileSystem(
join(__dirname, "../../integration-tests-migrations-has-one-belongs-to")
@@ -45,19 +46,20 @@ describe("hasOne - belongTo", () => {
await createDatabase({ databaseName: dbName }, pgGodCredentials)
orm = await MikroORM.init({
entities: [Team, User],
tsNode: true,
dbName,
password: pgGodCredentials.password,
host: pgGodCredentials.host,
user: pgGodCredentials.user,
type: "postgresql",
migrations: {
generator: CustomTsMigrationGenerator,
path: fileSystem.basePath,
},
})
orm = await MikroORM.init(
defineConfig({
entities: [Team, User],
tsNode: true,
dbName,
password: pgGodCredentials.password,
host: pgGodCredentials.host,
user: pgGodCredentials.user,
migrations: {
generator: CustomTsMigrationGenerator,
path: fileSystem.basePath,
},
})
)
const migrator = orm.getMigrator()
await migrator.createMigration()
@@ -1,15 +1,16 @@
import { join } from "path"
import { EntityConstructor } from "@medusajs/types"
import { MetadataStorage, MikroORM } from "@mikro-orm/core"
import { defineConfig } from "@mikro-orm/postgresql"
import { join } from "path"
import { createDatabase, dropDatabase } from "pg-god"
import { FileSystem } from "../../../common"
import { CustomTsMigrationGenerator, mikroOrmSerializer } from "../../../dal"
import { model } from "../../entity-builder"
import {
mikroORMEntityBuilder,
toMikroOrmEntities,
} from "../../helpers/create-mikro-orm-entity"
import { createDatabase, dropDatabase } from "pg-god"
import { CustomTsMigrationGenerator, mikroOrmSerializer } from "../../../dal"
import { EntityConstructor } from "@medusajs/types"
import { pgGodCredentials } from "../utils"
import { FileSystem } from "../../../common"
jest.setTimeout(30000)
@@ -62,19 +63,20 @@ describe("manyToMany - manyToMany", () => {
await createDatabase({ databaseName: dbName }, pgGodCredentials)
orm = await MikroORM.init({
entities: [Team, User, Squad],
tsNode: true,
dbName,
password: pgGodCredentials.password,
host: pgGodCredentials.host,
user: pgGodCredentials.user,
type: "postgresql",
migrations: {
generator: CustomTsMigrationGenerator,
path: fileSystem.basePath,
},
})
orm = await MikroORM.init(
defineConfig({
entities: [Team, User, Squad],
tsNode: true,
dbName,
password: pgGodCredentials.password,
host: pgGodCredentials.host,
user: pgGodCredentials.user,
migrations: {
generator: CustomTsMigrationGenerator,
path: fileSystem.basePath,
},
})
)
const migrator = orm.getMigrator()
await migrator.createMigration()
@@ -1,21 +1,21 @@
import { EntityConstructor } from "@medusajs/types"
import { MetadataStorage, MikroORM } from "@mikro-orm/core"
import { model } from "../../entity-builder"
import {
mikroORMEntityBuilder,
toMikroOrmEntities,
} from "../../helpers/create-mikro-orm-entity"
import { defineConfig, SqlEntityManager } from "@mikro-orm/postgresql"
import { join } from "path"
import { createDatabase, dropDatabase } from "pg-god"
import { FileSystem } from "../../../common"
import {
CustomTsMigrationGenerator,
mikroOrmSerializer,
mikroOrmUpdateDeletedAtRecursively,
SoftDeletableFilterKey,
} from "../../../dal"
import { EntityConstructor } from "@medusajs/types"
import { model } from "../../entity-builder"
import {
mikroORMEntityBuilder,
toMikroOrmEntities,
} from "../../helpers/create-mikro-orm-entity"
import { pgGodCredentials } from "../utils"
import { FileSystem } from "../../../common"
import { join } from "path"
import { SqlEntityManager } from "@mikro-orm/postgresql"
export const fileSystem = new FileSystem(
join(__dirname, "../../integration-tests-migrations-many-to-one")
@@ -55,19 +55,20 @@ describe("manyToOne - belongTo", () => {
await createDatabase({ databaseName: dbName }, pgGodCredentials)
orm = await MikroORM.init({
entities: [Team, User],
tsNode: true,
dbName,
password: pgGodCredentials.password,
host: pgGodCredentials.host,
user: pgGodCredentials.user,
type: "postgresql",
migrations: {
generator: CustomTsMigrationGenerator,
path: fileSystem.basePath,
},
})
orm = await MikroORM.init(
defineConfig({
entities: [Team, User],
tsNode: true,
dbName,
password: pgGodCredentials.password,
host: pgGodCredentials.host,
user: pgGodCredentials.user,
migrations: {
generator: CustomTsMigrationGenerator,
path: fileSystem.basePath,
},
})
)
const migrator = orm.getMigrator()
await migrator.createMigration()
@@ -1,5 +1,5 @@
const DB_HOST = process.env.DB_HOST ?? "localhost"
const DB_USERNAME = process.env.DB_USERNAME ?? ""
const DB_USERNAME = process.env.DB_USERNAME ?? "postgres"
const DB_PASSWORD = process.env.DB_PASSWORD ?? ""
export const pgGodCredentials = {
@@ -8,7 +8,10 @@ import { PrimaryKeyModifier } from "./primary-key"
export class NumberProperty extends BaseProperty<number> {
protected dataType: {
name: "number"
options: {}
options: {
primaryKey?: boolean
searchable?: boolean
}
}
/**
@@ -30,6 +33,27 @@ export class NumberProperty extends BaseProperty<number> {
return new PrimaryKeyModifier<number, NumberProperty>(this)
}
/**
* This method indicates that a number property is searchable.
*
* @example
* import { model } from "@medusajs/framework/utils"
*
* const MyCustom = model.define("my_custom", {
* name: model.number().searchable(),
* // ...
* })
*
* export default MyCustom
*
* @customNamespace Property Configuration Methods
*/
searchable() {
this.dataType.options.searchable = true
return this
}
constructor(options?: { primaryKey?: boolean }) {
super()