diff --git a/src/Model/Types/ModelFromRepositoryType.ts b/src/Model/Types/ModelFromRepositoryType.ts new file mode 100644 index 0000000..0163a2c --- /dev/null +++ b/src/Model/Types/ModelFromRepositoryType.ts @@ -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 extends ModelType +{ + 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(modelConstructor: ConstructorOf) +{ + return new ModelFromRepositoryType(modelConstructor); +} diff --git a/src/index.ts b/src/index.ts index 89326bf..29ea48a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,3 +3,5 @@ export * from "./Model/Repositories/ModelRepository"; export * from "./Model/Repositories/AutoRetriever"; +export * from "./Model/Types/ModelFromRepositoryType"; + diff --git a/tests/ModelFromRepositoryType.test.ts b/tests/ModelFromRepositoryType.test.ts new file mode 100644 index 0000000..57f2fb4 --- /dev/null +++ b/tests/ModelFromRepositoryType.test.ts @@ -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); +});