@muze-nl/assert 0.1.1 → 0.2.0

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/README.md CHANGED
@@ -8,19 +8,48 @@ _Note:_ This library was created as part of the [@muze-nl/metro](https://github.
8
8
 
9
9
  ## Installation
10
10
 
11
- Using NPM:
11
+ ### Using NPM:
12
12
 
13
13
  ```shell
14
14
  npm install @muze-nl/assert
15
15
  ```
16
16
 
17
- Using a CDN like jsdelivr
17
+ The include it in your javascript code like this:
18
+ ```javascript
19
+ import * as assert from '@muze-nl/assert'
20
+ ```
21
+
22
+ Or if you are a fan of shorter assertions:
23
+
24
+ ```javascript
25
+ import { assert, enable, disable, Optional, Required, Recommended, oneOf, anyOf, not, validURL, instanceOf } from '@muze-nl/assert'
26
+ ```
27
+
28
+ ### Using a CDN like jsdelivr
18
29
  ```html
19
- <script src="https://cdn.jsdelivr.net/npm/@muze-nl/assert@0.1.1/dist/browser.js" integrity="sha384-UzlYv+OL1tl0rZiZQAkX+6yECgjFWtCU/PCgShtCv41A1Vm75JgT1s05iAUUs/di" crossorigin="anonymous"></script>
30
+ <script src="https://cdn.jsdelivr.net/npm/@muze-nl/assert@0.1.1/dist/browser.js" integrity="sha384-fqO47gvA1/4UGo0iokMu6ZXdBCkRUbNfXejhrmZrWpJaP+7FPaJqJ03Irhzl1ifk" crossorigin="anonymous"></script>
20
31
  ```
21
32
 
22
33
  _Note_: jsdelivr.com doesn't calculate the integrity hash for you, I've used https://www.srihash.org here.
23
34
 
35
+ Using a CDN like this means that assert is loaded globally as window.assert.
36
+
37
+ ## Usage
38
+
39
+ ```javascript
40
+ function myFunction(param1, param2) {
41
+ assert(param1, Required(validURL))
42
+ assert(param2, Optional(not(/foo.*/)))
43
+ // do your own stuff here
44
+ }
45
+ ```
46
+
47
+ When calling myFunction above, none of the assertions are actually checked, unless you enable assertion checking first, like this:
48
+
49
+ ```javascript
50
+ enable()
51
+ ```
52
+
24
53
  ## Asserting preconditions
25
54
 
26
55
  When writing middleware there is usually quite a lot of preconditions to check. When a developer wants to use your middleware, it is nice to have explicit feedback about what he or she is doing wrong. However this is only useful during development. Once in production you should assume that there are no developer mistakes anymore... or at least that the end user has no use for detailed error reports about your middleware.
package/dist/browser.js CHANGED
@@ -1,2 +1,2 @@
1
- function t(t,e,n,a){Object.defineProperty(t,e,{get:n,set:a,enumerable:!0,configurable:!0})}var e={};function n(){globalThis.assertEnabled=!0}function a(){globalThis.assertEnabled=!1}function r(t,e,n){return{message:t,found:e,expected:n}}function o(t,e,n){let a=[];if(e===Boolean)"boolean"!=typeof t&&a.push(r("data is not a boolean",t,e));else if(e===Number)"number"!=typeof t&&a.push(r("data is not a number",t,e));else if(e instanceof RegExp){if(Array.isArray(t)){let n=t.findIndex(t=>o(t,e));n>-1&&a.push(r("data["+n+"] does not match pattern",t[n],e))}else e.test(t)||a.push(r("data does not match pattern",t,e))}else if(e instanceof Function)e(t,n)&&a.push(r("data does not match function",t,e));else if(Array.isArray(e))for(p of(Array.isArray(t)||a.push(r("data is not an array",t,[])),e)){let e=o(t,p);Array.isArray(e)?a.concat(e):e&&a.push(e)}else if(e&&"object"==typeof e){if(Array.isArray(t)){let n=t.findIndex(t=>o(t,e));n>-1&&a.push(r("data["+n+"] does not match pattern",t[n],e))}else if(t&&"object"==typeof t){t instanceof URLSearchParams&&(t=Object.fromEntries(t));let n=a[a.length-1];for(let[i,s]of Object.entries(e)){let e=o(t[i],s,t);e&&(n&&"string"!=typeof n||(n={},a.push(r(n,t[i],s))),n[i]=e.problems)}}else a.push(r("data is not an object, pattern is",t,e))}else e!=t&&a.push(r("data and pattern are not equal",t,e));return!!a.length&&a}function i(t,e){if(!globalThis.assertEnabled)return;let n=o(t,e);if(n)throw new y(n,t)}function s(t){return function(e){return null!=e&&void 0!==e&&o(e,t)}}function u(t){return function(e){return o(e,t)}}function f(t){return null==data||"undefined"==typeof data?(console.warning("data does not contain recommended value",data,t),!1):o(data,t)}function l(...t){return function(e){for(let n of t)if(!o(e,n))return!1;return r("data does not match oneOf patterns",e,t)}}function c(...t){return function(e){if(!Array.isArray(e))return r("data is not an array",e,"anyOf");for(let n of e)if(l(...t)(n))return r("data does not match anyOf patterns",n,t);return!1}}function d(t){try{if(new URL(t).href!=t)return r("data is not a fully qualified url",t,"validURL")}catch(e){return r("data is not a valid url",t,"validURL")}return!1}function h(t){return function(e){return!(e instanceof t)&&r("data is not an instanceof pattern",e,t)}}function b(t){return function(e){return!o(e,t)&&r("data matches pattern, when required not to",e,t)}}t(e,"enable",()=>n),t(e,"disable",()=>a),t(e,"error",()=>r),t(e,"fails",()=>o),t(e,"assert",()=>i),t(e,"Optional",()=>s),t(e,"Required",()=>u),t(e,"Recommended",()=>f),t(e,"oneOf",()=>l),t(e,"anyOf",()=>c),t(e,"validURL",()=>d),t(e,"instanceOf",()=>h),t(e,"not",()=>b),globalThis.assertEnabled=!1;class y{constructor(t,...e){this.problems=t,this.details=e,console.trace()}}globalThis.assert=e;
1
+ function t(t,e,a,n){Object.defineProperty(t,e,{get:a,set:n,enumerable:!0,configurable:!0})}var e={};function a(){globalThis.assertEnabled=!0}function n(){globalThis.assertEnabled=!1}t(e,"enable",()=>a),t(e,"disable",()=>n),t(e,"assert",()=>r),t(e,"fails",()=>p),t(e,"Optional",()=>s),t(e,"Required",()=>o),t(e,"Recommended",()=>i),t(e,"oneOf",()=>l),t(e,"error",()=>y),t(e,"anyOf",()=>f),t(e,"validURL",()=>d),t(e,"validEmail",()=>c),t(e,"instanceOf",()=>u),t(e,"not",()=>h),globalThis.assertEnabled=!1;const r=(t,e)=>{if(globalThis.assertEnabled){let a=p(t,e);if(a)throw new b("Assertions failed",a,t)}},s=t=>e=>null!=e&&void 0!==e&&p(e,t),o=t=>e=>p(e,t),i=t=>e=>null==e||void 0===e?(console.warning("data does not contain recommended value",e,t),!1):p(e,t),l=(...t)=>e=>{for(let a of t)if(!p(e,a))return!1;return y("data does not match oneOf patterns",e,t)},f=(...t)=>e=>{if(!Array.isArray(e))return y("data is not an array",e,"anyOf");for(let a of e)if(l(...t)(a))return y("data does not match anyOf patterns",a,t);return!1};function d(t){try{if(t instanceof URL&&(t=t.href),new URL(t).href!=t)return y("data is not a valid url",t,"validURL")}catch(e){return y("data is not a valid url",t,"validURL")}return!1}function c(t){return!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t)&&y("data is not a valid email",t,"validEmail")}const u=t=>e=>!(e instanceof t)&&y("data is not an instanceof pattern",e,t),h=t=>e=>!p(e,t)&&y("data matches pattern, when required not to",e,t);function p(t,e,a){a||(a=t);let n=[];if(e===Boolean)"boolean"==typeof t||t instanceof Boolean||n.push(y("data is not a boolean",t,e));else if(e===Number)"number"==typeof t||t instanceof Number||n.push(y("data is not a number",t,e));else if(e===String)"string"==typeof t||t instanceof String||n.push(y("data is not a string",t,e)),""==t&&n.push(y("data is an empty string, which is not allowed",t,e));else if(e instanceof RegExp){if(Array.isArray(t)){let r=t.findIndex(t=>p(t,e,a));r>-1&&n.push(y("data["+r+"] does not match pattern",t[r],e))}else e.test(t)||n.push(y("data does not match pattern",t,e))}else if(e instanceof Function)e(t,a)&&n.push(y("data does not match function",t,e));else if(Array.isArray(e))for(let r of(Array.isArray(t)||n.push(y("data is not an array",t,[])),e))for(let e of t){let t=p(e,r,a);Array.isArray(t)?n=n.concat(t):t&&n.push(t)}else if(e&&"object"==typeof e){if(Array.isArray(t)){let r=t.findIndex(t=>p(t,e,a));r>-1&&n.push(y("data["+r+"] does not match pattern",t[r],e))}else if(t&&"object"==typeof t)for(let[r,s]of(t instanceof URLSearchParams&&(t=Object.fromEntries(t)),Object.entries(e))){let e=p(t[r],s,a);e&&(n=n.concat(e))}else n.push(y("data is not an object, pattern is",t,e))}else e!=t&&n.push(y("data and pattern are not equal",t,e));return!!n.length&&n}class b extends Error{constructor(t,e,...a){super(t),this.problems=e,this.details=a}}function y(t,e,a){return{message:t,found:e,expected:a}}globalThis.assert=e;
2
2
  //# sourceMappingURL=browser.js.map
@@ -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, \"error\", () => $2ddd80d1adc2ea42$export$a3bc9b8ed74fc);\n$parcel$export($2ddd80d1adc2ea42$exports, \"fails\", () => $2ddd80d1adc2ea42$export$478159de811fd37d);\n$parcel$export($2ddd80d1adc2ea42$exports, \"assert\", () => $2ddd80d1adc2ea42$export$a7a9523472993e97);\n$parcel$export($2ddd80d1adc2ea42$exports, \"Optional\", () => $2ddd80d1adc2ea42$export$7acb7b24c478f9c6);\n$parcel$export($2ddd80d1adc2ea42$exports, \"Required\", () => $2ddd80d1adc2ea42$export$1788c381af06add2);\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, \"instanceOf\", () => $2ddd80d1adc2ea42$export$ca03416d6c9e029e);\n$parcel$export($2ddd80d1adc2ea42$exports, \"not\", () => $2ddd80d1adc2ea42$export$6003a5f097c73977);\n// global state switch to enable/disable assert\n// uses globalThis so that even if npm installs multiple\n// versions of this library, all use this same state\nglobalThis.assertEnabled = false;\nfunction $2ddd80d1adc2ea42$export$d7c4a0dd6a4567e5() {\n globalThis.assertEnabled = true;\n}\nfunction $2ddd80d1adc2ea42$export$e20fbacbb41798b() {\n globalThis.assertEnabled = false;\n}\nfunction $2ddd80d1adc2ea42$export$a3bc9b8ed74fc(message, found, expected) {\n return {\n message: message,\n found: found,\n expected: expected\n };\n}\nfunction $2ddd80d1adc2ea42$export$478159de811fd37d(data1, pattern, container) {\n let problems = [];\n if (pattern === Boolean) {\n if (typeof data1 != \"boolean\") problems.push($2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data is not a boolean\", data1, pattern));\n } else if (pattern === Number) {\n if (typeof data1 != \"number\") problems.push($2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data is not a number\", data1, pattern));\n } else if (pattern instanceof RegExp) {\n if (Array.isArray(data1)) {\n let index = data1.findIndex((element)=>$2ddd80d1adc2ea42$export$478159de811fd37d(element, pattern));\n if (index > -1) problems.push($2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data[\" + index + \"] does not match pattern\", data1[index], pattern));\n } else if (!pattern.test(data1)) problems.push($2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data does not match pattern\", data1, pattern));\n } else if (pattern instanceof Function) {\n if (pattern(data1, container)) problems.push($2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data does not match function\", data1, pattern));\n } else if (Array.isArray(pattern)) {\n if (!Array.isArray(data1)) problems.push($2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data is not an array\", data1, []));\n for (p of pattern){\n let problem = $2ddd80d1adc2ea42$export$478159de811fd37d(data1, p);\n if (Array.isArray(problem)) problems.concat(problem);\n else if (problem) problems.push(problem);\n }\n } else if (pattern && typeof pattern == \"object\") {\n if (Array.isArray(data1)) {\n let index = data1.findIndex((element)=>$2ddd80d1adc2ea42$export$478159de811fd37d(element, pattern));\n if (index > -1) problems.push($2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data[\" + index + \"] does not match pattern\", data1[index], pattern));\n } else if (!data1 || typeof data1 != \"object\") problems.push($2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data is not an object, pattern is\", data1, pattern));\n else {\n if (data1 instanceof URLSearchParams) data1 = Object.fromEntries(data1);\n let p1 = problems[problems.length - 1];\n for (const [wKey, wVal] of Object.entries(pattern)){\n let result = $2ddd80d1adc2ea42$export$478159de811fd37d(data1[wKey], wVal, data1);\n if (result) {\n if (!p1 || typeof p1 == \"string\") {\n p1 = {};\n problems.push($2ddd80d1adc2ea42$export$a3bc9b8ed74fc(p1, data1[wKey], wVal));\n }\n p1[wKey] = result.problems;\n }\n }\n }\n } else if (pattern != data1) problems.push($2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data and pattern are not equal\", data1, pattern));\n if (problems.length) return problems;\n return false;\n}\nfunction $2ddd80d1adc2ea42$export$a7a9523472993e97(source, test) {\n if (!globalThis.assertEnabled) return;\n let result = $2ddd80d1adc2ea42$export$478159de811fd37d(source, test);\n if (result) throw new $2ddd80d1adc2ea42$var$assertError(result, source);\n}\nfunction $2ddd80d1adc2ea42$export$7acb7b24c478f9c6(pattern) {\n return function(data1) {\n if (data1 == null || typeof data1 == \"undefined\") return false;\n return $2ddd80d1adc2ea42$export$478159de811fd37d(data1, pattern);\n };\n}\nfunction $2ddd80d1adc2ea42$export$1788c381af06add2(pattern) {\n return function(data1) {\n return $2ddd80d1adc2ea42$export$478159de811fd37d(data1, pattern);\n };\n}\nfunction $2ddd80d1adc2ea42$export$a83bcf183f49ea9(pattern) {\n if (data == null || typeof data == \"undefined\") {\n console.warning(\"data does not contain recommended value\", data, pattern);\n return false;\n }\n return $2ddd80d1adc2ea42$export$478159de811fd37d(data, pattern);\n}\nfunction $2ddd80d1adc2ea42$export$a9a18ae5ba42aeab(...patterns) {\n return function(data1) {\n for (let pattern of patterns){\n if (!$2ddd80d1adc2ea42$export$478159de811fd37d(data1, pattern)) return false;\n }\n return $2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data does not match oneOf patterns\", data1, patterns);\n };\n}\nfunction $2ddd80d1adc2ea42$export$b26c150f612c10f7(...patterns) {\n return function(data1) {\n if (!Array.isArray(data1)) return $2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data is not an array\", data1, \"anyOf\");\n for (let value of data1){\n if ($2ddd80d1adc2ea42$export$a9a18ae5ba42aeab(...patterns)(value)) return $2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data does not match anyOf patterns\", value, patterns);\n }\n return false;\n };\n}\nfunction $2ddd80d1adc2ea42$export$c6f1a4382426409f(data1) {\n try {\n let url = new URL(data1);\n if (url.href != data1) return $2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data is not a fully qualified url\", data1, \"validURL\");\n } catch (e) {\n return $2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data is not a valid url\", data1, \"validURL\");\n }\n return false;\n}\nfunction $2ddd80d1adc2ea42$export$ca03416d6c9e029e(constructor) {\n return function(data1) {\n if (!(data1 instanceof constructor)) return $2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data is not an instanceof pattern\", data1, constructor);\n return false;\n };\n}\nfunction $2ddd80d1adc2ea42$export$6003a5f097c73977(pattern) {\n return function(data1) {\n let problem = $2ddd80d1adc2ea42$export$478159de811fd37d(data1, pattern);\n if (problem) return false;\n return $2ddd80d1adc2ea42$export$a3bc9b8ed74fc(\"data matches pattern, when required not to\", data1, pattern);\n };\n}\nclass $2ddd80d1adc2ea42$var$assertError {\n constructor(problems, ...details){\n this.problems = problems;\n this.details = details;\n console.trace();\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","// global state switch to enable/disable assert\n// uses globalThis so that even if npm installs multiple\n// versions of this library, all use this same state\nglobalThis.assertEnabled = false\n\nexport function enable() {\n\tglobalThis.assertEnabled = true\n}\n\nexport function disable() {\n\tglobalThis.assertEnabled = false\n}\n\nexport function error(message, found, expected) {\n\treturn {\n\t\tmessage,\n\t\tfound,\n\t\texpected\n\t}\n}\n\n/**\n * returns new Boolean(true) if data does not match pattern\n * you can't return new Boolean(false), or at least that evaluates\n * to true, so if the data does match, it returns a primitive false\n * the Boolean(true) has an extra property called 'problems', which is\n * an array with a list of all fields that do not match, and why\n * @param {any} data The data to match\n * @param {any} pattern The pattern to match\n * @return {Array|false} Array with problems if the pattern fails, false\n */\nexport function fails(data, pattern, container) {\n\tlet problems = []\n\tif (pattern === Boolean) {\n\t\tif (typeof data != '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') {\n\t\t\tproblems.push(error('data is not a number', 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))\n if (index>-1) {\n \tproblems.push(error('data['+index+'] does not match pattern', data[index], pattern))\n }\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, container)) {\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 (p of pattern) {\n\t\t\tlet problem = fails(data, p)\n\t\t\tif (Array.isArray(problem)) {\n\t\t\t\tproblems.concat(problem)\n\t\t\t} else if (problem) {\n\t\t\t\tproblems.push(problem)\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))\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 let p = problems[problems.length-1]\n\t for (const [wKey, wVal] of Object.entries(pattern)) {\n\t let result = fails(data[wKey], wVal, data)\n\t if (result) {\n\t \tif (!p || typeof p == 'string') {\n\t \t\tp = {}\n\t \t\tproblems.push(error(p, data[wKey], wVal))\n\t \t}\n\t \tp[wKey] = result.problems\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\nexport function assert(source, test) {\n\tif (!globalThis.assertEnabled) {\n\t\treturn\n\t}\n\tlet result = fails(source,test)\n\tif (result) {\n\t\tthrow new assertError(result,source)\n\t}\n}\n\nexport function Optional(pattern) {\n\treturn function(data) {\n\t\tif (data==null || typeof data == 'undefined') {\n\t\t\treturn false\n\t\t}\n\t\treturn fails(data, pattern)\n\t}\n}\n\nexport function Required(pattern) {\n\treturn function(data) {\n\t\treturn fails(data, pattern)\n\t}\n}\n\nexport function Recommended(pattern) {\n\tif (data==null || typeof data == 'undefined') {\n\t\tconsole.warning('data does not contain recommended value', data, pattern)\n\t\treturn false\n\t}\n\treturn fails(data, pattern)\n}\n\nexport function oneOf(...patterns) {\n\treturn function(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\nexport function anyOf(...patterns) {\n\treturn function(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\nexport function validURL(data) {\n\ttry {\n\t\tlet url = new URL(data)\n\t\tif (url.href!=data) {\n\t\t\treturn error('data is not a fully qualified 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\nexport function instanceOf(constructor) {\n\treturn function(data) {\n\t\tif (!(data instanceof constructor)) {\n\t\t\treturn error('data is not an instanceof pattern',data,constructor)\n\t\t}\n\t\treturn false\n\t}\n}\n\nexport function not(pattern) {\n\treturn function(data) {\n\t\tlet problem = fails(data, pattern)\n\t\tif (problem) {\n\t\t\treturn false\n\t\t}\n\t\treturn error('data matches pattern, when required not to', data, pattern)\n\t}\n}\n\nclass assertError {\n\tconstructor(problems, ...details) {\n\t\tthis.problems = problems\n\t\tthis.details = details\n\t\tconsole.trace()\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$a3bc9b8ed74fc","message","found","expected","$2ddd80d1adc2ea42$export$478159de811fd37d","data1","pattern","container","problems","Boolean","push","Number","RegExp","Array","isArray","index","findIndex","element","test","Function","p","problem","concat","URLSearchParams","fromEntries","p1","length","wKey","wVal","entries","result","$2ddd80d1adc2ea42$export$a7a9523472993e97","source","$2ddd80d1adc2ea42$var$assertError","$2ddd80d1adc2ea42$export$7acb7b24c478f9c6","$2ddd80d1adc2ea42$export$1788c381af06add2","$2ddd80d1adc2ea42$export$a83bcf183f49ea9","data","console","warning","$2ddd80d1adc2ea42$export$a9a18ae5ba42aeab","patterns","$2ddd80d1adc2ea42$export$b26c150f612c10f7","value","$2ddd80d1adc2ea42$export$c6f1a4382426409f","url","URL","href","$2ddd80d1adc2ea42$export$ca03416d6c9e029e","constructor","$2ddd80d1adc2ea42$export$6003a5f097c73977","details","trace","assert"],"version":3,"file":"browser.js.map","sourceRoot":"../"}
1
+ {"mappings":"A,S,E,C,C,C,C,C,C,C,E,O,c,C,E,E,C,I,E,I,E,W,C,E,a,C,C,E,C,I,E,C,EESO,SAAS,IACf,WAAW,aAAa,CAAG,CAAA,CAC5B,CAKO,SAAS,IACf,WAAW,aAAa,CAAG,CAAA,CAC5B,C,E,E,S,I,G,E,E,U,I,G,E,E,S,I,G,E,E,Q,I,G,E,E,W,I,G,E,E,W,I,G,E,E,c,I,G,E,E,Q,I,G,E,E,Q,I,G,E,E,Q,I,G,E,E,W,I,G,E,E,a,I,G,E,E,a,I,G,E,E,M,I,GAdA,WAAW,aAAa,CAAG,CAAA,EAsBpB,MAAM,EAAS,CAAC,EAAQ,KAC9B,GAAI,WAAW,aAAa,CAAE,CAC7B,IAAI,EAAW,EAAM,EAAO,GAC5B,GAAI,EACH,MAAM,IAAI,EAAY,oBAAqB,EAAU,EAEvD,CACD,EAKa,EAAW,AAAC,GACxB,AAAC,GAAS,AAAO,MAAP,GAAe,AAAe,KAAA,IAAR,GAA+B,EAAM,EAAM,GAK/D,EAAW,AAAC,GACxB,AAAC,GAAS,EAAM,EAAM,GAMV,EAAc,AAAC,GAC3B,AAAC,GAAU,AAAM,MAAN,GAAc,AAAe,KAAA,IAAR,GAC/B,QAAQ,OAAO,CAAC,0CAA2C,EAAM,GAC1D,CAAA,GACD,EAAM,EAAM,GAMP,EAAQ,CAAC,GAAG,IACxB,AAAC,IACA,IAAI,IAAI,KAAW,EAClB,GAAI,CAAC,EAAM,EAAM,GAChB,MAAO,CAAA,EAGT,OAAO,EAAM,qCAAqC,EAAK,EACxD,EAOY,EAAQ,CAAC,GAAG,IACxB,AAAC,IACA,GAAI,CAAC,MAAM,OAAO,CAAC,GAClB,OAAO,EAAM,uBAAuB,EAAK,SAE1C,IAAK,IAAI,KAAS,EACjB,GAAI,KAAS,GAAU,GACtB,OAAO,EAAM,qCAAqC,EAAM,GAG1D,MAAO,CAAA,CACR,EAOM,SAAS,EAAS,CAAI,EAC5B,GAAI,CAKH,GAJI,aAAgB,KACnB,CAAA,EAAO,EAAK,IAAI,AAAJ,EAGT,AADM,IAAI,IAAI,GACV,IAAI,EAAE,EACb,OAAO,EAAM,0BAA0B,EAAK,WAE9C,CAAE,MAAM,EAAG,CACV,OAAO,EAAM,0BAA0B,EAAK,WAC7C,CACA,MAAO,CAAA,CACR,CAOO,SAAS,EAAW,CAAI,QAC9B,CAAI,6BAA6B,IAAI,CAAC,IAG/B,EAAM,4BAA4B,EAAK,aAC/C,CAMO,MAAM,EAAa,AAAC,GAC1B,AAAC,GAAS,CAAE,CAAA,aAAgB,CAAA,GACzB,EAAM,oCAAoC,EAAK,GAOtC,EAAM,AAAC,GACnB,AAAC,GAAS,CAAA,EAAM,EAAM,IAEnB,EAAM,6CAA8C,EAAM,GAUvD,SAAS,EAAM,CAAI,CAAE,CAAO,CAAE,CAAI,EACnC,GACJ,CAAA,EAAO,CADR,EAGA,IAAI,EAAW,EAAE,CACjB,GAAI,IAAY,QACI,WAAf,OAAO,GAAuB,aAAgB,SACjD,EAAS,IAAI,CAAC,EAAM,wBAAyB,EAAM,SAE9C,GAAI,IAAY,OACH,UAAf,OAAO,GAAsB,aAAgB,QAChD,EAAS,IAAI,CAAC,EAAM,uBAAwB,EAAM,SAE7C,GAAI,IAAY,OACH,UAAf,OAAO,GAAsB,aAAgB,QAChD,EAAS,IAAI,CAAC,EAAM,uBAAwB,EAAM,IAEvC,IAAR,GACH,EAAS,IAAI,CAAC,EAAM,gDAAiD,EAAM,SAEtE,GAAI,aAAmB,QAC1B,GAAI,MAAM,OAAO,CAAC,GAAO,CAC3B,IAAI,EAAQ,EAAK,SAAS,CAAC,AAAA,GAAW,EAAM,EAAQ,EAAQ,IAC/C,EAAM,IACT,EAAS,IAAI,CAAC,EAAM,QAAQ,EAAM,2BAA4B,CAAI,CAAC,EAAM,CAAE,GAEnF,MAAY,EAAQ,IAAI,CAAC,IACrB,EAAS,IAAI,CAAC,EAAM,8BAA+B,EAAM,SAEvD,GAAI,aAAmB,SACtB,EAAQ,EAAM,IACjB,EAAS,IAAI,CAAC,EAAM,+BAAgC,EAAM,SAExD,GAAI,MAAM,OAAO,CAAC,GAI3B,IAAK,IAAI,KAHJ,MAAM,OAAO,CAAC,IAClB,EAAS,IAAI,CAAC,EAAM,uBAAuB,EAAK,EAAE,GAErC,GACb,IAAK,IAAI,KAAO,EAAM,CACrB,IAAI,EAAU,EAAM,EAAK,EAAG,GACxB,MAAM,OAAO,CAAC,GACjB,EAAW,EAAS,MAAM,CAAC,GACjB,GACV,EAAS,IAAI,CAAC,EAEhB,MAEQ,GAAI,GAAW,AAAkB,UAAlB,OAAO,GACzB,GAAI,MAAM,OAAO,CAAC,GAAO,CACrB,IAAI,EAAQ,EAAK,SAAS,CAAC,AAAA,GAAW,EAAM,EAAQ,EAAQ,IACxD,EAAM,IACT,EAAS,IAAI,CAAC,EAAM,QAAQ,EAAM,2BAA4B,CAAI,CAAC,EAAM,CAAE,GAEhF,MAAO,GAAI,AAAC,GAAQ,AAAe,UAAf,OAAO,EAM1B,IAAK,GAAM,CAAC,EAAM,EAAK,GAHnB,aAAgB,iBACnB,CAAA,EAAO,OAAO,WAAW,CAAC,EAD3B,EAG2B,OAAO,OAAO,CAAC,IAAU,CAChD,IAAI,EAAS,EAAM,CAAI,CAAC,EAAK,CAAE,EAAM,GACjC,GACH,CAAA,EAAW,EAAS,MAAM,CAAC,EAD5B,CAGJ,MAVA,EAAS,IAAI,CAAC,EAAM,oCAAqC,EAAM,SAa/D,GAAS,GACZ,EAAS,IAAI,CAAC,EAAM,iCAAkC,EAAM,UAG9D,EAAI,EAAS,MAAM,EACX,CAGZ,CAMA,MAAM,UAAoB,MACzB,YAAY,CAAO,CAAE,CAAQ,CAAE,GAAG,CAAO,CAAE,CAC1C,KAAK,CAAC,GACN,IAAI,CAAC,QAAQ,CAAG,EAChB,IAAI,CAAC,OAAO,CAAG,CAChB,CACD,CAKO,SAAS,EAAM,CAAO,CAAE,CAAK,CAAE,CAAQ,EAC7C,MAAO,CACN,QAAA,EACA,MAAA,EACA,SAAA,CACD,CACD,CDnPA,WAAW,MAAM,CAAG","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, \"Recommended\", () => $2ddd80d1adc2ea42$export$a83bcf183f49ea9);\n$parcel$export($2ddd80d1adc2ea42$exports, \"oneOf\", () => $2ddd80d1adc2ea42$export$a9a18ae5ba42aeab);\n$parcel$export($2ddd80d1adc2ea42$exports, \"error\", () => $2ddd80d1adc2ea42$export$a3bc9b8ed74fc);\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)=>$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 (!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) => 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 \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$a83bcf183f49ea9","$2ddd80d1adc2ea42$export$a9a18ae5ba42aeab","$2ddd80d1adc2ea42$export$a3bc9b8ed74fc","$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":"../"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@muze-nl/assert",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "light optional assert library",
5
5
  "type": "module",
6
6
  "main": "src/assert.mjs",
package/src/assert.mjs CHANGED
@@ -1,47 +1,173 @@
1
- // global state switch to enable/disable assert
2
- // uses globalThis so that even if npm installs multiple
3
- // versions of this library, all use this same state
1
+ /**
2
+ * assertEnabled (Boolean) used to toggle whether the assert()
3
+ * method should test assertions or not.
4
+ */
4
5
  globalThis.assertEnabled = false
5
6
 
7
+ /**
8
+ * Enables assertion testing with assert()
9
+ */
6
10
  export function enable() {
7
11
  globalThis.assertEnabled = true
8
12
  }
9
13
 
14
+ /**
15
+ * Disables assertion testing with assert()
16
+ */
10
17
  export function disable() {
11
18
  globalThis.assertEnabled = false
12
19
  }
13
20
 
14
- export function error(message, found, expected) {
15
- return {
16
- message,
17
- found,
18
- expected
21
+ /**
22
+ * This function will check the source for the assertions in test, if
23
+ * assertion checking is enabled globally.
24
+ * If it is, and any assertion fails, it will throw an assertError
25
+ * with a list of problems and other details.
26
+ */
27
+ export const assert = (source, test) => {
28
+ if (globalThis.assertEnabled) {
29
+ let problems = fails(source,test)
30
+ if (problems) {
31
+ throw new assertError('Assertions failed', problems, source)
32
+ }
19
33
  }
20
34
  }
21
35
 
22
36
  /**
23
- * returns new Boolean(true) if data does not match pattern
24
- * you can't return new Boolean(false), or at least that evaluates
25
- * to true, so if the data does match, it returns a primitive false
26
- * the Boolean(true) has an extra property called 'problems', which is
27
- * an array with a list of all fields that do not match, and why
28
- * @param {any} data The data to match
29
- * @param {any} pattern The pattern to match
30
- * @return {Array|false} Array with problems if the pattern fails, false
37
+ * Tests a given value against a pattern, only if the value is not null or undefined
38
+ */
39
+ export const Optional = (pattern) =>
40
+ (data) => (data==null || typeof data == 'undefined') ? false : fails(data, pattern)
41
+
42
+ /**
43
+ * Tests a given value against a pattern, always.
44
+ */
45
+ export const Required = (pattern) =>
46
+ (data) => fails(data, pattern)
47
+
48
+ /**
49
+ * Tests a given value against a pattern, only if the value is not null or undefined
50
+ * If null or undefined, it does print a warning to the console.
51
+ */
52
+ export const Recommended = (pattern) =>
53
+ (data) => (data==null || typeof data == 'undefined') ? (() => {
54
+ console.warning('data does not contain recommended value', data, pattern)
55
+ return false
56
+ })() : fails(data, pattern)
57
+
58
+ /**
59
+ * Tests a given value against a set of patterns, untill one succeeds
60
+ * Returns an error if none succeed
61
+ */
62
+ export const oneOf = (...patterns) =>
63
+ (data) => {
64
+ for(let pattern of patterns) {
65
+ if (!fails(data, pattern)) {
66
+ return false
67
+ }
68
+ }
69
+ return error('data does not match oneOf patterns',data,patterns)
70
+ }
71
+
72
+ /**
73
+ * Tests a given array of values against a set of patterns
74
+ * If any value does not match one of the patterns, it will return an error
75
+ * If not given an array to test, it will return an error
31
76
  */
32
- export function fails(data, pattern, container) {
77
+ export const anyOf = (...patterns) =>
78
+ (data) => {
79
+ if (!Array.isArray(data)) {
80
+ return error('data is not an array',data,'anyOf')
81
+ }
82
+ for (let value of data) {
83
+ if (oneOf(...patterns)(value)) {
84
+ return error('data does not match anyOf patterns',value,patterns)
85
+ }
86
+ }
87
+ return false
88
+ }
89
+
90
+ /**
91
+ * Tests a given value to see if it is a valid (and absolute) URL, by
92
+ * parsing it with the URL() constructor, and then testing the href
93
+ * value to be equal to the initial value.
94
+ */
95
+ export function validURL(data) {
96
+ try {
97
+ if (data instanceof URL) {
98
+ data = data.href
99
+ }
100
+ let url = new URL(data)
101
+ if (url.href!=data) {
102
+ return error('data is not a valid url',data,'validURL')
103
+ }
104
+ } catch(e) {
105
+ return error('data is not a valid url',data,'validURL')
106
+ }
107
+ return false
108
+ }
109
+
110
+ /**
111
+ * Tests a given value to see if it looks like a valid email address, by
112
+ * testing it against a regular expression. So there are no guarantees that
113
+ * it is an actual working email address, just that it looks like one.
114
+ */
115
+ export function validEmail(data) {
116
+ if (/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(data)) {
117
+ return false // data matches email regex
118
+ }
119
+ return error('data is not a valid email',data,'validEmail')
120
+ }
121
+
122
+ /**
123
+ * Tests a given value to see if it is an object which is an instance of the given
124
+ * constructor
125
+ */
126
+ export const instanceOf = (constructor) =>
127
+ (data) => !(data instanceof constructor)
128
+ ? error('data is not an instanceof pattern',data,constructor)
129
+ : false
130
+
131
+ /**
132
+ * Runs the given test pattern on a value, if the test succeeds, it fails
133
+ * the not() test.
134
+ */
135
+ export const not = (pattern) =>
136
+ (data) => fails(data, pattern)
137
+ ? false
138
+ : error('data matches pattern, when required not to', data, pattern)
139
+
140
+ /**
141
+ * returns an array of problems if the data fails to satisfy
142
+ * the assertions in the given pattern, false otherwise
143
+ * @param {any} data The data to match
144
+ * @param {any} pattern The pattern to match
145
+ * @param {any} root Root object for assertions, set to data by default
146
+ * @return {Array|false} Array with problems if the pattern fails, false otherwise
147
+ */
148
+ export function fails(data, pattern, root) {
149
+ if (!root) {
150
+ root = data
151
+ }
33
152
  let problems = []
34
153
  if (pattern === Boolean) {
35
- if (typeof data != 'boolean') {
154
+ if (typeof data != 'boolean' && !(data instanceof Boolean)) {
36
155
  problems.push(error('data is not a boolean', data, pattern))
37
156
  }
38
157
  } else if (pattern === Number) {
39
- if (typeof data != 'number') {
158
+ if (typeof data != 'number' && !(data instanceof Number)) {
40
159
  problems.push(error('data is not a number', data, pattern))
41
160
  }
161
+ } else if (pattern === String) {
162
+ if (typeof data != 'string' && !(data instanceof String)) {
163
+ problems.push(error('data is not a string', data, pattern))
164
+ }
165
+ if (data == "") {
166
+ problems.push(error('data is an empty string, which is not allowed', data, pattern))
167
+ }
42
168
  } else if (pattern instanceof RegExp) {
43
169
  if (Array.isArray(data)) {
44
- let index = data.findIndex(element => fails(element,pattern))
170
+ let index = data.findIndex(element => fails(element,pattern,root))
45
171
  if (index>-1) {
46
172
  problems.push(error('data['+index+'] does not match pattern', data[index], pattern))
47
173
  }
@@ -49,24 +175,26 @@ export function fails(data, pattern, container) {
49
175
  problems.push(error('data does not match pattern', data, pattern))
50
176
  }
51
177
  } else if (pattern instanceof Function) {
52
- if (pattern(data, container)) {
178
+ if (pattern(data, root)) {
53
179
  problems.push(error('data does not match function', data, pattern))
54
180
  }
55
181
  } else if (Array.isArray(pattern)) {
56
182
  if (!Array.isArray(data)) {
57
183
  problems.push(error('data is not an array',data,[]))
58
184
  }
59
- for (p of pattern) {
60
- let problem = fails(data, p)
61
- if (Array.isArray(problem)) {
62
- problems.concat(problem)
63
- } else if (problem) {
64
- problems.push(problem)
185
+ for (let p of pattern) {
186
+ for (let val of data) {
187
+ let problem = fails(val, p, root)
188
+ if (Array.isArray(problem)) {
189
+ problems = problems.concat(problem)
190
+ } else if (problem) {
191
+ problems.push(problem)
192
+ }
65
193
  }
66
194
  }
67
195
  } else if (pattern && typeof pattern == 'object') {
68
196
  if (Array.isArray(data)) {
69
- let index = data.findIndex(element => fails(element,pattern))
197
+ let index = data.findIndex(element => fails(element,pattern,root))
70
198
  if (index>-1) {
71
199
  problems.push(error('data['+index+'] does not match pattern', data[index], pattern))
72
200
  }
@@ -76,15 +204,10 @@ export function fails(data, pattern, container) {
76
204
  if (data instanceof URLSearchParams) {
77
205
  data = Object.fromEntries(data)
78
206
  }
79
- let p = problems[problems.length-1]
80
207
  for (const [wKey, wVal] of Object.entries(pattern)) {
81
- let result = fails(data[wKey], wVal, data)
208
+ let result = fails(data[wKey], wVal, root)
82
209
  if (result) {
83
- if (!p || typeof p == 'string') {
84
- p = {}
85
- problems.push(error(p, data[wKey], wVal))
86
- }
87
- p[wKey] = result.problems
210
+ problems = problems.concat(result)
88
211
  }
89
212
  }
90
213
  }
@@ -99,99 +222,25 @@ export function fails(data, pattern, container) {
99
222
  return false
100
223
  }
101
224
 
102
- export function assert(source, test) {
103
- if (!globalThis.assertEnabled) {
104
- return
105
- }
106
- let result = fails(source,test)
107
- if (result) {
108
- throw new assertError(result,source)
109
- }
110
- }
111
-
112
- export function Optional(pattern) {
113
- return function(data) {
114
- if (data==null || typeof data == 'undefined') {
115
- return false
116
- }
117
- return fails(data, pattern)
118
- }
119
- }
120
-
121
- export function Required(pattern) {
122
- return function(data) {
123
- return fails(data, pattern)
124
- }
125
- }
126
-
127
- export function Recommended(pattern) {
128
- if (data==null || typeof data == 'undefined') {
129
- console.warning('data does not contain recommended value', data, pattern)
130
- return false
131
- }
132
- return fails(data, pattern)
133
- }
134
-
135
- export function oneOf(...patterns) {
136
- return function(data) {
137
- for(let pattern of patterns) {
138
- if (!fails(data, pattern)) {
139
- return false
140
- }
141
- }
142
- return error('data does not match oneOf patterns',data,patterns)
143
- }
144
- }
145
-
146
- export function anyOf(...patterns) {
147
- return function(data) {
148
- if (!Array.isArray(data)) {
149
- return error('data is not an array',data,'anyOf')
150
- }
151
- for (let value of data) {
152
- if (oneOf(...patterns)(value)) {
153
- return error('data does not match anyOf patterns',value,patterns)
154
- }
155
- }
156
- return false
157
- }
158
- }
159
-
160
- export function validURL(data) {
161
- try {
162
- let url = new URL(data)
163
- if (url.href!=data) {
164
- return error('data is not a fully qualified url',data,'validURL')
165
- }
166
- } catch(e) {
167
- return error('data is not a valid url',data,'validURL')
168
- }
169
- return false
170
- }
171
225
 
172
- export function instanceOf(constructor) {
173
- return function(data) {
174
- if (!(data instanceof constructor)) {
175
- return error('data is not an instanceof pattern',data,constructor)
176
- }
177
- return false
178
- }
179
- }
180
-
181
- export function not(pattern) {
182
- return function(data) {
183
- let problem = fails(data, pattern)
184
- if (problem) {
185
- return false
186
- }
187
- return error('data matches pattern, when required not to', data, pattern)
226
+ /**
227
+ * Class used in assert() to add problems found and details to the error object
228
+ */
229
+ class assertError extends Error {
230
+ constructor(message, problems, ...details) {
231
+ super(message)
232
+ this.problems = problems
233
+ this.details = details
188
234
  }
189
235
  }
190
236
 
191
- class assertError {
192
- constructor(problems, ...details) {
193
- this.problems = problems
194
- this.details = details
195
- console.trace()
237
+ /**
238
+ * Returns an object with message, found and expected properties
239
+ */
240
+ export function error(message, found, expected) {
241
+ return {
242
+ message,
243
+ found,
244
+ expected
196
245
  }
197
246
  }