Add ModelFromRepositoryType, that makes use of model repositories on deserialization.
This commit is contained in:
parent
44ba66b39f
commit
15de42f7ca
30
src/Model/Types/ModelFromRepositoryType.ts
Normal file
30
src/Model/Types/ModelFromRepositoryType.ts
Normal 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);
|
||||||
|
}
|
@ -3,3 +3,5 @@
|
|||||||
export * from "./Model/Repositories/ModelRepository";
|
export * from "./Model/Repositories/ModelRepository";
|
||||||
export * from "./Model/Repositories/AutoRetriever";
|
export * from "./Model/Repositories/AutoRetriever";
|
||||||
|
|
||||||
|
export * from "./Model/Types/ModelFromRepositoryType";
|
||||||
|
|
||||||
|
45
tests/ModelFromRepositoryType.test.ts
Normal file
45
tests/ModelFromRepositoryType.test.ts
Normal 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);
|
||||||
|
});
|
Reference in New Issue
Block a user