UNPKG

parse-part-json

Version:

Can parse an incomplete JSON string

2 lines (1 loc) 3.24 kB
let defaultOption={tolerateBasicIncomplete:!0},BasicParseIncomplete=new Error("BasicParseIncomplete"),UnexpectedCharacter=new Error("UnexpectedCharacter");function parseByObject(e,r,t){t=t||defaultOption;var a={};let n=r,i=null,l=void 0,c=!1;for(;e.length>n;){var o=e[n];if("}"===o){if(null!==i&&void 0!==l)break;if(null!=i||null!=l||c)throw UnexpectedCharacter;break}if('"'===o){if(null===i&&!c){var{endIndex:s,data:d}=parseByString(e,n+1,t);n=s,i=d;continue}if(null!==i&&!c)throw UnexpectedCharacter;if(null!==i&&void 0!==l&&c)throw UnexpectedCharacter}if(":"===o){if(null===i)throw UnexpectedCharacter;c=!0,n++}else if(","===o){if(null===i||null===l)throw UnexpectedCharacter;i=null,l=void 0,c=!1,n++}else if(" "===o||"\n"===o)n++;else{if(!c||null==i)throw UnexpectedCharacter;var{endIndex:s,data:d}=parseByValue(e,n,t);l=d,a[i]=d,n=s}}return{endIndex:n+1,data:a}}function parseByValue(e,r,t){let a=r;for(;e.length>a;){var n=e[a];if(" "!==n&&"\n"!==n){if("t"===n||"f"===n)return parseByBoolean(e,a+1,n,t);if('"'==n)return parseByString(e,a+1,t);if("{"==n)return parseByObject(e,a+1,t);if("["==n)return parseByArray(e,a+1,t);if("n"==n)return parseNull(e,a+1,t);if("0"<=n&&n<="9"||"-"===n)return parseByNumber(e,a+1,n);throw UnexpectedCharacter}a++}throw UnexpectedCharacter}function parseByArray(e,r,t){var a=[];let n=r,i=void 0,l=!1;for(;e.length>n&&"]"!=e[n];)if(" "==e[n]||"\n"==e[n])n++;else if(","==e[n]){if(void 0===i)throw UnexpectedCharacter;if(l)throw UnexpectedCharacter;a.push(i),i=void 0,n++,l=!0}else{if(void 0!==i)throw UnexpectedCharacter;var{endIndex:c,data:o}=parseByValue(e,n,t);l=!1,i=o,n=c}return void 0!==i&&a.push(i),{endIndex:n+1,data:a}}let escapeMap={'"':'"',"\\":"\\","/":"/",b:"\b",f:"\f",n:"\n",r:"\r",t:"\t"};function parseByString(e,r,t){let a="",n=r,i=n,l=!1;for(;;){if(e.length<=n){if(t.tolerateBasicIncomplete)return a+=e.substring(i,n),{endIndex:n,data:a};throw BasicParseIncomplete}if(l){var c=escapeMap[e[n]];if(!c)throw UnexpectedCharacter;a+=c,l=!1,n++,i=n}else if("\\"==e[n])a+=e.substring(i,n),n++,l=!0;else{if('"'==e[n])return a+=e.substring(i,n),{endIndex:n+1,data:a};n++}}}function isMatchText(e,r,t,a){let n=0;for(;n<t.length;){if(r+n>=e.length){if(a)return;throw BasicParseIncomplete}if(t[n]!==e[r+n])throw UnexpectedCharacter;n++}}function parseByBoolean(e,r,t,a){var n="f"==t?"alse":"rue";return isMatchText(e,r,n,a.tolerateBasicIncomplete),{endIndex:r+n.length,data:"t"==t}}function parseNull(e,r,t){return isMatchText(e,r,"ull",t.tolerateBasicIncomplete),{endIndex:r+3,data:null}}function parseByNumber(e,r,t,a){let n=t,i=r,l=!1;for(var c=[" ",",","}","]","\n","\r","\t"];e.length>i;){var o=e[i];if("0"<=o&&o<="9")n+=o;else if("."===o){if(l)throw UnexpectedCharacter;n+=o,l=!0}else{if("e"!==o&&"E"!==o&&"+"!==o){if("-"!==o&&c.includes(o))break;throw UnexpectedCharacter}n+=o}i++}t=Number(n);if(isNaN(t))throw UnexpectedCharacter;return{endIndex:i,data:t}}function parsePartJson(e,r){if("string"!=typeof e)throw TypeError("json must be a string");if(!e.trim())throw Error("json must be not empty");var{data:r,endIndex:t}=parseByValue(e,0,Object.assign({},defaultOption,r));if(t<e.length)throw UnexpectedCharacter;return r}export{BasicParseIncomplete,UnexpectedCharacter,parsePartJson};