diff --git a/.editorconfig b/.editorconfig index 99cd0f5..af61c4a 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,3 +1,5 @@ +[*] charset = utf-8 indent_size = 3 -indent_style = space \ No newline at end of file +indent_style = space +insert_final_newline = true \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 1baaa85..8fa4103 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,24 +1,24 @@ { "name": "@hibas123/realtimedb", - "version": "2.0.0-beta.8", + "version": "2.0.0-beta.9", "lockfileVersion": 1, "requires": true, "dependencies": { "@hibas123/logging": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@hibas123/logging/-/logging-2.1.2.tgz", - "integrity": "sha512-U3DcLa+CCfE5wflrYcCiMGfzTVPsRpgfbTIa34i6LBdyAjSYCvDhPKH5ERfB07sMarOKmkQ0EC2Nrx9UHJD+Hw==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@hibas123/logging/-/logging-2.1.5.tgz", + "integrity": "sha512-sZ+BVepmWz8AmRXd1J4i9Ut+XxpkUwjfC0zx3gYDQhRElPg56+vGTm1AUwBxiYmAqz8L6hTz62OVF1PFetXyqw==", "requires": { - "@hibas123/utils": "^2.1.1" + "@hibas123/utils": "^2.2.3" } }, "@hibas123/nodelogging": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@hibas123/nodelogging/-/nodelogging-2.1.2.tgz", - "integrity": "sha512-QoPr9pny7JJ6X5gHBvEztn1a0DYisNaHQZuG0Rzg4OeiHmsK/QDUgSkDpzmUemb0gD/wgW0um3Ht7KBsOAdY5A==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@hibas123/nodelogging/-/nodelogging-2.1.5.tgz", + "integrity": "sha512-yOLNJxlH9sVdm6uOVvsVRXX0WOIjUSpv6eo/6ZoHjuoNdopFhkz4TSrFiEC/5NSprnyzttmsZezn6H+sYhdRow==", "requires": { - "@hibas123/logging": "^2.1.2", - "@hibas123/utils": "^2.1.1" + "@hibas123/logging": "^2.1.5", + "@hibas123/utils": "^2.2.3" } }, "@hibas123/utils": { @@ -42,9 +42,9 @@ } }, "@types/body-parser": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.17.1.tgz", - "integrity": "sha512-RoX2EZjMiFMjZh9lmYrwgoP9RTpAjSHiJxdp4oidAQVO02T7HER3xj9UKue5534ULWeqVEkujhWcyvUce+d68w==", + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", "dev": true, "requires": { "@types/connect": "*", @@ -52,9 +52,9 @@ } }, "@types/connect": { - "version": "3.4.32", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.32.tgz", - "integrity": "sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg==", + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.33.tgz", + "integrity": "sha512-2+FrkXY4zllzTNfJth7jOqEHC+enpLeGslEhpnTAkg21GkRrWV4SsAtqchtT4YS9/nODBU2/ZfsBY2X4J/dX7A==", "dev": true, "requires": { "@types/node": "*" @@ -87,9 +87,9 @@ "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==" }, "@types/express": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.2.tgz", - "integrity": "sha512-5mHFNyavtLoJmnusB8OKJ5bshSzw+qkMIBAobLrIM48HJvunFva9mOa6aBwh64lBFyNwBbs0xiEFuj4eU/NjCA==", + "version": "4.17.3", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.3.tgz", + "integrity": "sha512-I8cGRJj3pyOLs/HndoP+25vOqhqWkAZsWMEmq1qXy/b/M3ppufecUwaK2/TVDVxcV61/iSdhykUjQQ2DLSrTdg==", "dev": true, "requires": { "@types/body-parser": "*", @@ -98,9 +98,9 @@ } }, "@types/express-serve-static-core": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.0.tgz", - "integrity": "sha512-Xnub7w57uvcBqFdIGoRg1KhNOeEj0vB6ykUM7uFWyxvbdE89GFyqgmUcanAriMr4YOxNFZBAWkfcWIb4WBPt3g==", + "version": "4.17.3", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.3.tgz", + "integrity": "sha512-sHEsvEzjqN+zLbqP+8OXTipc10yH1QLR+hnr5uw29gi9AhCAAAdri8ClNV7iMdrJrIzXIQtlkPvq8tJGhj3QJQ==", "dev": true, "requires": { "@types/node": "*", @@ -123,24 +123,24 @@ "dev": true }, "@types/jsonwebtoken": { - "version": "8.3.5", - "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.3.5.tgz", - "integrity": "sha512-VGM1gb+LwsQ5EPevvbvdnKncajBdYqNcrvixBif1BsiDQiSF1q+j4bBTvKC6Bt9n2kqNSx+yNTY2TVJ360E7EQ==", + "version": "8.3.8", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.3.8.tgz", + "integrity": "sha512-g2ke5+AR/RKYpQxd+HJ2yisLHGuOV0uourOcPtKlcT5Zqv4wFg9vKhFpXEztN4H/6Y6RSUKioz/2PTFPP30CTA==", "dev": true, "requires": { "@types/node": "*" } }, "@types/keygrip": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.1.tgz", - "integrity": "sha1-/1QEYtL7TQqIRBzq8n0oewHD2Hg=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.2.tgz", + "integrity": "sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw==", "dev": true }, "@types/koa": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.11.0.tgz", - "integrity": "sha512-Hgx/1/rVlJvqYBrdeCsS7PDiR2qbxlMt1RnmNWD4Uxi5FF9nwkYqIldo7urjc+dfNpk+2NRGcnAYd4L5xEhCcQ==", + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.11.2.tgz", + "integrity": "sha512-2UPelagNNW6bnc1I5kIzluCaheXRA9S+NyOdXEFFj9Az7jc15ek5V03kb8OTbb3tdZ5i2BIJObe86PhHvpMolg==", "dev": true, "requires": { "@types/accepts": "*", @@ -161,9 +161,9 @@ } }, "@types/koa-router": { - "version": "7.0.42", - "resolved": "https://registry.npmjs.org/@types/koa-router/-/koa-router-7.0.42.tgz", - "integrity": "sha512-mggrNY7Ywwjt7QjaMAlbb1ixE+v7AFskOeyKdmZT/NvPVEAo48gYUxIcF8ILlMc3eg1bo6SxNoUcbxhTv7edrA==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@types/koa-router/-/koa-router-7.4.0.tgz", + "integrity": "sha512-CkNyhGOCJ6rpBEG0rlSQhwHsHNwMzGLE49tV3jE5f0TvMzy/SmoCAIlHWdOLs8Mro+BqtKFH6e/lDaibWkydag==", "dev": true, "requires": { "@types/koa": "*" @@ -180,9 +180,9 @@ } }, "@types/levelup": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@types/levelup/-/levelup-3.1.1.tgz", - "integrity": "sha512-LjvlfctJYj23Xuqq3jCT8ZPSUSSgDcRJg8+XFDBasoYzefFbB4cHzlDmBVjc2rBOYvklpYHJRayD0jBsbJLD9w==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@types/levelup/-/levelup-4.3.0.tgz", + "integrity": "sha512-h82BoajhjU/zwLoM4BUBX/SCodCFi1ae/ZlFOYh5Z4GbHeaXj9H709fF1LYl/StrK8KSwnJOeMRPo9lnC6sz4w==", "dev": true, "requires": { "@types/abstract-leveldown": "*", @@ -205,9 +205,9 @@ } }, "@types/node": { - "version": "12.12.14", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.14.tgz", - "integrity": "sha512-u/SJDyXwuihpwjXy7hOOghagLEV1KdAST6syfnOk6QZAMzZuWZqXy5aYYZbh8Jdpd4escVFP0MvftHNDb9pruA==" + "version": "13.9.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.9.3.tgz", + "integrity": "sha512-01s+ac4qerwd6RHD+mVbOEsraDHSgUaefQlEdBbUolnQFjKwCr7luvAlEwW1RFojh67u0z4OUTjPn9LEl4zIkA==" }, "@types/range-parser": { "version": "1.2.3", @@ -226,9 +226,9 @@ } }, "@types/ws": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-6.0.4.tgz", - "integrity": "sha512-PpPrX7SZW9re6+Ha8ojZG4Se8AZXgf0GK6zmfqEuCsY49LFDNXO3SByp44X3dFEqtB73lkCDAdUazhAjVPiNwg==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.2.3.tgz", + "integrity": "sha512-VT/GK7nvDA7lfHy40G3LKM+ICqmdIsBLBHGXcWD97MtqQEjNMX+7Gudo8YGpaSlYdTX7IFThhCE8Jx09HegymQ==", "dev": true, "requires": { "@types/node": "*" @@ -266,12 +266,39 @@ "dev": true, "requires": { "string-width": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } } }, "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, "ansi-styles": { @@ -298,11 +325,6 @@ "picomatch": "^2.0.4" } }, - "async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" - }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -335,11 +357,36 @@ "widest-line": "^2.0.0" }, "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, "camelcase": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } } } }, @@ -425,19 +472,19 @@ } }, "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.1.tgz", + "integrity": "sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==", "dev": true, "requires": { "anymatch": "~3.1.1", "braces": "~3.0.2", - "fsevents": "~2.1.1", + "fsevents": "~2.1.2", "glob-parent": "~5.1.0", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" + "readdirp": "~3.3.0" } }, "ci-info": { @@ -453,14 +500,14 @@ "dev": true }, "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", "dev": true, "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" } }, "co": { @@ -479,12 +526,6 @@ "type-is": "^1.6.14" } }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -513,9 +554,9 @@ "dev": true }, "concurrently": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-5.0.0.tgz", - "integrity": "sha512-1yDvK8mduTIdxIxV9C60KoiOySUl/lfekpdbI+U5GXaPrgdffEavFa9QZB3vh68oWOpbCC+TuvxXV9YRPMvUrA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-5.1.0.tgz", + "integrity": "sha512-9ViZMu3OOCID3rBgU31mjBftro2chOop0G2u1olq1OuwRBVRw/GxHTg80TVJBUTJfoswMmEUeuOg1g1yu1X2dA==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -524,9 +565,9 @@ "read-pkg": "^4.0.1", "rxjs": "^6.5.2", "spawn-command": "^0.0.2-1", - "supports-color": "^4.5.0", - "tree-kill": "^1.2.1", - "yargs": "^12.0.5" + "supports-color": "^6.1.0", + "tree-kill": "^1.2.2", + "yargs": "^13.3.0" } }, "configstore": { @@ -582,14 +623,12 @@ } }, "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", "dev": true, "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", + "lru-cache": "^4.0.1", "shebang-command": "^1.2.0", "which": "^1.2.9" } @@ -601,15 +640,16 @@ "dev": true }, "date-fns": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.4.1.tgz", - "integrity": "sha512-2RhmH/sjDSCYW2F3ZQxOUx/I7PvzXpi89aQL2d3OAxSTwLx6NilATeUbe0menFE3Lu5lFkOFci36ivimwYHHxw==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.11.0.tgz", + "integrity": "sha512-8P1cDi8ebZyDxUyUprBXwidoEtiQAawYPGvpfb+Dg0G6JrQ+VozwOmm91xYC0vAv1+0VmLehEPb+isg4BGUFfA==", "dev": true }, "debug": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, "requires": { "ms": "^2.1.1" }, @@ -617,7 +657,8 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true } } }, @@ -707,20 +748,17 @@ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, "errno": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", @@ -755,13 +793,13 @@ "dev": true }, "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", "dev": true, "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", "is-stream": "^1.1.0", "npm-run-path": "^2.0.0", "p-finally": "^1.0.0", @@ -805,24 +843,21 @@ "optional": true }, "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true }, "glob-parent": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", - "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", "dev": true, "requires": { "is-glob": "^4.0.1" @@ -854,14 +889,6 @@ "timed-out": "^4.0.0", "unzip-response": "^2.0.1", "url-parse-lax": "^1.0.0" - }, - "dependencies": { - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - } } }, "graceful-fs": { @@ -871,21 +898,14 @@ "dev": true }, "handlebars": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.3.tgz", - "integrity": "sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA==", + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.3.tgz", + "integrity": "sha512-SRGwSYuNfx8DwHD/6InAPzD6RgeruWLT+B8e8a7gGs8FWgHzlExpTFMEq2IA6QpAfOClpKHy6+8IqTjeBCu6Kg==", "requires": { "neo-async": "^2.6.0", "optimist": "^0.6.1", "source-map": "^0.6.1", "uglify-js": "^3.1.4" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } } }, "has-flag": { @@ -895,9 +915,9 @@ "dev": true }, "hosted-git-info": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", - "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==", + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", "dev": true }, "http-assert": { @@ -968,12 +988,6 @@ "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "dev": true }, - "invert-kv": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", - "dev": true - }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -1079,6 +1093,11 @@ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -1218,25 +1237,30 @@ } }, "koa-router": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/koa-router/-/koa-router-7.4.0.tgz", - "integrity": "sha512-IWhaDXeAnfDBEpWS6hkGdZ1ablgr6Q6pGdXCyK38RbzuH4LkUOpPqPw+3f8l8aTDrQmBQ7xJc0bs2yV4dzcO+g==", + "version": "8.0.8", + "resolved": "https://registry.npmjs.org/koa-router/-/koa-router-8.0.8.tgz", + "integrity": "sha512-2rNF2cgu/EWi/NV8GlBE5+H/QBoaof83X6Z0dULmalkbt7W610/lyP2EOLVqVrUUFfjsVWL/Ju5TVBcGJDY9XQ==", "requires": { - "debug": "^3.1.0", - "http-errors": "^1.3.1", - "koa-compose": "^3.0.0", - "methods": "^1.0.1", - "path-to-regexp": "^1.1.1", - "urijs": "^1.19.0" + "debug": "^4.1.1", + "http-errors": "^1.7.3", + "koa-compose": "^4.1.0", + "methods": "^1.1.2", + "path-to-regexp": "1.x", + "urijs": "^1.19.2" }, "dependencies": { - "koa-compose": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/koa-compose/-/koa-compose-3.2.1.tgz", - "integrity": "sha1-qFzLQLfZhtjlo0Wzoazo6rz1Tec=", + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "requires": { - "any-promise": "^1.1.0" + "ms": "^2.1.1" } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, @@ -1249,15 +1273,6 @@ "package-json": "^4.0.0" } }, - "lcid": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", - "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", - "dev": true, - "requires": { - "invert-kv": "^2.0.0" - } - }, "level-concat-iterator": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz", @@ -1302,9 +1317,9 @@ } }, "leveldown": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/leveldown/-/leveldown-5.4.1.tgz", - "integrity": "sha512-3lMPc7eU3yj5g+qF1qlALInzIYnkySIosR1AsUKFjL9D8fYbTLuENBAeDRZXIG4qeWOAyqRItOoLu2v2avWiMA==", + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/leveldown/-/leveldown-5.5.1.tgz", + "integrity": "sha512-GoC455/ncfg4yLLItr192HuXpA+CcQ2q9GncXJhewvvlpsBBEegChn5tMPP+kGvJt7u2LuXAd8fY2moQxFD+sQ==", "requires": { "abstract-leveldown": "~6.2.1", "napi-macros": "~2.0.0", @@ -1399,31 +1414,11 @@ "pify": "^3.0.0" } }, - "map-age-cleaner": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", - "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", - "dev": true, - "requires": { - "p-defer": "^1.0.0" - } - }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" }, - "mem": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", - "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", - "dev": true, - "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^2.0.0", - "p-is-promise": "^2.0.0" - } - }, "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -1442,12 +1437,6 @@ "mime-db": "1.40.0" } }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -1458,9 +1447,9 @@ } }, "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, "ms": { @@ -1469,9 +1458,9 @@ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "nanoid": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.1.7.tgz", - "integrity": "sha512-fmS3qwDldm4bE01HCIRqNk+f255CNjnAoeV3Zzzv0KemObHKqYgirVaZA9DtKcjogicWjYcHkJs4D5A8CjnuVQ==" + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.1.11.tgz", + "integrity": "sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==" }, "napi-macros": { "version": "2.0.0", @@ -1488,21 +1477,15 @@ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==" }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, "node-gyp-build": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.1.1.tgz", "integrity": "sha512-dSq1xmcPDKPZ2EED2S6zw/b9NKsqzXRE6dVr8TVQnI3FJOTteUMuqF3Qqs6LZg+mLGYJWqQzMbIjMtJqTv87nQ==" }, "nodemon": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.1.tgz", - "integrity": "sha512-UC6FVhNLXjbbV4UzaXA3wUdbEkUZzLGgMGzmxvWAex5nzib/jhcSHVFlQODdbuUHq8SnnZ4/EABBAbC3RplvPg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.2.tgz", + "integrity": "sha512-GWhYPMfde2+M0FsHnggIHXTqPDHXia32HRhh6H0d75Mt9FKUoCBvumNHr7LdrpPBTKxsWmIEOjoN+P4IU6Hcaw==", "dev": true, "requires": { "chokidar": "^3.2.2", @@ -1564,12 +1547,6 @@ "path-key": "^2.0.0" } }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, "on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", @@ -1578,15 +1555,6 @@ "ee-first": "1.1.1" } }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, "only": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/only/-/only-0.0.2.tgz", @@ -1608,39 +1576,16 @@ } } }, - "os-locale": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", - "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", - "dev": true, - "requires": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" - } - }, - "p-defer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", - "dev": true - }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", "dev": true }, - "p-is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", - "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", - "dev": true - }, "p-limit": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", - "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", + "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", "dev": true, "requires": { "p-try": "^2.0.0" @@ -1713,24 +1658,17 @@ "dev": true }, "path-to-regexp": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", - "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", "requires": { "isarray": "0.0.1" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - } } }, "picomatch": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.1.1.tgz", - "integrity": "sha512-OYMyqkKzK7blWO/+XZYP6w8hH0LDvkBvdvKukti+7kqYFCiEAk+gI3DWnryapc0Dau05ugGTy0foQ6mqn4AHYA==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", "dev": true }, "pify": { @@ -1767,16 +1705,6 @@ "integrity": "sha512-xsMgrUwRpuGskEzBFkH8NmTimbZ5PcPup0LA8JJkHIm2IMUbQcpo3yeLNWVrufEYjh8YwtSVh0xz6UeWc5Oh5A==", "dev": true }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "qs": { "version": "6.8.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.8.0.tgz", @@ -1817,12 +1745,12 @@ } }, "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.3.0.tgz", + "integrity": "sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ==", "dev": true, "requires": { - "picomatch": "^2.0.4" + "picomatch": "^2.0.7" } }, "registry-auth-token": { @@ -1851,24 +1779,24 @@ "dev": true }, "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", + "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", "dev": true, "requires": { "path-parse": "^1.0.6" } }, "rxjs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", - "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", + "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", "dev": true, "requires": { "tslib": "^1.9.0" @@ -1930,6 +1858,11 @@ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, "spawn-command": { "version": "0.0.2-1", "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", @@ -1974,13 +1907,14 @@ "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" }, "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, "requires": { + "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "strip-ansi": "^5.1.0" } }, "string_decoder": { @@ -1992,12 +1926,12 @@ } }, "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "ansi-regex": "^4.1.0" } }, "strip-eof": { @@ -2013,20 +1947,12 @@ "dev": true }, "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "dev": true, "requires": { - "has-flag": "^2.0.0" - }, - "dependencies": { - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - } + "has-flag": "^3.0.0" } }, "term-size": { @@ -2036,40 +1962,6 @@ "dev": true, "requires": { "execa": "^0.7.0" - }, - "dependencies": { - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", - "dev": true, - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - } } }, "timed-out": { @@ -2102,15 +1994,15 @@ } }, "tree-kill": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.1.tgz", - "integrity": "sha512-4hjqbObwlh2dLyW4tcz0Ymw0ggoaVDMveUB9w8kFSQScdRLo0gxO9J7WFcUBo+W3C1TLdFIEwNOWebgZZ0RH9Q==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", "dev": true }, "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz", + "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==", "dev": true }, "tsscmp": { @@ -2128,33 +2020,25 @@ } }, "typescript": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.2.tgz", - "integrity": "sha512-ml7V7JfiN2Xwvcer+XAf2csGO1bPBdRbFCkYBczNZggrBZ9c7G3riSUeJmqEU5uOtXNPMhE3n+R4FA/3YOAWOQ==", + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.3.tgz", + "integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==", "dev": true }, "uglify-js": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.7.1.tgz", - "integrity": "sha512-pnOF7jY82wdIhATVn87uUY/FHU+MDUdPLkmGFvGoclQmeu229eTkbG5gjGGBi3R7UuYYSEeYXY/TTY5j2aym2g==", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.8.0.tgz", + "integrity": "sha512-ugNSTT8ierCsDHso2jkBHXYrU8Y5/fY2ZUprfrJUiD7YpuFvV4jODLFmb3h4btQjqr5Nh4TX4XtgDfCU1WdioQ==", "optional": true, "requires": { "commander": "~2.20.3", "source-map": "~0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "optional": true - } } }, "undefsafe": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz", - "integrity": "sha1-Il9rngM3Zj4Njnz9aG/Cg2zKznY=", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz", + "integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==", "dev": true, "requires": { "debug": "^2.2.0" @@ -2210,9 +2094,9 @@ } }, "urijs": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.1.tgz", - "integrity": "sha512-xVrGVi94ueCJNrBSTjWqjvtgvl3cyOTThp2zaMaFNGp3F542TR6sM3f2o8RqZl+AwteClSVmoCyt0ka4RjQOQg==" + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.2.tgz", + "integrity": "sha512-s/UIq9ap4JPZ7H1EB5ULo/aOUbWqfDi7FKzMC2Nz+0Si8GiT1rIEaprt8hy3Vy2Ex2aJPpOQv4P4DuOZ+K1c6w==" }, "url-parse-lax": { "version": "1.0.0", @@ -2274,6 +2158,33 @@ "dev": true, "requires": { "string-width": "^2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } } }, "wordwrap": { @@ -2282,58 +2193,16 @@ "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" }, "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", "dev": true, "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" } }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, "write-file-atomic": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", @@ -2346,12 +2215,9 @@ } }, "ws": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.0.tgz", - "integrity": "sha512-+SqNqFbwTm/0DC18KYzIsMTnEWpLwJsiasW/O17la4iDRRIO9uaHbvKiAS3AHgTiuuWerK/brj4O6MYZkei9xg==", - "requires": { - "async-limiter": "^1.0.0" - } + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.3.tgz", + "integrity": "sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ==" }, "xdg-basedir": { "version": "3.0.0", @@ -2377,29 +2243,27 @@ "dev": true }, "yargs": { - "version": "12.0.5", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", - "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", "dev": true, "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.2.0", + "cliui": "^5.0.0", "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.0.0", + "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", + "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", - "string-width": "^2.0.0", + "string-width": "^3.0.0", "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^11.1.1" + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" } }, "yargs-parser": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", - "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", "dev": true, "requires": { "camelcase": "^5.0.0", diff --git a/package.json b/package.json index de11746..1ace980 100644 --- a/package.json +++ b/package.json @@ -17,31 +17,31 @@ "license": "ISC", "devDependencies": { "@types/dotenv": "^8.2.0", - "@types/jsonwebtoken": "^8.3.5", - "@types/koa": "^2.11.0", - "@types/koa-router": "^7.0.42", + "@types/jsonwebtoken": "^8.3.8", + "@types/koa": "^2.11.2", + "@types/koa-router": "^7.4.0", "@types/leveldown": "^4.0.2", - "@types/levelup": "^3.1.1", + "@types/levelup": "^4.3.0", "@types/nanoid": "^2.1.0", - "@types/node": "^12.12.14", - "@types/ws": "^6.0.4", - "concurrently": "^5.0.0", - "nodemon": "^2.0.1", - "typescript": "^3.7.2" + "@types/node": "^13.9.3", + "@types/ws": "^7.2.3", + "concurrently": "^5.1.0", + "nodemon": "^2.0.2", + "typescript": "^3.8.3" }, "dependencies": { - "@hibas123/nodelogging": "^2.1.2", + "@hibas123/nodelogging": "^2.1.5", "@hibas123/utils": "^2.2.3", "dotenv": "^8.2.0", - "handlebars": "^4.5.3", + "handlebars": "^4.7.3", "jsonwebtoken": "^8.5.1", "koa": "^2.11.0", "koa-body": "^4.1.1", - "koa-router": "^7.4.0", - "leveldown": "^5.4.1", + "koa-router": "^8.0.8", + "leveldown": "^5.5.1", "levelup": "^4.3.2", - "nanoid": "^2.1.7", + "nanoid": "^2.1.11", "what-the-pack": "^2.0.3", - "ws": "^7.2.0" + "ws": "^7.2.3" } -} \ No newline at end of file +} diff --git a/src/database/query.ts b/src/database/query.ts index 89d2811..a05c077 100644 --- a/src/database/query.ts +++ b/src/database/query.ts @@ -7,7 +7,12 @@ import Session from "./session"; import { LevelUpChain } from "levelup"; export type IWriteQueries = "set" | "update" | "delete" | "add"; -export type ICollectionQueries = "get" | "add" | "keys" | "delete-collection" | "list"; +export type ICollectionQueries = + | "get" + | "add" + | "keys" + | "delete-collection" + | "list"; export type IDocumentQueries = "get" | "set" | "update" | "delete"; export interface ITypedQuery { @@ -17,21 +22,30 @@ export interface ITypedQuery { options?: any; } -export type IQuery = ITypedQuery; +export type IQuery = ITypedQuery< + ICollectionQueries | IDocumentQueries | "snapshot" +>; export const MP = MSGPack.initialize(2 ** 20); -const ALPHABET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; +const ALPHABET = + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; const { encode, decode } = MP; -type Runner = (collection: string, document: string, batch: LevelUpChain, collectionKey: string) => any; +type Runner = ( + collection: string, + document: string, + batch: LevelUpChain, + collectionKey: string +) => any; interface IPreparedQuery { createCollection: boolean; needDocument: boolean; batchCompatible: boolean; runner: Runner; + permission: "write" | "read"; additionalLock?: string[]; } @@ -46,7 +60,9 @@ export abstract class Query { * @param path Path to be checked */ private validatePath(path: string[]) { - return path.every(e => (e.match(/[^a-zA-Z0-9_\-\<\>]/g) || []).length === 0); + return path.every( + e => (e.match(/[^a-zA-Z0-9_\-\<\>]/g) || []).length === 0 + ); } public changes: Change[] = []; @@ -55,14 +71,24 @@ export abstract class Query { public readonly needDocument: boolean; public readonly batchCompatible: boolean; public readonly additionalLock?: string[]; + public readonly permission: string; private readonly _runner: Runner; - constructor(protected database: Database, protected session: Session, protected query: IQuery, snapshot = false) { + constructor( + protected database: Database, + protected session: Session, + protected query: IQuery, + snapshot = false + ) { if (query.path.length > 10) { - throw new QueryError("Path is to long. Path is only allowed to be 10 Layers deep!"); + throw new QueryError( + "Path is to long. Path is only allowed to be 10 Layers deep!" + ); } if (!this.validatePath(query.path)) { - throw new QueryError("Path can only contain a-z A-Z 0-9 '-' '-' '<' and '>' "); + throw new QueryError( + "Path can only contain a-z A-Z 0-9 '-' '-' '<' and '>' " + ); } if (!snapshot) { @@ -80,75 +106,113 @@ export abstract class Query { protected getDoc(collection: string, document: string) { return this.database.data .get(Database.getKey(collection, document), { asBuffer: true }) - .then(res => decode(res as Buffer)).catch(resNull); + .then(res => decode(res as Buffer)) + .catch(resNull); } - protected sendChange(collection: string, document: string, type: ChangeTypes, data: any) { + protected sendChange( + collection: string, + document: string, + type: ChangeTypes, + data: any + ) { let change: Change = { type, document, collection, data, sender: this.session.id - } + }; this.changes.push(change); } - protected static getConstructorParams(query: Query): [Database, Session, IQuery] { + protected static getConstructorParams( + query: Query + ): [Database, Session, IQuery] { return [query.database, query.session, query.query]; } protected abstract checkChange(change: Change): boolean; - protected abstract firstSend(collection: string, document: string): Promise; + protected abstract firstSend( + collection: string, + document: string + ): Promise; - public run(collection: string, document: string, batch: LevelUpChain, collectionKey: string) { - return this._runner.call(this, collection, document, batch, collectionKey); + public run( + collection: string, + document: string, + batch: LevelUpChain, + collectionKey: string + ) { + let perm = this.database.rules.hasPermission( + this.query.path, + this.session + ); + if (this.permission === "read" && !perm.read) { + throw new QueryError("No permission!"); + } else if (this.permission === "write" && !perm.write) { + throw new QueryError("No permission!"); + } + return this._runner.call( + this, + collection, + document, + batch, + collectionKey + ); } - public async snapshot(onChange: (change: (DocRes & { type: ChangeTypes })[]) => void) { + public async snapshot( + onChange: (change: (DocRes & { type: ChangeTypes })[]) => void + ) { + let perm = this.database.rules.hasPermission( + this.query.path, + this.session + ); + if (this.permission === "read" && !perm.read) { + throw new QueryError("No permission!"); + } + const receivedChanges = (changes: Change[]) => { - let res = changes.filter(change => this.checkChange(change)).map(change => { - return { - id: change.document, - data: change.data, - type: change.type - } - }) - if (res.length > 0) - onChange(res); + let res = changes + .filter(change => this.checkChange(change)) + .map(change => { + return { + id: change.document, + data: change.data, + type: change.type + }; + }); + if (res.length > 0) onChange(res); }; const unsub = this.database.collectionChangeListener.subscribe(change => { if (change.key === collectionKey) { - if (change.type === "create") - addSubscriber(change.id); - else - removeSubscriber(); // Send delete for all elements (Don't know how to do this...) + if (change.type === "create") addSubscriber(change.id); + else removeSubscriber(); // Send delete for all elements (Don't know how to do this...) } - }) + }); - - let { collection, document, collectionKey } = await this.database.resolve(this.query.path) + let { collection, document, collectionKey } = await this.database.resolve( + this.query.path + ); let oldKey: string = undefined; const removeSubscriber = () => { - if (!oldKey) - return; + if (!oldKey) return; let s = this.database.changeListener.get(oldKey); if (s) { s.delete(receivedChanges); - if (s.size <= 0) - this.database.changeListener.delete(oldKey); + if (s.size <= 0) this.database.changeListener.delete(oldKey); } oldKey = undefined; - } + }; - const addSubscriber = (collection: string) => { + const addSubscriber = () => { let key = Database.getKey(collection, document); if (oldKey !== key) { - if (oldKey !== undefined) - removeSubscriber(); + if (oldKey !== undefined) removeSubscriber(); let s = this.database.changeListener.get(key); if (!s) { @@ -158,10 +222,10 @@ export abstract class Query { s.add(receivedChanges); } - } + }; if (collection) { - addSubscriber(collection); + addSubscriber(); } return { @@ -170,7 +234,7 @@ export abstract class Query { removeSubscriber(); }, value: await this.firstSend(collection, document) - } + }; } } @@ -178,7 +242,7 @@ interface UpdateData { [path: string]: { type: "value" | "timestamp" | "increment" | "push"; value: any; - } + }; } export class DocumentQuery extends Query { prepare(query: IQuery): IPreparedQuery { @@ -189,29 +253,33 @@ export class DocumentQuery extends Query { batchCompatible: false, createCollection: false, needDocument: false, + permission: "read", runner: this.get - } + }; case "set": return { batchCompatible: true, createCollection: true, needDocument: true, + permission: "write", runner: this.set - } + }; case "update": return { batchCompatible: true, createCollection: true, needDocument: true, + permission: "write", runner: this.update - } + }; case "delete": return { batchCompatible: true, createCollection: false, needDocument: true, + permission: "write", runner: this.delete - } + }; default: throw new Error("Invalid query type: " + type); } @@ -225,22 +293,28 @@ export class DocumentQuery extends Query { return this.getDoc(collection, document); } - private async set(collection: string, document: string, batch?: LevelUpChain) { + private async set( + collection: string, + document: string, + batch?: LevelUpChain + ) { const { data, options } = this.query; - if (data === null) - return this.delete(collection, document, batch); + if (data === null) return this.delete(collection, document, batch); - - let isNew = !(await this.getDoc(collection, document)) - batch.put(Database.getKey(collection, document), encode(data)) - this.sendChange(collection, document, isNew ? "added" : "modified", data) + let isNew = !(await this.getDoc(collection, document)); + batch.put(Database.getKey(collection, document), encode(data)); + this.sendChange(collection, document, isNew ? "added" : "modified", data); } - private async update(collection: string, document: string, batch?: LevelUpChain) { + private async update( + collection: string, + document: string, + batch?: LevelUpChain + ) { const updateData: UpdateData = this.query.data; let data = await this.getDoc(collection, document); - let isNew = false + let isNew = false; if (!data) { isNew = true; data = {}; @@ -252,8 +326,7 @@ export class DocumentQuery extends Query { let parts = path.split("."); while (parts.length > 1) { let seg = parts.shift(); - if (!data[seg]) - data[seg] = {} + if (!data[seg]) data[seg] = {}; d = data[seg]; } @@ -290,23 +363,29 @@ export class DocumentQuery extends Query { } if (batch) { - batch.put(Database.getKey(collection, document), encode(data)) + batch.put(Database.getKey(collection, document), encode(data)); } else { - await this.database.data - .put(Database.getKey(collection, document), encode(data)) + await this.database.data.put( + Database.getKey(collection, document), + encode(data) + ); } - this.sendChange(collection, document, isNew ? "added" : "modified", data) + this.sendChange(collection, document, isNew ? "added" : "modified", data); } - private async delete(collection: string, document: string, batch?: LevelUpChain) { + private async delete( + collection: string, + document: string, + batch?: LevelUpChain + ) { if (batch) { - batch.del(Database.getKey(collection, document)) + batch.del(Database.getKey(collection, document)); } else { await this.database.data.del(Database.getKey(collection, document)); } - this.sendChange(collection, document, "deleted", null) + this.sendChange(collection, document, "deleted", null); } checkChange(change: Change) { @@ -324,19 +403,19 @@ export class DocumentQuery extends Query { type FieldPath = string; type WhereFilterOp = - | '<' - | '<=' - | '==' - | '>=' - | '>' - | 'array-contains' - | 'in' - | 'array-contains-any'; + | "<" + | "<=" + | "==" + | ">=" + | ">" + | "array-contains" + | "in" + | "array-contains-any"; interface IQueryWhereVerbose { - fieldPath: FieldPath, - opStr: WhereFilterOp, - value: any + fieldPath: FieldPath; + opStr: WhereFilterOp; + value: any; } type IQueryWhereArray = [FieldPath, WhereFilterOp, any]; @@ -346,53 +425,55 @@ type IQueryWhere = IQueryWhereArray | IQueryWhereVerbose; export class CollectionQuery extends Query { private _addId: string; - prepare(query): IPreparedQuery { switch (query.type as ICollectionQueries) { case "add": - this._addId = nanoid(ALPHABET, 32) + this._addId = nanoid(ALPHABET, 32); return { batchCompatible: true, createCollection: true, needDocument: false, runner: this.add, + permission: "write", additionalLock: [...query.path, this._addId] - } + }; case "get": const limit = (query.options || {}).limit; - if (limit) - this.limit = limit; + if (limit) this.limit = limit; const where = (query.options || {}).where; - if (where) - this.where = where; + if (where) this.where = where; return { batchCompatible: false, createCollection: false, needDocument: false, + permission: "read", runner: this.get - } + }; case "keys": return { batchCompatible: false, createCollection: false, needDocument: false, + permission: "read", runner: this.keys - } + }; case "list": return { batchCompatible: false, createCollection: false, needDocument: false, + permission: "read", runner: this.keys - } + }; case "delete-collection": return { batchCompatible: false, createCollection: false, needDocument: false, + permission: "write", runner: this.deleteCollection - } + }; // run = () => q.deleteCollection(); // break; default: @@ -400,32 +481,40 @@ export class CollectionQuery extends Query { } } - private _where: IQueryWhereArray[] = []; public set where(value: IQueryWhere[]) { const invalidWhere = new QueryError("Invalid Where"); - if (!Array.isArray(value)) - throw invalidWhere; + if (!Array.isArray(value)) throw invalidWhere; let c = []; this._where = value.map(cond => { Logging.debug("Query Condition", cond); if (Array.isArray(cond)) { - if (cond.length !== 3) - throw invalidWhere; + if (cond.length !== 3) throw invalidWhere; return cond; } else { - if (cond && typeof cond === "object" && "fieldPath" in cond && "opStr" in cond && "value" in cond) { + if ( + cond && + typeof cond === "object" && + "fieldPath" in cond && + "opStr" in cond && + "value" in cond + ) { return [cond.fieldPath, cond.opStr, cond.value]; } else { throw invalidWhere; } } - }) + }); } public limit: number = -1; - public async add(collection: string, document: string, batch: LevelUpChain, collectionKey: string) { + public async add( + collection: string, + document: string, + batch: LevelUpChain, + collectionKey: string + ) { let q = new DocumentQuery(this.database, this.session, { type: "set", path: this.additionalLock, @@ -442,28 +531,26 @@ export class CollectionQuery extends Query { let lt = Buffer.alloc(gt.length); lt.set(gt); - lt[gt.length - 1] = 0xFF; + lt[gt.length - 1] = 0xff; return { gt, lt - } + }; } public async keys(collection: string) { - if (!collection) - return [] + if (!collection) return []; return new Promise((yes, no) => { let keys = []; const stream = this.database.data.createKeyStream({ ...this.getStreamOptions(collection), keyAsBuffer: false - }) + }); stream.on("data", (key: string) => { let s = key.split("/", 2); - if (s.length > 1) - keys.push(s[1]); + if (s.length > 1) keys.push(s[1]); }); stream.on("end", () => yes(keys)); stream.on("error", no); @@ -477,8 +564,7 @@ export class CollectionQuery extends Query { let seg = parts.shift(); d = data[seg]; - if (d === undefined || d === null) - break; // Undefined/Null has no other fields! + if (d === undefined || d === null) break; // Undefined/Null has no other fields! } return d; } @@ -513,21 +599,20 @@ export class CollectionQuery extends Query { default: throw new QueryError("Invalid where operation " + opStr); } - }) + }); } return true; } async get(collection: string) { - if (!collection) - return []; + if (!collection) return []; return new Promise((yes, no) => { const stream = this.database.data.iterator({ ...this.getStreamOptions(collection), keyAsBuffer: false, valueAsBuffer: true - }) + }); let values: DocRes[] = []; @@ -535,16 +620,14 @@ export class CollectionQuery extends Query { if (err) { no(err); stream.end(err => Logging.error(err)); - } - else { + } else { if (!key && !value) { // END - Logging.debug("Checked all!") + Logging.debug("Checked all!"); yes(values); } else { let s = key.split("/", 2); - if (s.length <= 1) - return; + if (s.length <= 1) return; const id = s[1]; @@ -555,9 +638,8 @@ export class CollectionQuery extends Query { id, data }); - } - else { - stream.end((err) => err ? no(err) : yes(values)) + } else { + stream.end(err => (err ? no(err) : yes(values))); return; } } @@ -565,10 +647,10 @@ export class CollectionQuery extends Query { stream.next(onValue); } } - } + }; stream.next(onValue); - }) + }); } checkChange(change: Change) { @@ -576,25 +658,30 @@ export class CollectionQuery extends Query { } firstSend(collection: string) { - return this.get(collection) + return this.get(collection); } public async collections() { - if (!this.session.root) - throw new QueryError("No Permission!"); + if (!this.session.root) throw new QueryError("No Permission!"); return new Promise((yes, no) => { let keys = []; - const stream = this.database.data.createKeyStream({ keyAsBuffer: false }) + const stream = this.database.data.createKeyStream({ + keyAsBuffer: false + }); stream.on("data", (key: string) => keys.push(key.split("/"))); stream.on("end", () => yes(keys)); stream.on("error", no); }); } - public async deleteCollection(collection: string, document: string, _b: LevelUpChain, collectionKey: string) { - if (!this.session.root) - throw new QueryError("No Permission!"); + public async deleteCollection( + collection: string, + document: string, + _b: LevelUpChain, + collectionKey: string + ) { + if (!this.session.root) throw new QueryError("No Permission!"); //TODO: Lock whole collection! let batch = this.database.data.batch(); @@ -615,8 +702,7 @@ export class CollectionQuery extends Query { }); } } finally { - if (batch) - batch.clear(); + if (batch) batch.clear(); } } @@ -629,4 +715,4 @@ export class QueryError extends Error { constructor(message: string) { super(message); } -} \ No newline at end of file +} diff --git a/src/database/rules.ts b/src/database/rules.ts index 59c7849..e640d87 100644 --- a/src/database/rules.ts +++ b/src/database/rules.ts @@ -2,13 +2,15 @@ import Session from "./session"; import Logging from "@hibas123/nodelogging"; interface IRule { - ".write"?: T - ".read"?: T + ".write"?: T; + ".read"?: T; } -type IRuleConfig = { - [segment: string]: IRuleConfig; -} | IRule; +type IRuleConfig = + | IRule + | { + [segment: string]: IRuleConfig; + }; type IRuleRaw = IRuleConfig; type IRuleParsed = IRuleConfig; @@ -17,17 +19,16 @@ const resolve = (value: any) => { if (value === true) { return true; } else if (typeof value === "string") { - } return undefined; -} +}; export class Rules { rules: IRuleParsed; constructor(private config: string) { let parsed: IRuleRaw = JSON.parse(config); - const analyze = (raw: IRuleRaw) => { + const analyse = (raw: IRuleRaw) => { let r: IRuleParsed = {}; if (raw[".read"]) { @@ -47,18 +48,25 @@ export class Rules { } for (let segment in raw) { - if (segment.startsWith(".")) - continue; + if (segment.startsWith(".")) continue; - r[segment] = analyze(raw[segment]); + r[segment] = analyse(raw[segment]); } return r; - } + }; - this.rules = analyze(parsed); + this.rules = analyse(parsed); } - hasPermission(path: string[], session: Session): { read: boolean, write: boolean } { + hasPermission( + path: string[], + session: Session + ): { read: boolean; write: boolean } { + if (session.root) + return { + read: true, + write: true + }; let read = this.rules[".read"] || false; let write = this.rules[".write"] || false; @@ -77,22 +85,21 @@ export class Rules { .find(e => { switch (e) { case "$uid": - if (segment === session.uid) - return true; + if (segment === session.uid) return true; break; } return false; - }) + }); rules = (k ? rules[k] : undefined) || rules[segment] || rules["*"]; if (rules) { if (rules[".read"]) { - read = rules[".read"] + read = rules[".read"]; } if (rules[".write"]) { - read = rules[".write"] + read = rules[".write"]; } } else { break; @@ -102,10 +109,10 @@ export class Rules { return { read: read as boolean, write: write as boolean - } + }; } toJSON() { return this.config; } -} \ No newline at end of file +} diff --git a/src/web/v1/index.ts b/src/web/v1/index.ts index 7668736..14e73ec 100644 --- a/src/web/v1/index.ts +++ b/src/web/v1/index.ts @@ -1,7 +1,11 @@ import * as Router from "koa-router"; import AdminRoute from "./admin"; import { DatabaseManager } from "../../database/database"; -import { NotFoundError, NoPermissionError, BadRequestError } from "../helper/errors"; +import { + NotFoundError, + NoPermissionError, + BadRequestError +} from "../helper/errors"; import Logging from "@hibas123/nodelogging"; import Session from "../../database/session"; import nanoid = require("nanoid"); @@ -28,7 +32,7 @@ V1.post("/db/:database/query", async ctx => { if (db.accesskey) { if (!accesskey || accesskey !== db.accesskey) { - throw new NoPermissionError(""); + throw new NoPermissionError("Invalid Access Key"); } } @@ -36,7 +40,6 @@ V1.post("/db/:database/query", async ctx => { let res = await verifyJWT(authkey, db.publickey); if (!res || !res.uid) { throw new BadRequestError("Invalid JWT"); - return; } else { session.uid = res.uid; } @@ -54,6 +57,6 @@ V1.post("/db/:database/query", async ctx => { throw new BadRequestError(err.message); } throw err; - }) -}) -export default V1; \ No newline at end of file + }); +}); +export default V1;