graphql-model
Advanced tools
Comparing version 0.0.6 to 0.0.7
353
lib/index.js
@@ -6,9 +6,12 @@ 'use strict'; | ||
}); | ||
exports.Model = exports.clear = exports.get = exports.create = exports.config = undefined; | ||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); | ||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; | ||
var _util = require('./util'); | ||
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } | ||
@@ -18,150 +21,257 @@ | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
var SIGNATURE = {}; | ||
var getCleanObject = function getCleanObject() { | ||
return Object.create(null); | ||
}; | ||
var createSetter = function createSetter(key) { | ||
return function set(value) { | ||
this._data[key] = value; | ||
delete this._cache[key]; | ||
delete this[key]; | ||
}; | ||
}; | ||
var getGetter = function getGetter(obj, key) { | ||
var _Object$getOwnPropert = Object.getOwnPropertyDescriptor(obj, key); | ||
var models = getCleanObject(); | ||
var globalDefaultRead = true; | ||
var globalDefaultReadFail = null; | ||
var globalDefaultCache = true; | ||
var get = _Object$getOwnPropert.get; | ||
var getModel = function getModel(model) { | ||
return typeof model === 'string' ? models[model] : model; | ||
}; | ||
if (!get) { | ||
throw new Error('Getter must be set for property, \'' + key + '\''); | ||
} | ||
return get; | ||
var createChildModel = function createChildModel(parent, Class, data) { | ||
return new Class(data, parent._context, parent, parent._root); | ||
}; | ||
var models = {}; | ||
var createModelMapFn = function createModelMapFn(Class) { | ||
return function (data) { | ||
return data && createChildModel(this, Class, data); | ||
}; | ||
}; | ||
var getModel = function getModel(model) { | ||
return typeof model === 'string' ? models[model] : model; | ||
var createSimpleGetter = function createSimpleGetter(key) { | ||
return function () { | ||
return this._data[key]; | ||
}; | ||
}; | ||
var createGetter = function createGetter(prototype, key, Type) { | ||
if (Array.isArray(Type)) { | ||
var _ret = function () { | ||
// [Model] | ||
if (key in prototype) { | ||
var _ret2 = function () { | ||
var getter = getGetter(prototype, key); | ||
var FieldModel = Type[0]; | ||
return { | ||
v: { | ||
v: function get() { | ||
var c = this._cache; | ||
var wrapGetterWithModel = function wrapGetterWithModel(key, getter, _ref) { | ||
var type = _ref.type; | ||
var list = _ref.list; | ||
return c[key] || (c[key] = this.$createChildren(FieldModel, getter.call(this))); | ||
} | ||
} | ||
}; | ||
}(); | ||
if (!type) { | ||
return getter; | ||
} | ||
if ((typeof _ret2 === 'undefined' ? 'undefined' : _typeof(_ret2)) === "object") return _ret2.v; | ||
var _mapFn = void 0; | ||
if (typeof type === 'string') { | ||
_mapFn = function mapFn(data) { | ||
if (!models[type]) { | ||
throw new Error('Unknown field model. model=\'' + type + '\''); | ||
} | ||
var FieldModel = Type[0]; | ||
return { | ||
v: function get() { | ||
var c = this._cache; | ||
_mapFn = createModelMapFn(models[type]); | ||
return _mapFn.call(this, data); | ||
}; | ||
} else { | ||
_mapFn = createModelMapFn(type); | ||
} | ||
return c[key] || (c[key] = this.$createChildren(FieldModel, this._data[key])); | ||
} | ||
}; | ||
}(); | ||
if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v; | ||
if (list) { | ||
// List type field. | ||
return function get() { | ||
var val = getter.call(this); | ||
return val && val.map(_mapFn, this); | ||
}; | ||
} | ||
if (typeof Type === 'function' || typeof Type === 'string') { | ||
// Model | ||
if (key in prototype) { | ||
var _ret3 = function () { | ||
var getter = getGetter(prototype, key); | ||
return { | ||
v: function get() { | ||
var c = this._cache; | ||
// Non-list type field. | ||
return function get() { | ||
return _mapFn.call(this, getter.call(this)); | ||
}; | ||
}; | ||
return c[key] || (c[key] = this.$createChild(Type, getter.call(this))); | ||
} | ||
}; | ||
}(); | ||
var wrapGetterWithAccess = function wrapGetterWithAccess(key, getter, _ref2) { | ||
var read = _ref2.read; | ||
var readFail = _ref2.readFail; | ||
if ((typeof _ret3 === 'undefined' ? 'undefined' : _typeof(_ret3)) === "object") return _ret3.v; | ||
if (read === true) { | ||
return getter; | ||
} | ||
if (!read) { | ||
if (typeof readFail === 'function') { | ||
return function get() { | ||
return readFail(this, key); | ||
}; | ||
} | ||
return function get() { | ||
var c = this._cache; | ||
return c[key] || (c[key] = this.$createChild(Type, this._data[key])); | ||
return readFail; | ||
}; | ||
} | ||
if (Type) { | ||
// Value | ||
if (typeof readFail === 'function') { | ||
return function get() { | ||
return this._data[key]; | ||
if (read(this, key)) { | ||
return getter.call(this); | ||
} | ||
return readFail(this, key); | ||
}; | ||
} | ||
return function get() { | ||
if (read(this, key)) { | ||
return getter.call(this); | ||
} | ||
return readFail; | ||
}; | ||
}; | ||
var Model = function () { | ||
_createClass(Model, null, [{ | ||
key: 'create', | ||
value: function create(Class) { | ||
var _ref = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | ||
var wrapGetterWithCache = function wrapGetterWithCache(key, getter, _ref3) { | ||
var _ref3$cache = _ref3.cache; | ||
var cache = _ref3$cache === undefined ? globalDefaultCache : _ref3$cache; | ||
var _ref$base = _ref.base; | ||
var Base = _ref$base === undefined ? Model : _ref$base; | ||
var _ref$interfaces = _ref.interfaces; | ||
var interfaces = _ref$interfaces === undefined ? [] : _ref$interfaces; | ||
var _ref$fields = _ref.fields; | ||
var fields = _ref$fields === undefined ? {} : _ref$fields; | ||
if (!cache) { | ||
return getter; | ||
} | ||
var NewModel = function (_Base) { | ||
_inherits(NewModel, _Base); | ||
return function get() { | ||
var value = getter.call(this); | ||
this[key] = value; | ||
(0, _util.setProperty)(this, key, value); | ||
return value; | ||
}; | ||
}; | ||
function NewModel() { | ||
_classCallCheck(this, NewModel); | ||
var createGetter = function createGetter(prototype, key, rule) { | ||
var getter = void 0; | ||
getter = createSimpleGetter(key); | ||
getter = wrapGetterWithModel(key, getter, rule); | ||
getter = wrapGetterWithAccess(key, getter, rule); | ||
getter = wrapGetterWithCache(key, getter, rule); | ||
return getter; | ||
}; | ||
return _possibleConstructorReturn(this, Object.getPrototypeOf(NewModel).apply(this, arguments)); | ||
} | ||
// exports | ||
return NewModel; | ||
}(Base); | ||
var config = exports.config = function config(defaults) { | ||
if ('read' in defaults) globalDefaultRead = defaults.read; | ||
if ('readFail' in defaults) globalDefaultReadFail = defaults.readFail; | ||
if ('cache' in defaults) globalDefaultCache = Boolean(defaults.cache); | ||
}; | ||
var name = Class.name; | ||
var create = exports.create = function create() { | ||
var _ref4 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | ||
if (models[name]) { | ||
throw new Error('\'' + name + '\' model already exists!'); | ||
} | ||
models[name] = NewModel; | ||
var name = _ref4.name; | ||
var _ref4$base = _ref4.base; | ||
var base = _ref4$base === undefined ? Model : _ref4$base; | ||
var _ref4$props = _ref4.props; | ||
var props = _ref4$props === undefined ? getCleanObject() : _ref4$props; | ||
var _ref4$rules = _ref4.rules; | ||
var rules = _ref4$rules === undefined ? getCleanObject() : _ref4$rules; | ||
var _ref4$interfaces = _ref4.interfaces; | ||
var interfaces = _ref4$interfaces === undefined ? [] : _ref4$interfaces; | ||
(0, _util.defineClassName)(NewModel, name); | ||
(0, _util.defineStatic)(NewModel, 'isModel', true); | ||
(0, _util.defineStatic)(NewModel, 'fields', fields); | ||
(0, _util.defineStatic)(NewModel, 'interfaces', interfaces); | ||
var NewModel = function (_base) { | ||
_inherits(NewModel, _base); | ||
[Class, Base].concat(interfaces).forEach(function (from) { | ||
return (0, _util.inheritClass)(NewModel, from); | ||
}); | ||
function NewModel() { | ||
_classCallCheck(this, NewModel); | ||
(0, _util.forEach)(fields, function (type, key) { | ||
return (0, _util.defineGetterSetter)(NewModel.prototype, key, createGetter(NewModel.prototype, key, type), createSetter(key)); | ||
}); | ||
return _possibleConstructorReturn(this, Object.getPrototypeOf(NewModel).apply(this, arguments)); | ||
} | ||
return NewModel; | ||
return NewModel; | ||
}(base); | ||
// name | ||
if (models[name]) { | ||
throw new Error('\'' + name + '\' model already exists!'); | ||
} | ||
models[name] = NewModel; | ||
(0, _util.defineClassName)(NewModel, name); | ||
// signature | ||
(0, _util.defineStatic)(NewModel, '$signature', SIGNATURE); | ||
// props | ||
var Props = function Props(model) { | ||
_classCallCheck(this, Props); | ||
this.$model = model; | ||
}; | ||
(0, _util.defineStatic)(NewModel, '$Props', Props); | ||
(0, _util.forEach)(props, function (fn, key) { | ||
return (0, _util.defineLazyProperty)(Props.prototype, key, function () { | ||
return fn.call(this, this.$model); | ||
}); | ||
}); | ||
(0, _util.defineLazyProperty)(NewModel.prototype, '$props', function () { | ||
return new Props(this); | ||
}); | ||
// interfaces | ||
(0, _util.defineStatic)(NewModel, '$interfaces', interfaces); | ||
if (base !== Model) { | ||
(0, _util.inheritClass)(NewModel, base); | ||
if (base.$Props) (0, _util.inheritClass)(Props, base.$Props); | ||
} | ||
interfaces.forEach(function (from) { | ||
(0, _util.inheritClass)(NewModel, from); | ||
if (from.$Props) (0, _util.inheritClass)(Props, from.$Props); | ||
}); | ||
// rules | ||
var _rules$$default = rules.$default; | ||
_rules$$default = _rules$$default === undefined ? {} : _rules$$default; | ||
var _rules$$default$read = _rules$$default.read; | ||
var defaultRead = _rules$$default$read === undefined ? globalDefaultRead : _rules$$default$read; | ||
var _rules$$default$readF = _rules$$default.readFail; | ||
var defaultReadFail = _rules$$default$readF === undefined ? globalDefaultReadFail : _rules$$default$readF; | ||
var otherRules = _objectWithoutProperties(rules, ['$default']); | ||
(0, _util.forEach)(otherRules, function (rule, key) { | ||
if (rule === true) { | ||
rule = { | ||
read: true, | ||
readFail: defaultReadFail | ||
}; | ||
} else if (rule === false) { | ||
rule = { | ||
read: false, | ||
readFail: defaultReadFail | ||
}; | ||
} else if (typeof rule === 'function') { | ||
rule = { | ||
read: rule, | ||
readFail: defaultReadFail | ||
}; | ||
} else { | ||
if (rule.read === undefined) rule.read = defaultRead; | ||
if (rule.readFail === undefined) rule.readFail = defaultReadFail; | ||
} | ||
}, { | ||
key: 'clear', | ||
value: function clear() { | ||
models = {}; | ||
} | ||
}]); | ||
function Model(data, parent, root) { | ||
var context = arguments.length <= 3 || arguments[3] === undefined ? null : arguments[3]; | ||
(0, _util.defineGetterSetter)(NewModel.prototype, key, createGetter(NewModel.prototype, key, rule), createSetter(key)); | ||
}); | ||
return NewModel; | ||
}; | ||
var get = exports.get = getModel; | ||
var clear = exports.clear = function clear() { | ||
models = getCleanObject(); | ||
}; | ||
var Model = exports.Model = function () { | ||
function Model(data, context, parent, root) { | ||
_classCallCheck(this, Model); | ||
@@ -173,3 +283,2 @@ | ||
this._context = context; | ||
this._cache = {}; | ||
} | ||
@@ -183,7 +292,6 @@ | ||
delete this._context; | ||
delete this._cache; | ||
} | ||
}, { | ||
key: '$field', | ||
value: function $field(name) { | ||
key: '$get', | ||
value: function $get(name) { | ||
return this._data[name]; | ||
@@ -206,26 +314,18 @@ } | ||
value: function $createChild(model, data) { | ||
return new (getModel(model))(data, this, this._root, this._context); | ||
return createChildModel(this, getModel(model), data); | ||
} | ||
}, { | ||
key: '$createChildren', | ||
value: function $createChildren(model, dataList) { | ||
value: function $createChildren(model, list) { | ||
var _this2 = this; | ||
return dataList && dataList.map(function (data) { | ||
return _this2.$createChild(model, data); | ||
var Class = getModel(model); | ||
return list && list.map(function (data) { | ||
return createChildModel(_this2, Class, data); | ||
}); | ||
} | ||
}, { | ||
key: '$clearCache', | ||
value: function $clearCache(key) { | ||
if (key) { | ||
delete this._cache[key]; | ||
} else { | ||
this._cache = {}; | ||
} | ||
} | ||
}, { | ||
key: '$implements', | ||
value: function $implements(Type) { | ||
return this.constructor.interfaces.indexOf(Type) >= 0; | ||
return this.constructor.$interfaces.indexOf(Type) >= 0; | ||
} | ||
@@ -257,3 +357,8 @@ }, { | ||
Model.get = getModel; | ||
exports.default = Model; | ||
exports.default = { | ||
config: config, | ||
create: create, | ||
get: get, | ||
clear: clear, | ||
Model: Model | ||
}; |
@@ -7,3 +7,6 @@ 'use strict'; | ||
exports.forEach = forEach; | ||
exports.setProperty = setProperty; | ||
exports.defineStatic = defineStatic; | ||
exports.defineMethod = defineMethod; | ||
exports.defineLazyProperty = defineLazyProperty; | ||
exports.defineGetterSetter = defineGetterSetter; | ||
@@ -24,2 +27,11 @@ exports.inheritPropertyFrom = inheritPropertyFrom; | ||
function setProperty(obj, key, value) { | ||
return Object.defineProperty(obj, key, { | ||
value: value, | ||
enumerable: true, | ||
writable: true, | ||
configurable: true | ||
}); | ||
} | ||
function defineStatic(Class, name, value) { | ||
@@ -34,2 +46,39 @@ return Object.defineProperty(Class, name, { | ||
function defineMethod(prototype, name, value) { | ||
Object.defineProperty(prototype, name, { | ||
value: value, | ||
writable: true, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
} | ||
function defineLazyProperty(obj, name, fn) { | ||
var _ref = arguments.length <= 3 || arguments[3] === undefined ? {} : arguments[3]; | ||
var _ref$writable = _ref.writable; | ||
var writable = _ref$writable === undefined ? true : _ref$writable; | ||
var _ref$enumerable = _ref.enumerable; | ||
var enumerable = _ref$enumerable === undefined ? true : _ref$enumerable; | ||
var _ref$configurable = _ref.configurable; | ||
var configurable = _ref$configurable === undefined ? true : _ref$configurable; | ||
Object.defineProperty(obj, name, { | ||
get: function get() { | ||
// Use 'this' instead of obj so that obj can be a prototype. | ||
var value = fn.call(this); | ||
Object.defineProperty(this, name, { | ||
value: value, | ||
writable: writable, | ||
enumerable: enumerable, | ||
configurable: configurable | ||
}); | ||
return value; | ||
}, | ||
enumerable: enumerable, | ||
configurable: true | ||
}); | ||
} | ||
var defineClassName = void 0; | ||
@@ -51,4 +100,4 @@ if (function () { | ||
} else { | ||
// Old Node versions require the following options to overwrite class name. | ||
exports.defineClassName = defineClassName = function defineClassName(Class, value) { | ||
// Old Node versions require the following options to overwrite class name. | ||
return Object.defineProperty(Class, 'name', { | ||
@@ -70,3 +119,3 @@ value: value, | ||
}); | ||
}; | ||
} | ||
@@ -73,0 +122,0 @@ function inheritPropertyFrom(objA, objB, key, asKey) { |
{ | ||
"name": "graphql-model", | ||
"version": "0.0.6", | ||
"version": "0.0.7", | ||
"description": "A data model class for wrapping a data object for easier resolving fields in GraphQL", | ||
@@ -44,3 +44,8 @@ "main": "lib/index.js", | ||
"mocha": "^2.4.5" | ||
}, | ||
"dependencies": { | ||
"auth-perm": "0.0.3", | ||
"graphql-permissions": "0.0.4", | ||
"romodel": "github:joonhocho/romodel" | ||
} | ||
} |
290
README.md
# graphql-model | ||
A data model class for wrapping a data object for easier resolving fields in GraphQL. | ||
# Work In Progress | ||
@@ -11,292 +12,3 @@ ### Install | ||
### Usage | ||
```javascript | ||
it('User', () => { | ||
// Create a Node model | ||
const Node = Model.create(class Node { | ||
static isNode(obj) { return obj instanceof Node; } | ||
get type() { return this.constructor.name; } | ||
}, { | ||
fields: { | ||
id: true, | ||
}, | ||
}); | ||
// Create a InfoInterface model | ||
const InfoInterface = Model.create(class InfoInterface {}, { | ||
fields: { | ||
isPublic: true, | ||
}, | ||
}); | ||
// Create a InfoBase model | ||
const InfoBase = Model.create(class InfoBase { | ||
static isInfo = (obj) => obj instanceof InfoBase | ||
get user() { return this.$parentOfType('User'); } | ||
isSharedWith(user) { return this.user.isFriendsWith(user); } | ||
}); | ||
// Create a Name model | ||
const NameModel = Model.create(class Name { | ||
static isName(obj) { return obj instanceof NameModel; } | ||
getFirstAndLastName() { return [this.firstName, this.lastName]; } | ||
get shortName() { return `${this.firstName} ${this.lastName}`; } | ||
get profile() { return this.$parent; } | ||
get profile2() { return this.$parentOfType(Profile); } | ||
get profile3() { return this.$parentOfType('Profile'); } | ||
}, { | ||
base: InfoBase, | ||
interfaces: [Node, InfoInterface], | ||
fields: { | ||
firstName: true, | ||
lastName: true, | ||
}, | ||
}); | ||
// Create a Profile model | ||
const Profile = Model.create(class Profile {}, { | ||
fields: { | ||
names: [NameModel], | ||
}, | ||
}); | ||
// Create a User model | ||
const User = Model.create(class User { | ||
get friends() { | ||
return this.$field('friendIds').map((id) => ({id})); | ||
} | ||
isFriendsWith(user) { | ||
return this.$field('friendIds').indexOf(user.id) > -1; | ||
} | ||
}, { | ||
interfaces: [Node], | ||
fields: { | ||
profile: Profile, | ||
hiddenField: false, | ||
}, | ||
}); | ||
// Create a user instance | ||
const user = new User({ | ||
id: '1', | ||
profile: { | ||
names: [{id: 'n1', firstName: 'F', lastName: 'L', isPublic: true}], | ||
}, | ||
friendIds: ['2', '4'], | ||
hiddenField: 1, | ||
}); | ||
// static declared by interface Node | ||
expect(user.id).to.equal('1'); | ||
// dynamic field defined by interface Node | ||
expect(user.type).to.equal('User'); | ||
// undeclared field access | ||
expect(user.friendIds).to.be.undefined; | ||
// access undeclared field | ||
expect(user.$field('friendIds')).to.eql(['2', '4']); | ||
// hidden field access | ||
expect(user.hiddenField).to.be.undefined; | ||
// access hidden field | ||
expect(user.$field('hiddenField')).to.equal(1); | ||
// set hidden field | ||
user.hiddenField = 3; | ||
expect(user.hiddenField).to.be.undefined; | ||
expect(user.$field('hiddenField')).to.equal(3); | ||
// constructor | ||
expect(user.constructor).to.equal(User); | ||
// instanceof | ||
expect(user).to.be.an.instanceof(User); | ||
// $implements | ||
expect(user.$implements(Node)).to.be.true; | ||
// dynamic field | ||
expect(user.friends.map(({id}) => id)).to.eql(user.$data.friendIds); | ||
// method | ||
expect(user.isFriendsWith({id: '2'})).to.be.true; | ||
expect(user.isFriendsWith({id: '1'})).to.be.false; | ||
// instance field | ||
const {profile} = user; | ||
expect(profile).to.be.an.instanceof(Profile); | ||
// cached | ||
expect(profile).to.equal(user.profile); | ||
// instance list field | ||
const {names: [name]} = profile; | ||
expect(name.constructor).to.equal(NameModel); | ||
expect(name).to.be.an.instanceof(NameModel); | ||
// cached | ||
expect(name).to.equal(user.profile.names[0]); | ||
// base class | ||
expect(name).to.be.an.instanceof(InfoBase); | ||
// interfaces | ||
expect(name.$implements(Node)).to.be.true; | ||
expect(name.$implements(InfoInterface)).to.be.true; | ||
// field declared by Node | ||
expect(name.id).to.equal('n1'); | ||
// field declared by Node | ||
expect(name.type).to.equal('Name'); | ||
// declared field | ||
expect(name.firstName).to.equal('F'); | ||
// declared field | ||
expect(name.lastName).to.equal('L'); | ||
// method | ||
expect(name.getFirstAndLastName()).to.eql(['F', 'L']); | ||
expect(name.shortName).to.equal('F L'); | ||
// $parent | ||
expect(name.profile).to.equal(profile); | ||
// $parentOfType | ||
expect(name.profile2).to.equal(profile); | ||
expect(name.profile3).to.equal(profile); | ||
// $parentOfType declared by InfoBase | ||
expect(name.user).to.equal(user); | ||
// $parent | ||
expect(name.$parent.$parent).to.equal(user); | ||
// inherited from base | ||
expect(name.user).to.equal(user); | ||
// inherited from base | ||
expect(name.isSharedWith(user)).to.be.false; | ||
expect(name.isSharedWith({id: '2'})).to.be.true; | ||
expect(name.isSharedWith({id: '3'})).to.be.false; | ||
// inherited from InfoInterface | ||
expect(name.isPublic).to.be.true; | ||
// static method | ||
expect(NameModel.isName(name)).to.be.true; | ||
expect(NameModel.isName(user)).to.be.false; | ||
expect(NameModel.isInfo(user)).to.be.false; | ||
expect(NameModel.isInfo(name)).to.be.true; | ||
expect(NameModel.isInfo).to.equal(InfoBase.isInfo); | ||
// clear cache | ||
expect(profile.names[0]).to.equal(name); | ||
profile.$clearCache('names'); | ||
expect(profile.names[0]).to.not.equal(name); | ||
expect(profile.names[0].id).to.equal(name.id); | ||
// destory | ||
user.$destroy(); | ||
expect(() => user.id).to.throw(); | ||
expect(user.$parent).to.be.undefined; | ||
}); | ||
it('can pass down optional context', () => { | ||
const GrandChild = Model.create(class GrandChild {}, { | ||
fields: { | ||
id: true, | ||
}, | ||
}); | ||
const Child = Model.create(class Child {}, { | ||
fields: { | ||
id: true, | ||
child: GrandChild, | ||
}, | ||
}); | ||
const Parent = Model.create(class Parent {}, { | ||
fields: { | ||
child: Child, | ||
}, | ||
}); | ||
const context = {}; | ||
const parent = new Parent({child: {child: {}}}, null, null, context); | ||
expect(parent.$context).to.equal(context); | ||
expect(parent.child.$context).to.equal(context); | ||
expect(parent.child.child.$context).to.equal(context); | ||
}); | ||
it('passes down a root instance', () => { | ||
const GrandChild = Model.create(class GrandChild {}, { | ||
fields: { | ||
id: true, | ||
}, | ||
}); | ||
const Child = Model.create(class Child {}, { | ||
fields: { | ||
id: true, | ||
child: GrandChild, | ||
}, | ||
}); | ||
const Parent = Model.create(class Parent {}, { | ||
fields: { | ||
child: Child, | ||
}, | ||
}); | ||
const parent = new Parent({child: {child: {}}}); | ||
expect(parent.$root).to.equal(parent); | ||
expect(parent.child.$root).to.equal(parent); | ||
expect(parent.child.child.$root).to.equal(parent); | ||
}); | ||
it('can create a child that is an instance of itself', () => { | ||
const Selfie = Model.create(class Selfie {}, { | ||
fields: { | ||
child: 'Selfie', | ||
}, | ||
}); | ||
const parent = new Selfie({child: {}}); | ||
expect(parent).to.be.an.instanceof(Selfie); | ||
expect(parent.child).to.be.an.instanceof(Selfie); | ||
}); | ||
it('can create a child of future model class', () => { | ||
const Present = Model.create(class Present {}, { | ||
fields: { | ||
child: 'Future', | ||
}, | ||
}); | ||
const Future = Model.create(class Future {}); | ||
const parent = new Present({child: {}}); | ||
expect(parent).to.be.an.instanceof(Present); | ||
expect(parent.child).to.be.an.instanceof(Future); | ||
}); | ||
``` | ||
### TODO | ||
### LICENSE | ||
@@ -303,0 +15,0 @@ ``` |
GitHub dependency
Supply chain riskContains a dependency which resolves to a GitHub URL. Dependencies fetched from GitHub specifiers are not immutable can be used to inject untrusted code or reduce the likelihood of a reproducible install.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
433
0
18196
3
37
1
+ Addedauth-perm@0.0.3
+ Addedgraphql-permissions@0.0.4
+ Addedauth-perm@0.0.3(transitive)
+ Addedgraphql-permissions@0.0.4(transitive)