@jaysalvat/smart-model
Advanced tools
Comparing version 0.2.14 to 0.2.15
@@ -1,2 +0,1 @@ | ||
/**! | ||
@@ -6,3 +5,3 @@ * SmartModel | ||
* https://github.com/jaysalvat/smart-model | ||
* @version 0.2.14 built 2021-02-21 15:21:56 | ||
* @version 0.2.15 built 2021-02-22 07:45:48 | ||
* @license ISC | ||
@@ -18,30 +17,28 @@ * @author Jay Salvat http://jaysalvat.com | ||
/* eslint-disable new-cap */ | ||
function isArray(value) { | ||
return Array.isArray(value) | ||
return Array.isArray(value); | ||
} | ||
function isUndef(value) { | ||
return typeof value === 'undefined' | ||
return typeof value === "undefined"; | ||
} | ||
function isEmpty(value) { | ||
return value === '' || value === null || isUndef(value) | ||
return value === "" || value === null || isUndef(value); | ||
} | ||
function isFn(value) { | ||
return typeof value === 'function' | ||
return typeof value === "function"; | ||
} | ||
function isEqual(value1, value2) { | ||
return JSON.stringify(value1) === JSON.stringify(value2) | ||
return JSON.stringify(value1) === JSON.stringify(value2); | ||
} | ||
function isClass(value) { | ||
return value.toString().startsWith('class') | ||
return value.toString().startsWith("class"); | ||
} | ||
function isPlainObject(value) { | ||
return value.toString() === '[object Object]' | ||
return value.toString() === "[object Object]"; | ||
} | ||
@@ -51,37 +48,28 @@ | ||
const match = Type && Type.toString().match(/^\s*function (\w+)/); | ||
const type = (match ? match[1] : 'object').toLowerCase(); | ||
if (type === 'date' && value instanceof Type) { | ||
return true | ||
const type = (match ? match[1] : "object").toLowerCase(); | ||
if (type === "date" && value instanceof Type) { | ||
return true; | ||
} | ||
if (type === 'array' && isArray(value)) { | ||
return true | ||
if (type === "array" && isArray(value)) { | ||
return true; | ||
} | ||
if (type === 'object') { | ||
if (type === "object") { | ||
if (isClass(Type) && value instanceof Type) { | ||
return true | ||
return true; | ||
} | ||
if (!isClass(Type) && typeof value === type) { | ||
return true | ||
return true; | ||
} | ||
} else if (typeof value === type) { | ||
return true | ||
return true; | ||
} | ||
return false | ||
return false; | ||
} | ||
function toArray(value) { | ||
return [].concat([], value) | ||
return [].concat([], value); | ||
} | ||
function pascalCase(string) { | ||
return string | ||
.normalize('NFD') | ||
.replace(/[\u0300-\u036f]/g, '') | ||
.match(/[a-z]+/gi) | ||
.map((word) => word.charAt(0).toUpperCase() + word.substr(1).toLowerCase()) | ||
.join('') | ||
return string.normalize("NFD").replace(/[\u0300-\u036f]/g, "").match(/[a-z]+/gi).map((word => word.charAt(0).toUpperCase() + word.substr(1).toLowerCase())).join(""); | ||
} | ||
@@ -91,29 +79,23 @@ | ||
const errors = []; | ||
if (entry.required && isEmpty(value)) { | ||
errors.push({ | ||
message: `Invalid value 'required' on property '${property}'`, | ||
code: 'required' | ||
code: "required" | ||
}); | ||
return errors | ||
return errors; | ||
} | ||
if (typeof value === 'undefined') { | ||
return errors | ||
if (typeof value === "undefined") { | ||
return errors; | ||
} | ||
if (entry.type && (entry.required || !isEmpty(value))) { | ||
if (!toArray(entry.type).some((type) => isType(value, type))) { | ||
if (!toArray(entry.type).some((type => isType(value, type)))) { | ||
errors.push({ | ||
message: `Invalid type '${typeof value}' on property '${property}'`, | ||
code: 'type' | ||
code: "type" | ||
}); | ||
} | ||
} | ||
if (entry.rule) { | ||
Object.keys(entry.rule).forEach((key) => { | ||
Object.keys(entry.rule).forEach((key => { | ||
const rule = entry.rule[key]; | ||
if (rule(value)) { | ||
@@ -125,6 +107,5 @@ errors.push({ | ||
} | ||
}); | ||
})); | ||
} | ||
return errors | ||
return errors; | ||
} | ||
@@ -134,13 +115,10 @@ | ||
if (!entry.type) { | ||
return false | ||
return false; | ||
} | ||
const Child = entry.type.prototype instanceof SmartModel ? entry.type : false; | ||
const schema = isPlainObject(entry.type) ? entry.type : false; | ||
if (Child || schema) { | ||
return Child ? Child : SmartModel.create(pascalCase(property), schema, settings) | ||
return Child ? Child : SmartModel.create(pascalCase(property), schema, settings); | ||
} | ||
return false | ||
return false; | ||
} | ||
@@ -151,3 +129,2 @@ | ||
return new Proxy(this, { | ||
set(target, property, value) { | ||
@@ -158,27 +135,20 @@ let entry = schema[property]; | ||
const Nested = createNested(entry, property, settings); | ||
function trigger(method, args) { | ||
return Reflect.apply(method, target, args ? args : [ property, value, old, schema ]) | ||
return Reflect.apply(method, target, args ? args : [ property, value, old, schema ]); | ||
} | ||
if (!entry) { | ||
if (settings.strict) { | ||
return true | ||
return true; | ||
} | ||
entry = {}; | ||
} | ||
trigger(target.onBeforeSet); | ||
if (updated) { | ||
trigger(target.onBeforeUpdate); | ||
} | ||
if (isFn(entry.transform)) { | ||
value = trigger(entry.transform, [ value, schema ]); | ||
} | ||
if (settings.exceptions) { | ||
const errors = checkErrors(entry, property, value); | ||
if (errors.length) { | ||
@@ -190,56 +160,40 @@ throw new SmartModelError({ | ||
source: target.constructor.name | ||
}) | ||
}); | ||
} | ||
} | ||
if (Nested) { | ||
value = new Nested(value instanceof Object ? value : {}); | ||
} | ||
target[property] = value; | ||
trigger(target.onSet); | ||
if (updated) { | ||
trigger(target.onUpdate); | ||
} | ||
return true | ||
return true; | ||
}, | ||
get(target, property) { | ||
const entry = schema[property]; | ||
let value = target[property]; | ||
if (!entry) { | ||
return target[property] | ||
return target[property]; | ||
} | ||
function trigger(method, args) { | ||
return Reflect.apply(method, target, args ? args : [ property, value, schema ]) | ||
return Reflect.apply(method, target, args ? args : [ property, value, schema ]); | ||
} | ||
trigger(target.onBeforeGet); | ||
if (isFn(entry)) { | ||
value = trigger(entry, [ target, schema ]); | ||
} | ||
if (isFn(entry.format)) { | ||
value = trigger(entry.format, [ value, schema ]); | ||
} | ||
trigger(target.onGet); | ||
return value | ||
return value; | ||
}, | ||
deleteProperty(target, property) { | ||
const value = target[property]; | ||
const entry = schema[property]; | ||
function trigger(method, args) { | ||
return Reflect.apply(method, target, args ? args : [ property, value, schema ]) | ||
return Reflect.apply(method, target, args ? args : [ property, value, schema ]); | ||
} | ||
if (entry.required) { | ||
@@ -249,16 +203,12 @@ throw new SmartModelError({ | ||
property: property, | ||
code: 'required' | ||
}) | ||
code: "required" | ||
}); | ||
} | ||
trigger(target.onBeforeDelete); | ||
Reflect.deleteProperty(target, property); | ||
trigger(target.onDelete); | ||
trigger(target.onUpdate); | ||
return true | ||
return true; | ||
} | ||
}) | ||
}); | ||
} | ||
@@ -270,4 +220,3 @@ } | ||
super(schema, settings); | ||
Object.keys(schema).forEach((key) => { | ||
Object.keys(schema).forEach((key => { | ||
if (isUndef(data[key])) { | ||
@@ -280,13 +229,10 @@ if (!isUndef(schema[key].default)) { | ||
} | ||
}); | ||
})); | ||
this.feed(data); | ||
} | ||
feed(data) { | ||
Object.keys(data).forEach((key) => { | ||
Object.keys(data).forEach((key => { | ||
this[key] = data[key]; | ||
}); | ||
})); | ||
} | ||
onBeforeGet() {} | ||
@@ -307,15 +253,14 @@ onBeforeSet() {} | ||
SmartModel.create = function (name, schema, settings, prototype) { | ||
SmartModel.create = function(name, schema, settings, prototype) { | ||
settings = Object.assign({}, SmartModel.settings, settings); | ||
const Model = { [name]: class extends SmartModel { | ||
constructor(data) { | ||
super(schema, data, settings); | ||
const Model = { | ||
[name]: class extends SmartModel { | ||
constructor(data) { | ||
super(schema, data, settings); | ||
} | ||
} | ||
} }[name]; | ||
Model.checkErrors = function (payload, filters) { | ||
}[name]; | ||
Model.checkErrors = function(payload, filters) { | ||
const invalidations = {}; | ||
Object.keys(schema).forEach((property) => { | ||
Object.keys(schema).forEach((property => { | ||
let subErrors; | ||
@@ -325,9 +270,6 @@ const value = payload[property]; | ||
const Nested = createNested(entry, property, settings); | ||
if (Nested) { | ||
subErrors = Nested.checkErrors(value, filters); | ||
} | ||
let errors = checkErrors(entry, property, value); | ||
if (subErrors) { | ||
@@ -337,5 +279,4 @@ invalidations[property] = subErrors; | ||
if (filters) { | ||
errors = errors.filter((error) => !toArray(filters).includes(error.code)); | ||
errors = errors.filter((error => !toArray(filters).includes(error.code))); | ||
} | ||
if (errors.length) { | ||
@@ -345,22 +286,17 @@ invalidations[property] = errors; | ||
} | ||
}); | ||
return Object.keys(invalidations).length ? invalidations : false | ||
})); | ||
return Object.keys(invalidations).length ? invalidations : false; | ||
}; | ||
Model.hydrate = function (payload) { | ||
Model.hydrate = function(payload) { | ||
if (isArray(payload)) { | ||
return payload.map((item) => new Model(item)) | ||
return payload.map((item => new Model(item))); | ||
} else { | ||
return new Model(payload) | ||
return new Model(payload); | ||
} | ||
}; | ||
Object.assign(Model.prototype, prototype); | ||
Model.schema = schema; | ||
return Model | ||
return Model; | ||
}; | ||
export default SmartModel; |
@@ -1,2 +0,2 @@ | ||
/*! SmartModel v0.2.14 */ | ||
class e extends Error{constructor(e){super(e.message),Object.assign(this,e)}}function t(e){return Array.isArray(e)}function r(e){return void 0===e}function n(e){return""===e||null===e||r(e)}function o(e){return"function"==typeof e}function s(e){return e.toString().startsWith("class")}function c(e){return[].concat([],e)}function i(e,r,o){const i=[];return e.required&&n(o)?(i.push({message:`Invalid value 'required' on property '${r}'`,code:"required"}),i):(void 0===o||(!e.type||!e.required&&n(o)||c(e.type).some((e=>function(e,r){const n=r&&r.toString().match(/^\s*function (\w+)/),o=(n?n[1]:"object").toLowerCase();if("date"===o&&e instanceof r)return!0;if("array"===o&&t(e))return!0;if("object"===o){if(s(r)&&e instanceof r)return!0;if(!s(r)&&typeof e===o)return!0}else if(typeof e===o)return!0;return!1}(o,e)))||i.push({message:`Invalid type '${typeof o}' on property '${r}'`,code:"type"}),e.rule&&Object.keys(e.rule).forEach((t=>{(0,e.rule[t])(o)&&i.push({message:`Invalid value '${t}' on property '${r}'`,code:t})}))),i)}function u(e={},t,r){if(!e.type)return!1;const n=e.type.prototype instanceof a&&e.type,o="[object Object]"===e.type.toString()&&e.type;return!(!n&&!o)&&(n||a.create(t.normalize("NFD").replace(/[\u0300-\u036f]/g,"").match(/[a-z]+/gi).map((e=>e.charAt(0).toUpperCase()+e.substr(1).toLowerCase())).join(""),o,r))}class a extends class{constructor(t,r){return new Proxy(this,{set(n,s,c){let a=t[s];const f=n[s],p=(l=c,d=f,!(JSON.stringify(l)===JSON.stringify(d)));var l,d;const y=u(a,s,r);function h(e,r){return Reflect.apply(e,n,r||[s,c,f,t])}if(!a){if(r.strict)return!0;a={}}if(h(n.onBeforeSet),p&&h(n.onBeforeUpdate),o(a.transform)&&(c=h(a.transform,[c,t])),r.exceptions){const t=i(a,s,c);if(t.length)throw new e({message:t[0].message,property:s,code:t[0].code,source:n.constructor.name})}return y&&(c=new y(c instanceof Object?c:{})),n[s]=c,h(n.onSet),p&&h(n.onUpdate),!0},get(e,r){const n=t[r];let s=e[r];if(!n)return e[r];function c(n,o){return Reflect.apply(n,e,o||[r,s,t])}return c(e.onBeforeGet),o(n)&&(s=c(n,[e,t])),o(n.format)&&(s=c(n.format,[s,t])),c(e.onGet),s},deleteProperty(r,n){const o=r[n];function s(e,s){return Reflect.apply(e,r,s||[n,o,t])}if(t[n].required)throw new e({message:`Invalid delete on required propery ${n}`,property:n,code:"required"});return s(r.onBeforeDelete),Reflect.deleteProperty(r,n),s(r.onDelete),s(r.onUpdate),!0}})}}{constructor(e={},t={},n){super(e,n),Object.keys(e).forEach((n=>{r(t[n])&&(r(e[n].default)?this[n]=t[n]:this[n]=e[n].default)})),this.feed(t)}feed(e){Object.keys(e).forEach((t=>{this[t]=e[t]}))}onBeforeGet(){}onBeforeSet(){}onBeforeUpdate(){}onDelete(){}onGet(){}onBeforeDelete(){}onSet(){}onUpdate(){}}a.settings={strict:!1,exceptions:!0},a.create=function(e,r,n,o){n=Object.assign({},a.settings,n);const s={[e]:class extends a{constructor(e){super(r,e,n)}}}[e];return s.checkErrors=function(e,t){const o={};return Object.keys(r).forEach((s=>{let a;const f=e[s],p=r[s],l=u(p,s,n);l&&(a=l.checkErrors(f,t));let d=i(p,s,f);a?o[s]=a:d.length&&(t&&(d=d.filter((e=>!c(t).includes(e.code)))),d.length&&(o[s]=d))})),!!Object.keys(o).length&&o},s.hydrate=function(e){return t(e)?e.map((e=>new s(e))):new s(e)},Object.assign(s.prototype,o),s.schema=r,s};export default a; | ||
/*! SmartModel v0.2.15 */ | ||
class e extends Error{constructor(e){super(e.message),Object.assign(this,e)}}function t(e){return Array.isArray(e)}function r(e){return void 0===e}function n(e){return""===e||null===e||r(e)}function o(e){return"function"==typeof e}function s(e){return e.toString().startsWith("class")}function c(e){return[].concat([],e)}function u(e,r,o){const u=[];return e.required&&n(o)?(u.push({message:`Invalid value 'required' on property '${r}'`,code:"required"}),u):(void 0===o||(!e.type||!e.required&&n(o)||c(e.type).some((e=>function(e,r){const n=r&&r.toString().match(/^\s*function (\w+)/),o=(n?n[1]:"object").toLowerCase();if("date"===o&&e instanceof r)return!0;if("array"===o&&t(e))return!0;if("object"===o){if(s(r)&&e instanceof r)return!0;if(!s(r)&&typeof e===o)return!0}else if(typeof e===o)return!0;return!1}(o,e)))||u.push({message:`Invalid type '${typeof o}' on property '${r}'`,code:"type"}),e.rule&&Object.keys(e.rule).forEach((t=>{(0,e.rule[t])(o)&&u.push({message:`Invalid value '${t}' on property '${r}'`,code:t})}))),u)}function i(e={},t,r){if(!e.type)return!1;const n=e.type.prototype instanceof a&&e.type,o="[object Object]"===e.type.toString()&&e.type;return!(!n&&!o)&&(n||a.create(t.normalize("NFD").replace(/[\u0300-\u036f]/g,"").match(/[a-z]+/gi).map((e=>e.charAt(0).toUpperCase()+e.substr(1).toLowerCase())).join(""),o,r))}class a extends class{constructor(t,r){return new Proxy(this,{set(n,s,c){let a=t[s];const f=n[s],p=(l=f,!(JSON.stringify(c)===JSON.stringify(l)));var l;const d=i(a,s,r);function y(e,r){return Reflect.apply(e,n,r||[s,c,f,t])}if(!a){if(r.strict)return!0;a={}}if(y(n.onBeforeSet),p&&y(n.onBeforeUpdate),o(a.transform)&&(c=y(a.transform,[c,t])),r.exceptions){const t=u(a,s,c);if(t.length)throw new e({message:t[0].message,property:s,code:t[0].code,source:n.constructor.name})}return d&&(c=new d(c instanceof Object?c:{})),n[s]=c,y(n.onSet),p&&y(n.onUpdate),!0},get(e,r){const n=t[r];let s=e[r];if(!n)return e[r];function c(n,o){return Reflect.apply(n,e,o||[r,s,t])}return c(e.onBeforeGet),o(n)&&(s=c(n,[e,t])),o(n.format)&&(s=c(n.format,[s,t])),c(e.onGet),s},deleteProperty(r,n){const o=r[n];function s(e,s){return Reflect.apply(e,r,s||[n,o,t])}if(t[n].required)throw new e({message:`Invalid delete on required propery ${n}`,property:n,code:"required"});return s(r.onBeforeDelete),Reflect.deleteProperty(r,n),s(r.onDelete),s(r.onUpdate),!0}})}}{constructor(e={},t={},n){super(e,n),Object.keys(e).forEach((n=>{r(t[n])&&(this[n]=r(e[n].default)?t[n]:e[n].default)})),this.feed(t)}feed(e){Object.keys(e).forEach((t=>{this[t]=e[t]}))}onBeforeGet(){}onBeforeSet(){}onBeforeUpdate(){}onDelete(){}onGet(){}onBeforeDelete(){}onSet(){}onUpdate(){}}a.settings={strict:!1,exceptions:!0},a.create=function(e,r,n,o){n=Object.assign({},a.settings,n);const s={[e]:class extends a{constructor(e){super(r,e,n)}}}[e];return s.checkErrors=function(e,t){const o={};return Object.keys(r).forEach((s=>{let a;const f=e[s],p=r[s],l=i(p,s,n);l&&(a=l.checkErrors(f,t));let d=u(p,s,f);a?o[s]=a:d.length&&(t&&(d=d.filter((e=>!c(t).includes(e.code)))),d.length&&(o[s]=d))})),!!Object.keys(o).length&&o},s.hydrate=function(e){return t(e)?e.map((e=>new s(e))):new s(e)},Object.assign(s.prototype,o),s.schema=r,s};export default a; |
@@ -1,2 +0,1 @@ | ||
/**! | ||
@@ -6,12 +5,11 @@ * SmartModel | ||
* https://github.com/jaysalvat/smart-model | ||
* @version 0.2.14 built 2021-02-21 15:21:56 | ||
* @version 0.2.15 built 2021-02-22 07:45:48 | ||
* @license ISC | ||
* @author Jay Salvat http://jaysalvat.com | ||
*/ | ||
(function (global, factory) { | ||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : | ||
typeof define === 'function' && define.amd ? define(['exports'], factory) : | ||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.SmartModel = {})); | ||
}(this, (function (exports) { 'use strict'; | ||
(function(global, factory) { | ||
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define([ "exports" ], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, | ||
factory(global.SmartModel = {})); | ||
})(this, (function(exports) { | ||
"use strict"; | ||
class SmartModelError extends Error { | ||
@@ -23,101 +21,73 @@ constructor(data) { | ||
} | ||
/* eslint-disable new-cap */ | ||
function isArray(value) { | ||
return Array.isArray(value) | ||
return Array.isArray(value); | ||
} | ||
function isUndef(value) { | ||
return typeof value === 'undefined' | ||
return typeof value === "undefined"; | ||
} | ||
function isEmpty(value) { | ||
return value === '' || value === null || isUndef(value) | ||
return value === "" || value === null || isUndef(value); | ||
} | ||
function isFn(value) { | ||
return typeof value === 'function' | ||
return typeof value === "function"; | ||
} | ||
function isEqual(value1, value2) { | ||
return JSON.stringify(value1) === JSON.stringify(value2) | ||
return JSON.stringify(value1) === JSON.stringify(value2); | ||
} | ||
function isClass(value) { | ||
return value.toString().startsWith('class') | ||
return value.toString().startsWith("class"); | ||
} | ||
function isPlainObject(value) { | ||
return value.toString() === '[object Object]' | ||
return value.toString() === "[object Object]"; | ||
} | ||
function isType(value, Type) { | ||
const match = Type && Type.toString().match(/^\s*function (\w+)/); | ||
const type = (match ? match[1] : 'object').toLowerCase(); | ||
if (type === 'date' && value instanceof Type) { | ||
return true | ||
const type = (match ? match[1] : "object").toLowerCase(); | ||
if (type === "date" && value instanceof Type) { | ||
return true; | ||
} | ||
if (type === 'array' && isArray(value)) { | ||
return true | ||
if (type === "array" && isArray(value)) { | ||
return true; | ||
} | ||
if (type === 'object') { | ||
if (type === "object") { | ||
if (isClass(Type) && value instanceof Type) { | ||
return true | ||
return true; | ||
} | ||
if (!isClass(Type) && typeof value === type) { | ||
return true | ||
return true; | ||
} | ||
} else if (typeof value === type) { | ||
return true | ||
return true; | ||
} | ||
return false | ||
return false; | ||
} | ||
function toArray(value) { | ||
return [].concat([], value) | ||
return [].concat([], value); | ||
} | ||
function pascalCase(string) { | ||
return string | ||
.normalize('NFD') | ||
.replace(/[\u0300-\u036f]/g, '') | ||
.match(/[a-z]+/gi) | ||
.map((word) => word.charAt(0).toUpperCase() + word.substr(1).toLowerCase()) | ||
.join('') | ||
return string.normalize("NFD").replace(/[\u0300-\u036f]/g, "").match(/[a-z]+/gi).map((word => word.charAt(0).toUpperCase() + word.substr(1).toLowerCase())).join(""); | ||
} | ||
function checkErrors(entry, property, value) { | ||
const errors = []; | ||
if (entry.required && isEmpty(value)) { | ||
errors.push({ | ||
message: `Invalid value 'required' on property '${property}'`, | ||
code: 'required' | ||
code: "required" | ||
}); | ||
return errors | ||
return errors; | ||
} | ||
if (typeof value === 'undefined') { | ||
return errors | ||
if (typeof value === "undefined") { | ||
return errors; | ||
} | ||
if (entry.type && (entry.required || !isEmpty(value))) { | ||
if (!toArray(entry.type).some((type) => isType(value, type))) { | ||
if (!toArray(entry.type).some((type => isType(value, type)))) { | ||
errors.push({ | ||
message: `Invalid type '${typeof value}' on property '${property}'`, | ||
code: 'type' | ||
code: "type" | ||
}); | ||
} | ||
} | ||
if (entry.rule) { | ||
Object.keys(entry.rule).forEach((key) => { | ||
Object.keys(entry.rule).forEach((key => { | ||
const rule = entry.rule[key]; | ||
if (rule(value)) { | ||
@@ -129,27 +99,20 @@ errors.push({ | ||
} | ||
}); | ||
})); | ||
} | ||
return errors | ||
return errors; | ||
} | ||
function createNested(entry = {}, property, settings) { | ||
if (!entry.type) { | ||
return false | ||
return false; | ||
} | ||
const Child = entry.type.prototype instanceof SmartModel ? entry.type : false; | ||
const schema = isPlainObject(entry.type) ? entry.type : false; | ||
if (Child || schema) { | ||
return Child ? Child : SmartModel.create(pascalCase(property), schema, settings) | ||
return Child ? Child : SmartModel.create(pascalCase(property), schema, settings); | ||
} | ||
return false | ||
return false; | ||
} | ||
class SmartModelProxy { | ||
constructor(schema, settings) { | ||
return new Proxy(this, { | ||
set(target, property, value) { | ||
@@ -160,27 +123,20 @@ let entry = schema[property]; | ||
const Nested = createNested(entry, property, settings); | ||
function trigger(method, args) { | ||
return Reflect.apply(method, target, args ? args : [ property, value, old, schema ]) | ||
return Reflect.apply(method, target, args ? args : [ property, value, old, schema ]); | ||
} | ||
if (!entry) { | ||
if (settings.strict) { | ||
return true | ||
return true; | ||
} | ||
entry = {}; | ||
} | ||
trigger(target.onBeforeSet); | ||
if (updated) { | ||
trigger(target.onBeforeUpdate); | ||
} | ||
if (isFn(entry.transform)) { | ||
value = trigger(entry.transform, [ value, schema ]); | ||
} | ||
if (settings.exceptions) { | ||
const errors = checkErrors(entry, property, value); | ||
if (errors.length) { | ||
@@ -192,56 +148,40 @@ throw new SmartModelError({ | ||
source: target.constructor.name | ||
}) | ||
}); | ||
} | ||
} | ||
if (Nested) { | ||
value = new Nested(value instanceof Object ? value : {}); | ||
} | ||
target[property] = value; | ||
trigger(target.onSet); | ||
if (updated) { | ||
trigger(target.onUpdate); | ||
} | ||
return true | ||
return true; | ||
}, | ||
get(target, property) { | ||
const entry = schema[property]; | ||
let value = target[property]; | ||
if (!entry) { | ||
return target[property] | ||
return target[property]; | ||
} | ||
function trigger(method, args) { | ||
return Reflect.apply(method, target, args ? args : [ property, value, schema ]) | ||
return Reflect.apply(method, target, args ? args : [ property, value, schema ]); | ||
} | ||
trigger(target.onBeforeGet); | ||
if (isFn(entry)) { | ||
value = trigger(entry, [ target, schema ]); | ||
} | ||
if (isFn(entry.format)) { | ||
value = trigger(entry.format, [ value, schema ]); | ||
} | ||
trigger(target.onGet); | ||
return value | ||
return value; | ||
}, | ||
deleteProperty(target, property) { | ||
const value = target[property]; | ||
const entry = schema[property]; | ||
function trigger(method, args) { | ||
return Reflect.apply(method, target, args ? args : [ property, value, schema ]) | ||
return Reflect.apply(method, target, args ? args : [ property, value, schema ]); | ||
} | ||
if (entry.required) { | ||
@@ -251,24 +191,18 @@ throw new SmartModelError({ | ||
property: property, | ||
code: 'required' | ||
}) | ||
code: "required" | ||
}); | ||
} | ||
trigger(target.onBeforeDelete); | ||
Reflect.deleteProperty(target, property); | ||
trigger(target.onDelete); | ||
trigger(target.onUpdate); | ||
return true | ||
return true; | ||
} | ||
}) | ||
}); | ||
} | ||
} | ||
class SmartModel extends SmartModelProxy { | ||
constructor(schema = {}, data = {}, settings) { | ||
super(schema, settings); | ||
Object.keys(schema).forEach((key) => { | ||
Object.keys(schema).forEach((key => { | ||
if (isUndef(data[key])) { | ||
@@ -281,13 +215,10 @@ if (!isUndef(schema[key].default)) { | ||
} | ||
}); | ||
})); | ||
this.feed(data); | ||
} | ||
feed(data) { | ||
Object.keys(data).forEach((key) => { | ||
Object.keys(data).forEach((key => { | ||
this[key] = data[key]; | ||
}); | ||
})); | ||
} | ||
onBeforeGet() {} | ||
@@ -302,3 +233,2 @@ onBeforeSet() {} | ||
} | ||
SmartModel.settings = { | ||
@@ -308,16 +238,14 @@ strict: false, | ||
}; | ||
SmartModel.create = function (name, schema, settings, prototype) { | ||
SmartModel.create = function(name, schema, settings, prototype) { | ||
settings = Object.assign({}, SmartModel.settings, settings); | ||
const Model = { [name]: class extends SmartModel { | ||
constructor(data) { | ||
super(schema, data, settings); | ||
const Model = { | ||
[name]: class extends SmartModel { | ||
constructor(data) { | ||
super(schema, data, settings); | ||
} | ||
} | ||
} }[name]; | ||
Model.checkErrors = function (payload, filters) { | ||
}[name]; | ||
Model.checkErrors = function(payload, filters) { | ||
const invalidations = {}; | ||
Object.keys(schema).forEach((property) => { | ||
Object.keys(schema).forEach((property => { | ||
let subErrors; | ||
@@ -327,9 +255,6 @@ const value = payload[property]; | ||
const Nested = createNested(entry, property, settings); | ||
if (Nested) { | ||
subErrors = Nested.checkErrors(value, filters); | ||
} | ||
let errors = checkErrors(entry, property, value); | ||
if (subErrors) { | ||
@@ -339,5 +264,4 @@ invalidations[property] = subErrors; | ||
if (filters) { | ||
errors = errors.filter((error) => !toArray(filters).includes(error.code)); | ||
errors = errors.filter((error => !toArray(filters).includes(error.code))); | ||
} | ||
if (errors.length) { | ||
@@ -347,26 +271,20 @@ invalidations[property] = errors; | ||
} | ||
}); | ||
return Object.keys(invalidations).length ? invalidations : false | ||
})); | ||
return Object.keys(invalidations).length ? invalidations : false; | ||
}; | ||
Model.hydrate = function (payload) { | ||
Model.hydrate = function(payload) { | ||
if (isArray(payload)) { | ||
return payload.map((item) => new Model(item)) | ||
return payload.map((item => new Model(item))); | ||
} else { | ||
return new Model(payload) | ||
return new Model(payload); | ||
} | ||
}; | ||
Object.assign(Model.prototype, prototype); | ||
Model.schema = schema; | ||
return Model | ||
return Model; | ||
}; | ||
exports.default = SmartModel; | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
}))); | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
})); |
@@ -1,2 +0,2 @@ | ||
/*! SmartModel v0.2.14 */ | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).SmartModel={})}(this,(function(e){"use strict";class t extends Error{constructor(e){super(e.message),Object.assign(this,e)}}function r(e){return Array.isArray(e)}function n(e){return void 0===e}function o(e){return""===e||null===e||n(e)}function s(e){return"function"==typeof e}function c(e){return e.toString().startsWith("class")}function i(e){return[].concat([],e)}function u(e,t,n){const s=[];return e.required&&o(n)?(s.push({message:`Invalid value 'required' on property '${t}'`,code:"required"}),s):(void 0===n||(!e.type||!e.required&&o(n)||i(e.type).some((e=>function(e,t){const n=t&&t.toString().match(/^\s*function (\w+)/),o=(n?n[1]:"object").toLowerCase();if("date"===o&&e instanceof t)return!0;if("array"===o&&r(e))return!0;if("object"===o){if(c(t)&&e instanceof t)return!0;if(!c(t)&&typeof e===o)return!0}else if(typeof e===o)return!0;return!1}(n,e)))||s.push({message:`Invalid type '${typeof n}' on property '${t}'`,code:"type"}),e.rule&&Object.keys(e.rule).forEach((r=>{(0,e.rule[r])(n)&&s.push({message:`Invalid value '${r}' on property '${t}'`,code:r})}))),s)}function f(e={},t,r){if(!e.type)return!1;const n=e.type.prototype instanceof a&&e.type,o="[object Object]"===e.type.toString()&&e.type;return!(!n&&!o)&&(n||a.create(t.normalize("NFD").replace(/[\u0300-\u036f]/g,"").match(/[a-z]+/gi).map((e=>e.charAt(0).toUpperCase()+e.substr(1).toLowerCase())).join(""),o,r))}class a extends class{constructor(e,r){return new Proxy(this,{set(n,o,c){let i=e[o];const a=n[o],p=(l=c,d=a,!(JSON.stringify(l)===JSON.stringify(d)));var l,d;const y=f(i,o,r);function h(t,r){return Reflect.apply(t,n,r||[o,c,a,e])}if(!i){if(r.strict)return!0;i={}}if(h(n.onBeforeSet),p&&h(n.onBeforeUpdate),s(i.transform)&&(c=h(i.transform,[c,e])),r.exceptions){const e=u(i,o,c);if(e.length)throw new t({message:e[0].message,property:o,code:e[0].code,source:n.constructor.name})}return y&&(c=new y(c instanceof Object?c:{})),n[o]=c,h(n.onSet),p&&h(n.onUpdate),!0},get(t,r){const n=e[r];let o=t[r];if(!n)return t[r];function c(n,s){return Reflect.apply(n,t,s||[r,o,e])}return c(t.onBeforeGet),s(n)&&(o=c(n,[t,e])),s(n.format)&&(o=c(n.format,[o,e])),c(t.onGet),o},deleteProperty(r,n){const o=r[n];function s(t,s){return Reflect.apply(t,r,s||[n,o,e])}if(e[n].required)throw new t({message:`Invalid delete on required propery ${n}`,property:n,code:"required"});return s(r.onBeforeDelete),Reflect.deleteProperty(r,n),s(r.onDelete),s(r.onUpdate),!0}})}}{constructor(e={},t={},r){super(e,r),Object.keys(e).forEach((r=>{n(t[r])&&(n(e[r].default)?this[r]=t[r]:this[r]=e[r].default)})),this.feed(t)}feed(e){Object.keys(e).forEach((t=>{this[t]=e[t]}))}onBeforeGet(){}onBeforeSet(){}onBeforeUpdate(){}onDelete(){}onGet(){}onBeforeDelete(){}onSet(){}onUpdate(){}}a.settings={strict:!1,exceptions:!0},a.create=function(e,t,n,o){n=Object.assign({},a.settings,n);const s={[e]:class extends a{constructor(e){super(t,e,n)}}}[e];return s.checkErrors=function(e,r){const o={};return Object.keys(t).forEach((s=>{let c;const a=e[s],p=t[s],l=f(p,s,n);l&&(c=l.checkErrors(a,r));let d=u(p,s,a);c?o[s]=c:d.length&&(r&&(d=d.filter((e=>!i(r).includes(e.code)))),d.length&&(o[s]=d))})),!!Object.keys(o).length&&o},s.hydrate=function(e){return r(e)?e.map((e=>new s(e))):new s(e)},Object.assign(s.prototype,o),s.schema=t,s},e.default=a,Object.defineProperty(e,"__esModule",{value:!0})})); | ||
/*! SmartModel v0.2.15 */ | ||
var e,t;e=this,t=function(e){"use strict";class t extends Error{constructor(e){super(e.message),Object.assign(this,e)}}function r(e){return Array.isArray(e)}function n(e){return void 0===e}function o(e){return""===e||null===e||n(e)}function s(e){return"function"==typeof e}function c(e){return e.toString().startsWith("class")}function i(e){return[].concat([],e)}function u(e,t,n){const s=[];return e.required&&o(n)?(s.push({message:`Invalid value 'required' on property '${t}'`,code:"required"}),s):(void 0===n||(!e.type||!e.required&&o(n)||i(e.type).some((e=>function(e,t){const n=t&&t.toString().match(/^\s*function (\w+)/),o=(n?n[1]:"object").toLowerCase();if("date"===o&&e instanceof t)return!0;if("array"===o&&r(e))return!0;if("object"===o){if(c(t)&&e instanceof t)return!0;if(!c(t)&&typeof e===o)return!0}else if(typeof e===o)return!0;return!1}(n,e)))||s.push({message:`Invalid type '${typeof n}' on property '${t}'`,code:"type"}),e.rule&&Object.keys(e.rule).forEach((r=>{(0,e.rule[r])(n)&&s.push({message:`Invalid value '${r}' on property '${t}'`,code:r})}))),s)}function f(e={},t,r){if(!e.type)return!1;const n=e.type.prototype instanceof a&&e.type,o="[object Object]"===e.type.toString()&&e.type;return!(!n&&!o)&&(n||a.create(t.normalize("NFD").replace(/[\u0300-\u036f]/g,"").match(/[a-z]+/gi).map((e=>e.charAt(0).toUpperCase()+e.substr(1).toLowerCase())).join(""),o,r))}class a extends class{constructor(e,r){return new Proxy(this,{set(n,o,c){let i=e[o];const a=n[o],p=(l=a,!(JSON.stringify(c)===JSON.stringify(l)));var l;const d=f(i,o,r);function y(t,r){return Reflect.apply(t,n,r||[o,c,a,e])}if(!i){if(r.strict)return!0;i={}}if(y(n.onBeforeSet),p&&y(n.onBeforeUpdate),s(i.transform)&&(c=y(i.transform,[c,e])),r.exceptions){const e=u(i,o,c);if(e.length)throw new t({message:e[0].message,property:o,code:e[0].code,source:n.constructor.name})}return d&&(c=new d(c instanceof Object?c:{})),n[o]=c,y(n.onSet),p&&y(n.onUpdate),!0},get(t,r){const n=e[r];let o=t[r];if(!n)return t[r];function c(n,s){return Reflect.apply(n,t,s||[r,o,e])}return c(t.onBeforeGet),s(n)&&(o=c(n,[t,e])),s(n.format)&&(o=c(n.format,[o,e])),c(t.onGet),o},deleteProperty(r,n){const o=r[n];function s(t,s){return Reflect.apply(t,r,s||[n,o,e])}if(e[n].required)throw new t({message:`Invalid delete on required propery ${n}`,property:n,code:"required"});return s(r.onBeforeDelete),Reflect.deleteProperty(r,n),s(r.onDelete),s(r.onUpdate),!0}})}}{constructor(e={},t={},r){super(e,r),Object.keys(e).forEach((r=>{n(t[r])&&(this[r]=n(e[r].default)?t[r]:e[r].default)})),this.feed(t)}feed(e){Object.keys(e).forEach((t=>{this[t]=e[t]}))}onBeforeGet(){}onBeforeSet(){}onBeforeUpdate(){}onDelete(){}onGet(){}onBeforeDelete(){}onSet(){}onUpdate(){}}a.settings={strict:!1,exceptions:!0},a.create=function(e,t,n,o){n=Object.assign({},a.settings,n);const s={[e]:class extends a{constructor(e){super(t,e,n)}}}[e];return s.checkErrors=function(e,r){const o={};return Object.keys(t).forEach((s=>{let c;const a=e[s],p=t[s],l=f(p,s,n);l&&(c=l.checkErrors(a,r));let d=u(p,s,a);c?o[s]=c:d.length&&(r&&(d=d.filter((e=>!i(r).includes(e.code)))),d.length&&(o[s]=d))})),!!Object.keys(o).length&&o},s.hydrate=function(e){return r(e)?e.map((e=>new s(e))):new s(e)},Object.assign(s.prototype,o),s.schema=t,s},e.default=a,Object.defineProperty(e,"__esModule",{value:!0})},"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).SmartModel={}); |
{ | ||
"name": "@jaysalvat/smart-model", | ||
"version": "0.2.14", | ||
"version": "0.2.15", | ||
"description": "Javascript object model", | ||
@@ -43,2 +43,3 @@ "main": "./build/smart-model.umd.js", | ||
"rollup": "^2.39.0", | ||
"rollup-plugin-filesize": "^9.1.0", | ||
"rollup-plugin-terser": "^7.0.2", | ||
@@ -45,0 +46,0 @@ "shelljs": "^0.8.4" |
@@ -8,3 +8,3 @@ [![npm version](https://badge.fury.io/js/%40jaysalvat%2Fsmart-model.svg)](https://badge.fury.io/js/%40jaysalvat%2Fsmart-model) | ||
- [x] 1Kb gzipped | ||
- [x] ~1Kb gzipped | ||
- [x] Value transformation | ||
@@ -11,0 +11,0 @@ - [x] Value format |
@@ -0,2 +1,4 @@ | ||
/* eslint-disable camelcase */ | ||
import { terser } from 'rollup-plugin-terser' | ||
import filesize from 'rollup-plugin-filesize' | ||
import pkg from './package.json' | ||
@@ -15,4 +17,4 @@ | ||
const bannerLight = `/*! ${NAME} v${pkg.version} */` | ||
const bannerFull = ` | ||
const bannerMinify = `/*! ${NAME} v${pkg.version} */` | ||
const bannerBeautify = ` | ||
/**! | ||
@@ -27,2 +29,25 @@ * ${NAME} | ||
const terserBeautify = { | ||
mangle: false, | ||
compress: false, | ||
output: { | ||
beautify: true, | ||
indent_level: 2, | ||
braces: true | ||
} | ||
} | ||
const terserMinify = { | ||
mangle: { | ||
toplevel: true | ||
}, | ||
compress: { | ||
toplevel: true, | ||
reduce_funcs: true, | ||
keep_infinity: true, | ||
pure_getters: true, | ||
passes: 10 | ||
} | ||
} | ||
formats.forEach((type) => { | ||
@@ -39,5 +64,8 @@ const [ format, minify ] = type.split('.') | ||
name: format === 'umd' ? NAME : null, | ||
banner: !watched && (minify ? bannerLight : bannerFull), | ||
banner: !watched && (minify ? bannerMinify : bannerBeautify), | ||
plugins: [ | ||
!watched && minify ? terser() : null | ||
!watched && terser(minify ? terserMinify : terserBeautify), | ||
filesize({ | ||
showMinifiedSize: false | ||
}) | ||
] | ||
@@ -44,0 +72,0 @@ }, |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
61415
1632
9
23