Add support for created and updated at timestamps (#7765)

This commit is contained in:
Harminder Virk authored and GitHub committed 2024-06-18 21:22:31 +05:30
1 parent 89bb16cea1
commit 1451112f08
3 files changed
+945

No files matched your search

File diff suppressed because it is too large. Load diff
@@ -16,11 +16,30 @@ import type {
} from "./types" } from "./types"
import { NullableModifier } from "./properties/nullable" import { NullableModifier } from "./properties/nullable"
/**
* The implicit properties added by EntityBuilder in every schema
*/
const IMPLICIT_PROPERTIES = ["created_at", "updated_at", "deleted_at"]
/** /**
* Entity builder exposes the API to create an entity and define its * Entity builder exposes the API to create an entity and define its
* schema using the shorthand methods. * schema using the shorthand methods.
*/ */
export class EntityBuilder { export class EntityBuilder {
#disallowImplicitProperties(schema: Record<string, any>) {
const implicitProperties = Object.keys(schema).filter((fieldName) =>
IMPLICIT_PROPERTIES.includes(fieldName)
)
if (implicitProperties.length) {
throw new Error(
`Cannot define field(s) "${implicitProperties.join(
","
)}" as they are implicitly defined on every model`
)
}
}
/** /**
* Define an entity or a model. The name should be unique across * Define an entity or a model. The name should be unique across
* all the entities. * all the entities.
@@ -28,12 +47,18 @@ export class EntityBuilder {
define< define<
Schema extends Record<string, PropertyType<any> | RelationshipType<any>> Schema extends Record<string, PropertyType<any> | RelationshipType<any>>
>(name: string, schema: Schema) { >(name: string, schema: Schema) {
this.#disallowImplicitProperties(schema)
return new DmlEntity< return new DmlEntity<
Schema & { Schema & {
created_at: DateTimeProperty
updated_at: DateTimeProperty
deleted_at: NullableModifier<Date, DateTimeProperty> deleted_at: NullableModifier<Date, DateTimeProperty>
} }
>(name, { >(name, {
...schema, ...schema,
created_at: new DateTimeProperty(),
updated_at: new DateTimeProperty(),
deleted_at: new DateTimeProperty().nullable(), deleted_at: new DateTimeProperty().nullable(),
}) })
} }
@@ -64,6 +64,39 @@ const PROPERTY_TYPES: {
json: "any", json: "any",
} }
/**
* Properties that needs special treatment based upon their name.
* We can safely rely on these names because they are never
* provided by the end-user. Instead we output them
* implicitly via the DML.
*/
const SPECIAL_PROPERTIES: {
[propertyName: string]: (
MikroORMEntity: EntityConstructor<any>,
field: PropertyMetadata
) => void
} = {
created_at: (MikroORMEntity, field) => {
Property({
columnType: "timestamptz",
type: "date",
nullable: false,
defaultRaw: "now()",
onCreate: () => new Date(),
})(MikroORMEntity.prototype, field.fieldName)
},
updated_at: (MikroORMEntity, field) => {
Property({
columnType: "timestamptz",
type: "date",
nullable: false,
defaultRaw: "now()",
onCreate: () => new Date(),
onUpdate: () => new Date(),
})(MikroORMEntity.prototype, field.fieldName)
},
}
/** /**
* Factory function to create the mikro orm entity builder. The return * Factory function to create the mikro orm entity builder. The return
* value is a function that can be used to convert DML entities * value is a function that can be used to convert DML entities
@@ -92,6 +125,11 @@ export function createMikrORMEntity() {
MikroORMEntity: EntityConstructor<any>, MikroORMEntity: EntityConstructor<any>,
field: PropertyMetadata field: PropertyMetadata
) { ) {
if (SPECIAL_PROPERTIES[field.fieldName]) {
SPECIAL_PROPERTIES[field.fieldName](MikroORMEntity, field)
return
}
/** /**
* Defining an enum property * Defining an enum property
*/ */