feat: add support for float properties (#10551)
This commit is contained in:
1 parent
cccce65ef9
commit
885c82ded6
9 files changed
+209
No files matched your search
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
"@medusajs/types": patch
|
||||||
|
"@medusajs/utils": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
feat: add support for float properties
|
||||||
@@ -41,6 +41,7 @@ export type KnownDataTypes =
|
|||||||
| "enum"
|
| "enum"
|
||||||
| "number"
|
| "number"
|
||||||
| "bigNumber"
|
| "bigNumber"
|
||||||
|
| "float"
|
||||||
| "serial"
|
| "serial"
|
||||||
| "dateTime"
|
| "dateTime"
|
||||||
| "array"
|
| "array"
|
||||||
|
|||||||
@@ -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", () => {
|
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 { HasOne } from "./relations/has-one"
|
||||||
import { HasOneWithForeignKey } from "./relations/has-one-fk"
|
import { HasOneWithForeignKey } from "./relations/has-one-fk"
|
||||||
import { ManyToMany } from "./relations/many-to-many"
|
import { ManyToMany } from "./relations/many-to-many"
|
||||||
|
import { FloatProperty } from "./properties"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The implicit properties added by EntityBuilder in every schema
|
* The implicit properties added by EntityBuilder in every schema
|
||||||
@@ -249,6 +250,26 @@ export class EntityBuilder {
|
|||||||
return new BigNumberProperty()
|
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.
|
* This method defines an autoincrement property.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ const COLUMN_TYPES: {
|
|||||||
dateTime: "timestamptz",
|
dateTime: "timestamptz",
|
||||||
number: "integer",
|
number: "integer",
|
||||||
bigNumber: "numeric",
|
bigNumber: "numeric",
|
||||||
|
float: "real",
|
||||||
serial: "number",
|
serial: "number",
|
||||||
text: "text",
|
text: "text",
|
||||||
json: "jsonb",
|
json: "jsonb",
|
||||||
@@ -53,6 +54,7 @@ const PROPERTY_TYPES: {
|
|||||||
dateTime: "date",
|
dateTime: "date",
|
||||||
number: "number",
|
number: "number",
|
||||||
bigNumber: "number",
|
bigNumber: "number",
|
||||||
|
float: "number",
|
||||||
serial: "number",
|
serial: "number",
|
||||||
text: "string",
|
text: "string",
|
||||||
json: "any",
|
json: "any",
|
||||||
@@ -277,6 +279,31 @@ export function defineProperty(
|
|||||||
return
|
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
|
* Define rest of properties
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ describe("EntityBuilder", () => {
|
|||||||
id: model.id().primaryKey(),
|
id: model.id().primaryKey(),
|
||||||
username: model.text(),
|
username: model.text(),
|
||||||
points: model.number().default(0).nullable(),
|
points: model.number().default(0).nullable(),
|
||||||
|
tax_rate: model.float().default(0).nullable(),
|
||||||
})
|
})
|
||||||
|
|
||||||
;[User] = toMikroOrmEntities([user])
|
;[User] = toMikroOrmEntities([user])
|
||||||
@@ -86,6 +87,7 @@ describe("EntityBuilder", () => {
|
|||||||
id: user1.id,
|
id: user1.id,
|
||||||
username: "User 1",
|
username: "User 1",
|
||||||
points: 0,
|
points: 0,
|
||||||
|
tax_rate: 0,
|
||||||
created_at: expect.any(Date),
|
created_at: expect.any(Date),
|
||||||
updated_at: expect.any(Date),
|
updated_at: expect.any(Date),
|
||||||
deleted_at: null,
|
deleted_at: null,
|
||||||
@@ -112,6 +114,7 @@ describe("EntityBuilder", () => {
|
|||||||
id: user1.id,
|
id: user1.id,
|
||||||
username: "User 1",
|
username: "User 1",
|
||||||
points: null,
|
points: null,
|
||||||
|
tax_rate: 0,
|
||||||
created_at: expect.any(Date),
|
created_at: expect.any(Date),
|
||||||
updated_at: expect.any(Date),
|
updated_at: expect.any(Date),
|
||||||
deleted_at: null,
|
deleted_at: null,
|
||||||
@@ -139,6 +142,34 @@ describe("EntityBuilder", () => {
|
|||||||
id: user1.id,
|
id: user1.id,
|
||||||
username: "User 1",
|
username: "User 1",
|
||||||
points: null,
|
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),
|
created_at: expect.any(Date),
|
||||||
updated_at: expect.any(Date),
|
updated_at: expect.any(Date),
|
||||||
deleted_at: null,
|
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 "./json"
|
||||||
export * from "./nullable"
|
export * from "./nullable"
|
||||||
export * from "./number"
|
export * from "./number"
|
||||||
|
export * from "./float"
|
||||||
export * from "./primary-key"
|
export * from "./primary-key"
|
||||||
export * from "./text"
|
export * from "./text"
|
||||||
Reference in new issue
Block a user