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

@jaysalvat/smart-model

Package Overview
Dependencies
Maintainers
1
Versions
31
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@jaysalvat/smart-model - npm Package Compare versions

Comparing version 0.5.0 to 0.6.0

85

build/smart-model.esm.js
/**!
* SmartModel
* Javascript object model
* https://github.com/jaysalvat/smart-model
* @version 0.5.0 built 2021-02-25 09:18:46
* @version 0.6.0 built 2021-02-26 08:03:42
* @license ISC

@@ -30,3 +29,3 @@ * @author Jay Salvat http://jaysalvat.com

function isSmartModel(value) {
return value.prototype instanceof SmartModel || value instanceof SmartModel;
return value && (value.prototype instanceof SmartModel || value instanceof SmartModel);
}

@@ -43,3 +42,3 @@

function keys(obj, cb = function() {}) {
return Object.keys(obj).map(cb);
return Object.keys(obj).map((key => cb(key, obj[key])));
}

@@ -153,4 +152,3 @@

if (entry.rule) {
keys(entry.rule, (key => {
const rule = entry.rule[key];
keys(entry.rule, ((key, rule) => {
if (rule(value)) {

@@ -200,3 +198,3 @@ errors.push({

}
if (isTypeArrayOfSmartModels(entry.type)) {
if (isTypeArrayOfSmartModels(entry.type) && !isUndef(value)) {
value = entry.type[0].$hydrate(value);

@@ -216,3 +214,3 @@ entry.type = Array;

}
if (Nested) {
if (Nested && !isUndef(value)) {
value = new Nested(value);

@@ -224,2 +222,3 @@ }

trigger(target.$onUpdate);
target.$applySubscribers(property, value);
}

@@ -262,6 +261,9 @@ return true;

}
trigger(target.$onBeforeDelete);
if (trigger(target.$onBeforeDelete) === false) {
return true;
}
Reflect.deleteProperty(target, property);
trigger(target.$onDelete);
trigger(target.$onUpdate);
target.$applySubscribers(property, value);
return true;

@@ -276,12 +278,3 @@ }

super(schema, settings);
keys(schema, (key => {
if (isUndef(data[key])) {
if (!isUndef(schema[key].default)) {
this[key] = schema[key].default;
} else if (!isFn(schema[key])) {
this[key] = data[key];
}
}
}));
this.$patch(data);
this.$post(data);
}

@@ -293,22 +286,23 @@ $patch(data) {

}
$put(data) {
keys(this, (key => {
if (data[key]) {
if (isSmartModel(this[key])) {
this[key].$put(data[key]);
$post(data) {
let undef;
const schema = this.$schema();
keys(schema, ((key, value) => {
if (isUndef(data[key])) {
if (!isUndef(value.default)) {
this[key] = value.default;
} else {
this[key] = data[key];
this[key] = undef;
}
} else {
this.$delete(key);
}
}));
keys(data, (key => {
if (!this[key]) {
this[key] = data[key];
keys(this, ((key, value) => {
if (isUndef(schema[key] && isUndef(value))) {
this.$delete(key);
}
}));
this.$patch(data);
}
$post(data) {
return this.$put(data);
$put(data) {
return this.$post(data);
}

@@ -320,2 +314,8 @@ $delete(properties) {

}
$subscribe(fn) {
this.$subscribers().push(fn);
return () => {
this.$subscribers(fn);
};
}
}

@@ -346,2 +346,3 @@

SmartModel.create = function(name, schema, settings) {
let subscribers = [];
settings = merge(SmartModel.settings, settings);

@@ -353,10 +354,23 @@ const Model = {

}
$schema() {
return schema;
}
$subscribers(removedFn) {
if (removedFn) {
subscribers = subscribers.filter((fn => fn !== removedFn));
}
return subscribers;
}
$applySubscribers(property, value) {
keys(subscribers, ((_, subscriber) => {
Reflect.apply(subscriber, this, [ property, value, this ]);
}));
}
}
}[name];
Model.$check = function(payload, filters) {
Model.$check = function(payload = {}, filters) {
const invalidations = {};
keys(schema, (property => {
keys(schema, ((property, entry) => {
let subErrors;
const value = payload[property];
const entry = schema[property];
const Nested = createNested(entry, property, settings);

@@ -388,3 +402,2 @@ if (Nested) {

Object.assign(Model.prototype, settings.methods);
Model.schema = schema;
return Model;

@@ -391,0 +404,0 @@ };

@@ -1,2 +0,2 @@

/*! SmartModel v0.5.0 */
function e(e){return Array.isArray(e)}function t(e){return void 0===e}function r(e){return"function"==typeof e}function n(e){return e&&e.toString().startsWith("class")}function o(e){return e.prototype instanceof l||e instanceof l}function s(e){return e&&"[object Object]"===e.toString()}function c(e,t=function(){}){return Object.keys(e).map(t)}function i(e){return[].concat([],e)}function u(e,t){return t=Object.assign({},e,t),c(e,(r=>{s(e[r])&&s(t[r])&&(t[r]=Object.assign({},e[r],u(e[r],t[r])))})),t}class a extends Error{constructor(e){super(e.message),Object.assign(this,e)}}function p(t,r,u,a,p){const f=[];return p.strict&&!c(t||{}).length&&f.push({message:`Property "${r}" can't be set in strict mode`,code:"strict"}),t.required&&p.empty(u)?(f.push({message:`Property "${r}" is "required"`,code:"required"}),f):t.readonly&&!a?(f.push({message:`Property "${r}" is "readonly"`,code:"readonly"}),f):(void 0===u||(!t.type||!t.required&&p.empty(u)||o(t.type)&&s(u)||i(t.type).some((t=>function(t,r){const o=r&&r.toString().match(/^\s*function (\w+)/),s=(o?o[1]:"object").toLowerCase();if("date"===s&&t instanceof r)return!0;if("array"===s&&e(t))return!0;if("object"===s){if(n(r)&&t instanceof r)return!0;if(!n(r)&&typeof t===s)return!0}else if(typeof t===s)return!0;return!1}(u,t)))||f.push({message:`Property "${r}" has an invalid type "${typeof u}"`,code:"type"}),t.rule&&c(t.rule,(e=>{(0,t.rule[e])(u)&&f.push({message:`Property "${r}" triggers the "${e}" rule error`,code:"rule:"+e})}))),f)}function f(e={},t,r){if(e.type){const n=!!o(e.type)&&e.type,c=!!s(e.type)&&e.type;if(n||c){const o=n||l.create(t.normalize("NFD").replace(/[\u0300-\u036f]/g,"").match(/[a-z1-9]+/gi).map((e=>e.charAt(0).toUpperCase()+e.substr(1).toLowerCase())).join(""),c,r);return e.type=o,o}}return!1}a.throw=function(e,t,r,n,o){const c=t.split(":")[0];if(o=o&&o.constructor.name,!0===e.exceptions||s(e.exceptions)&&e.exceptions[c])throw new a({message:`[${o}] ${r}`,source:o,property:n,code:t})};class l extends class{constructor(n,s){return new Proxy(this,{set(i,u,l){const y=n[u]||{},d=i[u],h=t(d),$=!(h||(g=l,m=d,JSON.stringify(g)===JSON.stringify(m)));var g,m;const b=f(y,u,s);function w(e,r){const o=Reflect.apply(e,i,r||[u,l,d,n]);return t(o)?l:o}var j;l=w(i.$onBeforeSet),$&&(l=w(i.$onBeforeUpdate)),r(y.transform)&&(l=w(y.transform,[l,n])),e(j=y.type)&&1===j.length&&o(j[0])&&(l=y.type[0].$hydrate(l),y.type=Array);const x=p(y,u,l,h,s);if(x.length){if(!s.exceptions)return!0;a.throw(s,x[0].code,x[0].message,u,i)}return s.strict&&!c(y).length||(b&&(l=new b(l)),i[u]=l,w(i.$onSet),$&&w(i.$onUpdate)),!0},get(e,s){const i=n[s];let u=e[s];if(["$get"].includes(s))return function(){return function(e){return c(e=Object.assign({},e),(t=>{o(e[t])&&(e[t]=e[t].$get())})),e}(e)};if(!i)return e[s];function a(r,o){const c=Reflect.apply(r,e,o||[s,u,n]);return t(c)?u:c}return u=a(e.$onBeforeGet),r(i)&&(u=a(i,[e,n])),r(i.format)&&(u=a(i.format,[u,n])),u=a(e.$onGet),u},deleteProperty(e,t){const r=e[t];function o(o,s){return Reflect.apply(o,e,s||[t,r,n])}return(n[t]||{}).required&&a.throw(s,"required",`Property "${t}" is "required"`,t,e),o(e.$onBeforeDelete),Reflect.deleteProperty(e,t),o(e.$onDelete),o(e.$onUpdate),!0}})}}{constructor(e={},n={},o){super(e,o),c(e,(o=>{t(n[o])&&(t(e[o].default)?r(e[o])||(this[o]=n[o]):this[o]=e[o].default)})),this.$patch(n)}$patch(e){c(e,(t=>{this[t]=e[t]}))}$put(e){c(this,(t=>{e[t]?o(this[t])?this[t].$put(e[t]):this[t]=e[t]:this.$delete(t)})),c(e,(t=>{this[t]||(this[t]=e[t])}))}$post(e){return this.$put(e)}$delete(e){i(e).forEach((e=>{Reflect.deleteProperty(this,e)}))}}l.settings={empty:e=>""===e||null===e||t(e),strict:!1,exceptions:{readonly:!1,required:!0,rule:!0,strict:!1,type:!0},methods:{$onBeforeGet:()=>{},$onBeforeSet:()=>{},$onBeforeUpdate:()=>{},$onDelete:()=>{},$onGet:()=>{},$onBeforeDelete:()=>{},$onSet:()=>{},$onUpdate:()=>{}}},l.create=function(t,r,n){n=u(l.settings,n);const o={[t]:class extends l{constructor(e){super(r,e,n)}}}[t];return o.$check=function(e,t){const o={};return c(r,(s=>{let c;const u=e[s],a=r[s],l=f(a,s,n);l&&(c=l.$check(u,t));let y=p(a,s,u,!1,n);c?o[s]=c:y.length&&(t&&(y=y.filter((e=>!i(t).includes(e.code)))),y.length&&(o[s]=y))})),!!c(o).length&&o},o.$hydrate=function(t){return e(t)?t.map((e=>new o(e))):new o(t)},Object.assign(o.prototype,n.methods),o.schema=r,o};export default l;
/*! SmartModel v0.6.0 */
function e(e){return Array.isArray(e)}function t(e){return void 0===e}function r(e){return"function"==typeof e}function n(e){return e&&e.toString().startsWith("class")}function s(e){return e&&(e.prototype instanceof l||e instanceof l)}function o(e){return e&&"[object Object]"===e.toString()}function c(e,t=function(){}){return Object.keys(e).map((r=>t(r,e[r])))}function i(e){return[].concat([],e)}function u(e,t){return t=Object.assign({},e,t),c(e,(r=>{o(e[r])&&o(t[r])&&(t[r]=Object.assign({},e[r],u(e[r],t[r])))})),t}class p extends Error{constructor(e){super(e.message),Object.assign(this,e)}}function a(t,r,u,p,a){const f=[];return a.strict&&!c(t||{}).length&&f.push({message:`Property "${r}" can't be set in strict mode`,code:"strict"}),t.required&&a.empty(u)?(f.push({message:`Property "${r}" is "required"`,code:"required"}),f):t.readonly&&!p?(f.push({message:`Property "${r}" is "readonly"`,code:"readonly"}),f):(void 0===u||(!t.type||!t.required&&a.empty(u)||s(t.type)&&o(u)||i(t.type).some((t=>function(t,r){const s=r&&r.toString().match(/^\s*function (\w+)/),o=(s?s[1]:"object").toLowerCase();if("date"===o&&t instanceof r)return!0;if("array"===o&&e(t))return!0;if("object"===o){if(n(r)&&t instanceof r)return!0;if(!n(r)&&typeof t===o)return!0}else if(typeof t===o)return!0;return!1}(u,t)))||f.push({message:`Property "${r}" has an invalid type "${typeof u}"`,code:"type"}),t.rule&&c(t.rule,((e,t)=>{t(u)&&f.push({message:`Property "${r}" triggers the "${e}" rule error`,code:"rule:"+e})}))),f)}function f(e={},t,r){if(e.type){const n=!!s(e.type)&&e.type,c=!!o(e.type)&&e.type;if(n||c){const s=n||l.create(t.normalize("NFD").replace(/[\u0300-\u036f]/g,"").match(/[a-z1-9]+/gi).map((e=>e.charAt(0).toUpperCase()+e.substr(1).toLowerCase())).join(""),c,r);return e.type=s,s}}return!1}p.throw=function(e,t,r,n,s){const c=t.split(":")[0];if(s=s&&s.constructor.name,!0===e.exceptions||o(e.exceptions)&&e.exceptions[c])throw new p({message:`[${s}] ${r}`,source:s,property:n,code:t})};class l extends class{constructor(n,o){return new Proxy(this,{set(i,u,l){const y=n[u]||{},$=i[u],h=t($),d=!(h||(g=l,m=$,JSON.stringify(g)===JSON.stringify(m)));var g,m;const b=f(y,u,o);function w(e,r){const s=Reflect.apply(e,i,r||[u,l,$,n]);return t(s)?l:s}var S;l=w(i.$onBeforeSet),d&&(l=w(i.$onBeforeUpdate)),r(y.transform)&&(l=w(y.transform,[l,n])),e(S=y.type)&&1===S.length&&s(S[0])&&!t(l)&&(l=y.type[0].$hydrate(l),y.type=Array);const j=a(y,u,l,h,o);if(j.length){if(!o.exceptions)return!0;p.throw(o,j[0].code,j[0].message,u,i)}return o.strict&&!c(y).length||(b&&!t(l)&&(l=new b(l)),i[u]=l,w(i.$onSet),d&&(w(i.$onUpdate),i.$applySubscribers(u,l))),!0},get(e,o){const i=n[o];let u=e[o];if(["$get"].includes(o))return function(){return function(e){return c(e=Object.assign({},e),(t=>{s(e[t])&&(e[t]=e[t].$get())})),e}(e)};if(!i)return e[o];function p(r,s){const c=Reflect.apply(r,e,s||[o,u,n]);return t(c)?u:c}return u=p(e.$onBeforeGet),r(i)&&(u=p(i,[e,n])),r(i.format)&&(u=p(i.format,[u,n])),u=p(e.$onGet),u},deleteProperty(e,t){const r=e[t];function s(s,o){return Reflect.apply(s,e,o||[t,r,n])}return(n[t]||{}).required&&p.throw(o,"required",`Property "${t}" is "required"`,t,e),!1===s(e.$onBeforeDelete)||(Reflect.deleteProperty(e,t),s(e.$onDelete),s(e.$onUpdate),e.$applySubscribers(t,r)),!0}})}}{constructor(e={},t={},r){super(e,r),this.$post(t)}$patch(e){c(e,(t=>{this[t]=e[t]}))}$post(e){const r=this.$schema();c(r,((r,n)=>{t(e[r])&&(this[r]=t(n.default)?void 0:n.default)})),c(this,((e,n)=>{t(r[e]&&t(n))&&this.$delete(e)})),this.$patch(e)}$put(e){return this.$post(e)}$delete(e){i(e).forEach((e=>{Reflect.deleteProperty(this,e)}))}$subscribe(e){return this.$subscribers().push(e),()=>{this.$subscribers(e)}}}l.settings={empty:e=>""===e||null===e||t(e),strict:!1,exceptions:{readonly:!1,required:!0,rule:!0,strict:!1,type:!0},methods:{$onBeforeGet:()=>{},$onBeforeSet:()=>{},$onBeforeUpdate:()=>{},$onDelete:()=>{},$onGet:()=>{},$onBeforeDelete:()=>{},$onSet:()=>{},$onUpdate:()=>{}}},l.create=function(t,r,n){let s=[];n=u(l.settings,n);const o={[t]:class extends l{constructor(e){super(r,e,n)}$schema(){return r}$subscribers(e){return e&&(s=s.filter((t=>t!==e))),s}$applySubscribers(e,t){c(s,((r,n)=>{Reflect.apply(n,this,[e,t,this])}))}}}[t];return o.$check=function(e={},t){const s={};return c(r,((r,o)=>{let c;const u=e[r],p=f(o,r,n);p&&(c=p.$check(u,t));let l=a(o,r,u,!1,n);c?s[r]=c:l.length&&(t&&(l=l.filter((e=>!i(t).includes(e.code)))),l.length&&(s[r]=l))})),!!c(s).length&&s},o.$hydrate=function(t){return e(t)?t.map((e=>new o(e))):new o(t)},Object.assign(o.prototype,n.methods),o};export default l;
/**!
* SmartModel
* Javascript object model
* https://github.com/jaysalvat/smart-model
* @version 0.5.0 built 2021-02-25 09:18:46
* @version 0.6.0 built 2021-02-26 08:03:42
* @license ISC

@@ -27,3 +26,3 @@ * @author Jay Salvat http://jaysalvat.com

function isSmartModel(value) {
return value.prototype instanceof SmartModel || value instanceof SmartModel;
return value && (value.prototype instanceof SmartModel || value instanceof SmartModel);
}

@@ -37,3 +36,3 @@ function isPlainObject(value) {

function keys(obj, cb = function() {}) {
return Object.keys(obj).map(cb);
return Object.keys(obj).map((key => cb(key, obj[key])));
}

@@ -139,4 +138,3 @@ function toArray(value) {

if (entry.rule) {
keys(entry.rule, (key => {
const rule = entry.rule[key];
keys(entry.rule, ((key, rule) => {
if (rule(value)) {

@@ -184,3 +182,3 @@ errors.push({

}
if (isTypeArrayOfSmartModels(entry.type)) {
if (isTypeArrayOfSmartModels(entry.type) && !isUndef(value)) {
value = entry.type[0].$hydrate(value);

@@ -200,3 +198,3 @@ entry.type = Array;

}
if (Nested) {
if (Nested && !isUndef(value)) {
value = new Nested(value);

@@ -208,2 +206,3 @@ }

trigger(target.$onUpdate);
target.$applySubscribers(property, value);
}

@@ -246,6 +245,9 @@ return true;

}
trigger(target.$onBeforeDelete);
if (trigger(target.$onBeforeDelete) === false) {
return true;
}
Reflect.deleteProperty(target, property);
trigger(target.$onDelete);
trigger(target.$onUpdate);
target.$applySubscribers(property, value);
return true;

@@ -259,12 +261,3 @@ }

super(schema, settings);
keys(schema, (key => {
if (isUndef(data[key])) {
if (!isUndef(schema[key].default)) {
this[key] = schema[key].default;
} else if (!isFn(schema[key])) {
this[key] = data[key];
}
}
}));
this.$patch(data);
this.$post(data);
}

@@ -276,22 +269,23 @@ $patch(data) {

}
$put(data) {
keys(this, (key => {
if (data[key]) {
if (isSmartModel(this[key])) {
this[key].$put(data[key]);
$post(data) {
let undef;
const schema = this.$schema();
keys(schema, ((key, value) => {
if (isUndef(data[key])) {
if (!isUndef(value.default)) {
this[key] = value.default;
} else {
this[key] = data[key];
this[key] = undef;
}
} else {
this.$delete(key);
}
}));
keys(data, (key => {
if (!this[key]) {
this[key] = data[key];
keys(this, ((key, value) => {
if (isUndef(schema[key] && isUndef(value))) {
this.$delete(key);
}
}));
this.$patch(data);
}
$post(data) {
return this.$put(data);
$put(data) {
return this.$post(data);
}

@@ -303,2 +297,8 @@ $delete(properties) {

}
$subscribe(fn) {
this.$subscribers().push(fn);
return () => {
this.$subscribers(fn);
};
}
}

@@ -327,2 +327,3 @@ SmartModel.settings = {

SmartModel.create = function(name, schema, settings) {
let subscribers = [];
settings = merge(SmartModel.settings, settings);

@@ -334,10 +335,23 @@ const Model = {

}
$schema() {
return schema;
}
$subscribers(removedFn) {
if (removedFn) {
subscribers = subscribers.filter((fn => fn !== removedFn));
}
return subscribers;
}
$applySubscribers(property, value) {
keys(subscribers, ((_, subscriber) => {
Reflect.apply(subscriber, this, [ property, value, this ]);
}));
}
}
}[name];
Model.$check = function(payload, filters) {
Model.$check = function(payload = {}, filters) {
const invalidations = {};
keys(schema, (property => {
keys(schema, ((property, entry) => {
let subErrors;
const value = payload[property];
const entry = schema[property];
const Nested = createNested(entry, property, settings);

@@ -369,3 +383,2 @@ if (Nested) {

Object.assign(Model.prototype, settings.methods);
Model.schema = schema;
return Model;

@@ -372,0 +385,0 @@ };

@@ -1,2 +0,2 @@

/*! SmartModel v0.5.0 */
var SmartModel=function(){"use strict";function e(e){return Array.isArray(e)}function t(e){return void 0===e}function r(e){return"function"==typeof e}function n(e){return e&&e.toString().startsWith("class")}function o(e){return e.prototype instanceof l||e instanceof l}function s(e){return e&&"[object Object]"===e.toString()}function c(e,t=function(){}){return Object.keys(e).map(t)}function i(e){return[].concat([],e)}function u(e,t){return t=Object.assign({},e,t),c(e,(r=>{s(e[r])&&s(t[r])&&(t[r]=Object.assign({},e[r],u(e[r],t[r])))})),t}class a extends Error{constructor(e){super(e.message),Object.assign(this,e)}}function p(t,r,u,a,p){const f=[];return p.strict&&!c(t||{}).length&&f.push({message:`Property "${r}" can't be set in strict mode`,code:"strict"}),t.required&&p.empty(u)?(f.push({message:`Property "${r}" is "required"`,code:"required"}),f):t.readonly&&!a?(f.push({message:`Property "${r}" is "readonly"`,code:"readonly"}),f):(void 0===u||(!t.type||!t.required&&p.empty(u)||o(t.type)&&s(u)||i(t.type).some((t=>function(t,r){const o=r&&r.toString().match(/^\s*function (\w+)/),s=(o?o[1]:"object").toLowerCase();if("date"===s&&t instanceof r)return!0;if("array"===s&&e(t))return!0;if("object"===s){if(n(r)&&t instanceof r)return!0;if(!n(r)&&typeof t===s)return!0}else if(typeof t===s)return!0;return!1}(u,t)))||f.push({message:`Property "${r}" has an invalid type "${typeof u}"`,code:"type"}),t.rule&&c(t.rule,(e=>{(0,t.rule[e])(u)&&f.push({message:`Property "${r}" triggers the "${e}" rule error`,code:"rule:"+e})}))),f)}function f(e={},t,r){if(e.type){const n=!!o(e.type)&&e.type,c=!!s(e.type)&&e.type;if(n||c){const o=n||l.create(t.normalize("NFD").replace(/[\u0300-\u036f]/g,"").match(/[a-z1-9]+/gi).map((e=>e.charAt(0).toUpperCase()+e.substr(1).toLowerCase())).join(""),c,r);return e.type=o,o}}return!1}a.throw=function(e,t,r,n,o){const c=t.split(":")[0];if(o=o&&o.constructor.name,!0===e.exceptions||s(e.exceptions)&&e.exceptions[c])throw new a({message:`[${o}] ${r}`,source:o,property:n,code:t})};class l extends class{constructor(n,s){return new Proxy(this,{set(i,u,l){const y=n[u]||{},d=i[u],h=t(d),$=!(h||(g=l,m=d,JSON.stringify(g)===JSON.stringify(m)));var g,m;const b=f(y,u,s);function w(e,r){const o=Reflect.apply(e,i,r||[u,l,d,n]);return t(o)?l:o}var j;l=w(i.$onBeforeSet),$&&(l=w(i.$onBeforeUpdate)),r(y.transform)&&(l=w(y.transform,[l,n])),e(j=y.type)&&1===j.length&&o(j[0])&&(l=y.type[0].$hydrate(l),y.type=Array);const P=p(y,u,l,h,s);if(P.length){if(!s.exceptions)return!0;a.throw(s,P[0].code,P[0].message,u,i)}return s.strict&&!c(y).length||(b&&(l=new b(l)),i[u]=l,w(i.$onSet),$&&w(i.$onUpdate)),!0},get(e,s){const i=n[s];let u=e[s];if(["$get"].includes(s))return function(){return function(e){return c(e=Object.assign({},e),(t=>{o(e[t])&&(e[t]=e[t].$get())})),e}(e)};if(!i)return e[s];function a(r,o){const c=Reflect.apply(r,e,o||[s,u,n]);return t(c)?u:c}return u=a(e.$onBeforeGet),r(i)&&(u=a(i,[e,n])),r(i.format)&&(u=a(i.format,[u,n])),u=a(e.$onGet),u},deleteProperty(e,t){const r=e[t];function o(o,s){return Reflect.apply(o,e,s||[t,r,n])}return(n[t]||{}).required&&a.throw(s,"required",`Property "${t}" is "required"`,t,e),o(e.$onBeforeDelete),Reflect.deleteProperty(e,t),o(e.$onDelete),o(e.$onUpdate),!0}})}}{constructor(e={},n={},o){super(e,o),c(e,(o=>{t(n[o])&&(t(e[o].default)?r(e[o])||(this[o]=n[o]):this[o]=e[o].default)})),this.$patch(n)}$patch(e){c(e,(t=>{this[t]=e[t]}))}$put(e){c(this,(t=>{e[t]?o(this[t])?this[t].$put(e[t]):this[t]=e[t]:this.$delete(t)})),c(e,(t=>{this[t]||(this[t]=e[t])}))}$post(e){return this.$put(e)}$delete(e){i(e).forEach((e=>{Reflect.deleteProperty(this,e)}))}}return l.settings={empty:e=>""===e||null===e||t(e),strict:!1,exceptions:{readonly:!1,required:!0,rule:!0,strict:!1,type:!0},methods:{$onBeforeGet:()=>{},$onBeforeSet:()=>{},$onBeforeUpdate:()=>{},$onDelete:()=>{},$onGet:()=>{},$onBeforeDelete:()=>{},$onSet:()=>{},$onUpdate:()=>{}}},l.create=function(t,r,n){n=u(l.settings,n);const o={[t]:class extends l{constructor(e){super(r,e,n)}}}[t];return o.$check=function(e,t){const o={};return c(r,(s=>{let c;const u=e[s],a=r[s],l=f(a,s,n);l&&(c=l.$check(u,t));let y=p(a,s,u,!1,n);c?o[s]=c:y.length&&(t&&(y=y.filter((e=>!i(t).includes(e.code)))),y.length&&(o[s]=y))})),!!c(o).length&&o},o.$hydrate=function(t){return e(t)?t.map((e=>new o(e))):new o(t)},Object.assign(o.prototype,n.methods),o.schema=r,o},l}();
/*! SmartModel v0.6.0 */
var SmartModel=function(){"use strict";function e(e){return Array.isArray(e)}function t(e){return void 0===e}function r(e){return"function"==typeof e}function n(e){return e&&e.toString().startsWith("class")}function s(e){return e&&(e.prototype instanceof l||e instanceof l)}function o(e){return e&&"[object Object]"===e.toString()}function c(e,t=function(){}){return Object.keys(e).map((r=>t(r,e[r])))}function i(e){return[].concat([],e)}function u(e,t){return t=Object.assign({},e,t),c(e,(r=>{o(e[r])&&o(t[r])&&(t[r]=Object.assign({},e[r],u(e[r],t[r])))})),t}class p extends Error{constructor(e){super(e.message),Object.assign(this,e)}}function a(t,r,u,p,a){const f=[];return a.strict&&!c(t||{}).length&&f.push({message:`Property "${r}" can't be set in strict mode`,code:"strict"}),t.required&&a.empty(u)?(f.push({message:`Property "${r}" is "required"`,code:"required"}),f):t.readonly&&!p?(f.push({message:`Property "${r}" is "readonly"`,code:"readonly"}),f):(void 0===u||(!t.type||!t.required&&a.empty(u)||s(t.type)&&o(u)||i(t.type).some((t=>function(t,r){const s=r&&r.toString().match(/^\s*function (\w+)/),o=(s?s[1]:"object").toLowerCase();if("date"===o&&t instanceof r)return!0;if("array"===o&&e(t))return!0;if("object"===o){if(n(r)&&t instanceof r)return!0;if(!n(r)&&typeof t===o)return!0}else if(typeof t===o)return!0;return!1}(u,t)))||f.push({message:`Property "${r}" has an invalid type "${typeof u}"`,code:"type"}),t.rule&&c(t.rule,((e,t)=>{t(u)&&f.push({message:`Property "${r}" triggers the "${e}" rule error`,code:"rule:"+e})}))),f)}function f(e={},t,r){if(e.type){const n=!!s(e.type)&&e.type,c=!!o(e.type)&&e.type;if(n||c){const s=n||l.create(t.normalize("NFD").replace(/[\u0300-\u036f]/g,"").match(/[a-z1-9]+/gi).map((e=>e.charAt(0).toUpperCase()+e.substr(1).toLowerCase())).join(""),c,r);return e.type=s,s}}return!1}p.throw=function(e,t,r,n,s){const c=t.split(":")[0];if(s=s&&s.constructor.name,!0===e.exceptions||o(e.exceptions)&&e.exceptions[c])throw new p({message:`[${s}] ${r}`,source:s,property:n,code:t})};class l extends class{constructor(n,o){return new Proxy(this,{set(i,u,l){const y=n[u]||{},$=i[u],h=t($),d=!(h||(g=l,m=$,JSON.stringify(g)===JSON.stringify(m)));var g,m;const b=f(y,u,o);function S(e,r){const s=Reflect.apply(e,i,r||[u,l,$,n]);return t(s)?l:s}var w;l=S(i.$onBeforeSet),d&&(l=S(i.$onBeforeUpdate)),r(y.transform)&&(l=S(y.transform,[l,n])),e(w=y.type)&&1===w.length&&s(w[0])&&!t(l)&&(l=y.type[0].$hydrate(l),y.type=Array);const j=a(y,u,l,h,o);if(j.length){if(!o.exceptions)return!0;p.throw(o,j[0].code,j[0].message,u,i)}return o.strict&&!c(y).length||(b&&!t(l)&&(l=new b(l)),i[u]=l,S(i.$onSet),d&&(S(i.$onUpdate),i.$applySubscribers(u,l))),!0},get(e,o){const i=n[o];let u=e[o];if(["$get"].includes(o))return function(){return function(e){return c(e=Object.assign({},e),(t=>{s(e[t])&&(e[t]=e[t].$get())})),e}(e)};if(!i)return e[o];function p(r,s){const c=Reflect.apply(r,e,s||[o,u,n]);return t(c)?u:c}return u=p(e.$onBeforeGet),r(i)&&(u=p(i,[e,n])),r(i.format)&&(u=p(i.format,[u,n])),u=p(e.$onGet),u},deleteProperty(e,t){const r=e[t];function s(s,o){return Reflect.apply(s,e,o||[t,r,n])}return(n[t]||{}).required&&p.throw(o,"required",`Property "${t}" is "required"`,t,e),!1===s(e.$onBeforeDelete)||(Reflect.deleteProperty(e,t),s(e.$onDelete),s(e.$onUpdate),e.$applySubscribers(t,r)),!0}})}}{constructor(e={},t={},r){super(e,r),this.$post(t)}$patch(e){c(e,(t=>{this[t]=e[t]}))}$post(e){const r=this.$schema();c(r,((r,n)=>{t(e[r])&&(this[r]=t(n.default)?void 0:n.default)})),c(this,((e,n)=>{t(r[e]&&t(n))&&this.$delete(e)})),this.$patch(e)}$put(e){return this.$post(e)}$delete(e){i(e).forEach((e=>{Reflect.deleteProperty(this,e)}))}$subscribe(e){return this.$subscribers().push(e),()=>{this.$subscribers(e)}}}return l.settings={empty:e=>""===e||null===e||t(e),strict:!1,exceptions:{readonly:!1,required:!0,rule:!0,strict:!1,type:!0},methods:{$onBeforeGet:()=>{},$onBeforeSet:()=>{},$onBeforeUpdate:()=>{},$onDelete:()=>{},$onGet:()=>{},$onBeforeDelete:()=>{},$onSet:()=>{},$onUpdate:()=>{}}},l.create=function(t,r,n){let s=[];n=u(l.settings,n);const o={[t]:class extends l{constructor(e){super(r,e,n)}$schema(){return r}$subscribers(e){return e&&(s=s.filter((t=>t!==e))),s}$applySubscribers(e,t){c(s,((r,n)=>{Reflect.apply(n,this,[e,t,this])}))}}}[t];return o.$check=function(e={},t){const s={};return c(r,((r,o)=>{let c;const u=e[r],p=f(o,r,n);p&&(c=p.$check(u,t));let l=a(o,r,u,!1,n);c?s[r]=c:l.length&&(t&&(l=l.filter((e=>!i(t).includes(e.code)))),l.length&&(s[r]=l))})),!!c(s).length&&s},o.$hydrate=function(t){return e(t)?t.map((e=>new o(e))):new o(t)},Object.assign(o.prototype,n.methods),o},l}();
/**!
* SmartModel
* Javascript object model
* https://github.com/jaysalvat/smart-model
* @version 0.5.0 built 2021-02-25 09:18:46
* @version 0.6.0 built 2021-02-26 08:03:42
* @license ISC

@@ -30,3 +29,3 @@ * @author Jay Salvat http://jaysalvat.com

function isSmartModel(value) {
return value.prototype instanceof SmartModel || value instanceof SmartModel;
return value && (value.prototype instanceof SmartModel || value instanceof SmartModel);
}

@@ -40,3 +39,3 @@ function isPlainObject(value) {

function keys(obj, cb = function() {}) {
return Object.keys(obj).map(cb);
return Object.keys(obj).map((key => cb(key, obj[key])));
}

@@ -142,4 +141,3 @@ function toArray(value) {

if (entry.rule) {
keys(entry.rule, (key => {
const rule = entry.rule[key];
keys(entry.rule, ((key, rule) => {
if (rule(value)) {

@@ -187,3 +185,3 @@ errors.push({

}
if (isTypeArrayOfSmartModels(entry.type)) {
if (isTypeArrayOfSmartModels(entry.type) && !isUndef(value)) {
value = entry.type[0].$hydrate(value);

@@ -203,3 +201,3 @@ entry.type = Array;

}
if (Nested) {
if (Nested && !isUndef(value)) {
value = new Nested(value);

@@ -211,2 +209,3 @@ }

trigger(target.$onUpdate);
target.$applySubscribers(property, value);
}

@@ -249,6 +248,9 @@ return true;

}
trigger(target.$onBeforeDelete);
if (trigger(target.$onBeforeDelete) === false) {
return true;
}
Reflect.deleteProperty(target, property);
trigger(target.$onDelete);
trigger(target.$onUpdate);
target.$applySubscribers(property, value);
return true;

@@ -262,12 +264,3 @@ }

super(schema, settings);
keys(schema, (key => {
if (isUndef(data[key])) {
if (!isUndef(schema[key].default)) {
this[key] = schema[key].default;
} else if (!isFn(schema[key])) {
this[key] = data[key];
}
}
}));
this.$patch(data);
this.$post(data);
}

@@ -279,22 +272,23 @@ $patch(data) {

}
$put(data) {
keys(this, (key => {
if (data[key]) {
if (isSmartModel(this[key])) {
this[key].$put(data[key]);
$post(data) {
let undef;
const schema = this.$schema();
keys(schema, ((key, value) => {
if (isUndef(data[key])) {
if (!isUndef(value.default)) {
this[key] = value.default;
} else {
this[key] = data[key];
this[key] = undef;
}
} else {
this.$delete(key);
}
}));
keys(data, (key => {
if (!this[key]) {
this[key] = data[key];
keys(this, ((key, value) => {
if (isUndef(schema[key] && isUndef(value))) {
this.$delete(key);
}
}));
this.$patch(data);
}
$post(data) {
return this.$put(data);
$put(data) {
return this.$post(data);
}

@@ -306,2 +300,8 @@ $delete(properties) {

}
$subscribe(fn) {
this.$subscribers().push(fn);
return () => {
this.$subscribers(fn);
};
}
}

@@ -330,2 +330,3 @@ SmartModel.settings = {

SmartModel.create = function(name, schema, settings) {
let subscribers = [];
settings = merge(SmartModel.settings, settings);

@@ -337,10 +338,23 @@ const Model = {

}
$schema() {
return schema;
}
$subscribers(removedFn) {
if (removedFn) {
subscribers = subscribers.filter((fn => fn !== removedFn));
}
return subscribers;
}
$applySubscribers(property, value) {
keys(subscribers, ((_, subscriber) => {
Reflect.apply(subscriber, this, [ property, value, this ]);
}));
}
}
}[name];
Model.$check = function(payload, filters) {
Model.$check = function(payload = {}, filters) {
const invalidations = {};
keys(schema, (property => {
keys(schema, ((property, entry) => {
let subErrors;
const value = payload[property];
const entry = schema[property];
const Nested = createNested(entry, property, settings);

@@ -372,3 +386,2 @@ if (Nested) {

Object.assign(Model.prototype, settings.methods);
Model.schema = schema;
return Model;

@@ -375,0 +388,0 @@ };

@@ -1,2 +0,2 @@

/*! SmartModel v0.5.0 */
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).SmartModel=t()}(this,(function(){"use strict";function e(e){return Array.isArray(e)}function t(e){return void 0===e}function r(e){return"function"==typeof e}function n(e){return e&&e.toString().startsWith("class")}function o(e){return e.prototype instanceof l||e instanceof l}function s(e){return e&&"[object Object]"===e.toString()}function i(e,t=function(){}){return Object.keys(e).map(t)}function c(e){return[].concat([],e)}function u(e,t){return t=Object.assign({},e,t),i(e,(r=>{s(e[r])&&s(t[r])&&(t[r]=Object.assign({},e[r],u(e[r],t[r])))})),t}class f extends Error{constructor(e){super(e.message),Object.assign(this,e)}}function p(t,r,u,f,p){const a=[];return p.strict&&!i(t||{}).length&&a.push({message:`Property "${r}" can't be set in strict mode`,code:"strict"}),t.required&&p.empty(u)?(a.push({message:`Property "${r}" is "required"`,code:"required"}),a):t.readonly&&!f?(a.push({message:`Property "${r}" is "readonly"`,code:"readonly"}),a):(void 0===u||(!t.type||!t.required&&p.empty(u)||o(t.type)&&s(u)||c(t.type).some((t=>function(t,r){const o=r&&r.toString().match(/^\s*function (\w+)/),s=(o?o[1]:"object").toLowerCase();if("date"===s&&t instanceof r)return!0;if("array"===s&&e(t))return!0;if("object"===s){if(n(r)&&t instanceof r)return!0;if(!n(r)&&typeof t===s)return!0}else if(typeof t===s)return!0;return!1}(u,t)))||a.push({message:`Property "${r}" has an invalid type "${typeof u}"`,code:"type"}),t.rule&&i(t.rule,(e=>{(0,t.rule[e])(u)&&a.push({message:`Property "${r}" triggers the "${e}" rule error`,code:"rule:"+e})}))),a)}function a(e={},t,r){if(e.type){const n=!!o(e.type)&&e.type,i=!!s(e.type)&&e.type;if(n||i){const o=n||l.create(t.normalize("NFD").replace(/[\u0300-\u036f]/g,"").match(/[a-z1-9]+/gi).map((e=>e.charAt(0).toUpperCase()+e.substr(1).toLowerCase())).join(""),i,r);return e.type=o,o}}return!1}f.throw=function(e,t,r,n,o){const i=t.split(":")[0];if(o=o&&o.constructor.name,!0===e.exceptions||s(e.exceptions)&&e.exceptions[i])throw new f({message:`[${o}] ${r}`,source:o,property:n,code:t})};class l extends class{constructor(n,s){return new Proxy(this,{set(c,u,l){const d=n[u]||{},y=c[u],h=t(y),$=!(h||(g=l,m=y,JSON.stringify(g)===JSON.stringify(m)));var g,m;const b=a(d,u,s);function j(e,r){const o=Reflect.apply(e,c,r||[u,l,y,n]);return t(o)?l:o}var w;l=j(c.$onBeforeSet),$&&(l=j(c.$onBeforeUpdate)),r(d.transform)&&(l=j(d.transform,[l,n])),e(w=d.type)&&1===w.length&&o(w[0])&&(l=d.type[0].$hydrate(l),d.type=Array);const x=p(d,u,l,h,s);if(x.length){if(!s.exceptions)return!0;f.throw(s,x[0].code,x[0].message,u,c)}return s.strict&&!i(d).length||(b&&(l=new b(l)),c[u]=l,j(c.$onSet),$&&j(c.$onUpdate)),!0},get(e,s){const c=n[s];let u=e[s];if(["$get"].includes(s))return function(){return function(e){return i(e=Object.assign({},e),(t=>{o(e[t])&&(e[t]=e[t].$get())})),e}(e)};if(!c)return e[s];function f(r,o){const i=Reflect.apply(r,e,o||[s,u,n]);return t(i)?u:i}return u=f(e.$onBeforeGet),r(c)&&(u=f(c,[e,n])),r(c.format)&&(u=f(c.format,[u,n])),u=f(e.$onGet),u},deleteProperty(e,t){const r=e[t];function o(o,s){return Reflect.apply(o,e,s||[t,r,n])}return(n[t]||{}).required&&f.throw(s,"required",`Property "${t}" is "required"`,t,e),o(e.$onBeforeDelete),Reflect.deleteProperty(e,t),o(e.$onDelete),o(e.$onUpdate),!0}})}}{constructor(e={},n={},o){super(e,o),i(e,(o=>{t(n[o])&&(t(e[o].default)?r(e[o])||(this[o]=n[o]):this[o]=e[o].default)})),this.$patch(n)}$patch(e){i(e,(t=>{this[t]=e[t]}))}$put(e){i(this,(t=>{e[t]?o(this[t])?this[t].$put(e[t]):this[t]=e[t]:this.$delete(t)})),i(e,(t=>{this[t]||(this[t]=e[t])}))}$post(e){return this.$put(e)}$delete(e){c(e).forEach((e=>{Reflect.deleteProperty(this,e)}))}}return l.settings={empty:e=>""===e||null===e||t(e),strict:!1,exceptions:{readonly:!1,required:!0,rule:!0,strict:!1,type:!0},methods:{$onBeforeGet:()=>{},$onBeforeSet:()=>{},$onBeforeUpdate:()=>{},$onDelete:()=>{},$onGet:()=>{},$onBeforeDelete:()=>{},$onSet:()=>{},$onUpdate:()=>{}}},l.create=function(t,r,n){n=u(l.settings,n);const o={[t]:class extends l{constructor(e){super(r,e,n)}}}[t];return o.$check=function(e,t){const o={};return i(r,(s=>{let i;const u=e[s],f=r[s],l=a(f,s,n);l&&(i=l.$check(u,t));let d=p(f,s,u,!1,n);i?o[s]=i:d.length&&(t&&(d=d.filter((e=>!c(t).includes(e.code)))),d.length&&(o[s]=d))})),!!i(o).length&&o},o.$hydrate=function(t){return e(t)?t.map((e=>new o(e))):new o(t)},Object.assign(o.prototype,n.methods),o.schema=r,o},l}));
/*! SmartModel v0.6.0 */
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).SmartModel=t()}(this,(function(){"use strict";function e(e){return Array.isArray(e)}function t(e){return void 0===e}function r(e){return"function"==typeof e}function n(e){return e&&e.toString().startsWith("class")}function o(e){return e&&(e.prototype instanceof l||e instanceof l)}function s(e){return e&&"[object Object]"===e.toString()}function i(e,t=function(){}){return Object.keys(e).map((r=>t(r,e[r])))}function c(e){return[].concat([],e)}function u(e,t){return t=Object.assign({},e,t),i(e,(r=>{s(e[r])&&s(t[r])&&(t[r]=Object.assign({},e[r],u(e[r],t[r])))})),t}class p extends Error{constructor(e){super(e.message),Object.assign(this,e)}}function a(t,r,u,p,a){const f=[];return a.strict&&!i(t||{}).length&&f.push({message:`Property "${r}" can't be set in strict mode`,code:"strict"}),t.required&&a.empty(u)?(f.push({message:`Property "${r}" is "required"`,code:"required"}),f):t.readonly&&!p?(f.push({message:`Property "${r}" is "readonly"`,code:"readonly"}),f):(void 0===u||(!t.type||!t.required&&a.empty(u)||o(t.type)&&s(u)||c(t.type).some((t=>function(t,r){const o=r&&r.toString().match(/^\s*function (\w+)/),s=(o?o[1]:"object").toLowerCase();if("date"===s&&t instanceof r)return!0;if("array"===s&&e(t))return!0;if("object"===s){if(n(r)&&t instanceof r)return!0;if(!n(r)&&typeof t===s)return!0}else if(typeof t===s)return!0;return!1}(u,t)))||f.push({message:`Property "${r}" has an invalid type "${typeof u}"`,code:"type"}),t.rule&&i(t.rule,((e,t)=>{t(u)&&f.push({message:`Property "${r}" triggers the "${e}" rule error`,code:"rule:"+e})}))),f)}function f(e={},t,r){if(e.type){const n=!!o(e.type)&&e.type,i=!!s(e.type)&&e.type;if(n||i){const o=n||l.create(t.normalize("NFD").replace(/[\u0300-\u036f]/g,"").match(/[a-z1-9]+/gi).map((e=>e.charAt(0).toUpperCase()+e.substr(1).toLowerCase())).join(""),i,r);return e.type=o,o}}return!1}p.throw=function(e,t,r,n,o){const i=t.split(":")[0];if(o=o&&o.constructor.name,!0===e.exceptions||s(e.exceptions)&&e.exceptions[i])throw new p({message:`[${o}] ${r}`,source:o,property:n,code:t})};class l extends class{constructor(n,s){return new Proxy(this,{set(c,u,l){const y=n[u]||{},d=c[u],h=t(d),$=!(h||(g=l,m=d,JSON.stringify(g)===JSON.stringify(m)));var g,m;const b=f(y,u,s);function S(e,r){const o=Reflect.apply(e,c,r||[u,l,d,n]);return t(o)?l:o}var j;l=S(c.$onBeforeSet),$&&(l=S(c.$onBeforeUpdate)),r(y.transform)&&(l=S(y.transform,[l,n])),e(j=y.type)&&1===j.length&&o(j[0])&&!t(l)&&(l=y.type[0].$hydrate(l),y.type=Array);const w=a(y,u,l,h,s);if(w.length){if(!s.exceptions)return!0;p.throw(s,w[0].code,w[0].message,u,c)}return s.strict&&!i(y).length||(b&&!t(l)&&(l=new b(l)),c[u]=l,S(c.$onSet),$&&(S(c.$onUpdate),c.$applySubscribers(u,l))),!0},get(e,s){const c=n[s];let u=e[s];if(["$get"].includes(s))return function(){return function(e){return i(e=Object.assign({},e),(t=>{o(e[t])&&(e[t]=e[t].$get())})),e}(e)};if(!c)return e[s];function p(r,o){const i=Reflect.apply(r,e,o||[s,u,n]);return t(i)?u:i}return u=p(e.$onBeforeGet),r(c)&&(u=p(c,[e,n])),r(c.format)&&(u=p(c.format,[u,n])),u=p(e.$onGet),u},deleteProperty(e,t){const r=e[t];function o(o,s){return Reflect.apply(o,e,s||[t,r,n])}return(n[t]||{}).required&&p.throw(s,"required",`Property "${t}" is "required"`,t,e),!1===o(e.$onBeforeDelete)||(Reflect.deleteProperty(e,t),o(e.$onDelete),o(e.$onUpdate),e.$applySubscribers(t,r)),!0}})}}{constructor(e={},t={},r){super(e,r),this.$post(t)}$patch(e){i(e,(t=>{this[t]=e[t]}))}$post(e){const r=this.$schema();i(r,((r,n)=>{t(e[r])&&(this[r]=t(n.default)?void 0:n.default)})),i(this,((e,n)=>{t(r[e]&&t(n))&&this.$delete(e)})),this.$patch(e)}$put(e){return this.$post(e)}$delete(e){c(e).forEach((e=>{Reflect.deleteProperty(this,e)}))}$subscribe(e){return this.$subscribers().push(e),()=>{this.$subscribers(e)}}}return l.settings={empty:e=>""===e||null===e||t(e),strict:!1,exceptions:{readonly:!1,required:!0,rule:!0,strict:!1,type:!0},methods:{$onBeforeGet:()=>{},$onBeforeSet:()=>{},$onBeforeUpdate:()=>{},$onDelete:()=>{},$onGet:()=>{},$onBeforeDelete:()=>{},$onSet:()=>{},$onUpdate:()=>{}}},l.create=function(t,r,n){let o=[];n=u(l.settings,n);const s={[t]:class extends l{constructor(e){super(r,e,n)}$schema(){return r}$subscribers(e){return e&&(o=o.filter((t=>t!==e))),o}$applySubscribers(e,t){i(o,((r,n)=>{Reflect.apply(n,this,[e,t,this])}))}}}[t];return s.$check=function(e={},t){const o={};return i(r,((r,s)=>{let i;const u=e[r],p=f(s,r,n);p&&(i=p.$check(u,t));let l=a(s,r,u,!1,n);i?o[r]=i:l.length&&(t&&(l=l.filter((e=>!c(t).includes(e.code)))),l.length&&(o[r]=l))})),!!i(o).length&&o},s.$hydrate=function(t){return e(t)?t.map((e=>new s(e))):new s(t)},Object.assign(s.prototype,n.methods),s},l}));
{
"name": "@jaysalvat/smart-model",
"version": "0.5.0",
"description": "Javascript object model",
"version": "0.6.0",
"description": "SmartModel is a fun experiment over Javascript Proxy. It tends to bring useful tools and best practices to data objects.",
"main": "./build/smart-model.cjs.min.cjs",

@@ -6,0 +6,0 @@ "module": "./build/smart-model.esm.min.js",

@@ -14,17 +14,19 @@ ```

Javascript object model.
SmartModel is a fun experiment over Javascript Proxy. It tends to bring useful tools and best practices to data objects.
- [x] ~1.5Kb gzipped
- [x] Small footprint, <2Kb gzipped
- [x] Value transformation
- [x] Value format
- [x] Value formatting
- [x] Value type validation
- [x] Value content validation (required, custom rules)
- [x] Value content validation
- [x] Default value
- [x] Readonly properties
- [x] Computed property
- [x] Throw exception (or not) if invalid
- [x] Computed properties
- [x] Exceptions (or not) if invalid
- [x] Nested models
- [x] Live cycle events
- [ ] Better documentation ^^
- [x] Live cycle callbacks
- [x] Subscriptions
**Important note** SmartModel uses javascript proxy. It unfortunately makes it incompatible with VueJs reactive properties.
Works on modern browsers.

@@ -204,3 +206,3 @@ [Check if tests pass](https://unpkg.com/@jaysalvat/smart-model@latest/test/index.html) on your browser.

```javascript
const cloned = Object.assign({}, model)
const clonedObject = Object.assign({}, model)
```

@@ -212,9 +214,19 @@

```javascript
const cloned = model.$get()
const clonedObject = model.$get()
```
it could also cause unexpected effects when model is used in other Proxies (like Vue).
The formatting could be applied multiple times.
Consider using a computed property instead.
Or consider using a computed property.
```javascript
const Event = SmartModel.create('Event', {
name: {
type: String
},
date: {
type Date,
},
formattedDate: (value) => new Date(value).toLocaleString()
})
```
#### readonly

@@ -409,3 +421,3 @@

### Native methods
### Methods

@@ -451,2 +463,24 @@ #### $get

#### $subscribe()
Adds an update listener. It will be called any time a value is updated.
```javascript
article.$subscribe((property, value) => {
console.log(property, 'has been updated with', value)
})
```
To unsubscribe the change listener, invoke the function returned by subscribe.
```javascript
const unsubscribe = article.$subscribe((property, value) => {
console.log(property, 'has been updated with', value)
})
unsubscribe()
```
## Static methods
#### $check

@@ -453,0 +487,0 @@

@@ -26,3 +26,2 @@ /* eslint-disable camelcase */

* ${NAME}
* ${pkg.description}
* https://github.com/jaysalvat/${FILENAME}

@@ -29,0 +28,0 @@ * @version ${pkg.version} built ${DATE}

@@ -47,5 +47,3 @@ import { keys, isSmartModel, toArray, checkType, isPlainObject } from './utils.js'

if (entry.rule) {
keys(entry.rule, (key) => {
const rule = entry.rule[key]
keys(entry.rule, (key, rule) => {
if (rule(value)) {

@@ -52,0 +50,0 @@ errors.push({

@@ -5,3 +5,3 @@

import checkErrors from './checkErrors.js'
import { toArray, keys, merge, isSmartModel, isFn, isArray, isUndef } from './utils.js'
import { toArray, keys, merge, isArray, isUndef } from './utils.js'

@@ -12,13 +12,3 @@ class SmartModel extends SmartModelProxy {

keys(schema, (key) => {
if (isUndef(data[key])) {
if (!isUndef(schema[key].default)) {
this[key] = schema[key].default
} else if (!isFn(schema[key])) {
this[key] = data[key]
}
}
})
this.$patch(data)
this.$post(data)
}

@@ -34,24 +24,27 @@

$put(data) {
keys(this, (key) => {
if (data[key]) {
if (isSmartModel(this[key])) {
this[key].$put(data[key])
$post(data) {
let undef
const schema = this.$schema()
keys(schema, (key, value) => {
if (isUndef(data[key])) {
if (!isUndef(value.default)) {
this[key] = value.default
} else {
this[key] = data[key]
this[key] = undef
}
} else {
this.$delete(key)
}
})
keys(data, (key) => {
if (!this[key]) {
this[key] = data[key]
keys(this, (key, value) => {
if (isUndef(schema[key] && isUndef(value))) {
this.$delete(key)
}
})
this.$patch(data)
}
$post(data) {
return this.$put(data)
$put(data) {
return this.$post(data)
}

@@ -64,2 +57,10 @@

}
$subscribe(fn) {
this.$subscribers().push(fn)
return () => {
this.$subscribers(fn)
}
}
}

@@ -90,2 +91,4 @@

SmartModel.create = function (name, schema, settings) {
let subscribers = []
settings = merge(SmartModel.settings, settings)

@@ -97,11 +100,29 @@

}
} }[name]
Model.$check = function (payload, filters) {
$schema() {
return schema
}
$subscribers(removedFn) {
if (removedFn) {
subscribers = subscribers.filter((fn) => fn !== removedFn)
}
return subscribers
}
$applySubscribers(property, value) {
keys(subscribers, (_, subscriber) => {
Reflect.apply(subscriber, this, [ property, value, this ])
})
}
}
}[name]
Model.$check = function (payload = {}, filters) {
const invalidations = {}
keys(schema, (property) => {
keys(schema, (property, entry) => {
let subErrors
const value = payload[property]
const entry = schema[property]
const Nested = createNested(entry, property, settings)

@@ -141,4 +162,2 @@

Model.schema = schema
return Model

@@ -145,0 +164,0 @@ }

@@ -9,2 +9,3 @@ import SmartModelError from './SmartModelError.js'

return new Proxy(this, {
set(target, property, value) {

@@ -33,3 +34,3 @@ const entry = schema[property] || {}

if (isTypeArrayOfSmartModels(entry.type)) {
if (isTypeArrayOfSmartModels(entry.type) && !isUndef(value)) {
value = entry.type[0].$hydrate(value)

@@ -53,3 +54,3 @@ entry.type = Array

if (Nested) {
if (Nested && !isUndef(value)) {
value = new Nested(value)

@@ -64,2 +65,4 @@ }

trigger(target.$onUpdate)
target.$applySubscribers(property, value)
}

@@ -117,3 +120,5 @@

trigger(target.$onBeforeDelete)
if (trigger(target.$onBeforeDelete) === false) {
return true
}

@@ -125,2 +130,4 @@ Reflect.deleteProperty(target, property)

target.$applySubscribers(property, value)
return true

@@ -127,0 +134,0 @@ }

@@ -26,3 +26,3 @@ /* eslint-disable new-cap */

export function isSmartModel(value) {
return value.prototype instanceof SmartModel || value instanceof SmartModel
return value && (value.prototype instanceof SmartModel || value instanceof SmartModel)
}

@@ -38,4 +38,4 @@

export function keys(obj, cb = function () { }) {
return Object.keys(obj).map(cb)
export function keys(obj, cb = function () {}) {
return Object.keys(obj).map((key) => cb(key, obj[key]))
}

@@ -42,0 +42,0 @@

@@ -428,2 +428,20 @@ /* eslint-disable prefer-reflect */

})
it('should intercept delete', () => {
const Model = SmartModel.create('Model', {
prop: { default: 'string' }
}, {
methods: {
$onBeforeDelete() {
return false
}
}
})
const model = new Model()
delete model.prop
expect(model.prop).to.be.equal('string')
})
})

@@ -435,3 +453,3 @@

describe('$get', function () {
it('should works', function () {
it('should eject data model as standard JSON', function () {
const Model = SmartModel.create('Model', {

@@ -443,6 +461,13 @@ prop1: { default: 'string1' },

}
},
prop3: {
type: {
prop: { default: 'string3' }
}
}
})
const model = new Model()
const model = new Model({
prop2: {}
})
const obj = model.$get()

@@ -453,2 +478,3 @@

expect(model.prop2).to.be.instanceOf(SmartModel)
expect(model.prop3).to.not.be.instanceOf(SmartModel)
expect(obj).to.not.be.instanceOf(SmartModel)

@@ -469,6 +495,12 @@ expect(obj.prop2).to.not.be.instanceOf(SmartModel)

}
},
prop4: {
type: String
}
})
const model = new Model()
const model = new Model({
prop4: 'string5',
unregistred: 'unregistred'
})

@@ -485,7 +517,9 @@ model.$post({

expect(model.prop1).to.be.equal('newString1')
expect(model.prop2).to.be.equal(undef)
expect(model.prop2).to.be.equal('string2')
expect(model.new).to.be.equal('string')
expect(model.prop3.prop1).to.be.equal('newString2')
expect(model.prop3.prop2).to.be.equal(undef)
expect(model.prop3.prop2).to.be.equal('string4')
expect(model.prop3.new).to.be.equal('string')
expect(model.prop4).to.be.equal(undef)
expect(model.unregistred).to.be.equal(undef)
})

@@ -558,2 +592,60 @@ })

})
describe('$subscribe', function () {
it('should call subscribersa', function () {
const properties = []
const values = []
const Model = SmartModel.create('Model', {
prop1: { default: 'string' },
prop2: { default: 'string' },
prop3: { default: 'string' }
})
const model = new Model()
model.$subscribe((property) => {
properties.push(property)
})
model.$subscribe((_, value) => {
values.push(value)
})
model.prop1 = 'new string1'
model.prop2 = 'new string2'
expect(properties).to.have.all.members([ 'prop1', 'prop2' ])
expect(values).to.have.all.members([ 'new string1', 'new string2' ])
})
it('should remove subscribersa', function () {
const properties = []
const values = []
const Model = SmartModel.create('Model', {
prop1: { default: 'string' },
prop2: { default: 'string' }
})
const model = new Model()
const unsub1 = model.$subscribe((property) => {
properties.push(property)
})
const unsub2 = model.$subscribe((_, value) => {
values.push(value)
})
unsub1()
unsub2()
model.prop1 = 'new string1'
model.prop2 = 'new string2'
expect(properties.length).to.be.equal(0)
expect(values.length).to.be.equal(0)
})
})
})

@@ -872,3 +964,3 @@

prop1: { default: 'string1' },
prop2: { type: SubModel }
prop2: { default: {}, type: SubModel }
})

@@ -890,2 +982,3 @@

prop2: {
default: {},
type: {

@@ -909,4 +1002,6 @@ prop: {

prop: {
default: {},
type: {
prop: {
default: {},
type: {

@@ -1011,2 +1106,3 @@ nestedNestedProp: {

prop: {
default: {},
type: {

@@ -1013,0 +1109,0 @@ prop: {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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