fast-xml-parser 5.3.5 → 5.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/lib/fxbuilder.min.js +1 -1
- package/lib/fxbuilder.min.js.map +1 -1
- package/lib/fxp.cjs +1 -1
- package/lib/fxp.d.cts +75 -12
- package/lib/fxp.min.js +1 -1
- package/lib/fxp.min.js.map +1 -1
- package/lib/fxparser.min.js +1 -1
- package/lib/fxparser.min.js.map +1 -1
- package/lib/fxvalidator.min.js +1 -1
- package/lib/fxvalidator.min.js.map +1 -1
- package/package.json +4 -4
- package/src/fxp.d.ts +74 -12
- package/src/util.js +1 -26
- package/src/xmlparser/DocTypeReader.js +63 -53
- package/src/xmlparser/OptionsBuilder.js +84 -44
- package/src/xmlparser/OrderedObjParser.js +254 -187
package/lib/fxvalidator.min.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.XMLValidator=t():e.XMLValidator=t()}(this,(
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.XMLValidator=t():e.XMLValidator=t()}(this,()=>(()=>{"use strict";var e={d:(t,r)=>{for(var n in r)e.o(r,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:r[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{validate:()=>l});var r=":A-Za-z_\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD",n=new RegExp("^["+r+"]["+r+"\\-.\\d\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*$"),i=function(e){return!(null==n.exec(e))},a={allowBooleanAttributes:!1,unpairedTags:[]};function l(e,t){t=Object.assign({},a,t);var r=[],n=!1,i=!1;"\ufeff"===e[0]&&(e=e.substr(1));for(var l=0;l<e.length;l++)if("<"===e[l]&&"?"===e[l+1]){if((l=o(e,l+=2)).err)return l}else{if("<"!==e[l]){if(u(e[l]))continue;return p("InvalidChar","char '"+e[l]+"' is not expected.",F(e,l))}var s=l;if("!"===e[++l]){l=f(e,l);continue}var g=!1;"/"===e[l]&&(g=!0,l++);for(var v="";l<e.length&&">"!==e[l]&&" "!==e[l]&&"\t"!==e[l]&&"\n"!==e[l]&&"\r"!==e[l];l++)v+=e[l];if("/"===(v=v.trim())[v.length-1]&&(v=v.substring(0,v.length-1),l--),!m(v))return p("InvalidTag",0===v.trim().length?"Invalid space after '<'.":"Tag '"+v+"' is an invalid name.",F(e,l));var b=d(e,l);if(!1===b)return p("InvalidAttr","Attributes for '"+v+"' have open quote.",F(e,l));var I=b.value;if(l=b.index,"/"===I[I.length-1]){var x=l-I.length,A=c(I=I.substring(0,I.length-1),t);if(!0!==A)return p(A.err.code,A.err.msg,F(e,x+A.err.line));n=!0}else if(g){if(!b.tagClosed)return p("InvalidTag","Closing tag '"+v+"' doesn't have proper closing.",F(e,l));if(I.trim().length>0)return p("InvalidTag","Closing tag '"+v+"' can't have attributes or invalid starting.",F(e,s));if(0===r.length)return p("InvalidTag","Closing tag '"+v+"' has not been opened.",F(e,s));var y=r.pop();if(v!==y.tagName){var C=F(e,y.tagStartPos);return p("InvalidTag","Expected closing tag '"+y.tagName+"' (opened in line "+C.line+", col "+C.col+") instead of closing tag '"+v+"'.",F(e,s))}0==r.length&&(i=!0)}else{var T=c(I,t);if(!0!==T)return p(T.err.code,T.err.msg,F(e,l-I.length+T.err.line));if(!0===i)return p("InvalidXml","Multiple possible root nodes found.",F(e,l));-1!==t.unpairedTags.indexOf(v)||r.push({tagName:v,tagStartPos:s}),n=!0}for(l++;l<e.length;l++)if("<"===e[l]){if("!"===e[l+1]){l=f(e,++l);continue}if("?"!==e[l+1])break;if((l=o(e,++l)).err)return l}else if("&"===e[l]){var S=h(e,l);if(-1==S)return p("InvalidChar","char '&' is not expected.",F(e,l));l=S}else if(!0===i&&!u(e[l]))return p("InvalidXml","Extra text at the end",F(e,l));"<"===e[l]&&l--}return n?1==r.length?p("InvalidTag","Unclosed tag '"+r[0].tagName+"'.",F(e,r[0].tagStartPos)):!(r.length>0)||p("InvalidXml","Invalid '"+JSON.stringify(r.map(function(e){return e.tagName}),null,4).replace(/\r?\n/g,"")+"' found.",{line:1,col:1}):p("InvalidXml","Start tag expected.",1)}function u(e){return" "===e||"\t"===e||"\n"===e||"\r"===e}function o(e,t){for(var r=t;t<e.length;t++)if("?"!=e[t]&&" "!=e[t]);else{var n=e.substr(r,t-r);if(t>5&&"xml"===n)return p("InvalidXml","XML declaration allowed only at the start of the document.",F(e,t));if("?"==e[t]&&">"==e[t+1]){t++;break}}return t}function f(e,t){if(e.length>t+5&&"-"===e[t+1]&&"-"===e[t+2]){for(t+=3;t<e.length;t++)if("-"===e[t]&&"-"===e[t+1]&&">"===e[t+2]){t+=2;break}}else if(e.length>t+8&&"D"===e[t+1]&&"O"===e[t+2]&&"C"===e[t+3]&&"T"===e[t+4]&&"Y"===e[t+5]&&"P"===e[t+6]&&"E"===e[t+7]){var r=1;for(t+=8;t<e.length;t++)if("<"===e[t])r++;else if(">"===e[t]&&0===--r)break}else if(e.length>t+9&&"["===e[t+1]&&"C"===e[t+2]&&"D"===e[t+3]&&"A"===e[t+4]&&"T"===e[t+5]&&"A"===e[t+6]&&"["===e[t+7])for(t+=8;t<e.length;t++)if("]"===e[t]&&"]"===e[t+1]&&">"===e[t+2]){t+=2;break}return t}var s='"',g="'";function d(e,t){for(var r="",n="",i=!1;t<e.length;t++){if(e[t]===s||e[t]===g)""===n?n=e[t]:n!==e[t]||(n="");else if(">"===e[t]&&""===n){i=!0;break}r+=e[t]}return""===n&&{value:r,index:t,tagClosed:i}}var v=new RegExp("(\\s*)([^\\s=]+)(\\s*=)?(\\s*(['\"])(([\\s\\S])*?)\\5)?","g");function c(e,t){for(var r=function(e,t){for(var r=[],n=t.exec(e);n;){var i=[];i.startIndex=t.lastIndex-n[0].length;for(var a=n.length,l=0;l<a;l++)i.push(n[l]);r.push(i),n=t.exec(e)}return r}(e,v),n={},i=0;i<r.length;i++){if(0===r[i][1].length)return p("InvalidAttr","Attribute '"+r[i][2]+"' has no space in starting.",I(r[i]));if(void 0!==r[i][3]&&void 0===r[i][4])return p("InvalidAttr","Attribute '"+r[i][2]+"' is without value.",I(r[i]));if(void 0===r[i][3]&&!t.allowBooleanAttributes)return p("InvalidAttr","boolean attribute '"+r[i][2]+"' is not allowed.",I(r[i]));var a=r[i][2];if(!b(a))return p("InvalidAttr","Attribute '"+a+"' is an invalid name.",I(r[i]));if(n.hasOwnProperty(a))return p("InvalidAttr","Attribute '"+a+"' is repeated.",I(r[i]));n[a]=1}return!0}function h(e,t){if(";"===e[++t])return-1;if("#"===e[t])return function(e,t){var r=/\d/;for("x"===e[t]&&(t++,r=/[\da-fA-F]/);t<e.length;t++){if(";"===e[t])return t;if(!e[t].match(r))break}return-1}(e,++t);for(var r=0;t<e.length;t++,r++)if(!(e[t].match(/\w/)&&r<20)){if(";"===e[t])break;return-1}return t}function p(e,t,r){return{err:{code:e,msg:t,line:r.line||r,col:r.col}}}function b(e){return i(e)}function m(e){return i(e)}function F(e,t){var r=e.substring(0,t).split(/\r?\n/);return{line:r.length,col:r[r.length-1].length+1}}function I(e){return e.startIndex+e[1].length}return t})());
|
|
2
2
|
//# sourceMappingURL=fxvalidator.min.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"./lib/fxvalidator.min.js","mappings":"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","sources":["webpack://XMLValidator/webpack/universalModuleDefinition","webpack://XMLValidator/webpack/bootstrap","webpack://XMLValidator/webpack/runtime/define property getters","webpack://XMLValidator/webpack/runtime/hasOwnProperty shorthand","webpack://XMLValidator/webpack/runtime/make namespace object","webpack://XMLValidator/./src/util.js","webpack://XMLValidator/./src/validator.js"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"XMLValidator\"] = factory();\n\telse\n\t\troot[\"XMLValidator\"] = factory();\n})(this, () => {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","'use strict';\n\nconst nameStartChar = ':A-Za-z_\\\\u00C0-\\\\u00D6\\\\u00D8-\\\\u00F6\\\\u00F8-\\\\u02FF\\\\u0370-\\\\u037D\\\\u037F-\\\\u1FFF\\\\u200C-\\\\u200D\\\\u2070-\\\\u218F\\\\u2C00-\\\\u2FEF\\\\u3001-\\\\uD7FF\\\\uF900-\\\\uFDCF\\\\uFDF0-\\\\uFFFD';\nconst nameChar = nameStartChar + '\\\\-.\\\\d\\\\u00B7\\\\u0300-\\\\u036F\\\\u203F-\\\\u2040';\nexport const nameRegexp = '[' + nameStartChar + '][' + nameChar + ']*';\nconst regexName = new RegExp('^' + nameRegexp + '$');\n\nexport function getAllMatches(string, regex) {\n const matches = [];\n let match = regex.exec(string);\n while (match) {\n const allmatches = [];\n allmatches.startIndex = regex.lastIndex - match[0].length;\n const len = match.length;\n for (let index = 0; index < len; index++) {\n allmatches.push(match[index]);\n }\n matches.push(allmatches);\n match = regex.exec(string);\n }\n return matches;\n}\n\nexport const isName = function(string) {\n const match = regexName.exec(string);\n return !(match === null || typeof match === 'undefined');\n}\n\nexport function isExist(v) {\n return typeof v !== 'undefined';\n}\n\nexport function isEmptyObject(obj) {\n return Object.keys(obj).length === 0;\n}\n\n/**\n * Copy all the properties of a into b.\n * @param {*} target\n * @param {*} a\n */\nexport function merge(target, a, arrayMode) {\n if (a) {\n const keys = Object.keys(a); // will return an array of own properties\n const len = keys.length; //don't make it inline\n for (let i = 0; i < len; i++) {\n if (arrayMode === 'strict') {\n target[keys[i]] = [ a[keys[i]] ];\n } else {\n target[keys[i]] = a[keys[i]];\n }\n }\n }\n}\n/* exports.merge =function (b,a){\n return Object.assign(b,a);\n} */\n\nexport function getValue(v) {\n if (exports.isExist(v)) {\n return v;\n } else {\n return '';\n }\n}\n\n// const fakeCall = function(a) {return a;};\n// const fakeCallNoReturn = function() {};","'use strict';\n\nimport {getAllMatches, isName} from './util.js';\n\nconst defaultOptions = {\n allowBooleanAttributes: false, //A tag can have attributes without any value\n unpairedTags: []\n};\n\n//const tagsPattern = new RegExp(\"<\\\\/?([\\\\w:\\\\-_\\.]+)\\\\s*\\/?>\",\"g\");\nexport function validate(xmlData, options) {\n options = Object.assign({}, defaultOptions, options);\n\n //xmlData = xmlData.replace(/(\\r\\n|\\n|\\r)/gm,\"\");//make it single line\n //xmlData = xmlData.replace(/(^\\s*<\\?xml.*?\\?>)/g,\"\");//Remove XML starting tag\n //xmlData = xmlData.replace(/(<!DOCTYPE[\\s\\w\\\"\\.\\/\\-\\:]+(\\[.*\\])*\\s*>)/g,\"\");//Remove DOCTYPE\n const tags = [];\n let tagFound = false;\n\n //indicates that the root tag has been closed (aka. depth 0 has been reached)\n let reachedRoot = false;\n\n if (xmlData[0] === '\\ufeff') {\n // check for byte order mark (BOM)\n xmlData = xmlData.substr(1);\n }\n \n for (let i = 0; i < xmlData.length; i++) {\n\n if (xmlData[i] === '<' && xmlData[i+1] === '?') {\n i+=2;\n i = readPI(xmlData,i);\n if (i.err) return i;\n }else if (xmlData[i] === '<') {\n //starting of tag\n //read until you reach to '>' avoiding any '>' in attribute value\n let tagStartPos = i;\n i++;\n \n if (xmlData[i] === '!') {\n i = readCommentAndCDATA(xmlData, i);\n continue;\n } else {\n let closingTag = false;\n if (xmlData[i] === '/') {\n //closing tag\n closingTag = true;\n i++;\n }\n //read tagname\n let tagName = '';\n for (; i < xmlData.length &&\n xmlData[i] !== '>' &&\n xmlData[i] !== ' ' &&\n xmlData[i] !== '\\t' &&\n xmlData[i] !== '\\n' &&\n xmlData[i] !== '\\r'; i++\n ) {\n tagName += xmlData[i];\n }\n tagName = tagName.trim();\n //console.log(tagName);\n\n if (tagName[tagName.length - 1] === '/') {\n //self closing tag without attributes\n tagName = tagName.substring(0, tagName.length - 1);\n //continue;\n i--;\n }\n if (!validateTagName(tagName)) {\n let msg;\n if (tagName.trim().length === 0) {\n msg = \"Invalid space after '<'.\";\n } else {\n msg = \"Tag '\"+tagName+\"' is an invalid name.\";\n }\n return getErrorObject('InvalidTag', msg, getLineNumberForPosition(xmlData, i));\n }\n\n const result = readAttributeStr(xmlData, i);\n if (result === false) {\n return getErrorObject('InvalidAttr', \"Attributes for '\"+tagName+\"' have open quote.\", getLineNumberForPosition(xmlData, i));\n }\n let attrStr = result.value;\n i = result.index;\n\n if (attrStr[attrStr.length - 1] === '/') {\n //self closing tag\n const attrStrStart = i - attrStr.length;\n attrStr = attrStr.substring(0, attrStr.length - 1);\n const isValid = validateAttributeString(attrStr, options);\n if (isValid === true) {\n tagFound = true;\n //continue; //text may presents after self closing tag\n } else {\n //the result from the nested function returns the position of the error within the attribute\n //in order to get the 'true' error line, we need to calculate the position where the attribute begins (i - attrStr.length) and then add the position within the attribute\n //this gives us the absolute index in the entire xml, which we can use to find the line at last\n return getErrorObject(isValid.err.code, isValid.err.msg, getLineNumberForPosition(xmlData, attrStrStart + isValid.err.line));\n }\n } else if (closingTag) {\n if (!result.tagClosed) {\n return getErrorObject('InvalidTag', \"Closing tag '\"+tagName+\"' doesn't have proper closing.\", getLineNumberForPosition(xmlData, i));\n } else if (attrStr.trim().length > 0) {\n return getErrorObject('InvalidTag', \"Closing tag '\"+tagName+\"' can't have attributes or invalid starting.\", getLineNumberForPosition(xmlData, tagStartPos));\n } else if (tags.length === 0) {\n return getErrorObject('InvalidTag', \"Closing tag '\"+tagName+\"' has not been opened.\", getLineNumberForPosition(xmlData, tagStartPos));\n } else {\n const otg = tags.pop();\n if (tagName !== otg.tagName) {\n let openPos = getLineNumberForPosition(xmlData, otg.tagStartPos);\n return getErrorObject('InvalidTag',\n \"Expected closing tag '\"+otg.tagName+\"' (opened in line \"+openPos.line+\", col \"+openPos.col+\") instead of closing tag '\"+tagName+\"'.\",\n getLineNumberForPosition(xmlData, tagStartPos));\n }\n\n //when there are no more tags, we reached the root level.\n if (tags.length == 0) {\n reachedRoot = true;\n }\n }\n } else {\n const isValid = validateAttributeString(attrStr, options);\n if (isValid !== true) {\n //the result from the nested function returns the position of the error within the attribute\n //in order to get the 'true' error line, we need to calculate the position where the attribute begins (i - attrStr.length) and then add the position within the attribute\n //this gives us the absolute index in the entire xml, which we can use to find the line at last\n return getErrorObject(isValid.err.code, isValid.err.msg, getLineNumberForPosition(xmlData, i - attrStr.length + isValid.err.line));\n }\n\n //if the root level has been reached before ...\n if (reachedRoot === true) {\n return getErrorObject('InvalidXml', 'Multiple possible root nodes found.', getLineNumberForPosition(xmlData, i));\n } else if(options.unpairedTags.indexOf(tagName) !== -1){\n //don't push into stack\n } else {\n tags.push({tagName, tagStartPos});\n }\n tagFound = true;\n }\n\n //skip tag text value\n //It may include comments and CDATA value\n for (i++; i < xmlData.length; i++) {\n if (xmlData[i] === '<') {\n if (xmlData[i + 1] === '!') {\n //comment or CADATA\n i++;\n i = readCommentAndCDATA(xmlData, i);\n continue;\n } else if (xmlData[i+1] === '?') {\n i = readPI(xmlData, ++i);\n if (i.err) return i;\n } else{\n break;\n }\n } else if (xmlData[i] === '&') {\n const afterAmp = validateAmpersand(xmlData, i);\n if (afterAmp == -1)\n return getErrorObject('InvalidChar', \"char '&' is not expected.\", getLineNumberForPosition(xmlData, i));\n i = afterAmp;\n }else{\n if (reachedRoot === true && !isWhiteSpace(xmlData[i])) {\n return getErrorObject('InvalidXml', \"Extra text at the end\", getLineNumberForPosition(xmlData, i));\n }\n }\n } //end of reading tag text value\n if (xmlData[i] === '<') {\n i--;\n }\n }\n } else {\n if ( isWhiteSpace(xmlData[i])) {\n continue;\n }\n return getErrorObject('InvalidChar', \"char '\"+xmlData[i]+\"' is not expected.\", getLineNumberForPosition(xmlData, i));\n }\n }\n\n if (!tagFound) {\n return getErrorObject('InvalidXml', 'Start tag expected.', 1);\n }else if (tags.length == 1) {\n return getErrorObject('InvalidTag', \"Unclosed tag '\"+tags[0].tagName+\"'.\", getLineNumberForPosition(xmlData, tags[0].tagStartPos));\n }else if (tags.length > 0) {\n return getErrorObject('InvalidXml', \"Invalid '\"+\n JSON.stringify(tags.map(t => t.tagName), null, 4).replace(/\\r?\\n/g, '')+\n \"' found.\", {line: 1, col: 1});\n }\n\n return true;\n};\n\nfunction isWhiteSpace(char){\n return char === ' ' || char === '\\t' || char === '\\n' || char === '\\r';\n}\n/**\n * Read Processing insstructions and skip\n * @param {*} xmlData\n * @param {*} i\n */\nfunction readPI(xmlData, i) {\n const start = i;\n for (; i < xmlData.length; i++) {\n if (xmlData[i] == '?' || xmlData[i] == ' ') {\n //tagname\n const tagname = xmlData.substr(start, i - start);\n if (i > 5 && tagname === 'xml') {\n return getErrorObject('InvalidXml', 'XML declaration allowed only at the start of the document.', getLineNumberForPosition(xmlData, i));\n } else if (xmlData[i] == '?' && xmlData[i + 1] == '>') {\n //check if valid attribut string\n i++;\n break;\n } else {\n continue;\n }\n }\n }\n return i;\n}\n\nfunction readCommentAndCDATA(xmlData, i) {\n if (xmlData.length > i + 5 && xmlData[i + 1] === '-' && xmlData[i + 2] === '-') {\n //comment\n for (i += 3; i < xmlData.length; i++) {\n if (xmlData[i] === '-' && xmlData[i + 1] === '-' && xmlData[i + 2] === '>') {\n i += 2;\n break;\n }\n }\n } else if (\n xmlData.length > i + 8 &&\n xmlData[i + 1] === 'D' &&\n xmlData[i + 2] === 'O' &&\n xmlData[i + 3] === 'C' &&\n xmlData[i + 4] === 'T' &&\n xmlData[i + 5] === 'Y' &&\n xmlData[i + 6] === 'P' &&\n xmlData[i + 7] === 'E'\n ) {\n let angleBracketsCount = 1;\n for (i += 8; i < xmlData.length; i++) {\n if (xmlData[i] === '<') {\n angleBracketsCount++;\n } else if (xmlData[i] === '>') {\n angleBracketsCount--;\n if (angleBracketsCount === 0) {\n break;\n }\n }\n }\n } else if (\n xmlData.length > i + 9 &&\n xmlData[i + 1] === '[' &&\n xmlData[i + 2] === 'C' &&\n xmlData[i + 3] === 'D' &&\n xmlData[i + 4] === 'A' &&\n xmlData[i + 5] === 'T' &&\n xmlData[i + 6] === 'A' &&\n xmlData[i + 7] === '['\n ) {\n for (i += 8; i < xmlData.length; i++) {\n if (xmlData[i] === ']' && xmlData[i + 1] === ']' && xmlData[i + 2] === '>') {\n i += 2;\n break;\n }\n }\n }\n\n return i;\n}\n\nconst doubleQuote = '\"';\nconst singleQuote = \"'\";\n\n/**\n * Keep reading xmlData until '<' is found outside the attribute value.\n * @param {string} xmlData\n * @param {number} i\n */\nfunction readAttributeStr(xmlData, i) {\n let attrStr = '';\n let startChar = '';\n let tagClosed = false;\n for (; i < xmlData.length; i++) {\n if (xmlData[i] === doubleQuote || xmlData[i] === singleQuote) {\n if (startChar === '') {\n startChar = xmlData[i];\n } else if (startChar !== xmlData[i]) {\n //if vaue is enclosed with double quote then single quotes are allowed inside the value and vice versa\n } else {\n startChar = '';\n }\n } else if (xmlData[i] === '>') {\n if (startChar === '') {\n tagClosed = true;\n break;\n }\n }\n attrStr += xmlData[i];\n }\n if (startChar !== '') {\n return false;\n }\n\n return {\n value: attrStr,\n index: i,\n tagClosed: tagClosed\n };\n}\n\n/**\n * Select all the attributes whether valid or invalid.\n */\nconst validAttrStrRegxp = new RegExp('(\\\\s*)([^\\\\s=]+)(\\\\s*=)?(\\\\s*([\\'\"])(([\\\\s\\\\S])*?)\\\\5)?', 'g');\n\n//attr, =\"sd\", a=\"amit's\", a=\"sd\"b=\"saf\", ab cd=\"\"\n\nfunction validateAttributeString(attrStr, options) {\n //console.log(\"start:\"+attrStr+\":end\");\n\n //if(attrStr.trim().length === 0) return true; //empty string\n\n const matches = getAllMatches(attrStr, validAttrStrRegxp);\n const attrNames = {};\n\n for (let i = 0; i < matches.length; i++) {\n if (matches[i][1].length === 0) {\n //nospace before attribute name: a=\"sd\"b=\"saf\"\n return getErrorObject('InvalidAttr', \"Attribute '\"+matches[i][2]+\"' has no space in starting.\", getPositionFromMatch(matches[i]))\n } else if (matches[i][3] !== undefined && matches[i][4] === undefined) {\n return getErrorObject('InvalidAttr', \"Attribute '\"+matches[i][2]+\"' is without value.\", getPositionFromMatch(matches[i]));\n } else if (matches[i][3] === undefined && !options.allowBooleanAttributes) {\n //independent attribute: ab\n return getErrorObject('InvalidAttr', \"boolean attribute '\"+matches[i][2]+\"' is not allowed.\", getPositionFromMatch(matches[i]));\n }\n /* else if(matches[i][6] === undefined){//attribute without value: ab=\n return { err: { code:\"InvalidAttr\",msg:\"attribute \" + matches[i][2] + \" has no value assigned.\"}};\n } */\n const attrName = matches[i][2];\n if (!validateAttrName(attrName)) {\n return getErrorObject('InvalidAttr', \"Attribute '\"+attrName+\"' is an invalid name.\", getPositionFromMatch(matches[i]));\n }\n if (!attrNames.hasOwnProperty(attrName)) {\n //check for duplicate attribute.\n attrNames[attrName] = 1;\n } else {\n return getErrorObject('InvalidAttr', \"Attribute '\"+attrName+\"' is repeated.\", getPositionFromMatch(matches[i]));\n }\n }\n\n return true;\n}\n\nfunction validateNumberAmpersand(xmlData, i) {\n let re = /\\d/;\n if (xmlData[i] === 'x') {\n i++;\n re = /[\\da-fA-F]/;\n }\n for (; i < xmlData.length; i++) {\n if (xmlData[i] === ';')\n return i;\n if (!xmlData[i].match(re))\n break;\n }\n return -1;\n}\n\nfunction validateAmpersand(xmlData, i) {\n // https://www.w3.org/TR/xml/#dt-charref\n i++;\n if (xmlData[i] === ';')\n return -1;\n if (xmlData[i] === '#') {\n i++;\n return validateNumberAmpersand(xmlData, i);\n }\n let count = 0;\n for (; i < xmlData.length; i++, count++) {\n if (xmlData[i].match(/\\w/) && count < 20)\n continue;\n if (xmlData[i] === ';')\n break;\n return -1;\n }\n return i;\n}\n\nfunction getErrorObject(code, message, lineNumber) {\n return {\n err: {\n code: code,\n msg: message,\n line: lineNumber.line || lineNumber,\n col: lineNumber.col,\n },\n };\n}\n\nfunction validateAttrName(attrName) {\n return isName(attrName);\n}\n\n// const startsWithXML = /^xml/i;\n\nfunction validateTagName(tagname) {\n return isName(tagname) /* && !tagname.match(startsWithXML) */;\n}\n\n//this function returns the line number for the character at the given index\nfunction getLineNumberForPosition(xmlData, index) {\n const lines = xmlData.substring(0, index).split(/\\r?\\n/);\n return {\n line: lines.length,\n\n // column number is last line's length + 1, because column numbering starts at 1:\n col: lines[lines.length - 1].length + 1\n };\n}\n\n//this function returns the position of the first character of match within attrStr\nfunction getPositionFromMatch(match) {\n return match.startIndex + match[1].length;\n}\n"],"names":["root","factory","exports","module","define","amd","this","__webpack_require__","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","nameStartChar","regexName","RegExp","isName","string","exec","defaultOptions","allowBooleanAttributes","unpairedTags","validate","xmlData","options","assign","tags","tagFound","reachedRoot","substr","i","length","readPI","err","isWhiteSpace","getErrorObject","getLineNumberForPosition","tagStartPos","readCommentAndCDATA","closingTag","tagName","trim","substring","result","readAttributeStr","attrStr","index","attrStrStart","isValid","validateAttributeString","code","msg","line","tagClosed","otg","pop","openPos","col","indexOf","push","afterAmp","validateAmpersand","JSON","stringify","map","t","replace","char","start","tagname","angleBracketsCount","doubleQuote","singleQuote","startChar","validAttrStrRegxp","matches","regex","match","allmatches","startIndex","lastIndex","len","getAllMatches","attrNames","getPositionFromMatch","undefined","attrName","validateAttrName","re","validateNumberAmpersand","count","message","lineNumber","lines","split"],"sourceRoot":""}
|
|
1
|
+
{"version":3,"file":"./lib/fxvalidator.min.js","mappings":"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","sources":["webpack://XMLValidator/webpack/universalModuleDefinition","webpack://XMLValidator/webpack/bootstrap","webpack://XMLValidator/webpack/runtime/define property getters","webpack://XMLValidator/webpack/runtime/hasOwnProperty shorthand","webpack://XMLValidator/webpack/runtime/make namespace object","webpack://XMLValidator/./src/util.js","webpack://XMLValidator/./src/validator.js"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"XMLValidator\"] = factory();\n\telse\n\t\troot[\"XMLValidator\"] = factory();\n})(this, () => {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","'use strict';\n\nconst nameStartChar = ':A-Za-z_\\\\u00C0-\\\\u00D6\\\\u00D8-\\\\u00F6\\\\u00F8-\\\\u02FF\\\\u0370-\\\\u037D\\\\u037F-\\\\u1FFF\\\\u200C-\\\\u200D\\\\u2070-\\\\u218F\\\\u2C00-\\\\u2FEF\\\\u3001-\\\\uD7FF\\\\uF900-\\\\uFDCF\\\\uFDF0-\\\\uFFFD';\nconst nameChar = nameStartChar + '\\\\-.\\\\d\\\\u00B7\\\\u0300-\\\\u036F\\\\u203F-\\\\u2040';\nexport const nameRegexp = '[' + nameStartChar + '][' + nameChar + ']*';\nconst regexName = new RegExp('^' + nameRegexp + '$');\n\nexport function getAllMatches(string, regex) {\n const matches = [];\n let match = regex.exec(string);\n while (match) {\n const allmatches = [];\n allmatches.startIndex = regex.lastIndex - match[0].length;\n const len = match.length;\n for (let index = 0; index < len; index++) {\n allmatches.push(match[index]);\n }\n matches.push(allmatches);\n match = regex.exec(string);\n }\n return matches;\n}\n\nexport const isName = function (string) {\n const match = regexName.exec(string);\n return !(match === null || typeof match === 'undefined');\n}\n\nexport function isExist(v) {\n return typeof v !== 'undefined';\n}\n\nexport function isEmptyObject(obj) {\n return Object.keys(obj).length === 0;\n}\n\nexport function getValue(v) {\n if (exports.isExist(v)) {\n return v;\n } else {\n return '';\n }\n}\n","'use strict';\n\nimport {getAllMatches, isName} from './util.js';\n\nconst defaultOptions = {\n allowBooleanAttributes: false, //A tag can have attributes without any value\n unpairedTags: []\n};\n\n//const tagsPattern = new RegExp(\"<\\\\/?([\\\\w:\\\\-_\\.]+)\\\\s*\\/?>\",\"g\");\nexport function validate(xmlData, options) {\n options = Object.assign({}, defaultOptions, options);\n\n //xmlData = xmlData.replace(/(\\r\\n|\\n|\\r)/gm,\"\");//make it single line\n //xmlData = xmlData.replace(/(^\\s*<\\?xml.*?\\?>)/g,\"\");//Remove XML starting tag\n //xmlData = xmlData.replace(/(<!DOCTYPE[\\s\\w\\\"\\.\\/\\-\\:]+(\\[.*\\])*\\s*>)/g,\"\");//Remove DOCTYPE\n const tags = [];\n let tagFound = false;\n\n //indicates that the root tag has been closed (aka. depth 0 has been reached)\n let reachedRoot = false;\n\n if (xmlData[0] === '\\ufeff') {\n // check for byte order mark (BOM)\n xmlData = xmlData.substr(1);\n }\n \n for (let i = 0; i < xmlData.length; i++) {\n\n if (xmlData[i] === '<' && xmlData[i+1] === '?') {\n i+=2;\n i = readPI(xmlData,i);\n if (i.err) return i;\n }else if (xmlData[i] === '<') {\n //starting of tag\n //read until you reach to '>' avoiding any '>' in attribute value\n let tagStartPos = i;\n i++;\n \n if (xmlData[i] === '!') {\n i = readCommentAndCDATA(xmlData, i);\n continue;\n } else {\n let closingTag = false;\n if (xmlData[i] === '/') {\n //closing tag\n closingTag = true;\n i++;\n }\n //read tagname\n let tagName = '';\n for (; i < xmlData.length &&\n xmlData[i] !== '>' &&\n xmlData[i] !== ' ' &&\n xmlData[i] !== '\\t' &&\n xmlData[i] !== '\\n' &&\n xmlData[i] !== '\\r'; i++\n ) {\n tagName += xmlData[i];\n }\n tagName = tagName.trim();\n //console.log(tagName);\n\n if (tagName[tagName.length - 1] === '/') {\n //self closing tag without attributes\n tagName = tagName.substring(0, tagName.length - 1);\n //continue;\n i--;\n }\n if (!validateTagName(tagName)) {\n let msg;\n if (tagName.trim().length === 0) {\n msg = \"Invalid space after '<'.\";\n } else {\n msg = \"Tag '\"+tagName+\"' is an invalid name.\";\n }\n return getErrorObject('InvalidTag', msg, getLineNumberForPosition(xmlData, i));\n }\n\n const result = readAttributeStr(xmlData, i);\n if (result === false) {\n return getErrorObject('InvalidAttr', \"Attributes for '\"+tagName+\"' have open quote.\", getLineNumberForPosition(xmlData, i));\n }\n let attrStr = result.value;\n i = result.index;\n\n if (attrStr[attrStr.length - 1] === '/') {\n //self closing tag\n const attrStrStart = i - attrStr.length;\n attrStr = attrStr.substring(0, attrStr.length - 1);\n const isValid = validateAttributeString(attrStr, options);\n if (isValid === true) {\n tagFound = true;\n //continue; //text may presents after self closing tag\n } else {\n //the result from the nested function returns the position of the error within the attribute\n //in order to get the 'true' error line, we need to calculate the position where the attribute begins (i - attrStr.length) and then add the position within the attribute\n //this gives us the absolute index in the entire xml, which we can use to find the line at last\n return getErrorObject(isValid.err.code, isValid.err.msg, getLineNumberForPosition(xmlData, attrStrStart + isValid.err.line));\n }\n } else if (closingTag) {\n if (!result.tagClosed) {\n return getErrorObject('InvalidTag', \"Closing tag '\"+tagName+\"' doesn't have proper closing.\", getLineNumberForPosition(xmlData, i));\n } else if (attrStr.trim().length > 0) {\n return getErrorObject('InvalidTag', \"Closing tag '\"+tagName+\"' can't have attributes or invalid starting.\", getLineNumberForPosition(xmlData, tagStartPos));\n } else if (tags.length === 0) {\n return getErrorObject('InvalidTag', \"Closing tag '\"+tagName+\"' has not been opened.\", getLineNumberForPosition(xmlData, tagStartPos));\n } else {\n const otg = tags.pop();\n if (tagName !== otg.tagName) {\n let openPos = getLineNumberForPosition(xmlData, otg.tagStartPos);\n return getErrorObject('InvalidTag',\n \"Expected closing tag '\"+otg.tagName+\"' (opened in line \"+openPos.line+\", col \"+openPos.col+\") instead of closing tag '\"+tagName+\"'.\",\n getLineNumberForPosition(xmlData, tagStartPos));\n }\n\n //when there are no more tags, we reached the root level.\n if (tags.length == 0) {\n reachedRoot = true;\n }\n }\n } else {\n const isValid = validateAttributeString(attrStr, options);\n if (isValid !== true) {\n //the result from the nested function returns the position of the error within the attribute\n //in order to get the 'true' error line, we need to calculate the position where the attribute begins (i - attrStr.length) and then add the position within the attribute\n //this gives us the absolute index in the entire xml, which we can use to find the line at last\n return getErrorObject(isValid.err.code, isValid.err.msg, getLineNumberForPosition(xmlData, i - attrStr.length + isValid.err.line));\n }\n\n //if the root level has been reached before ...\n if (reachedRoot === true) {\n return getErrorObject('InvalidXml', 'Multiple possible root nodes found.', getLineNumberForPosition(xmlData, i));\n } else if(options.unpairedTags.indexOf(tagName) !== -1){\n //don't push into stack\n } else {\n tags.push({tagName, tagStartPos});\n }\n tagFound = true;\n }\n\n //skip tag text value\n //It may include comments and CDATA value\n for (i++; i < xmlData.length; i++) {\n if (xmlData[i] === '<') {\n if (xmlData[i + 1] === '!') {\n //comment or CADATA\n i++;\n i = readCommentAndCDATA(xmlData, i);\n continue;\n } else if (xmlData[i+1] === '?') {\n i = readPI(xmlData, ++i);\n if (i.err) return i;\n } else{\n break;\n }\n } else if (xmlData[i] === '&') {\n const afterAmp = validateAmpersand(xmlData, i);\n if (afterAmp == -1)\n return getErrorObject('InvalidChar', \"char '&' is not expected.\", getLineNumberForPosition(xmlData, i));\n i = afterAmp;\n }else{\n if (reachedRoot === true && !isWhiteSpace(xmlData[i])) {\n return getErrorObject('InvalidXml', \"Extra text at the end\", getLineNumberForPosition(xmlData, i));\n }\n }\n } //end of reading tag text value\n if (xmlData[i] === '<') {\n i--;\n }\n }\n } else {\n if ( isWhiteSpace(xmlData[i])) {\n continue;\n }\n return getErrorObject('InvalidChar', \"char '\"+xmlData[i]+\"' is not expected.\", getLineNumberForPosition(xmlData, i));\n }\n }\n\n if (!tagFound) {\n return getErrorObject('InvalidXml', 'Start tag expected.', 1);\n }else if (tags.length == 1) {\n return getErrorObject('InvalidTag', \"Unclosed tag '\"+tags[0].tagName+\"'.\", getLineNumberForPosition(xmlData, tags[0].tagStartPos));\n }else if (tags.length > 0) {\n return getErrorObject('InvalidXml', \"Invalid '\"+\n JSON.stringify(tags.map(t => t.tagName), null, 4).replace(/\\r?\\n/g, '')+\n \"' found.\", {line: 1, col: 1});\n }\n\n return true;\n};\n\nfunction isWhiteSpace(char){\n return char === ' ' || char === '\\t' || char === '\\n' || char === '\\r';\n}\n/**\n * Read Processing insstructions and skip\n * @param {*} xmlData\n * @param {*} i\n */\nfunction readPI(xmlData, i) {\n const start = i;\n for (; i < xmlData.length; i++) {\n if (xmlData[i] == '?' || xmlData[i] == ' ') {\n //tagname\n const tagname = xmlData.substr(start, i - start);\n if (i > 5 && tagname === 'xml') {\n return getErrorObject('InvalidXml', 'XML declaration allowed only at the start of the document.', getLineNumberForPosition(xmlData, i));\n } else if (xmlData[i] == '?' && xmlData[i + 1] == '>') {\n //check if valid attribut string\n i++;\n break;\n } else {\n continue;\n }\n }\n }\n return i;\n}\n\nfunction readCommentAndCDATA(xmlData, i) {\n if (xmlData.length > i + 5 && xmlData[i + 1] === '-' && xmlData[i + 2] === '-') {\n //comment\n for (i += 3; i < xmlData.length; i++) {\n if (xmlData[i] === '-' && xmlData[i + 1] === '-' && xmlData[i + 2] === '>') {\n i += 2;\n break;\n }\n }\n } else if (\n xmlData.length > i + 8 &&\n xmlData[i + 1] === 'D' &&\n xmlData[i + 2] === 'O' &&\n xmlData[i + 3] === 'C' &&\n xmlData[i + 4] === 'T' &&\n xmlData[i + 5] === 'Y' &&\n xmlData[i + 6] === 'P' &&\n xmlData[i + 7] === 'E'\n ) {\n let angleBracketsCount = 1;\n for (i += 8; i < xmlData.length; i++) {\n if (xmlData[i] === '<') {\n angleBracketsCount++;\n } else if (xmlData[i] === '>') {\n angleBracketsCount--;\n if (angleBracketsCount === 0) {\n break;\n }\n }\n }\n } else if (\n xmlData.length > i + 9 &&\n xmlData[i + 1] === '[' &&\n xmlData[i + 2] === 'C' &&\n xmlData[i + 3] === 'D' &&\n xmlData[i + 4] === 'A' &&\n xmlData[i + 5] === 'T' &&\n xmlData[i + 6] === 'A' &&\n xmlData[i + 7] === '['\n ) {\n for (i += 8; i < xmlData.length; i++) {\n if (xmlData[i] === ']' && xmlData[i + 1] === ']' && xmlData[i + 2] === '>') {\n i += 2;\n break;\n }\n }\n }\n\n return i;\n}\n\nconst doubleQuote = '\"';\nconst singleQuote = \"'\";\n\n/**\n * Keep reading xmlData until '<' is found outside the attribute value.\n * @param {string} xmlData\n * @param {number} i\n */\nfunction readAttributeStr(xmlData, i) {\n let attrStr = '';\n let startChar = '';\n let tagClosed = false;\n for (; i < xmlData.length; i++) {\n if (xmlData[i] === doubleQuote || xmlData[i] === singleQuote) {\n if (startChar === '') {\n startChar = xmlData[i];\n } else if (startChar !== xmlData[i]) {\n //if vaue is enclosed with double quote then single quotes are allowed inside the value and vice versa\n } else {\n startChar = '';\n }\n } else if (xmlData[i] === '>') {\n if (startChar === '') {\n tagClosed = true;\n break;\n }\n }\n attrStr += xmlData[i];\n }\n if (startChar !== '') {\n return false;\n }\n\n return {\n value: attrStr,\n index: i,\n tagClosed: tagClosed\n };\n}\n\n/**\n * Select all the attributes whether valid or invalid.\n */\nconst validAttrStrRegxp = new RegExp('(\\\\s*)([^\\\\s=]+)(\\\\s*=)?(\\\\s*([\\'\"])(([\\\\s\\\\S])*?)\\\\5)?', 'g');\n\n//attr, =\"sd\", a=\"amit's\", a=\"sd\"b=\"saf\", ab cd=\"\"\n\nfunction validateAttributeString(attrStr, options) {\n //console.log(\"start:\"+attrStr+\":end\");\n\n //if(attrStr.trim().length === 0) return true; //empty string\n\n const matches = getAllMatches(attrStr, validAttrStrRegxp);\n const attrNames = {};\n\n for (let i = 0; i < matches.length; i++) {\n if (matches[i][1].length === 0) {\n //nospace before attribute name: a=\"sd\"b=\"saf\"\n return getErrorObject('InvalidAttr', \"Attribute '\"+matches[i][2]+\"' has no space in starting.\", getPositionFromMatch(matches[i]))\n } else if (matches[i][3] !== undefined && matches[i][4] === undefined) {\n return getErrorObject('InvalidAttr', \"Attribute '\"+matches[i][2]+\"' is without value.\", getPositionFromMatch(matches[i]));\n } else if (matches[i][3] === undefined && !options.allowBooleanAttributes) {\n //independent attribute: ab\n return getErrorObject('InvalidAttr', \"boolean attribute '\"+matches[i][2]+\"' is not allowed.\", getPositionFromMatch(matches[i]));\n }\n /* else if(matches[i][6] === undefined){//attribute without value: ab=\n return { err: { code:\"InvalidAttr\",msg:\"attribute \" + matches[i][2] + \" has no value assigned.\"}};\n } */\n const attrName = matches[i][2];\n if (!validateAttrName(attrName)) {\n return getErrorObject('InvalidAttr', \"Attribute '\"+attrName+\"' is an invalid name.\", getPositionFromMatch(matches[i]));\n }\n if (!attrNames.hasOwnProperty(attrName)) {\n //check for duplicate attribute.\n attrNames[attrName] = 1;\n } else {\n return getErrorObject('InvalidAttr', \"Attribute '\"+attrName+\"' is repeated.\", getPositionFromMatch(matches[i]));\n }\n }\n\n return true;\n}\n\nfunction validateNumberAmpersand(xmlData, i) {\n let re = /\\d/;\n if (xmlData[i] === 'x') {\n i++;\n re = /[\\da-fA-F]/;\n }\n for (; i < xmlData.length; i++) {\n if (xmlData[i] === ';')\n return i;\n if (!xmlData[i].match(re))\n break;\n }\n return -1;\n}\n\nfunction validateAmpersand(xmlData, i) {\n // https://www.w3.org/TR/xml/#dt-charref\n i++;\n if (xmlData[i] === ';')\n return -1;\n if (xmlData[i] === '#') {\n i++;\n return validateNumberAmpersand(xmlData, i);\n }\n let count = 0;\n for (; i < xmlData.length; i++, count++) {\n if (xmlData[i].match(/\\w/) && count < 20)\n continue;\n if (xmlData[i] === ';')\n break;\n return -1;\n }\n return i;\n}\n\nfunction getErrorObject(code, message, lineNumber) {\n return {\n err: {\n code: code,\n msg: message,\n line: lineNumber.line || lineNumber,\n col: lineNumber.col,\n },\n };\n}\n\nfunction validateAttrName(attrName) {\n return isName(attrName);\n}\n\n// const startsWithXML = /^xml/i;\n\nfunction validateTagName(tagname) {\n return isName(tagname) /* && !tagname.match(startsWithXML) */;\n}\n\n//this function returns the line number for the character at the given index\nfunction getLineNumberForPosition(xmlData, index) {\n const lines = xmlData.substring(0, index).split(/\\r?\\n/);\n return {\n line: lines.length,\n\n // column number is last line's length + 1, because column numbering starts at 1:\n col: lines[lines.length - 1].length + 1\n };\n}\n\n//this function returns the position of the first character of match within attrStr\nfunction getPositionFromMatch(match) {\n return match.startIndex + match[1].length;\n}\n"],"names":["root","factory","exports","module","define","amd","this","__webpack_require__","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","nameStartChar","regexName","RegExp","isName","string","exec","defaultOptions","allowBooleanAttributes","unpairedTags","validate","xmlData","options","assign","tags","tagFound","reachedRoot","substr","i","length","readPI","err","isWhiteSpace","getErrorObject","getLineNumberForPosition","tagStartPos","readCommentAndCDATA","closingTag","tagName","trim","substring","validateTagName","result","readAttributeStr","attrStr","index","attrStrStart","isValid","validateAttributeString","code","msg","line","tagClosed","otg","pop","openPos","col","indexOf","push","afterAmp","validateAmpersand","JSON","stringify","map","t","replace","char","start","tagname","angleBracketsCount","doubleQuote","singleQuote","startChar","validAttrStrRegxp","matches","regex","match","allmatches","startIndex","lastIndex","len","getAllMatches","attrNames","getPositionFromMatch","undefined","attrName","validateAttrName","re","validateNumberAmpersand","count","message","lineNumber","lines","split"],"sourceRoot":""}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fast-xml-parser",
|
|
3
|
-
"version": "5.3.
|
|
3
|
+
"version": "5.3.7",
|
|
4
4
|
"description": "Validate XML, Parse XML, Build XML without C/C++ based libraries",
|
|
5
5
|
"main": "./lib/fxp.cjs",
|
|
6
6
|
"type": "module",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"prepublishOnly": "publish-please guard"
|
|
34
34
|
},
|
|
35
35
|
"bin": {
|
|
36
|
-
"fxparser": "
|
|
36
|
+
"fxparser": "src/cli/cli.js"
|
|
37
37
|
},
|
|
38
38
|
"files": [
|
|
39
39
|
"lib",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
],
|
|
43
43
|
"repository": {
|
|
44
44
|
"type": "git",
|
|
45
|
-
"url": "https://github.com/NaturalIntelligence/fast-xml-parser"
|
|
45
|
+
"url": "git+https://github.com/NaturalIntelligence/fast-xml-parser.git"
|
|
46
46
|
},
|
|
47
47
|
"keywords": [
|
|
48
48
|
"fast",
|
|
@@ -89,4 +89,4 @@
|
|
|
89
89
|
"dependencies": {
|
|
90
90
|
"strnum": "^2.1.2"
|
|
91
91
|
}
|
|
92
|
-
}
|
|
92
|
+
}
|
package/src/fxp.d.ts
CHANGED
|
@@ -1,3 +1,59 @@
|
|
|
1
|
+
export type ProcessEntitiesOptions = {
|
|
2
|
+
/**
|
|
3
|
+
* Whether to enable entity processing
|
|
4
|
+
*
|
|
5
|
+
* Defaults to `true`
|
|
6
|
+
*/
|
|
7
|
+
enabled?: boolean;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Maximum size in characters for a single entity definition
|
|
11
|
+
*
|
|
12
|
+
* Defaults to `10000`
|
|
13
|
+
*/
|
|
14
|
+
maxEntitySize?: number;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Maximum depth for nested entity references (reserved for future use)
|
|
18
|
+
*
|
|
19
|
+
* Defaults to `10`
|
|
20
|
+
*/
|
|
21
|
+
maxExpansionDepth?: number;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Maximum total number of entity expansions allowed
|
|
25
|
+
*
|
|
26
|
+
* Defaults to `1000`
|
|
27
|
+
*/
|
|
28
|
+
maxTotalExpansions?: number;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Maximum total expanded content length in characters
|
|
32
|
+
*
|
|
33
|
+
* Defaults to `100000`
|
|
34
|
+
*/
|
|
35
|
+
maxExpandedLength?: number;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Array of tag names where entity replacement is allowed.
|
|
39
|
+
* If null, entities are replaced in all tags.
|
|
40
|
+
*
|
|
41
|
+
* Defaults to `null`
|
|
42
|
+
*/
|
|
43
|
+
allowedTags?: string[] | null;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Custom filter function to determine if entities should be replaced in a tag
|
|
47
|
+
*
|
|
48
|
+
* @param tagName - The name of the current tag
|
|
49
|
+
* @param jPath - The jPath of the current tag
|
|
50
|
+
* @returns `true` to allow entity replacement, `false` to skip
|
|
51
|
+
*
|
|
52
|
+
* Defaults to `null`
|
|
53
|
+
*/
|
|
54
|
+
tagFilter?: ((tagName: string, jPath: string) => boolean) | null;
|
|
55
|
+
};
|
|
56
|
+
|
|
1
57
|
export type X2jOptions = {
|
|
2
58
|
/**
|
|
3
59
|
* Preserve the order of tags in resulting JS object
|
|
@@ -10,7 +66,7 @@ export type X2jOptions = {
|
|
|
10
66
|
* Give a prefix to the attribute name in the resulting JS object
|
|
11
67
|
*
|
|
12
68
|
* Defaults to '@_'
|
|
13
|
-
*/
|
|
69
|
+
*/
|
|
14
70
|
attributeNamePrefix?: string;
|
|
15
71
|
|
|
16
72
|
/**
|
|
@@ -161,9 +217,15 @@ export type X2jOptions = {
|
|
|
161
217
|
/**
|
|
162
218
|
* Whether to process default and DOCTYPE entities
|
|
163
219
|
*
|
|
220
|
+
* When `true` - enables entity processing with default limits
|
|
221
|
+
*
|
|
222
|
+
* When `false` - disables all entity processing
|
|
223
|
+
*
|
|
224
|
+
* When `ProcessEntitiesOptions` - enables entity processing with custom configuration
|
|
225
|
+
*
|
|
164
226
|
* Defaults to `true`
|
|
165
227
|
*/
|
|
166
|
-
processEntities?: boolean;
|
|
228
|
+
processEntities?: boolean | ProcessEntitiesOptions;
|
|
167
229
|
|
|
168
230
|
/**
|
|
169
231
|
* Whether to process HTML entities
|
|
@@ -209,7 +271,7 @@ export type X2jOptions = {
|
|
|
209
271
|
*
|
|
210
272
|
* Defaults to `(tagName, jPath, attrs) => tagName`
|
|
211
273
|
*/
|
|
212
|
-
updateTag?: (tagName: string, jPath: string, attrs: {[k: string]: string}) =>
|
|
274
|
+
updateTag?: (tagName: string, jPath: string, attrs: { [k: string]: string }) => string | boolean;
|
|
213
275
|
|
|
214
276
|
/**
|
|
215
277
|
* If true, adds a Symbol to all object nodes, accessible by {@link XMLParser.getMetaDataSymbol} with
|
|
@@ -232,7 +294,7 @@ export type validationOptions = {
|
|
|
232
294
|
* Defaults to `false`
|
|
233
295
|
*/
|
|
234
296
|
allowBooleanAttributes?: boolean;
|
|
235
|
-
|
|
297
|
+
|
|
236
298
|
/**
|
|
237
299
|
* List of tags without closing tags
|
|
238
300
|
*
|
|
@@ -246,7 +308,7 @@ export type XmlBuilderOptions = {
|
|
|
246
308
|
* Give a prefix to the attribute name in the resulting JS object
|
|
247
309
|
*
|
|
248
310
|
* Defaults to '@_'
|
|
249
|
-
*/
|
|
311
|
+
*/
|
|
250
312
|
attributeNamePrefix?: string;
|
|
251
313
|
|
|
252
314
|
/**
|
|
@@ -393,14 +455,14 @@ export type XmlBuilderOptions = {
|
|
|
393
455
|
oneListGroup?: boolean;
|
|
394
456
|
};
|
|
395
457
|
|
|
396
|
-
type ESchema = string | object | Array<string|object>;
|
|
458
|
+
type ESchema = string | object | Array<string | object>;
|
|
397
459
|
|
|
398
460
|
export type ValidationError = {
|
|
399
|
-
err: {
|
|
461
|
+
err: {
|
|
400
462
|
code: string;
|
|
401
463
|
msg: string,
|
|
402
464
|
line: number,
|
|
403
|
-
col: number
|
|
465
|
+
col: number
|
|
404
466
|
};
|
|
405
467
|
};
|
|
406
468
|
|
|
@@ -424,11 +486,11 @@ export class XMLParser {
|
|
|
424
486
|
* The XMLMetaData property is only present when {@link X2jOptions.captureMetaData}
|
|
425
487
|
* is true in the options.
|
|
426
488
|
*/
|
|
427
|
-
static getMetaDataSymbol()
|
|
489
|
+
static getMetaDataSymbol(): Symbol;
|
|
428
490
|
}
|
|
429
491
|
|
|
430
|
-
export class XMLValidator{
|
|
431
|
-
static validate(
|
|
492
|
+
export class XMLValidator {
|
|
493
|
+
static validate(xmlData: string, options?: validationOptions): true | ValidationError;
|
|
432
494
|
}
|
|
433
495
|
export class XMLBuilder {
|
|
434
496
|
constructor(options?: XmlBuilderOptions);
|
|
@@ -442,4 +504,4 @@ export class XMLBuilder {
|
|
|
442
504
|
export interface XMLMetaData {
|
|
443
505
|
/** The index, if available, of the character where the XML node began in the input stream. */
|
|
444
506
|
startIndex?: number;
|
|
445
|
-
}
|
|
507
|
+
}
|
package/src/util.js
CHANGED
|
@@ -21,7 +21,7 @@ export function getAllMatches(string, regex) {
|
|
|
21
21
|
return matches;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
export const isName = function(string) {
|
|
24
|
+
export const isName = function (string) {
|
|
25
25
|
const match = regexName.exec(string);
|
|
26
26
|
return !(match === null || typeof match === 'undefined');
|
|
27
27
|
}
|
|
@@ -34,28 +34,6 @@ export function isEmptyObject(obj) {
|
|
|
34
34
|
return Object.keys(obj).length === 0;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
/**
|
|
38
|
-
* Copy all the properties of a into b.
|
|
39
|
-
* @param {*} target
|
|
40
|
-
* @param {*} a
|
|
41
|
-
*/
|
|
42
|
-
export function merge(target, a, arrayMode) {
|
|
43
|
-
if (a) {
|
|
44
|
-
const keys = Object.keys(a); // will return an array of own properties
|
|
45
|
-
const len = keys.length; //don't make it inline
|
|
46
|
-
for (let i = 0; i < len; i++) {
|
|
47
|
-
if (arrayMode === 'strict') {
|
|
48
|
-
target[keys[i]] = [ a[keys[i]] ];
|
|
49
|
-
} else {
|
|
50
|
-
target[keys[i]] = a[keys[i]];
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
/* exports.merge =function (b,a){
|
|
56
|
-
return Object.assign(b,a);
|
|
57
|
-
} */
|
|
58
|
-
|
|
59
37
|
export function getValue(v) {
|
|
60
38
|
if (exports.isExist(v)) {
|
|
61
39
|
return v;
|
|
@@ -63,6 +41,3 @@ export function getValue(v) {
|
|
|
63
41
|
return '';
|
|
64
42
|
}
|
|
65
43
|
}
|
|
66
|
-
|
|
67
|
-
// const fakeCall = function(a) {return a;};
|
|
68
|
-
// const fakeCallNoReturn = function() {};
|
|
@@ -1,82 +1,82 @@
|
|
|
1
|
-
import {isName} from '../util.js';
|
|
1
|
+
import { isName } from '../util.js';
|
|
2
2
|
|
|
3
|
-
export default class DocTypeReader{
|
|
4
|
-
constructor(
|
|
5
|
-
this.suppressValidationErr = !
|
|
3
|
+
export default class DocTypeReader {
|
|
4
|
+
constructor(options) {
|
|
5
|
+
this.suppressValidationErr = !options;
|
|
6
|
+
this.options = options;
|
|
6
7
|
}
|
|
7
|
-
|
|
8
|
-
readDocType(xmlData, i){
|
|
9
|
-
|
|
8
|
+
|
|
9
|
+
readDocType(xmlData, i) {
|
|
10
|
+
|
|
10
11
|
const entities = {};
|
|
11
|
-
if(
|
|
12
|
+
if (xmlData[i + 3] === 'O' &&
|
|
12
13
|
xmlData[i + 4] === 'C' &&
|
|
13
14
|
xmlData[i + 5] === 'T' &&
|
|
14
15
|
xmlData[i + 6] === 'Y' &&
|
|
15
16
|
xmlData[i + 7] === 'P' &&
|
|
16
|
-
xmlData[i + 8] === 'E')
|
|
17
|
-
|
|
18
|
-
i = i+9;
|
|
17
|
+
xmlData[i + 8] === 'E') {
|
|
18
|
+
i = i + 9;
|
|
19
19
|
let angleBracketsCount = 1;
|
|
20
20
|
let hasBody = false, comment = false;
|
|
21
21
|
let exp = "";
|
|
22
|
-
for(;i<xmlData.length;i++){
|
|
22
|
+
for (; i < xmlData.length; i++) {
|
|
23
23
|
if (xmlData[i] === '<' && !comment) { //Determine the tag type
|
|
24
|
-
if(
|
|
25
|
-
i += 7;
|
|
24
|
+
if (hasBody && hasSeq(xmlData, "!ENTITY", i)) {
|
|
25
|
+
i += 7;
|
|
26
26
|
let entityName, val;
|
|
27
|
-
[entityName, val,i] = this.readEntityExp(xmlData,i+1,this.suppressValidationErr);
|
|
28
|
-
if(val.indexOf("&") === -1){ //Parameter entities are not supported
|
|
27
|
+
[entityName, val, i] = this.readEntityExp(xmlData, i + 1, this.suppressValidationErr);
|
|
28
|
+
if (val.indexOf("&") === -1) { //Parameter entities are not supported
|
|
29
29
|
const escaped = entityName.replace(/[.\-+*:]/g, '\\.');
|
|
30
|
-
entities[
|
|
31
|
-
regx
|
|
30
|
+
entities[entityName] = {
|
|
31
|
+
regx: RegExp(`&${escaped};`, "g"),
|
|
32
32
|
val: val
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
|
-
else if(
|
|
36
|
+
else if (hasBody && hasSeq(xmlData, "!ELEMENT", i)) {
|
|
37
37
|
i += 8;//Not supported
|
|
38
|
-
const {index} = this.readElementExp(xmlData,i+1);
|
|
38
|
+
const { index } = this.readElementExp(xmlData, i + 1);
|
|
39
39
|
i = index;
|
|
40
|
-
}else if(
|
|
40
|
+
} else if (hasBody && hasSeq(xmlData, "!ATTLIST", i)) {
|
|
41
41
|
i += 8;//Not supported
|
|
42
42
|
// const {index} = this.readAttlistExp(xmlData,i+1);
|
|
43
43
|
// i = index;
|
|
44
|
-
}else if(
|
|
44
|
+
} else if (hasBody && hasSeq(xmlData, "!NOTATION", i)) {
|
|
45
45
|
i += 9;//Not supported
|
|
46
|
-
const {index} = this.readNotationExp(xmlData,i+1,this.suppressValidationErr);
|
|
46
|
+
const { index } = this.readNotationExp(xmlData, i + 1, this.suppressValidationErr);
|
|
47
47
|
i = index;
|
|
48
|
-
}else if(
|
|
48
|
+
} else if (hasSeq(xmlData, "!--", i)) comment = true;
|
|
49
49
|
else throw new Error(`Invalid DOCTYPE`);
|
|
50
50
|
|
|
51
51
|
angleBracketsCount++;
|
|
52
52
|
exp = "";
|
|
53
53
|
} else if (xmlData[i] === '>') { //Read tag content
|
|
54
|
-
if(comment){
|
|
55
|
-
if(
|
|
54
|
+
if (comment) {
|
|
55
|
+
if (xmlData[i - 1] === "-" && xmlData[i - 2] === "-") {
|
|
56
56
|
comment = false;
|
|
57
57
|
angleBracketsCount--;
|
|
58
58
|
}
|
|
59
|
-
}else{
|
|
59
|
+
} else {
|
|
60
60
|
angleBracketsCount--;
|
|
61
61
|
}
|
|
62
62
|
if (angleBracketsCount === 0) {
|
|
63
|
-
|
|
63
|
+
break;
|
|
64
64
|
}
|
|
65
|
-
}else if(
|
|
65
|
+
} else if (xmlData[i] === '[') {
|
|
66
66
|
hasBody = true;
|
|
67
|
-
}else{
|
|
67
|
+
} else {
|
|
68
68
|
exp += xmlData[i];
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
|
-
if(angleBracketsCount !== 0){
|
|
71
|
+
if (angleBracketsCount !== 0) {
|
|
72
72
|
throw new Error(`Unclosed DOCTYPE`);
|
|
73
73
|
}
|
|
74
|
-
}else{
|
|
74
|
+
} else {
|
|
75
75
|
throw new Error(`Invalid Tag instead of DOCTYPE`);
|
|
76
76
|
}
|
|
77
|
-
return {entities, i};
|
|
77
|
+
return { entities, i };
|
|
78
78
|
}
|
|
79
|
-
readEntityExp(xmlData, i) {
|
|
79
|
+
readEntityExp(xmlData, i) {
|
|
80
80
|
//External entities are not supported
|
|
81
81
|
// <!ENTITY ext SYSTEM "http://normal-website.com" >
|
|
82
82
|
|
|
@@ -101,10 +101,10 @@ export default class DocTypeReader{
|
|
|
101
101
|
i = skipWhitespace(xmlData, i);
|
|
102
102
|
|
|
103
103
|
// Check for unsupported constructs (external entities or parameter entities)
|
|
104
|
-
if(!this.suppressValidationErr){
|
|
104
|
+
if (!this.suppressValidationErr) {
|
|
105
105
|
if (xmlData.substring(i, i + 6).toUpperCase() === "SYSTEM") {
|
|
106
106
|
throw new Error("External entities are not supported");
|
|
107
|
-
}else if (xmlData[i] === "%") {
|
|
107
|
+
} else if (xmlData[i] === "%") {
|
|
108
108
|
throw new Error("Parameter entities are not supported");
|
|
109
109
|
}
|
|
110
110
|
}
|
|
@@ -112,8 +112,18 @@ export default class DocTypeReader{
|
|
|
112
112
|
// Read entity value (internal entity)
|
|
113
113
|
let entityValue = "";
|
|
114
114
|
[i, entityValue] = this.readIdentifierVal(xmlData, i, "entity");
|
|
115
|
+
|
|
116
|
+
// Validate entity size
|
|
117
|
+
if (this.options.enabled !== false &&
|
|
118
|
+
this.options.maxEntitySize &&
|
|
119
|
+
entityValue.length > this.options.maxEntitySize) {
|
|
120
|
+
throw new Error(
|
|
121
|
+
`Entity "${entityName}" size (${entityValue.length}) exceeds maximum allowed size (${this.options.maxEntitySize})`
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
115
125
|
i--;
|
|
116
|
-
return [entityName, entityValue, i
|
|
126
|
+
return [entityName, entityValue, i];
|
|
117
127
|
}
|
|
118
128
|
|
|
119
129
|
readNotationExp(xmlData, i) {
|
|
@@ -146,25 +156,25 @@ export default class DocTypeReader{
|
|
|
146
156
|
let systemIdentifier = null;
|
|
147
157
|
|
|
148
158
|
if (identifierType === "PUBLIC") {
|
|
149
|
-
[i, publicIdentifier
|
|
159
|
+
[i, publicIdentifier] = this.readIdentifierVal(xmlData, i, "publicIdentifier");
|
|
150
160
|
|
|
151
161
|
// Skip whitespace after public identifier
|
|
152
162
|
i = skipWhitespace(xmlData, i);
|
|
153
163
|
|
|
154
164
|
// Optionally read system identifier
|
|
155
165
|
if (xmlData[i] === '"' || xmlData[i] === "'") {
|
|
156
|
-
[i, systemIdentifier
|
|
166
|
+
[i, systemIdentifier] = this.readIdentifierVal(xmlData, i, "systemIdentifier");
|
|
157
167
|
}
|
|
158
168
|
} else if (identifierType === "SYSTEM") {
|
|
159
169
|
// Read system identifier (mandatory for SYSTEM)
|
|
160
|
-
[i, systemIdentifier
|
|
170
|
+
[i, systemIdentifier] = this.readIdentifierVal(xmlData, i, "systemIdentifier");
|
|
161
171
|
|
|
162
172
|
if (!this.suppressValidationErr && !systemIdentifier) {
|
|
163
173
|
throw new Error("Missing mandatory system identifier for SYSTEM notation");
|
|
164
174
|
}
|
|
165
175
|
}
|
|
166
|
-
|
|
167
|
-
return {notationName, publicIdentifier, systemIdentifier, index: --i};
|
|
176
|
+
|
|
177
|
+
return { notationName, publicIdentifier, systemIdentifier, index: --i };
|
|
168
178
|
}
|
|
169
179
|
|
|
170
180
|
readIdentifierVal(xmlData, i, type) {
|
|
@@ -193,7 +203,7 @@ export default class DocTypeReader{
|
|
|
193
203
|
// <!ELEMENT title (#PCDATA)>
|
|
194
204
|
// <!ELEMENT book (title, author+)>
|
|
195
205
|
// <!ELEMENT name (content-model)>
|
|
196
|
-
|
|
206
|
+
|
|
197
207
|
// Skip leading whitespace after <!ELEMENT
|
|
198
208
|
i = skipWhitespace(xmlData, i);
|
|
199
209
|
|
|
@@ -213,8 +223,8 @@ export default class DocTypeReader{
|
|
|
213
223
|
i = skipWhitespace(xmlData, i);
|
|
214
224
|
let contentModel = "";
|
|
215
225
|
// Expect '(' to start content model
|
|
216
|
-
if(xmlData[i] === "E" && hasSeq(xmlData, "MPTY",i)) i+=4;
|
|
217
|
-
else if(xmlData[i] === "A" && hasSeq(xmlData, "NY",i)) i+=2;
|
|
226
|
+
if (xmlData[i] === "E" && hasSeq(xmlData, "MPTY", i)) i += 4;
|
|
227
|
+
else if (xmlData[i] === "A" && hasSeq(xmlData, "NY", i)) i += 2;
|
|
218
228
|
else if (xmlData[i] === "(") {
|
|
219
229
|
i++; // Move past '('
|
|
220
230
|
|
|
@@ -227,10 +237,10 @@ export default class DocTypeReader{
|
|
|
227
237
|
throw new Error("Unterminated content model");
|
|
228
238
|
}
|
|
229
239
|
|
|
230
|
-
}else if(!this.suppressValidationErr){
|
|
240
|
+
} else if (!this.suppressValidationErr) {
|
|
231
241
|
throw new Error(`Invalid Element Expression, found "${xmlData[i]}"`);
|
|
232
242
|
}
|
|
233
|
-
|
|
243
|
+
|
|
234
244
|
return {
|
|
235
245
|
elementName,
|
|
236
246
|
contentModel: contentModel.trim(),
|
|
@@ -366,16 +376,16 @@ const skipWhitespace = (data, index) => {
|
|
|
366
376
|
|
|
367
377
|
|
|
368
378
|
|
|
369
|
-
function hasSeq(data, seq,i){
|
|
370
|
-
for(let j=0;j<seq.length;j++){
|
|
371
|
-
if(seq[j]!==data[i+j+1]) return false;
|
|
379
|
+
function hasSeq(data, seq, i) {
|
|
380
|
+
for (let j = 0; j < seq.length; j++) {
|
|
381
|
+
if (seq[j] !== data[i + j + 1]) return false;
|
|
372
382
|
}
|
|
373
383
|
return true;
|
|
374
384
|
}
|
|
375
385
|
|
|
376
|
-
function validateEntityName(name){
|
|
386
|
+
function validateEntityName(name) {
|
|
377
387
|
if (isName(name))
|
|
378
|
-
|
|
388
|
+
return name;
|
|
379
389
|
else
|
|
380
390
|
throw new Error(`Invalid entity name ${name}`);
|
|
381
|
-
}
|
|
391
|
+
}
|