Add ModelFromRepositoryType, that makes use of model repositories on deserialization.

This commit is contained in:
Madeorsk 2022-08-04 01:18:54 +02:00
parent 44ba66b39f
commit 15de42f7ca
3 changed files with 77 additions and 0 deletions

View File

@ -0,0 +1,30 @@
import {ConstructorOf, Model, ModelType} from "@sharkitek/core";
import {ModelWithRepository} from "../Repositories/ModelRepository";
/**
* Type of a Sharkitek model (from repository) value.
*/
export class ModelFromRepositoryType<M extends Model&ModelWithRepository> extends ModelType<M>
{
deserialize(value: any): M
{
// Deserializing the given object in a new model.
let model = (new this.modelConstructor()).deserialize(value);
// Getting the object matching the current model identifier, if there is one, or the current model.
model = model.getRepository().get(String(model.getIdentifier()), () => model) as M;
model?.store(); // Storing the current model in the repository if it was not.
return model; // Returning the model.
}
}
/**
* Type of a Sharkitek model (from repository) value.
* @param modelConstructor - Constructor of the model.
*/
export function SModelFromRepository<M extends Model&ModelWithRepository>(modelConstructor: ConstructorOf<M>)
{
return new ModelFromRepositoryType(modelConstructor);
}

View File

@ -3,3 +3,5 @@
export * from "./Model/Repositories/ModelRepository";
export * from "./Model/Repositories/AutoRetriever";
export * from "./Model/Types/ModelFromRepositoryType";

View File

@ -0,0 +1,45 @@
import {Identifier, Model, Property, SNumeric, SString} from "@sharkitek/core";
import {WithRepository, SModelFromRepository} from "../src";
class A extends WithRepository("A")(Model)
{
@Property(SNumeric)
@Identifier
id: number = undefined;
@Property(SString)
foo: string = undefined;
}
class B extends Model
{
@Property(SNumeric)
@Identifier
id: number = undefined;
@Property(SModelFromRepository(A))
a: A = undefined;
}
it("get the same object after two deserializations", () => {
// First deserialization, that should store the A instance.
const firstB = (new B()).deserialize({
id: 5,
a: {
id: 3,
foo: "first",
}
});
// To check that the first instance of "A" is used, we change the value of "foo". If a.foo == "first", then the first object has been used.
const secondB = (new B()).deserialize({
id: 7,
a: {
id: 3,
foo: "second",
}
});
// `a` of `secondB` should be `a` of `firstB`.
expect(secondB.a).toBe(firstB.a);
});