Socket
Socket
Sign inDemoInstall

typeson

Package Overview
Dependencies
2
Maintainers
2
Versions
58
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 5.12.0 to 5.13.0

dist/typeson-commonjs2.min.js

12

CHANGES.md
# typeson CHANGES
## 5.13.0
- Enhancement: Add ESM dist format (and use in test and
`package.json`); provide non-minified versions
- Testing: Avoid need for build file (use `esm` and relative path
for browser test)
- npm: Indicate `core-js-bundle` and `regenerator-runtime` as
`peerDependencies` (and devDeps) in place of deprecated
`@babel/polyfill`
- npm: Update `opn-cli` -> `open-cli`; update devDeps; remove now
unused `rollup-plugin-node-resolve`
## 5.12.0

@@ -4,0 +16,0 @@

1614

dist/typeson-commonjs2.js

@@ -1,1 +0,1613 @@

"use strict";function _typeof(e){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function asyncGeneratorStep(e,t,n,r,o,i,a){try{var s=e[i](a),c=s.value}catch(e){return void n(e)}s.done?t(c):Promise.resolve(c).then(r,o)}function _asyncToGenerator(e){return function(){var t=this,n=arguments;return new Promise(function(r,o){var i=e.apply(t,n);function _next(e){asyncGeneratorStep(i,r,o,_next,_throw,"next",e)}function _throw(e){asyncGeneratorStep(i,r,o,_next,_throw,"throw",e)}_next(void 0)})}}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _defineProperties(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function _createClass(e,t,n){return t&&_defineProperties(e.prototype,t),n&&_defineProperties(e,n),e}function _defineProperty(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function _objectSpread(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{},r=Object.keys(n);"function"==typeof Object.getOwnPropertySymbols&&(r=r.concat(Object.getOwnPropertySymbols(n).filter(function(e){return Object.getOwnPropertyDescriptor(n,e).enumerable}))),r.forEach(function(t){_defineProperty(e,t,n[t])})}return e}function _slicedToArray(e,t){return _arrayWithHoles(e)||_iterableToArrayLimit(e,t)||_nonIterableRest()}function _toConsumableArray(e){return _arrayWithoutHoles(e)||_iterableToArray(e)||_nonIterableSpread()}function _arrayWithoutHoles(e){if(Array.isArray(e)){for(var t=0,n=new Array(e.length);t<e.length;t++)n[t]=e[t];return n}}function _arrayWithHoles(e){if(Array.isArray(e))return e}function _iterableToArray(e){if(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e))return Array.from(e)}function _iterableToArrayLimit(e,t){var n=[],r=!0,o=!1,i=void 0;try{for(var a,s=e[Symbol.iterator]();!(r=(a=s.next()).done)&&(n.push(a.value),!t||n.length!==t);r=!0);}catch(e){o=!0,i=e}finally{try{r||null==s.return||s.return()}finally{if(o)throw i}}return n}function _nonIterableSpread(){throw new TypeError("Invalid attempt to spread non-iterable instance")}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}var TypesonPromise=function TypesonPromise(e){_classCallCheck(this,TypesonPromise),this.p=new Promise(e)};"undefined"!=typeof Symbol&&(TypesonPromise.prototype[Symbol.toStringTag]="TypesonPromise"),TypesonPromise.prototype.then=function(e,t){var n=this;return new TypesonPromise(function(r,o){n.p.then(function(t){r(e?e(t):t)},function(e){n.p.catch(function(e){return t?t(e):Promise.reject(e)}).then(r,o)})})},TypesonPromise.prototype.catch=function(e){return this.then(null,e)},TypesonPromise.resolve=function(e){return new TypesonPromise(function(t){t(e)})},TypesonPromise.reject=function(e){return new TypesonPromise(function(t,n){n(e)})},["all","race"].map(function(e){TypesonPromise[e]=function(t){return new TypesonPromise(function(n,r){Promise[e](t.map(function(e){return e.p})).then(n,r)})}});var _ref={},toString=_ref.toString,hasOwn={}.hasOwnProperty,getProto=Object.getPrototypeOf,fnToString=hasOwn.toString;function isThenable(e,t){return isObject(e)&&"function"==typeof e.then&&(!t||"function"==typeof e.catch)}function toStringTag(e){return toString.call(e).slice(8,-1)}function hasConstructorOf(e,t){if(!e||"object"!==_typeof(e))return!1;var n=getProto(e);if(!n)return!1;var r=hasOwn.call(n,"constructor")&&n.constructor;return"function"!=typeof r?null===t:"function"==typeof r&&null!==t&&fnToString.call(r)===fnToString.call(t)}function isPlainObject(e){return!(!e||"Object"!==toStringTag(e))&&(!getProto(e)||hasConstructorOf(e,Object))}function isUserObject(e){if(!e||"Object"!==toStringTag(e))return!1;var t=getProto(e);return!t||(hasConstructorOf(e,Object)||isUserObject(t))}function isObject(e){return e&&"object"===_typeof(e)}function escapeKeyPathComponent(e){return e.replace(/~/g,"~0").replace(/\./g,"~1")}function unescapeKeyPathComponent(e){return e.replace(/~1/g,".").replace(/~0/g,"~")}function getByKeyPath(e,t){if(""===t)return e;var n=t.indexOf(".");if(n>-1){var r=e[unescapeKeyPathComponent(t.substr(0,n))];return void 0===r?void 0:getByKeyPath(r,t.substr(n+1))}return e[unescapeKeyPathComponent(t)]}function setAtKeyPath(e,t,n){if(""===t)return n;var r=t.indexOf(".");return r>-1?setAtKeyPath(e[unescapeKeyPathComponent(t.substr(0,r))],t.substr(r+1),n):(e[unescapeKeyPathComponent(t)]=n,e)}function getJSONType(e){return null===e?"null":Array.isArray(e)?"array":_typeof(e)}var keys=Object.keys,isArray=Array.isArray,hasOwn$1={}.hasOwnProperty,internalStateObjPropsToIgnore=["type","replaced","iterateIn","iterateUnsetNumeric"];function nestedPathsFirst(e,t){var n=e.keypath.match(/\./g),r=e.keypath.match(/\./g);return n&&(n=n.length),r&&(r=r.length),n>r?-1:n<r?1:e.keypath<t.keypath?-1:e.keypath>t.keypath}var Typeson=function(){function Typeson(e){_classCallCheck(this,Typeson),this.options=e,this.plainObjectReplacers=[],this.nonplainObjectReplacers=[],this.revivers={},this.types={}}return _createClass(Typeson,[{key:"stringify",value:function stringify(e,t,n,r){r=_objectSpread({},this.options,r,{stringification:!0});var o=this.encapsulate(e,null,r);return isArray(o)?JSON.stringify(o[0],t,n):o.then(function(e){return JSON.stringify(e,t,n)})}},{key:"stringifySync",value:function stringifySync(e,t,n,r){return this.stringify(e,t,n,_objectSpread({throwOnBadSyncType:!0},r,{sync:!0}))}},{key:"stringifyAsync",value:function stringifyAsync(e,t,n,r){return this.stringify(e,t,n,_objectSpread({throwOnBadSyncType:!0},r,{sync:!1}))}},{key:"parse",value:function parse(e,t,n){return n=_objectSpread({},this.options,n,{parse:!0}),this.revive(JSON.parse(e,t),n)}},{key:"parseSync",value:function parseSync(e,t,n){return this.parse(e,t,_objectSpread({throwOnBadSyncType:!0},n,{sync:!0}))}},{key:"parseAsync",value:function parseAsync(e,t,n){return this.parse(e,t,_objectSpread({throwOnBadSyncType:!0},n,{sync:!1}))}},{key:"specialTypeNames",value:function specialTypeNames(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return n.returnTypeNames=!0,this.encapsulate(e,t,n)}},{key:"rootTypeName",value:function rootTypeName(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return n.iterateNone=!0,this.encapsulate(e,t,n)}},{key:"encapsulate",value:function encapsulate(e,t,n){var r=(n=_objectSpread({sync:!0},this.options,n)).sync,o=this,i={},a=[],s=[],c=[],u=!("cyclic"in n)||n.cyclic,y=n.encapsulateObserver,p=_encapsulate("",e,u,t||{},c);function finish(e){var t=Object.values(i);if(n.iterateNone)return t.length?t[0]:Typeson.getJSONType(e);if(t.length){if(n.returnTypeNames)return _toConsumableArray(new Set(t));e&&isPlainObject(e)&&!hasOwn$1.call(e,"$types")?e.$types=i:e={$:e,$types:{$:i}}}else isObject(e)&&hasOwn$1.call(e,"$types")&&(e={$:e,$types:!0});return!n.returnTypeNames&&e}function checkPromises(e,t){return _checkPromises.apply(this,arguments)}function _checkPromises(){return(_checkPromises=_asyncToGenerator(regeneratorRuntime.mark(function _callee2(e,t){var n;return regeneratorRuntime.wrap(function _callee2$(r){for(;;)switch(r.prev=r.next){case 0:return r.next=2,Promise.all(t.map(function(e){return e[1].p}));case 2:return n=r.sent,r.next=5,Promise.all(n.map(function(){var n=_asyncToGenerator(regeneratorRuntime.mark(function _callee(n){var r,o,i,a,s,c,u,y,p,l,f,h,v,d;return regeneratorRuntime.wrap(function _callee$(b){for(;;)switch(b.prev=b.next){case 0:if(r=[],o=t.splice(0,1),i=_slicedToArray(o,1),a=i[0],s=_slicedToArray(a,7),c=s[0],u=s[2],y=s[3],p=s[4],l=s[5],f=s[6],h=_encapsulate(c,n,u,y,r,!0,f),v=hasConstructorOf(h,TypesonPromise),!c||!v){b.next=11;break}return b.next=8,h.p;case 8:return d=b.sent,p[l]=d,b.abrupt("return",checkPromises(e,r));case 11:return c?p[l]=h:e=v?h.p:h,b.abrupt("return",checkPromises(e,r));case 13:case"end":return b.stop()}},_callee)}));return function(e){return n.apply(this,arguments)}}()));case 5:return r.abrupt("return",e);case 6:case"end":return r.stop()}},_callee2)}))).apply(this,arguments)}function _adaptBuiltinStateObjectProperties(e,t,n){Object.assign(e,t);var r=internalStateObjPropsToIgnore.map(function(t){var n=e[t];return delete e[t],n});n(),internalStateObjPropsToIgnore.forEach(function(t,n){e[t]=r[n]})}function _encapsulate(e,t,r,c,u,p,l){var f,h={},v=_typeof(t),d=y?function(n){var o=l||c.type||Typeson.getJSONType(t);y(Object.assign(n||h,{keypath:e,value:t,cyclic:r,stateObj:c,promisesData:u,resolvingTypesonPromise:p,awaitingTypesonPromise:hasConstructorOf(t,TypesonPromise)},void 0!==o?{type:o}:{}))}:null;if(["string","boolean","number","undefined"].includes(v))return void 0===t||"number"===v&&(isNaN(t)||t===-1/0||t===1/0)?(f=replace(e,t,c,u,!1,p,d))!==t&&(h={replaced:f}):f=t,d&&d(),f;if(null===t)return d&&d(),t;if(r&&!c.iterateIn&&!c.iterateUnsetNumeric){var b=a.indexOf(t);if(!(b<0))return i[e]="#",d&&d({cyclicKeypath:s[b]}),"#"+s[b];!0===r&&(a.push(t),s.push(e))}var m,O=isPlainObject(t),T=isArray(t),P=(O||T)&&(!o.plainObjectReplacers.length||c.replaced)||c.iterateIn?t:replace(e,t,c,u,O||T,null,d);if(P!==t?(f=P,h={replaced:P}):T&&"object"!==c.iterateIn||"array"===c.iterateIn?(m=new Array(t.length),h={clone:m}):O||"object"===c.iterateIn?(m={},c.addLength&&(m.length=t.length),h={clone:m}):""===e&&hasConstructorOf(t,TypesonPromise)?(u.push([e,t,r,c,void 0,void 0,c.type]),f=t):f=t,d&&d(),n.iterateNone)return m||f;if(!m)return f;if(c.iterateIn){var g=function _loop(n){var o={ownKeys:hasOwn$1.call(t,n)};_adaptBuiltinStateObjectProperties(c,o,function(){var o=e+(e?".":"")+escapeKeyPathComponent(n),i=_encapsulate(o,t[n],!!r,c,u,p);hasConstructorOf(i,TypesonPromise)?u.push([o,i,!!r,c,m,n,c.type]):void 0!==i&&(m[n]=i)})};for(var _ in t)g(_);d&&d({endIterateIn:!0,end:!0})}else keys(t).forEach(function(n){var o=e+(e?".":"")+escapeKeyPathComponent(n);_adaptBuiltinStateObjectProperties(c,{ownKeys:!0},function(){var e=_encapsulate(o,t[n],!!r,c,u,p);hasConstructorOf(e,TypesonPromise)?u.push([o,e,!!r,c,m,n,c.type]):void 0!==e&&(m[n]=e)})}),d&&d({endIterateOwn:!0,end:!0});if(c.iterateUnsetNumeric){for(var S=t.length,j=function _loop2(n){if(!(n in t)){var o=e+(e?".":"")+n;_adaptBuiltinStateObjectProperties(c,{ownKeys:!1},function(){var e=_encapsulate(o,void 0,!!r,c,u,p);hasConstructorOf(e,TypesonPromise)?u.push([o,e,!!r,c,m,n,c.type]):void 0!==e&&(m[n]=e)})}},w=0;w<S;w++)j(w);d&&d({endIterateUnsetNumeric:!0,end:!0})}return m}function replace(e,t,n,a,s,c,y){for(var p=s?o.plainObjectReplacers:o.nonplainObjectReplacers,l=p.length;l--;){var f=p[l];if(f.test(t,n)){var h=f.type;if(o.revivers[h]){var v=i[e];i[e]=v?[h].concat(v):h}return Object.assign(n,{type:h,replaced:!0}),!r&&f.replaceAsync||f.replace?(y&&y({replacing:!0}),_encapsulate(e,f[r||!f.replaceAsync?"replace":"replaceAsync"](t,n),u&&"readonly",n,a,c,h)):(y&&y({typeDetected:!0}),_encapsulate(e,t,u&&"readonly",n,a,c,h))}}return t}return c.length?r&&n.throwOnBadSyncType?function(){throw new TypeError("Sync method requested but async result obtained")}():Promise.resolve(checkPromises(p,c)).then(finish):!r&&n.throwOnBadSyncType?function(){throw new TypeError("Async method requested but sync result obtained")}():n.stringification&&r?[finish(p)]:r?finish(p):Promise.resolve(finish(p))}},{key:"encapsulateSync",value:function encapsulateSync(e,t,n){return this.encapsulate(e,t,_objectSpread({throwOnBadSyncType:!0},n,{sync:!0}))}},{key:"encapsulateAsync",value:function encapsulateAsync(e,t,n){return this.encapsulate(e,t,_objectSpread({throwOnBadSyncType:!0},n,{sync:!1}))}},{key:"revive",value:function revive(e,t){var n=e&&e.$types;if(!n)return e;if(!0===n)return e.$;var r=(t=_objectSpread({sync:!0},this.options,t)).sync,o=[],i={},a=!0;n.$&&isPlainObject(n.$)&&(e=e.$,n=n.$,a=!1);var s=this;function _revive(e,t,c,u,y){if(!a||"$types"!==e){var p=n[e];if(isArray(t)||isPlainObject(t)){var l=isArray(t)?new Array(t.length):{};for(keys(t).forEach(function(n){var r=_revive(e+(e?".":"")+escapeKeyPathComponent(n),t[n],c||l,l,n);hasConstructorOf(r,Undefined)?l[n]=void 0:void 0!==r&&(l[n]=r)}),t=l;o.length;){var f=_slicedToArray(o[0],4),h=f[0],v=f[1],d=f[2],b=f[3],m=getByKeyPath(h,v);if(hasConstructorOf(m,Undefined))d[b]=void 0;else{if(void 0===m)break;d[b]=m}o.splice(0,1)}}if(!p)return t;if("#"===p){var O=getByKeyPath(c,t.slice(1));return void 0===O&&o.push([c,t.slice(1),u,y]),O}return[].concat(p).reduce(function reducer(e,t){if(hasConstructorOf(e,TypesonPromise))return e.then(function(e){return reducer(e,t)});var n=_slicedToArray(s.revivers[t],1)[0];if(!n)throw new Error("Unregistered type: "+t);return n[r&&n.revive?"revive":!r&&n.reviveAsync?"reviveAsync":"revive"](e,i)},t)}}function checkUndefined(e){return hasConstructorOf(e,Undefined)?void 0:e}var c,u=function revivePlainObjects(){var t=[];if(Object.entries(n).forEach(function(e){var r=_slicedToArray(e,2),o=r[0],i=r[1];"#"!==i&&[].concat(i).forEach(function(e){_slicedToArray(s.revivers[e],2)[1].plain&&(t.push({keypath:o,type:e}),delete n[o])})}),t.length)return t.sort(nestedPathsFirst).reduce(function reducer(t,n){var o=n.keypath,a=n.type;if(hasConstructorOf(t,TypesonPromise))return t.then(function(e){return reducer(e,a)});var c=getByKeyPath(e,o);if(hasConstructorOf(c,TypesonPromise))return c.then(function(e){return reducer(e,a)});var u=_slicedToArray(s.revivers[a],1)[0];if(!u)throw new Error("Unregistered type: "+a);void 0!==(c=u[r&&u.revive?"revive":!r&&u.reviveAsync?"reviveAsync":"revive"](c,i))&&(hasConstructorOf(c,Undefined)&&(c=void 0),setAtKeyPath(e,o,c)===c&&(e=c))},void 0)}();return isThenable(c=hasConstructorOf(u,TypesonPromise)?u.then(function(){return _revive("",e,null)}):_revive("",e,null))?r&&t.throwOnBadSyncType?function(){throw new TypeError("Sync method requested but async result obtained")}():hasConstructorOf(c,TypesonPromise)?c.p.then(checkUndefined):c:!r&&t.throwOnBadSyncType?function(){throw new TypeError("Async method requested but sync result obtained")}():r?checkUndefined(c):Promise.resolve(checkUndefined(c))}},{key:"reviveSync",value:function reviveSync(e,t){return this.revive(e,_objectSpread({throwOnBadSyncType:!0},t,{sync:!0}))}},{key:"reviveAsync",value:function reviveAsync(e,t){return this.revive(e,_objectSpread({throwOnBadSyncType:!0},t,{sync:!1}))}},{key:"register",value:function register(e,t){return t=t||{},[].concat(e).forEach(function R(e){if(isArray(e))return e.map(R,this);e&&keys(e).forEach(function(n){if("#"===n)throw new TypeError("# cannot be used as a type name as it is reserved for cyclic objects");if(Typeson.JSON_TYPES.includes(n))throw new TypeError("Plain JSON object types are reserved as type names");var r=e[n],o=r.testPlainObjects?this.plainObjectReplacers:this.nonplainObjectReplacers,i=o.filter(function(e){return e.type===n});if(i.length&&(o.splice(o.indexOf(i[0]),1),delete this.revivers[n],delete this.types[n]),r){if("function"==typeof r){var a=r;r={test:function test(e){return e&&e.constructor===a},replace:function replace(e){return Object.assign({},e)},revive:function revive(e){return Object.assign(Object.create(a.prototype),e)}}}else if(isArray(r)){var s=_slicedToArray(r,3);r={test:s[0],replace:s[1],revive:s[2]}}var c={type:n,test:r.test.bind(r)};r.replace&&(c.replace=r.replace.bind(r)),r.replaceAsync&&(c.replaceAsync=r.replaceAsync.bind(r));var u="number"==typeof t.fallback?t.fallback:t.fallback?0:1/0;if(r.testPlainObjects?this.plainObjectReplacers.splice(u,0,c):this.nonplainObjectReplacers.splice(u,0,c),r.revive||r.reviveAsync){var y={};r.revive&&(y.revive=r.revive.bind(r)),r.reviveAsync&&(y.reviveAsync=r.reviveAsync.bind(r)),this.revivers[n]=[y,{plain:r.testPlainObjects}]}this.types[n]=r}},this)},this),this}}]),Typeson}(),Undefined=function Undefined(){_classCallCheck(this,Undefined)};Typeson.Undefined=Undefined,Typeson.Promise=TypesonPromise,Typeson.isThenable=isThenable,Typeson.toStringTag=toStringTag,Typeson.hasConstructorOf=hasConstructorOf,Typeson.isObject=isObject,Typeson.isPlainObject=isPlainObject,Typeson.isUserObject=isUserObject,Typeson.escapeKeyPathComponent=escapeKeyPathComponent,Typeson.unescapeKeyPathComponent=unescapeKeyPathComponent,Typeson.getByKeyPath=getByKeyPath,Typeson.getJSONType=getJSONType,Typeson.JSON_TYPES=["null","boolean","number","string","array","object"],module.exports=Typeson;
'use strict';
function _typeof(obj) {
if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
_typeof = function (obj) {
return typeof obj;
};
} else {
_typeof = function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};
}
return _typeof(obj);
}
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
try {
var info = gen[key](arg);
var value = info.value;
} catch (error) {
reject(error);
return;
}
if (info.done) {
resolve(value);
} else {
Promise.resolve(value).then(_next, _throw);
}
}
function _asyncToGenerator(fn) {
return function () {
var self = this,
args = arguments;
return new Promise(function (resolve, reject) {
var gen = fn.apply(self, args);
function _next(value) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
}
function _throw(err) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
}
_next(undefined);
});
};
}
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a 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);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function _objectSpread(target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i] != null ? arguments[i] : {};
var ownKeys = Object.keys(source);
if (typeof Object.getOwnPropertySymbols === 'function') {
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) {
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
}));
}
ownKeys.forEach(function (key) {
_defineProperty(target, key, source[key]);
});
}
return target;
}
function _slicedToArray(arr, i) {
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest();
}
function _toConsumableArray(arr) {
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();
}
function _arrayWithoutHoles(arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
return arr2;
}
}
function _arrayWithHoles(arr) {
if (Array.isArray(arr)) return arr;
}
function _iterableToArray(iter) {
if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
}
function _iterableToArrayLimit(arr, i) {
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
try {
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"] != null) _i["return"]();
} finally {
if (_d) throw _e;
}
}
return _arr;
}
function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance");
}
function _nonIterableRest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
/**
* We keep this function minimized so if using two instances of this
* library, where one is minimized and one is not, it will still work
* with `hasConstructorOf`.
* With ES6 classes, we may be able to simply use `class TypesonPromise
* extends Promise` and add a string tag for detection
* @param {function} f
*/
var TypesonPromise = function TypesonPromise(f) {
_classCallCheck(this, TypesonPromise);
this.p = new Promise(f);
}; // eslint-disable-line block-spacing, space-before-function-paren, space-before-blocks, space-infix-ops, semi
// class TypesonPromise extends Promise {get[Symbol.toStringTag](){return 'TypesonPromise'};} // eslint-disable-line keyword-spacing, space-before-function-paren, space-before-blocks, block-spacing, semi
// Note: core-js-bundle provides a `Symbol` polyfill
if (typeof Symbol !== 'undefined') {
// Ensure `isUserObject` will return `false` for `TypesonPromise`
TypesonPromise.prototype[Symbol.toStringTag] = 'TypesonPromise';
}
/**
*
* @param {function} [onFulfilled]
* @param {function} [onRejected]
* @returns {TypesonPromise}
*/
TypesonPromise.prototype.then = function (onFulfilled, onRejected) {
var _this = this;
return new TypesonPromise(function (typesonResolve, typesonReject) {
_this.p.then(function (res) {
typesonResolve(onFulfilled ? onFulfilled(res) : res);
}, function (r) {
_this.p['catch'](function (res) {
return onRejected ? onRejected(res) : Promise.reject(res);
}).then(typesonResolve, typesonReject);
});
});
};
/**
*
* @param {function} onRejected
* @returns {TypesonPromise}
*/
TypesonPromise.prototype["catch"] = function (onRejected) {
return this.then(null, onRejected);
};
/**
*
* @param {} v
* @returns {TypesonPromise}
*/
TypesonPromise.resolve = function (v) {
return new TypesonPromise(function (typesonResolve) {
typesonResolve(v);
});
};
/**
*
* @param {} v
* @returns {TypesonPromise}
*/
TypesonPromise.reject = function (v) {
return new TypesonPromise(function (typesonResolve, typesonReject) {
typesonReject(v);
});
};
['all', 'race'].map(function (meth) {
/**
*
* @param {Promise[]} promArr
* @returns {TypesonPromise}
*/
TypesonPromise[meth] = function (promArr) {
return new TypesonPromise(function (typesonResolve, typesonReject) {
Promise[meth](promArr.map(function (prom) {
return prom.p;
})).then(typesonResolve, typesonReject);
});
};
});
var _ref = {},
toString = _ref.toString,
hasOwn = {}.hasOwnProperty,
getProto = Object.getPrototypeOf,
fnToString = hasOwn.toString;
/**
*
* @param {*} v
* @param {boolean} catchCheck
* @returns {boolean}
*/
function isThenable(v, catchCheck) {
return isObject(v) && typeof v.then === 'function' && (!catchCheck || typeof v["catch"] === 'function');
}
/**
*
* @param {*} val
* @returns {string}
*/
function toStringTag(val) {
return toString.call(val).slice(8, -1);
}
/**
* This function is dependent on both constructors
* being identical so any minimization is expected of both.
* @param {*} a
* @param {function} b
* @returns {boolean}
*/
function hasConstructorOf(a, b) {
if (!a || _typeof(a) !== 'object') {
return false;
}
var proto = getProto(a);
if (!proto) {
return false;
}
var Ctor = hasOwn.call(proto, 'constructor') && proto.constructor;
if (typeof Ctor !== 'function') {
return b === null;
}
return typeof Ctor === 'function' && b !== null && fnToString.call(Ctor) === fnToString.call(b);
}
/**
*
* @param {*} val
* @returns {boolean}
*/
function isPlainObject(val) {
// Mirrors jQuery's
if (!val || toStringTag(val) !== 'Object') {
return false;
}
var proto = getProto(val);
if (!proto) {
// `Object.create(null)`
return true;
}
return hasConstructorOf(val, Object);
}
/**
*
* @param {*} val
* @returns {boolean}
*/
function isUserObject(val) {
if (!val || toStringTag(val) !== 'Object') {
return false;
}
var proto = getProto(val);
if (!proto) {
// `Object.create(null)`
return true;
}
return hasConstructorOf(val, Object) || isUserObject(proto);
}
/**
*
* @param {*} v
* @returns {boolean}
*/
function isObject(v) {
return v && _typeof(v) === 'object';
}
/**
*
* @param {string} keyPathComponent
* @returns {string}
*/
function escapeKeyPathComponent(keyPathComponent) {
return keyPathComponent.replace(/~/g, '~0').replace(/\./g, '~1');
}
/**
*
* @param {string} keyPathComponent
* @returns {string}
*/
function unescapeKeyPathComponent(keyPathComponent) {
return keyPathComponent.replace(/~1/g, '.').replace(/~0/g, '~');
}
/**
* @param {object|array} obj
* @param {string} keyPath
* @returns {*}
*/
function getByKeyPath(obj, keyPath) {
if (keyPath === '') {
return obj;
}
var period = keyPath.indexOf('.');
if (period > -1) {
var innerObj = obj[unescapeKeyPathComponent(keyPath.substr(0, period))];
return innerObj === undefined ? undefined : getByKeyPath(innerObj, keyPath.substr(period + 1));
}
return obj[unescapeKeyPathComponent(keyPath)];
}
function setAtKeyPath(obj, keyPath, value) {
if (keyPath === '') {
return value;
}
var period = keyPath.indexOf('.');
if (period > -1) {
var innerObj = obj[unescapeKeyPathComponent(keyPath.substr(0, period))];
return setAtKeyPath(innerObj, keyPath.substr(period + 1), value);
}
obj[unescapeKeyPathComponent(keyPath)] = value;
return obj;
}
/**
*
* @param {external:JSON} value
* @returns {"null"|"array"|"undefined"|"boolean"|"number"|"string"|"object"|"symbol"}
*/
function getJSONType(value) {
return value === null ? 'null' : Array.isArray(value) ? 'array' : _typeof(value);
}
var keys = Object.keys,
isArray = Array.isArray,
hasOwn$1 = {}.hasOwnProperty,
internalStateObjPropsToIgnore = ['type', 'replaced', 'iterateIn', 'iterateUnsetNumeric'];
function nestedPathsFirst(a, b) {
var as = a.keypath.match(/\./g);
var bs = a.keypath.match(/\./g);
if (as) {
as = as.length;
}
if (bs) {
bs = bs.length;
}
return as > bs ? -1 : as < bs ? 1 : a.keypath < b.keypath ? -1 : a.keypath > b.keypath;
}
/**
* An instance of this class can be used to call `stringify()` and `parse()`.
* Typeson resolves cyclic references by default. Can also be extended to
* support custom types using the register() method.
*
* @constructor
* @param {{cyclic: boolean}} [options] - if cyclic (default true),
* cyclic references will be handled gracefully.
*/
var Typeson =
/*#__PURE__*/
function () {
function Typeson(options) {
_classCallCheck(this, Typeson);
this.options = options; // Replacers signature: replace (value). Returns falsy if not
// replacing. Otherwise ['Date', value.getTime()]
this.plainObjectReplacers = [];
this.nonplainObjectReplacers = []; // Revivers: [{type => reviver}, {plain: boolean}].
// Sample: [{'Date': value => new Date(value)}, {plain: false}]
this.revivers = {};
/** Types registered via register() */
this.types = {};
}
/**
* Serialize given object to Typeson.
* Initial arguments work identical to those of `JSON.stringify`.
* The `replacer` argument has nothing to do with our replacers.
* @param {*} obj
* @param {function|string[]} replacer
* @param {number|string} space
* @param {object} opts
* @returns {string|Promise} Promise resolves to a string
*/
_createClass(Typeson, [{
key: "stringify",
value: function stringify(obj, replacer, space, opts) {
opts = _objectSpread({}, this.options, opts, {
stringification: true
});
var encapsulated = this.encapsulate(obj, null, opts);
if (isArray(encapsulated)) {
return JSON.stringify(encapsulated[0], replacer, space);
}
return encapsulated.then(function (res) {
return JSON.stringify(res, replacer, space);
});
}
/**
* Also sync but throws on non-sync result
* @param {*} obj
* @param {function|string[]} replacer
* @param {number|string} space
* @param {object} opts
* @returns {string}
*/
}, {
key: "stringifySync",
value: function stringifySync(obj, replacer, space, opts) {
return this.stringify(obj, replacer, space, _objectSpread({
throwOnBadSyncType: true
}, opts, {
sync: true
}));
}
/**
*
* @param {*} obj
* @param {function|string[]} replacer
* @param {number|string} space
* @param {object} opts
* @returns {Promise} Resolves to string
*/
}, {
key: "stringifyAsync",
value: function stringifyAsync(obj, replacer, space, opts) {
return this.stringify(obj, replacer, space, _objectSpread({
throwOnBadSyncType: true
}, opts, {
sync: false
}));
}
/**
* Parse Typeson back into an obejct.
* Initial arguments works identical to those of `JSON.parse()`.
* @param {string} text
* @param {function} reviver This JSON reviver has nothing to do with
* our revivers.
* @param {object} opts
* @returns {external:JSON}
*/
}, {
key: "parse",
value: function parse(text, reviver, opts) {
opts = _objectSpread({}, this.options, opts, {
parse: true
});
return this.revive(JSON.parse(text, reviver), opts);
}
/**
* Also sync but throws on non-sync result
* @param {string} text
* @param {function} reviver This JSON reviver has nothing to do with
* our revivers.
* @param {object} opts
* @returns {external:JSON}
*/
}, {
key: "parseSync",
value: function parseSync(text, reviver, opts) {
return this.parse(text, reviver, _objectSpread({
throwOnBadSyncType: true
}, opts, {
sync: true
}));
}
/**
* @param {string} text
* @param {function} reviver This JSON reviver has nothing to do with
* our revivers.
* @param {object} opts
* @returns {Promise} Resolves to `external:JSON`
*/
}, {
key: "parseAsync",
value: function parseAsync(text, reviver, opts) {
return this.parse(text, reviver, _objectSpread({
throwOnBadSyncType: true
}, opts, {
sync: false
}));
}
/**
*
* @param {*} obj
* @param {object} stateObj
* @param {object} [opts={}]
* @returns {string[]|false}
*/
}, {
key: "specialTypeNames",
value: function specialTypeNames(obj, stateObj) {
var opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
opts.returnTypeNames = true;
return this.encapsulate(obj, stateObj, opts);
}
/**
*
* @param {*} obj
* @param {object} stateObj
* @param {object} [opts={}]
* @returns {Promise|Array|object|string|false}
*/
}, {
key: "rootTypeName",
value: function rootTypeName(obj, stateObj) {
var opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
opts.iterateNone = true;
return this.encapsulate(obj, stateObj, opts);
}
/**
* Encapsulate a complex object into a plain Object by replacing
* registered types with plain objects representing the types data.
*
* This method is used internally by T`ypeson.stringify()`.
* @param {Object} obj - Object to encapsulate.
* @param {object} stateObj
* @param {object} opts
* @returns {Promise|Array|object|string|false}
*/
}, {
key: "encapsulate",
value: function encapsulate(obj, stateObj, opts) {
opts = _objectSpread({
sync: true
}, this.options, opts);
var _opts = opts,
sync = _opts.sync;
var that = this,
types = {},
refObjs = [],
// For checking cyclic references
refKeys = [],
// For checking cyclic references
promisesDataRoot = []; // Clone the object deeply while at the same time replacing any
// special types or cyclic reference:
var cyclic = 'cyclic' in opts ? opts.cyclic : true;
var _opts2 = opts,
encapsulateObserver = _opts2.encapsulateObserver;
var ret = _encapsulate('', obj, cyclic, stateObj || {}, promisesDataRoot);
/**
*
* @param {*} ret
* @returns {Array|object|string|false}
*/
function finish(ret) {
// Add `$types` to result only if we ever bumped into a
// special type (or special case where object has own `$types`)
var typeNames = Object.values(types);
if (opts.iterateNone) {
if (typeNames.length) {
return typeNames[0];
}
return Typeson.getJSONType(ret);
}
if (typeNames.length) {
if (opts.returnTypeNames) {
return _toConsumableArray(new Set(typeNames));
} // Special if array (or a primitive) was serialized
// because JSON would ignore custom `$types` prop on it
if (!ret || !isPlainObject(ret) || // Also need to handle if this is an object with its
// own `$types` property (to avoid ambiguity)
hasOwn$1.call(ret, '$types')) {
ret = {
$: ret,
$types: {
$: types
}
};
} else {
ret.$types = types;
} // No special types
} else if (isObject(ret) && hasOwn$1.call(ret, '$types')) {
ret = {
$: ret,
$types: true
};
}
if (opts.returnTypeNames) {
return false;
}
return ret;
}
/**
*
* @param {*} ret
* @param {array} promisesData
* @returns {Promise} Resolves to ...
*/
function checkPromises(_x, _x2) {
return _checkPromises.apply(this, arguments);
}
/**
*
* @param {object} stateObj
* @param {object} ownKeysObj
* @param {function} cb
* @returns {undefined}
*/
function _checkPromises() {
_checkPromises = _asyncToGenerator(
/*#__PURE__*/
regeneratorRuntime.mark(function _callee2(ret, promisesData) {
var promResults;
return regeneratorRuntime.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
_context2.next = 2;
return Promise.all(promisesData.map(function (pd) {
return pd[1].p;
}));
case 2:
promResults = _context2.sent;
_context2.next = 5;
return Promise.all(promResults.map(
/*#__PURE__*/
function () {
var _ref = _asyncToGenerator(
/*#__PURE__*/
regeneratorRuntime.mark(function _callee(promResult) {
var newPromisesData, _promisesData$splice, _promisesData$splice2, prData, _prData, keyPath, cyclic, stateObj, parentObj, key, detectedType, encaps, isTypesonPromise, encaps2;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
newPromisesData = [];
_promisesData$splice = promisesData.splice(0, 1), _promisesData$splice2 = _slicedToArray(_promisesData$splice, 1), prData = _promisesData$splice2[0];
_prData = _slicedToArray(prData, 7), keyPath = _prData[0], cyclic = _prData[2], stateObj = _prData[3], parentObj = _prData[4], key = _prData[5], detectedType = _prData[6];
encaps = _encapsulate(keyPath, promResult, cyclic, stateObj, newPromisesData, true, detectedType);
isTypesonPromise = hasConstructorOf(encaps, TypesonPromise); // Handle case where an embedded custom type itself
// returns a `Typeson.Promise`
if (!(keyPath && isTypesonPromise)) {
_context.next = 11;
break;
}
_context.next = 8;
return encaps.p;
case 8:
encaps2 = _context.sent;
parentObj[key] = encaps2;
return _context.abrupt("return", checkPromises(ret, newPromisesData));
case 11:
if (keyPath) {
parentObj[key] = encaps;
} else if (isTypesonPromise) {
ret = encaps.p;
} else {
// If this is itself a `Typeson.Promise` (because the
// original value supplied was a `Promise` or
// because the supplied custom type value resolved
// to one), returning it below will be fine since
// a `Promise` is expected anyways given current
// config (and if not a `Promise`, it will be ready
// as the resolve value)
ret = encaps;
}
return _context.abrupt("return", checkPromises(ret, newPromisesData));
case 13:
case "end":
return _context.stop();
}
}
}, _callee);
}));
return function (_x3) {
return _ref.apply(this, arguments);
};
}()));
case 5:
return _context2.abrupt("return", ret);
case 6:
case "end":
return _context2.stop();
}
}
}, _callee2);
}));
return _checkPromises.apply(this, arguments);
}
function _adaptBuiltinStateObjectProperties(stateObj, ownKeysObj, cb) {
Object.assign(stateObj, ownKeysObj);
var vals = internalStateObjPropsToIgnore.map(function (prop) {
var tmp = stateObj[prop];
delete stateObj[prop];
return tmp;
});
cb();
internalStateObjPropsToIgnore.forEach(function (prop, i) {
stateObj[prop] = vals[i];
});
}
/**
*
* @param {string} keypath
* @param {*} value
* @param {boolean} cyclic
* @param {object} stateObj
* @param {boolean} promisesData
* @param {boolean} resolvingTypesonPromise
* @param {string} detectedType
* @returns {*}
*/
function _encapsulate(keypath, value, cyclic, stateObj, promisesData, resolvingTypesonPromise, detectedType) {
var ret;
var observerData = {};
var $typeof = _typeof(value);
var runObserver = encapsulateObserver ? function (obj) {
var type = detectedType || stateObj.type || Typeson.getJSONType(value);
encapsulateObserver(Object.assign(obj || observerData, {
keypath: keypath,
value: value,
cyclic: cyclic,
stateObj: stateObj,
promisesData: promisesData,
resolvingTypesonPromise: resolvingTypesonPromise,
awaitingTypesonPromise: hasConstructorOf(value, TypesonPromise)
}, type !== undefined ? {
type: type
} : {}));
} : null;
if (['string', 'boolean', 'number', 'undefined'].includes($typeof)) {
if (value === undefined || $typeof === 'number' && (isNaN(value) || value === -Infinity || value === Infinity)) {
ret = replace(keypath, value, stateObj, promisesData, false, resolvingTypesonPromise, runObserver);
if (ret !== value) {
observerData = {
replaced: ret
};
}
} else {
ret = value;
}
if (runObserver) {
runObserver();
}
return ret;
}
if (value === null) {
if (runObserver) {
runObserver();
}
return value;
}
if (cyclic && !stateObj.iterateIn && !stateObj.iterateUnsetNumeric) {
// Options set to detect cyclic references and be able
// to rewrite them.
var refIndex = refObjs.indexOf(value);
if (refIndex < 0) {
if (cyclic === true) {
refObjs.push(value);
refKeys.push(keypath);
}
} else {
types[keypath] = '#';
if (runObserver) {
runObserver({
cyclicKeypath: refKeys[refIndex]
});
}
return '#' + refKeys[refIndex];
}
}
var isPlainObj = isPlainObject(value);
var isArr = isArray(value);
var replaced = // Running replace will cause infinite loop as will test
// positive again
(isPlainObj || isArr) && (!that.plainObjectReplacers.length || stateObj.replaced) || stateObj.iterateIn ? // Optimization: if plain object and no plain-object
// replacers, don't try finding a replacer
value : replace(keypath, value, stateObj, promisesData, isPlainObj || isArr, null, runObserver);
var clone;
if (replaced !== value) {
ret = replaced;
observerData = {
replaced: replaced
};
} else {
if (isArr && stateObj.iterateIn !== 'object' || stateObj.iterateIn === 'array') {
clone = new Array(value.length);
observerData = {
clone: clone
};
} else if (isPlainObj || stateObj.iterateIn === 'object') {
clone = {};
if (stateObj.addLength) {
clone.length = value.length;
}
observerData = {
clone: clone
};
} else if (keypath === '' && hasConstructorOf(value, TypesonPromise)) {
promisesData.push([keypath, value, cyclic, stateObj, undefined, undefined, stateObj.type]);
ret = value;
} else {
ret = value; // Only clone vanilla objects and arrays
}
}
if (runObserver) {
runObserver();
}
if (opts.iterateNone) {
return clone || ret;
}
if (!clone) {
return ret;
} // Iterate object or array
if (stateObj.iterateIn) {
var _loop = function _loop(key) {
var ownKeysObj = {
ownKeys: hasOwn$1.call(value, key)
};
_adaptBuiltinStateObjectProperties(stateObj, ownKeysObj, function () {
var kp = keypath + (keypath ? '.' : '') + escapeKeyPathComponent(key);
var val = _encapsulate(kp, value[key], !!cyclic, stateObj, promisesData, resolvingTypesonPromise);
if (hasConstructorOf(val, TypesonPromise)) {
promisesData.push([kp, val, !!cyclic, stateObj, clone, key, stateObj.type]);
} else if (val !== undefined) {
clone[key] = val;
}
});
};
for (var key in value) {
_loop(key);
}
if (runObserver) {
runObserver({
endIterateIn: true,
end: true
});
}
} else {
// Note: Non-indexes on arrays won't survive stringify so
// somewhat wasteful for arrays, but so too is iterating
// all numeric indexes on sparse arrays when not wanted
// or filtering own keys for positive integers
keys(value).forEach(function (key) {
var kp = keypath + (keypath ? '.' : '') + escapeKeyPathComponent(key);
var ownKeysObj = {
ownKeys: true
};
_adaptBuiltinStateObjectProperties(stateObj, ownKeysObj, function () {
var val = _encapsulate(kp, value[key], !!cyclic, stateObj, promisesData, resolvingTypesonPromise);
if (hasConstructorOf(val, TypesonPromise)) {
promisesData.push([kp, val, !!cyclic, stateObj, clone, key, stateObj.type]);
} else if (val !== undefined) {
clone[key] = val;
}
});
});
if (runObserver) {
runObserver({
endIterateOwn: true,
end: true
});
}
} // Iterate array for non-own numeric properties (we can't
// replace the prior loop though as it iterates non-integer
// keys)
if (stateObj.iterateUnsetNumeric) {
var vl = value.length;
var _loop2 = function _loop2(i) {
if (!(i in value)) {
// No need to escape numeric
var kp = keypath + (keypath ? '.' : '') + i;
var ownKeysObj = {
ownKeys: false
};
_adaptBuiltinStateObjectProperties(stateObj, ownKeysObj, function () {
var val = _encapsulate(kp, undefined, !!cyclic, stateObj, promisesData, resolvingTypesonPromise);
if (hasConstructorOf(val, TypesonPromise)) {
promisesData.push([kp, val, !!cyclic, stateObj, clone, i, stateObj.type]);
} else if (val !== undefined) {
clone[i] = val;
}
});
}
};
for (var i = 0; i < vl; i++) {
_loop2(i);
}
if (runObserver) {
runObserver({
endIterateUnsetNumeric: true,
end: true
});
}
}
return clone;
}
/**
*
* @param {string} keypath
* @param {*} value
* @param {object} stateObj
* @param {array} promisesData
* @param {boolean} plainObject
* @param {boolean} resolvingTypesonPromise
* @param {function} [runObserver]
* @returns {*}
*/
function replace(keypath, value, stateObj, promisesData, plainObject, resolvingTypesonPromise, runObserver) {
// Encapsulate registered types
var replacers = plainObject ? that.plainObjectReplacers : that.nonplainObjectReplacers;
var i = replacers.length;
while (i--) {
var replacer = replacers[i];
if (replacer.test(value, stateObj)) {
var type = replacer.type;
if (that.revivers[type]) {
// Record the type only if a corresponding reviver
// exists. This is to support specs where only
// replacement is done.
// For example, ensuring deep cloning of the object,
// or replacing a type to its equivalent without
// the need to revive it.
var existing = types[keypath]; // type can comprise an array of types (see test
// `shouldSupportIntermediateTypes`)
types[keypath] = existing ? [type].concat(existing) : type;
} // Now, also traverse the result in case it contains its
// own types to replace
Object.assign(stateObj, {
type: type,
replaced: true
});
if ((sync || !replacer.replaceAsync) && !replacer.replace) {
if (runObserver) {
runObserver({
typeDetected: true
});
}
return _encapsulate(keypath, value, cyclic && 'readonly', stateObj, promisesData, resolvingTypesonPromise, type);
}
if (runObserver) {
runObserver({
replacing: true
});
}
var replaceMethod = sync || !replacer.replaceAsync ? 'replace' : 'replaceAsync';
return _encapsulate(keypath, replacer[replaceMethod](value, stateObj), cyclic && 'readonly', stateObj, promisesData, resolvingTypesonPromise, type);
}
}
return value;
}
return promisesDataRoot.length ? sync && opts.throwOnBadSyncType ? function () {
throw new TypeError('Sync method requested but async result obtained');
}() : Promise.resolve(checkPromises(ret, promisesDataRoot)).then(finish) : !sync && opts.throwOnBadSyncType ? function () {
throw new TypeError('Async method requested but sync result obtained');
}() // If this is a synchronous request for stringification, yet
// a promise is the result, we don't want to resolve leading
// to an async result, so we return an array to avoid
// ambiguity
: opts.stringification && sync ? [finish(ret)] : sync ? finish(ret) : Promise.resolve(finish(ret));
}
/**
* Also sync but throws on non-sync result
* @param {*} obj
* @param {object} stateObj
* @param {object} opts
* @returns {*}
*/
}, {
key: "encapsulateSync",
value: function encapsulateSync(obj, stateObj, opts) {
return this.encapsulate(obj, stateObj, _objectSpread({
throwOnBadSyncType: true
}, opts, {
sync: true
}));
}
/**
* @param {*} obj
* @param {object} stateObj
* @param {object} opts
* @returns {*}
*/
}, {
key: "encapsulateAsync",
value: function encapsulateAsync(obj, stateObj, opts) {
return this.encapsulate(obj, stateObj, _objectSpread({
throwOnBadSyncType: true
}, opts, {
sync: false
}));
}
/**
* Revive an encapsulated object.
* This method is used internally by `Typeson.parse()`.
* @param {object} obj - Object to revive. If it has `$types` member, the
* properties that are listed there will be replaced with its true type
* instead of just plain objects.
* @param {object} opts
* @throws TypeError If mismatch between sync/async type and result
* @returns {Promise|*} If async, returns a Promise that resolves to `*`
*/
}, {
key: "revive",
value: function revive(obj, opts) {
var types = obj && obj.$types; // No type info added. Revival not needed.
if (!types) {
return obj;
} // Object happened to have own `$types` property but with
// no actual types, so we unescape and return that object
if (types === true) {
return obj.$;
}
opts = _objectSpread({
sync: true
}, this.options, opts);
var _opts3 = opts,
sync = _opts3.sync;
var keyPathResolutions = [];
var stateObj = {};
var ignore$Types = true; // Special when root object is not a trivial Object, it will
// be encapsulated in `$`. It will also be encapsulated in
// `$` if it has its own `$` property to avoid ambiguity
if (types.$ && isPlainObject(types.$)) {
obj = obj.$;
types = types.$;
ignore$Types = false;
}
var that = this;
function revivePlainObjects() {
// const references = [];
// const reviveTypes = [];
var plainObjectTypes = [];
Object.entries(types).forEach(function (_ref2) {
var _ref3 = _slicedToArray(_ref2, 2),
keypath = _ref3[0],
type = _ref3[1];
if (type === '#') {
/*
references.push({
keypath,
reference: getByKeyPath(obj, keypath)
});
*/
return;
}
[].concat(type).forEach(function (type) {
var _that$revivers$type = _slicedToArray(that.revivers[type], 2),
plain = _that$revivers$type[1].plain;
if (!plain) {
// reviveTypes.push({keypath, type});
return;
}
plainObjectTypes.push({
keypath: keypath,
type: type
});
delete types[keypath]; // Avoid repeating
});
});
if (!plainObjectTypes.length) {
return;
} // Handle plain object revivers first so reference
// setting can use revived type (e.g., array instead
// of object); assumes revived has same structure
// or will otherwise break subsequent references
return plainObjectTypes.sort(nestedPathsFirst).reduce(function reducer(possibleTypesonPromise, _ref4) {
var keypath = _ref4.keypath,
type = _ref4.type;
if (hasConstructorOf(possibleTypesonPromise, TypesonPromise)) {
// TypesonPromise here too
return possibleTypesonPromise.then(function (v) {
return reducer(v, type);
});
}
var val = getByKeyPath(obj, keypath);
if (hasConstructorOf(val, TypesonPromise)) {
return val.then(function (v) {
// TypesonPromise here too
return reducer(v, type);
});
}
var _that$revivers$type2 = _slicedToArray(that.revivers[type], 1),
reviver = _that$revivers$type2[0];
if (!reviver) {
throw new Error('Unregistered type: ' + type);
}
val = reviver[sync && reviver.revive ? 'revive' : !sync && reviver.reviveAsync ? 'reviveAsync' : 'revive'](val, stateObj);
if (val === undefined) {
return undefined;
}
if (hasConstructorOf(val, Undefined)) {
val = undefined;
}
var newVal = setAtKeyPath(obj, keypath, val);
if (newVal === val) {
obj = val;
}
return undefined;
}, undefined // This argument must be explicit
); // references.forEach(({keypath, reference}) => {});
// reviveTypes.sort(nestedPathsFirst).forEach(() => {});
}
/**
*
* @param {string} keypath
* @param {*} value
* @param {?(Array|object)} target
* @param {Array|object} [clone]
* @param {string} [key]
* @returns {*}
*/
function _revive(keypath, value, target, clone, key) {
if (ignore$Types && keypath === '$types') {
return undefined;
}
var type = types[keypath];
if (isArray(value) || isPlainObject(value)) {
var _clone = isArray(value) ? new Array(value.length) : {}; // Iterate object or array
keys(value).forEach(function (k) {
var val = _revive(keypath + (keypath ? '.' : '') + escapeKeyPathComponent(k), value[k], target || _clone, _clone, k);
if (hasConstructorOf(val, Undefined)) {
_clone[k] = undefined;
} else if (val !== undefined) {
_clone[k] = val;
}
});
value = _clone; // Try to resolve cyclic reference as soon as available
while (keyPathResolutions.length) {
var _keyPathResolutions$ = _slicedToArray(keyPathResolutions[0], 4),
_target = _keyPathResolutions$[0],
keyPath = _keyPathResolutions$[1],
_clone2 = _keyPathResolutions$[2],
k = _keyPathResolutions$[3];
var val = getByKeyPath(_target, keyPath);
if (hasConstructorOf(val, Undefined)) {
_clone2[k] = undefined;
} else if (val !== undefined) {
_clone2[k] = val;
} else {
break;
}
keyPathResolutions.splice(0, 1);
}
}
if (!type) {
return value;
}
if (type === '#') {
var _ret = getByKeyPath(target, value.slice(1));
if (_ret === undefined) {
// Cyclic reference not yet available
keyPathResolutions.push([target, value.slice(1), clone, key]);
}
return _ret;
}
return [].concat(type).reduce(function reducer(val, type) {
if (hasConstructorOf(val, TypesonPromise)) {
return val.then(function (v) {
// TypesonPromise here too
return reducer(v, type);
});
}
var _that$revivers$type3 = _slicedToArray(that.revivers[type], 1),
reviver = _that$revivers$type3[0];
if (!reviver) {
throw new Error('Unregistered type: ' + type);
}
return reviver[sync && reviver.revive ? 'revive' : !sync && reviver.reviveAsync ? 'reviveAsync' : 'revive'](val, stateObj);
}, value);
}
function checkUndefined(retrn) {
return hasConstructorOf(retrn, Undefined) ? undefined : retrn;
}
var possibleTypesonPromise = revivePlainObjects();
var ret;
if (hasConstructorOf(possibleTypesonPromise, TypesonPromise)) {
ret = possibleTypesonPromise.then(function () {
return _revive('', obj, null);
});
} else {
ret = _revive('', obj, null);
}
return isThenable(ret) ? sync && opts.throwOnBadSyncType ? function () {
throw new TypeError('Sync method requested but async result obtained');
}() : hasConstructorOf(ret, TypesonPromise) ? ret.p.then(checkUndefined) : ret : !sync && opts.throwOnBadSyncType ? function () {
throw new TypeError('Async method requested but sync result obtained');
}() : sync ? checkUndefined(ret) : Promise.resolve(checkUndefined(ret));
}
/**
* Also sync but throws on non-sync result
* @param {*} obj
* @param {object} opts
* @returns {*}
*/
}, {
key: "reviveSync",
value: function reviveSync(obj, opts) {
return this.revive(obj, _objectSpread({
throwOnBadSyncType: true
}, opts, {
sync: true
}));
}
/**
* @param {*} obj
* @param {object} opts
* @returns {Promise} Resolves to `*`
*/
}, {
key: "reviveAsync",
value: function reviveAsync(obj, opts) {
return this.revive(obj, _objectSpread({
throwOnBadSyncType: true
}, opts, {
sync: false
}));
}
/**
* Register types.
* For examples on how to use this method, see
* {@link https://github.com/dfahlander/typeson-registry/tree/master/types}
* @param {Array.<Object.<string,Function[]>>} typeSpecSets - Types and
* their functions [test, encapsulate, revive];
* @param {object} opts
* @returns {Typeson}
*/
}, {
key: "register",
value: function register(typeSpecSets, opts) {
opts = opts || {};
[].concat(typeSpecSets).forEach(function R(typeSpec) {
// Allow arrays of arrays of arrays...
if (isArray(typeSpec)) {
return typeSpec.map(R, this);
}
typeSpec && keys(typeSpec).forEach(function (typeId) {
if (typeId === '#') {
throw new TypeError('# cannot be used as a type name as it is reserved ' + 'for cyclic objects');
} else if (Typeson.JSON_TYPES.includes(typeId)) {
throw new TypeError('Plain JSON object types are reserved as type names');
}
var spec = typeSpec[typeId];
var replacers = spec.testPlainObjects ? this.plainObjectReplacers : this.nonplainObjectReplacers;
var existingReplacer = replacers.filter(function (r) {
return r.type === typeId;
});
if (existingReplacer.length) {
// Remove existing spec and replace with this one.
replacers.splice(replacers.indexOf(existingReplacer[0]), 1);
delete this.revivers[typeId];
delete this.types[typeId];
}
if (!spec) {
return;
}
if (typeof spec === 'function') {
// Support registering just a class without replacer/reviver
var Class = spec;
spec = {
test: function test(x) {
return x && x.constructor === Class;
},
replace: function replace(x) {
return Object.assign({}, x);
},
revive: function revive(x) {
return Object.assign(Object.create(Class.prototype), x);
}
};
} else if (isArray(spec)) {
var _spec = spec,
_spec2 = _slicedToArray(_spec, 3),
test = _spec2[0],
replace = _spec2[1],
revive = _spec2[2];
spec = {
test: test,
replace: replace,
revive: revive
};
}
var replacerObj = {
type: typeId,
test: spec.test.bind(spec)
};
if (spec.replace) {
replacerObj.replace = spec.replace.bind(spec);
}
if (spec.replaceAsync) {
replacerObj.replaceAsync = spec.replaceAsync.bind(spec);
}
var start = typeof opts.fallback === 'number' ? opts.fallback : opts.fallback ? 0 : Infinity;
if (spec.testPlainObjects) {
this.plainObjectReplacers.splice(start, 0, replacerObj);
} else {
this.nonplainObjectReplacers.splice(start, 0, replacerObj);
} // Todo: We might consider a testAsync type
if (spec.revive || spec.reviveAsync) {
var reviverObj = {};
if (spec.revive) {
reviverObj.revive = spec.revive.bind(spec);
}
if (spec.reviveAsync) {
reviverObj.reviveAsync = spec.reviveAsync.bind(spec);
}
this.revivers[typeId] = [reviverObj, {
plain: spec.testPlainObjects
}];
} // Record to be retrieved via public types property.
this.types[typeId] = spec;
}, this);
}, this);
return this;
}
}]);
return Typeson;
}();
/**
* We keep this function minimized so if using two instances of this
* library, where one is minimized and one is not, it will still work
* with `hasConstructorOf`.
* @constructor
*/
var Undefined = function Undefined() {
_classCallCheck(this, Undefined);
}; // eslint-disable-line space-before-blocks
// The following provide classes meant to avoid clashes with other values
// To insist `undefined` should be added
Typeson.Undefined = Undefined; // To support async encapsulation/stringification
Typeson.Promise = TypesonPromise; // Some fundamental type-checking utilities
Typeson.isThenable = isThenable;
Typeson.toStringTag = toStringTag;
Typeson.hasConstructorOf = hasConstructorOf;
Typeson.isObject = isObject;
Typeson.isPlainObject = isPlainObject;
Typeson.isUserObject = isUserObject;
Typeson.escapeKeyPathComponent = escapeKeyPathComponent;
Typeson.unescapeKeyPathComponent = unescapeKeyPathComponent;
Typeson.getByKeyPath = getByKeyPath;
Typeson.getJSONType = getJSONType;
Typeson.JSON_TYPES = ['null', 'boolean', 'number', 'string', 'array', 'object'];
module.exports = Typeson;

@@ -1,1 +0,1619 @@

!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).Typeson=t()}(this,function(){"use strict";function _typeof(e){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function asyncGeneratorStep(e,t,n,r,i,a,o){try{var c=e[a](o),s=c.value}catch(e){return void n(e)}c.done?t(s):Promise.resolve(s).then(r,i)}function _asyncToGenerator(e){return function(){var t=this,n=arguments;return new Promise(function(r,i){var a=e.apply(t,n);function _next(e){asyncGeneratorStep(a,r,i,_next,_throw,"next",e)}function _throw(e){asyncGeneratorStep(a,r,i,_next,_throw,"throw",e)}_next(void 0)})}}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _defineProperties(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function _defineProperty(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function _objectSpread(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{},r=Object.keys(n);"function"==typeof Object.getOwnPropertySymbols&&(r=r.concat(Object.getOwnPropertySymbols(n).filter(function(e){return Object.getOwnPropertyDescriptor(n,e).enumerable}))),r.forEach(function(t){_defineProperty(e,t,n[t])})}return e}function _slicedToArray(e,t){return function _arrayWithHoles(e){if(Array.isArray(e))return e}(e)||function _iterableToArrayLimit(e,t){var n=[],r=!0,i=!1,a=void 0;try{for(var o,c=e[Symbol.iterator]();!(r=(o=c.next()).done)&&(n.push(o.value),!t||n.length!==t);r=!0);}catch(e){i=!0,a=e}finally{try{r||null==c.return||c.return()}finally{if(i)throw a}}return n}(e,t)||function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}function _toConsumableArray(e){return function _arrayWithoutHoles(e){if(Array.isArray(e)){for(var t=0,n=new Array(e.length);t<e.length;t++)n[t]=e[t];return n}}(e)||function _iterableToArray(e){if(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e))return Array.from(e)}(e)||function _nonIterableSpread(){throw new TypeError("Invalid attempt to spread non-iterable instance")}()}var e=function TypesonPromise(e){_classCallCheck(this,TypesonPromise),this.p=new Promise(e)};"undefined"!=typeof Symbol&&(e.prototype[Symbol.toStringTag]="TypesonPromise"),e.prototype.then=function(t,n){var r=this;return new e(function(e,i){r.p.then(function(n){e(t?t(n):n)},function(t){r.p.catch(function(e){return n?n(e):Promise.reject(e)}).then(e,i)})})},e.prototype.catch=function(e){return this.then(null,e)},e.resolve=function(t){return new e(function(e){e(t)})},e.reject=function(t){return new e(function(e,n){n(t)})},["all","race"].map(function(t){e[t]=function(n){return new e(function(e,r){Promise[t](n.map(function(e){return e.p})).then(e,r)})}});var t={}.toString,n={}.hasOwnProperty,r=Object.getPrototypeOf,i=n.toString;function isThenable(e,t){return isObject(e)&&"function"==typeof e.then&&(!t||"function"==typeof e.catch)}function toStringTag(e){return t.call(e).slice(8,-1)}function hasConstructorOf(e,t){if(!e||"object"!==_typeof(e))return!1;var a=r(e);if(!a)return!1;var o=n.call(a,"constructor")&&a.constructor;return"function"!=typeof o?null===t:"function"==typeof o&&null!==t&&i.call(o)===i.call(t)}function isPlainObject(e){return!(!e||"Object"!==toStringTag(e))&&(!r(e)||hasConstructorOf(e,Object))}function isObject(e){return e&&"object"===_typeof(e)}function escapeKeyPathComponent(e){return e.replace(/~/g,"~0").replace(/\./g,"~1")}function unescapeKeyPathComponent(e){return e.replace(/~1/g,".").replace(/~0/g,"~")}function getByKeyPath(e,t){if(""===t)return e;var n=t.indexOf(".");if(n>-1){var r=e[unescapeKeyPathComponent(t.substr(0,n))];return void 0===r?void 0:getByKeyPath(r,t.substr(n+1))}return e[unescapeKeyPathComponent(t)]}var a=Object.keys,o=Array.isArray,c={}.hasOwnProperty,s=["type","replaced","iterateIn","iterateUnsetNumeric"];function nestedPathsFirst(e,t){var n=e.keypath.match(/\./g),r=e.keypath.match(/\./g);return n&&(n=n.length),r&&(r=r.length),n>r?-1:n<r?1:e.keypath<t.keypath?-1:e.keypath>t.keypath}var u=function(){function Typeson(e){_classCallCheck(this,Typeson),this.options=e,this.plainObjectReplacers=[],this.nonplainObjectReplacers=[],this.revivers={},this.types={}}return function _createClass(e,t,n){return t&&_defineProperties(e.prototype,t),n&&_defineProperties(e,n),e}(Typeson,[{key:"stringify",value:function stringify(e,t,n,r){r=_objectSpread({},this.options,r,{stringification:!0});var i=this.encapsulate(e,null,r);return o(i)?JSON.stringify(i[0],t,n):i.then(function(e){return JSON.stringify(e,t,n)})}},{key:"stringifySync",value:function stringifySync(e,t,n,r){return this.stringify(e,t,n,_objectSpread({throwOnBadSyncType:!0},r,{sync:!0}))}},{key:"stringifyAsync",value:function stringifyAsync(e,t,n,r){return this.stringify(e,t,n,_objectSpread({throwOnBadSyncType:!0},r,{sync:!1}))}},{key:"parse",value:function parse(e,t,n){return n=_objectSpread({},this.options,n,{parse:!0}),this.revive(JSON.parse(e,t),n)}},{key:"parseSync",value:function parseSync(e,t,n){return this.parse(e,t,_objectSpread({throwOnBadSyncType:!0},n,{sync:!0}))}},{key:"parseAsync",value:function parseAsync(e,t,n){return this.parse(e,t,_objectSpread({throwOnBadSyncType:!0},n,{sync:!1}))}},{key:"specialTypeNames",value:function specialTypeNames(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return n.returnTypeNames=!0,this.encapsulate(e,t,n)}},{key:"rootTypeName",value:function rootTypeName(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return n.iterateNone=!0,this.encapsulate(e,t,n)}},{key:"encapsulate",value:function encapsulate(t,n,r){var i=(r=_objectSpread({sync:!0},this.options,r)).sync,u=this,p={},l=[],y=[],f=[],h=!("cyclic"in r)||r.cyclic,v=r.encapsulateObserver,d=_encapsulate("",t,h,n||{},f);function finish(e){var t=Object.values(p);if(r.iterateNone)return t.length?t[0]:Typeson.getJSONType(e);if(t.length){if(r.returnTypeNames)return _toConsumableArray(new Set(t));e&&isPlainObject(e)&&!c.call(e,"$types")?e.$types=p:e={$:e,$types:{$:p}}}else isObject(e)&&c.call(e,"$types")&&(e={$:e,$types:!0});return!r.returnTypeNames&&e}function checkPromises(e,t){return _checkPromises.apply(this,arguments)}function _checkPromises(){return(_checkPromises=_asyncToGenerator(regeneratorRuntime.mark(function _callee2(t,n){var r;return regeneratorRuntime.wrap(function _callee2$(i){for(;;)switch(i.prev=i.next){case 0:return i.next=2,Promise.all(n.map(function(e){return e[1].p}));case 2:return r=i.sent,i.next=5,Promise.all(r.map(function(){var r=_asyncToGenerator(regeneratorRuntime.mark(function _callee(r){var i,a,o,c,s,u,p,l,y,f,h,v,d,b;return regeneratorRuntime.wrap(function _callee$(O){for(;;)switch(O.prev=O.next){case 0:if(i=[],a=n.splice(0,1),o=_slicedToArray(a,1),c=o[0],s=_slicedToArray(c,7),u=s[0],p=s[2],l=s[3],y=s[4],f=s[5],h=s[6],v=_encapsulate(u,r,p,l,i,!0,h),d=hasConstructorOf(v,e),!u||!d){O.next=11;break}return O.next=8,v.p;case 8:return b=O.sent,y[f]=b,O.abrupt("return",checkPromises(t,i));case 11:return u?y[f]=v:t=d?v.p:v,O.abrupt("return",checkPromises(t,i));case 13:case"end":return O.stop()}},_callee)}));return function(e){return r.apply(this,arguments)}}()));case 5:return i.abrupt("return",t);case 6:case"end":return i.stop()}},_callee2)}))).apply(this,arguments)}function _adaptBuiltinStateObjectProperties(e,t,n){Object.assign(e,t);var r=s.map(function(t){var n=e[t];return delete e[t],n});n(),s.forEach(function(t,n){e[t]=r[n]})}function _encapsulate(t,n,i,s,f,h,d){var b,O={},m=_typeof(n),g=v?function(r){var a=d||s.type||Typeson.getJSONType(n);v(Object.assign(r||O,{keypath:t,value:n,cyclic:i,stateObj:s,promisesData:f,resolvingTypesonPromise:h,awaitingTypesonPromise:hasConstructorOf(n,e)},void 0!==a?{type:a}:{}))}:null;if(["string","boolean","number","undefined"].includes(m))return void 0===n||"number"===m&&(isNaN(n)||n===-1/0||n===1/0)?(b=replace(t,n,s,f,!1,h,g))!==n&&(O={replaced:b}):b=n,g&&g(),b;if(null===n)return g&&g(),n;if(i&&!s.iterateIn&&!s.iterateUnsetNumeric){var _=l.indexOf(n);if(!(_<0))return p[t]="#",g&&g({cyclicKeypath:y[_]}),"#"+y[_];!0===i&&(l.push(n),y.push(t))}var j,P=isPlainObject(n),S=o(n),T=(P||S)&&(!u.plainObjectReplacers.length||s.replaced)||s.iterateIn?n:replace(t,n,s,f,P||S,null,g);if(T!==n?(b=T,O={replaced:T}):S&&"object"!==s.iterateIn||"array"===s.iterateIn?(j=new Array(n.length),O={clone:j}):P||"object"===s.iterateIn?(j={},s.addLength&&(j.length=n.length),O={clone:j}):""===t&&hasConstructorOf(n,e)?(f.push([t,n,i,s,void 0,void 0,s.type]),b=n):b=n,g&&g(),r.iterateNone)return j||b;if(!j)return b;if(s.iterateIn){var w=function _loop(r){var a={ownKeys:c.call(n,r)};_adaptBuiltinStateObjectProperties(s,a,function(){var a=t+(t?".":"")+escapeKeyPathComponent(r),o=_encapsulate(a,n[r],!!i,s,f,h);hasConstructorOf(o,e)?f.push([a,o,!!i,s,j,r,s.type]):void 0!==o&&(j[r]=o)})};for(var A in n)w(A);g&&g({endIterateIn:!0,end:!0})}else a(n).forEach(function(r){var a=t+(t?".":"")+escapeKeyPathComponent(r);_adaptBuiltinStateObjectProperties(s,{ownKeys:!0},function(){var t=_encapsulate(a,n[r],!!i,s,f,h);hasConstructorOf(t,e)?f.push([a,t,!!i,s,j,r,s.type]):void 0!==t&&(j[r]=t)})}),g&&g({endIterateOwn:!0,end:!0});if(s.iterateUnsetNumeric){for(var k=n.length,C=function _loop2(r){if(!(r in n)){var a=t+(t?".":"")+r;_adaptBuiltinStateObjectProperties(s,{ownKeys:!1},function(){var t=_encapsulate(a,void 0,!!i,s,f,h);hasConstructorOf(t,e)?f.push([a,t,!!i,s,j,r,s.type]):void 0!==t&&(j[r]=t)})}},K=0;K<k;K++)C(K);g&&g({endIterateUnsetNumeric:!0,end:!0})}return j}function replace(e,t,n,r,a,o,c){for(var s=a?u.plainObjectReplacers:u.nonplainObjectReplacers,l=s.length;l--;){var y=s[l];if(y.test(t,n)){var f=y.type;if(u.revivers[f]){var v=p[e];p[e]=v?[f].concat(v):f}return Object.assign(n,{type:f,replaced:!0}),!i&&y.replaceAsync||y.replace?(c&&c({replacing:!0}),_encapsulate(e,y[i||!y.replaceAsync?"replace":"replaceAsync"](t,n),h&&"readonly",n,r,o,f)):(c&&c({typeDetected:!0}),_encapsulate(e,t,h&&"readonly",n,r,o,f))}}return t}return f.length?i&&r.throwOnBadSyncType?function(){throw new TypeError("Sync method requested but async result obtained")}():Promise.resolve(checkPromises(d,f)).then(finish):!i&&r.throwOnBadSyncType?function(){throw new TypeError("Async method requested but sync result obtained")}():r.stringification&&i?[finish(d)]:i?finish(d):Promise.resolve(finish(d))}},{key:"encapsulateSync",value:function encapsulateSync(e,t,n){return this.encapsulate(e,t,_objectSpread({throwOnBadSyncType:!0},n,{sync:!0}))}},{key:"encapsulateAsync",value:function encapsulateAsync(e,t,n){return this.encapsulate(e,t,_objectSpread({throwOnBadSyncType:!0},n,{sync:!1}))}},{key:"revive",value:function revive(t,n){var r=t&&t.$types;if(!r)return t;if(!0===r)return t.$;var i=(n=_objectSpread({sync:!0},this.options,n)).sync,c=[],s={},u=!0;r.$&&isPlainObject(r.$)&&(t=t.$,r=r.$,u=!1);var l=this;function _revive(t,n,y,f,h){if(!u||"$types"!==t){var v=r[t];if(o(n)||isPlainObject(n)){var d=o(n)?new Array(n.length):{};for(a(n).forEach(function(e){var r=_revive(t+(t?".":"")+escapeKeyPathComponent(e),n[e],y||d,d,e);hasConstructorOf(r,p)?d[e]=void 0:void 0!==r&&(d[e]=r)}),n=d;c.length;){var b=_slicedToArray(c[0],4),O=b[0],m=b[1],g=b[2],_=b[3],j=getByKeyPath(O,m);if(hasConstructorOf(j,p))g[_]=void 0;else{if(void 0===j)break;g[_]=j}c.splice(0,1)}}if(!v)return n;if("#"===v){var P=getByKeyPath(y,n.slice(1));return void 0===P&&c.push([y,n.slice(1),f,h]),P}return[].concat(v).reduce(function reducer(t,n){if(hasConstructorOf(t,e))return t.then(function(e){return reducer(e,n)});var r=_slicedToArray(l.revivers[n],1)[0];if(!r)throw new Error("Unregistered type: "+n);return r[i&&r.revive?"revive":!i&&r.reviveAsync?"reviveAsync":"revive"](t,s)},n)}}function checkUndefined(e){return hasConstructorOf(e,p)?void 0:e}var y,f=function revivePlainObjects(){var n=[];if(Object.entries(r).forEach(function(e){var t=_slicedToArray(e,2),i=t[0],a=t[1];"#"!==a&&[].concat(a).forEach(function(e){_slicedToArray(l.revivers[e],2)[1].plain&&(n.push({keypath:i,type:e}),delete r[i])})}),n.length)return n.sort(nestedPathsFirst).reduce(function reducer(n,r){var a=r.keypath,o=r.type;if(hasConstructorOf(n,e))return n.then(function(e){return reducer(e,o)});var c=getByKeyPath(t,a);if(hasConstructorOf(c,e))return c.then(function(e){return reducer(e,o)});var u=_slicedToArray(l.revivers[o],1)[0];if(!u)throw new Error("Unregistered type: "+o);void 0!==(c=u[i&&u.revive?"revive":!i&&u.reviveAsync?"reviveAsync":"revive"](c,s))&&(hasConstructorOf(c,p)&&(c=void 0),function setAtKeyPath(e,t,n){if(""===t)return n;var r=t.indexOf(".");return r>-1?setAtKeyPath(e[unescapeKeyPathComponent(t.substr(0,r))],t.substr(r+1),n):(e[unescapeKeyPathComponent(t)]=n,e)}(t,a,c)===c&&(t=c))},void 0)}();return isThenable(y=hasConstructorOf(f,e)?f.then(function(){return _revive("",t,null)}):_revive("",t,null))?i&&n.throwOnBadSyncType?function(){throw new TypeError("Sync method requested but async result obtained")}():hasConstructorOf(y,e)?y.p.then(checkUndefined):y:!i&&n.throwOnBadSyncType?function(){throw new TypeError("Async method requested but sync result obtained")}():i?checkUndefined(y):Promise.resolve(checkUndefined(y))}},{key:"reviveSync",value:function reviveSync(e,t){return this.revive(e,_objectSpread({throwOnBadSyncType:!0},t,{sync:!0}))}},{key:"reviveAsync",value:function reviveAsync(e,t){return this.revive(e,_objectSpread({throwOnBadSyncType:!0},t,{sync:!1}))}},{key:"register",value:function register(e,t){return t=t||{},[].concat(e).forEach(function R(e){if(o(e))return e.map(R,this);e&&a(e).forEach(function(n){if("#"===n)throw new TypeError("# cannot be used as a type name as it is reserved for cyclic objects");if(Typeson.JSON_TYPES.includes(n))throw new TypeError("Plain JSON object types are reserved as type names");var r=e[n],i=r.testPlainObjects?this.plainObjectReplacers:this.nonplainObjectReplacers,a=i.filter(function(e){return e.type===n});if(a.length&&(i.splice(i.indexOf(a[0]),1),delete this.revivers[n],delete this.types[n]),r){if("function"==typeof r){var c=r;r={test:function test(e){return e&&e.constructor===c},replace:function replace(e){return Object.assign({},e)},revive:function revive(e){return Object.assign(Object.create(c.prototype),e)}}}else if(o(r)){var s=_slicedToArray(r,3);r={test:s[0],replace:s[1],revive:s[2]}}var u={type:n,test:r.test.bind(r)};r.replace&&(u.replace=r.replace.bind(r)),r.replaceAsync&&(u.replaceAsync=r.replaceAsync.bind(r));var p="number"==typeof t.fallback?t.fallback:t.fallback?0:1/0;if(r.testPlainObjects?this.plainObjectReplacers.splice(p,0,u):this.nonplainObjectReplacers.splice(p,0,u),r.revive||r.reviveAsync){var l={};r.revive&&(l.revive=r.revive.bind(r)),r.reviveAsync&&(l.reviveAsync=r.reviveAsync.bind(r)),this.revivers[n]=[l,{plain:r.testPlainObjects}]}this.types[n]=r}},this)},this),this}}]),Typeson}(),p=function Undefined(){_classCallCheck(this,Undefined)};return u.Undefined=p,u.Promise=e,u.isThenable=isThenable,u.toStringTag=toStringTag,u.hasConstructorOf=hasConstructorOf,u.isObject=isObject,u.isPlainObject=isPlainObject,u.isUserObject=function isUserObject(e){if(!e||"Object"!==toStringTag(e))return!1;var t=r(e);return!t||hasConstructorOf(e,Object)||isUserObject(t)},u.escapeKeyPathComponent=escapeKeyPathComponent,u.unescapeKeyPathComponent=unescapeKeyPathComponent,u.getByKeyPath=getByKeyPath,u.getJSONType=function getJSONType(e){return null===e?"null":Array.isArray(e)?"array":_typeof(e)},u.JSON_TYPES=["null","boolean","number","string","array","object"],u});
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = global || self, global.Typeson = factory());
}(this, function () { 'use strict';
function _typeof(obj) {
if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
_typeof = function (obj) {
return typeof obj;
};
} else {
_typeof = function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};
}
return _typeof(obj);
}
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
try {
var info = gen[key](arg);
var value = info.value;
} catch (error) {
reject(error);
return;
}
if (info.done) {
resolve(value);
} else {
Promise.resolve(value).then(_next, _throw);
}
}
function _asyncToGenerator(fn) {
return function () {
var self = this,
args = arguments;
return new Promise(function (resolve, reject) {
var gen = fn.apply(self, args);
function _next(value) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
}
function _throw(err) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
}
_next(undefined);
});
};
}
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a 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);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function _objectSpread(target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i] != null ? arguments[i] : {};
var ownKeys = Object.keys(source);
if (typeof Object.getOwnPropertySymbols === 'function') {
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) {
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
}));
}
ownKeys.forEach(function (key) {
_defineProperty(target, key, source[key]);
});
}
return target;
}
function _slicedToArray(arr, i) {
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest();
}
function _toConsumableArray(arr) {
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();
}
function _arrayWithoutHoles(arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
return arr2;
}
}
function _arrayWithHoles(arr) {
if (Array.isArray(arr)) return arr;
}
function _iterableToArray(iter) {
if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
}
function _iterableToArrayLimit(arr, i) {
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
try {
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"] != null) _i["return"]();
} finally {
if (_d) throw _e;
}
}
return _arr;
}
function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance");
}
function _nonIterableRest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
/**
* We keep this function minimized so if using two instances of this
* library, where one is minimized and one is not, it will still work
* with `hasConstructorOf`.
* With ES6 classes, we may be able to simply use `class TypesonPromise
* extends Promise` and add a string tag for detection
* @param {function} f
*/
var TypesonPromise = function TypesonPromise(f) {
_classCallCheck(this, TypesonPromise);
this.p = new Promise(f);
}; // eslint-disable-line block-spacing, space-before-function-paren, space-before-blocks, space-infix-ops, semi
// class TypesonPromise extends Promise {get[Symbol.toStringTag](){return 'TypesonPromise'};} // eslint-disable-line keyword-spacing, space-before-function-paren, space-before-blocks, block-spacing, semi
// Note: core-js-bundle provides a `Symbol` polyfill
if (typeof Symbol !== 'undefined') {
// Ensure `isUserObject` will return `false` for `TypesonPromise`
TypesonPromise.prototype[Symbol.toStringTag] = 'TypesonPromise';
}
/**
*
* @param {function} [onFulfilled]
* @param {function} [onRejected]
* @returns {TypesonPromise}
*/
TypesonPromise.prototype.then = function (onFulfilled, onRejected) {
var _this = this;
return new TypesonPromise(function (typesonResolve, typesonReject) {
_this.p.then(function (res) {
typesonResolve(onFulfilled ? onFulfilled(res) : res);
}, function (r) {
_this.p['catch'](function (res) {
return onRejected ? onRejected(res) : Promise.reject(res);
}).then(typesonResolve, typesonReject);
});
});
};
/**
*
* @param {function} onRejected
* @returns {TypesonPromise}
*/
TypesonPromise.prototype["catch"] = function (onRejected) {
return this.then(null, onRejected);
};
/**
*
* @param {} v
* @returns {TypesonPromise}
*/
TypesonPromise.resolve = function (v) {
return new TypesonPromise(function (typesonResolve) {
typesonResolve(v);
});
};
/**
*
* @param {} v
* @returns {TypesonPromise}
*/
TypesonPromise.reject = function (v) {
return new TypesonPromise(function (typesonResolve, typesonReject) {
typesonReject(v);
});
};
['all', 'race'].map(function (meth) {
/**
*
* @param {Promise[]} promArr
* @returns {TypesonPromise}
*/
TypesonPromise[meth] = function (promArr) {
return new TypesonPromise(function (typesonResolve, typesonReject) {
Promise[meth](promArr.map(function (prom) {
return prom.p;
})).then(typesonResolve, typesonReject);
});
};
});
var _ref = {},
toString = _ref.toString,
hasOwn = {}.hasOwnProperty,
getProto = Object.getPrototypeOf,
fnToString = hasOwn.toString;
/**
*
* @param {*} v
* @param {boolean} catchCheck
* @returns {boolean}
*/
function isThenable(v, catchCheck) {
return isObject(v) && typeof v.then === 'function' && (!catchCheck || typeof v["catch"] === 'function');
}
/**
*
* @param {*} val
* @returns {string}
*/
function toStringTag(val) {
return toString.call(val).slice(8, -1);
}
/**
* This function is dependent on both constructors
* being identical so any minimization is expected of both.
* @param {*} a
* @param {function} b
* @returns {boolean}
*/
function hasConstructorOf(a, b) {
if (!a || _typeof(a) !== 'object') {
return false;
}
var proto = getProto(a);
if (!proto) {
return false;
}
var Ctor = hasOwn.call(proto, 'constructor') && proto.constructor;
if (typeof Ctor !== 'function') {
return b === null;
}
return typeof Ctor === 'function' && b !== null && fnToString.call(Ctor) === fnToString.call(b);
}
/**
*
* @param {*} val
* @returns {boolean}
*/
function isPlainObject(val) {
// Mirrors jQuery's
if (!val || toStringTag(val) !== 'Object') {
return false;
}
var proto = getProto(val);
if (!proto) {
// `Object.create(null)`
return true;
}
return hasConstructorOf(val, Object);
}
/**
*
* @param {*} val
* @returns {boolean}
*/
function isUserObject(val) {
if (!val || toStringTag(val) !== 'Object') {
return false;
}
var proto = getProto(val);
if (!proto) {
// `Object.create(null)`
return true;
}
return hasConstructorOf(val, Object) || isUserObject(proto);
}
/**
*
* @param {*} v
* @returns {boolean}
*/
function isObject(v) {
return v && _typeof(v) === 'object';
}
/**
*
* @param {string} keyPathComponent
* @returns {string}
*/
function escapeKeyPathComponent(keyPathComponent) {
return keyPathComponent.replace(/~/g, '~0').replace(/\./g, '~1');
}
/**
*
* @param {string} keyPathComponent
* @returns {string}
*/
function unescapeKeyPathComponent(keyPathComponent) {
return keyPathComponent.replace(/~1/g, '.').replace(/~0/g, '~');
}
/**
* @param {object|array} obj
* @param {string} keyPath
* @returns {*}
*/
function getByKeyPath(obj, keyPath) {
if (keyPath === '') {
return obj;
}
var period = keyPath.indexOf('.');
if (period > -1) {
var innerObj = obj[unescapeKeyPathComponent(keyPath.substr(0, period))];
return innerObj === undefined ? undefined : getByKeyPath(innerObj, keyPath.substr(period + 1));
}
return obj[unescapeKeyPathComponent(keyPath)];
}
function setAtKeyPath(obj, keyPath, value) {
if (keyPath === '') {
return value;
}
var period = keyPath.indexOf('.');
if (period > -1) {
var innerObj = obj[unescapeKeyPathComponent(keyPath.substr(0, period))];
return setAtKeyPath(innerObj, keyPath.substr(period + 1), value);
}
obj[unescapeKeyPathComponent(keyPath)] = value;
return obj;
}
/**
*
* @param {external:JSON} value
* @returns {"null"|"array"|"undefined"|"boolean"|"number"|"string"|"object"|"symbol"}
*/
function getJSONType(value) {
return value === null ? 'null' : Array.isArray(value) ? 'array' : _typeof(value);
}
var keys = Object.keys,
isArray = Array.isArray,
hasOwn$1 = {}.hasOwnProperty,
internalStateObjPropsToIgnore = ['type', 'replaced', 'iterateIn', 'iterateUnsetNumeric'];
function nestedPathsFirst(a, b) {
var as = a.keypath.match(/\./g);
var bs = a.keypath.match(/\./g);
if (as) {
as = as.length;
}
if (bs) {
bs = bs.length;
}
return as > bs ? -1 : as < bs ? 1 : a.keypath < b.keypath ? -1 : a.keypath > b.keypath;
}
/**
* An instance of this class can be used to call `stringify()` and `parse()`.
* Typeson resolves cyclic references by default. Can also be extended to
* support custom types using the register() method.
*
* @constructor
* @param {{cyclic: boolean}} [options] - if cyclic (default true),
* cyclic references will be handled gracefully.
*/
var Typeson =
/*#__PURE__*/
function () {
function Typeson(options) {
_classCallCheck(this, Typeson);
this.options = options; // Replacers signature: replace (value). Returns falsy if not
// replacing. Otherwise ['Date', value.getTime()]
this.plainObjectReplacers = [];
this.nonplainObjectReplacers = []; // Revivers: [{type => reviver}, {plain: boolean}].
// Sample: [{'Date': value => new Date(value)}, {plain: false}]
this.revivers = {};
/** Types registered via register() */
this.types = {};
}
/**
* Serialize given object to Typeson.
* Initial arguments work identical to those of `JSON.stringify`.
* The `replacer` argument has nothing to do with our replacers.
* @param {*} obj
* @param {function|string[]} replacer
* @param {number|string} space
* @param {object} opts
* @returns {string|Promise} Promise resolves to a string
*/
_createClass(Typeson, [{
key: "stringify",
value: function stringify(obj, replacer, space, opts) {
opts = _objectSpread({}, this.options, opts, {
stringification: true
});
var encapsulated = this.encapsulate(obj, null, opts);
if (isArray(encapsulated)) {
return JSON.stringify(encapsulated[0], replacer, space);
}
return encapsulated.then(function (res) {
return JSON.stringify(res, replacer, space);
});
}
/**
* Also sync but throws on non-sync result
* @param {*} obj
* @param {function|string[]} replacer
* @param {number|string} space
* @param {object} opts
* @returns {string}
*/
}, {
key: "stringifySync",
value: function stringifySync(obj, replacer, space, opts) {
return this.stringify(obj, replacer, space, _objectSpread({
throwOnBadSyncType: true
}, opts, {
sync: true
}));
}
/**
*
* @param {*} obj
* @param {function|string[]} replacer
* @param {number|string} space
* @param {object} opts
* @returns {Promise} Resolves to string
*/
}, {
key: "stringifyAsync",
value: function stringifyAsync(obj, replacer, space, opts) {
return this.stringify(obj, replacer, space, _objectSpread({
throwOnBadSyncType: true
}, opts, {
sync: false
}));
}
/**
* Parse Typeson back into an obejct.
* Initial arguments works identical to those of `JSON.parse()`.
* @param {string} text
* @param {function} reviver This JSON reviver has nothing to do with
* our revivers.
* @param {object} opts
* @returns {external:JSON}
*/
}, {
key: "parse",
value: function parse(text, reviver, opts) {
opts = _objectSpread({}, this.options, opts, {
parse: true
});
return this.revive(JSON.parse(text, reviver), opts);
}
/**
* Also sync but throws on non-sync result
* @param {string} text
* @param {function} reviver This JSON reviver has nothing to do with
* our revivers.
* @param {object} opts
* @returns {external:JSON}
*/
}, {
key: "parseSync",
value: function parseSync(text, reviver, opts) {
return this.parse(text, reviver, _objectSpread({
throwOnBadSyncType: true
}, opts, {
sync: true
}));
}
/**
* @param {string} text
* @param {function} reviver This JSON reviver has nothing to do with
* our revivers.
* @param {object} opts
* @returns {Promise} Resolves to `external:JSON`
*/
}, {
key: "parseAsync",
value: function parseAsync(text, reviver, opts) {
return this.parse(text, reviver, _objectSpread({
throwOnBadSyncType: true
}, opts, {
sync: false
}));
}
/**
*
* @param {*} obj
* @param {object} stateObj
* @param {object} [opts={}]
* @returns {string[]|false}
*/
}, {
key: "specialTypeNames",
value: function specialTypeNames(obj, stateObj) {
var opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
opts.returnTypeNames = true;
return this.encapsulate(obj, stateObj, opts);
}
/**
*
* @param {*} obj
* @param {object} stateObj
* @param {object} [opts={}]
* @returns {Promise|Array|object|string|false}
*/
}, {
key: "rootTypeName",
value: function rootTypeName(obj, stateObj) {
var opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
opts.iterateNone = true;
return this.encapsulate(obj, stateObj, opts);
}
/**
* Encapsulate a complex object into a plain Object by replacing
* registered types with plain objects representing the types data.
*
* This method is used internally by T`ypeson.stringify()`.
* @param {Object} obj - Object to encapsulate.
* @param {object} stateObj
* @param {object} opts
* @returns {Promise|Array|object|string|false}
*/
}, {
key: "encapsulate",
value: function encapsulate(obj, stateObj, opts) {
opts = _objectSpread({
sync: true
}, this.options, opts);
var _opts = opts,
sync = _opts.sync;
var that = this,
types = {},
refObjs = [],
// For checking cyclic references
refKeys = [],
// For checking cyclic references
promisesDataRoot = []; // Clone the object deeply while at the same time replacing any
// special types or cyclic reference:
var cyclic = 'cyclic' in opts ? opts.cyclic : true;
var _opts2 = opts,
encapsulateObserver = _opts2.encapsulateObserver;
var ret = _encapsulate('', obj, cyclic, stateObj || {}, promisesDataRoot);
/**
*
* @param {*} ret
* @returns {Array|object|string|false}
*/
function finish(ret) {
// Add `$types` to result only if we ever bumped into a
// special type (or special case where object has own `$types`)
var typeNames = Object.values(types);
if (opts.iterateNone) {
if (typeNames.length) {
return typeNames[0];
}
return Typeson.getJSONType(ret);
}
if (typeNames.length) {
if (opts.returnTypeNames) {
return _toConsumableArray(new Set(typeNames));
} // Special if array (or a primitive) was serialized
// because JSON would ignore custom `$types` prop on it
if (!ret || !isPlainObject(ret) || // Also need to handle if this is an object with its
// own `$types` property (to avoid ambiguity)
hasOwn$1.call(ret, '$types')) {
ret = {
$: ret,
$types: {
$: types
}
};
} else {
ret.$types = types;
} // No special types
} else if (isObject(ret) && hasOwn$1.call(ret, '$types')) {
ret = {
$: ret,
$types: true
};
}
if (opts.returnTypeNames) {
return false;
}
return ret;
}
/**
*
* @param {*} ret
* @param {array} promisesData
* @returns {Promise} Resolves to ...
*/
function checkPromises(_x, _x2) {
return _checkPromises.apply(this, arguments);
}
/**
*
* @param {object} stateObj
* @param {object} ownKeysObj
* @param {function} cb
* @returns {undefined}
*/
function _checkPromises() {
_checkPromises = _asyncToGenerator(
/*#__PURE__*/
regeneratorRuntime.mark(function _callee2(ret, promisesData) {
var promResults;
return regeneratorRuntime.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
_context2.next = 2;
return Promise.all(promisesData.map(function (pd) {
return pd[1].p;
}));
case 2:
promResults = _context2.sent;
_context2.next = 5;
return Promise.all(promResults.map(
/*#__PURE__*/
function () {
var _ref = _asyncToGenerator(
/*#__PURE__*/
regeneratorRuntime.mark(function _callee(promResult) {
var newPromisesData, _promisesData$splice, _promisesData$splice2, prData, _prData, keyPath, cyclic, stateObj, parentObj, key, detectedType, encaps, isTypesonPromise, encaps2;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
newPromisesData = [];
_promisesData$splice = promisesData.splice(0, 1), _promisesData$splice2 = _slicedToArray(_promisesData$splice, 1), prData = _promisesData$splice2[0];
_prData = _slicedToArray(prData, 7), keyPath = _prData[0], cyclic = _prData[2], stateObj = _prData[3], parentObj = _prData[4], key = _prData[5], detectedType = _prData[6];
encaps = _encapsulate(keyPath, promResult, cyclic, stateObj, newPromisesData, true, detectedType);
isTypesonPromise = hasConstructorOf(encaps, TypesonPromise); // Handle case where an embedded custom type itself
// returns a `Typeson.Promise`
if (!(keyPath && isTypesonPromise)) {
_context.next = 11;
break;
}
_context.next = 8;
return encaps.p;
case 8:
encaps2 = _context.sent;
parentObj[key] = encaps2;
return _context.abrupt("return", checkPromises(ret, newPromisesData));
case 11:
if (keyPath) {
parentObj[key] = encaps;
} else if (isTypesonPromise) {
ret = encaps.p;
} else {
// If this is itself a `Typeson.Promise` (because the
// original value supplied was a `Promise` or
// because the supplied custom type value resolved
// to one), returning it below will be fine since
// a `Promise` is expected anyways given current
// config (and if not a `Promise`, it will be ready
// as the resolve value)
ret = encaps;
}
return _context.abrupt("return", checkPromises(ret, newPromisesData));
case 13:
case "end":
return _context.stop();
}
}
}, _callee);
}));
return function (_x3) {
return _ref.apply(this, arguments);
};
}()));
case 5:
return _context2.abrupt("return", ret);
case 6:
case "end":
return _context2.stop();
}
}
}, _callee2);
}));
return _checkPromises.apply(this, arguments);
}
function _adaptBuiltinStateObjectProperties(stateObj, ownKeysObj, cb) {
Object.assign(stateObj, ownKeysObj);
var vals = internalStateObjPropsToIgnore.map(function (prop) {
var tmp = stateObj[prop];
delete stateObj[prop];
return tmp;
});
cb();
internalStateObjPropsToIgnore.forEach(function (prop, i) {
stateObj[prop] = vals[i];
});
}
/**
*
* @param {string} keypath
* @param {*} value
* @param {boolean} cyclic
* @param {object} stateObj
* @param {boolean} promisesData
* @param {boolean} resolvingTypesonPromise
* @param {string} detectedType
* @returns {*}
*/
function _encapsulate(keypath, value, cyclic, stateObj, promisesData, resolvingTypesonPromise, detectedType) {
var ret;
var observerData = {};
var $typeof = _typeof(value);
var runObserver = encapsulateObserver ? function (obj) {
var type = detectedType || stateObj.type || Typeson.getJSONType(value);
encapsulateObserver(Object.assign(obj || observerData, {
keypath: keypath,
value: value,
cyclic: cyclic,
stateObj: stateObj,
promisesData: promisesData,
resolvingTypesonPromise: resolvingTypesonPromise,
awaitingTypesonPromise: hasConstructorOf(value, TypesonPromise)
}, type !== undefined ? {
type: type
} : {}));
} : null;
if (['string', 'boolean', 'number', 'undefined'].includes($typeof)) {
if (value === undefined || $typeof === 'number' && (isNaN(value) || value === -Infinity || value === Infinity)) {
ret = replace(keypath, value, stateObj, promisesData, false, resolvingTypesonPromise, runObserver);
if (ret !== value) {
observerData = {
replaced: ret
};
}
} else {
ret = value;
}
if (runObserver) {
runObserver();
}
return ret;
}
if (value === null) {
if (runObserver) {
runObserver();
}
return value;
}
if (cyclic && !stateObj.iterateIn && !stateObj.iterateUnsetNumeric) {
// Options set to detect cyclic references and be able
// to rewrite them.
var refIndex = refObjs.indexOf(value);
if (refIndex < 0) {
if (cyclic === true) {
refObjs.push(value);
refKeys.push(keypath);
}
} else {
types[keypath] = '#';
if (runObserver) {
runObserver({
cyclicKeypath: refKeys[refIndex]
});
}
return '#' + refKeys[refIndex];
}
}
var isPlainObj = isPlainObject(value);
var isArr = isArray(value);
var replaced = // Running replace will cause infinite loop as will test
// positive again
(isPlainObj || isArr) && (!that.plainObjectReplacers.length || stateObj.replaced) || stateObj.iterateIn ? // Optimization: if plain object and no plain-object
// replacers, don't try finding a replacer
value : replace(keypath, value, stateObj, promisesData, isPlainObj || isArr, null, runObserver);
var clone;
if (replaced !== value) {
ret = replaced;
observerData = {
replaced: replaced
};
} else {
if (isArr && stateObj.iterateIn !== 'object' || stateObj.iterateIn === 'array') {
clone = new Array(value.length);
observerData = {
clone: clone
};
} else if (isPlainObj || stateObj.iterateIn === 'object') {
clone = {};
if (stateObj.addLength) {
clone.length = value.length;
}
observerData = {
clone: clone
};
} else if (keypath === '' && hasConstructorOf(value, TypesonPromise)) {
promisesData.push([keypath, value, cyclic, stateObj, undefined, undefined, stateObj.type]);
ret = value;
} else {
ret = value; // Only clone vanilla objects and arrays
}
}
if (runObserver) {
runObserver();
}
if (opts.iterateNone) {
return clone || ret;
}
if (!clone) {
return ret;
} // Iterate object or array
if (stateObj.iterateIn) {
var _loop = function _loop(key) {
var ownKeysObj = {
ownKeys: hasOwn$1.call(value, key)
};
_adaptBuiltinStateObjectProperties(stateObj, ownKeysObj, function () {
var kp = keypath + (keypath ? '.' : '') + escapeKeyPathComponent(key);
var val = _encapsulate(kp, value[key], !!cyclic, stateObj, promisesData, resolvingTypesonPromise);
if (hasConstructorOf(val, TypesonPromise)) {
promisesData.push([kp, val, !!cyclic, stateObj, clone, key, stateObj.type]);
} else if (val !== undefined) {
clone[key] = val;
}
});
};
for (var key in value) {
_loop(key);
}
if (runObserver) {
runObserver({
endIterateIn: true,
end: true
});
}
} else {
// Note: Non-indexes on arrays won't survive stringify so
// somewhat wasteful for arrays, but so too is iterating
// all numeric indexes on sparse arrays when not wanted
// or filtering own keys for positive integers
keys(value).forEach(function (key) {
var kp = keypath + (keypath ? '.' : '') + escapeKeyPathComponent(key);
var ownKeysObj = {
ownKeys: true
};
_adaptBuiltinStateObjectProperties(stateObj, ownKeysObj, function () {
var val = _encapsulate(kp, value[key], !!cyclic, stateObj, promisesData, resolvingTypesonPromise);
if (hasConstructorOf(val, TypesonPromise)) {
promisesData.push([kp, val, !!cyclic, stateObj, clone, key, stateObj.type]);
} else if (val !== undefined) {
clone[key] = val;
}
});
});
if (runObserver) {
runObserver({
endIterateOwn: true,
end: true
});
}
} // Iterate array for non-own numeric properties (we can't
// replace the prior loop though as it iterates non-integer
// keys)
if (stateObj.iterateUnsetNumeric) {
var vl = value.length;
var _loop2 = function _loop2(i) {
if (!(i in value)) {
// No need to escape numeric
var kp = keypath + (keypath ? '.' : '') + i;
var ownKeysObj = {
ownKeys: false
};
_adaptBuiltinStateObjectProperties(stateObj, ownKeysObj, function () {
var val = _encapsulate(kp, undefined, !!cyclic, stateObj, promisesData, resolvingTypesonPromise);
if (hasConstructorOf(val, TypesonPromise)) {
promisesData.push([kp, val, !!cyclic, stateObj, clone, i, stateObj.type]);
} else if (val !== undefined) {
clone[i] = val;
}
});
}
};
for (var i = 0; i < vl; i++) {
_loop2(i);
}
if (runObserver) {
runObserver({
endIterateUnsetNumeric: true,
end: true
});
}
}
return clone;
}
/**
*
* @param {string} keypath
* @param {*} value
* @param {object} stateObj
* @param {array} promisesData
* @param {boolean} plainObject
* @param {boolean} resolvingTypesonPromise
* @param {function} [runObserver]
* @returns {*}
*/
function replace(keypath, value, stateObj, promisesData, plainObject, resolvingTypesonPromise, runObserver) {
// Encapsulate registered types
var replacers = plainObject ? that.plainObjectReplacers : that.nonplainObjectReplacers;
var i = replacers.length;
while (i--) {
var replacer = replacers[i];
if (replacer.test(value, stateObj)) {
var type = replacer.type;
if (that.revivers[type]) {
// Record the type only if a corresponding reviver
// exists. This is to support specs where only
// replacement is done.
// For example, ensuring deep cloning of the object,
// or replacing a type to its equivalent without
// the need to revive it.
var existing = types[keypath]; // type can comprise an array of types (see test
// `shouldSupportIntermediateTypes`)
types[keypath] = existing ? [type].concat(existing) : type;
} // Now, also traverse the result in case it contains its
// own types to replace
Object.assign(stateObj, {
type: type,
replaced: true
});
if ((sync || !replacer.replaceAsync) && !replacer.replace) {
if (runObserver) {
runObserver({
typeDetected: true
});
}
return _encapsulate(keypath, value, cyclic && 'readonly', stateObj, promisesData, resolvingTypesonPromise, type);
}
if (runObserver) {
runObserver({
replacing: true
});
}
var replaceMethod = sync || !replacer.replaceAsync ? 'replace' : 'replaceAsync';
return _encapsulate(keypath, replacer[replaceMethod](value, stateObj), cyclic && 'readonly', stateObj, promisesData, resolvingTypesonPromise, type);
}
}
return value;
}
return promisesDataRoot.length ? sync && opts.throwOnBadSyncType ? function () {
throw new TypeError('Sync method requested but async result obtained');
}() : Promise.resolve(checkPromises(ret, promisesDataRoot)).then(finish) : !sync && opts.throwOnBadSyncType ? function () {
throw new TypeError('Async method requested but sync result obtained');
}() // If this is a synchronous request for stringification, yet
// a promise is the result, we don't want to resolve leading
// to an async result, so we return an array to avoid
// ambiguity
: opts.stringification && sync ? [finish(ret)] : sync ? finish(ret) : Promise.resolve(finish(ret));
}
/**
* Also sync but throws on non-sync result
* @param {*} obj
* @param {object} stateObj
* @param {object} opts
* @returns {*}
*/
}, {
key: "encapsulateSync",
value: function encapsulateSync(obj, stateObj, opts) {
return this.encapsulate(obj, stateObj, _objectSpread({
throwOnBadSyncType: true
}, opts, {
sync: true
}));
}
/**
* @param {*} obj
* @param {object} stateObj
* @param {object} opts
* @returns {*}
*/
}, {
key: "encapsulateAsync",
value: function encapsulateAsync(obj, stateObj, opts) {
return this.encapsulate(obj, stateObj, _objectSpread({
throwOnBadSyncType: true
}, opts, {
sync: false
}));
}
/**
* Revive an encapsulated object.
* This method is used internally by `Typeson.parse()`.
* @param {object} obj - Object to revive. If it has `$types` member, the
* properties that are listed there will be replaced with its true type
* instead of just plain objects.
* @param {object} opts
* @throws TypeError If mismatch between sync/async type and result
* @returns {Promise|*} If async, returns a Promise that resolves to `*`
*/
}, {
key: "revive",
value: function revive(obj, opts) {
var types = obj && obj.$types; // No type info added. Revival not needed.
if (!types) {
return obj;
} // Object happened to have own `$types` property but with
// no actual types, so we unescape and return that object
if (types === true) {
return obj.$;
}
opts = _objectSpread({
sync: true
}, this.options, opts);
var _opts3 = opts,
sync = _opts3.sync;
var keyPathResolutions = [];
var stateObj = {};
var ignore$Types = true; // Special when root object is not a trivial Object, it will
// be encapsulated in `$`. It will also be encapsulated in
// `$` if it has its own `$` property to avoid ambiguity
if (types.$ && isPlainObject(types.$)) {
obj = obj.$;
types = types.$;
ignore$Types = false;
}
var that = this;
function revivePlainObjects() {
// const references = [];
// const reviveTypes = [];
var plainObjectTypes = [];
Object.entries(types).forEach(function (_ref2) {
var _ref3 = _slicedToArray(_ref2, 2),
keypath = _ref3[0],
type = _ref3[1];
if (type === '#') {
/*
references.push({
keypath,
reference: getByKeyPath(obj, keypath)
});
*/
return;
}
[].concat(type).forEach(function (type) {
var _that$revivers$type = _slicedToArray(that.revivers[type], 2),
plain = _that$revivers$type[1].plain;
if (!plain) {
// reviveTypes.push({keypath, type});
return;
}
plainObjectTypes.push({
keypath: keypath,
type: type
});
delete types[keypath]; // Avoid repeating
});
});
if (!plainObjectTypes.length) {
return;
} // Handle plain object revivers first so reference
// setting can use revived type (e.g., array instead
// of object); assumes revived has same structure
// or will otherwise break subsequent references
return plainObjectTypes.sort(nestedPathsFirst).reduce(function reducer(possibleTypesonPromise, _ref4) {
var keypath = _ref4.keypath,
type = _ref4.type;
if (hasConstructorOf(possibleTypesonPromise, TypesonPromise)) {
// TypesonPromise here too
return possibleTypesonPromise.then(function (v) {
return reducer(v, type);
});
}
var val = getByKeyPath(obj, keypath);
if (hasConstructorOf(val, TypesonPromise)) {
return val.then(function (v) {
// TypesonPromise here too
return reducer(v, type);
});
}
var _that$revivers$type2 = _slicedToArray(that.revivers[type], 1),
reviver = _that$revivers$type2[0];
if (!reviver) {
throw new Error('Unregistered type: ' + type);
}
val = reviver[sync && reviver.revive ? 'revive' : !sync && reviver.reviveAsync ? 'reviveAsync' : 'revive'](val, stateObj);
if (val === undefined) {
return undefined;
}
if (hasConstructorOf(val, Undefined)) {
val = undefined;
}
var newVal = setAtKeyPath(obj, keypath, val);
if (newVal === val) {
obj = val;
}
return undefined;
}, undefined // This argument must be explicit
); // references.forEach(({keypath, reference}) => {});
// reviveTypes.sort(nestedPathsFirst).forEach(() => {});
}
/**
*
* @param {string} keypath
* @param {*} value
* @param {?(Array|object)} target
* @param {Array|object} [clone]
* @param {string} [key]
* @returns {*}
*/
function _revive(keypath, value, target, clone, key) {
if (ignore$Types && keypath === '$types') {
return undefined;
}
var type = types[keypath];
if (isArray(value) || isPlainObject(value)) {
var _clone = isArray(value) ? new Array(value.length) : {}; // Iterate object or array
keys(value).forEach(function (k) {
var val = _revive(keypath + (keypath ? '.' : '') + escapeKeyPathComponent(k), value[k], target || _clone, _clone, k);
if (hasConstructorOf(val, Undefined)) {
_clone[k] = undefined;
} else if (val !== undefined) {
_clone[k] = val;
}
});
value = _clone; // Try to resolve cyclic reference as soon as available
while (keyPathResolutions.length) {
var _keyPathResolutions$ = _slicedToArray(keyPathResolutions[0], 4),
_target = _keyPathResolutions$[0],
keyPath = _keyPathResolutions$[1],
_clone2 = _keyPathResolutions$[2],
k = _keyPathResolutions$[3];
var val = getByKeyPath(_target, keyPath);
if (hasConstructorOf(val, Undefined)) {
_clone2[k] = undefined;
} else if (val !== undefined) {
_clone2[k] = val;
} else {
break;
}
keyPathResolutions.splice(0, 1);
}
}
if (!type) {
return value;
}
if (type === '#') {
var _ret = getByKeyPath(target, value.slice(1));
if (_ret === undefined) {
// Cyclic reference not yet available
keyPathResolutions.push([target, value.slice(1), clone, key]);
}
return _ret;
}
return [].concat(type).reduce(function reducer(val, type) {
if (hasConstructorOf(val, TypesonPromise)) {
return val.then(function (v) {
// TypesonPromise here too
return reducer(v, type);
});
}
var _that$revivers$type3 = _slicedToArray(that.revivers[type], 1),
reviver = _that$revivers$type3[0];
if (!reviver) {
throw new Error('Unregistered type: ' + type);
}
return reviver[sync && reviver.revive ? 'revive' : !sync && reviver.reviveAsync ? 'reviveAsync' : 'revive'](val, stateObj);
}, value);
}
function checkUndefined(retrn) {
return hasConstructorOf(retrn, Undefined) ? undefined : retrn;
}
var possibleTypesonPromise = revivePlainObjects();
var ret;
if (hasConstructorOf(possibleTypesonPromise, TypesonPromise)) {
ret = possibleTypesonPromise.then(function () {
return _revive('', obj, null);
});
} else {
ret = _revive('', obj, null);
}
return isThenable(ret) ? sync && opts.throwOnBadSyncType ? function () {
throw new TypeError('Sync method requested but async result obtained');
}() : hasConstructorOf(ret, TypesonPromise) ? ret.p.then(checkUndefined) : ret : !sync && opts.throwOnBadSyncType ? function () {
throw new TypeError('Async method requested but sync result obtained');
}() : sync ? checkUndefined(ret) : Promise.resolve(checkUndefined(ret));
}
/**
* Also sync but throws on non-sync result
* @param {*} obj
* @param {object} opts
* @returns {*}
*/
}, {
key: "reviveSync",
value: function reviveSync(obj, opts) {
return this.revive(obj, _objectSpread({
throwOnBadSyncType: true
}, opts, {
sync: true
}));
}
/**
* @param {*} obj
* @param {object} opts
* @returns {Promise} Resolves to `*`
*/
}, {
key: "reviveAsync",
value: function reviveAsync(obj, opts) {
return this.revive(obj, _objectSpread({
throwOnBadSyncType: true
}, opts, {
sync: false
}));
}
/**
* Register types.
* For examples on how to use this method, see
* {@link https://github.com/dfahlander/typeson-registry/tree/master/types}
* @param {Array.<Object.<string,Function[]>>} typeSpecSets - Types and
* their functions [test, encapsulate, revive];
* @param {object} opts
* @returns {Typeson}
*/
}, {
key: "register",
value: function register(typeSpecSets, opts) {
opts = opts || {};
[].concat(typeSpecSets).forEach(function R(typeSpec) {
// Allow arrays of arrays of arrays...
if (isArray(typeSpec)) {
return typeSpec.map(R, this);
}
typeSpec && keys(typeSpec).forEach(function (typeId) {
if (typeId === '#') {
throw new TypeError('# cannot be used as a type name as it is reserved ' + 'for cyclic objects');
} else if (Typeson.JSON_TYPES.includes(typeId)) {
throw new TypeError('Plain JSON object types are reserved as type names');
}
var spec = typeSpec[typeId];
var replacers = spec.testPlainObjects ? this.plainObjectReplacers : this.nonplainObjectReplacers;
var existingReplacer = replacers.filter(function (r) {
return r.type === typeId;
});
if (existingReplacer.length) {
// Remove existing spec and replace with this one.
replacers.splice(replacers.indexOf(existingReplacer[0]), 1);
delete this.revivers[typeId];
delete this.types[typeId];
}
if (!spec) {
return;
}
if (typeof spec === 'function') {
// Support registering just a class without replacer/reviver
var Class = spec;
spec = {
test: function test(x) {
return x && x.constructor === Class;
},
replace: function replace(x) {
return Object.assign({}, x);
},
revive: function revive(x) {
return Object.assign(Object.create(Class.prototype), x);
}
};
} else if (isArray(spec)) {
var _spec = spec,
_spec2 = _slicedToArray(_spec, 3),
test = _spec2[0],
replace = _spec2[1],
revive = _spec2[2];
spec = {
test: test,
replace: replace,
revive: revive
};
}
var replacerObj = {
type: typeId,
test: spec.test.bind(spec)
};
if (spec.replace) {
replacerObj.replace = spec.replace.bind(spec);
}
if (spec.replaceAsync) {
replacerObj.replaceAsync = spec.replaceAsync.bind(spec);
}
var start = typeof opts.fallback === 'number' ? opts.fallback : opts.fallback ? 0 : Infinity;
if (spec.testPlainObjects) {
this.plainObjectReplacers.splice(start, 0, replacerObj);
} else {
this.nonplainObjectReplacers.splice(start, 0, replacerObj);
} // Todo: We might consider a testAsync type
if (spec.revive || spec.reviveAsync) {
var reviverObj = {};
if (spec.revive) {
reviverObj.revive = spec.revive.bind(spec);
}
if (spec.reviveAsync) {
reviverObj.reviveAsync = spec.reviveAsync.bind(spec);
}
this.revivers[typeId] = [reviverObj, {
plain: spec.testPlainObjects
}];
} // Record to be retrieved via public types property.
this.types[typeId] = spec;
}, this);
}, this);
return this;
}
}]);
return Typeson;
}();
/**
* We keep this function minimized so if using two instances of this
* library, where one is minimized and one is not, it will still work
* with `hasConstructorOf`.
* @constructor
*/
var Undefined = function Undefined() {
_classCallCheck(this, Undefined);
}; // eslint-disable-line space-before-blocks
// The following provide classes meant to avoid clashes with other values
// To insist `undefined` should be added
Typeson.Undefined = Undefined; // To support async encapsulation/stringification
Typeson.Promise = TypesonPromise; // Some fundamental type-checking utilities
Typeson.isThenable = isThenable;
Typeson.toStringTag = toStringTag;
Typeson.hasConstructorOf = hasConstructorOf;
Typeson.isObject = isObject;
Typeson.isPlainObject = isPlainObject;
Typeson.isUserObject = isUserObject;
Typeson.escapeKeyPathComponent = escapeKeyPathComponent;
Typeson.unescapeKeyPathComponent = unescapeKeyPathComponent;
Typeson.getByKeyPath = getByKeyPath;
Typeson.getJSONType = getJSONType;
Typeson.JSON_TYPES = ['null', 'boolean', 'number', 'string', 'array', 'object'];
return Typeson;
}));

41

package.json
{
"name": "typeson",
"version": "5.12.0",
"version": "5.13.0",
"description": "Preserves types over JSON, BSON or socket.io",
"main": "./dist/typeson-commonjs2.js",
"browser": "./dist/typeson.js",
"module": "./typeson.js",
"module": "./dist/typeson-esm.js",
"scripts": {

@@ -12,6 +12,6 @@ "prepublishOnly": "yarn",

"start": "static -p 8092",
"browser-test": "npm run eslint && npm run rollup && opn http://localhost:8092/test/ && npm start",
"node-test": "npx babel-node test/test.js",
"test": "npm run eslint && npm run rollup && npm run node-test",
"rollup": "rollup -c"
"rollup": "rollup -c",
"browser-test": "npm run eslint && npm run rollup && open-cli http://localhost:8092/test/ && npm start",
"node-test": "node -r esm test/test.js",
"test": "npm run eslint && npm run rollup && npm run node-test"
},

@@ -40,24 +40,29 @@ "repository": {

"homepage": "https://github.com/dfahlander/typeson#readme",
"engines": {},
"peerDependencies": {
"core-js-bundle": "^3.1.3",
"regenerator-runtime": "^0.13.2"
},
"dependencies": {},
"engines": {},
"devDependencies": {
"@babel/core": "^7.4.0",
"@babel/node": "^7.2.2",
"@babel/preset-env": "^7.4.2",
"base64-arraybuffer-es6": "^0.4.2",
"@babel/core": "^7.4.5",
"@babel/preset-env": "^7.4.5",
"base64-arraybuffer-es6": "^0.5.0",
"core-js-bundle": "^3.1.3",
"eslint": "5.16.0",
"eslint-config-standard": "12.0.0",
"eslint-plugin-compat": "3.1.0",
"eslint-plugin-import": "2.16.0",
"eslint-plugin-node": "8.0.1",
"eslint-plugin-compat": "3.1.1",
"eslint-plugin-import": "2.17.3",
"eslint-plugin-node": "9.1.0",
"eslint-plugin-promise": "4.1.1",
"eslint-plugin-standard": "4.0.0",
"esm": "^3.2.25",
"node-static": "0.7.11",
"opn-cli": "^4.0.0",
"rollup": "1.7.4",
"open-cli": "^5.0.0",
"regenerator-runtime": "^0.13.2",
"rollup": "1.13.1",
"rollup-plugin-babel": "^4.3.2",
"rollup-plugin-node-resolve": "^4.0.1",
"rollup-plugin-terser": "^4.0.4"
"rollup-plugin-terser": "^5.0.0"
},
"tonicExample": "var Typeson = require('typeson');\nvar TSON = new Typeson().register(require('typeson-registry/presets/builtin'));\n\nTSON.stringify({foo: new Date()}, null, 2);"
}

@@ -12,3 +12,3 @@ /**

// Note: @babel/polyfill provides a `Symbol` polyfill
// Note: core-js-bundle provides a `Symbol` polyfill
if (typeof Symbol !== 'undefined') {

@@ -15,0 +15,0 @@ // Ensure `isUserObject` will return `false` for `TypesonPromise`

SocketSocket SOC 2 Logo

Product

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

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc