Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@graphand/core

Package Overview
Dependencies
Maintainers
1
Versions
205
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@graphand/core - npm Package Compare versions

Comparing version 0.3.10 to 0.3.12

1

dist/lib/Adapter.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class Adapter {
static __modelsMap;
fetcher;

@@ -5,0 +6,0 @@ fieldsMap;

26

dist/lib/controllersMap.js

@@ -6,3 +6,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const DataModel_1 = __importDefault(require("../models/DataModel"));
const Model_1 = __importDefault(require("../lib/Model"));
const model_env_scopes_1 = __importDefault(require("../enums/model-env-scopes"));

@@ -15,4 +15,4 @@ const _controllersMap = {

scope: ({ model }) => {
const Model = DataModel_1.default.getFromSlug(model);
if (Model.scope === model_env_scopes_1.default.GLOBAL)
const _model = Model_1.default.getFromSlug(model);
if (_model.scope === model_env_scopes_1.default.GLOBAL)
return "global";

@@ -27,4 +27,4 @@ return "project";

scope: ({ model }) => {
const Model = DataModel_1.default.getFromSlug(model);
if (Model.scope === model_env_scopes_1.default.GLOBAL)
const _model = Model_1.default.getFromSlug(model);
if (_model.scope === model_env_scopes_1.default.GLOBAL)
return "global";

@@ -39,4 +39,4 @@ return "project";

scope: ({ model }) => {
const Model = DataModel_1.default.getFromSlug(model);
if (Model.scope === model_env_scopes_1.default.GLOBAL)
const _model = Model_1.default.getFromSlug(model);
if (_model.scope === model_env_scopes_1.default.GLOBAL)
return "global";

@@ -51,4 +51,4 @@ return "project";

scope: ({ model }) => {
const Model = DataModel_1.default.getFromSlug(model);
if (Model.scope === model_env_scopes_1.default.GLOBAL)
const _model = Model_1.default.getFromSlug(model);
if (_model.scope === model_env_scopes_1.default.GLOBAL)
return "global";

@@ -63,4 +63,4 @@ return "project";

scope: ({ model }) => {
const Model = DataModel_1.default.getFromSlug(model);
if (Model.scope === model_env_scopes_1.default.GLOBAL)
const _model = Model_1.default.getFromSlug(model);
if (_model.scope === model_env_scopes_1.default.GLOBAL)
return "global";

@@ -75,4 +75,4 @@ return "project";

scope: ({ model }) => {
const Model = DataModel_1.default.getFromSlug(model);
if (Model.scope === model_env_scopes_1.default.GLOBAL)
const _model = Model_1.default.getFromSlug(model);
if (_model.scope === model_env_scopes_1.default.GLOBAL)
return "global";

@@ -79,0 +79,0 @@ return "project";

@@ -23,24 +23,28 @@ "use strict";

static __datamodel;
static __modelsMap = new Map();
static getFromDatamodel(datamodel) {
let model = Data_1.__modelsMap.get(datamodel.slug);
if (!model) {
model = class extends Data_1 {
static __name = datamodel.name;
static slug = datamodel.slug;
static fields = datamodel.fields;
static validators = [];
static configKey = datamodel.configKey;
};
model.__datamodel = datamodel;
Data_1.__modelsMap.set(datamodel.slug, model);
static getFromDatamodel(datamodel, adapter) {
if (!adapter) {
adapter = datamodel.model.__adapter?.constructor;
}
const adapter = datamodel.model.__adapter?.constructor;
if (adapter) {
return model.withAdapter(adapter);
adapter.__modelsMap ??= new Map();
}
let model = class extends Data_1 {
static __name = datamodel.name;
static slug = datamodel.slug;
static fields = datamodel.fields;
static validators = [];
static configKey = datamodel.configKey;
};
model.__datamodel = datamodel;
if (adapter) {
model = model.withAdapter(adapter);
}
adapter?.__modelsMap.set(datamodel.slug, model);
return model;
}
static __getFromSlug(slug) {
let model = Data_1.__modelsMap.get(slug);
static __getFromSlug(slug, adapter) {
if (adapter) {
adapter.__modelsMap ??= new Map();
}
let model = adapter?.__modelsMap.get(slug);
if (!model) {

@@ -58,3 +62,4 @@ model = class extends Data_1 {

}
const datamodel = await DataModel_1.default.withAdapter(this.__adapter.constructor).get({ filter: { slug } }, ctx);
const adapter = this.__adapter.constructor;
const datamodel = await DataModel_1.default.withAdapter(adapter).get({ filter: { slug } }, ctx);
if (!datamodel) {

@@ -75,3 +80,6 @@ throw new CoreError_1.default({

};
Data_1.__modelsMap.set(slug, model);
if (adapter) {
model = model.withAdapter(adapter);
}
adapter?.__modelsMap.set(slug, model);
}

@@ -78,0 +86,0 @@ return model;

@@ -12,2 +12,3 @@ "use strict";

const field_types_1 = __importDefault(require("../enums/field-types"));
const Model_1 = __importDefault(require("./Model"));
describe("Data", () => {

@@ -17,15 +18,46 @@ const adapter = (0, test_utils_1.mockAdapter)({

});
it("should get same model from slug and from datamodel instance", async () => {
const slug = faker_1.faker.animal.type();
const datamodel = new DataModel_1.default({ slug });
const modelFromDM = Data_1.default.getFromDatamodel(datamodel);
const modelFromSlug = Data_1.default.getFromSlug(slug);
expect(modelFromDM).toBe(modelFromSlug);
describe("model unicity", () => {
it("should get same model from slug and from datamodel instance with same adapter", async () => {
const slug = faker_1.faker.animal.type();
const datamodel = new DataModel_1.default({ slug });
const modelFromDM = Data_1.default.getFromDatamodel(datamodel, adapter);
const modelFromSlug = Data_1.default.getFromSlug(slug, adapter);
expect(modelFromDM).toBe(modelFromSlug);
});
it("should get different models from slug and from datamodel instance with different adapters", async () => {
const slug = faker_1.faker.animal.type();
const datamodel = new DataModel_1.default({ slug });
const modelFromDM = Data_1.default.getFromDatamodel(datamodel);
const modelFromSlug = Data_1.default.getFromSlug(slug, adapter);
expect(modelFromDM).not.toBe(modelFromSlug);
});
it("getFromDatamodel should returns model with the instance adapter", async () => {
const DM = DataModel_1.default.withAdapter(adapter);
const datamodel = new DM({ slug: faker_1.faker.animal.type() });
const modelFromDM = Data_1.default.getFromDatamodel(datamodel);
expect(modelFromDM.__adapter?.constructor).toBe(adapter);
});
it("getFromDatamodel should save adapted model in cache", () => {
const DM = DataModel_1.default.withAdapter(adapter);
const datamodel = new DM({ slug: faker_1.faker.animal.type() });
const modelFromDM = Data_1.default.getFromDatamodel(datamodel, adapter);
const modelFromDataSlug = Data_1.default.__getFromSlug(datamodel.slug, adapter);
const modelFromModelSlug = Model_1.default.getFromSlug(datamodel.slug, adapter);
expect(modelFromDM).toBe(modelFromDataSlug);
expect(modelFromDM).toBe(modelFromModelSlug);
expect(modelFromDataSlug).toBe(modelFromModelSlug);
});
it("getFromDatamodel should override adapted model in cache", () => {
const DM = DataModel_1.default.withAdapter(adapter);
const datamodel = new DM({ slug: faker_1.faker.animal.type() });
const modelFromDataSlug = Data_1.default.__getFromSlug(datamodel.slug, adapter);
const modelFromDM = Data_1.default.getFromDatamodel(datamodel, adapter);
const modelFromModelSlug = Model_1.default.getFromSlug(datamodel.slug, adapter);
expect(modelFromModelSlug).toBe(modelFromDM);
expect(modelFromDM).not.toBe(modelFromDataSlug);
const adaptedModelFromModel = Model_1.default.getAdaptedModel(modelFromDataSlug, adapter);
expect(adaptedModelFromModel).toBe(modelFromModelSlug);
expect(modelFromDM).toBe(modelFromModelSlug);
});
});
it("getFromDatamodel should returns model with the instance adapter", async () => {
const DM = DataModel_1.default.withAdapter(adapter);
const datamodel = new DM({ slug: faker_1.faker.animal.type() });
const modelFromDM = Data_1.default.getFromDatamodel(datamodel);
expect(modelFromDM.__adapter?.constructor).toBe(adapter);
});
it("should throw error at initializing if no adapter", async () => {

@@ -59,3 +91,15 @@ const slug = faker_1.faker.animal.type();

});
it("Test", () => { });
it("Multiple model get should return the same model & initialize once", async () => {
const DM = DataModel_1.default.withAdapter(adapter);
const slug = faker_1.faker.lorem.word();
await DM.create({ slug });
const model = Data_1.default.getFromSlug(slug, adapter);
const modelBis = Data_1.default.getFromSlug(slug, adapter);
expect(model).toBe(modelBis);
const spy = jest.spyOn(model, "reloadModel");
expect(spy).toHaveBeenCalledTimes(0);
await expect(model.initialize()).resolves.toBeUndefined();
await expect(modelBis.initialize()).resolves.toBeUndefined();
expect(spy).toHaveBeenCalledTimes(1);
});
});

@@ -87,3 +87,3 @@ "use strict";

const adapter = from.model.__adapter.constructor;
let model = Model_1.default.getFromSlug(this.options.ref).withAdapter(adapter);
let model = Model_1.default.getFromSlug(this.options.ref, adapter);
if (this.options.multiple) {

@@ -90,0 +90,0 @@ const ids = Array.isArray(value) ? value : [value];

@@ -40,3 +40,3 @@ "use strict";

static __baseClass;
static __decorated;
static __modelsMap = new Map();
__doc;

@@ -181,14 +181,44 @@ _id;

}
static getFromSlug(slug, fallbackData = true) {
static getFromSlug(slug, adapter, fallbackData = true) {
if (!adapter) {
adapter = this.__adapter?.constructor;
}
if (adapter) {
adapter.__modelsMap ??= new Map();
}
const models = require("../index").models;
let model = Object.values(models).find((m) => m.slug === slug);
if (!model && fallbackData) {
if (model) {
let adaptedModel = adapter?.__modelsMap.get(model.slug);
if (!adaptedModel && adapter) {
adaptedModel = model.withAdapter(adapter);
adapter.__modelsMap.set(model.slug, adaptedModel);
}
model = adaptedModel || model;
}
else if (fallbackData) {
const Data = require("./Data").default;
model = Data.__getFromSlug(slug);
model = Data.__getFromSlug(slug, adapter);
}
if (!this.__adapter) {
return model;
return model;
}
static getAdaptedModel(model, adapter, override) {
if (!adapter) {
adapter = this.__adapter?.constructor;
}
const adapter = this.__adapter.constructor;
return model.withAdapter(adapter);
if (!adapter) {
throw new CoreError_1.default({
message: "Adapter is required in getAdaptedModel method",
});
}
adapter.__modelsMap ??= new Map();
let adaptedModel;
if (!override) {
adaptedModel = adapter?.__modelsMap.get(model.slug);
}
if (!adaptedModel) {
adaptedModel = model.withAdapter(adapter);
adapter.__modelsMap.set(model.slug, adaptedModel);
}
return adaptedModel;
}

@@ -195,0 +225,0 @@ /**

@@ -14,2 +14,3 @@ "use strict";

const utils_1 = require("../utils");
const Data_1 = __importDefault(require("./Data"));
describe("Test Model", () => {

@@ -337,2 +338,71 @@ let adapter;

});
describe("Model unicity", () => {
it("should get same model from slug with same adapter", () => {
const model = Model_1.default.getFromSlug("accounts", adapter);
const modelBis = Model_1.default.getFromSlug("accounts", adapter);
expect(model).toBe(modelBis);
});
it("should get different models from slug with different adapter", () => {
const model = Model_1.default.getFromSlug("accounts");
const modelBis = Model_1.default.getFromSlug("accounts", adapter);
expect(model).not.toBe(modelBis);
});
it("should returns same model from slug and then adapter", () => {
BaseModel = (0, test_utils_1.mockModel)();
const model = Model_1.default.getFromSlug(BaseModel.slug, adapter);
const modelBis = Model_1.default.getAdaptedModel(BaseModel, adapter);
expect(model).toBe(modelBis);
});
it("should returns same model from adapter and then slug", () => {
BaseModel = (0, test_utils_1.mockModel)();
const model = Model_1.default.getAdaptedModel(BaseModel, adapter);
const modelBis = Model_1.default.getFromSlug(BaseModel.slug, adapter);
expect(model).toBe(modelBis);
});
it("should returns first cached model", () => {
const baseAccountFromSlug = Model_1.default.getFromSlug("accounts", adapter);
const baseAccountFromModel = Model_1.default.getAdaptedModel(index_1.models.Account, adapter);
expect(baseAccountFromSlug).toBe(baseAccountFromModel);
const extendedAccount = class extends index_1.models.Account {
};
const extendedAccountFromModel = Model_1.default.getAdaptedModel(extendedAccount, adapter);
expect(extendedAccountFromModel.getBaseClass()).not.toBe(extendedAccount);
expect(extendedAccountFromModel.getBaseClass()).toBe(index_1.models.Account);
});
it("should be able to override model", () => {
const baseAccountFromSlug = Model_1.default.getFromSlug("accounts", adapter);
const baseAccountFromModel = Model_1.default.getAdaptedModel(index_1.models.Account, adapter);
expect(baseAccountFromSlug).toBe(baseAccountFromModel);
const extendedAccount = class extends index_1.models.Account {
};
const extendedAccountFromModel = Model_1.default.getAdaptedModel(extendedAccount, adapter, true);
expect(extendedAccountFromModel.getBaseClass()).toBe(extendedAccount);
});
it("Should be able to get adapted model from slug once it has been adapted from model", () => {
const baseAccountFromSlug = Model_1.default.getFromSlug("accounts", adapter);
const baseAccountFromModel = Model_1.default.getAdaptedModel(index_1.models.Account, adapter);
expect(baseAccountFromSlug).toBe(baseAccountFromModel);
const extendedAccount = class ExtendedAccount extends index_1.models.Account {
};
const extendedAccountFromModel = Model_1.default.getAdaptedModel(extendedAccount, adapter, true);
expect(extendedAccountFromModel.getBaseClass()).toBe(extendedAccount);
const extendedAccountFromSlug = Model_1.default.getFromSlug("accounts", adapter);
expect(extendedAccountFromSlug.getBaseClass()).toBe(extendedAccount);
});
it("Should be able to get adapted model from slug once it has been adapted from model on data", () => {
const slug = "example";
const ExampleModel = class ExampleModel extends Data_1.default {
static slug = slug;
};
const baseModelFromSlug = Model_1.default.getFromSlug(slug, adapter);
const baseModelFromModel = Model_1.default.getAdaptedModel(ExampleModel, adapter);
expect(baseModelFromSlug).toBe(baseModelFromModel);
expect(baseModelFromModel.getBaseClass()).not.toBe(ExampleModel);
const extendedModelFromModel = Model_1.default.getAdaptedModel(ExampleModel, adapter, true);
expect(extendedModelFromModel.getBaseClass()).toBe(ExampleModel);
const extendedModelFromSlug = Model_1.default.getFromSlug(slug, adapter);
expect(extendedModelFromSlug.getBaseClass()).toBe(ExampleModel);
expect(extendedModelFromSlug).toBe(extendedModelFromModel);
});
});
});

@@ -20,3 +20,2 @@ "use strict";

const field_types_1 = __importDefault(require("../enums/field-types"));
const validator_types_1 = __importDefault(require("../enums/validator-types"));
let Project = class Project extends Model_1.default {

@@ -27,10 +26,10 @@ static __name = "Project";

static validators = [
{ type: validator_types_1.default.REQUIRED, options: { field: "name" } },
{ type: validator_types_1.default.REQUIRED, options: { field: "slug" } },
{ type: validator_types_1.default.REQUIRED, options: { field: "organization" } },
{ type: validator_types_1.default.UNIQUE, options: { field: "slug" } },
{
type: validator_types_1.default.REGEX,
options: { field: "slug", pattern: "^[a-zA-Z0-9_\\-]+$" },
},
// { type: ValidatorTypes.REQUIRED, options: { field: "name" } },
// { type: ValidatorTypes.REQUIRED, options: { field: "slug" } },
// { type: ValidatorTypes.REQUIRED, options: { field: "organization" } },
// { type: ValidatorTypes.UNIQUE, options: { field: "slug" } },
// {
// type: ValidatorTypes.REGEX,
// options: { field: "slug", pattern: "^[a-zA-Z0-9_\\-]+$" },
// },
];

@@ -37,0 +36,0 @@ name;

@@ -25,2 +25,3 @@ "use strict";

static scope = model_env_scopes_1.default.PROJECT;
static configKey = "name";
static validators = [

@@ -27,0 +28,0 @@ { type: validator_types_1.default.REQUIRED, options: { field: "name" } },

@@ -8,2 +8,3 @@ import { AdapterFetcher } from "../types";

declare class Adapter {
static __modelsMap: Map<string, typeof Model>;
fetcher: AdapterFetcher;

@@ -10,0 +11,0 @@ fieldsMap: {

import Model from "./Model";
import ModelEnvScopes from "../enums/model-env-scopes";
import DataModel from "../models/DataModel";
import Adapter from "./Adapter";
declare class Data extends Model {

@@ -8,7 +9,6 @@ static extendable: boolean;

static __datamodel: DataModel;
static __modelsMap: Map<string, typeof Data>;
static getFromDatamodel(datamodel: DataModel): typeof Data;
static __getFromSlug<M extends typeof Model = typeof Data>(slug: string): M;
static getFromDatamodel(datamodel: DataModel, adapter?: typeof Adapter): typeof Data;
static __getFromSlug<M extends typeof Model = typeof Data>(slug: string, adapter?: typeof Adapter): M;
[prop: string]: any;
}
export default Data;

@@ -28,3 +28,3 @@ import ModelEnvScopes from "../enums/model-env-scopes";

static __baseClass: typeof Model;
static __decorated: typeof Model;
static __modelsMap: Map<string, Map<typeof Adapter, typeof Model>>;
__doc: DocumentDefinition;

@@ -50,3 +50,4 @@ _id: FieldIdDefinition;

static verifyAdapter(): void;
static getFromSlug<M extends typeof Model = typeof Model>(slug: string, fallbackData?: boolean): M;
static getFromSlug<M extends typeof Model = typeof Model>(slug: string, adapter?: typeof Adapter, fallbackData?: boolean): M;
static getAdaptedModel<M extends typeof Model = typeof Model>(model: M, adapter?: typeof Adapter, override?: boolean): M;
/**

@@ -53,0 +54,0 @@ * Model instance getter. Returns the value for the specified key

@@ -10,2 +10,3 @@ import Model from "../lib/Model";

static scope: ModelEnvScopes;
static configKey: string;
static validators: ValidatorsDefinition;

@@ -12,0 +13,0 @@ name: FieldTextDefinition;

@@ -192,2 +192,3 @@ import Adapter from "./lib/Adapter";

};
__modelsMap: Map<string, typeof Model>;
};

@@ -237,3 +238,3 @@ export declare const mockModel: ({ scope, fields, validators, }?: {

__baseClass: typeof Model;
__decorated: typeof Model;
__modelsMap: Map<string, Map<typeof Adapter, typeof Model>>;
getBaseClass(): typeof Model;

@@ -248,3 +249,4 @@ hasAdapter(): boolean;

verifyAdapter(): void;
getFromSlug<M extends typeof Model = typeof Model>(slug: string, fallbackData?: boolean): M;
getFromSlug<M extends typeof Model = typeof Model>(slug: string, adapter?: typeof Adapter, fallbackData?: boolean): M;
getAdaptedModel<M_1 extends typeof Model = typeof Model>(model: M_1, adapter?: typeof Adapter, override?: boolean): M_1;
fromString<T_2 extends typeof Model>(this: T_2, str: string, cleanPayload?: boolean): Model;

@@ -260,3 +262,3 @@ count<T_3 extends typeof Model>(this: T_3, query?: string | import("./types").JSONQuery, ctx?: any): Promise<number>;

validate<T_11 extends typeof Model>(this: T_11, input: (import("./types").DocumentDefinition | InstanceType<T_11>)[], ctx?: any): Promise<boolean>;
execute<M_1 extends typeof Model, A_1 extends keyof AdapterFetcher<M_1>, Args extends Parameters<AdapterFetcher<typeof Model>[A_1]>[0]>(this: M_1, action: A_1, args: Args, bindCtx?: any): Promise<ReturnType<AdapterFetcher<M_1>[A_1]>>;
execute<M_2 extends typeof Model, A_1 extends keyof AdapterFetcher<M_2>, Args extends Parameters<AdapterFetcher<typeof Model>[A_1]>[0]>(this: M_2, action: A_1, args: Args, bindCtx?: any): Promise<ReturnType<AdapterFetcher<M_2>[A_1]>>;
};
{
"name": "@graphand/core",
"version": "0.3.10",
"version": "0.3.12",
"description": "",

@@ -5,0 +5,0 @@ "homepage": "https://github.com/graphand/core",

@@ -9,2 +9,4 @@ import { AdapterFetcher } from "../types";

class Adapter {
static __modelsMap: Map<string, typeof Model>;
fetcher: AdapterFetcher;

@@ -11,0 +13,0 @@ fieldsMap: { [T in FieldTypes]?: typeof Field<T> };

import { ControllerDefinition } from "../types";
import DataModel from "../models/DataModel";
import Model from "../lib/Model";
import ModelEnvScopes from "../enums/model-env-scopes";

@@ -11,4 +11,4 @@

scope: ({ model }) => {
const Model = DataModel.getFromSlug(model);
if (Model.scope === ModelEnvScopes.GLOBAL) return "global";
const _model = Model.getFromSlug(model);
if (_model.scope === ModelEnvScopes.GLOBAL) return "global";
return "project";

@@ -22,4 +22,4 @@ },

scope: ({ model }) => {
const Model = DataModel.getFromSlug(model);
if (Model.scope === ModelEnvScopes.GLOBAL) return "global";
const _model = Model.getFromSlug(model);
if (_model.scope === ModelEnvScopes.GLOBAL) return "global";
return "project";

@@ -33,4 +33,4 @@ },

scope: ({ model }) => {
const Model = DataModel.getFromSlug(model);
if (Model.scope === ModelEnvScopes.GLOBAL) return "global";
const _model = Model.getFromSlug(model);
if (_model.scope === ModelEnvScopes.GLOBAL) return "global";
return "project";

@@ -44,4 +44,4 @@ },

scope: ({ model }) => {
const Model = DataModel.getFromSlug(model);
if (Model.scope === ModelEnvScopes.GLOBAL) return "global";
const _model = Model.getFromSlug(model);
if (_model.scope === ModelEnvScopes.GLOBAL) return "global";
return "project";

@@ -55,4 +55,4 @@ },

scope: ({ model }) => {
const Model = DataModel.getFromSlug(model);
if (Model.scope === ModelEnvScopes.GLOBAL) return "global";
const _model = Model.getFromSlug(model);
if (_model.scope === ModelEnvScopes.GLOBAL) return "global";
return "project";

@@ -66,4 +66,4 @@ },

scope: ({ model }) => {
const Model = DataModel.getFromSlug(model);
if (Model.scope === ModelEnvScopes.GLOBAL) return "global";
const _model = Model.getFromSlug(model);
if (_model.scope === ModelEnvScopes.GLOBAL) return "global";
return "project";

@@ -70,0 +70,0 @@ },

@@ -7,2 +7,3 @@ import DataModel from "../models/DataModel";

import FieldTypes from "../enums/field-types";
import Model from "./Model";

@@ -14,20 +15,66 @@ describe("Data", () => {

it("should get same model from slug and from datamodel instance", async () => {
const slug = faker.animal.type();
describe("model unicity", () => {
it("should get same model from slug and from datamodel instance with same adapter", async () => {
const slug = faker.animal.type();
const datamodel = new DataModel({ slug });
const datamodel = new DataModel({ slug });
const modelFromDM = Data.getFromDatamodel(datamodel);
const modelFromSlug = Data.getFromSlug(slug);
const modelFromDM = Data.getFromDatamodel(datamodel, adapter);
const modelFromSlug = Data.getFromSlug(slug, adapter);
expect(modelFromDM).toBe(modelFromSlug);
});
expect(modelFromDM).toBe(modelFromSlug);
});
it("getFromDatamodel should returns model with the instance adapter", async () => {
const DM = DataModel.withAdapter(adapter);
const datamodel = new DM({ slug: faker.animal.type() });
it("should get different models from slug and from datamodel instance with different adapters", async () => {
const slug = faker.animal.type();
const modelFromDM = Data.getFromDatamodel(datamodel);
const datamodel = new DataModel({ slug });
expect(modelFromDM.__adapter?.constructor).toBe(adapter);
const modelFromDM = Data.getFromDatamodel(datamodel);
const modelFromSlug = Data.getFromSlug(slug, adapter);
expect(modelFromDM).not.toBe(modelFromSlug);
});
it("getFromDatamodel should returns model with the instance adapter", async () => {
const DM = DataModel.withAdapter(adapter);
const datamodel = new DM({ slug: faker.animal.type() });
const modelFromDM = Data.getFromDatamodel(datamodel);
expect(modelFromDM.__adapter?.constructor).toBe(adapter);
});
it("getFromDatamodel should save adapted model in cache", () => {
const DM = DataModel.withAdapter(adapter);
const datamodel = new DM({ slug: faker.animal.type() });
const modelFromDM = Data.getFromDatamodel(datamodel, adapter);
const modelFromDataSlug = Data.__getFromSlug(datamodel.slug, adapter);
const modelFromModelSlug = Model.getFromSlug(datamodel.slug, adapter);
expect(modelFromDM).toBe(modelFromDataSlug);
expect(modelFromDM).toBe(modelFromModelSlug);
expect(modelFromDataSlug).toBe(modelFromModelSlug);
});
it("getFromDatamodel should override adapted model in cache", () => {
const DM = DataModel.withAdapter(adapter);
const datamodel = new DM({ slug: faker.animal.type() });
const modelFromDataSlug = Data.__getFromSlug(datamodel.slug, adapter);
const modelFromDM = Data.getFromDatamodel(datamodel, adapter);
const modelFromModelSlug = Model.getFromSlug(datamodel.slug, adapter);
expect(modelFromModelSlug).toBe(modelFromDM);
expect(modelFromDM).not.toBe(modelFromDataSlug);
const adaptedModelFromModel = Model.getAdaptedModel(
modelFromDataSlug,
adapter
);
expect(adaptedModelFromModel).toBe(modelFromModelSlug);
expect(modelFromDM).toBe(modelFromModelSlug);
});
});

@@ -74,3 +121,21 @@

it("Test", () => {});
it("Multiple model get should return the same model & initialize once", async () => {
const DM = DataModel.withAdapter(adapter);
const slug = faker.lorem.word();
await DM.create({ slug });
const model = Data.getFromSlug(slug, adapter);
const modelBis = Data.getFromSlug(slug, adapter);
expect(model).toBe(modelBis);
const spy = jest.spyOn(model, "reloadModel");
expect(spy).toHaveBeenCalledTimes(0);
await expect(model.initialize()).resolves.toBeUndefined();
await expect(modelBis.initialize()).resolves.toBeUndefined();
expect(spy).toHaveBeenCalledTimes(1);
});
});

@@ -15,32 +15,45 @@ import Model from "./Model";

static __datamodel: DataModel;
static __modelsMap: Map<string, typeof Data> = new Map();
static getFromDatamodel(datamodel: DataModel): typeof Data {
let model = Data.__modelsMap.get(datamodel.slug);
if (!model) {
model = class extends Data {
static __name = datamodel.name;
static getFromDatamodel(
datamodel: DataModel,
adapter?: typeof Adapter
): typeof Data {
if (!adapter) {
adapter = datamodel.model.__adapter?.constructor as typeof Adapter;
}
static slug = datamodel.slug;
static fields = datamodel.fields;
static validators = [];
static configKey = datamodel.configKey;
};
if (adapter) {
adapter.__modelsMap ??= new Map();
}
model.__datamodel = datamodel;
let model = class extends Data {
static __name = datamodel.name;
Data.__modelsMap.set(datamodel.slug, model);
}
static slug = datamodel.slug;
static fields = datamodel.fields;
static validators = [];
static configKey = datamodel.configKey;
};
const adapter = datamodel.model.__adapter?.constructor as typeof Adapter;
model.__datamodel = datamodel;
if (adapter) {
return model.withAdapter(adapter);
model = model.withAdapter(adapter);
}
adapter?.__modelsMap.set(datamodel.slug, model);
return model;
}
static __getFromSlug<M extends typeof Model = typeof Data>(slug: string): M {
let model = Data.__modelsMap.get(slug);
static __getFromSlug<M extends typeof Model = typeof Data>(
slug: string,
adapter?: typeof Adapter
): M {
if (adapter) {
adapter.__modelsMap ??= new Map();
}
let model: typeof Data = adapter?.__modelsMap.get(slug) as typeof Data;
if (!model) {

@@ -61,5 +74,7 @@ model = class extends Data {

const datamodel = await DataModel.withAdapter(
this.__adapter.constructor as typeof Adapter
).get({ filter: { slug } }, ctx);
const adapter = this.__adapter.constructor as typeof Adapter;
const datamodel = await DataModel.withAdapter(adapter).get(
{ filter: { slug } },
ctx
);

@@ -85,3 +100,7 @@ if (!datamodel) {

Data.__modelsMap.set(slug, model);
if (adapter) {
model = model.withAdapter(adapter);
}
adapter?.__modelsMap.set(slug, model);
}

@@ -88,0 +107,0 @@

@@ -109,3 +109,3 @@ import FieldTypes from "../enums/field-types";

const adapter = from.model.__adapter.constructor as typeof Adapter;
let model = Model.getFromSlug(this.options.ref).withAdapter(adapter);
let model = Model.getFromSlug(this.options.ref, adapter);

@@ -112,0 +112,0 @@ if (this.options.multiple) {

@@ -9,2 +9,3 @@ import { mockAdapter, mockModel } from "../test-utils";

import { getRecursiveValidatorsFromModel } from "../utils";
import Data from "./Data";

@@ -420,2 +421,127 @@ describe("Test Model", () => {

});
describe("Model unicity", () => {
it("should get same model from slug with same adapter", () => {
const model = Model.getFromSlug("accounts", adapter);
const modelBis = Model.getFromSlug("accounts", adapter);
expect(model).toBe(modelBis);
});
it("should get different models from slug with different adapter", () => {
const model = Model.getFromSlug("accounts");
const modelBis = Model.getFromSlug("accounts", adapter);
expect(model).not.toBe(modelBis);
});
it("should returns same model from slug and then adapter", () => {
BaseModel = mockModel();
const model = Model.getFromSlug(BaseModel.slug, adapter);
const modelBis = Model.getAdaptedModel(BaseModel, adapter);
expect(model).toBe(modelBis);
});
it("should returns same model from adapter and then slug", () => {
BaseModel = mockModel();
const model = Model.getAdaptedModel(BaseModel, adapter);
const modelBis = Model.getFromSlug(BaseModel.slug, adapter);
expect(model).toBe(modelBis);
});
it("should returns first cached model", () => {
const baseAccountFromSlug = Model.getFromSlug("accounts", adapter);
const baseAccountFromModel = Model.getAdaptedModel(
models.Account,
adapter
);
expect(baseAccountFromSlug).toBe(baseAccountFromModel);
const extendedAccount = class extends models.Account {};
const extendedAccountFromModel = Model.getAdaptedModel(
extendedAccount,
adapter
);
expect(extendedAccountFromModel.getBaseClass()).not.toBe(extendedAccount);
expect(extendedAccountFromModel.getBaseClass()).toBe(models.Account);
});
it("should be able to override model", () => {
const baseAccountFromSlug = Model.getFromSlug("accounts", adapter);
const baseAccountFromModel = Model.getAdaptedModel(
models.Account,
adapter
);
expect(baseAccountFromSlug).toBe(baseAccountFromModel);
const extendedAccount = class extends models.Account {};
const extendedAccountFromModel = Model.getAdaptedModel(
extendedAccount,
adapter,
true
);
expect(extendedAccountFromModel.getBaseClass()).toBe(extendedAccount);
});
it("Should be able to get adapted model from slug once it has been adapted from model", () => {
const baseAccountFromSlug = Model.getFromSlug("accounts", adapter);
const baseAccountFromModel = Model.getAdaptedModel(
models.Account,
adapter
);
expect(baseAccountFromSlug).toBe(baseAccountFromModel);
const extendedAccount = class ExtendedAccount extends models.Account {};
const extendedAccountFromModel = Model.getAdaptedModel(
extendedAccount,
adapter,
true
);
expect(extendedAccountFromModel.getBaseClass()).toBe(extendedAccount);
const extendedAccountFromSlug = Model.getFromSlug("accounts", adapter);
expect(extendedAccountFromSlug.getBaseClass()).toBe(extendedAccount);
});
it("Should be able to get adapted model from slug once it has been adapted from model on data", () => {
const slug = "example";
const ExampleModel = class ExampleModel extends Data {
static slug = slug;
};
const baseModelFromSlug = Model.getFromSlug(slug, adapter);
const baseModelFromModel = Model.getAdaptedModel(ExampleModel, adapter);
expect(baseModelFromSlug).toBe(baseModelFromModel);
expect(baseModelFromModel.getBaseClass()).not.toBe(ExampleModel);
const extendedModelFromModel = Model.getAdaptedModel(
ExampleModel,
adapter,
true
);
expect(extendedModelFromModel.getBaseClass()).toBe(ExampleModel);
const extendedModelFromSlug = Model.getFromSlug(slug, adapter);
expect(extendedModelFromSlug.getBaseClass()).toBe(ExampleModel);
expect(extendedModelFromSlug).toBe(extendedModelFromModel);
});
});
});

@@ -52,3 +52,4 @@ import ModelEnvScopes from "../enums/model-env-scopes";

static __baseClass: typeof Model;
static __decorated: typeof Model;
static __modelsMap: Map<string, Map<typeof Adapter, typeof Model>> =
new Map();

@@ -263,17 +264,60 @@ __doc: DocumentDefinition;

slug: string,
fallbackData = true
adapter?: typeof Adapter,
fallbackData: boolean = true
): M {
if (!adapter) {
adapter = this.__adapter?.constructor as typeof Adapter;
}
if (adapter) {
adapter.__modelsMap ??= new Map();
}
const models = require("../index").models as Record<string, typeof Model>;
let model: M = Object.values(models).find((m) => m.slug === slug) as M;
if (!model && fallbackData) {
if (model) {
let adaptedModel = adapter?.__modelsMap.get(model.slug) as M;
if (!adaptedModel && adapter) {
adaptedModel = model.withAdapter(adapter);
adapter.__modelsMap.set(model.slug, adaptedModel);
}
model = adaptedModel || model;
} else if (fallbackData) {
const Data = require("./Data").default;
model = Data.__getFromSlug(slug);
model = Data.__getFromSlug(slug, adapter);
}
if (!this.__adapter) {
return model;
return model;
}
static getAdaptedModel<M extends typeof Model = typeof Model>(
model: M,
adapter?: typeof Adapter,
override?: boolean
): M {
if (!adapter) {
adapter = this.__adapter?.constructor as typeof Adapter;
}
const adapter = this.__adapter.constructor as typeof Adapter;
return model.withAdapter(adapter);
if (!adapter) {
throw new CoreError({
message: "Adapter is required in getAdaptedModel method",
});
}
adapter.__modelsMap ??= new Map();
let adaptedModel: M;
if (!override) {
adaptedModel = adapter?.__modelsMap.get(model.slug) as M;
}
if (!adaptedModel) {
adaptedModel = model.withAdapter(adapter);
adapter.__modelsMap.set(model.slug, adaptedModel);
}
return adaptedModel;
}

@@ -280,0 +324,0 @@

@@ -23,10 +23,10 @@ import Model from "../lib/Model";

static validators: ValidatorsDefinition = [
{ type: ValidatorTypes.REQUIRED, options: { field: "name" } },
{ type: ValidatorTypes.REQUIRED, options: { field: "slug" } },
{ type: ValidatorTypes.REQUIRED, options: { field: "organization" } },
{ type: ValidatorTypes.UNIQUE, options: { field: "slug" } },
{
type: ValidatorTypes.REGEX,
options: { field: "slug", pattern: "^[a-zA-Z0-9_\\-]+$" },
},
// { type: ValidatorTypes.REQUIRED, options: { field: "name" } },
// { type: ValidatorTypes.REQUIRED, options: { field: "slug" } },
// { type: ValidatorTypes.REQUIRED, options: { field: "organization" } },
// { type: ValidatorTypes.UNIQUE, options: { field: "slug" } },
// {
// type: ValidatorTypes.REGEX,
// options: { field: "slug", pattern: "^[a-zA-Z0-9_\\-]+$" },
// },
];

@@ -33,0 +33,0 @@

@@ -21,2 +21,3 @@ import Model from "../lib/Model";

static scope = ModelEnvScopes.PROJECT;
static configKey = "name";
static validators: ValidatorsDefinition = [

@@ -23,0 +24,0 @@ { type: ValidatorTypes.REQUIRED, options: { field: "name" } },

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc