feat: add support for float properties (#10551)
This commit is contained in:
@@ -1450,6 +1450,94 @@ describe("Entity builder", () => {
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
test("define a float property", () => {
|
||||
const tax = model.define("tax", {
|
||||
id: model.number(),
|
||||
rate: model.float(),
|
||||
})
|
||||
|
||||
expect(tax.name).toEqual("Tax")
|
||||
expect(tax.parse().tableName).toEqual("tax")
|
||||
|
||||
const Tax = toMikroORMEntity(tax)
|
||||
expectTypeOf(new Tax()).toMatchTypeOf<{
|
||||
id: number
|
||||
rate: number
|
||||
}>()
|
||||
|
||||
const metaData = MetadataStorage.getMetadataFromDecorator(Tax)
|
||||
expect(metaData.className).toEqual("Tax")
|
||||
expect(metaData.path).toEqual("Tax")
|
||||
|
||||
expect(metaData.filters).toEqual({
|
||||
softDeletable: {
|
||||
name: "softDeletable",
|
||||
cond: expect.any(Function),
|
||||
default: true,
|
||||
args: false,
|
||||
},
|
||||
})
|
||||
|
||||
expect(metaData.properties).toEqual({
|
||||
id: {
|
||||
reference: "scalar",
|
||||
type: "number",
|
||||
columnType: "integer",
|
||||
name: "id",
|
||||
fieldName: "id",
|
||||
nullable: false,
|
||||
getter: false,
|
||||
setter: false,
|
||||
},
|
||||
rate: {
|
||||
reference: "scalar",
|
||||
type: "number",
|
||||
columnType: "real",
|
||||
name: "rate",
|
||||
fieldName: "rate",
|
||||
serializer: Number,
|
||||
nullable: false,
|
||||
getter: false,
|
||||
setter: false,
|
||||
},
|
||||
created_at: {
|
||||
reference: "scalar",
|
||||
type: "date",
|
||||
columnType: "timestamptz",
|
||||
name: "created_at",
|
||||
fieldName: "created_at",
|
||||
defaultRaw: "now()",
|
||||
onCreate: expect.any(Function),
|
||||
nullable: false,
|
||||
getter: false,
|
||||
setter: false,
|
||||
},
|
||||
updated_at: {
|
||||
reference: "scalar",
|
||||
type: "date",
|
||||
columnType: "timestamptz",
|
||||
name: "updated_at",
|
||||
fieldName: "updated_at",
|
||||
defaultRaw: "now()",
|
||||
onCreate: expect.any(Function),
|
||||
onUpdate: expect.any(Function),
|
||||
nullable: false,
|
||||
getter: false,
|
||||
setter: false,
|
||||
},
|
||||
deleted_at: {
|
||||
reference: "scalar",
|
||||
type: "date",
|
||||
columnType: "timestamptz",
|
||||
name: "deleted_at",
|
||||
fieldName: "deleted_at",
|
||||
nullable: true,
|
||||
getter: false,
|
||||
setter: false,
|
||||
},
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("Entity builder | relationships", () => {
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import { expectTypeOf } from "expect-type"
|
||||
import { FloatProperty } from "../properties"
|
||||
|
||||
describe("Float property", () => {
|
||||
test("create float property type", () => {
|
||||
const property = new FloatProperty()
|
||||
|
||||
expectTypeOf(property["$dataType"]).toEqualTypeOf<number>()
|
||||
expect(property.parse("rate")).toEqual({
|
||||
fieldName: "rate",
|
||||
dataType: {
|
||||
name: "float",
|
||||
},
|
||||
nullable: false,
|
||||
indexes: [],
|
||||
relationships: [],
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -27,6 +27,7 @@ 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
|
||||
@@ -249,6 +250,26 @@ export class EntityBuilder {
|
||||
return new BigNumberProperty()
|
||||
}
|
||||
|
||||
/**
|
||||
* This method defines a float property that allows for
|
||||
* values with decimal places
|
||||
*
|
||||
* @example
|
||||
* import { model } from "@medusajs/framework/utils"
|
||||
*
|
||||
* const MyCustom = model.define("tax", {
|
||||
* tax_rate: model.float(),
|
||||
* // ...
|
||||
* })
|
||||
*
|
||||
* export default MyCustom
|
||||
*
|
||||
* @customNamespace Property Types
|
||||
*/
|
||||
float() {
|
||||
return new FloatProperty()
|
||||
}
|
||||
|
||||
/**
|
||||
* This method defines an autoincrement property.
|
||||
*
|
||||
|
||||
@@ -33,6 +33,7 @@ const COLUMN_TYPES: {
|
||||
dateTime: "timestamptz",
|
||||
number: "integer",
|
||||
bigNumber: "numeric",
|
||||
float: "real",
|
||||
serial: "number",
|
||||
text: "text",
|
||||
json: "jsonb",
|
||||
@@ -53,6 +54,7 @@ const PROPERTY_TYPES: {
|
||||
dateTime: "date",
|
||||
number: "number",
|
||||
bigNumber: "number",
|
||||
float: "number",
|
||||
serial: "number",
|
||||
text: "string",
|
||||
json: "any",
|
||||
@@ -277,6 +279,31 @@ export function defineProperty(
|
||||
return
|
||||
}
|
||||
|
||||
/**
|
||||
* Handling serial property separately to set the column type
|
||||
*/
|
||||
if (field.dataType.name === "float") {
|
||||
Property({
|
||||
columnType: "real",
|
||||
type: "number",
|
||||
nullable: field.nullable,
|
||||
fieldName: field.fieldName,
|
||||
/**
|
||||
* Applying number serializer to convert value back to a
|
||||
* JavaScript number
|
||||
*/
|
||||
serializer: Number,
|
||||
/**
|
||||
* MikroORM does not ignore undefined values for default when generating
|
||||
* the database schema SQL. Conditionally add it here to prevent undefined
|
||||
* from being set as default value in SQL.
|
||||
*/
|
||||
...(isDefined(field.defaultValue) && { default: field.defaultValue }),
|
||||
})(MikroORMEntity.prototype, field.fieldName)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
/**
|
||||
* Define rest of properties
|
||||
*/
|
||||
|
||||
@@ -33,6 +33,7 @@ describe("EntityBuilder", () => {
|
||||
id: model.id().primaryKey(),
|
||||
username: model.text(),
|
||||
points: model.number().default(0).nullable(),
|
||||
tax_rate: model.float().default(0).nullable(),
|
||||
})
|
||||
|
||||
;[User] = toMikroOrmEntities([user])
|
||||
@@ -86,6 +87,7 @@ describe("EntityBuilder", () => {
|
||||
id: user1.id,
|
||||
username: "User 1",
|
||||
points: 0,
|
||||
tax_rate: 0,
|
||||
created_at: expect.any(Date),
|
||||
updated_at: expect.any(Date),
|
||||
deleted_at: null,
|
||||
@@ -112,6 +114,7 @@ describe("EntityBuilder", () => {
|
||||
id: user1.id,
|
||||
username: "User 1",
|
||||
points: null,
|
||||
tax_rate: 0,
|
||||
created_at: expect.any(Date),
|
||||
updated_at: expect.any(Date),
|
||||
deleted_at: null,
|
||||
@@ -139,6 +142,34 @@ describe("EntityBuilder", () => {
|
||||
id: user1.id,
|
||||
username: "User 1",
|
||||
points: null,
|
||||
tax_rate: 0,
|
||||
created_at: expect.any(Date),
|
||||
updated_at: expect.any(Date),
|
||||
deleted_at: null,
|
||||
})
|
||||
})
|
||||
|
||||
it("set the tax rate as a float value", async () => {
|
||||
let manager = orm.em.fork()
|
||||
|
||||
const user1 = manager.create(User, {
|
||||
username: "User 1",
|
||||
tax_rate: 1.2122,
|
||||
})
|
||||
expect(user1.tax_rate).toEqual(1.2122)
|
||||
|
||||
await manager.persistAndFlush([user1])
|
||||
manager = orm.em.fork()
|
||||
|
||||
const user = await manager.findOne(User, {
|
||||
id: user1.id,
|
||||
})
|
||||
|
||||
expect(await mikroOrmSerializer(user)).toEqual({
|
||||
id: user1.id,
|
||||
username: "User 1",
|
||||
points: 0,
|
||||
tax_rate: 1.2122,
|
||||
created_at: expect.any(Date),
|
||||
updated_at: expect.any(Date),
|
||||
deleted_at: null,
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import { BaseProperty } from "./base"
|
||||
|
||||
/**
|
||||
* The FloatProperty is used to define values with decimal
|
||||
* places.
|
||||
*/
|
||||
export class FloatProperty extends BaseProperty<number> {
|
||||
protected dataType = {
|
||||
name: "float",
|
||||
} as const
|
||||
|
||||
static isFloatProperty(obj: any): obj is FloatProperty {
|
||||
return obj?.dataType?.name === "float"
|
||||
}
|
||||
}
|
||||
@@ -9,5 +9,6 @@ export * from "./id"
|
||||
export * from "./json"
|
||||
export * from "./nullable"
|
||||
export * from "./number"
|
||||
export * from "./float"
|
||||
export * from "./primary-key"
|
||||
export * from "./text"
|
||||
|
||||
Reference in New Issue
Block a user