@muze-nl/assert 0.2.1 → 0.3.1
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/dist/browser.js +1 -1
- package/dist/browser.js.map +1 -1
- package/package.json +1 -1
- package/src/assert.mjs +129 -58
package/dist/browser.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
function t(t,e,a
|
|
1
|
+
function t(t,n,e,a){Object.defineProperty(t,n,{get:e,set:a,enumerable:!0,configurable:!0})}var n={};function e(){globalThis.assertEnabled=!0}function a(){globalThis.assertEnabled=!1}function r(t,n){if(globalThis.assertEnabled){let e=y(t,n);if(e)throw new b("Assertions failed",e,t)}}function o(t){return function(n,e,a){return null!=n&&void 0!==n&&y(n,t,e,a)}}function i(t){return function(n,e,a){return null==n||void 0===n?m("data is required",n,t||"any value",a):void 0!==t&&y(n,t,e,a)}}function s(...t){return function(n,e,a){return null==n||void 0===n?(console.warn("data does not contain recommended value",n,t,a),!1):y(n,t,e,a)}}function f(...t){return function(n,e,a){for(let r of t)if(!y(n,r,e,a))return!1;return m("data does not match oneOf patterns",n,t,a)}}function l(...t){return function(n,e,a){if(!Array.isArray(n))return m("data is not an array",n,"anyOf",a);for(let e of n)if(f(...t)(e))return m("data does not match anyOf patterns",e,t,a);return!1}}function u(...t){return function(n,e,a){let r=[];for(let o of t)r=r.concat(y(n,o,e,a));if((r=r.filter(Boolean)).length)return m("data does not match all given patterns",n,t,a,r)}}function c(t,n,e){try{t instanceof URL&&(t=t.href);let n=new URL(t);if(n.href!=t&&!(n.href+"/"==t||n.href==t+"/"))return m("data is not a valid url",t,"validURL",e)}catch(n){return m("data is not a valid url",t,"validURL",e)}}function d(t,n,e){if(!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t))return m("data is not a valid email",t,"validEmail",e)}function h(t){return function(n,e,a){if(!(n instanceof t))return m("data is not an instanceof pattern",n,t,a)}}function p(t){return function(n,e,a){if(!y(n,t,e,a))return m("data matches pattern, when required not to",n,t,a)}}function y(t,n,e,a=""){e||(e=t);let r=[];if(n===Boolean)"boolean"==typeof t||t instanceof Boolean||r.push(m("data is not a boolean",t,n,a));else if(n===Number)"number"==typeof t||t instanceof Number||r.push(m("data is not a number",t,n,a));else if(n===String)"string"==typeof t||t instanceof String||r.push(m("data is not a string",t,n,a)),""==t&&r.push(m("data is an empty string, which is not allowed",t,n,a));else if(n instanceof RegExp){if(Array.isArray(t)){let o=t.findIndex((t,r)=>y(t,n,e,a+"["+r+"]"));o>-1&&r.push(m("data["+o+"] does not match pattern",t[o],n,a+"["+o+"]"))}else void 0===t?r.push(m("data is undefined, should match pattern",t,n,a)):n.test(t)||r.push(m("data does not match pattern",t,n,a))}else if(n instanceof Function){let o=n(t,e,a);o&&(Array.isArray(o)?r=r.concat(o):r.push(o))}else if(Array.isArray(n))for(let o of(Array.isArray(t)||r.push(m("data is not an array",t,[],a)),n))for(let n of t.keys()){let i=y(t[n],o,e,a+"["+n+"]");Array.isArray(i)?r=r.concat(i):i&&r.push(i)}else if(n&&"object"==typeof n){if(Array.isArray(t)){let o=t.findIndex((t,r)=>y(t,n,e,a+"["+r+"]"));o>-1&&r.push(m("data["+o+"] does not match pattern",t[o],n,a+"["+o+"]"))}else if(t&&"object"==typeof t){if(t instanceof URLSearchParams&&(t=Object.fromEntries(t)),n instanceof Function){let o=y(t,n,e,a);o&&(r=r.concat(o))}else for(let[o,i]of Object.entries(n)){let n=y(t[o],i,e,a+"."+o);n&&(r=r.concat(n))}}else r.push(m("data is not an object, pattern is",t,n,a))}else n!=t&&r.push(m("data and pattern are not equal",t,n,a));return!!r.length&&r}t(n,"enable",()=>e),t(n,"disable",()=>a),t(n,"assert",()=>r),t(n,"fails",()=>y),t(n,"Optional",()=>o),t(n,"Required",()=>i),t(n,"error",()=>m),t(n,"Recommended",()=>s),t(n,"oneOf",()=>f),t(n,"anyOf",()=>l),t(n,"allOf",()=>u),t(n,"validURL",()=>c),t(n,"validEmail",()=>d),t(n,"instanceOf",()=>h),t(n,"not",()=>p),globalThis.assertEnabled=!1;class b extends Error{constructor(t,n,...e){super(t),this.problems=n,this.details=e}}function m(t,n,e,a,r){let o={message:t,found:n,expected:e,path:a};return r&&(o.problems=r),o}globalThis.assert=n;
|
|
2
2
|
//# sourceMappingURL=browser.js.map
|
package/dist/browser.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"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","sources":["<anon>","src/browser.mjs","src/assert.mjs"],"sourcesContent":["\nfunction $parcel$export(e, n, v, s) {\n Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});\n}\nvar $2ddd80d1adc2ea42$exports = {};\n\n$parcel$export($2ddd80d1adc2ea42$exports, \"enable\", () => $2ddd80d1adc2ea42$export$d7c4a0dd6a4567e5);\n$parcel$export($2ddd80d1adc2ea42$exports, \"disable\", () => $2ddd80d1adc2ea42$export$e20fbacbb41798b);\n$parcel$export($2ddd80d1adc2ea42$exports, \"assert\", () => $2ddd80d1adc2ea42$export$a7a9523472993e97);\n$parcel$export($2ddd80d1adc2ea42$exports, \"fails\", () => $2ddd80d1adc2ea42$export$478159de811fd37d);\n$parcel$export($2ddd80d1adc2ea42$exports, \"Optional\", () => $2ddd80d1adc2ea42$export$7acb7b24c478f9c6);\n$parcel$export($2ddd80d1adc2ea42$exports, \"Required\", () => $2ddd80d1adc2ea42$export$1788c381af06add2);\n$parcel$export($2ddd80d1adc2ea42$exports, \"error\", () => $2ddd80d1adc2ea42$export$a3bc9b8ed74fc);\n$parcel$export($2ddd80d1adc2ea42$exports, \"Recommended\", () => $2ddd80d1adc2ea42$export$a83bcf183f49ea9);\n$parcel$export($2ddd80d1adc2ea42$exports, \"oneOf\", () => $2ddd80d1adc2ea42$export$a9a18ae5ba42aeab);\n$parcel$export($2ddd80d1adc2ea42$exports, \"anyOf\", () => $2ddd80d1adc2ea42$export$b26c150f612c10f7);\n$parcel$export($2ddd80d1adc2ea42$exports, \"validURL\", () => $2ddd80d1adc2ea42$export$c6f1a4382426409f);\n$parcel$export($2ddd80d1adc2ea42$exports, \"validEmail\", () => $2ddd80d1adc2ea42$export$9ab921aaffe56820);\n$parcel$export($2ddd80d1adc2ea42$exports, \"instanceOf\", () => $2ddd80d1adc2ea42$export$ca03416d6c9e029e);\n$parcel$export($2ddd80d1adc2ea42$exports, \"not\", () => $2ddd80d1adc2ea42$export$6003a5f097c73977);\n/**\n * assertEnabled (Boolean) used to toggle whether the assert()\n * method should test assertions or not.\n */ globalThis.assertEnabled = false;\nfunction $2ddd80d1adc2ea42$export$d7c4a0dd6a4567e5() {\n globalThis.assertEnabled = true;\n}\nfunction $2ddd80d1adc2ea42$export$e20fbacbb41798b() {\n globalThis.assertEnabled = false;\n}\nconst $2ddd80d1adc2ea42$export$a7a9523472993e97 = (source, test)=>{\n if (globalThis.assertEnabled) {\n let problems = $2ddd80d1adc2ea42$export$478159de811fd37d(source, test);\n if (problems) throw new $2ddd80d1adc2ea42$var$assertError(\"Assertions failed\", problems, source);\n }\n};\nconst $2ddd80d1adc2ea42$export$7acb7b24c478f9c6 = (pattern)=>(data)=>data == null || typeof data == \"undefined\" ? false : $2ddd80d1adc2ea42$export$478159de811fd37d(data, pattern);\nconst $2ddd80d1adc2ea42$export$1788c381af06add2 = (pattern)=>(data)=>data == null || typeof data == \"undefined\" ? $2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data is required\") : $2ddd80d1adc2ea42$export$478159de811fd37d(data, pattern);\nconst $2ddd80d1adc2ea42$export$a83bcf183f49ea9 = (pattern)=>(data)=>data == null || typeof data == \"undefined\" ? (()=>{\n console.warning(\"data does not contain recommended value\", data, pattern);\n return false;\n })() : $2ddd80d1adc2ea42$export$478159de811fd37d(data, pattern);\nconst $2ddd80d1adc2ea42$export$a9a18ae5ba42aeab = (...patterns)=>(data)=>{\n for (let pattern of patterns){\n if (!$2ddd80d1adc2ea42$export$478159de811fd37d(data, pattern)) return false;\n }\n return $2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data does not match oneOf patterns\", data, patterns);\n };\nconst $2ddd80d1adc2ea42$export$b26c150f612c10f7 = (...patterns)=>(data)=>{\n if (!Array.isArray(data)) return $2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data is not an array\", data, \"anyOf\");\n for (let value of data){\n if ($2ddd80d1adc2ea42$export$a9a18ae5ba42aeab(...patterns)(value)) return $2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data does not match anyOf patterns\", value, patterns);\n }\n return false;\n };\nfunction $2ddd80d1adc2ea42$export$c6f1a4382426409f(data) {\n try {\n if (data instanceof URL) data = data.href;\n let url = new URL(data);\n if (url.href != data) return $2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data is not a valid url\", data, \"validURL\");\n } catch (e) {\n return $2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data is not a valid url\", data, \"validURL\");\n }\n return false;\n}\nfunction $2ddd80d1adc2ea42$export$9ab921aaffe56820(data) {\n if (/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(data)) return false // data matches email regex\n ;\n return $2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data is not a valid email\", data, \"validEmail\");\n}\nconst $2ddd80d1adc2ea42$export$ca03416d6c9e029e = (constructor)=>(data)=>!(data instanceof constructor) ? $2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data is not an instanceof pattern\", data, constructor) : false;\nconst $2ddd80d1adc2ea42$export$6003a5f097c73977 = (pattern)=>(data)=>$2ddd80d1adc2ea42$export$478159de811fd37d(data, pattern) ? false : $2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data matches pattern, when required not to\", data, pattern);\nfunction $2ddd80d1adc2ea42$export$478159de811fd37d(data, pattern, root) {\n if (!root) root = data;\n let problems = [];\n if (pattern === Boolean) {\n if (typeof data != \"boolean\" && !(data instanceof Boolean)) problems.push($2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data is not a boolean\", data, pattern));\n } else if (pattern === Number) {\n if (typeof data != \"number\" && !(data instanceof Number)) problems.push($2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data is not a number\", data, pattern));\n } else if (pattern === String) {\n if (typeof data != \"string\" && !(data instanceof String)) problems.push($2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data is not a string\", data, pattern));\n if (data == \"\") problems.push($2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data is an empty string, which is not allowed\", data, pattern));\n } else if (pattern instanceof RegExp) {\n if (Array.isArray(data)) {\n let index = data.findIndex((element)=>$2ddd80d1adc2ea42$export$478159de811fd37d(element, pattern, root));\n if (index > -1) problems.push($2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data[\" + index + \"] does not match pattern\", data[index], pattern));\n } else if (typeof data == \"undefined\") problems.push($2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data is undefined, should match pattern\", data, pattern));\n else if (!pattern.test(data)) problems.push($2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data does not match pattern\", data, pattern));\n } else if (pattern instanceof Function) {\n if (pattern(data, root)) problems.push($2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data does not match function\", data, pattern));\n } else if (Array.isArray(pattern)) {\n if (!Array.isArray(data)) problems.push($2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data is not an array\", data, []));\n for (let p of pattern)for (let val of data){\n let problem = $2ddd80d1adc2ea42$export$478159de811fd37d(val, p, root);\n if (Array.isArray(problem)) problems = problems.concat(problem);\n else if (problem) problems.push(problem);\n }\n } else if (pattern && typeof pattern == \"object\") {\n if (Array.isArray(data)) {\n let index = data.findIndex((element)=>$2ddd80d1adc2ea42$export$478159de811fd37d(element, pattern, root));\n if (index > -1) problems.push($2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data[\" + index + \"] does not match pattern\", data[index], pattern));\n } else if (!data || typeof data != \"object\") problems.push($2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data is not an object, pattern is\", data, pattern));\n else {\n if (data instanceof URLSearchParams) data = Object.fromEntries(data);\n for (const [wKey, wVal] of Object.entries(pattern)){\n let result = $2ddd80d1adc2ea42$export$478159de811fd37d(data[wKey], wVal, root);\n if (result) problems = problems.concat(result);\n }\n }\n } else if (pattern != data) problems.push($2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data and pattern are not equal\", data, pattern));\n if (problems.length) return problems;\n return false;\n}\n/**\n * Class used in assert() to add problems found and details to the error object\n */ class $2ddd80d1adc2ea42$var$assertError extends Error {\n constructor(message, problems, ...details){\n super(message);\n this.problems = problems;\n this.details = details;\n }\n}\nfunction $2ddd80d1adc2ea42$export$a3bc9b8ed74fc(message, found, expected) {\n return {\n message: message,\n found: found,\n expected: expected\n };\n}\n\n\nglobalThis.assert = $2ddd80d1adc2ea42$exports;\n\n\n//# sourceMappingURL=browser.js.map\n","import * as assert from './assert.mjs'\n\nglobalThis.assert = assert\n","/**\n * assertEnabled (Boolean) used to toggle whether the assert()\n * method should test assertions or not.\n */\nglobalThis.assertEnabled = false\n\n/**\n * Enables assertion testing with assert()\n */\nexport function enable() {\n\tglobalThis.assertEnabled = true\n}\n\n/**\n * Disables assertion testing with assert()\n */\nexport function disable() {\n\tglobalThis.assertEnabled = false\n}\n\n/**\n * This function will check the source for the assertions in test, if\n * assertion checking is enabled globally.\n * If it is, and any assertion fails, it will throw an assertError\n * with a list of problems and other details.\n */\nexport const assert = (source, test) => {\n\tif (globalThis.assertEnabled) {\n\t\tlet problems = fails(source,test)\n\t\tif (problems) {\n\t\t\tthrow new assertError('Assertions failed', problems, source)\n\t\t}\n\t}\n}\n\n/**\n * Tests a given value against a pattern, only if the value is not null or undefined\n */\nexport const Optional = (pattern) => \n\t(data) => (data==null || typeof data == 'undefined') ? false : fails(data, pattern)\n\n/**\n * Tests a given value against a pattern, always.\n */\nexport const Required = (pattern) =>\n\t(data) => (data==null || typeof data == 'undefined') ? error('data is required') : fails(data, pattern)\n\n/**\n * Tests a given value against a pattern, only if the value is not null or undefined\n * If null or undefined, it does print a warning to the console.\n */\nexport const Recommended = (pattern) =>\n\t(data) => (data==null || typeof data == 'undefined') ? (() => {\n\t\tconsole.warning('data does not contain recommended value', data, pattern)\n\t\treturn false\n\t})() : fails(data, pattern)\n\n/**\n * Tests a given value against a set of patterns, untill one succeeds\n * Returns an error if none succeed\n */\nexport const oneOf = (...patterns) => \n\t(data) => {\n\t\tfor(let pattern of patterns) {\n\t\t\tif (!fails(data, pattern)) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\treturn error('data does not match oneOf patterns',data,patterns)\n\t}\n\n/**\n * Tests a given array of values against a set of patterns\n * If any value does not match one of the patterns, it will return an error\n * If not given an array to test, it will return an error\n */\nexport const anyOf = (...patterns) =>\n\t(data) => {\n\t\tif (!Array.isArray(data)) {\n\t\t\treturn error('data is not an array',data,'anyOf')\n\t\t}\n\t\tfor (let value of data) {\n\t\t\tif (oneOf(...patterns)(value)) {\n\t\t\t\treturn error('data does not match anyOf patterns',value,patterns)\n\t\t\t}\n\t\t}\n\t\treturn false\n\t}\n\n/**\n * Tests a given value to see if it is a valid (and absolute) URL, by\n * parsing it with the URL() constructor, and then testing the href\n * value to be equal to the initial value.\n */\nexport function validURL(data) {\n\ttry {\n\t\tif (data instanceof URL) {\n\t\t\tdata = data.href\n\t\t}\n\t\tlet url = new URL(data)\n\t\tif (url.href!=data) {\n\t\t\treturn error('data is not a valid url',data,'validURL')\n\t\t}\n\t} catch(e) {\n\t\treturn error('data is not a valid url',data,'validURL')\n\t}\n\treturn false\n}\n\n/**\n * Tests a given value to see if it looks like a valid email address, by\n * testing it against a regular expression. So there are no guarantees that\n * it is an actual working email address, just that it looks like one.\n */\nexport function validEmail(data) {\n\tif (/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(data)) {\n\t\treturn false // data matches email regex\n\t}\n\treturn error('data is not a valid email',data,'validEmail')\n}\n\n/**\n * Tests a given value to see if it is an object which is an instance of the given\n * constructor\n */\nexport const instanceOf = (constructor) =>\n\t(data) => !(data instanceof constructor) \n\t\t? error('data is not an instanceof pattern',data,constructor)\n\t\t: false\n\n/**\n * Runs the given test pattern on a value, if the test succeeds, it fails\n * the not() test.\n */\nexport const not = (pattern) =>\n\t(data) => fails(data, pattern) \n\t\t? false \n\t\t: error('data matches pattern, when required not to', data, pattern)\n\n/**\n * returns an array of problems if the data fails to satisfy \n * the assertions in the given pattern, false otherwise\n * @param {any} data The data to match\n * @param {any} pattern The pattern to match\n * @param {any} root Root object for assertions, set to data by default\n * @return {Array|false} Array with problems if the pattern fails, false otherwise\n */\nexport function fails(data, pattern, root) {\n\tif (!root) {\n\t\troot = data\n\t}\n\tlet problems = []\n\tif (pattern === Boolean) {\n\t\tif (typeof data != 'boolean' && !(data instanceof Boolean)) {\n\t\t\tproblems.push(error('data is not a boolean', data, pattern))\n\t\t}\t\t\n\t} else if (pattern === Number) {\n\t\tif (typeof data != 'number' && !(data instanceof Number)) {\n\t\t\tproblems.push(error('data is not a number', data, pattern))\n\t\t}\n\t} else if (pattern === String) {\n\t\tif (typeof data != 'string' && !(data instanceof String)) {\n\t\t\tproblems.push(error('data is not a string', data, pattern))\n\t\t}\n\t\tif (data == \"\") {\n\t\t\tproblems.push(error('data is an empty string, which is not allowed', data, pattern))\n\t\t}\n\t} else if (pattern instanceof RegExp) {\n \tif (Array.isArray(data)) {\n\t\t\tlet index = data.findIndex(element => fails(element,pattern,root))\n if (index>-1) {\n \tproblems.push(error('data['+index+'] does not match pattern', data[index], pattern))\n }\n } else if (typeof data == 'undefined') {\n \tproblems.push(error('data is undefined, should match pattern', data, pattern))\n \t} else if (!pattern.test(data)) {\n \tproblems.push(error('data does not match pattern', data, pattern))\n }\n } else if (pattern instanceof Function) {\n if (pattern(data, root)) {\n \tproblems.push(error('data does not match function', data, pattern))\n }\n } else if (Array.isArray(pattern)) {\n\t\tif (!Array.isArray(data)) {\n\t\t\tproblems.push(error('data is not an array',data,[]))\n\t\t}\n\t\tfor (let p of pattern) {\n\t\t\tfor (let val of data) {\n\t\t\t\tlet problem = fails(val, p, root)\n\t\t\t\tif (Array.isArray(problem)) {\n\t\t\t\t\tproblems = problems.concat(problem)\n\t\t\t\t} else if (problem) {\n\t\t\t\t\tproblems.push(problem)\n\t\t\t\t}\n\t\t\t}\n \t}\n } else if (pattern && typeof pattern == 'object') {\n if (Array.isArray(data)) {\n let index = data.findIndex(element => fails(element,pattern,root))\n if (index>-1) {\n \tproblems.push(error('data['+index+'] does not match pattern', data[index], pattern))\n }\n } else if (!data || typeof data != 'object') {\n \tproblems.push(error('data is not an object, pattern is', data, pattern))\n } else {\n \tif (data instanceof URLSearchParams) {\n \t\tdata = Object.fromEntries(data)\n \t}\n\t for (const [wKey, wVal] of Object.entries(pattern)) {\n\t let result = fails(data[wKey], wVal, root)\n\t if (result) {\n\t \tproblems = problems.concat(result)\n\t }\n\t }\n\t }\n } else {\n \tif (pattern!=data) {\n \t\tproblems.push(error('data and pattern are not equal', data, pattern))\n \t}\n }\n if (problems.length) {\n \treturn problems\n }\n return false\n}\n\n\n/**\n * Class used in assert() to add problems found and details to the error object\n */\nclass assertError extends Error {\n\tconstructor(message, problems, ...details) {\n\t\tsuper(message)\n\t\tthis.problems = problems\n\t\tthis.details = details\n\t}\n}\n\n/**\n * Returns an object with message, found and expected properties\n */ \nexport function error(message, found, expected) {\n\treturn {\n\t\tmessage,\n\t\tfound,\n\t\texpected\n\t}\n}\n"],"names":["$parcel$export","e","n","v","s","Object","defineProperty","get","set","enumerable","configurable","$2ddd80d1adc2ea42$exports","$2ddd80d1adc2ea42$export$d7c4a0dd6a4567e5","globalThis","assertEnabled","$2ddd80d1adc2ea42$export$e20fbacbb41798b","$2ddd80d1adc2ea42$export$a7a9523472993e97","$2ddd80d1adc2ea42$export$478159de811fd37d","$2ddd80d1adc2ea42$export$7acb7b24c478f9c6","$2ddd80d1adc2ea42$export$1788c381af06add2","$2ddd80d1adc2ea42$export$a3bc9b8ed74fc","$2ddd80d1adc2ea42$export$a83bcf183f49ea9","$2ddd80d1adc2ea42$export$a9a18ae5ba42aeab","$2ddd80d1adc2ea42$export$b26c150f612c10f7","$2ddd80d1adc2ea42$export$c6f1a4382426409f","$2ddd80d1adc2ea42$export$9ab921aaffe56820","$2ddd80d1adc2ea42$export$ca03416d6c9e029e","$2ddd80d1adc2ea42$export$6003a5f097c73977","source","test","problems","$2ddd80d1adc2ea42$var$assertError","pattern","data","console","warning","patterns","Array","isArray","value","URL","href","url","constructor","root","Boolean","push","Number","String","RegExp","index","findIndex","element","Function","p","val","problem","concat","wKey","wVal","URLSearchParams","fromEntries","entries","result","length","Error","message","details","found","expected","assert"],"version":3,"file":"browser.js.map","sourceRoot":"../"}
|
|
1
|
+
{"mappings":"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","sources":["<anon>","src/browser.mjs","src/assert.mjs"],"sourcesContent":["\nfunction $parcel$export(e, n, v, s) {\n Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});\n}\nvar $2ddd80d1adc2ea42$exports = {};\n\n$parcel$export($2ddd80d1adc2ea42$exports, \"enable\", () => $2ddd80d1adc2ea42$export$d7c4a0dd6a4567e5);\n$parcel$export($2ddd80d1adc2ea42$exports, \"disable\", () => $2ddd80d1adc2ea42$export$e20fbacbb41798b);\n$parcel$export($2ddd80d1adc2ea42$exports, \"assert\", () => $2ddd80d1adc2ea42$export$a7a9523472993e97);\n$parcel$export($2ddd80d1adc2ea42$exports, \"fails\", () => $2ddd80d1adc2ea42$export$478159de811fd37d);\n$parcel$export($2ddd80d1adc2ea42$exports, \"Optional\", () => $2ddd80d1adc2ea42$export$7acb7b24c478f9c6);\n$parcel$export($2ddd80d1adc2ea42$exports, \"Required\", () => $2ddd80d1adc2ea42$export$1788c381af06add2);\n$parcel$export($2ddd80d1adc2ea42$exports, \"error\", () => $2ddd80d1adc2ea42$export$a3bc9b8ed74fc);\n$parcel$export($2ddd80d1adc2ea42$exports, \"Recommended\", () => $2ddd80d1adc2ea42$export$a83bcf183f49ea9);\n$parcel$export($2ddd80d1adc2ea42$exports, \"oneOf\", () => $2ddd80d1adc2ea42$export$a9a18ae5ba42aeab);\n$parcel$export($2ddd80d1adc2ea42$exports, \"anyOf\", () => $2ddd80d1adc2ea42$export$b26c150f612c10f7);\n$parcel$export($2ddd80d1adc2ea42$exports, \"allOf\", () => $2ddd80d1adc2ea42$export$f632c79c8963a286);\n$parcel$export($2ddd80d1adc2ea42$exports, \"validURL\", () => $2ddd80d1adc2ea42$export$c6f1a4382426409f);\n$parcel$export($2ddd80d1adc2ea42$exports, \"validEmail\", () => $2ddd80d1adc2ea42$export$9ab921aaffe56820);\n$parcel$export($2ddd80d1adc2ea42$exports, \"instanceOf\", () => $2ddd80d1adc2ea42$export$ca03416d6c9e029e);\n$parcel$export($2ddd80d1adc2ea42$exports, \"not\", () => $2ddd80d1adc2ea42$export$6003a5f097c73977);\n/*\nFIXME: Optional() fails if the pattern is not set and the value is\nTODO: scratch: Required() and Optional() and Recommended() should test multiple patterns\n instead: add allOf(...patterns) function\nTODO: add assertExplain global flag, so that if assert() fails, you can call explain() with\n the same pattern and it will return text explanation of why it failed, each assertion function must \n then check assertExplain, and return a text explanation of what fails or succeeds\n top level can then filter to show only the failures\n (so that not(x) can show the succeeds message of x)\n*/ /**\n * assertEnabled (Boolean) used to toggle whether the assert()\n * method should test assertions or not.\n */ globalThis.assertEnabled = false;\nfunction $2ddd80d1adc2ea42$export$d7c4a0dd6a4567e5() {\n globalThis.assertEnabled = true;\n}\nfunction $2ddd80d1adc2ea42$export$e20fbacbb41798b() {\n globalThis.assertEnabled = false;\n}\nfunction $2ddd80d1adc2ea42$export$a7a9523472993e97(source, test) {\n if (globalThis.assertEnabled) {\n let problems = $2ddd80d1adc2ea42$export$478159de811fd37d(source, test);\n if (problems) throw new $2ddd80d1adc2ea42$var$assertError(\"Assertions failed\", problems, source);\n }\n}\nfunction $2ddd80d1adc2ea42$export$7acb7b24c478f9c6(pattern) {\n return function _Optional(data, root, path) {\n if (data == null || typeof data == \"undefined\") return false;\n else return $2ddd80d1adc2ea42$export$478159de811fd37d(data, pattern, root, path);\n };\n}\nfunction $2ddd80d1adc2ea42$export$1788c381af06add2(pattern) {\n return function _Required(data, root, path) {\n if (data == null || typeof data == \"undefined\") return $2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data is required\", data, pattern || \"any value\", path);\n else if (typeof pattern != \"undefined\") return $2ddd80d1adc2ea42$export$478159de811fd37d(data, pattern, root, path);\n else return false;\n };\n}\nfunction $2ddd80d1adc2ea42$export$a83bcf183f49ea9(...pattern) {\n return function _Recommended(data, root, path) {\n if (data == null || typeof data == \"undefined\") {\n console.warn(\"data does not contain recommended value\", data, pattern, path);\n return false;\n } else return $2ddd80d1adc2ea42$export$478159de811fd37d(data, pattern, root, path);\n };\n}\nfunction $2ddd80d1adc2ea42$export$a9a18ae5ba42aeab(...patterns) {\n return function _oneOf(data, root, path) {\n for (let pattern of patterns){\n if (!$2ddd80d1adc2ea42$export$478159de811fd37d(data, pattern, root, path)) return false;\n }\n return $2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data does not match oneOf patterns\", data, patterns, path);\n };\n}\nfunction $2ddd80d1adc2ea42$export$b26c150f612c10f7(...patterns) {\n return function _anyOf(data, root, path) {\n if (!Array.isArray(data)) return $2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data is not an array\", data, \"anyOf\", path);\n for (let value of data){\n if ($2ddd80d1adc2ea42$export$a9a18ae5ba42aeab(...patterns)(value)) return $2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data does not match anyOf patterns\", value, patterns, path);\n }\n return false;\n };\n}\nfunction $2ddd80d1adc2ea42$export$f632c79c8963a286(...patterns) {\n return function _allOf(data, root, path) {\n let problems = [];\n for (let pattern of patterns)problems = problems.concat($2ddd80d1adc2ea42$export$478159de811fd37d(data, pattern, root, path));\n problems = problems.filter(Boolean);\n if (problems.length) return $2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data does not match all given patterns\", data, patterns, path, problems);\n };\n}\nfunction $2ddd80d1adc2ea42$export$c6f1a4382426409f(data, root, path) {\n try {\n if (data instanceof URL) data = data.href;\n let url = new URL(data);\n if (url.href != data) {\n if (!(url.href + \"/\" == data || url.href == data + \"/\")) // new URL() always adds a / as path\n return $2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data is not a valid url\", data, \"validURL\", path);\n }\n } catch (e) {\n return $2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data is not a valid url\", data, \"validURL\", path);\n }\n}\nfunction $2ddd80d1adc2ea42$export$9ab921aaffe56820(data, root, path) {\n if (!/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(data)) return $2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data is not a valid email\", data, \"validEmail\", path);\n}\nfunction $2ddd80d1adc2ea42$export$ca03416d6c9e029e(constructor) {\n return function _instanceOf(data, root, path) {\n if (!(data instanceof constructor)) return $2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data is not an instanceof pattern\", data, constructor, path);\n };\n}\nfunction $2ddd80d1adc2ea42$export$6003a5f097c73977(pattern) {\n return function _not(data, root, path) {\n if (!$2ddd80d1adc2ea42$export$478159de811fd37d(data, pattern, root, path)) return $2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data matches pattern, when required not to\", data, pattern, path);\n };\n}\nfunction $2ddd80d1adc2ea42$export$478159de811fd37d(data, pattern, root, path = \"\") {\n if (!root) root = data;\n let problems = [];\n if (pattern === Boolean) {\n if (typeof data != \"boolean\" && !(data instanceof Boolean)) problems.push($2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data is not a boolean\", data, pattern, path));\n } else if (pattern === Number) {\n if (typeof data != \"number\" && !(data instanceof Number)) problems.push($2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data is not a number\", data, pattern, path));\n } else if (pattern === String) {\n if (typeof data != \"string\" && !(data instanceof String)) problems.push($2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data is not a string\", data, pattern, path));\n if (data == \"\") problems.push($2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data is an empty string, which is not allowed\", data, pattern, path));\n } else if (pattern instanceof RegExp) {\n if (Array.isArray(data)) {\n let index = data.findIndex((element, index)=>$2ddd80d1adc2ea42$export$478159de811fd37d(element, pattern, root, path + \"[\" + index + \"]\"));\n if (index > -1) problems.push($2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data[\" + index + \"] does not match pattern\", data[index], pattern, path + \"[\" + index + \"]\"));\n } else if (typeof data == \"undefined\") problems.push($2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data is undefined, should match pattern\", data, pattern, path));\n else if (!pattern.test(data)) problems.push($2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data does not match pattern\", data, pattern, path));\n } else if (pattern instanceof Function) {\n let problem = pattern(data, root, path);\n if (problem) {\n if (Array.isArray(problem)) problems = problems.concat(problem);\n else problems.push(problem);\n }\n } else if (Array.isArray(pattern)) {\n if (!Array.isArray(data)) problems.push($2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data is not an array\", data, [], path));\n for (let p of pattern)for (let index of data.keys()){\n let problem = $2ddd80d1adc2ea42$export$478159de811fd37d(data[index], p, root, path + \"[\" + index + \"]\");\n if (Array.isArray(problem)) problems = problems.concat(problem);\n else if (problem) problems.push(problem);\n }\n } else if (pattern && typeof pattern == \"object\") {\n if (Array.isArray(data)) {\n let index = data.findIndex((element, index)=>$2ddd80d1adc2ea42$export$478159de811fd37d(element, pattern, root, path + \"[\" + index + \"]\"));\n if (index > -1) problems.push($2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data[\" + index + \"] does not match pattern\", data[index], pattern, path + \"[\" + index + \"]\"));\n } else if (!data || typeof data != \"object\") problems.push($2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data is not an object, pattern is\", data, pattern, path));\n else {\n if (data instanceof URLSearchParams) data = Object.fromEntries(data);\n if (pattern instanceof Function) {\n let result = $2ddd80d1adc2ea42$export$478159de811fd37d(data, pattern, root, path);\n if (result) problems = problems.concat(result);\n } else for (const [wKey, wVal] of Object.entries(pattern)){\n let result = $2ddd80d1adc2ea42$export$478159de811fd37d(data[wKey], wVal, root, path + \".\" + wKey);\n if (result) problems = problems.concat(result);\n }\n }\n } else if (pattern != data) problems.push($2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data and pattern are not equal\", data, pattern, path));\n if (problems.length) return problems;\n return false;\n}\n/**\n * Class used in assert() to add problems found and details to the error object\n */ class $2ddd80d1adc2ea42$var$assertError extends Error {\n constructor(message, problems, ...details){\n super(message);\n this.problems = problems;\n this.details = details;\n }\n}\nfunction $2ddd80d1adc2ea42$export$a3bc9b8ed74fc(message, found, expected, path, problems) {\n let result = {\n message: message,\n found: found,\n expected: expected,\n path: path\n };\n if (problems) result.problems = problems;\n return result;\n}\n\n\nglobalThis.assert = $2ddd80d1adc2ea42$exports;\n\n\n//# sourceMappingURL=browser.js.map\n","import * as assert from './assert.mjs'\n\nglobalThis.assert = assert\n","/*\nFIXME: Optional() fails if the pattern is not set and the value is\nTODO: scratch: Required() and Optional() and Recommended() should test multiple patterns\n instead: add allOf(...patterns) function\nTODO: add assertExplain global flag, so that if assert() fails, you can call explain() with\n the same pattern and it will return text explanation of why it failed, each assertion function must \n then check assertExplain, and return a text explanation of what fails or succeeds\n top level can then filter to show only the failures\n (so that not(x) can show the succeeds message of x)\n*/\n\n/**\n * assertEnabled (Boolean) used to toggle whether the assert()\n * method should test assertions or not.\n */\nglobalThis.assertEnabled = false\n\n/**\n * Enables assertion testing with assert()\n */\nexport function enable() {\n\tglobalThis.assertEnabled = true\n}\n\n/**\n * Disables assertion testing with assert()\n */\nexport function disable() {\n\tglobalThis.assertEnabled = false\n}\n\n/**\n * This function will check the source for the assertions in test, if\n * assertion checking is enabled globally.\n * If it is, and any assertion fails, it will throw an assertError\n * with a list of problems and other details.\n */\nexport function assert(source, test) {\n\tif (globalThis.assertEnabled) {\n\t\tlet problems = fails(source,test)\n\t\tif (problems) {\n\t\t\tthrow new assertError('Assertions failed', problems, source)\n\t\t}\n\t}\n}\n\n/**\n * Tests a given value against a pattern, only if the value is not null or undefined\n */\nexport function Optional(pattern) {\n\treturn function _Optional(data, root, path) {\n\t\tif (data==null || typeof data == 'undefined') {\n\t\t\treturn false \n\t\t} else {\n\t\t\treturn fails(data, pattern, root, path)\n\t\t}\n\t}\n}\n\n/**\n * Tests a given value against a pattern, always.\n */\nexport function Required(pattern) {\n\treturn function _Required(data, root, path) {\n\t\tif (data==null || typeof data == 'undefined') {\n\t\t\treturn error('data is required', data, pattern || 'any value', path)\n\t\t} else if (typeof pattern != 'undefined') {\n\t\t\treturn fails(data, pattern, root, path)\n\t\t} else {\n\t\t\treturn false\n\t\t}\n\t}\n}\n\n/**\n * Tests a given value against a pattern, only if the value is not null or undefined\n * If null or undefined, it does print a warning to the console.\n */\nexport function Recommended(...pattern) {\n\treturn function _Recommended(data, root, path) {\n\t\tif (data==null || typeof data == 'undefined') {\n\t\t\tconsole.warn('data does not contain recommended value', data, pattern, path)\n\t\t\treturn false\n\t\t} else {\n\t\t\treturn fails(data, pattern, root, path)\n\t\t}\n\t}\n}\n\n/**\n * Tests a given value against a set of patterns, untill one succeeds\n * Returns an error if none succeed\n */\nexport function oneOf(...patterns) { \n\treturn function _oneOf(data, root, path) {\n\t\tfor(let pattern of patterns) {\n\t\t\tif (!fails(data, pattern, root, path)) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\treturn error('data does not match oneOf patterns', data, patterns, path)\n\t}\n}\n\n/**\n * Tests a given array of values against a set of patterns\n * If any value does not match one of the patterns, it will return an error\n * If not given an array to test, it will return an error\n */\nexport function anyOf(...patterns) {\n\treturn function _anyOf(data, root, path) {\n\t\tif (!Array.isArray(data)) {\n\t\t\treturn error('data is not an array',data,'anyOf',path)\n\t\t}\n\t\tfor (let value of data) {\n\t\t\tif (oneOf(...patterns)(value)) {\n\t\t\t\treturn error('data does not match anyOf patterns',value,patterns,path)\n\t\t\t}\n\t\t}\n\t\treturn false\n\t}\n}\n\nexport function allOf(...patterns) {\n\treturn function _allOf(data, root, path) {\n\t\tlet problems = []\n\t\tfor (let pattern of patterns) {\n\t\t\tproblems = problems.concat(fails(data, pattern, root, path))\n\t\t}\n\t\tproblems = problems.filter(Boolean)\n\t\tif (problems.length) {\n\t\t\treturn error('data does not match all given patterns', data, patterns, path, problems)\n\t\t}\n\t}\n}\n\n/**\n * Tests a given value to see if it is a valid (and absolute) URL, by\n * parsing it with the URL() constructor, and then testing the href\n * value to be equal to the initial value.\n */\nexport function validURL(data, root, path) {\n\ttry {\n\t\tif (data instanceof URL) {\n\t\t\tdata = data.href\n\t\t}\n\t\tlet url = new URL(data)\n\t\tif (url.href!=data) {\n\t\t\tif (!(url.href+'/'==data || url.href==data+'/')) {\n\t\t\t\t// new URL() always adds a / as path\n\t\t\t\treturn error('data is not a valid url',data,'validURL',path)\n\t\t\t}\n\t\t}\n\t} catch(e) {\n\t\treturn error('data is not a valid url',data,'validURL',path)\n\t}\n}\n\n/**\n * Tests a given value to see if it looks like a valid email address, by\n * testing it against a regular expression. So there are no guarantees that\n * it is an actual working email address, just that it looks like one.\n */\nexport function validEmail(data, root, path) {\n\tif (!/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(data)) {\n\t\treturn error('data is not a valid email',data,'validEmail',path)\n\t}\n}\n\n/**\n * Tests a given value to see if it is an object which is an instance of the given\n * constructor\n */\nexport function instanceOf(constructor) {\n\treturn function _instanceOf(data, root, path) {\n\t\tif (!(data instanceof constructor)) {\n\t\t\treturn error('data is not an instanceof pattern',data,constructor,path)\n\t\t}\n\t}\n}\n\n/**\n * Runs the given test pattern on a value, if the test succeeds, it fails\n * the not() test.\n */\nexport function not(pattern) {\n\treturn function _not(data, root, path) {\n\t\tif (!fails(data, pattern, root, path)) {\n\t\t\treturn error('data matches pattern, when required not to', data, pattern, path)\n\t\t}\n\t}\n}\n\n/**\n * returns an array of problems if the data fails to satisfy \n * the assertions in the given pattern, false otherwise\n * @param {any} data The data to match\n * @param {any} pattern The pattern to match\n * @param {any} root Root object for assertions, set to data by default\n * @return {Array|false} Array with problems if the pattern fails, false otherwise\n */\nexport function fails(data, pattern, root, path='') {\n\tif (!root) {\n\t\troot = data\n\t}\n\tlet problems = []\n\tif (pattern === Boolean) {\n\t\tif (typeof data != 'boolean' && !(data instanceof Boolean)) {\n\t\t\tproblems.push(error('data is not a boolean', data, pattern, path))\n\t\t}\t\t\n\t} else if (pattern === Number) {\n\t\tif (typeof data != 'number' && !(data instanceof Number)) {\n\t\t\tproblems.push(error('data is not a number', data, pattern, path))\n\t\t}\n\t} else if (pattern === String) {\n\t\tif (typeof data != 'string' && !(data instanceof String)) {\n\t\t\tproblems.push(error('data is not a string', data, pattern, path))\n\t\t}\n\t\tif (data == \"\") {\n\t\t\tproblems.push(error('data is an empty string, which is not allowed', data, pattern, path))\n\t\t}\n\t} else if (pattern instanceof RegExp) {\n \tif (Array.isArray(data)) {\n\t\t\tlet index = data.findIndex((element,index) => fails(element,pattern,root,path+'['+index+']'))\n if (index>-1) {\n \tproblems.push(error('data['+index+'] does not match pattern', data[index], pattern, path+'['+index+']'))\n }\n } else if (typeof data == 'undefined') {\n \tproblems.push(error('data is undefined, should match pattern', data, pattern, path))\n \t} else if (!pattern.test(data)) {\n \tproblems.push(error('data does not match pattern', data, pattern, path))\n }\n } else if (pattern instanceof Function) {\n let problem = pattern(data, root, path)\n if (problem) {\n \tif (Array.isArray(problem)) {\n \t\tproblems = problems.concat(problem)\n \t} else {\n\t \tproblems.push(problem)\n\t }\n }\n } else if (Array.isArray(pattern)) {\n\t\tif (!Array.isArray(data)) {\n\t\t\tproblems.push(error('data is not an array',data,[],path))\n\t\t}\n\t\tfor (let p of pattern) {\n\t\t\tfor (let index of data.keys()) {\n\t\t\t\tlet problem = fails(data[index], p, root, path+'['+index+']')\n\t\t\t\tif (Array.isArray(problem)) {\n\t\t\t\t\tproblems = problems.concat(problem)\n\t\t\t\t} else if (problem) {\n\t\t\t\t\tproblems.push(problem)\n\t\t\t\t}\n\t\t\t}\n \t}\n } else if (pattern && typeof pattern == 'object') {\n if (Array.isArray(data)) {\n let index = data.findIndex((element,index) => fails(element,pattern,root,path+'['+index+']'))\n if (index>-1) {\n \tproblems.push(error('data['+index+'] does not match pattern', data[index], pattern, path+'['+index+']'))\n }\n } else if (!data || typeof data != 'object') {\n \tproblems.push(error('data is not an object, pattern is', data, pattern, path))\n } else {\n \tif (data instanceof URLSearchParams) {\n \t\tdata = Object.fromEntries(data)\n \t}\n \tif (pattern instanceof Function) {\n \t\tlet result = fails(data, pattern, root, path)\n\t if (result) {\n\t \tproblems = problems.concat(result)\n\t }\n \t} else {\n\t\t for (const [wKey, wVal] of Object.entries(pattern)) {\n\t\t let result = fails(data[wKey], wVal, root, path+'.'+wKey)\n\t\t if (result) {\n\t\t \tproblems = problems.concat(result)\n\t\t }\n\t\t }\n\t\t }\n\t }\n } else {\n \tif (pattern!=data) {\n \t\tproblems.push(error('data and pattern are not equal', data, pattern, path))\n \t}\n }\n if (problems.length) {\n \treturn problems\n }\n return false\n}\n\n\n/**\n * Class used in assert() to add problems found and details to the error object\n */\nclass assertError extends Error {\n\tconstructor(message, problems, ...details) {\n\t\tsuper(message)\n\t\tthis.problems = problems\n\t\tthis.details = details\n\t}\n}\n\n/**\n * Returns an object with message, found and expected properties\n */ \nexport function error(message, found, expected, path, problems) {\n\tlet result = {\n\t\tmessage,\n\t\tfound,\n\t\texpected,\n\t\tpath\n\t}\n\tif (problems) {\n\t\tresult.problems = problems\n\t}\n\treturn result\n}\n"],"names":["$parcel$export","e","n","v","s","Object","defineProperty","get","set","enumerable","configurable","$2ddd80d1adc2ea42$exports","$2ddd80d1adc2ea42$export$d7c4a0dd6a4567e5","globalThis","assertEnabled","$2ddd80d1adc2ea42$export$e20fbacbb41798b","$2ddd80d1adc2ea42$export$a7a9523472993e97","source","test","problems","$2ddd80d1adc2ea42$export$478159de811fd37d","$2ddd80d1adc2ea42$var$assertError","$2ddd80d1adc2ea42$export$7acb7b24c478f9c6","pattern","data","root","path","$2ddd80d1adc2ea42$export$1788c381af06add2","$2ddd80d1adc2ea42$export$a3bc9b8ed74fc","$2ddd80d1adc2ea42$export$a83bcf183f49ea9","console","warn","$2ddd80d1adc2ea42$export$a9a18ae5ba42aeab","patterns","$2ddd80d1adc2ea42$export$b26c150f612c10f7","Array","isArray","value","$2ddd80d1adc2ea42$export$f632c79c8963a286","concat","filter","Boolean","length","$2ddd80d1adc2ea42$export$c6f1a4382426409f","URL","href","url","$2ddd80d1adc2ea42$export$9ab921aaffe56820","$2ddd80d1adc2ea42$export$ca03416d6c9e029e","constructor","$2ddd80d1adc2ea42$export$6003a5f097c73977","push","Number","String","RegExp","index","findIndex","element","Function","problem","p","keys","URLSearchParams","fromEntries","result","wKey","wVal","entries","Error","message","details","found","expected","assert"],"version":3,"file":"browser.js.map","sourceRoot":"../"}
|
package/package.json
CHANGED
package/src/assert.mjs
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
/*
|
|
2
|
+
FIXME: Optional() fails if the pattern is not set and the value is
|
|
3
|
+
TODO: scratch: Required() and Optional() and Recommended() should test multiple patterns
|
|
4
|
+
instead: add allOf(...patterns) function
|
|
5
|
+
TODO: add assertExplain global flag, so that if assert() fails, you can call explain() with
|
|
6
|
+
the same pattern and it will return text explanation of why it failed, each assertion function must
|
|
7
|
+
then check assertExplain, and return a text explanation of what fails or succeeds
|
|
8
|
+
top level can then filter to show only the failures
|
|
9
|
+
(so that not(x) can show the succeeds message of x)
|
|
10
|
+
*/
|
|
11
|
+
|
|
1
12
|
/**
|
|
2
13
|
* assertEnabled (Boolean) used to toggle whether the assert()
|
|
3
14
|
* method should test assertions or not.
|
|
@@ -24,7 +35,7 @@ export function disable() {
|
|
|
24
35
|
* If it is, and any assertion fails, it will throw an assertError
|
|
25
36
|
* with a list of problems and other details.
|
|
26
37
|
*/
|
|
27
|
-
export
|
|
38
|
+
export function assert(source, test) {
|
|
28
39
|
if (globalThis.assertEnabled) {
|
|
29
40
|
let problems = fails(source,test)
|
|
30
41
|
if (problems) {
|
|
@@ -36,75 +47,113 @@ export const assert = (source, test) => {
|
|
|
36
47
|
/**
|
|
37
48
|
* Tests a given value against a pattern, only if the value is not null or undefined
|
|
38
49
|
*/
|
|
39
|
-
export
|
|
40
|
-
|
|
50
|
+
export function Optional(pattern) {
|
|
51
|
+
return function _Optional(data, root, path) {
|
|
52
|
+
if (data==null || typeof data == 'undefined') {
|
|
53
|
+
return false
|
|
54
|
+
} else {
|
|
55
|
+
return fails(data, pattern, root, path)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
41
59
|
|
|
42
60
|
/**
|
|
43
61
|
* Tests a given value against a pattern, always.
|
|
44
62
|
*/
|
|
45
|
-
export
|
|
46
|
-
|
|
63
|
+
export function Required(pattern) {
|
|
64
|
+
return function _Required(data, root, path) {
|
|
65
|
+
if (data==null || typeof data == 'undefined') {
|
|
66
|
+
return error('data is required', data, pattern || 'any value', path)
|
|
67
|
+
} else if (typeof pattern != 'undefined') {
|
|
68
|
+
return fails(data, pattern, root, path)
|
|
69
|
+
} else {
|
|
70
|
+
return false
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
47
74
|
|
|
48
75
|
/**
|
|
49
76
|
* Tests a given value against a pattern, only if the value is not null or undefined
|
|
50
77
|
* If null or undefined, it does print a warning to the console.
|
|
51
78
|
*/
|
|
52
|
-
export
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
79
|
+
export function Recommended(...pattern) {
|
|
80
|
+
return function _Recommended(data, root, path) {
|
|
81
|
+
if (data==null || typeof data == 'undefined') {
|
|
82
|
+
console.warn('data does not contain recommended value', data, pattern, path)
|
|
83
|
+
return false
|
|
84
|
+
} else {
|
|
85
|
+
return fails(data, pattern, root, path)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
57
89
|
|
|
58
90
|
/**
|
|
59
91
|
* Tests a given value against a set of patterns, untill one succeeds
|
|
60
92
|
* Returns an error if none succeed
|
|
61
93
|
*/
|
|
62
|
-
export
|
|
63
|
-
(data)
|
|
94
|
+
export function oneOf(...patterns) {
|
|
95
|
+
return function _oneOf(data, root, path) {
|
|
64
96
|
for(let pattern of patterns) {
|
|
65
|
-
if (!fails(data, pattern)) {
|
|
97
|
+
if (!fails(data, pattern, root, path)) {
|
|
66
98
|
return false
|
|
67
99
|
}
|
|
68
100
|
}
|
|
69
|
-
return error('data does not match oneOf patterns',data,patterns)
|
|
101
|
+
return error('data does not match oneOf patterns', data, patterns, path)
|
|
70
102
|
}
|
|
103
|
+
}
|
|
71
104
|
|
|
72
105
|
/**
|
|
73
106
|
* Tests a given array of values against a set of patterns
|
|
74
107
|
* If any value does not match one of the patterns, it will return an error
|
|
75
108
|
* If not given an array to test, it will return an error
|
|
76
109
|
*/
|
|
77
|
-
export
|
|
78
|
-
(data)
|
|
110
|
+
export function anyOf(...patterns) {
|
|
111
|
+
return function _anyOf(data, root, path) {
|
|
79
112
|
if (!Array.isArray(data)) {
|
|
80
|
-
return error('data is not an array',data,'anyOf')
|
|
113
|
+
return error('data is not an array',data,'anyOf',path)
|
|
81
114
|
}
|
|
82
115
|
for (let value of data) {
|
|
83
116
|
if (oneOf(...patterns)(value)) {
|
|
84
|
-
return error('data does not match anyOf patterns',value,patterns)
|
|
117
|
+
return error('data does not match anyOf patterns',value,patterns,path)
|
|
85
118
|
}
|
|
86
119
|
}
|
|
87
120
|
return false
|
|
88
121
|
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export function allOf(...patterns) {
|
|
125
|
+
return function _allOf(data, root, path) {
|
|
126
|
+
let problems = []
|
|
127
|
+
for (let pattern of patterns) {
|
|
128
|
+
problems = problems.concat(fails(data, pattern, root, path))
|
|
129
|
+
}
|
|
130
|
+
problems = problems.filter(Boolean)
|
|
131
|
+
if (problems.length) {
|
|
132
|
+
return error('data does not match all given patterns', data, patterns, path, problems)
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
89
136
|
|
|
90
137
|
/**
|
|
91
138
|
* Tests a given value to see if it is a valid (and absolute) URL, by
|
|
92
139
|
* parsing it with the URL() constructor, and then testing the href
|
|
93
140
|
* value to be equal to the initial value.
|
|
94
141
|
*/
|
|
95
|
-
export function validURL(data) {
|
|
142
|
+
export function validURL(data, root, path) {
|
|
96
143
|
try {
|
|
97
144
|
if (data instanceof URL) {
|
|
98
145
|
data = data.href
|
|
99
146
|
}
|
|
100
147
|
let url = new URL(data)
|
|
101
148
|
if (url.href!=data) {
|
|
102
|
-
|
|
149
|
+
if (!(url.href+'/'==data || url.href==data+'/')) {
|
|
150
|
+
// new URL() always adds a / as path
|
|
151
|
+
return error('data is not a valid url',data,'validURL',path)
|
|
152
|
+
}
|
|
103
153
|
}
|
|
104
154
|
} catch(e) {
|
|
105
|
-
return error('data is not a valid url',data,'validURL')
|
|
155
|
+
return error('data is not a valid url',data,'validURL',path)
|
|
106
156
|
}
|
|
107
|
-
return false
|
|
108
157
|
}
|
|
109
158
|
|
|
110
159
|
/**
|
|
@@ -112,30 +161,35 @@ export function validURL(data) {
|
|
|
112
161
|
* testing it against a regular expression. So there are no guarantees that
|
|
113
162
|
* it is an actual working email address, just that it looks like one.
|
|
114
163
|
*/
|
|
115
|
-
export function validEmail(data) {
|
|
116
|
-
if (
|
|
117
|
-
return
|
|
164
|
+
export function validEmail(data, root, path) {
|
|
165
|
+
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(data)) {
|
|
166
|
+
return error('data is not a valid email',data,'validEmail',path)
|
|
118
167
|
}
|
|
119
|
-
return error('data is not a valid email',data,'validEmail')
|
|
120
168
|
}
|
|
121
169
|
|
|
122
170
|
/**
|
|
123
171
|
* Tests a given value to see if it is an object which is an instance of the given
|
|
124
172
|
* constructor
|
|
125
173
|
*/
|
|
126
|
-
export
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
174
|
+
export function instanceOf(constructor) {
|
|
175
|
+
return function _instanceOf(data, root, path) {
|
|
176
|
+
if (!(data instanceof constructor)) {
|
|
177
|
+
return error('data is not an instanceof pattern',data,constructor,path)
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
130
181
|
|
|
131
182
|
/**
|
|
132
183
|
* Runs the given test pattern on a value, if the test succeeds, it fails
|
|
133
184
|
* the not() test.
|
|
134
185
|
*/
|
|
135
|
-
export
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
186
|
+
export function not(pattern) {
|
|
187
|
+
return function _not(data, root, path) {
|
|
188
|
+
if (!fails(data, pattern, root, path)) {
|
|
189
|
+
return error('data matches pattern, when required not to', data, pattern, path)
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
139
193
|
|
|
140
194
|
/**
|
|
141
195
|
* returns an array of problems if the data fails to satisfy
|
|
@@ -145,48 +199,53 @@ export const not = (pattern) =>
|
|
|
145
199
|
* @param {any} root Root object for assertions, set to data by default
|
|
146
200
|
* @return {Array|false} Array with problems if the pattern fails, false otherwise
|
|
147
201
|
*/
|
|
148
|
-
export function fails(data, pattern, root) {
|
|
202
|
+
export function fails(data, pattern, root, path='') {
|
|
149
203
|
if (!root) {
|
|
150
204
|
root = data
|
|
151
205
|
}
|
|
152
206
|
let problems = []
|
|
153
207
|
if (pattern === Boolean) {
|
|
154
208
|
if (typeof data != 'boolean' && !(data instanceof Boolean)) {
|
|
155
|
-
problems.push(error('data is not a boolean', data, pattern))
|
|
209
|
+
problems.push(error('data is not a boolean', data, pattern, path))
|
|
156
210
|
}
|
|
157
211
|
} else if (pattern === Number) {
|
|
158
212
|
if (typeof data != 'number' && !(data instanceof Number)) {
|
|
159
|
-
problems.push(error('data is not a number', data, pattern))
|
|
213
|
+
problems.push(error('data is not a number', data, pattern, path))
|
|
160
214
|
}
|
|
161
215
|
} else if (pattern === String) {
|
|
162
216
|
if (typeof data != 'string' && !(data instanceof String)) {
|
|
163
|
-
problems.push(error('data is not a string', data, pattern))
|
|
217
|
+
problems.push(error('data is not a string', data, pattern, path))
|
|
164
218
|
}
|
|
165
219
|
if (data == "") {
|
|
166
|
-
problems.push(error('data is an empty string, which is not allowed', data, pattern))
|
|
220
|
+
problems.push(error('data is an empty string, which is not allowed', data, pattern, path))
|
|
167
221
|
}
|
|
168
222
|
} else if (pattern instanceof RegExp) {
|
|
169
223
|
if (Array.isArray(data)) {
|
|
170
|
-
let index = data.findIndex(element => fails(element,pattern,root))
|
|
224
|
+
let index = data.findIndex((element,index) => fails(element,pattern,root,path+'['+index+']'))
|
|
171
225
|
if (index>-1) {
|
|
172
|
-
problems.push(error('data['+index+'] does not match pattern', data[index], pattern))
|
|
226
|
+
problems.push(error('data['+index+'] does not match pattern', data[index], pattern, path+'['+index+']'))
|
|
173
227
|
}
|
|
174
228
|
} else if (typeof data == 'undefined') {
|
|
175
|
-
problems.push(error('data is undefined, should match pattern', data, pattern))
|
|
229
|
+
problems.push(error('data is undefined, should match pattern', data, pattern, path))
|
|
176
230
|
} else if (!pattern.test(data)) {
|
|
177
|
-
problems.push(error('data does not match pattern', data, pattern))
|
|
231
|
+
problems.push(error('data does not match pattern', data, pattern, path))
|
|
178
232
|
}
|
|
179
233
|
} else if (pattern instanceof Function) {
|
|
180
|
-
|
|
181
|
-
|
|
234
|
+
let problem = pattern(data, root, path)
|
|
235
|
+
if (problem) {
|
|
236
|
+
if (Array.isArray(problem)) {
|
|
237
|
+
problems = problems.concat(problem)
|
|
238
|
+
} else {
|
|
239
|
+
problems.push(problem)
|
|
240
|
+
}
|
|
182
241
|
}
|
|
183
242
|
} else if (Array.isArray(pattern)) {
|
|
184
243
|
if (!Array.isArray(data)) {
|
|
185
|
-
problems.push(error('data is not an array',data,[]))
|
|
244
|
+
problems.push(error('data is not an array',data,[],path))
|
|
186
245
|
}
|
|
187
246
|
for (let p of pattern) {
|
|
188
|
-
for (let
|
|
189
|
-
let problem = fails(
|
|
247
|
+
for (let index of data.keys()) {
|
|
248
|
+
let problem = fails(data[index], p, root, path+'['+index+']')
|
|
190
249
|
if (Array.isArray(problem)) {
|
|
191
250
|
problems = problems.concat(problem)
|
|
192
251
|
} else if (problem) {
|
|
@@ -196,26 +255,33 @@ export function fails(data, pattern, root) {
|
|
|
196
255
|
}
|
|
197
256
|
} else if (pattern && typeof pattern == 'object') {
|
|
198
257
|
if (Array.isArray(data)) {
|
|
199
|
-
let index = data.findIndex(element => fails(element,pattern,root))
|
|
258
|
+
let index = data.findIndex((element,index) => fails(element,pattern,root,path+'['+index+']'))
|
|
200
259
|
if (index>-1) {
|
|
201
|
-
problems.push(error('data['+index+'] does not match pattern', data[index], pattern))
|
|
260
|
+
problems.push(error('data['+index+'] does not match pattern', data[index], pattern, path+'['+index+']'))
|
|
202
261
|
}
|
|
203
262
|
} else if (!data || typeof data != 'object') {
|
|
204
|
-
problems.push(error('data is not an object, pattern is', data, pattern))
|
|
263
|
+
problems.push(error('data is not an object, pattern is', data, pattern, path))
|
|
205
264
|
} else {
|
|
206
265
|
if (data instanceof URLSearchParams) {
|
|
207
266
|
data = Object.fromEntries(data)
|
|
208
267
|
}
|
|
209
|
-
|
|
210
|
-
|
|
268
|
+
if (pattern instanceof Function) {
|
|
269
|
+
let result = fails(data, pattern, root, path)
|
|
211
270
|
if (result) {
|
|
212
271
|
problems = problems.concat(result)
|
|
213
272
|
}
|
|
214
|
-
|
|
273
|
+
} else {
|
|
274
|
+
for (const [wKey, wVal] of Object.entries(pattern)) {
|
|
275
|
+
let result = fails(data[wKey], wVal, root, path+'.'+wKey)
|
|
276
|
+
if (result) {
|
|
277
|
+
problems = problems.concat(result)
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
215
281
|
}
|
|
216
282
|
} else {
|
|
217
283
|
if (pattern!=data) {
|
|
218
|
-
problems.push(error('data and pattern are not equal', data, pattern))
|
|
284
|
+
problems.push(error('data and pattern are not equal', data, pattern, path))
|
|
219
285
|
}
|
|
220
286
|
}
|
|
221
287
|
if (problems.length) {
|
|
@@ -239,10 +305,15 @@ class assertError extends Error {
|
|
|
239
305
|
/**
|
|
240
306
|
* Returns an object with message, found and expected properties
|
|
241
307
|
*/
|
|
242
|
-
export function error(message, found, expected) {
|
|
243
|
-
|
|
308
|
+
export function error(message, found, expected, path, problems) {
|
|
309
|
+
let result = {
|
|
244
310
|
message,
|
|
245
311
|
found,
|
|
246
|
-
expected
|
|
312
|
+
expected,
|
|
313
|
+
path
|
|
314
|
+
}
|
|
315
|
+
if (problems) {
|
|
316
|
+
result.problems = problems
|
|
247
317
|
}
|
|
318
|
+
return result
|
|
248
319
|
}
|