jsonrepair
Version:
Repair broken JSON documents
3 lines • 6.32 kB
JavaScript
((t,n)=>{"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((t="undefined"!=typeof globalThis?globalThis:t||self).JSONRepair={})})(this,function(t){class x extends Error{constructor(t,n){super(t+" at position "+n),this.position=n}}let r=32,e=10,i=9,f=13,a=160,g=6158,y=8192,O=8203,N=8239,J=8287,S=12288,j=65279;function k(t){return"0"<=t&&t<="9"}function C(t){return",:[]/{}()\n+".includes(t)}function m(t){return"a"<=t&&t<="z"||"A"<=t&&t<="Z"||"_"===t||"$"===t}function z(t){return"a"<=t&&t<="z"||"A"<=t&&t<="Z"||"_"===t||"$"===t||"0"<=t&&t<="9"}let E=/^(http|https|ftp|mailto|file|data|irc):\/\/$/,I=/^[A-Za-z0-9-._~:/?#@!$&'()*+;=]$/;function T(t){return",[]/{}\n+".includes(t)}function Z(t){return R(t)||n.test(t)}let n=/^[[{\w-]$/;function _(t,n){t=t.charCodeAt(n);return t===r||t===e||t===i||t===f}function F(t,n){t=t.charCodeAt(n);return t===r||t===i||t===f}function R(t){return U(t)||B(t)}function U(t){return'"'===t||"“"===t||"”"===t}function q(t){return'"'===t}function B(t){return"'"===t||"‘"===t||"’"===t||"`"===t||"´"===t}function D(t){return"'"===t}function G(t,n,r){r=2<arguments.length&&void 0!==r&&r,n=t.lastIndexOf(n);return-1!==n?t.substring(0,n)+(r?"":t.substring(n+1)):t}function H(t,n){let r=t.length;if(!_(t,r-1))return t+n;for(;_(t,r-1);)r--;return t.substring(0,r)+n+t.substring(r)}let K={"\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t"},L={'"':'"',"\\":"\\","/":"/",b:"\b",f:"\f",n:"\n",r:"\r",t:"\t"};t.JSONRepairError=x,t.jsonrepair=function(h){let d=0,v="";if(n(["```","[```","{```"]),!f())throw new x("Unexpected end of json string",h.length);n(["```","```]","```}"]);var t=u(",");if(t&&b(),Z(h[d])&&/[,\n][ \t\r]*$/.test(v)){t||(v=H(v,","));{let t=!0,n=!0;for(;n;)t?t=!1:u(",")||(v=H(v,",")),n=f();v=`[
${v=n?v:G(v,",")}
]`}}else t&&(v=G(v,","));for(;"}"===h[d]||"]"===h[d];)d++,b();if(d>=h.length)return v;throw new x("Unexpected character "+JSON.stringify(h[d]),d);function f(){b();var t=(()=>{if("{"!==h[d])return!1;{v+="{",d++,b(),p(",")&&b();let n=!0;for(;d<h.length&&"}"!==h[d];){let t;if(n?(t=!0,n=!1):((t=u(","))||(v=H(v,",")),b()),o(),!(w()||l(!0))){"}"===h[d]||"{"===h[d]||"]"===h[d]||"["===h[d]||void 0===h[d]?v=G(v,","):(()=>{throw new x("Object key expected",d)})();break}b();var r=u(":"),e=d>=h.length,i=(r||(Z(h[d])||e?v=H(v,":"):c()),f());i||(r||e?v+="null":c())}return"}"===h[d]?(v+="}",d++):v=H(v,"}"),!0}})()||(()=>{if("["!==h[d])return!1;{v+="[",d++,b(),p(",")&&b();let t=!0;for(;d<h.length&&"]"!==h[d];){t?t=!1:u(",")||(v=H(v,",")),o();var n=f();if(!n){v=G(v,",");break}}return"]"===h[d]?(v+="]",d++):v=H(v,"]"),!0}})()||w()||(()=>{var t,n,r=d;if("-"===h[d]){if(d++,i())return s(r),!0;if(!k(h[d]))return d=r,!1}for(;k(h[d]);)d++;if("."===h[d]){if(d++,i())return s(r),!0;if(!k(h[d]))return d=r,!1;for(;k(h[d]);)d++}if("e"===h[d]||"E"===h[d]){if(d++,"-"!==h[d]&&"+"!==h[d]||d++,i())return s(r),!0;if(!k(h[d]))return d=r,!1;for(;k(h[d]);)d++}if(i()){if(d>r)return t=h.slice(r,d),n=/^0\d/.test(t),v+=n?`"${t}"`:t,!0}else d=r;return!1})()||r("true","true")||r("false","false")||r("null","null")||r("True","true")||r("False","false")||r("None","null")||l(!1)||(()=>{if("/"===h[d]){var t=d;for(d++;d<h.length&&("/"!==h[d]||"\\"===h[d-1]);)d++;return d++,v+=JSON.stringify(h.substring(t,d)),!0}})();return b(),t}function b(t){var n=!(0<arguments.length&&void 0!==t)||t;d;let r=e(n);for(;r=(r=(()=>{if("/"===h[d]&&"*"===h[d+1]){for(;d<h.length&&!((t,n)=>"*"===t[n]&&"/"===t[n+1])(h,d);)d++;d+=2}else{if("/"!==h[d]||"/"!==h[d+1])return!1;for(;d<h.length&&"\n"!==h[d];)d++}return!0})())&&e(n););d}function e(t){var n,r,e=t?_:F;let i="";for(;;){if(e(h,d))i+=h[d];else{if(n=h,r=d,!((n=n.charCodeAt(r))===a||n===g||n>=y&&n<=O||n===N||n===J||n===S||n===j))break;i+=" "}d++}return 0<i.length&&(v+=i,!0)}function n(t){if((t=>{e(!0);for(var n of t){var r=d+n.length;if(h.slice(d,r)===n)return d=r,1}})(t)){if(m(h[d]))for(;d<h.length&&z(h[d]);)d++;b()}}function u(t){return h[d]===t&&(v+=h[d],d++,!0)}function p(t){return h[d]===t&&(d++,!0)}function o(){b(),"."===h[d]&&"."===h[d+1]&&"."===h[d+2]&&(d+=3,b(),p(","))}function w(t,n){var r=0<arguments.length&&void 0!==t&&t,e=1<arguments.length&&void 0!==n?n:-1;let i="\\"===h[d];if(i&&(d++,i=!0),R(h[d])){var f=q(h[d])?q:D(h[d])?D:B(h[d])?B:U,u=d,o=v.length;let n='"';for(d++;;){if(d>=h.length)return l=$(d-1),!r&&C(h.charAt(l))?(d=u,v=v.substring(0,o),w(!0)):(n=H(n,'"'),v+=n,!0);if(d===e)return n=H(n,'"'),v+=n,!0;if(f(h[d])){var l=d,s=n.length;if(n+='"',d++,v+=n,b(!1),r||d>=h.length||C(h[d])||R(h[d])||k(h[d]))return A(),!0;var c=$(l-1),a=h.charAt(c);if(","===a)return d=u,v=v.substring(0,o),w(!1,c);if(C(a))return d=u,v=v.substring(0,o),w(!0);v=v.substring(0,o),d=l+1,n=n.substring(0,s)+"\\"+n.substring(s)}else{if(r&&T(h[d])){if(":"===h[d-1]&&E.test(h.substring(u+1,d+2)))for(;d<h.length&&I.test(h[d]);)n+=h[d],d++;return n=H(n,'"'),v+=n,A(),!0}if("\\"===h[d]){c=h.charAt(d+1);if(void 0!==L[c])n+=h.slice(d,d+2),d+=2;else if("u"===c){let t=2;for(;t<6&&/^[0-9A-Fa-f]$/.test(h[d+t]);)t++;if(6===t)n+=h.slice(d,d+6),d+=6;else{if(!(d+t>=h.length))throw a=void 0,a=h.slice(d,d+6),new x(`Invalid unicode character "${a}"`,d);d=h.length}}else n+="\n"===c?"\\n":c,d+=2}else{var g,s=h.charAt(d);if('"'===s&&"\\"!==h[d-1])n+="\\"+s;else if("\n"===(g=s)||"\r"===g||"\t"===g||"\b"===g||"\f"===g)n+=K[s];else{if(!(" "<=s))throw g=void 0,g=s,new x("Invalid character "+JSON.stringify(g),d);n+=s}d++}}i&&p("\\")}}return!1}function A(){let t=!1;for(b();"+"===h[d];){t=!0,d++,b();var n=(v=G(v,'"',!0)).length,r=w();v=r?(r=v,n=n,e=1,r.substring(0,n)+r.substring(n+e)):H(v,'"')}var e;t}function r(t,n){return h.slice(d,d+t.length)===t&&(v+=n,d+=t.length,!0)}function l(t){var n=d;if(m(h[d])){for(;d<h.length&&z(h[d]);)d++;let t=d;for(;_(h,t);)t++;if("("===h[t])return d=t+1,f(),")"===h[d]&&(d++,";"===h[d])&&d++,!0}for(;d<h.length&&!T(h[d])&&!R(h[d])&&(!t||":"!==h[d]);)d++;if(":"===h[d-1]&&E.test(h.substring(n,d+2)))for(;d<h.length&&I.test(h[d]);)d++;if(d>n){for(;_(h,d-1)&&0<d;)d--;n=h.slice(n,d);return v+="undefined"===n?"null":JSON.stringify(n),'"'===h[d]&&d++,!0}}function $(t){let n=t;for(;0<n&&_(h,n);)n--;return n}function i(){return d>=h.length||C(h[d])||_(h,d)}function s(t){v+=h.slice(t,d)+"0"}function c(){throw new x("Colon expected",d)}}});