{"_id":"gubu","_rev":"28-718ec818a4a13db79c7005e5de4b74cf","name":"gubu","dist-tags":{"latest":"9.0.0"},"versions":{"0.0.1":{"name":"gubu","version":"0.0.1","keywords":["gubu"],"author":{"url":"http://richardrodger.com","name":"Richard Rodger"},"license":"MIT","_id":"gubu@0.0.1","maintainers":[{"name":"rjrodger","email":"richard.rodger@voxgig.com"}],"homepage":"https://github.com/rjrodger/gubu","bugs":{"url":"https://github.com/rjrodger/gubu/issues"},"dist":{"shasum":"72bafec842a1fbe6560721618cd94e921e591460","tarball":"https://registry.npmjs.org/gubu/-/gubu-0.0.1.tgz","fileCount":8,"integrity":"sha512-AQvXT191cMXaggGuLPSLf2Tm6/92LoPTwx73byY3NQeT2Xaxm2zL6RzY1LixhqYZ6p0Z0gYyew/B8V42DKbpSQ==","signatures":[{"sig":"MEUCIGNqkFcHPYvGcVyfkuSAiq+a9ZJzJT8rASyiwYXERvbgAiEA8DfE3hswoHNoeL7J3U6s6q70pYWB6sJhv9W9WTyHqAw=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":3374,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhn+MTCRA9TVsSAnZWagAA14UP/23Ty0hSmADMv1gIZaE0\nrfzG0gEvxCL3wu/lzRvrlWFI5LgXcL8FEvHBph5/XvEIpaSTamCxANHVb8i5\nre6JK3MmF0NFbSo2bSvG6Q/d9jwQfjB5Fc6k6w2VyyqOWdXiq8NaVr+F06Eo\nivs0Fs5gg5CmQBR59w+QrsS/TAyRPM7iEEwgAL/jTskmQoWo943eRyza9O/l\nr2kZjK47PwjeZ2BYP3EBc6pQtYVvYzYZiRDDdv8L1vuWFOVTv1WX+GEc9Rvm\nkE9+I9ujY/R9xvhDeyxwVTr8U45wxzOkdga4np2SlxDsUJwP1oYlA/EwgCpH\ncycOsSv2IZuWVhROD35mUiPIANPpXlGTak3JheY4vpXRA+Wsr6u56kxcdC62\nKqpRULn0cdz11zbse2WM56u3G+KcZo/M/DrEFM69CSfY/Q3xydBady93c3r6\n2f+s3Y6rTXUjiJyaaues26C5zf3UHI0YHk93gIpVfQjwdMSCCUH6TQiFwGKU\ne4kh+wIjIrIB0YiMzOSy/YFEJ2l/JAEpLP6ZsYUl4gvqFDz7JJfchIOqqg8y\ncANold0GUL3/+UP7zBB4WN7i99Srm8+upXZxcOAtzepGuIizxMimSo7NvAR4\n4VFNFLCmLEkD/cLHYing1dUhUgi8IbKt4my6Kuei91QfcumhwYTKcp2D+KHC\n4lIr\r\n=PkPl\r\n-----END PGP SIGNATURE-----\r\n"},"main":"gubu.js","type":"commonjs","types":"gubu.d.ts","gitHead":"e7bf5ad7e57f4a3c22e85ced942a5b331bee5cbe","scripts":{"test":"jest --coverage","build":"tsc -d","clean":"rm -rf node_modules yarn.lock package-lock.json","reset":"npm run clean && npm i && npm test","watch":"tsc -w -d","repo-tag":"REPO_VERSION=`node -e \"console.log(require('./package').version)\"` && echo TAG: v$REPO_VERSION && git commit -a -m v$REPO_VERSION && git push && git tag v$REPO_VERSION && git push --tags;","test-some":"jest -t","test-watch":"jest --coverage --watchAll","repo-publish":"npm run clean && npm i && npm run repo-publish-quick","repo-publish-quick":"npm run build && npm run test && npm run repo-tag && npm publish --access public --registry https://registry.npmjs.org "},"_npmUser":{"name":"rjrodger","email":"richard.rodger@voxgig.com"},"repository":{"url":"git://github.com/rjrodger/gubu.git","type":"git"},"_npmVersion":"8.0.0","description":"gubu","directories":{},"_nodeVersion":"14.17.6","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"jest":"^27.3.1","jsonic":"github:jsonicjs/jsonic#nextgen","ts-jest":"^27.0.7","typescript":"^4.5.2","@types/jest":"^27.0.3"},"_npmOperationalInternal":{"tmp":"tmp/gubu_0.0.1_1637868307373_0.8982129826616905","host":"s3://npm-registry-packages"}},"0.0.2":{"name":"gubu","version":"0.0.2","keywords":["gubu"],"author":{"url":"http://richardrodger.com","name":"Richard Rodger"},"license":"MIT","_id":"gubu@0.0.2","maintainers":[{"name":"rjrodger","email":"richard.rodger@voxgig.com"}],"homepage":"https://github.com/rjrodger/gubu","bugs":{"url":"https://github.com/rjrodger/gubu/issues"},"dist":{"shasum":"9491f7e74ec58d60b07987f6bacf11415a796c5a","tarball":"https://registry.npmjs.org/gubu/-/gubu-0.0.2.tgz","fileCount":8,"integrity":"sha512-oEuzfyyqPrJIsgbbFVAYzscCGOD5krgnCq8bArLb6jC4g1Um9ShReGjRZGEU7ugUwXrbL2EWQvLc/bA/8j131A==","signatures":[{"sig":"MEUCIHU4a6VO1iUsEa9OO6hJCHwT6G3OeIgaGSx9bgmd+LXPAiEA/osmYngVjbORHzhcj1KAGxsBEBPdYjrPppcJugRblfk=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":82665,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhshWHCRA9TVsSAnZWagAADn8P/RNoIIWo3VIZYqxlap38\nV9hHru9H08uuG+JrUuy7yNHwgWqunPtf0mS1VY0kSjYZMbdOxrWy9eIs4yUr\nS39waXzsbZvmFAPykfIn80H0ycqhUJiffZoTHjfJlFd1jcmRoThQWhC61pDZ\n+kND8B49N4T9PJmvEauggF7yQsxrDEGGhS6kjiWMihoS74kFSprvb0hgZ8zf\n/z2tUwLnyONLRXsR4HdS+WlOo/lD9EBAHT2SEr6v2iNGvXx+imFiltgrtar0\nR9EkLZ2Mfgb2SZIWXmjne1gKYQyCNOer/iRchg0r94sBSdnbrQ7ZUCs+P6Yv\nvwHI/E4EzbWwj2GBdwBAOWobr4mRvroGa7NUKFheJWWrdCAPAyBphpvLQfeb\nxtdO19/DUJK1aF0PPsCTLA3SmUGuzSz28JjSJZ/PtmzmH5q8gCMMJo3PdgYM\nFmHlOG1HrvB4HGmhjdJhwKWBbmJslDwB/GfUPt+A1jafCYGCf21RbPJHKE64\n8Vtw4rURUAvTRfDWvZoWpCGLSbbLDd7O3serV1UVfm//W6VF9Cjtw1l/Zz76\nQJjgTuXW671XX+lDxybJMyXWfTJGOLdQLipcPF6pELaEZQS0RyHVJlV3oGU1\nqHKJTzXtDLcQd/DuRONnWCHAdDxlnuW+YYuIsH8mAFjdtTKVPCZh3ojqvjBm\nbxIf\r\n=q95B\r\n-----END PGP SIGNATURE-----\r\n"},"main":"gubu.js","type":"commonjs","types":"gubu.d.ts","gitHead":"9f557262afad23b63d897720e217f7dea3476d04","scripts":{"test":"jest --coverage","build":"tsc -d","clean":"rm -rf node_modules yarn.lock package-lock.json","reset":"npm run clean && npm i && npm test","watch":"tsc -w -d","repo-tag":"REPO_VERSION=`node -e \"console.log(require('./package').version)\"` && echo TAG: v$REPO_VERSION && git commit -a -m v$REPO_VERSION && git push && git tag v$REPO_VERSION && git push --tags;","test-some":"jest -t","test-watch":"jest --coverage --watchAll","repo-publish":"npm run clean && npm i && npm run repo-publish-quick","repo-publish-quick":"npm run build && npm run test && npm run repo-tag && npm publish --access public --registry https://registry.npmjs.org "},"_npmUser":{"name":"rjrodger","email":"richard.rodger@voxgig.com"},"repository":{"url":"git://github.com/rjrodger/gubu.git","type":"git"},"_npmVersion":"8.0.0","description":"gubu","directories":{},"_nodeVersion":"14.17.6","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"jest":"^27.4.3","jsonic":"github:jsonicjs/jsonic#nextgen","ts-jest":"^27.1.1","typescript":"^4.5.2","@types/jest":"^27.0.3"},"_npmOperationalInternal":{"tmp":"tmp/gubu_0.0.2_1639060871211_0.8653209076517507","host":"s3://npm-registry-packages"}},"0.0.3":{"name":"gubu","version":"0.0.3","keywords":["gubu"],"author":{"url":"http://richardrodger.com","name":"Richard Rodger"},"license":"MIT","_id":"gubu@0.0.3","maintainers":[{"name":"rjrodger","email":"richard.rodger@voxgig.com"}],"homepage":"https://github.com/rjrodger/gubu","bugs":{"url":"https://github.com/rjrodger/gubu/issues"},"dist":{"shasum":"53be70a6497af962734fda9d4c576ec973d2ee10","tarball":"https://registry.npmjs.org/gubu/-/gubu-0.0.3.tgz","fileCount":8,"integrity":"sha512-a8QxxJ2nYGDgwZaiW75qq1dIMERH0BiMCFpjHuQLUD03FMh+FuQ8KdAREkVc3gTZ13TwYhQE6HJQIxLC1IZzrQ==","signatures":[{"sig":"MEYCIQCGJRy8efPVj/2zecjbzx9uayqNdE6HpEYKJLefqN9MEwIhAOx2bJE0jotX1utgC5vQfUyer7eUw8MNlkkjZb9A54Br","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":92516,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhukHCCRA9TVsSAnZWagAAk1gP/Aia0wwT350XmHBJK8t5\n3Xc3UkOOP7YZIT9JejYN5NGeWI0NbcYwAd4AKKoNtRcado2d1oCEzMsCK2zM\n5SUjVkbt7rib92LBlb0BXmuGB6WK+XsHFHcwiZK/kzNdbpXNmmM9ty/HBYUr\nDWKf8GxRDEpOJH+vuxMuC1R21m9xVNgufaReIkkk7tNtixlj6MdAzun+5QbM\nLqPJ2zcg99PEYGotNZPjm3ewWwFXkufcpdi36s0aT1DWqIT9sIx5kogSaior\nyoNZDggRkCOOH5RXSvUVzvOPPdtVZ1gLlcV5DQHX7TBdKxWIyL9DIr/O5WxO\n5YIdPA+18qthonxcjbE8ilCPsBLs8dx5C3o+Llp2gagQj/0U9cXxP7T7Xosz\nU5Iuh6mEoDsbZnnyf9kgi7yVzHpksoWNSoaaoAofCgB2C8aBpjF1np3YSb4T\nHwDlujuqpYT8DPKLmpsOUAWMG+IXgsTOez0oG93re+NaO3SkhWuWNFJgUIYP\nYSD93H7SjjD2sKbWMYqFESonqWsV5O1PwI1KrJ/E/hllA3q2TtL2t2wMMfm/\nQPYIS8hpSaWpGeyGHVD6G7+KF0W3/zGZafjlx4ONSvHcrobWjG4zhXaPfAgd\nGDgPsIZbBGGBOtbqIZ0f3s+MDDzjBpPeX5TU52TaQnV/W+4qapJPzc/OsmBC\nHKop\r\n=Rc83\r\n-----END PGP SIGNATURE-----\r\n"},"main":"gubu.js","type":"commonjs","types":"gubu.d.ts","gitHead":"cff811b34c11bd19b70e3fbcd468bc6e846827fe","scripts":{"test":"jest --coverage","build":"tsc -d","clean":"rm -rf node_modules yarn.lock package-lock.json","reset":"npm run clean && npm i && npm test","watch":"tsc -w -d","repo-tag":"REPO_VERSION=`node -e \"console.log(require('./package').version)\"` && echo TAG: v$REPO_VERSION && git commit -a -m v$REPO_VERSION && git push && git tag v$REPO_VERSION && git push --tags;","test-some":"jest -t","test-watch":"jest --coverage --watchAll","repo-publish":"npm run clean && npm i && npm run repo-publish-quick","repo-publish-quick":"npm run build && npm run test && npm run repo-tag && npm publish --access public --registry https://registry.npmjs.org "},"_npmUser":{"name":"rjrodger","email":"richard.rodger@voxgig.com"},"repository":{"url":"git://github.com/rjrodger/gubu.git","type":"git"},"_npmVersion":"8.0.0","description":"An object shape validation utility.","directories":{},"_nodeVersion":"14.17.6","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"jest":"^27.4.5","ts-jest":"^27.1.1","typescript":"^4.5.4","@types/jest":"^27.0.3"},"_npmOperationalInternal":{"tmp":"tmp/gubu_0.0.3_1639596482456_0.364798944447319","host":"s3://npm-registry-packages"}},"0.0.4":{"name":"gubu","version":"0.0.4","keywords":["gubu"],"author":{"url":"http://richardrodger.com","name":"Richard Rodger"},"license":"MIT","_id":"gubu@0.0.4","maintainers":[{"name":"rjrodger","email":"richard.rodger@voxgig.com"}],"homepage":"https://github.com/rjrodger/gubu","bugs":{"url":"https://github.com/rjrodger/gubu/issues"},"dist":{"shasum":"5e2bdb1498dd006a79bc692655c69f7ecadb59d1","tarball":"https://registry.npmjs.org/gubu/-/gubu-0.0.4.tgz","fileCount":10,"integrity":"sha512-tWd9PIH6N9NFxVDSE5jv51vII159rJO0G+b2mCNIMq/vAB2AW3EzNPqX79opP1eU7g8lsm/sej/n5mvz2w5qmg==","signatures":[{"sig":"MEYCIQDzxq8f1H+1wvTJWjyKrXUhgwGBJtSQxbiiZqYQKmrFeAIhAMKVqeTQTEO6yz8IJdYg98n/KFNyIn4WoLNkBAavDgUL","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":100857,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhu5bNCRA9TVsSAnZWagAALREQAKE5Mxs2x2jyW0mqMwNH\nxAuRWWnH6LHufPd29jcS+MYg9cZ40L5a9ghGWMBbzo62fVKFO+BIYwpF/k67\nNETUoz9uDy9G9mT+IDXWVo1k+wCiTwxwBo92ZBPZuvQQ+uOGxrSHKVd1JMXE\nIQorjpgwWfO7rRXuKLUx8PRyhNobvi3pCVzs12E6KzuGktFc3zRfI/TquUDw\n12egP/pvL8fVwr4FFzcj21TI6DdQ1bN5kZlevRYvmPR7un5BepSHU9E+0s3l\n9wZdJLb9oYqfEgiyuQ8QpI9cpxsox3wmrF2KSuWINF1RqaTXGRSPfijejHgv\nfXzuW5+JXMudEyT8EBS+6NcEitBlZBV9Ofyk9Dq/0ikslNpRtkQEsyfshYW5\nQtJLdmSgW16TzyGbO4ZeDCxaCP8dihd+oVDu4i5P0FsNRTPmiIPAHhvJ6Axu\noDQWcR7DYREwI8XAa8w4u+rJKUxftCHO+YSUvsre198qWP8SFV3lmFzQEm2s\nyVSZ7zrn2gd0VkGyOYeE5Kp+2rwQgA6gwO/yAhR21CwEG3zZUp4Nbefec4xq\nBe0au9OUaMX6SXz5I0XnUesIU2IeC13KalRxW8IhVPAFtzZ07p6OCXFhg1uV\njGWVZ19CZZ4XxidnvRzpriMr78ccSmvS+mEeJFXyCz3ckhfftn4CpFG7uYhd\nod/9\r\n=fcgC\r\n-----END PGP SIGNATURE-----\r\n"},"main":"gubu.js","type":"commonjs","types":"gubu.d.ts","browser":"gubu.min.js","engines":{"node":">=12"},"gitHead":"cdd42cdbc4ecdc722cf9cd9e66f75f512a7ac359","scripts":{"test":"jest --coverage","build":"tsc -d","clean":"rm -rf node_modules yarn.lock package-lock.json","reset":"npm run clean && npm i && npm test","watch":"tsc -w -d","repo-tag":"REPO_VERSION=`node -e \"console.log(require('./package').version)\"` && echo TAG: v$REPO_VERSION && git commit -a -m v$REPO_VERSION && git push && git tag v$REPO_VERSION && git push --tags;","test-web":"npm run build-web && browserify -o test/web.js -e test/entry.js -im && open test/web.html","build-web":"cp gubu.js gubu.min.js && browserify -o gubu.min.js -e gubu.web.js -s Gubu -im -p tinyify","test-some":"jest -t","test-watch":"jest --coverage --watchAll","repo-publish":"npm run clean && npm i && npm run repo-publish-quick","repo-publish-quick":"npm run build && npm run test && npm run build-web && npm run test-web && npm run repo-tag && npm publish --access public --registry https://registry.npmjs.org "},"_npmUser":{"name":"rjrodger","email":"richard.rodger@voxgig.com"},"repository":{"url":"git://github.com/rjrodger/gubu.git","type":"git"},"_npmVersion":"8.0.0","description":"An object shape validation utility.","directories":{},"_nodeVersion":"14.17.6","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"jest":"^27.4.5","tinyify":"^3.0.0","ts-jest":"^27.1.2","browserify":"^17.0.0","typescript":"^4.5.4","@types/jest":"^27.0.3"},"_npmOperationalInternal":{"tmp":"tmp/gubu_0.0.4_1639683789413_0.3089738491448646","host":"s3://npm-registry-packages"}},"0.0.5":{"name":"gubu","version":"0.0.5","keywords":["gubu"],"author":{"url":"http://richardrodger.com","name":"Richard Rodger"},"license":"MIT","_id":"gubu@0.0.5","maintainers":[{"name":"rjrodger","email":"richard.rodger@voxgig.com"}],"homepage":"https://github.com/rjrodger/gubu","bugs":{"url":"https://github.com/rjrodger/gubu/issues"},"dist":{"shasum":"f989768017d507a4458db3ce932b91eede5fdae6","tarball":"https://registry.npmjs.org/gubu/-/gubu-0.0.5.tgz","fileCount":10,"integrity":"sha512-0LCblxuaNcaThS4pZFR11k+fOhy3ko6Yr/mVmRRRT5CLHIRCQjGvNQz2G1UzQz2wmhMfGxICS9MSjAzTsl7gNA==","signatures":[{"sig":"MEQCIG48EUrKqbMNkphG63UYLD40HOh6RVSYWIRf/VkIKQNpAiB5fT6jHCc+8SNRlZrck+9M3IH4tDl9006jF9v4mNlLNQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":167716,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh1a0oCRA9TVsSAnZWagAAkwEP/0AKZPamrjmzIwxD2KbL\nJdmZp8DsHXjCLH6jFcEAVkW6rQxovQ4htz1kuH4cqtj67pKmIqgUtuxtxN+F\nVehuDtW4S52CEBnTpY0ndjDETm0WVyOxF3OOUVyNvarZDM3JJO3DVwiab/ss\nQ4BNb/RqhJhFpR9P5+HxbDiGN3Kw4Q/dp+tCa1VEpNG2AhYNypXDcktqRgVw\ncUc5FJ04hEEeqNWnGLQ+hygyY+tzenwEz/P0QkqLQWousAII6sVo+AizOHNy\nFjf/XHdu680tw3qkSBrdD1bP2cAWh6/lco8U8/ImIiCZ3hY+iec37nAaAnM0\nLTEMSxcmqewEi0EU95F7Z3LyU+ptecBjmUSJhO0E+XmXppj3POmMOrYTh8V+\ncFzQH4Cohc2S6GMsgRSdgggdGPeAXWhNmdEA79LGB3DT6g6sQfrmwR/OMBQz\nFYDay32bAFTbfTmZRbeOoO2NHL6WMLJtXmBNMMLLuZLjV8Y4DX6b94ba9LGd\nWkyPKrSOas+Pahe5Dl1vb0uLbjOhVVVIk/yq6gXVSYmYJALlnYqAqHmeut9N\nG3vV9jYitq2fkjSpw4kIp1eOpPrMafoDRAEhgjj0H30kKBsKaVrkBM+5MkFm\nFmw0Oj56xoBEiK8BnEW4wGVx6eU0Pd/BodJ2TTdJ6m3WxkaIW6wbuvzVynOL\nYD6v\r\n=RdX0\r\n-----END PGP SIGNATURE-----\r\n"},"main":"gubu.js","type":"commonjs","types":"gubu.d.ts","browser":"gubu.min.js","engines":{"node":">=12"},"gitHead":"c6fb40dd313556f2abca3cfa21dc22fe701257a5","scripts":{"test":"jest --coverage","build":"tsc -d","clean":"rm -rf node_modules yarn.lock package-lock.json","reset":"npm run clean && npm i && npm test","watch":"tsc -w -d","repo-tag":"REPO_VERSION=`node -e \"console.log(require('./package').version)\"` && echo TAG: v$REPO_VERSION && git commit -a -m v$REPO_VERSION && git push && git tag v$REPO_VERSION && git push --tags;","test-web":"npm run build-web && browserify -o test/web.js -e test/entry.js -im && open test/web.html","build-web":"cp gubu.js gubu.min.js && browserify -o gubu.min.js -e gubu.web.js -s Gubu -im -p tinyify","test-some":"jest -t","test-watch":"jest --coverage --watchAll","repo-publish":"npm run clean && npm i && npm run repo-publish-quick","repo-publish-quick":"npm run build && npm run test && npm run build-web && npm run test-web && npm run repo-tag && npm publish --access public --registry https://registry.npmjs.org "},"_npmUser":{"name":"rjrodger","email":"richard.rodger@voxgig.com"},"repository":{"url":"git://github.com/rjrodger/gubu.git","type":"git"},"_npmVersion":"8.0.0","description":"An object shape validation utility.","directories":{},"_nodeVersion":"14.17.6","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"jest":"^27.4.7","tinyify":"^3.0.0","ts-jest":"^27.1.2","browserify":"^17.0.0","typescript":"^4.5.4","@types/jest":"^27.4.0"},"_npmOperationalInternal":{"tmp":"tmp/gubu_0.0.5_1641393448020_0.8817693508637785","host":"s3://npm-registry-packages"}},"0.0.6":{"name":"gubu","version":"0.0.6","keywords":["gubu"],"author":{"url":"http://richardrodger.com","name":"Richard Rodger"},"license":"MIT","_id":"gubu@0.0.6","maintainers":[{"name":"rjrodger","email":"richard.rodger@voxgig.com"}],"homepage":"https://github.com/rjrodger/gubu","bugs":{"url":"https://github.com/rjrodger/gubu/issues"},"dist":{"shasum":"005cbfa7e32910849457dec9a6911b6d94502fde","tarball":"https://registry.npmjs.org/gubu/-/gubu-0.0.6.tgz","fileCount":10,"integrity":"sha512-lScFT2kJ/EO4su+wEno29+qimMXE5IkxHe/rTkVCNyX2drBKiU8j3/Pdtxp3BmI4ChRHHIxZIJ5NMxXF/cYqdA==","signatures":[{"sig":"MEYCIQDBFAji0d9Yzm2kYIK2mqSI0B58tXaNvjOoaGC2iV8zBAIhAJTkR8Cab6ggGb1v3L8RzhYf0XwZt1wvA9YVYexlRGby","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":175692,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh1u7cCRA9TVsSAnZWagAAlFIP/A1pAl+y8/CjPpk/DHbd\nt55Ly/THred3z9yujBb4bWaE2AyWiRlUmLhFrZ9LD6Wf7/9425wYFj2aQVu2\nOxhmPBZ08E311eHfgzS55rG2oJkrQrfWubvjq1mGZSN2UNnpDRv3gMd7C08X\nOOl2hjkQk8ibkO4GD07cGXs43e1TLNZ9JLMlsGoCWebajAZ+qJ/h6PFqQXzj\nK68S6YgO204046V1CJ3K/U/hJHUWxuygJG54Y9y89Rh6ISvUdTFztXib4kbS\n2CLl2pOmNUDT80ISrJFYfqbeGQyRpGlkUUC4dA9LoS9TBocgtcIzeC6UvtQV\n0w+JwGoTdjh7aXr4164Eeh5NSlG1uuo7oA+Iux7yhznTjJT9IZCmU5vR6rsf\n2vnVp+mpgloH1yN7IB2ngA4leFvsTnOtE8/2phOt1vjTARt64Jnciy7ZSZps\nOyLI8omazdxrhCnbHfZK//woLshwur3RSD1yke+vGECOrxontMXeU5s2gH5v\nQVQGsyfH8IlxXO9o/NxnmeUEyCEwqtxpn1Etxs+sC524KAHGBfS78mBvs5xj\n/lImByFXyzqZwjl3f67SQlMFdYm28A09ZXJ3YRxcYplHeGP6aZJxmMD623fF\nxYBHbmdEpzG3l2AVGj8IY006AjR7/Wd3p4/Zz0dlgjtsFXppMLhqd9DhL/fF\nkY/f\r\n=IR0c\r\n-----END PGP SIGNATURE-----\r\n"},"main":"gubu.js","type":"commonjs","types":"gubu.d.ts","browser":"gubu.min.js","engines":{"node":">=12"},"gitHead":"02ac78559999ba070109854f7dd6d39266d6df41","scripts":{"test":"jest --coverage","build":"tsc -d","clean":"rm -rf node_modules yarn.lock package-lock.json","reset":"npm run clean && npm i && npm test","watch":"tsc -w -d","repo-tag":"REPO_VERSION=`node -e \"console.log(require('./package').version)\"` && echo TAG: v$REPO_VERSION && git commit -a -m v$REPO_VERSION && git push && git tag v$REPO_VERSION && git push --tags;","test-web":"npm run build-web && browserify -o test/web.js -e test/entry.js -im && open test/web.html","build-web":"cp gubu.js gubu.min.js && browserify -o gubu.min.js -e gubu.web.js -s Gubu -im -p tinyify","test-some":"jest -t","test-watch":"jest --coverage --watchAll","repo-publish":"npm run clean && npm i && npm run repo-publish-quick","repo-publish-quick":"npm run build && npm run test && npm run build-web && npm run test-web && npm run repo-tag && npm publish --access public --registry https://registry.npmjs.org "},"_npmUser":{"name":"rjrodger","email":"richard.rodger@voxgig.com"},"repository":{"url":"git://github.com/rjrodger/gubu.git","type":"git"},"_npmVersion":"8.0.0","description":"An object shape validation utility.","directories":{},"_nodeVersion":"14.17.6","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"jest":"^27.4.7","tinyify":"^3.0.0","ts-jest":"^27.1.2","browserify":"^17.0.0","typescript":"^4.5.4","@types/jest":"^27.4.0"},"_npmOperationalInternal":{"tmp":"tmp/gubu_0.0.6_1641475804100_0.36950915749902413","host":"s3://npm-registry-packages"}},"0.1.0":{"name":"gubu","version":"0.1.0","keywords":["gubu"],"author":{"url":"http://richardrodger.com","name":"Richard Rodger"},"license":"MIT","_id":"gubu@0.1.0","maintainers":[{"name":"rjrodger","email":"richard.rodger@voxgig.com"}],"homepage":"https://github.com/rjrodger/gubu","bugs":{"url":"https://github.com/rjrodger/gubu/issues"},"dist":{"shasum":"f3e6c508b1e3b1261c351f95ee15b70d4f920251","tarball":"https://registry.npmjs.org/gubu/-/gubu-0.1.0.tgz","fileCount":10,"integrity":"sha512-wo2SoF56jR7ocr5SjiiaJ/n3KS5K+CEQ9hpMlG6n0IoTENyVtBlo6pt5rsBwXuqsrKD1o2bYrBf4NzHGSYtQFg==","signatures":[{"sig":"MEQCIENObnKhRYkeJk15mgMcf5e54LrsWUvWOfiUDefGLE7nAiAe6mxKk1xaa7gww7yBXHNvA8/cq0ecgIiBIkzNxzorgQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":183984,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh14qXCRA9TVsSAnZWagAAU78P/36y9LkcE1RWVDlkB0ZV\n7QKsQWZ+Gi1KufGwFM1fgklwZh5y9U7ppdquV9de+4Owvexa/Le4DpwQSX0f\ngz2bxrDBFf0zqvmk0vTXR6RDvQe190WIpHs+E2La24UpssAMkuXMZyp3e1oC\nKAzC35LjaVshR1kblP93RnkX9xZxSJ5eyYW7dexeW8hMJQnRWpaC5xESZiWf\nVuMWYBb9xAw9mPiVjDxrfWb9iWNyD1FbeyRPjTrBJfEONRlsKmqLwqwNCFrz\nBRLXRyt2PXgXTqn7mTtnMWn4aKj/aNI/X8JXvxXlixjycYusBlFxeeAbAOfR\nCu6scEqt6MZpc3oxlkfNHRmqe1CM6VfIMjE5VcrO7n3gxr/oLUqd2u7NSFhF\ntqHricTuht0cNyqfpqkkkI6y31WVKcFyJxQSwaXtRcMYSgZQFt8tROFk2ECD\nxmldzu8vTi+yyp1uphncbQdLrIB9rnbrHkwTtStyjhAd2TwteON/a3Oxouv7\nyiY/BZ3Fch9lyz5StNxNyPRntccQYiD6c0uuy7uobcg0hK5YCP17eV+3H5C/\nBWckqjL/tFzlxQGkF3WFd8MlOISkfNL2Bx6WiADqSay8gs0Mx0c21UrS5lJN\ndZoxjG3SLGyzEdIMVnwURVEI4gjmKwLbgM1O/Xy1yHZbazorPo20wHnJSfDX\nP4xG\r\n=kUi9\r\n-----END PGP SIGNATURE-----\r\n"},"main":"gubu.js","type":"commonjs","types":"gubu.d.ts","browser":"gubu.min.js","engines":{"node":">=12"},"gitHead":"5e2238ae4c80879c9ecb7481b39f2dd79ed08fee","scripts":{"test":"jest --coverage","build":"tsc -d","clean":"rm -rf node_modules yarn.lock package-lock.json","reset":"npm run clean && npm i && npm test","watch":"tsc -w -d","repo-tag":"REPO_VERSION=`node -e \"console.log(require('./package').version)\"` && echo TAG: v$REPO_VERSION && git commit -a -m v$REPO_VERSION && git push && git tag v$REPO_VERSION && git push --tags;","test-web":"npm run build && npm run build-web && browserify -o test/web.js -e test/entry.js -im && open test/web.html","build-web":"cp gubu.js gubu.min.js && browserify -o gubu.min.js -e gubu.web.js -s Gubu -im -p tinyify","test-some":"jest -t","test-watch":"jest --coverage --watchAll","repo-publish":"npm run clean && npm i && npm run repo-publish-quick","repo-publish-quick":"npm run build && npm run test && npm run build-web && npm run test-web && npm run repo-tag && npm publish --access public --registry https://registry.npmjs.org "},"_npmUser":{"name":"rjrodger","email":"richard.rodger@voxgig.com"},"repository":{"url":"git://github.com/rjrodger/gubu.git","type":"git"},"_npmVersion":"8.0.0","description":"An object shape validation utility.","directories":{},"_nodeVersion":"14.17.6","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"jest":"^27.4.7","tinyify":"^3.0.0","ts-jest":"^27.1.2","browserify":"^17.0.0","typescript":"^4.5.4","@types/jest":"^27.4.0"},"_npmOperationalInternal":{"tmp":"tmp/gubu_0.1.0_1641515671759_0.33563876365505063","host":"s3://npm-registry-packages"}},"0.2.0":{"name":"gubu","version":"0.2.0","keywords":["gubu"],"author":{"url":"http://richardrodger.com","name":"Richard Rodger"},"license":"MIT","_id":"gubu@0.2.0","maintainers":[{"name":"rjrodger","email":"richard.rodger@voxgig.com"}],"homepage":"https://github.com/rjrodger/gubu","bugs":{"url":"https://github.com/rjrodger/gubu/issues"},"dist":{"shasum":"9067c85c600b79a366b8edb7fd3d4e88e956117a","tarball":"https://registry.npmjs.org/gubu/-/gubu-0.2.0.tgz","fileCount":14,"integrity":"sha512-kM/VMqbaqdvUJluP6uxctaxCLCi/RgEDrfbC4hTreG2pTbYakRcMYIDeN0jBZTP1CPg+NweXdMwVOBPtEnBxOQ==","signatures":[{"sig":"MEUCICQqSuQhG1L3RTmnAVumrV+Myijymi0j6ebFqKOIxi48AiEAyn9zXvGBlpYYBDPTZ6QWE9DU70V32Ibt8oOHhbwSuhg=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":241524,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh4WkZCRA9TVsSAnZWagAAvt0P/3M/34fTYV2MMlGjYqn+\nN1TYZGY5zpDP/HKMcwTL+v73RZ5lQ4StlE7K30XKmCQQE3KynraTp89dde4V\nMgvhyC6DNdQR6vYyzp89VFLZYv41S6t0CAr8udrUsTo8uEYKbQFWibh41//v\n0hEmPGVRRtmXv08UrQKNQnlcm8S6AUgQOEdwB22ffTLMRWxhKOSGkS6y892B\nddFmkdGTgzoWO28aWKqYLeR/reWvRv8H/5k/vIinw8KpkaBkQh3nzK8JFSgp\n5SdjM1HaiviDHs1gmZ9lekKh0c9MeNpkBs1/1F5F0fdVroeGsRrcZsA3Pt/t\nKXxx8Nq1ZVNXeYxxLCm9iLIuFN3jonJp7yRG42xUwEES7KFy89D5zErsvwia\n7sQEjZYQNyLEt1WClaR9RIl9oX0J6C2ngUZ4eRBunczELo4OvMX2LzIXih35\nOCTO1FdVrQOiKDEoNHM4GzGaO/Mx1NbitV6bE4uJYXEarCIwDHXOOfJrJltV\nTVqWom6ARFO4BL2EZyp0zR6wevrbOlKesfhHFf5YVPuWU/XbXlzhRcTJ2yoK\n82Nx2JM4ImkiPT8I6P9DGU++lYgQ9227L6lGWUxPNcz6vRVaMFruo796Bz+j\niP7baHGOzFmb1Tm45JrdbSxqcsW34DUUThuNTV54/gbRMZPOq1EIUZXeakJB\nH+Yo\r\n=AEYT\r\n-----END PGP SIGNATURE-----\r\n"},"main":"gubu.js","type":"commonjs","types":"gubu.d.ts","browser":"gubu.min.js","engines":{"node":">=12"},"gitHead":"d59fe0c3aca076966d940a3b21710080e8732478","scripts":{"lint":"markdownlint README.md","test":"jest --coverage","build":"tsc -d","clean":"rm -rf node_modules yarn.lock package-lock.json","reset":"npm run clean && npm i && npm test","watch":"tsc -w -d","repo-tag":"REPO_VERSION=`node -e \"console.log(require('./package').version)\"` && echo TAG: v$REPO_VERSION && git commit -a -m v$REPO_VERSION && git push && git tag v$REPO_VERSION && git push --tags;","test-web":"npm run build && npm run build-web && browserify -o test/web.js -e test/entry.js -im && open test/web.html","build-web":"cp gubu.js gubu.min.js && browserify -o gubu.min.js -e gubu.web.js -s Gubu -im -p tinyify","test-some":"jest -t","test-watch":"jest --coverage --watchAll","repo-publish":"npm run clean && npm i && npm run repo-publish-quick","repo-publish-quick":"npm run build && npm run test && npm run build-web && npm run test-web && npm run repo-tag && npm publish --access public --registry https://registry.npmjs.org "},"_npmUser":{"name":"rjrodger","email":"richard.rodger@voxgig.com"},"repository":{"url":"git://github.com/rjrodger/gubu.git","type":"git"},"_npmVersion":"8.0.0","description":"An object shape validation utility.","directories":{},"_nodeVersion":"14.17.6","_hasShrinkwrap":false,"devDependencies":{"jest":"^27.4.7","tinyify":"^3.0.0","ts-jest":"^27.1.2","browserify":"^17.0.0","typescript":"^4.5.4","@types/jest":"^27.4.0"},"_npmOperationalInternal":{"tmp":"tmp/gubu_0.2.0_1642162457106_0.5216605643982137","host":"s3://npm-registry-packages"}},"0.2.1":{"name":"gubu","version":"0.2.1","keywords":["gubu"],"author":{"url":"http://richardrodger.com","name":"Richard Rodger"},"license":"MIT","_id":"gubu@0.2.1","maintainers":[{"name":"rjrodger","email":"richard.rodger@voxgig.com"}],"homepage":"https://github.com/rjrodger/gubu","bugs":{"url":"https://github.com/rjrodger/gubu/issues"},"dist":{"shasum":"eae7057c412a1a384aff30dba8f8e3fb0d0ae882","tarball":"https://registry.npmjs.org/gubu/-/gubu-0.2.1.tgz","fileCount":14,"integrity":"sha512-7m5m4AJJd0UkkUBRqa4XGigQPYh98H1iG/1KWbx/lpFvl/+fOaI0LY2XZEg9rcODMnIRT56cAyudIAW5tngtlQ==","signatures":[{"sig":"MEUCIQDk3NauNKjJvoavNM5TzlBxOYlyJgcg+es0TejcpUTsjgIgQljj/aHfDrTCCQHCUIlNRyhBbojoc3is9BK9tD04K8M=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":218243,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh4ZmnCRA9TVsSAnZWagAAB94QAI5KORPCR1BnQt+7NXAi\nKdEeUbrQVIf5EU+6GTlVF8o5KGPEswAC27tCIBPVpdUEA1TccqOHAMkYtACp\nX5vOVvXoMCndQeEJEvTOxiNEWPMKhJLr6gtKD7z86/SfTDJsCs4cur/giNmQ\nQn4yYMWw78iDu06tqshBKyrlotzcO8juE5vi3LVqOvY05k8rx5moN7gZ+v8U\nDtXbHioURRE6AAb3Z6kv9e+b5EJTkBTDL55Vn9Ei3db/mUi+X3SLPs8J5Esx\n9aMLvC3jf5PvxYg4U08HNdM6kmBVYVXL/9OMHlDUUmNQwrALM4QUP8Swyh77\nhlBLJjUyjwdI8o+EYDwllWw8EbIKUxzNJpvT6T2tjWWum/gkKIm/m37iiJ+d\nyDGrJTkpEqz0PlX5Vnf28aqVBWYaE1N7DiJPZXl6N7ccFDYKoWpyzVzgenHC\ngeqfrpx5sjxt+rRxAMraRYCR6Sr4gvQYGuL1xj+JfX8+D2qRymCXXgYVyoSd\nvLIuCNRKePbSxWTQcRqf9E7lGg9uFz3FQi3oedv0hxfmPxM7wQmewZ7kgZdv\n8U4Ud4YkOrOg+UZRd7oLjkyyaWsgxy9eAW0LLRT5Vwsa5ZEcg22cQJCBEP1s\n+5pgGFOFfwgAM9k5j7t8gQyvld5231oKva+RiFKBnmp8WQ2c6AwBmzo0GvGQ\nWH5o\r\n=9XTz\r\n-----END PGP SIGNATURE-----\r\n"},"main":"gubu.js","type":"commonjs","types":"gubu.d.ts","browser":"gubu.min.js","engines":{"node":">=12"},"gitHead":"19ffd2e377ad479a69e12373ed27e30f2290cbd8","scripts":{"test":"npm run version && jest --coverage","build":"npm run version && tsc -d","clean":"rm -rf node_modules yarn.lock package-lock.json","reset":"npm run clean && npm i && npm build && npm test","watch":"npm run version && tsc -w -d","version":"node -r fs -e \"v=require('./package.json').version;s=fs.readFileSync('./gubu.ts').toString().replace(/VERSION = '.*?'/,'VERSION = \\''+v+'\\'');fs.writeFileSync('./gubu.ts',s)\"","repo-tag":"REPO_VERSION=`node -e \"console.log(require('./package').version)\"` && echo TAG: v$REPO_VERSION && git commit -a -m v$REPO_VERSION && git push && git tag v$REPO_VERSION && git push --tags;","test-web":"npm run build && npm run build-web && browserify -i util -o test/web.js -e test/entry.js -im && open test/web.html","build-web":"cp gubu.js gubu.min.js && browserify -i util -o gubu.min.js -e gubu.web.js -s Gubu -im -p tinyify","test-some":"npm run version && jest -t","test-watch":"npm run version && jest --coverage --watchAll","repo-publish":"npm run clean && npm i && npm run repo-publish-quick","repo-publish-quick":"npm run build && npm run test && npm run build-web && npm run test-web && npm run repo-tag && npm publish --access public --registry https://registry.npmjs.org "},"_npmUser":{"name":"rjrodger","email":"richard.rodger@voxgig.com"},"repository":{"url":"git://github.com/rjrodger/gubu.git","type":"git"},"_npmVersion":"8.0.0","description":"An object shape validation utility.","directories":{},"_nodeVersion":"14.17.6","_hasShrinkwrap":false,"devDependencies":{"jest":"^27.4.7","tinyify":"^3.0.0","ts-jest":"^27.1.2","browserify":"^17.0.0","typescript":"^4.5.4","@types/jest":"^27.4.0"},"_npmOperationalInternal":{"tmp":"tmp/gubu_0.2.1_1642174887489_0.11912138093319391","host":"s3://npm-registry-packages"}},"1.0.0":{"name":"gubu","version":"1.0.0","keywords":["gubu"],"author":{"url":"http://richardrodger.com","name":"Richard Rodger"},"license":"MIT","_id":"gubu@1.0.0","maintainers":[{"name":"rjrodger","email":"richard.rodger@voxgig.com"}],"homepage":"https://github.com/rjrodger/gubu","bugs":{"url":"https://github.com/rjrodger/gubu/issues"},"dist":{"shasum":"0c2ee805d54916f1777adaa7e98704c5e5c3c97e","tarball":"https://registry.npmjs.org/gubu/-/gubu-1.0.0.tgz","fileCount":14,"integrity":"sha512-q6Y0txZyC5x/RAGoLO1FdgO0VlagQWdSuLTTMfJwW/tWQpEjNhAKQO6H/fypWwaFqAjMcs0LbllQ2fp/jJUDAA==","signatures":[{"sig":"MEQCICfO9BAxZRDQD6W3XkrN2GWSVfPDWPy8ODEzhada1XWIAiBnY2sF8+mVbm1kX7Yuw6fIjrM+z+yhyuzCQ8MkAIxN6A==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":226673,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh4u12CRA9TVsSAnZWagAAyGMQAKCBhcqfLT41dSKo3C20\n94sVMkzLpMhoFWcA1zLc0hSp7IIa4RvDQwDp5qf3eKIFepVu8JQL4bsqPYA3\nkyj5N/AYtLn9FfgIWDYcGGHMU1ByagzZE/7BvX5VJ1lSjREQdumvgqTAslDv\niPoPOECna7tSCoZ3YVj9neUtFpfpSokZuU0LDgpRrXdbo/AQJaWbH2DdFRng\nDqyJs64Z7nZYpAzgOJsRMjYrlp2n68FDp6SHwudGFSRqL54mMO6LF2oLvNbh\najRB/wwWE4ylo9gLsQkqVlSGozDF5RfXnam3ZDHE5cem7UgPGJekkowNlcf2\nqGOfDJBswXqfxdqOhu1rVXoXmvPDMiID87AMET++Cij/z6IASJ4lArSqM3za\nlEvHmpnzF+w10F7VT5fLc3MAlPGElKMhJsrLo5/oApDY1u2p6MQy/IWNFVEa\nVPn0hHsSG6rdUUlK/9K0o/nR59BiKVmP1REMesXL6W/ol8qkWxPmZTa3M+Uw\n4TSjqsYd5jJvKCP58K0HnDywLlqPqcgLmcnard4dQpUuXcUZCtODV726yBxJ\nn51lhhuqH8i8H3Sgm9PFYOuFy7ICIoeNKue0HWnC9gsqUTIOzaRY1O0/LTeZ\nJO/m75PPCXXcjHz0cu3iq34M7fErS7W5QYQyeMwxraZWHrM0WUeDtRrcFlSG\nmKr3\r\n=Rrni\r\n-----END PGP SIGNATURE-----\r\n"},"main":"gubu.js","type":"commonjs","types":"gubu.d.ts","browser":"gubu.min.js","engines":{"node":">=12"},"gitHead":"fa85695a877021d360bb53d44d0f11fd8db4075b","scripts":{"test":"npm run version && jest --coverage","build":"npm run version && tsc -d","clean":"rm -rf node_modules yarn.lock package-lock.json","reset":"npm run clean && npm i && npm run build && npm test","watch":"npm run version && tsc -w -d","version":"node -r fs -e \"v=require('./package.json').version;s=fs.readFileSync('./gubu.ts').toString().replace(/VERSION = '.*?'/,'VERSION = \\''+v+'\\'');fs.writeFileSync('./gubu.ts',s)\"","repo-tag":"REPO_VERSION=`node -e \"console.log(require('./package').version)\"` && echo TAG: v$REPO_VERSION && git commit -a -m v$REPO_VERSION && git push && git tag v$REPO_VERSION && git push --tags;","test-web":"npm run build && npm run build-web && browserify -i util -o test/web.js -e test/entry.js -im && open test/web.html","build-web":"cp gubu.js gubu.min.js && browserify -i util -o gubu.min.js -e gubu.web.js -s Gubu -im -p tinyify","test-some":"npm run version && jest -t","test-watch":"npm run version && jest --coverage --watchAll","repo-publish":"npm run clean && npm i && npm run repo-publish-quick","repo-publish-quick":"npm run build && npm run test && npm run build-web && npm run test-web && npm run repo-tag && npm publish --access public --registry https://registry.npmjs.org "},"_npmUser":{"name":"rjrodger","email":"richard.rodger@voxgig.com"},"repository":{"url":"git://github.com/rjrodger/gubu.git","type":"git"},"_npmVersion":"8.0.0","description":"An object shape validation utility.","directories":{},"_nodeVersion":"14.17.6","_hasShrinkwrap":false,"devDependencies":{"jest":"^27.4.7","tinyify":"^3.0.0","ts-jest":"^27.1.3","browserify":"^17.0.0","typescript":"^4.5.4","@types/jest":"^27.4.0"},"_npmOperationalInternal":{"tmp":"tmp/gubu_1.0.0_1642261878199_0.5044406054878801","host":"s3://npm-registry-packages"}},"2.0.0":{"name":"gubu","version":"2.0.0","keywords":["gubu"],"author":{"url":"http://richardrodger.com","name":"Richard Rodger"},"license":"MIT","_id":"gubu@2.0.0","maintainers":[{"name":"rjrodger","email":"richard.rodger@voxgig.com"}],"homepage":"https://github.com/rjrodger/gubu","bugs":{"url":"https://github.com/rjrodger/gubu/issues"},"dist":{"shasum":"34d69c7a13acabc822e1c2240f080edbf7cf3eb5","tarball":"https://registry.npmjs.org/gubu/-/gubu-2.0.0.tgz","fileCount":11,"integrity":"sha512-L9SIA46eIzL7BaUPTQMNbTHAusC0Vj0soA0LXENntpo7Qc3i8+qF1jMv1MmakHinu8hkcjdZPh2O06oTc4UWjQ==","signatures":[{"sig":"MEQCIEMDWj9tlxEZds8su28o4X0WTJhnD4mCVMMv+LA6W98WAiASJRgUpzx2z5wM6pua3+eb7XOiIWzOI1HIoMMs3UipcQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":249250,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiPOT7ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqKng//UzNFPDPTXVb6ZTwwiAJCEMbNYT3Q5M1gi+443PYzXQPznUSi\r\nyIK3Y6f7g9+NZCHAcmmyfaXuGnT5AcJMTFiIJFAR9DRVimxAWW6ez0/B3InG\r\nEB9kIO3kbOm/SlKabMvIXgHkUE3U+4FzBqP/aFgnJMXVSeiUBbHwlWeKpbYn\r\nkA6Kiru+gmC6/RWT+rwlMuVCxXkU/7gTkWaXbBu/VCWr8ksmIp/NH0UysFF3\r\nTnzHQsZMIVgiHYgURMogXm1mjKDzZ2zVfMEIBHX7hGb2DOjvvdt5LDrWAgSR\r\n5afywy9HUShd0cX+Cu9crSlHzm4y01Mjpg19uUdegwhKCVI39m683goYoGUT\r\nON+UAylQySO3o4bFOMuZxoHS214P8gE32moqNYZDbIIc1q5Xz0QMWTSMtVq0\r\nym1UtwAtrEJO+dj4NXqWfCEGeTo0npAS0LsBjETDEqmwyfxnq/h51aiU409z\r\nW+OcQJN2LvF16GtQC3TxFplVhnI0m+3teU7FBQ62sLJA560/YmDmNjJxamuA\r\nBNMAiLGSgE+X79qlPacd7k47Kbb8GcZi7WRgm9b0Lufna8MUz5wb8IuRD49n\r\nUIYQn0H4lU3OuX/He7bZkKTSnkgSJM5KlUnAe/lwtS7TWaFaczw4ZZdYBfHa\r\ngUMgX9b/pTOPugCcoYpommvNFtJ48UeXI3I=\r\n=Kn84\r\n-----END PGP SIGNATURE-----\r\n"},"main":"gubu.js","type":"commonjs","types":"gubu.d.ts","browser":"gubu.min.js","engines":{"node":">=12"},"gitHead":"e071db69154089a1f69f85df9f35330a68c670da","scripts":{"test":"npm run version && jest --coverage","build":"npm run version && tsc -d","clean":"rm -rf node_modules yarn.lock package-lock.json","reset":"npm run clean && npm i && npm run build && npm test","watch":"npm run version && tsc -w -d","version":"node -r fs -e \"v=require('./package.json').version;s=fs.readFileSync('./gubu.ts').toString().replace(/VERSION = '.*?'/,'VERSION = \\''+v+'\\'');fs.writeFileSync('./gubu.ts',s)\"","repo-tag":"REPO_VERSION=`node -e \"console.log(require('./package').version)\"` && echo TAG: v$REPO_VERSION && git commit -a -m v$REPO_VERSION && git push && git tag v$REPO_VERSION && git push --tags;","test-web":"npm run build && npm run build-web && browserify -i util -o test/web.js -e test/entry.js -im && open test/web.html","build-web":"cp gubu.js gubu.min.js && browserify -i util -o gubu.min.js -e gubu.web.js -s Gubu -im -p tinyify","test-pure":"npm run version && jest --coverage --config jest.config.pure.js","test-some":"npm run version && jest -t","test-watch":"npm run version && jest --coverage --watchAll","repo-publish":"npm run clean && npm i && npm run repo-publish-quick","test-some-pure":"npm run version && jest --config jest.config.pure.js -t","repo-publish-quick":"npm run build && npm run test && npm run build-web && npm run test-web && npm run repo-tag && npm publish --access public --registry https://registry.npmjs.org "},"_npmUser":{"name":"rjrodger","email":"richard.rodger@voxgig.com"},"repository":{"url":"git://github.com/rjrodger/gubu.git","type":"git"},"_npmVersion":"8.5.0","description":"An object shape validation utility.","directories":{},"_nodeVersion":"16.14.1","_hasShrinkwrap":false,"devDependencies":{"jest":"^27.5.1","esbuild":"^0.14.27","tinyify":"^3.0.0","ts-jest":"^27.1.4","browserify":"^17.0.0","typescript":"^4.6.2","@types/jest":"^27.4.1","esbuild-jest":"^0.5.0"},"_npmOperationalInternal":{"tmp":"tmp/gubu_2.0.0_1648157947649_0.004168878401668685","host":"s3://npm-registry-packages"}},"2.0.1":{"name":"gubu","version":"2.0.1","keywords":["gubu"],"author":{"url":"http://richardrodger.com","name":"Richard Rodger"},"license":"MIT","_id":"gubu@2.0.1","maintainers":[{"name":"rjrodger","email":"richard.rodger@voxgig.com"}],"homepage":"https://github.com/rjrodger/gubu","bugs":{"url":"https://github.com/rjrodger/gubu/issues"},"dist":{"shasum":"e2d26cbc872e1fdb18a7c221802c5f6c547db999","tarball":"https://registry.npmjs.org/gubu/-/gubu-2.0.1.tgz","fileCount":11,"integrity":"sha512-OVsl4A1vyDBYq+6hp0h+vUi7P7fq48GjOV30hpwLCAYuZ3FuaR0ZdtDE0nwwtDUqF3nnJ6/mYekvUMxlNdr1RQ==","signatures":[{"sig":"MEUCIDo0vd0SK6oBF+MoDIM1HcZfN28BMp+GF+kee3ClRUV7AiEAkZ234cp7jY/6x9LHY2Vq8vfKQalR44fu5FElVAFhg6g=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":249806,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiVcW6ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqaAg//eU5DJxaJ1Wi1wxwffhN8bzDxHrVeSeUg1BGyeuodOwSTYhwd\r\nsRtpG41VUyDLBYjsBrxTRwuE9+5bf8R+YtQNpHlcsL8nzJTNwLtpSItlvJGl\r\nwfgevuhcVFmOIj0JPd61UBICfhWX2KajRY9LOHXHiFEhcG0UnRayMK5xtDoC\r\nDpqBg2XSovX+Lt8ywabRT4iKXP2OFm7dgCkjVqYztvMLwqTjKM2RmPCO69FK\r\nkUx3DFpb/r3hOI2czdoUGosZ2sn4ZUC3HfKegmoJIhQziJme1jitXTSkznEV\r\nP5U4aonjr7tQLLFx3zL8OBpkJvGhQKgs28CtzfxdMdX/8rvguw/9u7GRZ44g\r\nr+vmgPG4sMs+QIksKBxIqloF4kTQqE0ozUouPSWVVDIegbVDu8q9Gnbg1UCw\r\nXgBUwrW6pqPmAdzRMr2tPmvpdmQxAUwhW45xkv5vLodMHDqnSPmwiQS3a6rw\r\nRdUSXJ0SLNi4VrmdrowtnIISzcT0C7R4uKuzgb10xORV1bwySB/XyDNqC2AS\r\npAOUt3gAaP4E2YKEVN3DoVV5mKU3XuMNK51jxREuRt1E85eBo8ZhOubhvY82\r\nFRvNQTprwtVZVfwHUQM4V4VF1XfQQbR02BcwSZOF69BS9/aQZFZHZCPs0eir\r\nYDh1g7PO1UtwWbmlW75QJVIpLGeRNFzbmXY=\r\n=xp1q\r\n-----END PGP SIGNATURE-----\r\n"},"main":"gubu.js","type":"commonjs","types":"gubu.d.ts","browser":"gubu.min.js","engines":{"node":">=12"},"gitHead":"4582a9edf3253b0bffe555f038e229b3b5a33427","scripts":{"test":"npm run version && jest --coverage","build":"npm run version && tsc -d","clean":"rm -rf node_modules yarn.lock package-lock.json","reset":"npm run clean && npm i && npm run build && npm test","watch":"npm run version && tsc -w -d","version":"node -r fs -e \"v=require('./package.json').version;s=fs.readFileSync('./gubu.ts').toString().replace(/VERSION = '.*?'/,'VERSION = \\''+v+'\\'');fs.writeFileSync('./gubu.ts',s)\"","repo-tag":"REPO_VERSION=`node -e \"console.log(require('./package').version)\"` && echo TAG: v$REPO_VERSION && git commit -a -m v$REPO_VERSION && git push && git tag v$REPO_VERSION && git push --tags;","test-web":"npm run build && npm run build-web && browserify -i util -o test/web.js -e test/entry.js -im && open test/web.html","build-web":"cp gubu.js gubu.min.js && browserify -i util -o gubu.min.js -e gubu.web.js -s Gubu -im -p tinyify","test-pure":"npm run version && jest --coverage --config jest.config.pure.js","test-some":"npm run version && jest -t","test-watch":"npm run version && jest --coverage --watchAll","repo-publish":"npm run clean && npm i && npm run repo-publish-quick","test-some-pure":"npm run version && jest --config jest.config.pure.js -t","repo-publish-quick":"npm run build && npm run test && npm run build-web && npm run test-web && npm run repo-tag && npm publish --access public --registry https://registry.npmjs.org "},"_npmUser":{"name":"rjrodger","email":"richard.rodger@voxgig.com"},"repository":{"url":"git://github.com/rjrodger/gubu.git","type":"git"},"_npmVersion":"8.5.0","description":"An object shape validation utility.","directories":{},"_nodeVersion":"16.14.2","_hasShrinkwrap":false,"devDependencies":{"jest":"^27.5.1","esbuild":"^0.14.36","tinyify":"^3.0.0","ts-jest":"^27.1.4","browserify":"^17.0.0","typescript":"^4.6.3","@types/jest":"^27.4.1","esbuild-jest":"^0.5.0"},"_npmOperationalInternal":{"tmp":"tmp/gubu_2.0.1_1649788346507_0.4585812984342674","host":"s3://npm-registry-packages"}},"3.0.0":{"name":"gubu","version":"3.0.0","keywords":["gubu","schema","validation"],"author":{"url":"http://richardrodger.com","name":"Richard Rodger"},"license":"MIT","_id":"gubu@3.0.0","maintainers":[{"name":"rjrodger","email":"richard.rodger@voxgig.com"}],"homepage":"https://github.com/rjrodger/gubu","bugs":{"url":"https://github.com/rjrodger/gubu/issues"},"dist":{"shasum":"758cdaa3076f2bfb43c608d0f2a2318f54cf975c","tarball":"https://registry.npmjs.org/gubu/-/gubu-3.0.0.tgz","fileCount":11,"integrity":"sha512-e+AzCsSTOeT4P/L5R0m8vedzWkFsHywaUr9GhWwhpwkKAch+1O4rWr+dtU7DQpXSR3JEWzuEdkOtTzrbsriEPw==","signatures":[{"sig":"MEUCIQDOljGv+0PDL1OhHcxnSBp7kgkouKUpUOJEfOoSa6LnOgIgVXshpaWfasGiIGhovRVfjdn4nGMowsUzZJh76rGwREA=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":252295,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiiXXwACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrvVw/+Pw3TZ7Qqrukxs45eVwHg/SkxcfmYL+dwX+skH3pqtQTUBerG\r\nVHoCa8MPRF6XX9djEdLF30hsPzitclQwg+k8HSlMcIdqY3733VFJT/9VrUiU\r\nBquhBIs0psZVBtj5yKTkIGpcDKZPGRJC2Nx2O1cyCTanjMrByLizxz7Nu2r6\r\n9PrrbeK21Y6bKI4sA4s6iJqvwtphESkGsdrMUoqYoLKAnoQPRVuD8ML7HP5a\r\n6nXdhHQU/qdWJwc0wRjw5Rx5f/UxzPwLOX9RdiUy6WkT74Rpi+EBYjBeX+NV\r\n6t7lznkSBL6eaTVbXxzT4go2H7SjXF1q64qMXMr8NbjZpksUKEeSclVXCMND\r\nIRSxxIbHFleNyhJbOJB+MQPie8rr2lPWpIugbIzN/Ng3r9TCSafcikPjJdxI\r\nGaLSn3JPcWONGejbN6tT6D+BYlg36J22tTjXLBRw0JE3XKwER/UI8cEm+d6/\r\nAs1r7+P0xJcb9p+9qZtzhQMLeHmy+pNCxVln5OMh01dW27hvsTzuQj4RyhQq\r\ngwvEOhyCI9I5NN4FHELF50GKJBd8WzODAAQuHrAYYerPit98HOOlXej/3Nt8\r\nnmKrnQzA7ej1FX87mWxCyJIG5MUAlbHYDHkdWvyOpXrobQFokztA6Kbq8/Rb\r\neBqgBmrAx+tc5ugKvZgUWLqh24UNnWgBnlw=\r\n=8mDE\r\n-----END PGP SIGNATURE-----\r\n"},"main":"gubu.js","type":"commonjs","types":"gubu.d.ts","browser":"gubu.min.js","engines":{"node":">=12"},"gitHead":"3eaf561b780e0e380bd37d007033aac533f0118c","scripts":{"test":"npm run version && jest --coverage","build":"npm run version && tsc -d","clean":"rm -rf node_modules yarn.lock package-lock.json","reset":"npm run clean && npm i && npm run build && npm test","watch":"npm run version && tsc -w -d","version":"node -r fs -e \"v=require('./package.json').version;s=fs.readFileSync('./gubu.ts').toString().replace(/VERSION = '.*?'/,'VERSION = \\''+v+'\\'');fs.writeFileSync('./gubu.ts',s)\"","repo-tag":"REPO_VERSION=`node -e \"console.log(require('./package').version)\"` && echo TAG: v$REPO_VERSION && git commit -a -m v$REPO_VERSION && git push && git tag v$REPO_VERSION && git push --tags;","test-web":"npm run build && npm run build-web && browserify -i util -o test/web.js -e test/entry.js -im && open test/web.html","build-web":"cp gubu.js gubu.min.js && browserify -i util -o gubu.min.js -e gubu.web.js -s Gubu -im -p tinyify","test-pure":"npm run version && jest --coverage --config jest.config.pure.js","test-some":"npm run version && jest -t","test-watch":"npm run version && jest --coverage --watchAll","repo-publish":"npm run clean && npm i && npm run repo-publish-quick","test-some-pure":"npm run version && jest --config jest.config.pure.js -t","repo-publish-quick":"npm run build && npm run test && npm run build-web && npm run test-web && npm run repo-tag && npm publish --access public --registry https://registry.npmjs.org "},"_npmUser":{"name":"rjrodger","email":"richard.rodger@voxgig.com"},"repository":{"url":"git://github.com/rjrodger/gubu.git","type":"git"},"_npmVersion":"8.5.0","description":"An object shape validation utility.","directories":{},"_nodeVersion":"16.14.2","_hasShrinkwrap":false,"devDependencies":{"jest":"^28.1.0","esbuild":"^0.14.39","tinyify":"^3.0.0","ts-jest":"^28.0.2","browserify":"^17.0.0","typescript":"^4.6.4","@types/jest":"^27.5.1","esbuild-jest":"^0.5.0"},"_npmOperationalInternal":{"tmp":"tmp/gubu_3.0.0_1653175792323_0.29275532499782275","host":"s3://npm-registry-packages"}},"3.1.0":{"name":"gubu","version":"3.1.0","keywords":["gubu","schema","validation"],"author":{"url":"http://richardrodger.com","name":"Richard Rodger"},"license":"MIT","_id":"gubu@3.1.0","maintainers":[{"name":"rjrodger","email":"richard.rodger@voxgig.com"}],"homepage":"https://github.com/rjrodger/gubu","bugs":{"url":"https://github.com/rjrodger/gubu/issues"},"dist":{"shasum":"3fd65fc9772a94244e571f9647b5f46f193d1e0e","tarball":"https://registry.npmjs.org/gubu/-/gubu-3.1.0.tgz","fileCount":11,"integrity":"sha512-8VZT2l165iyDBf7PjRtj+g81mZovGz22LL+a74I5SINMwb8t0wzfXa6Ig1Arvbv6pzuxO6MtFDIXR+r6eMb15Q==","signatures":[{"sig":"MEUCIQDhBY6dMokOkDJyJjtNspF7akNZTpPOU8iVTOLPTJYpuAIgLP593eT0InHnOOk8Dzmq3txl0o4QLWYUZIZDG6pm+hA=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":262493,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJirTguACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoU7xAAl3+aCXneV7iW40R9/niuzKJFhvZ/wBgPTrqU5+2jC6k47e2b\r\nu2pIgEasCxfoAqz24fagkwhhrdWXDG2DMY84soZLuLQx3GBAfXo+4JZn3CA6\r\nNXUNgTbFIo07I4E/JEqdezQjAMTIF4OhLfNd0qN9yR2qZNyJU2P1oEe2zxt4\r\nLHn/mpu3iiLBdFnSFQA+Voc4D8Jm6HcoHo4JNeLf8SlLes61Pg7rwhnz7Y66\r\npZyVMNBZ7fyvKGp+5GHwRSkFhfySFBEjdCa7nPNhFhrvdmpQvgodO/3DD2mJ\r\nLfOIGQJ9TrGiwNjBYeFXhfb1N/ZdIPAJ2u3Y3rVNwVUpnCCtdVhNOp6pbvEs\r\nHGIs3Lnwvr0NqEq1IluMEWs5cDtRbhgzphLF/3zoDGifaUlw9+zkWAMIissP\r\ntVCoygjfip4cvgRqlgh2bthtWymWN9uypHcmED/UqqmcWYBaolWq9hKxwqLd\r\nCfxNKIKaVYFshQWOgnqBzfDtXd4wO8wEnHmptkrSsUFjvLcf72XqhmqTrE8b\r\nkTbyppBFpxXgj9wAKRLe/uC8Ltb8cgQgCLIYe3VB0rvYcu3dHQacl9BT2RBr\r\n4s5lFA+rhR76pqmGLMrkynvkw/um5du504e4hFB0SzpnBPXNckhuL3OmWAYq\r\nvK8qXQCKGwr0tZxhYi9qXy1p5vrEToJekXk=\r\n=pWbs\r\n-----END PGP SIGNATURE-----\r\n"},"main":"gubu.js","type":"commonjs","types":"gubu.d.ts","browser":"gubu.min.js","engines":{"node":">=12"},"gitHead":"944ef7175d3bbf87a0792fe42f16c425d92efe34","scripts":{"test":"npm run version && jest --coverage","build":"npm run version && tsc -d","clean":"rm -rf node_modules yarn.lock package-lock.json","reset":"npm run clean && npm i && npm run build && npm test","watch":"npm run version && tsc -w -d","version":"node -r fs -e \"v=require('./package.json').version;s=fs.readFileSync('./gubu.ts').toString();if(!s.includes('VERSION = \\''+v+'\\'')){s=s.replace(/VERSION = '.*?'/,'VERSION = \\''+v+'\\'');fs.writeFileSync('./gubu.ts',s)}\"","repo-tag":"REPO_VERSION=`node -e \"console.log(require('./package').version)\"` && echo TAG: v$REPO_VERSION && git commit -a -m v$REPO_VERSION && git push && git tag v$REPO_VERSION && git push --tags;","test-web":"npm run build && npm run build-web && browserify -i util -o test/web.js -e test/entry.js -im && open test/web.html","build-web":"cp gubu.js gubu.min.js && browserify -i util -o gubu.min.js -e gubu.web.js -s Gubu -im -p tinyify","test-pure":"npm run version && jest --coverage --config jest.config.pure.js","test-some":"npm run version && jest -t","test-watch":"npm run version && jest --coverage --watchAll","repo-publish":"npm run clean && npm i && npm run repo-publish-quick","test-some-pure":"npm run version && jest --config jest.config.pure.js -t","repo-publish-quick":"npm run build && npm run test && npm run build-web && npm run test-web && npm run repo-tag && npm publish --access public --registry https://registry.npmjs.org "},"_npmUser":{"name":"rjrodger","email":"richard.rodger@voxgig.com"},"repository":{"url":"git://github.com/rjrodger/gubu.git","type":"git"},"_npmVersion":"8.5.0","description":"An object shape validation utility.","directories":{},"_nodeVersion":"16.14.2","_hasShrinkwrap":false,"devDependencies":{"jest":"^28.1.1","esbuild":"^0.14.45","tinyify":"^3.0.0","ts-jest":"^28.0.5","browserify":"^17.0.0","typescript":"^4.7.4","@types/jest":"^28.1.2","esbuild-jest":"^0.5.0"},"_npmOperationalInternal":{"tmp":"tmp/gubu_3.1.0_1655519277962_0.4881234540821904","host":"s3://npm-registry-packages"}},"4.0.0":{"name":"gubu","version":"4.0.0","keywords":["gubu","schema","validation"],"author":{"url":"http://richardrodger.com","name":"Richard Rodger"},"license":"MIT","_id":"gubu@4.0.0","maintainers":[{"name":"rjrodger","email":"richard.rodger@voxgig.com"}],"homepage":"https://github.com/rjrodger/gubu","bugs":{"url":"https://github.com/rjrodger/gubu/issues"},"dist":{"shasum":"3f70e33921a1e52fc5ec4903a192355d43d2e226","tarball":"https://registry.npmjs.org/gubu/-/gubu-4.0.0.tgz","fileCount":11,"integrity":"sha512-peS5eEDwGw8wz95zPetmIAU26tT6CfvChr1aQVX5peVXqh+xmmKX9v93t4NZKISfd2+BkWKYejzqzAMRi3qfSQ==","signatures":[{"sig":"MEQCIHMoT/HOQBkADf7DUnhpLhyRhvBMtlvNHNHsz7YkUzCBAiBkXpu2JZTnfNTP3KfB+qFV+KO+oZjRD/mCtchHfNDhvg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":275328,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjETEYACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr6xg//YmKq1stl/ytQVieuMytCLgA606rIuVICOki9Hyd2RoClAs9M\r\nSsVpUrOhm6TmkJAXCNrHz0IhlBOLW2Wnjb+n55oXUkYnenpOfLpxzUHgYY99\r\nsAwoT5E0jW+sksC+V97+9pK4VHMKUOOkBIkjrMlsRqJHZIVLusbVTisF+GHl\r\nECIFT9ZpTfcCc9QrK0/iVJnehGAZzjwI0h1Fe7Xia3zKRrrDXDMB1uNM9+k2\r\n+GiT3+P0LunXEqOu49ui4njhqTXFrnQLfy0h6w4/LOsv0x82cmVYzxiuOb51\r\noEVw8mwkJpjdwr9TAuFfFgDwaJUlMZdvR+o8kf6toWe9RTPWLe9JvDW7UDC6\r\n8x9mdC+9G1rwWA9/Z2YRqMDMeJJiEOaXyFmzofOkFX/gUs3yExuwMaJdgcMP\r\nYNi155H9SUHssK8CCCkysDUwhoacSON/x/lf0dlS6owT7Z2shqJD4PyqBkJ2\r\nxMOs/Qy5C2DXvmn4TpsRz/YUrFfVojq80+zykwmmIMlmP/52PFtlesLXQd2R\r\nJ/NfYNESph3iG7n7a3NwaIjYkG2cq4KL+SvVTMlPLIydvOoh2PMItxUgGcqT\r\nPKW1I2CWjgkwfLeR4t8Emm5ITDVnMWQYVED73sVsGeEHB8BQdJExqP9h3aNU\r\nH3YSuzq78we0L7ue1Best5rEHRHTMx+ETlk=\r\n=DjeY\r\n-----END PGP SIGNATURE-----\r\n"},"main":"gubu.js","type":"commonjs","types":"gubu.d.ts","browser":"gubu.min.js","engines":{"node":">=12"},"gitHead":"23841018ade55ad5665cacf797d8208a24e2fd83","scripts":{"test":"npm run version && jest --coverage","build":"npm run version && tsc -d","clean":"rm -rf node_modules yarn.lock package-lock.json","reset":"npm run clean && npm i && npm run build && npm test","watch":"npm run version && tsc -w -d","version":"node -r fs -e \"v=require('./package.json').version;s=fs.readFileSync('./gubu.ts').toString();if(!s.includes('VERSION = \\''+v+'\\'')){s=s.replace(/VERSION = '.*?'/,'VERSION = \\''+v+'\\'');fs.writeFileSync('./gubu.ts',s)}\"","repo-tag":"REPO_VERSION=`node -e \"console.log(require('./package').version)\"` && echo TAG: v$REPO_VERSION && git commit -a -m v$REPO_VERSION && git push && git tag v$REPO_VERSION && git push --tags;","test-web":"npm run build && npm run build-web && browserify -i util -o test/web.js -e test/entry.js -im && open test/web.html","build-web":"cp gubu.js gubu.min.js && browserify -i util -o gubu.min.js -e gubu.web.js -s Gubu -im -p tinyify","test-pure":"npm run version && jest --coverage --config jest.config.pure.js","test-some":"npm run version && jest -t","test-watch":"npm run version && jest --coverage --watchAll","repo-publish":"npm run clean && npm i && npm run repo-publish-quick","test-some-pure":"npm run version && jest --config jest.config.pure.js -t","repo-publish-quick":"npm run build && npm run test && npm run build-web && npm run test-web && npm run repo-tag && npm publish --access public --registry https://registry.npmjs.org "},"_npmUser":{"name":"rjrodger","email":"richard.rodger@voxgig.com"},"repository":{"url":"git://github.com/rjrodger/gubu.git","type":"git"},"_npmVersion":"8.5.0","description":"An object shape validation utility.","directories":{},"_nodeVersion":"16.14.2","_hasShrinkwrap":false,"devDependencies":{"jest":"^28.1.1","esbuild":"^0.15.6","tinyify":"^3.1.0","ts-jest":"^28.0.8","browserify":"^17.0.0","typescript":"^4.8.2","@types/jest":"^28.1.2","esbuild-jest":"^0.5.0"},"_npmOperationalInternal":{"tmp":"tmp/gubu_4.0.0_1662071063902_0.39618671487036305","host":"s3://npm-registry-packages"}},"5.0.0":{"name":"gubu","version":"5.0.0","keywords":["gubu","schema","validation"],"author":{"url":"http://richardrodger.com","name":"Richard Rodger"},"license":"MIT","_id":"gubu@5.0.0","maintainers":[{"name":"rjrodger","email":"richard.rodger@voxgig.com"}],"homepage":"https://github.com/rjrodger/gubu","bugs":{"url":"https://github.com/rjrodger/gubu/issues"},"dist":{"shasum":"38c8ab741b5d865657d7583dbaa7b986a79420da","tarball":"https://registry.npmjs.org/gubu/-/gubu-5.0.0.tgz","fileCount":11,"integrity":"sha512-6rlJYJ0gk9txKTYpZwTkFtTUJVC0FX4yT8MmD7wcqFGjxsLW/bOWxENeHK5572KY6nKkpONIjjlWtQFb9Q6riA==","signatures":[{"sig":"MEUCIQDZYhsZUi/cE1x6GCzIgmwFd4xHPOibY2k+erNND9+9NwIgRFAOrwnKWLN3MGwkwRmZuv3qTD/8T0x3rzjzM2oEDZk=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":285618,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkOZmnACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmooJw/+JizzxEh2tYlzZ7ceRgY4KMy74ku/iMCixvMrIWFGFLidyD4g\r\nuBIAJWuDRcgsj7mtf+J1xennKhMoGjTrEHDSihwI7bbWe3x0AC5QzGyc7O1x\r\nJQdgehAGpOmWcWAm/2VBFiBawflqVXQhgeS500deT7b6lZEEyWsJhi4p86KO\r\nN4cr8axT04RKdGnD8GTx2wha7gCg7zSO2pq40LgwU4N9Fe8fAwJqrpqA7m1u\r\nE7IUDdMYT3sTXx1jkUXfME0f9NINXwG+luDXs6frDBevlJjHU3HVRtvxJFhL\r\nFhlVo6WZ+PgxnS6QoDCH/uU2cCao4iEYslb+iGMuWsCzfa/s2sIAJ1QeWRRZ\r\nyG1x5dDCqZZNPV1+hVQBfTvaRKXoyDu5sfTmUZtJZKQMgh7YXSEyjVQ22i/3\r\n1o+BvphUggbngUA6F1jFn9h9xrkI8gZ1GmlIvVz6iXkhzVEGLM/E5TUEj0QW\r\nmpMVAeU59U5OSG5ZQqnnAe9ZprjpEOGkS7v5OM5qYDHiXMQJMXDrRDQxvEuU\r\nO6iHlIiELZFwo22rZLcq5J/ixc1hJc8jTpuOT+kGievl1XgxyoPdxf/lSmt3\r\nQk7gFIRCKHIWJC0M8xo+fyQV+GPSx3CUP9+N40nVwRoa71a0eWPOcdvzUT7O\r\nHPk6okm3Qo+yhPBQBvOxacUzmZjxMs6nRMI=\r\n=iGcx\r\n-----END PGP SIGNATURE-----\r\n"},"main":"gubu.js","type":"commonjs","types":"gubu.d.ts","browser":"gubu.min.js","engines":{"node":">=12"},"gitHead":"cf01266fc0c20bea91bea290245f48993234b2df","scripts":{"test":"npm run version && jest --coverage","build":"npm run version && tsc -d","clean":"rm -rf node_modules yarn.lock package-lock.json","reset":"npm run clean && npm i && npm run build && npm test","watch":"npm run version && tsc -w -d","version":"node -r fs -e \"v=require('./package.json').version;s=fs.readFileSync('./gubu.ts').toString();if(!s.includes('VERSION = \\''+v+'\\'')){s=s.replace(/VERSION = '.*?'/,'VERSION = \\''+v+'\\'');fs.writeFileSync('./gubu.ts',s)}\"","repo-tag":"REPO_VERSION=`node -e \"console.log(require('./package').version)\"` && echo TAG: v$REPO_VERSION && git commit -a -m v$REPO_VERSION && git push && git tag v$REPO_VERSION && git push --tags;","test-web":"npm run build && npm run build-web && browserify -i util -o test/web.js -e test/entry.js -im && open test/web.html","build-web":"cp gubu.js gubu.min.js && browserify -i util -o gubu.min.js -e gubu.web.js -s Gubu -im -p tinyify","test-pure":"npm run version && jest --coverage --config jest.config.pure.js","test-some":"npm run version && jest -t","test-watch":"npm run version && jest --coverage --watchAll","repo-publish":"npm run clean && npm i && npm run repo-publish-quick","test-some-pure":"npm run version && jest --config jest.config.pure.js -t","repo-publish-quick":"npm run build && npm run test && npm run build-web && npm run test-web && npm run repo-tag && npm publish --access public --registry https://registry.npmjs.org "},"_npmUser":{"name":"rjrodger","email":"richard.rodger@voxgig.com"},"repository":{"url":"git://github.com/rjrodger/gubu.git","type":"git"},"_npmVersion":"8.5.0","description":"An object shape validation utility.","directories":{},"_nodeVersion":"16.14.2","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","esbuild":"^0.17.16","tinyify":"^4.0.0","ts-jest":"^29.1.0","browserify":"^17.0.0","typescript":"^5.0.4","@types/jest":"^29.5.0","esbuild-jest":"^0.5.0"},"_npmOperationalInternal":{"tmp":"tmp/gubu_5.0.0_1681496487182_0.15935485671305072","host":"s3://npm-registry-packages"}},"5.0.1":{"name":"gubu","version":"5.0.1","keywords":["gubu","schema","validation"],"author":{"url":"http://richardrodger.com","name":"Richard Rodger"},"license":"MIT","_id":"gubu@5.0.1","maintainers":[{"name":"rjrodger","email":"richard.rodger@voxgig.com"}],"homepage":"https://github.com/rjrodger/gubu","bugs":{"url":"https://github.com/rjrodger/gubu/issues"},"dist":{"shasum":"64d702ac5ea4f56f14607eb0b4ada104e3ba2a20","tarball":"https://registry.npmjs.org/gubu/-/gubu-5.0.1.tgz","fileCount":11,"integrity":"sha512-+mW/JMKYSriAT6VZEaoo+Invl2IDIrKjyRCrwIfvJ2KeUvDXZLCH7UzaBk3gZZHkoQxbKx0+AR20kS1oyADCgQ==","signatures":[{"sig":"MEQCIFl9fIf4Zt6i8x6Q4UfdBv7fWozPJ/1coUPqdX9VVezlAiBubFOcaBj5vC1fSd50KKbUMINkiKg33BoOI920gjdzMg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":285795},"main":"gubu.js","type":"commonjs","types":"gubu.d.ts","browser":"gubu.min.js","engines":{"node":">=12"},"gitHead":"82d6a1c3914af0f21c2886ee1c783f61e307b704","scripts":{"test":"npm run version && jest --coverage","build":"npm run version && tsc -d","clean":"rm -rf node_modules yarn.lock package-lock.json","reset":"npm run clean && npm i && npm run build && npm test","watch":"npm run version && tsc -w -d","version":"node -r fs -e \"v=require('./package.json').version;s=fs.readFileSync('./gubu.ts').toString();if(!s.includes('VERSION = \\''+v+'\\'')){s=s.replace(/VERSION = '.*?'/,'VERSION = \\''+v+'\\'');fs.writeFileSync('./gubu.ts',s)}\"","repo-tag":"REPO_VERSION=`node -e \"console.log(require('./package').version)\"` && echo TAG: v$REPO_VERSION && git commit -a -m v$REPO_VERSION && git push && git tag v$REPO_VERSION && git push --tags;","test-web":"npm run build && npm run build-web && browserify -i util -o test/web.js -e test/entry.js -im && open test/web.html","build-web":"cp gubu.js gubu.min.js && browserify -i util -o gubu.min.js -e gubu.web.js -s Gubu -im -p tinyify","test-pure":"npm run version && jest --coverage --config jest.config.pure.js","test-some":"npm run version && jest -t","test-watch":"npm run version && jest --coverage --watchAll","repo-publish":"npm run clean && npm i && npm run repo-publish-quick","test-some-pure":"npm run version && jest --config jest.config.pure.js -t","repo-publish-quick":"npm run build && npm run test && npm run build-web && npm run test-web && npm run repo-tag && npm publish --access public --registry https://registry.npmjs.org "},"_npmUser":{"name":"rjrodger","email":"richard.rodger@voxgig.com"},"repository":{"url":"git://github.com/rjrodger/gubu.git","type":"git"},"_npmVersion":"8.5.0","description":"An object shape validation utility.","directories":{},"_nodeVersion":"16.14.2","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","esbuild":"^0.17.19","tinyify":"^4.0.0","ts-jest":"^29.1.0","browserify":"^17.0.0","typescript":"^5.0.4","@types/jest":"^29.5.1","esbuild-jest":"^0.5.0"},"_npmOperationalInternal":{"tmp":"tmp/gubu_5.0.1_1685539594423_0.3105997785300254","host":"s3://npm-registry-packages"}},"6.0.1":{"name":"gubu","version":"6.0.1","keywords":["gubu","schema","validation"],"author":{"url":"http://richardrodger.com","name":"Richard Rodger"},"license":"MIT","_id":"gubu@6.0.1","maintainers":[{"name":"rjrodger","email":"richard.rodger@voxgig.com"}],"homepage":"https://github.com/rjrodger/gubu","bugs":{"url":"https://github.com/rjrodger/gubu/issues"},"dist":{"shasum":"cfe997f63c867fb4a48a0d52aa16fcad62f0f109","tarball":"https://registry.npmjs.org/gubu/-/gubu-6.0.1.tgz","fileCount":11,"integrity":"sha512-lWLXluBdR/L1rryvRZk2LDs5CI4i+rP8FgLPZ+gQmIvsjqBmC1T0sApYMnrco6Supl4Rx/qT80rYJgdyZ1ktfA==","signatures":[{"sig":"MEQCID35onzCBZquUVsm8oKNw8P9uP3dIgh03E02uoEncpnoAiArQGltIdQ4EI+s6LIbxABnn1ngM+z5RDkXPutqC7c9SQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":324774},"main":"gubu.js","type":"commonjs","types":"gubu.d.ts","browser":"gubu.min.js","engines":{"node":">=14"},"gitHead":"0dace11bcca422e190ca975a07229fd5da3f7aff","scripts":{"test":"npm run version && jest --coverage","build":"npm run version && tsc -d","clean":"rm -rf node_modules yarn.lock package-lock.json","reset":"npm run clean && npm i && npm run build && npm test","watch":"npm run version && tsc -w -d","version":"node -r fs -e \"v=require('./package.json').version;s=fs.readFileSync('./gubu.ts').toString();if(!s.includes('VERSION = \\''+v+'\\'')){s=s.replace(/VERSION = '.*?'/,'VERSION = \\''+v+'\\'');fs.writeFileSync('./gubu.ts',s)}\"","repo-tag":"REPO_VERSION=`node -e \"console.log(require('./package').version)\"` && echo TAG: v$REPO_VERSION && git commit -a -m v$REPO_VERSION && git push && git tag v$REPO_VERSION && git push --tags;","test-web":"npm run build && npm run build-web && browserify -i util -o test/web.js -e test/entry.js -im && open test/web.html","build-web":"cp gubu.js gubu.min.js && browserify -i util -o gubu.min.js -e gubu.web.js -s Gubu -im -p tinyify","test-pure":"npm run version && jest --coverage --config jest.config.pure.js","test-some":"npm run version && jest -t","test-watch":"npm run version && jest --coverage --watchAll","repo-publish":"npm run clean && npm i && npm run repo-publish-quick","test-some-pure":"npm run version && jest --config jest.config.pure.js -t","repo-publish-quick":"npm run build && npm run test && npm run build-web && npm run test-web && npm run repo-tag && npm publish --access public --registry https://registry.npmjs.org "},"_npmUser":{"name":"rjrodger","email":"richard.rodger@voxgig.com"},"repository":{"url":"git://github.com/rjrodger/gubu.git","type":"git"},"_npmVersion":"8.5.0","description":"An object shape validation utility.","directories":{},"_nodeVersion":"16.14.2","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","es-jest":"^2.1.0","esbuild":"^0.19.5","tinyify":"^4.0.0","ts-jest":"^29.1.1","browserify":"^17.0.0","typescript":"^5.2.2","@types/jest":"^29.5.7","esbuild-jest":"^0.5.0"},"_npmOperationalInternal":{"tmp":"tmp/gubu_6.0.1_1698891300087_0.06195310650593844","host":"s3://npm-registry-packages"}},"7.0.0":{"name":"gubu","version":"7.0.0","keywords":["gubu","schema","validation"],"author":{"url":"http://richardrodger.com","name":"Richard Rodger"},"license":"MIT","_id":"gubu@7.0.0","maintainers":[{"name":"rjrodger","email":"richard.rodger@voxgig.com"}],"homepage":"https://github.com/rjrodger/gubu","bugs":{"url":"https://github.com/rjrodger/gubu/issues"},"dist":{"shasum":"2d4e1cc5eba4745ac09424455909e53eba86e826","tarball":"https://registry.npmjs.org/gubu/-/gubu-7.0.0.tgz","fileCount":11,"integrity":"sha512-rweqG/nL/wKd1QTN6e8jwsQ6S1aoXPMF3KPeWCNEmSC2emNKvVuUbvU7B+1tAm7x8/4EiLjakUm3+lAEkqD7Nw==","signatures":[{"sig":"MEUCIQD7jtcK0Pu/5njQNLv2jvvs3fJ2Up9rLanhUCvdw6TP6QIgLKXnrV1NGCnGdzNQfKRlfD3aLXZO68jnznK5iy+SD6M=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":334195},"main":"gubu.js","type":"commonjs","types":"gubu.d.ts","browser":"gubu.min.js","engines":{"node":">=14"},"gitHead":"d2f059bac4045cb5a946529e2b025d27b428bf1f","scripts":{"test":"npm run version && jest --coverage","build":"npm run version && tsc -d","clean":"rm -rf node_modules yarn.lock package-lock.json","reset":"npm run clean && npm i && npm run build && npm test","watch":"npm run version && tsc -w -d","version":"node -r fs -e \"v=require('./package.json').version;s=fs.readFileSync('./gubu.ts').toString();if(!s.includes('VERSION = \\''+v+'\\'')){s=s.replace(/VERSION = '.*?'/,'VERSION = \\''+v+'\\'');fs.writeFileSync('./gubu.ts',s)}\"","repo-tag":"REPO_VERSION=`node -e \"console.log(require('./package').version)\"` && echo TAG: v$REPO_VERSION && git commit -a -m v$REPO_VERSION && git push && git tag v$REPO_VERSION && git push --tags;","test-web":"npm run build && npm run build-web && browserify -i util -o test/web.js -e test/entry.js -im && open test/web.html","build-web":"cp gubu.js gubu.min.js && browserify -i util -o gubu.min.js -e gubu.web.js -s Gubu -im -p tinyify","test-pure":"npm run version && jest --coverage --config jest.config.pure.js","test-some":"npm run version && jest -t","test-watch":"npm run version && jest --coverage --watchAll","repo-publish":"npm run clean && npm i && npm run repo-publish-quick","test-some-pure":"npm run version && jest --config jest.config.pure.js -t","repo-publish-quick":"npm run build && npm run test && npm run build-web && npm run test-web && npm run repo-tag && npm publish --access public --registry https://registry.npmjs.org "},"_npmUser":{"name":"rjrodger","email":"richard.rodger@voxgig.com"},"repository":{"url":"git://github.com/rjrodger/gubu.git","type":"git"},"_npmVersion":"8.19.4","description":"An object shape validation utility.","directories":{},"_nodeVersion":"16.20.2","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","es-jest":"^2.1.0","esbuild":"^0.19.11","tinyify":"^4.0.0","ts-jest":"^29.1.1","browserify":"^17.0.0","typescript":"^5.3.3","@types/jest":"^29.5.11","esbuild-jest":"^0.5.0"},"_npmOperationalInternal":{"tmp":"tmp/gubu_7.0.0_1705089146115_0.4554781017580942","host":"s3://npm-registry-packages"}},"7.1.0":{"name":"gubu","version":"7.1.0","keywords":["gubu","schema","validation"],"author":{"url":"http://richardrodger.com","name":"Richard Rodger"},"license":"MIT","_id":"gubu@7.1.0","maintainers":[{"name":"rjrodger","email":"richard.rodger@voxgig.com"}],"homepage":"https://github.com/rjrodger/gubu","bugs":{"url":"https://github.com/rjrodger/gubu/issues"},"dist":{"shasum":"884da9425543c6c7f9d13673713fdcaa9672d263","tarball":"https://registry.npmjs.org/gubu/-/gubu-7.1.0.tgz","fileCount":11,"integrity":"sha512-0wWSbGqQ4TEVsc40OqH/ZwsJrp16I5jYQ96Pycui1gwDC+htmwfwmoV9k9tIZ+Mmg9DDkeetWybCLY7gpxxeRQ==","signatures":[{"sig":"MEQCICwhQFD5WRwseqpjJOfZqs1WeMwzxsvbJfsJIZwgG5m1AiAwJp5+QoYITHmiqh9f8pyW+Uo3RruGuFAY3dhQWM7X+w==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":334130},"main":"gubu.js","type":"commonjs","types":"gubu.d.ts","browser":"gubu.min.js","engines":{"node":">=14"},"gitHead":"1cb68309bb40ac1539b74f547a5f5265461024e3","scripts":{"test":"npm run version && jest --coverage","build":"npm run version && tsc -d","clean":"rm -rf node_modules yarn.lock package-lock.json","reset":"npm run clean && npm i && npm run build && npm test","watch":"npm run version && tsc -w -d","version":"node -r fs -e \"v=require('./package.json').version;s=fs.readFileSync('./gubu.ts').toString();if(!s.includes('VERSION = \\''+v+'\\'')){s=s.replace(/VERSION = '.*?'/,'VERSION = \\''+v+'\\'');fs.writeFileSync('./gubu.ts',s)}\"","repo-tag":"REPO_VERSION=`node -e \"console.log(require('./package').version)\"` && echo TAG: v$REPO_VERSION && git commit -a -m v$REPO_VERSION && git push && git tag v$REPO_VERSION && git push --tags;","test-web":"npm run build && npm run build-web && browserify -i util -o test/web.js -e test/entry.js -im && open test/web.html","build-web":"cp gubu.js gubu.min.js && browserify -i util -o gubu.min.js -e gubu.web.js -s Gubu -im -p tinyify","test-pure":"npm run version && jest --coverage --config jest.config.pure.js","test-some":"npm run version && jest -t","test-watch":"npm run version && jest --coverage --watchAll","repo-publish":"npm run clean && npm i && npm run repo-publish-quick","test-some-pure":"npm run version && jest --config jest.config.pure.js -t","repo-publish-quick":"npm run build && npm run test && npm run build-web && npm run test-web && npm run repo-tag && npm publish --access public --registry https://registry.npmjs.org "},"_npmUser":{"name":"rjrodger","email":"richard.rodger@voxgig.com"},"repository":{"url":"git://github.com/rjrodger/gubu.git","type":"git"},"_npmVersion":"10.2.4","description":"An object shape validation utility.","directories":{},"_nodeVersion":"20.11.1","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","es-jest":"^2.1.0","esbuild":"^0.21.4","tinyify":"^4.0.0","ts-jest":"^29.1.4","browserify":"^17.0.0","typescript":"^5.4.5","@types/jest":"^29.5.12","esbuild-jest":"^0.5.0"},"_npmOperationalInternal":{"tmp":"tmp/gubu_7.1.0_1717593746513_0.8676143915603136","host":"s3://npm-registry-packages"}},"7.1.1":{"name":"gubu","version":"7.1.1","keywords":["gubu","schema","validation"],"author":{"url":"http://richardrodger.com","name":"Richard Rodger"},"license":"MIT","_id":"gubu@7.1.1","maintainers":[{"name":"rjrodger","email":"richard.rodger@voxgig.com"}],"homepage":"https://github.com/rjrodger/gubu","bugs":{"url":"https://github.com/rjrodger/gubu/issues"},"dist":{"shasum":"955281cca75414ea05f59e42646fcb6198627529","tarball":"https://registry.npmjs.org/gubu/-/gubu-7.1.1.tgz","fileCount":11,"integrity":"sha512-e/t3VD80epShShcOQRPB5qC8mTw9JNggQZnF9ljKCbedRohzylSWV0UuuVPg0UiAqls8TbAbF4c3TsNdZ30lBg==","signatures":[{"sig":"MEUCICQ2iyCYQyyM+vdn9pA+1GrEsMBoUUy+MA4Lo5/DikuHAiEAzf/79+S+XcNbcPvFplikxHMR8LLk+4B7tOODFsNmA1o=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":334245},"main":"gubu.js","type":"commonjs","types":"gubu.d.ts","browser":"gubu.min.js","engines":{"node":">=14"},"gitHead":"bea24147034075273abe302ae46e82f3fd023525","scripts":{"test":"npm run version && jest --coverage","build":"npm run version && tsc -d","clean":"rm -rf node_modules yarn.lock package-lock.json","reset":"npm run clean && npm i && npm run build && npm test","watch":"npm run version && tsc -w -d","version":"node -r fs -e \"v=require('./package.json').version;s=fs.readFileSync('./gubu.ts').toString();if(!s.includes('VERSION = \\''+v+'\\'')){s=s.replace(/VERSION = '.*?'/,'VERSION = \\''+v+'\\'');fs.writeFileSync('./gubu.ts',s)}\"","repo-tag":"REPO_VERSION=`node -e \"console.log(require('./package').version)\"` && echo TAG: v$REPO_VERSION && git commit -a -m v$REPO_VERSION && git push && git tag v$REPO_VERSION && git push --tags;","test-web":"npm run build && npm run build-web && browserify -i util -o test/web.js -e test/entry.js -im && open test/web.html","build-web":"cp gubu.js gubu.min.js && browserify -i util -o gubu.min.js -e gubu.web.js -s Gubu -im -p tinyify","test-pure":"npm run version && jest --coverage --config jest.config.pure.js","test-some":"npm run version && jest -t","test-watch":"npm run version && jest --coverage --watchAll","repo-publish":"npm run clean && npm i && npm run repo-publish-quick","test-some-pure":"npm run version && jest --config jest.config.pure.js -t","repo-publish-quick":"npm run build && npm run test && npm run build-web && npm run test-web && npm run repo-tag && npm publish --access public --registry https://registry.npmjs.org "},"_npmUser":{"name":"rjrodger","email":"richard.rodger@voxgig.com"},"repository":{"url":"git://github.com/rjrodger/gubu.git","type":"git"},"_npmVersion":"10.2.4","description":"An object shape validation utility.","directories":{},"_nodeVersion":"20.11.1","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","es-jest":"^2.1.0","esbuild":"^0.21.5","tinyify":"^4.0.0","ts-jest":"^29.1.4","browserify":"^17.0.0","typescript":"^5.4.5","@types/jest":"^29.5.12","esbuild-jest":"^0.5.0"},"_npmOperationalInternal":{"tmp":"tmp/gubu_7.1.1_1718102292819_0.2967718606417724","host":"s3://npm-registry-packages"}},"8.0.1":{"name":"gubu","version":"8.0.1","keywords":["gubu","schema","validation"],"author":{"url":"http://richardrodger.com","name":"Richard Rodger"},"license":"MIT","_id":"gubu@8.0.1","maintainers":[{"name":"rjrodger","email":"richard.rodger@voxgig.com"}],"homepage":"https://github.com/rjrodger/gubu","bugs":{"url":"https://github.com/rjrodger/gubu/issues"},"dist":{"shasum":"667ff5d3ff8605bea247f8c62d5296854ba115ba","tarball":"https://registry.npmjs.org/gubu/-/gubu-8.0.1.tgz","fileCount":11,"integrity":"sha512-bPryzSL8ft2J4PG453jKjynK+wtEWEpJFw432UboEQ//z927NnWvCGWkCmvq6ZFmNjRN/3qwL/oMFHnwdeG0fQ==","signatures":[{"sig":"MEQCIEkKWHXsvqDX0KETUXmauD/1Oke9scoIAFD83hUgCNr4AiAzOuTbHUURYrnxlf+N3Lp8tWYfruK0912TC29NjkIYBA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":447883},"main":"gubu.js","type":"commonjs","types":"gubu.d.ts","browser":"gubu.min.js","engines":{"node":">=14"},"gitHead":"ad56e105efa6254c479ec9505052125bc75c4691","scripts":{"test":"npm run version && jest --coverage","build":"npm run version && tsc -d","clean":"rm -rf node_modules yarn.lock package-lock.json","reset":"npm run clean && npm i && npm run build && npm test","watch":"npm run version && tsc -w -d","version":"node -r fs -e \"v=require('./package.json').version;s=fs.readFileSync('./gubu.ts').toString();if(!s.includes('VERSION = \\''+v+'\\'')){s=s.replace(/VERSION = '.*?'/,'VERSION = \\''+v+'\\'');fs.writeFileSync('./gubu.ts',s)}\"","repo-tag":"REPO_VERSION=`node -e \"console.log(require('./package').version)\"` && echo TAG: v$REPO_VERSION && git commit -a -m v$REPO_VERSION && git push && git tag v$REPO_VERSION && git push --tags;","test-web":"npm run build && npm run build-web && browserify -i util -o test/web.js -e test/entry.js -im && open test/web.test.html","build-web":"cp gubu.js gubu.min.js && browserify -i util -o gubu.min.js -e gubu.web.js -s Gubu -im","test-pure":"npm run version && jest --coverage --config jest.config.pure.js","test-some":"npm run version && jest -t","test-watch":"npm run version && jest --coverage --watchAll","repo-publish":"npm run clean && npm i && npm run repo-publish-quick","test-some-pure":"npm run version && jest --config jest.config.pure.js -t","repo-publish-quick":"npm run build && npm run test && npm run build-web && npm run test-web && npm run repo-tag && npm publish --access public --registry https://registry.npmjs.org "},"_npmUser":{"name":"rjrodger","email":"richard.rodger@voxgig.com"},"overrides":{"acorn":"8.12.1"},"repository":{"url":"git://github.com/rjrodger/gubu.git","type":"git"},"_npmVersion":"10.2.4","description":"An object shape validation utility.","directories":{},"_nodeVersion":"20.11.1","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","vite":"^5.2.8","es-jest":"^2.1.0","esbuild":"^0.23.0","tinyify":"^4.0.0","ts-jest":"^29.1.5","browserify":"^17.0.0","typescript":"^5.5.3","@types/jest":"^29.5.12","esbuild-jest":"^0.5.0","vite-plugin-commonjs":"^0.10.1","@rollup/plugin-commonjs":"^26.0.1"},"_npmOperationalInternal":{"tmp":"tmp/gubu_8.0.1_1720172648124_0.7097824234240251","host":"s3://npm-registry-packages"}},"8.0.2":{"name":"gubu","version":"8.0.2","keywords":["gubu","schema","validation"],"author":{"url":"http://richardrodger.com","name":"Richard Rodger"},"license":"MIT","_id":"gubu@8.0.2","maintainers":[{"name":"rjrodger","email":"richard.rodger@voxgig.com"}],"homepage":"https://github.com/rjrodger/gubu","bugs":{"url":"https://github.com/rjrodger/gubu/issues"},"dist":{"shasum":"b40eb193283583bcfaa288894ac15c110a72fc0a","tarball":"https://registry.npmjs.org/gubu/-/gubu-8.0.2.tgz","fileCount":11,"integrity":"sha512-N62ZP/WQGZ7rVMNKzwO3dCmXm7F8EpO05ECchrkiK3qn8erWQITFcB3vCKe0SJ92JY7162eP2NM9AWpTz4Erdw==","signatures":[{"sig":"MEUCIQDvK2iKzrDE8ZmDoJqiXc9g+mbv1xFtjFFZalc5SgNERAIgGTwIuNJ/fogukmW3DetQV1wmJQb1o+oC1i/CYFrSzFw=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":389994},"main":"gubu.js","type":"commonjs","types":"gubu.d.ts","browser":"gubu.min.js","engines":{"node":">=14"},"gitHead":"9c80615f46a00115aa557779e7f215410f54497e","scripts":{"test":"npm run version && jest --coverage","build":"npm run version && tsc -d","clean":"rm -rf node_modules yarn.lock package-lock.json","reset":"npm run clean && npm i && npm run build && npm test","watch":"npm run version && tsc -w -d","version":"node -r fs -e \"v=require('./package.json').version;s=fs.readFileSync('./gubu.ts').toString();if(!s.includes('VERSION = \\''+v+'\\'')){s=s.replace(/VERSION = '.*?'/,'VERSION = \\''+v+'\\'');fs.writeFileSync('./gubu.ts',s)}\"","repo-tag":"REPO_VERSION=`node -e \"console.log(require('./package').version)\"` && echo TAG: v$REPO_VERSION && git commit -a -m v$REPO_VERSION && git push && git tag v$REPO_VERSION && git push --tags;","test-web":"npm run build && npm run build-web && browserify -i util -o test/web.js -e test/entry.js -im && open test/web.test.html","build-web":"cp gubu.js gubu.min.js && browserify -i util -o gubu.min.js -e gubu.web.js -s Gubu -im -p tinyify","test-pure":"npm run version && jest --coverage --config jest.config.pure.js","test-some":"npm run version && jest -t","test-watch":"npm run version && jest --coverage --watchAll","repo-publish":"npm run clean && npm i && npm run repo-publish-quick","test-some-pure":"npm run version && jest --config jest.config.pure.js -t","repo-publish-quick":"npm run build && npm run test && npm run build-web && npm run test-web && npm run repo-tag && npm publish --access public --registry https://registry.npmjs.org "},"_npmUser":{"name":"rjrodger","email":"richard.rodger@voxgig.com"},"overrides":{"acorn":"8.12.1"},"repository":{"url":"git://github.com/rjrodger/gubu.git","type":"git"},"_npmVersion":"10.2.4","description":"An object shape validation utility.","directories":{},"_nodeVersion":"20.11.1","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","vite":"^5.2.8","es-jest":"^2.1.0","esbuild":"^0.23.0","tinyify":"^4.0.0","ts-jest":"^29.1.5","browserify":"^17.0.0","typescript":"^5.5.3","@types/jest":"^29.5.12","esbuild-jest":"^0.5.0","vite-plugin-commonjs":"^0.10.1","@rollup/plugin-commonjs":"^26.0.1"},"_npmOperationalInternal":{"tmp":"tmp/gubu_8.0.2_1720181131341_0.3336805075929734","host":"s3://npm-registry-packages"}},"8.1.0":{"name":"gubu","version":"8.1.0","keywords":["gubu","schema","validation"],"author":{"url":"http://richardrodger.com","name":"Richard Rodger"},"license":"MIT","_id":"gubu@8.1.0","maintainers":[{"name":"rjrodger","email":"richard.rodger@voxgig.com"}],"homepage":"https://github.com/rjrodger/gubu","bugs":{"url":"https://github.com/rjrodger/gubu/issues"},"dist":{"shasum":"d18a9782e5ebed50b52e3f8b2cbc74705a11e63d","tarball":"https://registry.npmjs.org/gubu/-/gubu-8.1.0.tgz","fileCount":11,"integrity":"sha512-u+PC5oLH6hORwzDpmsXfMvP8+KMf5nEqpDc9CO9ImzHp4qun9zEqryOzrXOiCcuG8j3110NXH538JOobBI53/w==","signatures":[{"sig":"MEYCIQCJQVPJNuwgc8ulvHXGdyaValJ5vKB8wsSekYxI9uaJBwIhAOfRzFZYNy1F5wK5lQaqvD97e0Ij/F3ztvYB7Jk5RQRf","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":381685},"main":"gubu.js","type":"commonjs","types":"gubu.d.ts","browser":"gubu.min.js","engines":{"node":">=14"},"gitHead":"fb5db09aa4e6bd63bcb6b8251897fb0a6b224c5a","scripts":{"test":"npm run version && jest --coverage","build":"npm run version && tsc -d","clean":"rm -rf node_modules yarn.lock package-lock.json","reset":"npm run clean && npm i && npm run build && npm test","watch":"npm run version && tsc -w -d","version":"node -r fs -e \"v=require('./package.json').version;s=fs.readFileSync('./gubu.ts').toString();if(!s.includes('VERSION = \\''+v+'\\'')){s=s.replace(/VERSION = '.*?'/,'VERSION = \\''+v+'\\'');fs.writeFileSync('./gubu.ts',s)}\"","repo-tag":"REPO_VERSION=`node -e \"console.log(require('./package').version)\"` && echo TAG: v$REPO_VERSION && git commit -a -m v$REPO_VERSION && git push && git tag v$REPO_VERSION && git push --tags;","test-web":"npm run build && npm run build-web && browserify -i util -o test/web.js -e test/entry.js -im && open test/web.test.html","build-web":"cp gubu.js gubu.min.js && browserify -i util -o gubu.min.js -e gubu.web.js -s Gubu -im -p tinyify","test-pure":"npm run version && jest --coverage --config jest.config.pure.js","test-some":"npm run version && jest -t","test-watch":"npm run version && jest --coverage --watchAll","repo-publish":"npm run clean && npm i && npm run repo-publish-quick","test-some-pure":"npm run version && jest --config jest.config.pure.js -t","repo-publish-quick":"npm run build && npm run test && npm run build-web && npm run test-web && npm run repo-tag && npm publish --access public --registry https://registry.npmjs.org "},"_npmUser":{"name":"rjrodger","email":"richard.rodger@voxgig.com"},"overrides":{"acorn":"8.12.1"},"repository":{"url":"git://github.com/rjrodger/gubu.git","type":"git"},"_npmVersion":"10.2.4","description":"An object shape validation utility.","directories":{},"_nodeVersion":"20.11.1","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","vite":"^5.3.3","es-jest":"^2.1.0","esbuild":"^0.23.0","tinyify":"^4.0.0","ts-jest":"^29.2.2","browserify":"^17.0.0","typescript":"^5.5.3","@types/jest":"^29.5.12","esbuild-jest":"^0.5.0","vite-plugin-commonjs":"^0.10.1","@rollup/plugin-commonjs":"^26.0.1"},"_npmOperationalInternal":{"tmp":"tmp/gubu_8.1.0_1720698744381_0.720702232771709","host":"s3://npm-registry-packages"}},"8.2.0":{"name":"gubu","version":"8.2.0","keywords":["gubu","schema","validation"],"author":{"url":"http://richardrodger.com","name":"Richard Rodger"},"license":"MIT","_id":"gubu@8.2.0","maintainers":[{"name":"rjrodger","email":"richard.rodger@voxgig.com"}],"homepage":"https://github.com/rjrodger/gubu","bugs":{"url":"https://github.com/rjrodger/gubu/issues"},"dist":{"shasum":"2def0b5a248dcfe33e369052244e6a8af8e68bb6","tarball":"https://registry.npmjs.org/gubu/-/gubu-8.2.0.tgz","fileCount":11,"integrity":"sha512-oV9nAypKXVt4lyfK1D5/j/gtAJpqX4eFv5OjjM2lVMUOsfKc02MvHYEhmzUM0IEz0XteSfuMeXa3ENCIIKjfrA==","signatures":[{"sig":"MEQCICIF2i20oDJzRkUuAkqjBlzQ/1K59xe4csBe+s/qi119AiAiLp6B0yzyg8PAdxpuyyFZzu0i5fpZ5Fan5pyJlRpjtQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":382044},"main":"gubu.js","type":"commonjs","types":"gubu.d.ts","browser":"gubu.min.js","engines":{"node":">=14"},"gitHead":"3849d330d26dbda34d3c3dd549238bf1584939c0","scripts":{"test":"npm run version && jest --coverage","build":"npm run version && tsc -d","clean":"rm -rf node_modules yarn.lock package-lock.json","reset":"npm run clean && npm i && npm run build && npm test","watch":"npm run version && tsc -w -d","version":"node -r fs -e \"v=require('./package.json').version;s=fs.readFileSync('./gubu.ts').toString();if(!s.includes('VERSION = \\''+v+'\\'')){s=s.replace(/VERSION = '.*?'/,'VERSION = \\''+v+'\\'');fs.writeFileSync('./gubu.ts',s)}\"","repo-tag":"REPO_VERSION=`node -e \"console.log(require('./package').version)\"` && echo TAG: v$REPO_VERSION && git commit -a -m v$REPO_VERSION && git push && git tag v$REPO_VERSION && git push --tags;","test-web":"npm run build && npm run build-web && browserify -i util -o test/web.js -e test/entry.js -im && open test/web.test.html","build-web":"cp gubu.js gubu.min.js && browserify -i util -o gubu.min.js -e gubu.web.js -s Gubu -im -p tinyify","test-pure":"npm run version && jest --coverage --config jest.config.pure.js","test-some":"npm run version && jest -t","test-watch":"npm run version && jest --coverage --watchAll","repo-publish":"npm run clean && npm i && npm run repo-publish-quick","test-some-pure":"npm run version && jest --config jest.config.pure.js -t","repo-publish-quick":"npm run build && npm run test && npm run build-web && npm run test-web && npm run repo-tag && npm publish --access public --registry https://registry.npmjs.org "},"_npmUser":{"name":"rjrodger","email":"richard.rodger@voxgig.com"},"overrides":{"acorn":"8.12.1"},"repository":{"url":"git://github.com/rjrodger/gubu.git","type":"git"},"_npmVersion":"10.2.4","description":"An object shape validation utility.","directories":{},"_nodeVersion":"20.11.1","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","vite":"^5.3.3","es-jest":"^2.1.0","esbuild":"^0.23.0","tinyify":"^4.0.0","ts-jest":"^29.2.2","browserify":"^17.0.0","typescript":"^5.5.3","@types/jest":"^29.5.12","esbuild-jest":"^0.5.0","vite-plugin-commonjs":"^0.10.1","@rollup/plugin-commonjs":"^26.0.1"},"_npmOperationalInternal":{"tmp":"tmp/gubu_8.2.0_1720795605712_0.48298496090393805","host":"s3://npm-registry-packages"}},"8.2.1":{"name":"gubu","version":"8.2.1","keywords":["gubu","schema","validation"],"author":{"url":"http://richardrodger.com","name":"Richard Rodger"},"license":"MIT","_id":"gubu@8.2.1","maintainers":[{"name":"rjrodger","email":"richard.rodger@voxgig.com"}],"homepage":"https://github.com/rjrodger/gubu","bugs":{"url":"https://github.com/rjrodger/gubu/issues"},"dist":{"shasum":"ce87dacff3fd88de78a64d8c671469f3bc9cc021","tarball":"https://registry.npmjs.org/gubu/-/gubu-8.2.1.tgz","fileCount":11,"integrity":"sha512-hCcPYnmhYTNmYEHROl8USIOu5a0kbhRwgZ7K+XELdij3IizMG6Izv+fvuyWwz0GIl5TPG9swWU6IOLPQnz6kRA==","signatures":[{"sig":"MEQCIAc+8+X5HCU0RNt2Z8RbUDNzx4VOTEFZIwcjV64981R1AiB2c8QqvF+YeWDNTjOOTBdDN78ZMaP7a14mUaDswnlQPw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":382205},"main":"gubu.js","type":"commonjs","types":"gubu.d.ts","browser":"gubu.min.js","engines":{"node":">=14"},"gitHead":"c53cb083779d6e9ccb4356c4f6606af46baef046","scripts":{"test":"npm run version && jest --coverage","build":"npm run version && tsc -d","clean":"rm -rf node_modules yarn.lock package-lock.json","reset":"npm run clean && npm i && npm run build && npm test","watch":"npm run version && tsc -w -d","version":"node -r fs -e \"v=require('./package.json').version;s=fs.readFileSync('./gubu.ts').toString();if(!s.includes('VERSION = \\''+v+'\\'')){s=s.replace(/VERSION = '.*?'/,'VERSION = \\''+v+'\\'');fs.writeFileSync('./gubu.ts',s)}\"","repo-tag":"REPO_VERSION=`node -e \"console.log(require('./package').version)\"` && echo TAG: v$REPO_VERSION && git commit -a -m v$REPO_VERSION && git push && git tag v$REPO_VERSION && git push --tags;","test-web":"npm run build && npm run build-web && browserify -i util -o test/web.js -e test/entry.js -im && open test/web.test.html","build-web":"cp gubu.js gubu.min.js && browserify -i util -o gubu.min.js -e gubu.web.js -s Gubu -im -p tinyify","test-pure":"npm run version && jest --coverage --config jest.config.pure.js","test-some":"npm run version && jest -t","test-watch":"npm run version && jest --coverage --watchAll","repo-publish":"npm run clean && npm i && npm run repo-publish-quick","test-some-pure":"npm run version && jest --config jest.config.pure.js -t","repo-publish-quick":"npm run build && npm run test && npm run build-web && npm run test-web && npm run repo-tag && npm publish --access public --registry https://registry.npmjs.org "},"_npmUser":{"name":"rjrodger","email":"richard.rodger@voxgig.com"},"overrides":{"acorn":"8.12.1"},"repository":{"url":"git://github.com/rjrodger/gubu.git","type":"git"},"_npmVersion":"10.2.4","description":"An object shape validation utility.","directories":{},"_nodeVersion":"20.11.1","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","vite":"^5.3.3","es-jest":"^2.1.0","esbuild":"^0.23.0","tinyify":"^4.0.0","ts-jest":"^29.2.2","browserify":"^17.0.0","typescript":"^5.5.3","@types/jest":"^29.5.12","esbuild-jest":"^0.5.0","vite-plugin-commonjs":"^0.10.1","@rollup/plugin-commonjs":"^26.0.1"},"_npmOperationalInternal":{"tmp":"tmp/gubu_8.2.1_1720796424307_0.6454757593892253","host":"s3://npm-registry-packages"}},"8.3.0":{"name":"gubu","version":"8.3.0","keywords":["gubu","schema","validation"],"author":{"url":"http://richardrodger.com","name":"Richard Rodger"},"license":"MIT","_id":"gubu@8.3.0","maintainers":[{"name":"rjrodger","email":"richard.rodger@voxgig.com"}],"homepage":"https://github.com/rjrodger/gubu","bugs":{"url":"https://github.com/rjrodger/gubu/issues"},"dist":{"shasum":"30c5dbee1861d24660b0d57d05851aae18c30bb1","tarball":"https://registry.npmjs.org/gubu/-/gubu-8.3.0.tgz","fileCount":11,"integrity":"sha512-v/CrDWq3VSGDuUxeVjvgeDfDas2w4pi8KHTO2r+AJ2qoIULxCUHXZ+OOFIBRmm2xp3SHOynJtx6VabtYPBYUbQ==","signatures":[{"sig":"MEQCIE9QkSX3cIddQgcjUJ8E+7oB3nVj09dqEphGcShEFkupAiB48nLFWxP1mb4zvunm7xpUP/jpCjELsUFigAYzKuUepQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":382500},"main":"gubu.js","type":"commonjs","types":"gubu.d.ts","browser":"gubu.min.js","engines":{"node":">=14"},"gitHead":"7c81d6b4ae43f42e691980b610be5cde999e6446","scripts":{"test":"npm run version && jest --coverage","build":"npm run version && tsc -d","clean":"rm -rf node_modules yarn.lock package-lock.json","reset":"npm run clean && npm i && npm run build && npm test","watch":"npm run version && tsc -w -d","version":"node -r fs -e \"v=require('./package.json').version;s=fs.readFileSync('./gubu.ts').toString();if(!s.includes('VERSION = \\''+v+'\\'')){s=s.replace(/VERSION = '.*?'/,'VERSION = \\''+v+'\\'');fs.writeFileSync('./gubu.ts',s)}\"","repo-tag":"REPO_VERSION=`node -e \"console.log(require('./package').version)\"` && echo TAG: v$REPO_VERSION && git commit -a -m v$REPO_VERSION && git push && git tag v$REPO_VERSION && git push --tags;","test-web":"npm run build && npm run build-web && browserify -i util -o test/web.js -e test/entry.js -im && open test/web.test.html","build-web":"cp gubu.js gubu.min.js && browserify -i util -o gubu.min.js -e gubu.web.js -s Gubu -im -p tinyify","test-pure":"npm run version && jest --coverage --config jest.config.pure.js","test-some":"npm run version && jest -t","test-watch":"npm run version && jest --coverage --watchAll","repo-publish":"npm run clean && npm i && npm run repo-publish-quick","test-some-pure":"npm run version && jest --config jest.config.pure.js -t","repo-publish-quick":"npm run build && npm run test && npm run build-web && npm run test-web && npm run repo-tag && npm publish --access public --registry https://registry.npmjs.org "},"_npmUser":{"name":"rjrodger","email":"richard.rodger@voxgig.com"},"overrides":{"acorn":"8.12.1"},"repository":{"url":"git://github.com/rjrodger/gubu.git","type":"git"},"_npmVersion":"10.2.4","description":"An object shape validation utility.","directories":{},"_nodeVersion":"20.11.1","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","vite":"^5.3.3","es-jest":"^2.1.0","esbuild":"^0.23.0","tinyify":"^4.0.0","ts-jest":"^29.2.2","browserify":"^17.0.0","typescript":"^5.5.3","@types/jest":"^29.5.12","esbuild-jest":"^0.5.0","vite-plugin-commonjs":"^0.10.1","@rollup/plugin-commonjs":"^26.0.1"},"_npmOperationalInternal":{"tmp":"tmp/gubu_8.3.0_1721140794327_0.6595713946754931","host":"s3://npm-registry-packages"}},"9.0.0":{"name":"gubu","version":"9.0.0","description":"An object shape validation utility.","main":"gubu.js","browser":"gubu.min.js","type":"commonjs","types":"gubu.d.ts","homepage":"https://github.com/rjrodger/gubu","keywords":["gubu","schema","validation"],"author":{"name":"Richard Rodger","url":"http://richardrodger.com"},"repository":{"type":"git","url":"git://github.com/rjrodger/gubu.git"},"scripts":{"test":"npm run version && jest --coverage","test-pure":"npm run version && jest --coverage --config jest.config.pure.js","test-some":"npm run version && jest -t","test-some-pure":"npm run version && jest --config jest.config.pure.js -t","test-watch":"npm run version && jest --coverage --watchAll","test-web":"npm run build && npm run build-web && browserify -i util -o test/web.js -e test/entry.js -im && open test/web.test.html","watch":"npm run version && tsc -w -d","build":"npm run version && tsc -d","build-web":"cp gubu.js gubu.min.js && browserify -i util -o gubu.min.js -e gubu.web.js -s Gubu -im -p tinyify","version":"node -r fs -e \"v=require('./package.json').version;s=fs.readFileSync('./gubu.ts').toString();if(!s.includes('VERSION = \\''+v+'\\'')){s=s.replace(/VERSION = '.*?'/,'VERSION = \\''+v+'\\'');fs.writeFileSync('./gubu.ts',s)}\"","clean":"rm -rf node_modules yarn.lock package-lock.json","reset":"npm run clean && npm i && npm run build && npm test","repo-tag":"REPO_VERSION=`node -e \"console.log(require('./package').version)\"` && echo TAG: v$REPO_VERSION && git commit -a -m v$REPO_VERSION && git push && git tag v$REPO_VERSION && git push --tags;","repo-publish":"npm run clean && npm i && npm run repo-publish-quick","repo-publish-quick":"npm run build && npm run test && npm run build-web && npm run test-web && npm run repo-tag && npm publish --access public --registry https://registry.npmjs.org "},"license":"MIT","engines":{"node":">=14"},"devDependencies":{"@rollup/plugin-commonjs":"^28.0.2","@types/jest":"^29.5.14","browserify":"^17.0.1","es-jest":"^2.1.0","esbuild":"^0.24.0","esbuild-jest":"^0.5.0","jest":"^29.7.0","tinyify":"^4.0.0","ts-jest":"^29.2.5","typescript":"^5.7.2","vite":"^6.0.3","vite-plugin-commonjs":"^0.10.4"},"overrides":{"acorn":"8.12.1"},"_id":"gubu@9.0.0","gitHead":"e9004ccba2b7311b39ffd3f103e031ac93227cb7","bugs":{"url":"https://github.com/rjrodger/gubu/issues"},"_nodeVersion":"20.11.1","_npmVersion":"10.2.4","dist":{"integrity":"sha512-ha4I76HekhYzoXoA5gJql3ql/fTRaj+pyQUwOITCuEENE8sdInUU1lc0+Wr7v4GeAh0Kh8sUCNuwwOw6DHRYTA==","shasum":"b226bbfc3d9904ca244d249b6014714462c6c712","tarball":"https://registry.npmjs.org/gubu/-/gubu-9.0.0.tgz","fileCount":11,"unpackedSize":390145,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCfyaLGizkQNVIyP9/kNnpI7s8P0ji1p7yE8VRYqIUoEwIgc1nLftVtqeQwoo9RcXgORMTv5J8QHnNIVtH9Ecmpa5Q="}]},"_npmUser":{"name":"rjrodger","email":"richard.rodger@voxgig.com"},"directories":{},"maintainers":[{"name":"rjrodger","email":"richard.rodger@voxgig.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/gubu_9.0.0_1734354037450_0.46701712998772127"},"_hasShrinkwrap":false}},"time":{"created":"2021-11-25T19:25:07.310Z","modified":"2024-12-16T13:00:38.303Z","0.0.1":"2021-11-25T19:25:07.623Z","0.0.2":"2021-12-09T14:41:11.388Z","0.0.3":"2021-12-15T19:28:02.615Z","0.0.4":"2021-12-16T19:43:09.536Z","0.0.5":"2022-01-05T14:37:28.159Z","0.0.6":"2022-01-06T13:30:04.287Z","0.1.0":"2022-01-07T00:34:31.984Z","0.2.0":"2022-01-14T12:14:17.302Z","0.2.1":"2022-01-14T15:41:27.666Z","1.0.0":"2022-01-15T15:51:18.579Z","2.0.0":"2022-03-24T21:39:07.780Z","2.0.1":"2022-04-12T18:32:26.722Z","3.0.0":"2022-05-21T23:29:52.501Z","3.1.0":"2022-06-18T02:27:58.186Z","4.0.0":"2022-09-01T22:24:24.101Z","5.0.0":"2023-04-14T18:21:27.468Z","5.0.1":"2023-05-31T13:26:34.625Z","6.0.1":"2023-11-02T02:15:00.277Z","7.0.0":"2024-01-12T19:52:26.278Z","7.1.0":"2024-06-05T13:22:26.681Z","7.1.1":"2024-06-11T10:38:12.996Z","8.0.1":"2024-07-05T09:44:08.346Z","8.0.2":"2024-07-05T12:05:31.533Z","8.1.0":"2024-07-11T11:52:24.612Z","8.2.0":"2024-07-12T14:46:45.909Z","8.2.1":"2024-07-12T15:00:24.523Z","8.3.0":"2024-07-16T14:39:54.513Z","9.0.0":"2024-12-16T13:00:37.611Z"},"bugs":{"url":"https://github.com/rjrodger/gubu/issues"},"author":{"name":"Richard Rodger","url":"http://richardrodger.com"},"license":"MIT","homepage":"https://github.com/rjrodger/gubu","keywords":["gubu","schema","validation"],"repository":{"type":"git","url":"git://github.com/rjrodger/gubu.git"},"description":"An object shape validation utility.","maintainers":[{"name":"rjrodger","email":"richard.rodger@voxgig.com"}],"readme":"<a name=\"top\"></a>\n\n# Gubu: An object shape validation utility.\n\n[![npm version](https://img.shields.io/npm/v/gubu.svg)](https://npmjs.com/package/gubu)\n[![build](https://github.com/rjrodger/gubu/actions/workflows/build.yml/badge.svg)](https://github.com/rjrodger/gubu/actions/workflows/build.yml)\n[![Coverage Status](https://coveralls.io/repos/github/rjrodger/gubu/badge.svg?branch=main)](https://coveralls.io/github/rjrodger/gubu?branch=main)\n[![Known Vulnerabilities](https://snyk.io/test/github/rjrodger/gubu/badge.svg)](https://snyk.io/test/github/rjrodger/gubu)\n[![DeepScan grade](https://deepscan.io/api/teams/5016/projects/19509/branches/508695/badge/grade.svg)](https://deepscan.io/dashboard#view=project&tid=5016&pid=19509&bid=508695)\n[![Maintainability](https://api.codeclimate.com/v1/badges/de19e425771fb65e98e2/maintainability)](https://codeclimate.com/github/rjrodger/gubu/maintainability)\n\n| ![Voxgig](https://www.voxgig.com/res/img/vgt01r.png) | This open source module is sponsored and supported by [Voxgig](https://www.voxgig.com). |\n|---|---|\n\n[Quick Example](#quick-example) | \n[Common Use Cases](#common-use-cases) | \n[Install and Usage](#install) | \n[Shape Rules](#shape-rules) | \n[Shape Reference](#shape-builder-reference) | \n[API](#api)\n\n\nThis is a schema validator in the tradition of [Joi](https://joi.dev)\nor any [JSON-Schema](https://json-schema.org/) validator, but with a\nmuch nicer developer experience. It works in JavaScript and\nTypeScript, on the browser and the backend.\n\n**The big idea is that your schema looks (almost) exactly like your\ndata.** \n\nThat makes your schema much easier to read and reason about. You\ncould call it:\n\n> \"Schema By Example\"\n\nLet's say you want to have the some options for a module you are writing:\n\n```js\n{\n  port: 8080,\n  host: 'localhost'\n}\n```\n\nThis is a valid Gubu specification. It means:\n\n\n```js\n{\n  port: 8080,        // Must be a number, is optional, and the default is 8080\n  host: 'localhost'  // Must be a string, is optional, and the default is 'localhost'\n}\n```\n\nIf your user does not specify these options, then you get the defaults:\n\n```js\n{} --> { port: 8080, host: 'localhost' }\n```\n\nIn Gubu, the most common case for options is the easiest: everything\nis optional, and the default value defines the type you will accept.\nThis also works for objects, which get \"filled out\" if not present:\n\n```js\nconst { Gubu } = require('gubu')\n\nconst shape = Gubu({\n  server: {\n    port: 8080,\n    host: 'localhost'\n  }\n}\n\nlet options = {}\nshape(options)\n\n// And now options is:\n{\n  server: {\n    port: 8080,\n    host: 'localhost'\n  }\n}\n```\n\nAnother big feature of Gubu is that you can fill out objects to any\ndepth (unlike `Object.assign` or the `...` spread operator).\n\nYou may have noticed that Gubu mutates the input to be validated (by\ninjecting defaults as needed). This is deliberate. Cloning arbitrary\nvalues in JavaScript is\n[complicated](https://www.digitalocean.com/community/tutorials/copying-objects-in-javascript),\nso Gubu leaves that decision to calling code.\n\n\nTo make properties required, you use the standard JavaScript wrapper\nobjects (*Number*, *String*, *Boolean*, ...):\n\n```js\nconst { Gubu } = import 'gubu' // `import` also works! And in browsers too.\n\nconst shape = Gubu({\n  timeout: Number,\n  message: String,\n  debug: Boolean,\n})\n\n// All good here - these are valid options!\nshape({\n  timeout: 10000,\n  message: 'Hello!',\n  debug: true,\n})\n```\n\nRequired properties don't have defaults (how could they?), so you only\nneed to specify the type.\n\nTo validate arrays, you provide an example element. All elements of the\narray must match the example element:\n\n```js\nconst shape = Gubu([Number])\n\n// All good - we want numbers!\nshape([100, 200, 300])\n```\n\n\n## Motivation  \n  \nWhy write yet another validator? I've used [Joi](https://joi.dev) for\na long time, but always found its schema definition a little verbose\nat the syntax level. I've never liked JSON-Schema - it's just too\nnoisy to eyeball. What I do like is [Vue.js property\nvalidation](https://vuejs.org/v2/guide/components-props.html#Prop-Validation),\nbut that only works at the top level. I did write a prototype deep\n[Vue property validator using\nJoi](https://github.com/rjrodger/joiprops), but it's pretty clunky.\n\nThis validator is motivated by two use cases: adding message\nvalidation to the [Seneca microservices\nframework](https://senecajs.org), and providing deep defaults for\ncomplex [React](https://react.dev/) and [Vue.js](https://vuejs.org/)\ncomponents. I think it does both jobs rather nicely with an\neasy-to-read syntax.\n\nOn the philosophical side, this validator is motivated by the idea of\n[query-by-example](https://wiki.c2.com/?QueryByExample). This comes\nfrom the belief that software developers should not be subjected to\nunnecessary additional levels of abstraction. Abstraction is hard,\ntakes you further from the problem you're getting paid to solve, and\nis hard to \"eye-ball\". I don't want to parse and run schemas \"in my\nhead\", **I just want to see the literal values and structure that I care\nabout, right here, right now**.\n\n\n## Quick Example\n<sub><sup>[top](#top)</sup></sub>\n\n\n```js\n\nconst { Gubu } = require('gubu')\n\n// Property a is optional, must be a Number, and defaults to 1.\n// Property b is required, and must be a String.\nconst shape = Gubu({ a: 1, b: String })\n\n// Object shape is good! Prints `{ a: 99, b: 'foo' }`\nconsole.log( shape({ a: 99, b: 'foo' }) )\n\n// Object shape is also good. Prints `{ a: 1, b: 'foo' }`\nconsole.log( shape({ b: 'foo' }) )\n\n// Object shape is bad. Throws an exception with message:\n//   Validation failed for property \"a\" with value \"BAD\" because the value is not of type number.\n//   Validation failed for property \"b\" with value \"\" because the value is required.\nconsole.log( shape({ a: 'BAD' }) )\n\n// Object shape is bad. Throws an exception with message:\n//    Validation failed for object \"{b:foo,c:true}\" because the property \"c\" is not allowed.\nconsole.log( shape({ b: 'foo', c: true }) )\n```\n\nAs shown above, you use the exported `Gubu` function to create a\nvalidation shape checker using an example object. Pass the value you\nwant to validate to the shape checker. If the value is valid (matches\nthe example object), the shape checker returns the value (with missing\ndefaults injected). Otherwise the shape checker throws an exception\nlisting all (not just the first!) of the validation errors.\n \n\n## Common Use Cases\n<sub><sup>[top](#top)</sup></sub>\n\n\n### Option defaults and validation\n\nLet's say you have a server that needs to run on a given host and\nport, but by default should run on `localhost` on port `8080`. The host should\nbe a non-empty string, and the port should be a number.\n\n```js\nconst optionShape = Gubu({\n  host: 'localhost',\n  port: 8080\n})\n\n// These print: { host: 'localhost', port: 8080 }\nconsole.log(optionShape())\nconsole.log(optionShape({}))\n\n// Prints: { host: 'localhost', port: 9090 }\nconsole.log(optionShape({ port: 9090 }))\n\n// All of these throw an error.\nconsole.log(optionShape({ host: 9090 }))   // Not a string.\nconsole.log(optionShape({ port: '9090' })) // Not a number.\nconsole.log(optionShape({ host: '' }))     // The empty string is a host name!\nconsole.log(optionShape({ hpst: 'foo' }))  // 'hpst' is not a valid property name.\n\n```\n\n### Deep structures\n\nYou're building a front end component that displays complex data from\nthe back end, and you want to handle missing data gracefully, at any\ndepth in the structure.\n\n```js\nconst productListShape = Gubu({\n  products: [\n    {\n      name: String, // Product name is a required String\n      img: 'generic.png' // Use a default image if not defined\n    }\n  ]\n})\n\nlet result = productListShape({})\n\n// No products, but our data structure still has an array where\n// one is expected, so no `undefined` errors.\nresult === {\n  products: []\n}\n\n// Fix data with missing fields\nlet result = productListShape({\n  products: [\n    { name: 'Apple', img: 'apple.png' },\n    { name: 'Pear', img: 'pear.png' },\n    { name: 'Banana' } // Missing image!\n  ]\n})\n\n// Banana will not have a broken image.\nresult === {\n  products: [\n    { name: 'Apple', img: 'apple.png' },\n    { name: 'Pear', img: 'pear.png' },\n    { name: 'Banana', img: 'generic.png' }\n  ]\n}\n\n```\n\n\n### Shape Building\n\nFor more specific shapes, such as required objects and arrays, you can\nuse shape builder functions that still respect your data structure.\n\nThe [Required](#required-builder) shape builder makes a value\nexplicitly required:\n\n```js\nconst { Gubu, Required } = require('gubu')\n\nconst userShape = Gubu({\n  person: Required({  // person must be a defined object\n    name: String,\n    age: Number,\n  })\n})\n\n// This will fail, with message:\n//   Validation failed for property \"person\" with value \"\" because the value is required.\nuserShape({}) \n\n// This will pass, returning the object:\nuserShape({\n  person: {\n    name: 'Alice',\n    age: 99\n  }\n})\n```\n\nShape builders are exported by the Gubu module directly, and are also\navailable as properties of the `Gubu` function:\n\n```js\nconst { Gubu, Required, Closed } = import 'gubu'\n\nRequired === Gubu.Required\nClosed === Gubu.Closed\n```\n\nFor the full list of shape builders, see the [API\nreference](#shape-builders).\n\n---\n\n[Quick Example](#quick-example) | \n[Common Use Cases](#common-use-cases) | \n[Install and Usage](#install) | \n[Shape Rules](#shape-rules) | \n[Shape Reference](#shape-builder-reference) | \n[API](#api)\n\n\n## Install\n<sub><sup>[top](#top)</sup></sub>\n\n```sh\n$ npm install gubu\n```\n\n\n## Usage\n\n\nThe *Gubu* module has no dependencies. A function named `Gubu` is\nexported as the main entry point.  Shape builders (such as\n[Required](#required-builder)) and utility functions are provided as\nproperties of `Gubu` or can be imported separately.\n\n\n### TypeScript\n\n*Gubu* is written in TypeScript, and can be imported naturally:\n\n```js\nimport { Gubu } from 'gubu' \n```\n\nTypes are provided in [gubu.d.ts](gubu.d.ts).\n\nGubu tries to play nice with compile-time type validation of your\nshapes, and [mostly succeeds](#typescript-types).\n\n\n### Browser\n\nA minified version is provided as [gubu.min.js](gubu.min.js), which\ncan be directly loaded into a web page and exports a `Gubu` global\nobject.\n\nHowever you're probably better off importing this module in the usual\nmanner for your build process and bundling it together with everything\nelse.\n\n\n\n### Shape Rules\n<sub><sup>[top](#top)</sup></sub>\n\n\nThe general principle of Gubu's design is that the schema shape should\nmatch a valid object or value as closely as possible.\n\nFor scalar values you can provide a native type object to make the value required:\n* `Gubu(String)` matches strings: `'foo'`\n* `Gubu(Number)` matches numbers: `123`\n* `Gubu(Boolean)` matches booleans: `true`\n\nOr defaults to make the value optional:\n* `Gubu('bar')` matches strings: `'foo'`, and `undefined`\n* `Gubu(0)` matches numbers: `123`, and `undefined`\n* `Gubu(false)` matches booleans: `true`, and `undefined`\n\nIf a value is optional and `undefined`, the default value is returned:\n`Gubu('bar')()` returns `'bar'`.\n\nThe values `null` and `NaN` must match exactly. They are *not* the\nsame as `undefined`. The value `undefined` is special - it literally\nmeans no value. To allow a property to be absent entirely, use the\n[Skip](#skip-builder) shape builder.\n\nEmpty strings are not considered to be valid (this is usually what you\nwant). To allow an empty string, use `Gubu(Empty('foo'))` or\n`Gubu(Empty(String))` (where `Empty` is exported by the `Gubu`\nmodule).\n\nFor objects, write them as you want them:\n\n```js\nlet shape = Gubu({\n  foo: {\n    bar: {\n      zed: String,\n      qaz: Number,\n    }\n  }\n})\n```\n\nThe above shape will match:\n\n```js\n{\n  foo: {\n    bar: {\n      zed: 'x',\n      qaz: 1\n    }\n  }\n}\n```\n\nIf you want to allow arbitrary properties in an object, you can use the \n[Open](#open-builder) shape builder:\n\n```js\nlet openObject = Gubu(Open({ a: 1 }))\n\n// This now passes (normally property `b` would not be allowed).\nopenObject({ a: 11, b: 22 }))\n```\n\n\nFor arrays, the first element is treated as the shape that all\nelements in the array must match:\n\n* `Gubu([String])` matches `['a', 'b', 'c']`\n* `Gubu([{x: 1}])` matches `[{x: 11}, {x: 22}, {x: 33}]`\n\n\nIf you need specific elements to match specific shapes, use the\n[Closed](#closed-builder) shape builder:\n\n* `Gubu(Closed([String, Number]))` matches `['a', 1]`.\n\nYou can specify custom validation functions using the\n[Check](#check-builder) shape builder:\n\n* `Gubu({a: Check((v) => 10 < v) })`: matches `{a: 11}` as `10 < 11`\n\nAnd you can manipulate the value if you need to:\n\n* `Gubu({a: Check((v, u) => 10 < v ? (u.val = 2 * v, true) : false )})`:\n  matches `{a: 11}` as `10 < 11` and returns `{a: 22}`.\n\n\nYou can also compose validations together:\n\n```js\nconst shape = Gubu({ a: Gubu({ x: Number }) })\n\n// Matches { a: { x: 1 } } as expected\nshape({ a: { x: 1 } })\n```\n\n\nThe shape builder functions ([Required](#required-builder),\n[Closed](#closed-builder), etc.) are also available as properties of\nthe main `Gubu` function, so you don't have to introduce them into\nyour top level variable namespace.\n\nAs a convenience, you can chain most builders. Thus a `Required` and\n`Closed` object can be specified with:\n\n```js\nconst { Gubu } = require('gubu')\n\nconst shape = Gubu({\n  a: Gubu.Closed({ x: 1 }).Required(),\n  b: Gubu.Required({ x: 1 }).Closed(), // Same as line above\n})\n```\n\nYou can also use an optional syntax to avoid importing the shape\nbuilders entirely. This is useful if you want your schemas to be fully\nserializable to JSON.\n\n```\n// The key string format `name: builder-expression` is converted into \n// an application of the shape builders on the value.\n\nconst shape = Gubu({ 'a: Open': { x: 1 }}, { keyexpr: { active: true } })\n\n// Matches as a.y is allowed as a is Open\nshape({ a: { x: 1, y: 2 } })\n\n// shape is equivalent to:\nshape = Gubu({ a: Open({ x: 1 }) })\n\n```\n\nThe builder expression syntax is the same as JavaScript function call\nsyntax, **but** all values must be in JSON format.\n\n```js\nconst shape = Gubu({ 'a: Exact(\"red\",1,true)': 'red'}, { keyexpr: { active: true } })\n```\n\nYou can write your own builders&mdash;see the next section.\n\nIn addition to this README, the [unit tests](lib/gubu.test.ts) are\ncomprehensive and provide many usage examples.\n\n\n### Shape Builders\n\nThe built-in shape builders help you match the following shapes:\n\n* Existence:\n  * [Required](#required-builder): Make a value required.\n  * [Optional](#optional-builder): Make a value optional.\n  * [Skip](#skip-builder): Make a value skippable (no default value is injected if missing).\n  * [Default](#default-builder) Specify a default builder.\n* Value constraints:\n  * [Empty](#empty-builder): Allow string values to be empty.\n  * [Exact](#exact-builder): The value must match one of an exact list of *literal* values.\n  * [All](#all-builder): All shapes must match value.\n  * [Some](#some-builder): Some shapes (at least one) must match value.\n  * [One](#one-builder): Exactly one shape (and no more) must match value.\n  * [Any](#any-builder): This shape will match any value.\n  * [Never](#never-builder): This shape will never match anything.\n* Length constraints (operate on values with a length or numeric value):\n  * [Below](#below-builder): Match a value (or length of value) less than the given amount.\n  * [Max](#max-builder): Match a value (or length of value) less than or equal to the given amount.\n  * [Min](#min-builder): Match a value (or length of value) greater than or equal to the given amount.\n  * [Len](#len-builder): Match a value (or length of value) exactly equal to the given amount.\n  * [Above](#above-builder): Match a value (or length of value) greater than the given amount.\n* General constraints:\n  * [Closed](#closed-builder): Allow only explicitly defined elements in an array.\n  * [Open](#open-builder): Allow arbitrary properties in an object (no constraint on their value).\n  * [Child](#child-builder): All non-explicit child values of an object must match this shape.\n  * [Func](#func-builder): The value is explicitly a function.\n* Mutations:\n  * [Rename](#rename-builder): Rename the key of a property.\n  * [Define](#define-builder): Define a name for a value.\n  * [Refer](#refer-builder): Refer to a defined value by name.\n* Customizations:\n  * [Check](#check-builder): Define a general custom validation function for the value (recommended).\n  * [Before](#before-builder): Define a custom validation function called before a value is processed (advanced use).\n  * [After](#after-builder): Define a custom validation function called after a value is processed (advanced use).\n  * [Key](#key-builder): The key (or path) of the current object is injected as the value.\n\n\n### Regular Expressions\n\nThe [Check](#check-builder) shape builder will also accept a regular\nexpression (instead of a function). The value will be converted to a\nstring (using `String(...)`), and will be valid if it matches the\nregular expression. The values `null`, `undefined` and `NaN` are not\nconverted to strings and will always fail this check.\n\n```js\nlet shape = Gubu({ countryCode: Check(/^[A-Z][A-Z]$/) })\n\nshape({ countryCode: 'IE' })) // PASS.\nshape({ countryCode: 'BAD' })) // FAIL: 'Validation failed for property \"countryCode\" with value \"BAD\" because check \"/^[A-Z][A-Z]$/\" failed.'\n```\n\n\n### Recursive Shapes\n\nYou can use the [Define](#define-builder) and [Refer](#refer-builder)\nshape builders to validate recursive shapes. Use `Define` first to\nname a given shape. Then use `Refer` to apply the definition of the shape.\n\n```js\nlet tree = Gubu({\n  root: Define('BRANCH', {\n    value: String,\n    left: Refer('BRANCH'),\n    right: Refer('BRANCH'),\n  })\n})\n\n// This passes, returning the object.\ntree({\n  root: {\n    value: 'A',\n    left: {\n      value: 'AB',\n      left: {\n        value: 'ABC'\n      },\n      right: {\n        value: 'ABD'\n      },\n    },\n    right: {\n      value: 'AE',\n      left: {\n        value: 'AEF'\n      },\n    },\n  }\n})\n\n// This fails with error:\n// \"Validation failed for property \"root.left.left.left.value\" with value \"123\" because the value is not of type string.\"\n\ntree({\n  root: {\n    value: 'A',\n    left: {\n      value: 'AB',\n      left: {\n        value: 'ABC',\n        left: {\n          value: 123\n        },\n      },\n    },\n  }\n})\n```\n\n\n## API\n<sub><sup>[top](#top)</sup></sub>\n\n### Shape\n\n[API](#api) | \n[Shapes](#shape) | \n[Errors](#errors) | \n[Custom Validation](#custom-validation) |\n[Builders](#shape-builder-reference)\n\n\nA shape specification can either be at the root of a JSON structure,\nan array element, or the value of an object property.  For a value to\npass validation, it is compared to the shape, and must match the\nconstraints of the shape. If the shape has elements or properties,\nthese must also match, and are validated recursively in a depth-first\nmanner [^1].\n\n\n#### Required Values\n\nThe value must be of the indicated type, and must exist.\n\n* `String`: match any string, but not the empty string [^2].\n* `Number`: match any number, but not `BigInt` values.\n* `Boolean`: match any boolean.\n* `Function`: match any function.\n* `Object`: match any object.\n* `Array`: match any array.\n* `Symbol`: match any symbol.\n* `BigInt`: match any `BigInt` (including the `1n` syntax form).\n* `Error`: match an object created with `new Error(...)`\n* `Date`: match an object created with `new Date(...)`\n* `RegExp`: match an object created with `/.../` or `new RegExp(...)`\n\nYou can require an instance of any class (that is, an object created\nwith `new`) by using the class name as the shape.\n\n\n#### Optional Values with Defaults\n\nThe value must be of the indicated type, and is derived from the given\ndefault. If the value does not exist, the default value is inserted.\n\n* `foo`: match any string, but replace an empty string [^3].\n* `123`: match any number, but not `BigInt` values.\n* `true`: match any boolean.\n* `new Object()`: match any object.\n* `new Array()`: match any array.\n* `new Symbol('bar')`: match any symbol.\n* `new BigInt(456)`: match any `BigInt` (including the `1n` syntax form).\n* `new Error()`: match an object created with `new Error(...)`\n* `new Date()`: match an object created with `new Date(...)`\n* `/x/`: match an object created with `/.../` or `new RegExp(...)`\n\nYou can provide an instance of any class as a default. The value, if\npresent, must be an instance of the same class.\n\nNote that `new Function()` does not match anonymous functions, and\nshould not be used [^4].\n\n\n#### Objects\n\nPlain objects can be specified directly as they appear in values to be\nvalidated. If you want an object `{foo: 123}`, then the shape is also\n`{foo: 123}`, meaning any object with a `foo` property (and no other\nproperties) that is a `number`. The `foo` property is optional, and\nwill default to the value `123`.\n\nYou can define plain objects to any depth. The shape `{ bar: { foo:\n123 } }` defines an object that optionally contains another object as\nthe value of the property `bar`.\n\nAs objects and sub-objects are often referenced directly in data\nstructures (using dot notation), *Gubu* will construct missing objects\nby default, and fill in the missing child values (which may themselves\nbe objects). These protect your code from `undefined` value errors\nin default cases.\n\nThe general form of an object shape is:\n\n```js\n{ \n  'propName0': <SHAPE>,\n  'propName1': <SHAPE>,\n  ...\n  'propNameN': <SHAPE>,\n}\n```\n\nwhere `propNameX` is any string (the quotes may be omitted if the\nproperty name is a valid JavaScript identifier&mdash;this is just\nnormal JavaScript syntax after all).\n\nThe `<SHAPE>` can be any valid *Gubu* shape definition.\n\n\n##### Required Properties (Object)\n\nTo mark an object property as required, use the [required\nvalue](#required-values) shapes (such as `String`), or use the shape\nbuilder [Required](#required-builder):\n\n```js\nconst { Required } = Gubu\n\nlet shape = Gubu({\n  foo: Number,\n  bar: Required({\n    zed: Boolean\n  })\n})\n\n// This passes, returning the value unchanged.\nshape({ foo: 1, bar: { zed: false } })\n\n// These fail, throwing an Error.\nshape({ bar: { zed: false } }) // foo is required\nshape({ foo: 'abc', bar: { zed: false } }) // foo is not a number\nshape({ foo: 1 }) // bar is required\nshape({ foo: 1, bar: {} }) // bar.zed is required\nshape({ foo: 1, bar: { zed: false, baz: 2 }, qaz: 3 }) // new properties are not allowed\n```\n\nObject properties that are required must always be provided, even if\nthey are children of optional objects&mdash;they wouldn't be required\notherwise! To allow such deep required properties to be missing, use\nan explicit [Skip](#skip-builder) shape builder:\n\n```js\nlet strictShape = Gubu({ a: { b: String } })\n\n// Passes\nstrictShape({ a: { b: 'ABC' } })\n\n// Fails, even though a is not required, because a.b is required.\nstrictShape({})\n\n\nlet easyShape = Gubu({ a: Skip({ b: String }) })\n\n// Now both pass\neasyShape({ a: { b: 'ABC' } })\neasyShape({})\n\n// This still fails, as `a` is now defined, and needs `b`\neasyShape({ a: {} })\n\n```\n \n\n##### Open Objects\n\nNormally, objects can only contain explicitly defined properties. To\nallow an object to have an unrestricted set of properties, use the\n[Open](#open-builder) shape builder:\n\n```js\nconst { Open } = Gubu\n\nlet shape = Gubu(Open({\n  a: 1\n}))\n\nshape({ a: 11, b: 22 }) // PASS: returns { a: 11, b: 22 }\nshape({ b: 22, c: 'foo' }) // PASS: returns { a: 1, b: 22, c: 'foo' }\n\nshape({ a: 'foo' }) // FAIL: property `a` must still be a number\n\n```\n\nThe [Open](#open-builder) shape builder applies only to the object it\nwraps, and does not apply to child objects. You need to use `Open`\nexplicitly for each object that can have arbitrary properties.\n\n\n```js\nlet shape = Gubu(Open({\n  a: Open({\n    b: 1\n  })\n}))\n\n\nshape({ a: { b: 11, c: 22 }, d: 33 }) // PASS, returns object\n```\n\nAn empty object shape (`{}`) is automatically open and will allow any\nproperties.\n\nThe [Open](#open-builder) shape builder can also be used without\nadding the `Open` builder function to your imports. Instead, use the\noptional `keyexpr` feature and specify that an object is open with:\n\n```js\nlet shape = Gubu({\n  'a: Open': {\n    b: 1\n  }\n}, { keyexpr: { active: true } })\n```\n\n\n##### Optional Objects\n\nObjects are optional by default, and will be created if not\npresent. To prevent this, use the shape builder [Skip](#skip-builder)\nto indicate that you do *not* wish an object to be inserted when it is\nmissing&mdash;it can be skipped.\n\n```js\nconst { Skip } = Gubu\nlet shape = Gubu({\n  a: { x: 1 },\n  b: Skip({ y: 2 }),\n  c: Skip({ z: Skip({ k: 3 }) }),\n})\n\n// Skippable properties are not inserted as defaults if missing.\nshape({}) // returns { a: { x: 1 } }, b and c are missing entirely\nshape({ b: {} }) // returns { a: { x: 1 }, b: { y: 2 } }, defaults for b are inserted\nshape({ c: {} }) // returns { a: { x: 1 }, c: {} }, c has no non-optional defaults\nshape({ c: { z: {} } }) // returns { a: { x: 1 }, c: { z: { k: 3 } } } // z has defaults\n```\n\nIf the object value is present but empty, any default values will be inserted.\n\n\n##### Object Values\n\nYou can define a general shape for all non-explicit object values\nusing the [Child](#child-builder) shape builder:\n\n```js\nconst { Value } = Gubu\n\nlet shape = Gubu(Child(String, {\n  a: 123,\n}))\n\n// All non-explicit properties must be a String\nshape({ a: 11, b: 'abc' }) // b is a string\nshape({ c: 'foo', d: 'bar' }) // c and d are strings\n\n// These fail\nshape({ a: 'abc' }) // a must be a number\nshape({ b: { x: 1 } }) // b must be a string\n```\n\nUsing the [Child](#child-builder) shape builder in this way automatically\nmakes the object open, but constrains the values that can be used for\nnon-explicit properties.\n\nThe general shape can be any valid shape:\n\n\n```js\nconst { Required, Value } = Gubu\n\nlet shape = Gubu({\n  people: Required({}).Value({ name: String, age: Number })\n})\n\n// This passes:\nshape({ people: { \n  alice: { name: 'Alice', age:99 }, \n  bob:   { name: 'Bob',   age:98 },\n} })\n\n// These fail:\nshape({ people: { \n  alice: { name: 'Alice', age:99 }, \n  bob:   { name: 'Bob' }, // age is a required number\n} })\nshape({}) // people is a required object\n\n```\n\n\n#### Arrays\n\nArrays can be specified directly using the first element as the shape\nthat each element of the value array must match. If you want an array\nof numbers (`[ 1, 2, 3 ]`, say), then the shape is `[Number]`.\n\n```js\nlet shape = Gubu([Number])\nshape() // PASS: returns [] (the array itself is optional)\nshape([]) // PASS: returns [] (empty arrays pass)\nshape([1]) // PASS: element matches Number shape\nshape([1, 2]) // PASS: all elements match Number shape\n\nshape([1, 2, 'bad']) // FAILS; element 2 is not a number\n\n\n// Array elements can be any complex shape.\nshape = Gubu([{x: 1}])\nshape([{ x: 123 }, { x: 456 }]) // PASS: elements match {x: 1}\nshape([{}]) // PASS:  returns [{x: 1}]\n\nshape([{x: 123}, {x: 'a'}]) // FAILS; element 1 does not match {x: 1}\n```\n\nYou can also define special shapes for individual elements at specific\nindexes, using the [Closed](#closed-builder) shape builder, as shown\nbelow.\n\nThe general form of an array shape is:\n\n```js\n[\n  <SHAPE>,\n]\n```\n\nwhere `<SHAPE>` is any valid *Gubu* shape definition. All elements\nmust match `<SHAPE>`, and the empty array is allowed. This is the\nstandard case and usually what you want.\n\nFor special cases, where elements at specific indexes must match\nspecific shapes, you can define these arrays using the\n[Closed](#closed-builder) shape builder.\n\n```js\nlet shape = Gubu(Closed([Number, String, Boolean]))\n\n// This passes, returning the array as is.\nshape([ 123, 'abc', true ])\n\n// These fail.\nshape([ 'bad' ]) // Index 0 must be a number\nshape([ 123 ]) // Index 1 and 2 are missing\nshape([ 123, 'abc', true, 'extra' ]) // Too many elements\n```\n\nAs a shortcut, a shape array with *two or more* elements is considered\nclosed, and all elements are considered special. Thus `Closed([String,\nNumber])` is the same as `[String, Number]`. For a single element\nclosed array, you *must* use the [Closed](#closed-builder) shape\nbuilder to close the array. Thus `Closed([Number])` means the array\ncan only ever have one element, a number.\n\nAs arrays are often referenced directly in data structures, *Gubu*\nwill construct missing arrays by default, and for closed arrays, fill\nin the missing element values if there are empty or `undefined` array\nentries.\n\n\n##### Required Properties (Array)\n\nTo mark an array element as required, use the [required\nvalue](#required-values) shapes (such as `String`), or use the shape\nbuilder [Required](#required-builder).\n\n```js\nlet shape = Gubu([{ x: 1 }, Required({ y: true })])\n\n// These pass\nshape([{ x: 2 }, { y: false }])\nshape([undefined, { y: false }]) // returns [{ x: 1 }, { y: false }]\nshape([{ x: 2 }, {}]) // returns [{ x: 2 }, { y: true }]\n\n// These fail\nshape([{ x: 2 }, undefined]) // Element 1 is required\nshape([{ x: 2 }]) // Element 1 is required\n```\n\n\n##### Array Properties\n\nJavaScript allows arrays to have properties: `let a = []; a.foo = 1`.\nMatching against array properties in the current version must be done\nby writing a [custom validator](#custom-validation) using the\n[Check](#check-builder) shape builder.\n\n\n##### Length Constraints\n\nYou can control the allowed length of an array using the shape\nbuilders [Min](#min-builder), [Max](#max-builder),\n[Above](#above-builder), [Below](#below-builder), and\n[Len](#len-builder) to restrict the length of the array.\n\n```js\nlet { Min } = Gubu\nlet shape = Gubu(Min(2, [Number]))\n\n// These pass\nshape([11,22]) // length is 2, >= minimum 2\nshape([11,22,33]) // length is 3, >= minimum 2\n\n// These fail\nshape([11]) // length is 1, not >= minimum 2\nshape([]) // length is 0, not >= minimum 2\n```\n\n\nThe length constraining shape builders ([Min](#min-builder),\n[Max](#max-builder), [Above](#above-builder), [Below](#below-builder),\nand [Len](#len-builder)) work in a sensible way depending on the data\ntype. For strings they control character length, for numbers they\ncontrol magnitude, for objects they control property count, and for\narrays, they control length:\n\n```js\nlet { Max } = Gubu\n\n// Maximum string length\nshape = Gubu(Max(2, String))\nshape('a') // PASS\nshape('ab') // PASS\nshape('abc') // FAIL: string longer than 2 characters\n\n// Maximum object size\nshape = Gubu(Max(2, {})) // An empty object is open, so can accept any properties\nshape({ a: 1 }) // PASS\nshape({ a: 1, b: 2 }) // PASS\nshape({ a: 1, b: 2, c: 3 }) // FAIL: more than 2 properties in object\n\n```\n\n\n#### Functions\n\nLiteral function value operate in the same way as any other literal\nvalues, defining an optional value shape with a default. This allows\nyou to provide default functions for your module options, if you are\nusing *Gubu* as an option validator.\n\n```js\nlet shape = Gubu({\n  fn: () => true\n})\n\n// This passes\nshape({ \n  fn: () => false \n})\n\n// This injects the default function\nshape({)) === {\n  fn: () => true \n})\n```\n\n\nTo require a function, use the shape `Function`,\n(`Gubu(Function)(()=>true)` will pass).\n\n\n#### Key Expressions\n\nIf you wish to avoid importing the shape builder functions, or you\nwould like your shape schema to be serializable to JSON, then you can\nuse *key expressions*.\n\nKey expressions allow you to specify the shape builders in the\nproperty key string. They must be enabled with an optional flag when\ncreating the shape.\n\n```js\nlet shape = Gubu({\n  'a: Skip': 1\n}, { keyexpr: { active: true } })\n```\n\nThis syntax is equivalent to:\n\n```js\nlet shape = Gubu({\n  a: Skip(1)\n})\n```\n\nWhen key epxressions are active, any key string of the form: \n```\nkey:builder-expression\n``` \nis evaluated as a key expression.\n\nThe syntax of key expressions is the same as JavaScript function call\nsyntax. However, literal values must be written as JSON, and commas\nbetween arguments are optional. Sequential shape builder functions are\nevaluated left-to-right.\n\nThe following are all equivalent:\n\n```js\nlet shape = Gubu({\n  a: Min(1, Max(4, Number)), // A number x, where 1 <= x <= 4.\n  'b: Min(1, Max(4))': Number, // The property value (in this case, Number) is implicit,\n  'c: Min(1) Max(4)': Number, // Same effect, since both operate on Number.\n  'd: Min(1).Max(4)': Number, // Chaining is also supported.\n\n}, { keyexpr: { active: true } })\n```\n\nNot all shape builders are supported, only those that can accept\nliteral values as arguments. Thus custom [Check]($check-builder)\nfunctions cannot be specified as key expressions.\n\nThe literal value arguments are parsed with JSON.parse, so must be\nvalid JSON. In addition, regular expressions, and the values\n`undefined` and `NaN` are also recognized.\n\nKey expressions can only be used with object keys, and are not\nsupported at the top level.\n\n\n#### Custom Validation\n\n[API](#api) | \n[Shapes](#shape) | \n[Errors](#errors) | \n[Custom Validation](#custom-validation) |\n[Builders](#shape-builder-reference)\n\n\nYou can define custom validators by providing a function to the\n[Check](#check-builder) shape builder. The first argument to this\nfunction will provide the value to validate. Return `true` if the\nvalue is valid, and `false` if not.\n\n```js\nimport { Gubu, Check } from 'gubu'\n\nlet shape = Gubu({ a: Check((v) => 10 < v) })\nshape({ a: 11 }) // passes, as 10 < 11 is true\nshape({ a: 9 })  // fails, as 10 < 9 is false\n```\n\n<a name=\"update-type\"></a> \nYou can modify the value using the second argument to the custom\nvalidation function, by assigning a new value to the `val` property:\n\n```js\nlet shape = Gubu({ \n  a: Check((value, update) => {\n    update.val = value * 2 \n    return true // Remember to return true to indicate value is valid!\n  })\n})\n\nshape({ a: 3 }) // returns { a: 6 }\n```\n\nAs a special case, if you want to explicitly set the value to\n`undefined` or `NaN`, use the property `uval`.\n\nYou can also provide a custom error message using the `update` argument:\n\n```js\nlet shape = Gubu({ \n  a: Check((value, update) => {\n    update.err = 'BAD VALUE $VALUE AT $PATH'\n    return false // always fails\n  })\n})\nshape({ a: 3 }) // throws \"BAD VALUE 3 AT a\"\n```\n\nThe special replacement tags `$VALUE` and `$PATH` are replaced with\nthe value, and the property path to the value, respectively.\n\n<a name=\"state-type\"></a> The third argument to a custom validator is\nthe internal state of the validation process. This is provided for\nspecial cases and workarounds, and the internal set of properties\nshould not be considered stable. Review the [source\ncode](https://github.com/rjrodger/gubu/blob/main/gubu.ts#L98) to see\nwhat is available.\n\n```js\nshape = Gubu({\n  a: Check((value: any, update: any, state: any) => {\n    update.val = value + ` KEY=${state.key}`\n    return true\n  })\n})\nshape({ a: 3 }) // returns { a: '3 KEY=a'}\n```\n\nThe shape builders [Before](#before-builder) and\n[After](#after-builder) operate in a similar manner to the\n[Check](#check-builder). They allow you to perform your custom\nvalidation before, or after, normal validation, respectively. They do\nnot support regular expressions as an argument.\n\nIn general, you should use the `Check` shape builder for custom\nvalidation. The `Before` and `After` builders are provided for\nadvanced usage.\n\n\n### Gubu function\n\nTo construct a shape use the `Gubu` function exported by this module:\n\n```js\n// Using require\nconst { Gubu } = require('gubu')\n\n// Using import\nimport { Gubu } from 'gubu'\n\nlet shape = Gubu({ x: 1 })\n```\n\nIn the browser, *Gubu* adds itself directly to the `window` object for\nimmediate use (if you directly load this module using a `script`\ntag). However you'll probably just want to import *Gubu* in the usual\nway into your own source code and let your package builder look after\nthings.\n\nThe `Gubu` function has two arguments:\n* `shape` (optional): any valid shape definition (`'abc'`, `String`, `{ x: 123 }`, etc.).\n* `options` (optional): an options object.\n\n\nThe shape argument can be anything, and is used to define the\nvalidation shape expected. See the sections above for descriptions of\nthe various shapes.\n\n\nThe options are:\n* `name`: a string defining a custom name for this shape (useful for debugging).\n\nThe `Gubu` function provides all built-in [shape builders](#shape-builders)\n(`Required`, `Closed`, etc.) as properties. These are also exported directly\nfrom the module, so the following are equivalent:\n\n```js\nconst { Gubu, Required } = import 'gubu'\n\nconst { Gubu } = require('gubu')\nconst { Require } = Gubu\n```\n\nIf you are concerned about namespacing the builders (if the names\nclash with your own names), the shape builders are also available with\na 'G' prefix as an alias:\n\n```js\nGubu.GRequired === Gubu.Required\n```\n\n\n### GubuShape function\n\nWhen you create a shape using `Gubu`, a `GubuShape` shape validator\nfunction is returned:\n\n```js\n// TypeScript\nimport { Gubu, GubuShape } from 'gubu'\n\n// GubuShape is inferred:\nconst shape = Gubu(123) // `shape` is a validator function\n```\n\nThe shape validator function has two arguments:\n* `value`: the value to validate (and modify with defaults).\n* `context`: (optional) a context object containing your own data.\n\nThe value can be anything. It is not duplicated and **will be\nmutated** if defaults are inserted.\n\n> **If you do not wish the value to be mutated, you must clone it yourself\nfirst [^5]**.\n\nThe context is a general purpose store for anything you might want to\nuse in custom validation builders. It may also be used by builders to\nhold state information (the name of the builder is used for\nnamespacing).\n\nThe context has one reserved name:\n* `err`: an array of validation errors.\n\nIf you provide a context with the property `err` as an empty array,\nany validation errors will be added to this array, and an Error will\n**not be thrown**:\n\n```js\nlet ctx = { err: [] }\nGubu(Number)('abc', ctx)  // does not throw\nconsole.log(err[0]) // prints error description (number was expected)\n```\n\nThe [error descriptions](#errors) are plain objects, not `Error` objects.\n\nThe `GubuShape` function has the following methods:\n* `valid(value: any, context?: any): boolean`\n  * returns `true` if the value matches the shape\n  * **injects defaults into value**\n  * does not throw Errors, use context = { err: [] } to get any errors\n  * can be used as type guard in TypeScript\n* `match(value: any, context?: any): boolean`\n  * returns `true` if the value matches the shape\n  * **does not inject defaults**, \n  * does not throw Errors, use context = { err: [] } to get any errors\n  * can be used as type guard in TypeScript\n* `toString()`\n  * returns a short string describing this `GubuShape` instance\n* `[Util.inspect.custom]()`\n  * same as `toString`\n* `spec()`\n  * returns a declarative description of the shape\n\nThe shape description provided by `spec` can be passed to `Gubu` to\ngenerate a new separate shape instance (see the \n[Shape Nodes](#shape-nodes) section).\n\nMany shapes can be fully serialized to JSON, but those with custom\nvalidator functions are not serializable in the current version.\n\nA `GubuShape` can be used be used as part of new shape\ndefinition. They are intended to be composable.\n\n\n### Errors\n\n[API](#api) | \n[Shapes](#shape) | \n[Errors](#errors) | \n[Custom Validation](#custom-validation) |\n[Builders](#shape-builder-reference)\n\n\n*Gubu* will attempt a full validation of the input value, collect all\nerrors, and throw an Error if any validation failed. The error object\nwill be an instance of `GubuError`, which extends `TypeError` with the\nfollowing extra properties:\n\n* `gubu`: A marker value, always `true`.\n* `code`: Top level error code, in this version, always `'shape'`\n* `desc()`: Call this function to get a more detailed description of the error.\n\nThe error description returned by `desc()` has the properties:\n* `name`: Always `'GubuError'`\n* `code`: Top level error code, in this version, always `'shape'`\n* `err`: An array of `ErrDesc` objects (these are all the errors that occurred).\n* `ctx`: The context object (if any) passed to this `GubuShape` validation call.\n\nThe message string of GubuError is a human readable generic\ndescription of the validation failure (with one issue per line) that\nis usable in your own application as-is. You can use the `ErrDesc`\nobject instead to create entirely custom messages. Custom messages for\nspecific custom errors can also be defined (see below).\n\n```js\nGubu(Number)('abc') // throws an Error with message:\n`\nValidation failed for value \"abc\" because the value is not of type number.'\n`\n\nlet shape = Gubu({ \n  top: { \n    foo: String, \n    bar: Number \n  }\n})\n\nshape({ top: { foo: 123, bar: 'abc' }}) // throws an Error with message:\n`\nValidation failed for property \"top.foo\" with value \"123\" because the value is not of type string.\nValidation failed for property \"top.bar\" with value \"abc\" because the value is not of type number.\n`\n```\n\n#### ErrDesc Object\n\nThe `ErrDesc` object is the internal representation of an error,\ncontaining the full details of the error, which you can use for\ncustomization. The properties are:\n\n* `k: string`  : Key of failing value (or empty string at top level).\n* `n: Node`    : Failing shape node.\n* `v: any`     : Failing value.\n* `p: string`  : Key path to value.\n* `w: string`  : Error code (\"why\").\n* `m: number`  : Unique error mark for debugging (search in source code of gubu.ts).\n* `t: string`  : Error message text.\n* `u: any`     : User custom info.\n\nThe property `n` is the [shape node](#shape-nodes) whose validation failed.\n\n```js\ntry {\n    Gubu({x: Number})({x: 'abc'})\n}\ncatch(gubuError) {\n  gubuError.desc()) === {\n    name: 'GubuError',\n    code: 'shape',\n    err: [\n      {\n        k: undefined,\n        n: { \n          '$': { 'gubu$': Symbol(gubu$), 'v$': '<VERSION>' },\n          t: 'number',\n          v: 0,\n          r: true,\n          o: false,\n          d: 0,\n          u: {},\n          a: [],\n          b: []\n        },\n        v: 'x',\n        p: '',\n        w: 'type',\n        m: 1050,\n        t: 'Validation failed for property \"\" with value \"x\" because the value is not of type number.',\n        u: {},\n      }\n    ],\n    ctx: {}\n  }\n}\n```\n\nFrom this description, you can determine that:\n* There was one err: `err.length === 1`\n* A type constraint failed: `err[0].w === 'type'`\n* The value was required: `err[0].n.r === true`\n* The value should be a number: `err[0].n.t === 'number'`\n* The value occurred at the top level: `err[0].p = ''`\n\nThe *path* of an error is the chain of properties that you follow to\nreach the failing value. For example, the path of the value of `c` in\n`{ a: { b: { c: 123 } }}` is `a.b.c`.\n\nIn the case of arrays, the index is used as the property value. Thus,\nthe path of the second element (`=== 'y'`) of `{ a: ['x','y'] }` is\n`a.1`. Paths do not used `[]` notation for arrays.\n\nValues are converted to strings for the error message by using\n`JSON.stringify`. Circular values are handled safely. Long values are\ntruncated to 30 characters.\n\nThe *mark* value (property `m`) is a numeric code that uniquely\nidentifies the generation point of the error in the source code of\n[gubu.ts](https://github.com/rjrodger/gubu/blob/main/gubu.ts), and\nshould be quoted in bug reports (or indeed you can use it yourself to\ninspect the source code).\n\n\n#### Error Collection\n\nInstead of throwing validation errors, you can collect them using the\nreserved property `err` in the context argument:\n\n```js\nlet ctx = { err: [] }\nGubu(Number)('abc', ctx)  // does not throw\n// ctx.err now contains an array of ErrDesc objects \n```\n\nThe return value from `Gubu` in this case (and the value passed in!)\nshould be considered corrupted (defaults may only be partially\napplied). If you want to retain the original value, you must clone it\nyourself before passing it to *Gubu* [^5].\n\nYou can also set the context `err` property to `false`. In this case\nerrors are not collected at all, and they are ignored, so that the\nfull shape depth is always validated. The `GubuShape.spec` method uses\nthis feature to generate a normalized validation `Node` hierarchy\nagainst the `undefined` value.\n\n\n#### Custom Errors\n\nWhen using a [custom validator](#custom-validation) you can provide a custom\nerror message using the `Update.err` property.\n\n```js\nlet shape = Gubu({ a: (value, update) => {\n  update.err = 'BAD VALUE $VALUE AT $PATH'\n  return false // always fails\n})\nshape({ a: 3 }) // throws \"BAD VALUE 3 AT a\"\n```\n\nWhere `$VALUE` and `$PATH` are replaced by the value and path to the\nvalue, respectively.\n\n\n### TypeScript Types\n\nGubu makes a best-effort to support TypeScript types. The intersection\nof the type of the shape and the type of the value is used as the\nreturn type. This almost always does what you want, especially with\noptional default values (from which types will be inferred).\n\nThe [GubuShape](#gubushape-function) function also contains a property\nfunction `valid` with form:\n\n```js\nvalid(value: any, context?: any): boolean\n```\n\nThis can be used as a [type guard](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates):\n\n```js\nconst shape = Gubu({ x: 1, y: 'Y' })\nlet data = { x: 2 }\n\nif (shape.valid(data)) {\n  console.log(data) // prints { x: 2, y: 'Y', z: true }\n  console.log(data.x) // no type errors; prints 2\n  console.log(data.y) // no type errors; prints 'Y'\n  console.log(data.q) // type error! does not compile\n}\n```\n\nThe `valid` function does not throw, but you can optionally collect\n[errors](#Errors) in the usual way with:\n```js\n...\ncontext = { err: [] }\nif (shape.valid(data, context)) {\n  ...\n}\n\n// failed\nelse {\n  // context.err has the errors!\n}\n```\n\n\nWhere TypeScript cannot infer your types properly, you'll need to\nmanually define them:\n\n```js\nlet shape = Gubu(Open({ x: 1}) as unknown as { x: number })\nlet data = { z: true }\n\nif (shape.valid(data)) {\n  console.log(data) // prints{ x: 1, z: true })\n  console.log(data.x) // no type errors; prints 1\n  console.log(data.z) // no type errors; prints true \n  console.log(data.q) // type error! does not compile\n}\n```\n\nThe holy grail would be for Gubu to use your type definitions directly:\n\n```js\ninterface User {\n  name: string\n  age: number\n  job?: string\n}\n\n// DOES NOT WORK!\nlet shape = Gubu(User)\n```\n\nSadly TypeScript does not provide runtime type information at\npresent&mdash;[it should](https://www.typescriptneedstypes.com/)!\n\nIf you're really keen on being ultra-DRY, and really want to avoid\nduplicating type definitions into almost, but not quite, the same shape\ndefinitions, here are your options:\n\n1. Create an instance of your type, and use that as the shape definition:\n\n```js\nClass Car {\n  // These defaults become the shape definitions\n  make: string = ''\n  model: string = ''\n}\nconst shape = Gubu({ ...new Car() })\n```\n\n2. Use code generation. Perhaps you are already building types from a\n   SQL Schema? Use the same approach to build the shapes.\n   \n3. Parse the `d.ts` type definitions at runtime use those to\n   dynamically define your shapes.\n   \nNone of these options are that great. For moment, I recommend that you\nuse the instance trick above if you can (option 1), and live with some\nmanual fix up.\n\nOne more thing: at the moment I don't plan to support definitions in\nthe other direction, going from shapes to TypeScript types. That would\njust be building a bad copy of the TypeScript type system using\ndifferent syntax. That said, never say never, and if TypeScript\ninference can support it, I may look at it again.\n\n\n### Shape Nodes\n\nThe data structure returned by `GubuShape.spec()` is the internal\nrepresentation of the validation shape. This is a hierarchical data\nstructure where the validation for each key-value pair is defined by a\nshape `Node`, which has the following structure:\n\n* `$`: typeof GUBU         : Special marker to indicate a *Gubu* `Node` object.\n* `t`: `ValType`           : Value type name (see below).\n* `d`: number              : Depth of the object tree.\n* `v`: any                 : Default value.\n* `r`: boolean             : Value is required.\n* `p`: boolean             : Value is skippable (if key is absent, no default is injected).\n* `n`: number              : Number of keys in default value.\n* `c`: any                 : Default child shape (for array elements and open objects).\n* `u`: Record<string, any> : Custom user meta data.\n* `b`: Validate[]          : Custom before-validation functions.\n* `a`: Validate[]          : Custom after-validation functions.\n* `s?`: string             : Custom stringification of the value (mostly for error messages).\n\nThe `ValType` is string with exactly one of these values: \n* `'any'` :       Any type.\n* `'array'` :     An array.\n* `'bigint'` :    A BigInt value.\n* `'boolean'` :   The values `true` or `false`.\n* `'custom'` :    Custom type defined by a validation function.\n* `'function'` :  A function.\n* `'instance'` :  An instance of a constructed object.\n* `'list'` :      A list of types under a given logical rule.\n* `'nan'` :       The `NaN` value.\n* `'never'` :     No type.\n* `'null'` :      The `null` value.\n* `'number'` :    A number.\n* `'object'` :    A plain object.\n* `'string'` :    A string (but *not* the empty string).\n* `'symbol'` :    A symbol reference.\n* `'undefined'` : The `undefined` value.\n\n\nThis structure is deliberately terse (hence the one character property\nnames) to make eye-balling deep structure debugging print-outs easier.\n\nAs noted above, in the current version this structure is only fully\nserializable to JSON if there are no custom validations, and the\ncustom user meta data is serializable.\n\nThis structure can be accessed in [custom\nvalidators](#custom-validation) via the `state.node` parameter, and in\n[shape builders](#shape-builders) via the [before](#custom-builders) and\n[after](#custom-builders) hook functions. It is also provided in error\nmessages under the `n` property.\n\n\n\n### Shape Builder Usage\n\nThe validation rules for each value shape can be modified using shape\nbuilders. These are wrapping functions that add additional constraints\nto the value shape.\n\nFor example, the [Required](#required-builder) shape builder marks a\nvalue as required. This is most useful for objects and array, which\nare by default optional:\n\n```js\nconst { Gubu, Required } = require('gubu') // shaper builders are exported\nlet easier = Gubu({ x: 1 })\nlet stricter = Gubu(Required({ x: 1 }))\n\neasier() // returns { x: 1 }\n\nstricter() // fails\nstricter({}) // returns { x: 1 } (x itself is an optional default)\n```\n\nMost shape builders can also be chained. For example, the\n[Open](#open-builder) shape builder allows additional properties to be\nadded to an object. To also make the object required you can use\neither of these expressions:\n\n```js\nconst { Required, Open } = Gubu // shape builders are also properties of Gubu\nGubu(Open({ a: 1, b: 2 }).Required())\nGubu(Required({ a: 1, b: 2 }).Open())\n```\n\nMost shape builders can be composed (check their expected arguments!),\nso the following are also equivalent:\n\n```js\nGubu(Open(Required({ a: 1, b: 2 })))\nGubu(Required(Open({ a: 1, b: 2 })))\n```\n\nThis flexibility allows you to adjust shapes without too much\nrefactoring or \"schema noise\".\n\n\n### Shape Builder Reference\n<sub><sup>[top](#top)</sup></sub>\n\n[API](#api) | \n[Shapes](#shape) | \n[Errors](#errors) | \n[Custom Validation](#custom-validation) |\n[Shape Rules](#shape-rules)\n\nThe built-in shape builders are:\n\n* [Above](#above-builder): \n  Match a value (or length of value) greater than the given amount.\n\n* [After](#after-builder): \n  Define a custom validation function called after a value is processed.\n\n* [All](#all-builder): \n  All shapes must match value.\n\n* [Any](#any-builder): \n  This shape will match any value.\n\n* [Before](#before-builder): \n  Define a custom validation function called before a value is processed.\n\n* [Below](#below-builder): \n  Match a value (or length of value) less than the given amount.\n\n* [Check](#check-builder): \n  Check value with a custom validation function or regular expression.\n\n* [Child](#child-builder): \n  All non-explicit child values of an object must match this shape.\n\n* [Closed](#closed-builder): \n  Allow only explicitly defined elements in an array.\n\n* [Default](#default-builder): \n  Specify a default value.\n\n* [Define](#define-builder): \n  Define a name for a value.\n\n* [Empty](#empty-builder): \n  Allow string values to be empty.\n\n* [Exact](#exact-builder): \n  The value must one of an exact list of values.\n\n* [Func](#func-builder): \n  The value is explicitly a function.\n\n* [Key](#key-builder): \n  The key (or path) of the current object is injected as the value.\n\n* [Max](#max-builder): \n  Match a value (or length of value) less than or equal to the given amount.\n\n* [Min](#min-builder): \n  Match a value (or length of value) greater than or equal to the given amount.\n\n* [Never](#never-builder): \n  This shape will never match anything.\n\n* [Len](#len-builder): \n  Match a value (or length of value) exactly equal to the given amount.\n\n* [One](#one-builder): \n  Exactly one shape (and no more) must match value.\n\n* [Open](#open-builder): \n  Allow arbitrary properties in an object.\n\n* [Optional](#optional-builder): \n  Make a value optional.\n\n* [Skip](#skip-builder): \n  Make a value explicitly optional (no default created).\n\n* [Refer](#refer-builder): \n  Refer to a defined value by name.\n\n* [Rename](#rename-builder): \n  Rename the key of a property.\n\n* [Required](#required-builder): \n  Make a value required.\n\n* [Some](#some-builder): \n  Some shapes (at least one) must match value.\n\n\n---\n#### Above Builder\n<sub><sup>[builders](#shape-builder-reference) [api](#api) [top](#top)</sup></sub>\n\n```ts\nAbove( value: number|string|array|object, child?: any )\n```\n\n* **Standalone:** `Above(2)`\n* **As Parent:** `Above(2, Number)`\n* **As Child:** `Skip(Above(2))`\n* **Chainable:** `Required(Number).Above(2)`\n\nOnly allow values that are above the given value in length. \"Length\" means:\n* Arrays: array length; \n* Strings: string length; \n* Objects: number of keys;\n* Numbers: numeric value;\n* Object with property `length`: numeric value of `length`;\n* Anything else fails.\n\nFor more complex validation, use the [Check](#check-builder) shape builder to write\na custom validation function.\n\n\n```js\nconst { Above } = Gubu\nlet shape = Gubu(Above(2))\n\nshape(3) // PASS: 3 > 2; returns 3\nshape(2) // FAIL: throws 'Value \"2\" for property \"\" must be above 2 (was 2).'\n\nshape('abc') // PASS: 'abc'.length 3 > 2; returns 'abc'\nshape('ab')  // FAIL: 'Value \"ab\" for property \"\" must have length above 2 (was 2).'\n\nshape([1, 2, 3]) // PASS: array length 3 > 2; returns [1, 2, 3]\nshape([1, 2])    // FAIL: throws: 'Value \"[1,2]\" for property \"\" must have length above 2 (was 2).'\n\nshape({ a: 1, b: 2, c: 3 }) // PASS: number of keys 3 > 2; returns { a: 1, b: 2, c: 3 }\nshape({ a: 1, b: 2 })       // FAIL: throws: 'Value \"{a:1,b:2}\" for property \"\" must have length above 2 (was 2).'\n```\n\nSee also: \n[Below](#below-builder), \n[Min](#min-builder), \n[Max](#max-builder), \n[Len](#len-builder), \n[Check](#check-builder).\n\n\n---\n#### After Builder\n<sub><sup>[builders](#shape-builder-reference) [api](#api) [top](#top)</sup></sub>\n\n```ts\nAfter( validate: Validate, child?: any )\n```\n\n* **Standalone:** `After(() => true)`\n* **As Parent:** `After(() => true, {x: 1})`\n* **As Child:** `Required(After(() => true))`\n* **Chainable:** `Skip({x: 1}).After(() => true)`\n\nProvide a validation function that will run **after** the value has been\nprocessed normally. The validation function has the form:\n\n```js\nValidate(value: any, update?: Update, state?: State): boolean\n```\n\nReturn `true` if the value is valid, `false` otherwise. See the \n[Custom Validations](#custom-validation) section.\n\n\n> NOTE: In general you should use the [Check](#check-builder) shape\n> builder for custom validation. This builder is intended for advanced\n> usage.\n\n```js\nconst { After } = Gubu\nlet shape = Gubu(After(v => 0 === v % 2)) // Pass if value is even\n\nshape(2) // PASS: 2 is even; returns 2\nshape()  // PASS: returns undefined (value was not required)\nshape(1) // FAIL: 1 is not even\n\n\nshape = Gubu(After(v => 0 === v.x % 2, Required({x: Number})))\n\nshape({x: 2))   // PASS: 2 is even; returns 2\nshape({x: 1})   // FAIL: 1 is not even\nshape({x: 'X'}) // FAIL: 'X' is not a number\nshape({})       // FAIL: x is required\nshape()         // FAIL: {x: Number} is required\n```\n\nSee also: \n[Check](#check-builder), \n[Before](#before-builder), \n[Update](#update-type), \n[State](#state-type).\n\n\n---\n#### All Builder\n<sub><sup>[builders](#shape-builder-reference) [api](#api) [top](#top)</sup></sub>\n\n```ts\nAll( ...children: any[] )\n```\n\n* **Standalone:** `All(Number, v => v>10)`\n* **As Parent:** INVALID\n* **As Child:** `Skip(All({x: 1}, Min(2)))`\n* **Chainable:** INVALID\n\nTo be valid, the source value must match all of the shapes given as\narguments. All shapes are **always evaluated**, even if some fail, to\nensure all errors are collected.\n\nThis shape builder implicitly creates a [Required](#required-builder)\nvalue. Use the [Skip](#skip-builder) shape builder to\nmake the value skippable (if absent, no default is injected).\n\nTo match exact values, use the [Exact](#exact-builder) shape builder\n(literal values alone will just create optional defaults).\n\n```js\nconst { All } = Gubu\n\nlet shape = Gubu(All(Number, Check(v => v > 10)))\n\nshape(11) // PASS: 11 is a number, and 11 > 10 \nshape(9)  // FAIL: 9 is a number, but 9 < 10 \nshape()   // FAIL: a value is required (implicitly)\n\n// Make the All skippable\nshape = Gubu({ a: Skip(All(Open({ b: String }), Max(2))) })\nshape({ a: { b: 'X' } }) // PASS: returns same object\nshape({}) // PASS: `a` is optional, returns {}\n```\n\nSee also: \n[One](#one-builder), \n[Some](#some-builder), \n[Exact](#exact-builder), \n\n\n\n---\n#### Any Builder\n<sub><sup>[builders](#shape-builder-reference) [api](#api) [top](#top)</sup></sub>\n\n```ts\nAny( child?: any )\n```\n\n* **Standalone:** `Any()`\n* **As Parent:** `Any({x: 1})`\n* **As Child:** `Required(Any())`\n* **Chainable:** `Skip({x: 1}).Any()`\n\nAccept any value. If a child value is provided, it will be used as a\ndefault (when the source value is `undefined`).\n\n```js\nconst { Any } = Gubu\nlet shape = Gubu(Any())\n\nconsole.log(shape(11)) // prints 11\nconsole.log(shape(10)) // prints 10\nconsole.log(shape()) // prints undefined\nconsole.log(shape(null)) // prints null\nconsole.log(shape(NaN)) // prints NaN\nconsole.log(shape({})) // prints {}\nconsole.log(shape([])) // prints []\n\n// with default\nshape = Gubu(Any({x: 1}))\nconsole.log(shape(11)) // prints 11\nconsole.log(shape(10)) // prints 10\nconsole.log(shape()) // prints {x: 1}\n```\n\n\n\n---\n#### Before Builder\n<sub><sup>[builders](#shape-builder-reference) [api](#api) [top](#top)</sup></sub>\n\n```ts\nBefore( validate: Validate, child?: any )\n```\n\n* **Standalone:** `Before(() => true)`\n* **As Parent:** `Before(() => true, {x: 1})`\n* **As Child:** `Required(Before(() => true))`\n* **Chainable:** `Skip({x: 1}).Before(() => true)`\n\nProvide a validation function that will run **before** the value has been\nprocessed normally. The validation function has the form:\n\n```js\nValidate(value: any, update?: Update, state?: State): boolean\n```\n\nReturn `true` if the value is valid, `false` otherwise. See the \n[Custom Validations](#custom-validation) section.\n\nEven if validation fails, the value will still be processed\nnormally. This ensures that all errors, particularly those in child\nvalues, are also captured. To prevent further processing, set\n`Update.done = true`.\n\n> NOTE: In general you should use the [Check](#check-builder) shape\n> builder for custom validation. This builder is intended for advanced\n> usage.\n\n```js\nconst { Before } = Gubu\nlet shape = Gubu(Before(v => 0 === v % 2)) // Pass if value is even\n\nshape(1) // FAIL: 1 is not even\nshape(2) // PASS: 2 is even; returns 2\nshape()  // PASS: returns undefined\n\n\nshape = Gubu(Before(v => 0 === v.x % 2, Required({x: Number})))\n\nshape({x: 1})   // FAIL: 1 is not even\nshape({x: 2))   // PASS: 2 is even; returns 2\nshape({x: 'X'}) // FAIL: 'X' is not a number\nshape({})       // FAIL: x is required\nshape()         // FAIL: {x: Number} is required\n```\n\nSee also: \n[Check](#check-builder), \n[After](#after-builder), \n[Update](#update-type), \n[State](#state-type).\n\n\n\n---\n#### Below Builder\n<sub><sup>[builders](#shape-builder-reference) [api](#api) [top](#top)</sup></sub>\n\n```ts\nBelow( value: number|string, child?: any )\n```\n\n* **Standalone:** `Below(2)`\n* **As Parent:** `Below(2, Number)`\n* **As Child:** `Skip(Below(2))`\n* **Chainable:** `Required(Number).Below(2)`\n\nOnly allow values that are below the given value in length. \"Length\" means:\n* Arrays: array length; \n* Strings: string length; \n* Objects: number of keys;\n* Numbers: numeric value;\n* Object with property `length`: numeric value of `length`;\n* Anything else fails.\n\nFor more complex validation, use the [Check](#check-builder) shape builder to write\na custom validation function.\n\n\n```js\nconst { Below } = Gubu\nlet shape = Gubu(Below(2))\n\nshape(1) // PASS: 1 < 2; returns 1\nshape(2) // FAIL: throws 'Value \"2\" for property \"\" must be below 2 (was 2).'\n\nshape('abc') // PASS: 'abc'.length 1 < 2; returns 'abc' \nshape('ab')  // FAIL: 'Value \"ab\" for property \"\" must have length below 2 (was 2).'\n\nshape([1])    // PASS: array length 1 < 2; returns [1]\nshape([1, 2]) // FAIL: throws: 'Value \"[1, 2]\" for property \"\" must have length below 2 (was 2).'\n```\n\nSee also: \n[Above](#above-builder), \n[Min](#min-builder), \n[Max](#max-builder), \n[Len](#len-builder), \n[Check](#check-builder).\n\n\n\n---\n#### Check Builder\n<sub><sup>[builders](#shape-builder-reference) [api](#api) [top](#top)</sup></sub>\n\n```ts\nCheck( validate: Validate | RegExp, child?: any )\n```\n\n* **Standalone:** `Check(v => v > 10)`\n* **As Parent:** `Check(v => !(v.foo % 2), { foo: 2 })`\n* **As Child:** `Skip('a', (Check(/a/))`\n* **Chainable:** `Skip(String).Check(/a/)`\n\nDefine a custom validation function. Return `true` if the value is\nvalid, `false` otherwise.\n\nThe custom validation function has three arguments:\n* `val`: the value to validate\n* `update`: the [Update](#update-type) data structure\n* `state`: the [State](#state-type) data structure\n\nSee the [custom validation](#custom-validation) section for more\ndetails on these arguments, and usage examples.\n\nEven if validation fails, the value will still be processed\nnormally. This ensures that all errors, particularly those in child\nvalues, are also captured. To prevent further processing, set\n`Update.done = true`.\n\nThis shape builder implicitly creates a [Required](#required-builder)\nvalue. Use the [Skip](#skip-builder) shape builder to make the value\nskippable (if absent, no default is injected).\n\nThe validation function will never be passed an `undefined` value, so\nvalidation functions do not need to check for this case. If you do\nneed to obtain `undefined` values, use the [Before](#before-builder)\nshape builder.\n\nInstead of a validation function, you can also pass a regular\nexpression. The value will be converted to a string (with\n`String(...)`) and matched against the regular expression.\n\n\n```js\nconst { Check } = Gubu\n\nlet shape = Gubu(Check(v => v > 10))\nshape(11) // PASS: 11 > 10 is true, returns 11\nshape(10) // FAIL: 10 > 10 is false\n\nshape = Gubu(Check(/a/))\nshape('bar') // PASS: bar matches /a/\nshape('foo') // FAIL: foo does not match /a/\n```\n\nSee also: \n[Before](#before-builder), \n[After](#after-builder), \n[Update](#update-type), \n[State](#state-type).\n\n\n\n---\n#### Closed Builder\n<sub><sup>[builders](#shape-builder-reference) [api](#api) [top](#top)</sup></sub>\n\n```ts\nClosed( child?: any )\n```\n\n* **Standalone:** `Closed([String])`\n* **As Parent:** INVALID\n* **As Child:** `Required(Closed([Number]))`\n* **Chainable:** `Skip([{x: 1}]).Closed()`\n\nRestricts an array to an explicit set of elements. The array\nis \"closed\" and can only have the elements defined in the shape.\n\n> NOTE: Arrays with two or more elements are already considered\n> closed. The `Closed` shape builder makes it possible to close single\n> element arrays, which would normally be open with the single element\n> defining the general shape of all elements.\n\n```js\nconst { Closed } = Gubu\n\n// Closed array.\nlet shape = Gubu(Closed([Number]))\nshape([1]) // PASS: returns [1]\nshape([1, 2]) // FAIL: element \"2\" is not allowed\n\n// Open array.\nshape = Gubu([Number])\nshape([1]) // PASS: returns [1]\nshape([1, 2]) // PASS: returns [1, 2], all elements are numbers\n```\n\n\n---\n#### Define Builder\n<sub><sup>[builders](#shape-builder-reference) [api](#api) [top](#top)</sup></sub>\n\n```ts\nDefine( options: string | { name: string }, child?: any )\n```\n\n* **Standalone:** `Define('FOO',{x: 1})`\n* **As Parent:** `Define('FOO\", {x: 1})`\n* **As Child:** `Required(Define('FOO', {x: 1}))`\n* **Chainable:** `Skip({x: 1}).Define('FOO')`\n\nDefine a name for a value that can be referenced by the\n[Refer](#refer-builder) shape builder. Definitions must precede usage\nby `Refer`, in depth-first order.\n\nIn order to prevent infinite loops caused by self-reference in\nchildren, `Refer` does *not* inject default values. This is normally\nwhat you want for [recursive shapes](#recursive-shapes).\n\nTo force injection of default values, use the `fill` option (of\n`Refer`). Use this option only when there is no self-reference. Note\nalso that `Refer` does not copy the referred value. Instead it uses\nthe referred shape, thus `fill` only inserts the default value.\n\n```js\nconst { Define, Refer } = Gubu\n\nlet shape = Gubu({ a: Define('foo', 11), b: Refer('foo') })\nconsole.log(shape({ a: 10, b: 12 })) // prints { a: 10, b: 12 })\nconsole.log(shape({ a: 10 })) // prints { a: 10, b: undefined }) - b is not filled!\nconsol","readmeFilename":"README.md"}