From 08dc861dc14fd5744160084d6ab695393fc92e90 Mon Sep 17 00:00:00 2001 From: Stevche Radevski Date: Wed, 17 Apr 2024 17:07:20 +0200 Subject: [PATCH] fix: Support bigNumber in upsertWithReplace (#7084) --- .../src/dal/mikro-orm/big-number-field.ts | 9 ++++++ .../__tests__/mikro-orm-repository.spec.ts | 17 +++++++++-- .../src/dal/mikro-orm/mikro-orm-repository.ts | 30 ++++++++++++------- 3 files changed, 42 insertions(+), 14 deletions(-) diff --git a/packages/utils/src/dal/mikro-orm/big-number-field.ts b/packages/utils/src/dal/mikro-orm/big-number-field.ts index 56142e34c1..5604003403 100644 --- a/packages/utils/src/dal/mikro-orm/big-number-field.ts +++ b/packages/utils/src/dal/mikro-orm/big-number-field.ts @@ -51,6 +51,15 @@ export function MikroOrmBigNumberProperty( this[rawColumnName] = raw } + // This is custom code to keep track of which fields are bignumber, as well as their data + if (!this.__helper.__bignumberdata) { + this.__helper.__bignumberdata = {} + } + + this.__helper.__bignumberdata[columnName] = + this.__helper.__data[columnName] + this.__helper.__bignumberdata[rawColumnName] = + this.__helper.__data[rawColumnName] this.__helper.__touched = !this.__helper.hydrator.isRunning() }, enumerable: true, diff --git a/packages/utils/src/dal/mikro-orm/integration-tests/__tests__/mikro-orm-repository.spec.ts b/packages/utils/src/dal/mikro-orm/integration-tests/__tests__/mikro-orm-repository.spec.ts index 6457ce5391..eabd38e74f 100644 --- a/packages/utils/src/dal/mikro-orm/integration-tests/__tests__/mikro-orm-repository.spec.ts +++ b/packages/utils/src/dal/mikro-orm/integration-tests/__tests__/mikro-orm-repository.spec.ts @@ -15,6 +15,9 @@ import { } from "@mikro-orm/core" import { mikroOrmBaseRepositoryFactory } from "../../mikro-orm-repository" import { dropDatabase } from "pg-god" +import { MikroOrmBigNumberProperty } from "../../big-number-field" +import BigNumber from "bignumber.js" +import { BigNumberRawValue } from "@medusajs/types" const DB_HOST = process.env.DB_HOST ?? "localhost" const DB_USERNAME = process.env.DB_USERNAME ?? "" @@ -42,6 +45,12 @@ class Entity1 { @Property() title: string + @MikroOrmBigNumberProperty({ nullable: true }) + amount: BigNumber | number | null + + @Property({ columnType: "jsonb", nullable: true }) + raw_amount: BigNumberRawValue | null + @Property({ nullable: true }) deleted_at: Date | null @@ -165,16 +174,18 @@ describe("mikroOrmRepository", () => { describe("upsert with replace", () => { it("should successfully create a flat entity", async () => { - const entity1 = { id: "1", title: "en1" } + const entity1 = { id: "1", title: "en1", amount: 100 } const resp = await manager1().upsertWithReplace([entity1]) const listedEntities = await manager1().find() expect(listedEntities).toHaveLength(1) - expect(listedEntities[0]).toEqual( + expect(wrap(listedEntities[0]).toPOJO()).toEqual( expect.objectContaining({ id: "1", title: "en1", + amount: 100, + raw_amount: { value: "100", precision: 20 }, }) ) }) @@ -188,7 +199,7 @@ describe("mikroOrmRepository", () => { const listedEntities = await manager1().find() expect(listedEntities).toHaveLength(1) - expect(listedEntities[0]).toEqual( + expect(wrap(listedEntities[0]).toPOJO()).toEqual( expect.objectContaining({ id: "1", title: "newen1", diff --git a/packages/utils/src/dal/mikro-orm/mikro-orm-repository.ts b/packages/utils/src/dal/mikro-orm/mikro-orm-repository.ts index b7711c5062..8af2efcb83 100644 --- a/packages/utils/src/dal/mikro-orm/mikro-orm-repository.ts +++ b/packages/utils/src/dal/mikro-orm/mikro-orm-repository.ts @@ -639,16 +639,6 @@ export function mikroOrmBaseRepositoryFactory( Object.assign(normalizedDataItem, { ...joinColumnsConstraints, }) - // Non-persist relation columns should be removed before we do the upsert. - Object.entries(relation.targetMeta?.properties ?? {}) - .filter( - ([_, propDef]) => - propDef.persist === false && - propDef.reference === ReferenceType.MANY_TO_ONE - ) - .forEach(([key]) => { - delete normalizedDataItem[key] - }) }) await this.upsertMany_(manager, relation.type, normalizedData) @@ -717,7 +707,25 @@ export function mikroOrmBaseRepositoryFactory( persist: false, }) - return { id: (created as any).id, ...data } + const resp = { + // `create` will omit non-existent fields, but we want to pass the data the user provided through so the correct errors get thrown + ...data, + ...(created as any).__helper.__bignumberdata, + id: (created as any).id, + } + + // Non-persist relation columns should be removed before we do the upsert. + Object.entries((created as any).__helper?.__meta.properties ?? {}) + .filter( + ([_, propDef]: any) => + propDef.persist === false && + propDef.reference === ReferenceType.MANY_TO_ONE + ) + .forEach(([key]) => { + delete resp[key] + }) + + return resp } protected async upsertMany_(