typeson
Version:
Preserves types over JSON, BSON or socket.io
2 lines (1 loc) • 18.8 kB
JavaScript
function _arrayLikeToArray(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=Array(t);r<t;r++)n[r]=e[r];return n}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _createClass(e,t,r){return t&&function _defineProperties(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,_toPropertyKey(n.key),n)}}(e.prototype,t),Object.defineProperty(e,"prototype",{writable:!1}),e}function _defineProperty(e,t,r){return(t=_toPropertyKey(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function ownKeys(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function _objectSpread2(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?ownKeys(Object(r),!0).forEach((function(t){_defineProperty(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):ownKeys(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function _slicedToArray(e,t){return function _arrayWithHoles(e){if(Array.isArray(e))return e}(e)||function _iterableToArrayLimit(e,t){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var n,o,i,a,c=[],s=!0,u=!1;try{if(i=(r=r.call(e)).next,0===t){if(Object(r)!==r)return;s=!1}else for(;!(s=(n=i.call(r)).done)&&(c.push(n.value),c.length!==t);s=!0);}catch(e){u=!0,o=e}finally{try{if(!s&&null!=r.return&&(a=r.return(),Object(a)!==a))return}finally{if(u)throw o}}return c}}(e,t)||_unsupportedIterableToArray(e,t)||function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function _toConsumableArray(e){return function _arrayWithoutHoles(e){if(Array.isArray(e))return _arrayLikeToArray(e)}(e)||function _iterableToArray(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||_unsupportedIterableToArray(e)||function _nonIterableSpread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function _toPropertyKey(e){var t=function _toPrimitive(e,t){if("object"!=typeof e||!e)return e;var r=e[Symbol.toPrimitive];if(void 0!==r){var n=r.call(e,t);if("object"!=typeof n)return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e,"string");return"symbol"==typeof t?t:t+""}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},_typeof(e)}function _unsupportedIterableToArray(e,t){if(e){if("string"==typeof e)return _arrayLikeToArray(e,t);var r={}.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?_arrayLikeToArray(e,t):void 0}}var e=_createClass((function TypesonPromise(e){_classCallCheck(this,TypesonPromise),this.p=new Promise(e)}));e.__typeson__type__="TypesonPromise","undefined"!=typeof Symbol&&Object.defineProperty(e.prototype,Symbol.toStringTag,{get:function get(){return"TypesonPromise"}}),e.prototype.then=function(t,r){var n=this;return new e((function(e,o){n.p.then((function(r){e(t?t(r):r)})).catch((function(e){return r?r(e):Promise.reject(e)})).then(e,o)}))},e.prototype.catch=function(e){return this.then((function(){}),e)},e.resolve=function(t){return new e((function(e){e(t)}))},e.reject=function(t){return new e((function(e,r){r(t)}))},e.all=function(t){return new e((function(e,r){Promise.all(t.map((function(e){return null!=e&&e.constructor&&"__typeson__type__"in e.constructor&&"TypesonPromise"===e.constructor.__typeson__type__?e.p:e}))).then(e,r)}))},e.race=function(t){return new e((function(e,r){Promise.race(t.map((function(e){return null!=e&&e.constructor&&"__typeson__type__"in e.constructor&&"TypesonPromise"===e.constructor.__typeson__type__?e.p:e}))).then(e,r)}))},e.allSettled=function(t){return new e((function(e,r){Promise.allSettled(t.map((function(e){return null!=e&&e.constructor&&"__typeson__type__"in e.constructor&&"TypesonPromise"===e.constructor.__typeson__type__?e.p:e}))).then(e,r)}))};var t=Object.hasOwn,r=Object.getPrototypeOf;function isThenable(e,t){return isObject(e)&&"function"==typeof e.then&&(!t||"function"==typeof e.catch)}function toStringTag(e){return Object.prototype.toString.call(e).slice(8,-1)}function hasConstructorOf(e,n){if(!e||"object"!==_typeof(e))return!1;var o=r(e);if(!o)return null===n;var i=t(o,"constructor")&&o.constructor;return"function"!=typeof i?null===n:n===i||(null!==n&&Function.prototype.toString.call(i)===Function.prototype.toString.call(n)||"function"==typeof n&&"string"==typeof i.__typeson__type__&&i.__typeson__type__===n.__typeson__type__)}function isPlainObject(e){return!(!e||"Object"!==toStringTag(e))&&(!r(e)||hasConstructorOf(e,Object))}function isUserObject(e){if(!e||"Object"!==toStringTag(e))return!1;var t=r(e);return!t||(hasConstructorOf(e,Object)||isUserObject(t))}function isObject(e){return null!==e&&"object"===_typeof(e)}function escapeKeyPathComponent(e){return e.replaceAll("''","''''").replace(/^$/,"''").replaceAll("~","~0").replaceAll(".","~1")}function unescapeKeyPathComponent(e){return e.replaceAll("~1",".").replaceAll("~0","~").replace(/^''$/,"").replaceAll("''''","''")}function getByKeyPath(e,t){if(""===t)return e;if(null===e||"object"!==_typeof(e))throw new TypeError("Unexpected non-object type");var r=t.indexOf(".");if(-1!==r){var n=e[unescapeKeyPathComponent(t.slice(0,r))];return void 0===n?void 0:getByKeyPath(n,t.slice(r+1))}return e[unescapeKeyPathComponent(t)]}function setAtKeyPath(e,t,r){if(""===t)return r;if(!e||"object"!==_typeof(e))throw new TypeError("Unexpected non-object type");if("__proto__"===t)throw new TypeError("Invalid property");var n=t.indexOf(".");return-1!==n?setAtKeyPath(e[unescapeKeyPathComponent(t.slice(0,n))],t.slice(n+1),r):(e[unescapeKeyPathComponent(t)]=r,e)}function getJSONType(e){return null===e?"null":Array.isArray(e)?"array":_typeof(e)}function _await(e,t,r){return e&&e.then||(e=Promise.resolve(e)),t?e.then(t):e}var n=Object.keys,o=Object.hasOwn,i=Array.isArray,a=["type","replaced","iterateIn","iterateUnsetNumeric","addLength"];function _async(e){return function(){for(var t=[],r=0;r<arguments.length;r++)t[r]=arguments[r];try{return Promise.resolve(e.apply(this,t))}catch(e){return Promise.reject(e)}}}function nestedPathsFirst(e,t){var r,n;if(""===e.keypath)return-1;var o=null!==(r=e.keypath.match(/\./g))&&void 0!==r?r:0,i=null!==(n=t.keypath.match(/\./g))&&void 0!==n?n:0;return o&&(o=o.length),i&&(i=i.length),o>i?-1:o<i?1:e.keypath<t.keypath?-1:e.keypath>t.keypath?1:0}var c=function(){return _createClass((function Typeson(e){_classCallCheck(this,Typeson),this.options=e,this.plainObjectReplacers=[],this.nonplainObjectReplacers=[],this.revivers={},this.types={}}),[{key:"stringify",value:function stringify(e,t,r,n){n=_objectSpread2(_objectSpread2(_objectSpread2({},this.options),n),{},{stringification:!0});var o=this.encapsulate(e,null,n);return i(o)?JSON.stringify(o[0],t,r):o.then((function(e){return JSON.stringify(e,t,r)}))}},{key:"stringifySync",value:function stringifySync(e,t,r,n){return this.stringify(e,t,r,_objectSpread2(_objectSpread2({throwOnBadSyncType:!0},n),{},{sync:!0}))}},{key:"stringifyAsync",value:function stringifyAsync(e,t,r,n){return this.stringify(e,t,r,_objectSpread2(_objectSpread2({throwOnBadSyncType:!0},n),{},{sync:!1}))}},{key:"parse",value:function parse(e,t,r){return r=_objectSpread2(_objectSpread2(_objectSpread2({},this.options),r),{},{parse:!0}),this.revive(JSON.parse(e,t),r)}},{key:"parseSync",value:function parseSync(e,t,r){return this.parse(e,t,_objectSpread2(_objectSpread2({throwOnBadSyncType:!0},r),{},{sync:!0}))}},{key:"parseAsync",value:function parseAsync(e,t,r){return this.parse(e,t,_objectSpread2(_objectSpread2({throwOnBadSyncType:!0},r),{},{sync:!1}))}},{key:"specialTypeNames",value:function specialTypeNames(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return r.returnTypeNames=!0,this.encapsulate(e,t,r)}},{key:"rootTypeName",value:function rootTypeName(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return r.iterateNone=!0,this.encapsulate(e,t,r)}},{key:"encapsulate",value:function encapsulate(t,r,c){var s=this,u=_objectSpread2(_objectSpread2({sync:!0},this.options),c),y=u.sync,l={},p=[],f=[],v=[],h=!("cyclic"in u)||u.cyclic,d=u.encapsulateObserver,b=function finish(e){var t=Object.values(l);if(u.iterateNone)return t.length?t[0]:getJSONType(e);if(t.length){if(u.returnTypeNames)return _toConsumableArray(new Set(t));e&&isPlainObject(e)&&!o(e,"$types")?e.$types=l:e={$:e,$types:{$:l}}}else isObject(e)&&o(e,"$types")&&(e={$:e,$types:!0});return!u.returnTypeNames&&e},_=_async((function(t,r){return _await(Promise.all(r.map((function(e){return e[1].p}))),(function(n){return _await(Promise.all(n.map(_async((function(n){var o=!1,i=[],a=_slicedToArray(r.splice(0,1),1),c=_slicedToArray(a[0],7),s=c[0],u=c[2],y=c[3],l=c[4],p=c[5],f=c[6],v=m(s,n,u,y,i,!0,f),h=hasConstructorOf(v,e);return function _invoke(e,t){var r=e();return r&&r.then?r.then(t):t(r)}((function(){if(s&&h)return _await(v.p,(function(e){l[p]=e;var r=_(t,i);return o=!0,r}))}),(function(e){return o?e:(s?l[p]=v:t=h?v.p:v,_(t,i))}))})))),(function(){return t}))}))})),O=function _adaptBuiltinStateObjectProperties(e,t,r){Object.assign(e,t);var n=a.map((function(t){var r=e[t];return delete e[t],r}));r(),a.forEach((function(t,r){e[t]=n[r]}))},m=function _encapsulate(t,r,a,c,y,v,h){var b,_={},g=_typeof(r),S=d?function(n){var o,i=null!==(o=null!=h?h:c.type)&&void 0!==o?o:getJSONType(r);d(Object.assign(null!=n?n:_,{keypath:t,value:r,cyclic:a,stateObj:c,promisesData:y,resolvingTypesonPromise:v,awaitingTypesonPromise:hasConstructorOf(r,e)},{type:i}))}:null;if(["string","boolean","number","undefined"].includes(g))return void 0===r||Number.isNaN(r)||r===Number.NEGATIVE_INFINITY||r===Number.POSITIVE_INFINITY||0===r?(b=c.replaced?r:j(t,r,c,y,!1,v,S))!==r&&(_={replaced:b}):b=r,S&&S(),b;if(null===r)return S&&S(),r;if(a&&!c.iterateIn&&!c.iterateUnsetNumeric&&r&&"object"===_typeof(r)){var w=p.indexOf(r);if(-1!==w)return l[t]="#",S&&S({cyclicKeypath:f[w]}),"#"+f[w];!0===a&&(p.push(r),f.push(t))}var T,P=isPlainObject(r),A=i(r),C=(P||A)&&(!s.plainObjectReplacers.length||c.replaced)||c.iterateIn?r:j(t,r,c,y,P||A,null,S);if(C!==r?(b=C,_={replaced:C}):""===t&&hasConstructorOf(r,e)?(y.push([t,r,a,c,void 0,void 0,c.type]),b=r):A&&"object"!==c.iterateIn||"array"===c.iterateIn?(T=new Array(r.length),_={clone:T}):(["function","symbol"].includes(_typeof(r))||"toJSON"in r||hasConstructorOf(r,e)||hasConstructorOf(r,Promise)||hasConstructorOf(r,ArrayBuffer))&&!P&&"object"!==c.iterateIn?b=r:(T={},c.addLength&&(T.length=r.length),_={clone:T}),S&&S(),u.iterateNone)return null!=T?T:b;if(!T)return b;if(c.iterateIn){var k=function _loop(n){var i={ownKeys:o(r,n)};O(c,i,(function(){var o=t+(t?".":"")+escapeKeyPathComponent(n),i=m(o,r[n],Boolean(a),c,y,v);hasConstructorOf(i,e)?y.push([o,i,Boolean(a),c,T,n,c.type]):void 0!==i&&(T[n]=i)}))};for(var N in r)k(N);S&&S({endIterateIn:!0,end:!0})}else n(r).forEach((function(n){var o=t+(t?".":"")+escapeKeyPathComponent(n);O(c,{ownKeys:!0},(function(){var t=m(o,r[n],Boolean(a),c,y,v);hasConstructorOf(t,e)?y.push([o,t,Boolean(a),c,T,n,c.type]):void 0!==t&&(T[n]=t)}))})),S&&S({endIterateOwn:!0,end:!0});if(c.iterateUnsetNumeric){for(var I=r.length,E=function _loop2(n){if(!(n in r)){var o="".concat(t).concat(t?".":"").concat(String(n));O(c,{ownKeys:!1},(function(){var t=m(o,void 0,Boolean(a),c,y,v);hasConstructorOf(t,e)?y.push([o,t,Boolean(a),c,T,n,c.type]):void 0!==t&&(T[n]=t)}))}},K=0;K<I;K++)E(K);S&&S({endIterateUnsetNumeric:!0,end:!0})}return T},j=function replace(e,t,r,n,o,i,a){for(var c=o?s.plainObjectReplacers:s.nonplainObjectReplacers,u=c.length;u--;){var p=c[u];if(p.test(t,r)){var f=p.type;if(s.revivers[f]){var v=l[e];l[e]=v?[f].concat(v):f}if(Object.assign(r,{type:f,replaced:!0}),(y||!p.replaceAsync)&&!p.replace)return a&&a({typeDetected:!0}),m(e,t,h&&"readonly",r,n,i,f);a&&a({replacing:!0});var d=void 0;if(y||!p.replaceAsync){if(void 0===p.replace)throw new TypeError("Missing replacer");d=p.replace(t,r)}else d=p.replaceAsync(t,r);return m(e,d,h&&"readonly",r,n,i,f)}}return t},g=m("",t,h,null!=r?r:{},v);if(v.length)return y&&u.throwOnBadSyncType?function(){throw new TypeError("Sync method requested but async result obtained")}():Promise.resolve(_(g,v)).then(b);if(!y&&u.throwOnBadSyncType)throw new TypeError("Async method requested but sync result obtained");return u.stringification&&y?[b(g)]:y?b(g):Promise.resolve(b(g))}},{key:"encapsulateSync",value:function encapsulateSync(e,t,r){return this.encapsulate(e,t,_objectSpread2(_objectSpread2({throwOnBadSyncType:!0},r),{},{sync:!0}))}},{key:"encapsulateAsync",value:function encapsulateAsync(e,t,r){return this.encapsulate(e,t,_objectSpread2(_objectSpread2({throwOnBadSyncType:!0},r),{},{sync:!1}))}},{key:"revive",value:function revive(t,r){var o=this,a=_objectSpread2(_objectSpread2({sync:!0},this.options),r),c=a.sync;function finishRevival(e){if(c)return e;if(a.throwOnBadSyncType)throw new TypeError("Async method requested but sync result obtained");return Promise.resolve(e)}if(!t||"object"!==_typeof(t)||Array.isArray(t))return finishRevival(t);var u=t.$types;if(!0===u)return finishRevival(t.$);if(!u||"object"!==_typeof(u)||Array.isArray(u))return finishRevival(t);var y=[],l={},p=!0;u.$&&isPlainObject(u.$)&&(t=t.$,u=u.$,p=!1);var f=function executeReviver(e,t){var r,n=_slicedToArray(null!==(r=o.revivers[e])&&void 0!==r?r:[],1)[0];if(!n)throw new Error("Unregistered type: "+e);if(c&&!("revive"in n))return t;if(!c&&n.reviveAsync)return n.reviveAsync(t,l);if(n.revive)return n.revive(t,l);throw new Error("Missing reviver")},v=[];function checkUndefined(e){return hasConstructorOf(e,s)?void 0:e}var h,d=function revivePlainObjects(){var r=[];if(!u)throw new Error("Found bad `types`");if(Object.entries(u).forEach((function(e){var t=_slicedToArray(e,2),n=t[0],i=t[1];"#"!==i&&[].concat(i).forEach((function(e){var t;_slicedToArray(null!==(t=o.revivers[e])&&void 0!==t?t:[null,{}],2)[1].plain&&(r.push({keypath:n,type:e}),delete u[n])}))})),r.length)return r.sort(nestedPathsFirst),r.reduce((function reducer(r,n){var o=n.keypath,i=n.type;if(isThenable(r))return r.then((function(e){return reducer(e,{keypath:o,type:i})}));var a=getByKeyPath(t,o);if(hasConstructorOf(a=f(i,a),e))return a.then((function(e){var r=setAtKeyPath(t,o,e);r===e&&(t=r)}));var c=setAtKeyPath(t,o,a);c===a&&(t=c)}),void 0)}();return hasConstructorOf(d,e)?h=d.then((function(){return t})):(h=function _revive(t,r,o,a,c){if(!p||"$types"!==t){var l=u[t],h=i(r);if(h||isPlainObject(r)){var d=h?new Array(r.length):{};for(n(r).forEach((function(n){var i=_revive(t+(t?".":"")+escapeKeyPathComponent(n),r[n],null!=o?o:d,d,n),a=function set(e){return hasConstructorOf(e,s)?d[n]=void 0:void 0!==e&&(d[n]=e),e};hasConstructorOf(i,e)?v.push(i.then((function(e){return a(e)}))):a(i)})),r=d;y.length;){var b=_slicedToArray(y[0],4),_=b[0],O=b[1],m=b[2],j=b[3],g=getByKeyPath(_,O);if(void 0===g)break;m[j]=g,y.splice(0,1)}}if(!l)return r;if("#"===l){var S=getByKeyPath(o,r.slice(1));return void 0===S&&y.push([o,r.slice(1),a,c]),S}return[].concat(l).reduce((function reducer(t,r){if(hasConstructorOf(t,e))return t.then((function(e){return reducer(e,r)}));if("string"!=typeof r)throw new TypeError("Bad type JSON");return f(r,t)}),r)}}("",t,null),v.length&&(h=e.resolve(h).then((function(t){return e.all([t].concat(v))})).then((function(e){return _slicedToArray(e,1)[0]})))),isThenable(h)?c&&a.throwOnBadSyncType?function(){throw new TypeError("Sync method requested but async result obtained")}():hasConstructorOf(h,e)?h.p.then(checkUndefined):h:!c&&a.throwOnBadSyncType?function(){throw new TypeError("Async method requested but sync result obtained")}():c?checkUndefined(h):Promise.resolve(checkUndefined(h))}},{key:"reviveSync",value:function reviveSync(e,t){return this.revive(e,_objectSpread2(_objectSpread2({throwOnBadSyncType:!0},t),{},{sync:!0}))}},{key:"reviveAsync",value:function reviveAsync(e,t){return this.revive(e,_objectSpread2(_objectSpread2({throwOnBadSyncType:!0},t),{},{sync:!1}))}},{key:"register",value:function register(e,t){var r=this,o=null!=t?t:{},a=function reg(e){i(e)?e.forEach((function(e){a(e)})):n(e).forEach((function(t){var n;if("#"===t)throw new TypeError("# cannot be used as a type name as it is reserved for cyclic objects");if(u.includes(t))throw new TypeError("Plain JSON object types are reserved as type names");var a=e[t],c=a&&"function"!=typeof a&&!Array.isArray(a)&&a.testPlainObjects?r.plainObjectReplacers:r.nonplainObjectReplacers,s=c.filter((function(e){return e.type===t}));if(s.length&&(c.splice(c.indexOf(s[0]),1),delete r.revivers[t],delete r.types[t]),"function"==typeof a){var y=a;a={test:function test(e){return e&&e.constructor===y},replace:function replace(e){return _objectSpread2({},e)},revive:function revive(e){return Object.assign(Object.create(y.prototype),e)}}}else if(i(a)){var l=_slicedToArray(a,3);a={test:l[0],replace:l[1],revive:l[2]}}if(null!==(n=a)&&void 0!==n&&n.test){var p={type:t,test:a.test.bind(a)};a.replace&&(p.replace=a.replace.bind(a)),a.replaceAsync&&(p.replaceAsync=a.replaceAsync.bind(a));var f="number"==typeof o.fallback?o.fallback:o.fallback?0:Number.POSITIVE_INFINITY;if(a.testPlainObjects?r.plainObjectReplacers.splice(f,0,p):r.nonplainObjectReplacers.splice(f,0,p),a.revive||a.reviveAsync){var v={};a.revive&&(v.revive=a.revive.bind(a)),a.reviveAsync&&(v.reviveAsync=a.reviveAsync.bind(a)),r.revivers[t]=[v,{plain:a.testPlainObjects}]}r.types[t]=a}}))};return[].concat(e).forEach((function(e){a(e)})),this}}])}(),s=_createClass((function Undefined(){_classCallCheck(this,Undefined)}));s.__typeson__type__="TypesonUndefined";var u=["null","boolean","number","string","array","object"];export{u as JSON_TYPES,c as Typeson,e as TypesonPromise,s as Undefined,escapeKeyPathComponent,getByKeyPath,getJSONType,hasConstructorOf,isObject,isPlainObject,isThenable,isUserObject,setAtKeyPath,toStringTag,unescapeKeyPathComponent};