From 4a7abd4f9c9b72d88c1f304b36a124f0b785c615 Mon Sep 17 00:00:00 2001 From: daffl Date: Sun, 24 Apr 2022 16:16:37 -0700 Subject: [PATCH 1/6] feat(mongodb): Add and update feathers-mongodb as @feathersjs/mongodb --- package-lock.json | 218 ++++++--------- packages/mongodb/LICENSE | 22 ++ packages/mongodb/README.md | 22 ++ packages/mongodb/package.json | 69 +++++ packages/mongodb/src/adapter.ts | 322 ++++++++++++++++++++++ packages/mongodb/src/error-handler.ts | 14 + packages/mongodb/src/index.ts | 42 +++ packages/mongodb/test/index.test.ts | 378 ++++++++++++++++++++++++++ packages/mongodb/tsconfig.json | 9 + 9 files changed, 956 insertions(+), 140 deletions(-) create mode 100644 packages/mongodb/LICENSE create mode 100644 packages/mongodb/README.md create mode 100644 packages/mongodb/package.json create mode 100644 packages/mongodb/src/adapter.ts create mode 100644 packages/mongodb/src/error-handler.ts create mode 100644 packages/mongodb/src/index.ts create mode 100644 packages/mongodb/test/index.test.ts create mode 100644 packages/mongodb/tsconfig.json diff --git a/package-lock.json b/package-lock.json index e9f929cabc..2c9ecde658 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3129,9 +3129,9 @@ } }, "node_modules/@socket.io/component-emitter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.0.0.tgz", - "integrity": "sha512-2pTGuibAXJswAPJjaKisthqS/NOK5ypG4LYT6tEAV0S/mxW0zOIvYvGK0V8w8+SHxAm6vRMSjqSalFXeBAqs+Q==" + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", + "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" }, "node_modules/@szmarczak/http-timer": { "version": "1.1.2", @@ -3427,9 +3427,9 @@ } }, "node_modules/@types/node": { - "version": "17.0.25", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.25.tgz", - "integrity": "sha512-wANk6fBrUwdpY4isjWrKTufkrXdu1D2YHCot2fD/DfWxF5sMrVSA+KN7ydckvaTCh0HiqX9IVl0L5/ZoXg5M7w==" + "version": "17.0.26", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.26.tgz", + "integrity": "sha512-z/FG/6DUO7pnze3AE3TBGIjGGKkvCcGcWINe1C7cADY8hKLJPDYpzsNE37uExQ4md5RFtTCvg+M8Mu1Enyeg2A==" }, "node_modules/@types/node-fetch": { "version": "3.0.2", @@ -5559,11 +5559,6 @@ "babylon": "bin/babylon.js" } }, - "node_modules/backo2": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", - "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -5790,9 +5785,9 @@ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" }, "node_modules/browserslist": { - "version": "4.20.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.2.tgz", - "integrity": "sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA==", + "version": "4.20.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.3.tgz", + "integrity": "sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg==", "funding": [ { "type": "opencollective", @@ -5804,10 +5799,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001317", - "electron-to-chromium": "^1.4.84", + "caniuse-lite": "^1.0.30001332", + "electron-to-chromium": "^1.4.118", "escalade": "^3.1.1", - "node-releases": "^2.0.2", + "node-releases": "^2.0.3", "picocolors": "^1.0.0" }, "bin": { @@ -7286,9 +7281,9 @@ } }, "node_modules/engine.io": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.1.3.tgz", - "integrity": "sha512-rqs60YwkvWTLLnfazqgZqLa/aKo+9cueVfEi/dZ8PyGyaf8TLOxj++4QMIgeG3Gn0AhrWiFXvghsoY9L9h25GA==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.2.0.tgz", + "integrity": "sha512-4KzwW3F3bk+KlzSOY57fj/Jx6LyRQ1nbcyIadehl+AnXjKT7gDO0ORdRi/84ixvMKTym6ZKuxvbzN62HDDU1Lg==", "dependencies": { "@types/cookie": "^0.4.1", "@types/cors": "^2.8.12", @@ -7306,19 +7301,15 @@ } }, "node_modules/engine.io-client": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.1.1.tgz", - "integrity": "sha512-V05mmDo4gjimYW+FGujoGmmmxRaDsrVr7AXA3ZIfa04MWM1jOfZfUwou0oNqhNwy/votUDvGDt4JA4QF4e0b4g==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.2.1.tgz", + "integrity": "sha512-5cu7xubVxEwoB6O9hJ6Zfu990yBVjXfyMlE1ZvfO5L8if3Kvc9bgDNEapV0C5pMp+5Om1UZFnljxoOuFm6dBKA==", "dependencies": { - "@socket.io/component-emitter": "~3.0.0", + "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.1", - "engine.io-parser": "~5.0.0", - "has-cors": "1.1.0", - "parseqs": "0.0.6", - "parseuri": "0.0.6", + "engine.io-parser": "~5.0.3", "ws": "~8.2.3", - "xmlhttprequest-ssl": "~2.0.0", - "yeast": "0.1.2" + "xmlhttprequest-ssl": "~2.0.0" } }, "node_modules/engine.io-client/node_modules/ws": { @@ -9420,11 +9411,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-cors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", - "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=" - }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -14461,16 +14447,6 @@ "protocols": "^1.4.0" } }, - "node_modules/parseqs": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz", - "integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==" - }, - "node_modules/parseuri": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz", - "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==" - }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -16276,15 +16252,15 @@ } }, "node_modules/socket.io": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.4.1.tgz", - "integrity": "sha512-s04vrBswdQBUmuWJuuNTmXUVJhP0cVky8bBDhdkf8y0Ptsu7fKU2LuLbts9g+pdmAdyMMn8F/9Mf1/wbtUN0fg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.0.tgz", + "integrity": "sha512-slTYqU2jCgMjXwresG8grhUi/cC6GjzmcfqArzaH3BN/9I/42eZk9yamNvZJdBfTubkjEdKAKs12NEztId+bUA==", "dependencies": { "accepts": "~1.3.4", "base64id": "~2.0.0", "debug": "~4.3.2", - "engine.io": "~6.1.0", - "socket.io-adapter": "~2.3.3", + "engine.io": "~6.2.0", + "socket.io-adapter": "~2.4.0", "socket.io-parser": "~4.0.4" }, "engines": { @@ -16292,32 +16268,30 @@ } }, "node_modules/socket.io-adapter": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.3.3.tgz", - "integrity": "sha512-Qd/iwn3VskrpNO60BeRyCyr8ZWw9CPZyitW4AQwmRZ8zCiyDiL+znRnWX6tDHXnWn1sJrM1+b6Mn6wEDJJ4aYQ==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz", + "integrity": "sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg==" }, "node_modules/socket.io-client": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.4.1.tgz", - "integrity": "sha512-N5C/L5fLNha5Ojd7Yeb/puKcPWWcoB/A09fEjjNsg91EDVr5twk/OEyO6VT9dlLSUNY85NpW6KBhVMvaLKQ3vQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.5.0.tgz", + "integrity": "sha512-HW61c1G7OrYGxaI79WRn17+b03iBCdvhBj4iqyXHBoL5M8w2MSO/vChsjA93knG4GYEai1/vbXWJna9dzxXtSg==", "dependencies": { - "@socket.io/component-emitter": "~3.0.0", - "backo2": "~1.0.2", + "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.2", - "engine.io-client": "~6.1.1", - "parseuri": "0.0.6", - "socket.io-parser": "~4.1.1" + "engine.io-client": "~6.2.1", + "socket.io-parser": "~4.2.0" }, "engines": { "node": ">=10.0.0" } }, "node_modules/socket.io-client/node_modules/socket.io-parser": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.1.2.tgz", - "integrity": "sha512-j3kk71QLJuyQ/hh5F/L2t1goqzdTL0gvDzuhTuNSwihfuFUrcSji0qFZmJJPtG6Rmug153eOPsUizeirf1IIog==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.0.tgz", + "integrity": "sha512-tLfmEwcEwnlQTxFB7jibL/q2+q8dlVQzj4JdRLJ/W/G1+Fu9VSxCx1Lo+n1HvXxKnM//dUuD0xgiA7tQf57Vng==", "dependencies": { - "@socket.io/component-emitter": "~3.0.0", + "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.1" }, "engines": { @@ -18254,11 +18228,6 @@ "fd-slicer": "~1.1.0" } }, - "node_modules/yeast": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", - "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=" - }, "node_modules/ylru": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/ylru/-/ylru-1.3.2.tgz", @@ -20583,9 +20552,9 @@ "integrity": "sha512-dOlCBKnDw4iShaIsH/bxujKTM18+2TOAsYz+KSc11Am38H4q5Xw8Bbz97ZYdrVNM+um3p7w86Bvvmcn9q+5+eQ==" }, "@socket.io/component-emitter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.0.0.tgz", - "integrity": "sha512-2pTGuibAXJswAPJjaKisthqS/NOK5ypG4LYT6tEAV0S/mxW0zOIvYvGK0V8w8+SHxAm6vRMSjqSalFXeBAqs+Q==" + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", + "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" }, "@szmarczak/http-timer": { "version": "1.1.2", @@ -20873,9 +20842,9 @@ } }, "@types/node": { - "version": "17.0.25", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.25.tgz", - "integrity": "sha512-wANk6fBrUwdpY4isjWrKTufkrXdu1D2YHCot2fD/DfWxF5sMrVSA+KN7ydckvaTCh0HiqX9IVl0L5/ZoXg5M7w==" + "version": "17.0.26", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.26.tgz", + "integrity": "sha512-z/FG/6DUO7pnze3AE3TBGIjGGKkvCcGcWINe1C7cADY8hKLJPDYpzsNE37uExQ4md5RFtTCvg+M8Mu1Enyeg2A==" }, "@types/node-fetch": { "version": "3.0.2", @@ -22680,11 +22649,6 @@ "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" }, - "backo2": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", - "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" - }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -22867,14 +22831,14 @@ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" }, "browserslist": { - "version": "4.20.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.2.tgz", - "integrity": "sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA==", + "version": "4.20.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.3.tgz", + "integrity": "sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg==", "requires": { - "caniuse-lite": "^1.0.30001317", - "electron-to-chromium": "^1.4.84", + "caniuse-lite": "^1.0.30001332", + "electron-to-chromium": "^1.4.118", "escalade": "^3.1.1", - "node-releases": "^2.0.2", + "node-releases": "^2.0.3", "picocolors": "^1.0.0" } }, @@ -24024,9 +23988,9 @@ } }, "engine.io": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.1.3.tgz", - "integrity": "sha512-rqs60YwkvWTLLnfazqgZqLa/aKo+9cueVfEi/dZ8PyGyaf8TLOxj++4QMIgeG3Gn0AhrWiFXvghsoY9L9h25GA==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.2.0.tgz", + "integrity": "sha512-4KzwW3F3bk+KlzSOY57fj/Jx6LyRQ1nbcyIadehl+AnXjKT7gDO0ORdRi/84ixvMKTym6ZKuxvbzN62HDDU1Lg==", "requires": { "@types/cookie": "^0.4.1", "@types/cors": "^2.8.12", @@ -24049,19 +24013,15 @@ } }, "engine.io-client": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.1.1.tgz", - "integrity": "sha512-V05mmDo4gjimYW+FGujoGmmmxRaDsrVr7AXA3ZIfa04MWM1jOfZfUwou0oNqhNwy/votUDvGDt4JA4QF4e0b4g==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.2.1.tgz", + "integrity": "sha512-5cu7xubVxEwoB6O9hJ6Zfu990yBVjXfyMlE1ZvfO5L8if3Kvc9bgDNEapV0C5pMp+5Om1UZFnljxoOuFm6dBKA==", "requires": { - "@socket.io/component-emitter": "~3.0.0", + "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.1", - "engine.io-parser": "~5.0.0", - "has-cors": "1.1.0", - "parseqs": "0.0.6", - "parseuri": "0.0.6", + "engine.io-parser": "~5.0.3", "ws": "~8.2.3", - "xmlhttprequest-ssl": "~2.0.0", - "yeast": "0.1.2" + "xmlhttprequest-ssl": "~2.0.0" }, "dependencies": { "ws": { @@ -25692,11 +25652,6 @@ "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", "dev": true }, - "has-cors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", - "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=" - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -29656,16 +29611,6 @@ "protocols": "^1.4.0" } }, - "parseqs": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz", - "integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==" - }, - "parseuri": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz", - "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==" - }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -31078,42 +31023,40 @@ "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==" }, "socket.io": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.4.1.tgz", - "integrity": "sha512-s04vrBswdQBUmuWJuuNTmXUVJhP0cVky8bBDhdkf8y0Ptsu7fKU2LuLbts9g+pdmAdyMMn8F/9Mf1/wbtUN0fg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.0.tgz", + "integrity": "sha512-slTYqU2jCgMjXwresG8grhUi/cC6GjzmcfqArzaH3BN/9I/42eZk9yamNvZJdBfTubkjEdKAKs12NEztId+bUA==", "requires": { "accepts": "~1.3.4", "base64id": "~2.0.0", "debug": "~4.3.2", - "engine.io": "~6.1.0", - "socket.io-adapter": "~2.3.3", + "engine.io": "~6.2.0", + "socket.io-adapter": "~2.4.0", "socket.io-parser": "~4.0.4" } }, "socket.io-adapter": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.3.3.tgz", - "integrity": "sha512-Qd/iwn3VskrpNO60BeRyCyr8ZWw9CPZyitW4AQwmRZ8zCiyDiL+znRnWX6tDHXnWn1sJrM1+b6Mn6wEDJJ4aYQ==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz", + "integrity": "sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg==" }, "socket.io-client": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.4.1.tgz", - "integrity": "sha512-N5C/L5fLNha5Ojd7Yeb/puKcPWWcoB/A09fEjjNsg91EDVr5twk/OEyO6VT9dlLSUNY85NpW6KBhVMvaLKQ3vQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.5.0.tgz", + "integrity": "sha512-HW61c1G7OrYGxaI79WRn17+b03iBCdvhBj4iqyXHBoL5M8w2MSO/vChsjA93knG4GYEai1/vbXWJna9dzxXtSg==", "requires": { - "@socket.io/component-emitter": "~3.0.0", - "backo2": "~1.0.2", + "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.2", - "engine.io-client": "~6.1.1", - "parseuri": "0.0.6", - "socket.io-parser": "~4.1.1" + "engine.io-client": "~6.2.1", + "socket.io-parser": "~4.2.0" }, "dependencies": { "socket.io-parser": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.1.2.tgz", - "integrity": "sha512-j3kk71QLJuyQ/hh5F/L2t1goqzdTL0gvDzuhTuNSwihfuFUrcSji0qFZmJJPtG6Rmug153eOPsUizeirf1IIog==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.0.tgz", + "integrity": "sha512-tLfmEwcEwnlQTxFB7jibL/q2+q8dlVQzj4JdRLJ/W/G1+Fu9VSxCx1Lo+n1HvXxKnM//dUuD0xgiA7tQf57Vng==", "requires": { - "@socket.io/component-emitter": "~3.0.0", + "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.1" } } @@ -32570,11 +32513,6 @@ "fd-slicer": "~1.1.0" } }, - "yeast": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", - "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=" - }, "ylru": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/ylru/-/ylru-1.3.2.tgz", diff --git a/packages/mongodb/LICENSE b/packages/mongodb/LICENSE new file mode 100644 index 0000000000..59604f46f3 --- /dev/null +++ b/packages/mongodb/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2022 Feathers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/packages/mongodb/README.md b/packages/mongodb/README.md new file mode 100644 index 0000000000..df26a2d75c --- /dev/null +++ b/packages/mongodb/README.md @@ -0,0 +1,22 @@ +# @feathersjs/mongodb + +[![CI](https://github.com/feathersjs/feathers/workflows/CI/badge.svg)](https://github.com/feathersjs/feathers/actions?query=workflow%3ACI) +[![Download Status](https://img.shields.io/npm/dm/@feathersjs/mongodb.svg?style=flat-square)](https://www.npmjs.com/package/@feathersjs/mongodb) + +> Feathers MongoDB service adapter + +## Installation + +``` +npm install @feathersjs/mongodb --save +``` + +## Documentation + +Refer to the [Feathers documentation](https://docs.feathersjs.com) for more details. + +## License + +Copyright (c) 2022 [Feathers contributors](https://github.com/feathersjs/feathers/graphs/contributors) + +Licensed under the [MIT license](LICENSE). diff --git a/packages/mongodb/package.json b/packages/mongodb/package.json new file mode 100644 index 0000000000..cad9336b3c --- /dev/null +++ b/packages/mongodb/package.json @@ -0,0 +1,69 @@ +{ + "name": "@feathersjs/mongodb", + "description": "Feathers MongoDB service adapter", + "version": "0.0.0", + "homepage": "https://feathersjs.com", + "main": "lib/", + "keywords": [ + "feathers", + "feathers-plugin" + ], + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/daffl" + }, + "repository": { + "type": "git", + "url": "git://github.com/feathersjs/feathers.git" + }, + "author": { + "name": "Feathers contributors", + "email": "hello@feathersjs.com", + "url": "https://feathersjs.com" + }, + "contributors": [], + "bugs": { + "url": "https://github.com/feathersjs/feathers/issues" + }, + "engines": { + "node": ">= 14" + }, + "files": [ + "CHANGELOG.md", + "LICENSE", + "README.md", + "src/**", + "lib/**", + "*.d.ts", + "*.js" + ], + "scripts": { + "prepublish": "npm run compile", + "compile": "shx rm -rf lib/ && tsc", + "test": "mocha --config ../../.mocharc.json --recursive test/**.test.ts test/**/*.test.ts" + }, + "directories": { + "lib": "lib" + }, + "publishConfig": { + "access": "public" + }, + "dependencies": { + "@feathersjs/feathers": "^5.0.0-pre.18", + "@feathersjs/adapter-commons": "^5.0.0-pre.18", + "@feathersjs/commons": "^5.0.0-pre.18", + "@feathersjs/errors": "^5.0.0-pre.18" + }, + "peerDependencies": { + "mongodb": "^4.5.0" + }, + "devDependencies": { + "@feathersjs/adapter-tests": "^5.0.0-pre.18", + "@types/mocha": "^9.1.0", + "@types/node": "^17.0.23", + "mocha": "^9.2.2", + "shx": "^0.3.4", + "typescript": "^4.6.3" + } +} diff --git a/packages/mongodb/src/adapter.ts b/packages/mongodb/src/adapter.ts new file mode 100644 index 0000000000..d2b14f363a --- /dev/null +++ b/packages/mongodb/src/adapter.ts @@ -0,0 +1,322 @@ +import { + ObjectId, Collection, CollationOptions, Hint, FindOptions, BulkWriteOptions, + InsertOneOptions, UpdateOptions, DeleteOptions, CountDocumentsOptions, ReplaceOptions +} from 'mongodb' +import { BadRequest, MethodNotAllowed, NotFound } from '@feathersjs/errors' +import { _ } from '@feathersjs/commons' +import { AdapterBase, select, AdapterParams, AdapterServiceOptions, PaginationOptions } from '@feathersjs/adapter-commons' +import { NullableId, Query, Id, Paginated } from '@feathersjs/feathers' +import { errorHandler } from './error-handler' + +export type MongoDBAdapterOptions = { + Model: Collection + disableObjectify?: boolean + useEstimatedDocumentCount?: boolean +} & AdapterServiceOptions + +export interface MongoDBAdapterParams extends AdapterParams { + mongodb?: Partial + options?: BulkWriteOptions|FindOptions|InsertOneOptions|DeleteOptions|CountDocumentsOptions|ReplaceOptions + collation?: CollationOptions + hint?: Hint +} + +// Create the service. +export class MongoDbAdapter, P extends MongoDBAdapterParams = MongoDBAdapterParams> extends AdapterBase { + constructor (options: MongoDBAdapterOptions) { + if (!options) { + throw new Error('MongoDB options have to be provided') + } + + super({ + id: '_id', + ...options + }) + } + + get Model () { + return this.options.Model + } + + set Model (value) { + this.options.Model = value + } + + _objectifyId (id: Id|ObjectId) { + if (this.options.disableObjectify) { + return id + } + + if (this.id === '_id' && ObjectId.isValid(id)) { + id = new ObjectId(id.toString()) + } + + return id + } + + _multiOptions (id: NullableId|ObjectId, params: MongoDBAdapterParams = {}) { + const { query } = this.filterQuery(params) + const options = Object.assign({ multi: true }, params.mongodb || params.options) + + if (id !== null) { + options.multi = false + query.$and = (query.$and || []).concat({ [this.id]: this._objectifyId(id) }) + } + + if (params.collation != null) { + query.collation = params.collation + } + + return { query, options } + } + + _options (params: MongoDBAdapterParams = {}) { + const { filters, query, paginate } = this.filterQuery(params) + const options = Object.assign({}, params.mongodb || params.options) + return { filters, query, paginate, options } + } + + _getSelect (select: string[]|{ [key: string]: number }) { + if (Array.isArray(select)) { + return select.reduce<{ [key: string]: number }>((value, name) => ({ + ...value, + [name]: 1 + }), {}) + } + + return select + } + + async _findOrGet (id: NullableId, params: P) { + return id === null ? await this._find(params) : await this._get(id, params) + } + + _normalizeId (id: NullableId, data: Partial) { + if (this.id === '_id') { + // Default Mongo IDs cannot be updated. The Mongo library handles + // this automatically. + return _.omit(data, this.id) + } else if (id !== null) { + // If not using the default Mongo _id field set the ID to its + // previous value. This prevents orphaned documents. + return { + ...data, + [this.id]: id + } + } + return data + } + + // Map stray records into $set + _remapModifiers (data: { [key: string]: any }) { + let set: { [key: string]: any } = {} + // Step through the rooot + for (const key of Object.keys(data)) { + // Check for keys that aren't modifiers + if (key.charAt(0) !== '$') { + // Move them to set, and remove their record + set[key] = data[key] + delete data[key] + } + // If the '$set' modifier is used, add that to the temp variable + if (key === '$set') { + set = Object.assign(set, data[key]) + delete data[key] + } + } + // If we have a $set, then attach to the data object + if (Object.keys(set).length > 0) { + (data as any).$set = set + } + return data + } + + async _find (params?: P & { paginate?: PaginationOptions }): Promise>; + async _find (params?: P & { paginate: false }): Promise; + async _find (params?: P): Promise|T[]>; + async _find (params: P = {} as P): Promise|T[]> { + // Start with finding all, and limit when necessary. + const { filters, query, paginate, options } = this._options(params) + + if (query[this.id]) { + query[this.id] = this._objectifyId(query[this.id]) + } + + const q = this.Model.find(query, options as FindOptions) + + if (filters.$select) { + q.project(this._getSelect(filters.$select)) + } + + if (filters.$sort) { + q.sort(filters.$sort) + } + + if (params.collation != null) { + q.collation(params.collation) + } + + if (params.hint) { + q.hint(params.hint) + } + + if (filters.$limit) { + q.limit(filters.$limit) + } + + if (filters.$skip) { + q.skip(filters.$skip) + } + + let runQuery = async (total: number) => { + return await q.toArray().then((data: any) => { + return { + total, + limit: filters.$limit, + skip: filters.$skip || 0, + data: data as T[] + } + }) + } + + if (filters.$limit === 0) { + runQuery = async total => { + return await Promise.resolve({ + total, + limit: filters.$limit, + skip: filters.$skip || 0, + data: [] + }) + } + } + + if (paginate && paginate.default) { + if (this.options.useEstimatedDocumentCount && (typeof this.Model.estimatedDocumentCount === 'function')) { + return this.Model.estimatedDocumentCount().then(runQuery) + } + + return this.Model.countDocuments(query, options as CountDocumentsOptions).then(runQuery) + } + + return runQuery(0).then(page => page.data) + } + + async _get (id: Id, params: P = {} as P): Promise { + const { query, options } = this._options(params) + + query.$and = (query.$and || []).concat({ [this.id]: this._objectifyId(id) }) + + return this.Model.findOne(query, options as FindOptions).then(data => { + if (data == null) { + throw new NotFound(`No record found for id '${id}'`) + } + + return data + }).then(select(params, this.id)).catch(errorHandler) + } + + async _create (data: Partial, params?: P): Promise; + async _create (data: Partial[], params?: P): Promise; + async _create (data: Partial|Partial[], _params?: P): Promise; + async _create (data: Partial|Partial[], params: P = {} as P): Promise { + const { options } = this._options(params) + const setId = (item: any) => { + const entry = Object.assign({}, item) + + // Generate a MongoId if we use a custom id + if (this.id !== '_id' && typeof entry[this.id] === 'undefined') { + return { + [this.id]: new ObjectId().toHexString(), + ...entry + } + } + + return entry + } + + if (Array.isArray(data) && !this.allowsMulti('create', params)) { + throw new MethodNotAllowed('Can not create multiple entries') + } + + const promise = Array.isArray(data) + ? this.Model.insertMany(data.map(setId), options as BulkWriteOptions).then(async result => + await Promise.all(Object.values(result.insertedIds).map(async _id => await this.Model.findOne({ _id }, options as FindOptions))) + ) + : this.Model.insertOne(setId(data), options as InsertOneOptions).then(async result => + await this.Model.findOne({ _id: result.insertedId }, options as FindOptions) + ) + + return promise.then(select(params, this.id)).catch(errorHandler) + } + + async _patch (id: null, data: Partial, params?: P): Promise; + async _patch (id: Id, data: Partial, params?: P): Promise; + async _patch (id: NullableId, data: Partial, _params?: P): Promise; + async _patch (id: NullableId, data: Partial, params: P = {} as P): Promise { + const { query, options } = this._multiOptions(id, params) + + if (id === null && !this.allowsMulti('patch', params)) { + throw new MethodNotAllowed('Can not patch multiple entries') + } + + const remapModifier = this._remapModifiers(this._normalizeId(id, data)) + const idParams = { + ...params, + paginate: false + } + const originalItems = await this._findOrGet(id, idParams) + const items = Array.isArray(originalItems) ? originalItems : [originalItems] + const idList = items.map((item: any) => item[this.id]) + const findParams = { + ...params, + paginate: false, + query: { [this.id]: { $in: idList } } + } + + await this.Model.updateMany(query, remapModifier, options as UpdateOptions) + + return this._findOrGet(id, findParams) + .then(select(params, this.id)) + .catch(errorHandler) + } + + async _update (id: Id, data: D, params: P = {} as P): Promise { + if (Array.isArray(data) || id === null) { + return await Promise.reject( + new BadRequest('Not replacing multiple records. Did you mean `patch`?') + ) + } + + const { query, options } = this._multiOptions(id, params) + + await this.Model.replaceOne(query, this._normalizeId(id, data), options as ReplaceOptions) + + return this._findOrGet(id, params) + .then(select(params, this.id)) + .catch(errorHandler) + } + + async _remove (id: null, params?: P): Promise; + async _remove (id: Id, params?: P): Promise; + async _remove (id: NullableId, _params?: P): Promise; + async _remove (id: NullableId, params: P = {} as P): Promise { + const { query, options } = this._multiOptions(id, params) + + if (id === null && !this.allowsMulti('remove', params)) { + throw new MethodNotAllowed('Can not remove multiple entries') + } + + const findParams = Object.assign({}, params, { + paginate: false, + query: params.query + }) + + return this._findOrGet(id, findParams) + .then(async items => { + await this.Model.deleteMany(query, options as DeleteOptions) + return items + }) + .then(select(params, this.id)) + .catch(errorHandler) + } +} diff --git a/packages/mongodb/src/error-handler.ts b/packages/mongodb/src/error-handler.ts new file mode 100644 index 0000000000..9c1b60dbae --- /dev/null +++ b/packages/mongodb/src/error-handler.ts @@ -0,0 +1,14 @@ +import errors from '@feathersjs/errors' +import { MongoError } from 'mongodb' + +export function errorHandler (error: MongoError) { + // See https://github.com/mongodb/mongo/blob/master/docs/errors.md + if (error.name === 'MongoError') { + throw new errors.GeneralError(error, { + name: error.name, + code: error.code + }) + } + + throw error +} diff --git a/packages/mongodb/src/index.ts b/packages/mongodb/src/index.ts new file mode 100644 index 0000000000..63f659f54e --- /dev/null +++ b/packages/mongodb/src/index.ts @@ -0,0 +1,42 @@ +import { PaginationOptions } from '@feathersjs/adapter-commons' +import { Paginated, ServiceMethods, Id, NullableId } from '@feathersjs/feathers' +import { MongoDbAdapter, MongoDBAdapterParams } from './adapter' + +export * from './adapter' +export * from './error-handler' + +export class MongoDBService, P extends MongoDBAdapterParams = MongoDBAdapterParams> + extends MongoDbAdapter implements ServiceMethods, D, P> { + async find (params?: P & { paginate?: PaginationOptions }): Promise>; + async find (params?: P & { paginate: false }): Promise; + async find (params?: P): Promise|T[]>; + async find (params?: P): Promise|T[]> { + return await this._find(params) + } + + async get (id: Id, params?: P): Promise { + return await this._get(id, params) + } + + async create (data: Partial, params?: P): Promise; + async create (data: Partial[], params?: P): Promise; + async create (data: Partial|Partial[], params?: P): Promise { + return await this._create(data, params) + } + + async update (id: Id, data: D, params?: P): Promise { + return await this._update(id, data, params) + } + + async patch (id: Id, data: Partial, params?: P): Promise; + async patch (id: null, data: Partial, params?: P): Promise; + async patch (id: NullableId, data: Partial, params?: P): Promise { + return await this._patch(id, data, params) + } + + async remove (id: Id, params?: P): Promise; + async remove (id: null, params?: P): Promise; + async remove (id: NullableId, params?: P): Promise { + return await this._remove(id, params) + } +} diff --git a/packages/mongodb/test/index.test.ts b/packages/mongodb/test/index.test.ts new file mode 100644 index 0000000000..b4ab04d15a --- /dev/null +++ b/packages/mongodb/test/index.test.ts @@ -0,0 +1,378 @@ +import { Db, MongoClient, ObjectId } from 'mongodb' +import adapterTests from '@feathersjs/adapter-tests' +import assert from 'assert' + +import { feathers } from '@feathersjs/feathers' +import errors from '@feathersjs/errors' +import { MongoDBService } from '../src' + +const testSuite = adapterTests([ + '.options', + '.events', + '._get', + '._find', + '._create', + '._update', + '._patch', + '._remove', + '.get', + '.get + $select', + '.get + id + query', + '.get + NotFound', + '.get + id + query id', + '.find', + '.find + paginate + query', + '.remove', + '.remove + $select', + '.remove + id + query', + '.remove + multi', + '.remove + multi no pagination', + '.remove + id + query id', + '.update', + '.update + $select', + '.update + id + query', + '.update + NotFound', + '.update + id + query id', + '.update + query + NotFound', + '.patch', + '.patch + $select', + '.patch + id + query', + '.patch multiple', + '.patch multiple no pagination', + '.patch multi query same', + '.patch multi query changed', + '.patch + query + NotFound', + '.patch + NotFound', + '.patch + id + query id', + '.create', + '.create + $select', + '.create multi', + 'internal .find', + 'internal .get', + 'internal .create', + 'internal .update', + 'internal .patch', + 'internal .remove', + '.find + equal', + '.find + equal multiple', + '.find + $sort', + '.find + $sort + string', + '.find + $limit', + '.find + $limit 0', + '.find + $skip', + '.find + $select', + '.find + $or', + '.find + $in', + '.find + $nin', + '.find + $lt', + '.find + $lte', + '.find + $gt', + '.find + $gte', + '.find + $ne', + '.find + $gt + $lt + $sort', + '.find + $or nested + $sort', + '.find + paginate', + '.find + paginate + $limit + $skip', + '.find + paginate + $limit 0', + '.find + paginate + params', + 'params.adapter + paginate', + 'params.adapter + multi' +]) + +describe('Feathers MongoDB Service', () => { + type Person = { + _id: string + name: string + age: number, + friends?: string[], + team: string, + $push: { + friends: string + } + } + + type ServiceTypes = { + people: MongoDBService, + 'people-customid': MongoDBService, + } + + const app = feathers() + + let db: Db + let mongoClient: MongoClient + + before(async () => { + const client = await MongoClient.connect('mongodb://localhost:27017/feathers-test') + + mongoClient = client + db = client.db('feathers-test') + + app.use('people', new MongoDBService({ + Model: db.collection('people-customid'), + events: ['testing'] + })) + app.use('people-customid', new MongoDBService({ + Model: db.collection('people-customid'), + id: 'customid', + events: ['testing'] + })) + + app.service('people').Model = db.collection('people') + + db.collection('people-customid').deleteMany({}) + db.collection('people').deleteMany({}) + db.collection('todos').deleteMany({}) + + db.collection('people').createIndex( + { name: 1 }, + { partialFilterExpression: { team: 'blue' } } + ) + }) + + after(async () => { + await db.dropDatabase(); + await mongoClient.close(); + }) + + describe('Service utility functions', () => { + describe('objectifyId', () => { + it('returns an ObjectID instance for a valid ID', () => { + const id = new ObjectId() + const objectify = app.service('people')._objectifyId(id.toString()) + + assert.ok(objectify instanceof ObjectId) + assert.strictEqual(objectify.toString(), id.toString()) + }) + + it('returns an ObjectID instance for a valid ID', () => { + const id = 'non-valid object id' + const objectify = app.service('people')._objectifyId(id.toString()) + + assert.ok(!(objectify instanceof ObjectId)) + assert.strictEqual(objectify, id) + }) + }) + + describe('_multiOptions', () => { + const params = { + query: { + age: 21 + }, + options: { + limit: 5 + } + } + + it('returns valid result when passed an ID', () => { + const id = new ObjectId() + const result = app.service('people')._multiOptions(id, params) + + assert.deepStrictEqual(result.query, { + ...params.query, + $and: [{ _id: id }] + }) + assert.deepStrictEqual(result.options, { + ...params.options, + multi: false + }) + }) + + it('returns original object', () => { + const result = app.service('people')._multiOptions(null, params) + + assert.deepStrictEqual(result.query, params.query) + assert.deepStrictEqual(result.options, { + ...params.options, + multi: true + }) + }) + }) + + describe('_options', () => { + const params = { + query: { + age: 21 + }, + options: { + limit: 5 + } + } + + it('returns original object', () => { + const result = app.service('people')._options(params) + + assert.deepStrictEqual(result.options, params.options) + }) + }) + + describe('getSelect', () => { + const projectFields = { name: 1, age: 1 } + const selectFields = ['name', 'age'] + + it('returns Mongo project object when an array is passed', () => { + const result = app.service('people')._getSelect(selectFields) + + assert.deepStrictEqual(result, projectFields) + }) + + it('returns original object', () => { + const result = app.service('people')._getSelect(projectFields) + + assert.deepStrictEqual(result, projectFields) + }) + }) + }) + + describe('Special collation param', () => { + let peopleService: MongoDBService; + let people: Person[]; + + function indexOfName (results: Person[], name: string) { + let index = 0; + + for (const person of results) { + if (person.name === name) { + return index + } + index++; + } + + return -1; + } + + beforeEach(async () => { + peopleService = app.service('people') + peopleService.options.multi = true + peopleService.options.disableObjectify = true + people = await peopleService.create([ + { name: 'AAA' }, { name: 'aaa' }, { name: 'ccc' } + ]) + }) + + afterEach(async () => { + peopleService.options.multi = false + await Promise.all([ + peopleService.remove(people[0]._id), + peopleService.remove(people[1]._id), + peopleService.remove(people[2]._id) + ]).catch(() => {}) + }) + + it('queries for ObjectId in find', async () => { + const person = await peopleService.create({ name: 'Coerce' }) + const results = await peopleService.find({ + paginate: false, + query: { + _id: new ObjectId(person._id) + } + }) + + assert.strictEqual(results.length, 1) + + await peopleService.remove(person._id) + }) + + it('works with normal string _id', async () => { + const person = await peopleService.create({ + _id: 'lessonKTDA08', + name: 'Coerce' + }) + const result = await peopleService.get(person._id) + + assert.strictEqual(result.name, 'Coerce') + + await peopleService.remove(person._id) + }) + + it('sorts with default behavior without collation param', async () => { + const results = await peopleService.find({ + paginate: false, + query: { $sort: { name: -1 } } + }) + + assert.ok(indexOfName(results, 'aaa') < indexOfName(results, 'AAA')) + }) + + it.skip('sorts using collation param if present', async () => { + const results = await peopleService.find({ + paginate: false, + query: { $sort: { name: -1 } }, + collation: { locale: 'en', strength: 1 } + }) + + assert.ok(indexOfName(results, 'aaa') > indexOfName(results, 'AAA')) + }) + + it('removes with default behavior without collation param', async () => { + await peopleService.remove(null, { query: { name: { $gt: 'AAA' } } }) + + const results = await peopleService.find({ paginate: false }) + + assert.strictEqual(results.length, 1) + assert.strictEqual(results[0].name, 'AAA') + }) + + it('removes using collation param if present', async () => { + await peopleService.remove(null, { + query: { name: { $gt: 'AAA' } }, + collation: { locale: 'en', strength: 1 } + }) + + const results = await peopleService.find({ paginate: false }) + + assert.strictEqual(results.length, 3) + }) + + it('updates with default behavior without collation param', async () => { + const query = { name: { $gt: 'AAA' } } + + const result = await peopleService.patch(null, { age: 99 }, { query }) + + assert.strictEqual(result.length, 2) + result.forEach(person => { + assert.strictEqual(person.age, 99) + }) + }) + + it('updates using collation param if present', async () => { + const result = await peopleService.patch(null, { age: 110 }, { + query: { name: { $gt: 'AAA' } }, + collation: { locale: 'en', strength: 1 } + }) + + assert.strictEqual(result.length, 1) + assert.strictEqual(result[0].name, 'ccc') + }) + + it('pushes to an array using patch', async () => { + const result = await peopleService.patch(null, { $push: { friends: 'Adam' } }, { + query: { name: { $gt: 'AAA' } } + }) + + assert.strictEqual(result[0].friends.length, 1) + + const patched = await peopleService.patch(null, { + $push: { friends: 'Bell' } + }, { query: { name: { $gt: 'AAA' } } }) + + assert.strictEqual(patched[0].friends.length, 2) + }) + + it('overrides default index selection using hint param if present', async () => { + const indexed = await peopleService.create({ name: 'Indexed', team: 'blue' }) + + const result = await peopleService.find({ + paginate: false, + query: {}, + hint: { name: 1 } + }) + + assert.strictEqual(result.length, 1) + + await peopleService.remove(indexed._id) + }) + }) + + testSuite(app, errors, 'people', '_id') + testSuite(app, errors, 'people-customid', 'customid') +}) diff --git a/packages/mongodb/tsconfig.json b/packages/mongodb/tsconfig.json new file mode 100644 index 0000000000..316fd41336 --- /dev/null +++ b/packages/mongodb/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig", + "include": [ + "src/**/*.ts" + ], + "compilerOptions": { + "outDir": "lib" + } +} From 6b864ed47c34ab721ce0259c7edac37f016627eb Mon Sep 17 00:00:00 2001 From: daffl Date: Fri, 29 Apr 2022 08:52:33 -0700 Subject: [PATCH 2/6] Ported MongoDB adapter all tests passing --- package-lock.json | 676 ++++++++++++------ packages/adapter-commons/src/declarations.ts | 17 +- packages/adapter-commons/src/service.ts | 8 +- packages/adapter-commons/test/fixture.ts | 4 +- packages/adapter-commons/test/service.test.ts | 4 +- packages/memory/src/index.ts | 10 +- packages/mongodb/src/adapter.ts | 250 +++---- packages/mongodb/src/error-handler.ts | 2 +- packages/mongodb/src/index.ts | 12 +- packages/mongodb/test/index.test.ts | 101 +-- 10 files changed, 629 insertions(+), 455 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2c9ecde658..539e092609 100644 --- a/package-lock.json +++ b/package-lock.json @@ -89,11 +89,12 @@ } }, "node_modules/@ampproject/remapping": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.2.tgz", - "integrity": "sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.0" + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" }, "engines": { "node": ">=6.0.0" @@ -1795,6 +1796,18 @@ "node": ">=8" } }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "dependencies": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@jridgewell/resolve-uri": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.6.tgz", @@ -1803,6 +1816,14 @@ "node": ">=6.0.0" } }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.0.tgz", + "integrity": "sha512-SfJxIxNVYLTsKwzB3MoOQ1yxf4w/E6MdkvTgrgAt1bfxjSrLUoHMKrDOykwN14q65waezZIdqDneUIPh4/sKxg==", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.11", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", @@ -3427,9 +3448,9 @@ } }, "node_modules/@types/node": { - "version": "17.0.26", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.26.tgz", - "integrity": "sha512-z/FG/6DUO7pnze3AE3TBGIjGGKkvCcGcWINe1C7cADY8hKLJPDYpzsNE37uExQ4md5RFtTCvg+M8Mu1Enyeg2A==" + "version": "17.0.29", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.29.tgz", + "integrity": "sha512-tx5jMmMFwx7wBwq/V7OohKDVb/JwJU5qCVkeLMh1//xycAJ/ESuw9aJ9SEtlCZDYi2pBfe4JkisSoAtbOsBNAA==" }, "node_modules/@types/node-fetch": { "version": "3.0.2", @@ -5671,23 +5692,26 @@ "optional": true }, "node_modules/body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", + "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.4", "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.8.1", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.9.7", - "raw-body": "2.4.3", - "type-is": "~1.6.18" + "on-finished": "2.4.1", + "qs": "6.10.3", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" }, "engines": { - "node": ">= 0.8" + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" } }, "node_modules/body-parser/node_modules/debug": { @@ -5698,22 +5722,19 @@ "ms": "2.0.0" } }, + "node_modules/body-parser/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/body-parser/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, - "node_modules/body-parser/node_modules/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==", - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/boxen": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", @@ -6703,9 +6724,9 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", "engines": { "node": ">= 0.6" } @@ -7210,9 +7231,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "node_modules/electron-to-chromium": { - "version": "1.4.118", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.118.tgz", - "integrity": "sha512-maZIKjnYDvF7Fs35nvVcyr44UcKNwybr93Oba2n3HkKDFAtk0svERkLN/HyczJDS3Fo4wU9th9fUQd09ZLtj1w==" + "version": "1.4.123", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.123.tgz", + "integrity": "sha512-0pHGE53WkYoFbsgwYcVKEpWa6jbzlvkohIEA2CUoZ9b5KC+w/zlMiQHvW/4IBcOh7YoEFqRNavgTk02TBoUTUw==" }, "node_modules/elliptic": { "version": "6.5.4", @@ -7343,6 +7364,14 @@ "node": ">=10.0.0" } }, + "node_modules/engine.io/node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/engine.io/node_modules/ws": { "version": "8.2.3", "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", @@ -8107,37 +8136,38 @@ } }, "node_modules/express": { - "version": "4.17.3", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", - "integrity": "sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.0.tgz", + "integrity": "sha512-EJEXxiTQJS3lIPrU1AE2vRuT7X7E+0KBbpm5GSoK524yl0K8X+er8zS2P14E64eqsVNoWbMCT7MpmQ+ErAhgRg==", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.19.2", + "body-parser": "1.20.0", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.4.2", + "cookie": "0.5.0", "cookie-signature": "1.0.6", "debug": "2.6.9", - "depd": "~1.1.2", + "depd": "2.0.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "~1.1.2", + "finalhandler": "1.2.0", "fresh": "0.5.2", + "http-errors": "2.0.0", "merge-descriptors": "1.0.1", "methods": "~1.1.2", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", "proxy-addr": "~2.0.7", - "qs": "6.9.7", + "qs": "6.10.3", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.17.2", - "serve-static": "1.14.2", + "send": "0.18.0", + "serve-static": "1.15.0", "setprototypeof": "1.2.0", - "statuses": "~1.5.0", + "statuses": "2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" @@ -8201,22 +8231,19 @@ "ms": "2.0.0" } }, + "node_modules/express/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/express/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, - "node_modules/express/node_modules/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==", - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -8490,16 +8517,16 @@ } }, "node_modules/finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "parseurl": "~1.3.3", - "statuses": "~1.5.0", + "statuses": "2.0.1", "unpipe": "~1.0.0" }, "engines": { @@ -9280,6 +9307,15 @@ "jws": "^4.0.0" } }, + "node_modules/grant/node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/grant/node_modules/cookie-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.0.tgz", @@ -9558,6 +9594,29 @@ "node": ">= 0.8" } }, + "node_modules/http-assert/node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-assert/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/http-cache-semantics": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", @@ -9565,18 +9624,26 @@ "dev": true }, "node_modules/http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dependencies": { - "depd": "~1.1.2", + "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", + "statuses": "2.0.1", "toidentifier": "1.0.1" }, "engines": { - "node": ">= 0.6" + "node": ">= 0.8" + } + }, + "node_modules/http-errors/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" } }, "node_modules/http-proxy-agent": { @@ -10858,6 +10925,37 @@ "node": ">= 0.8" } }, + "node_modules/koa/node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/koa/node_modules/http-errors/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/koa/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/lasso": { "version": "2.11.24", "resolved": "https://registry.npmjs.org/lasso/-/lasso-2.11.24.tgz", @@ -11213,6 +11311,17 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=" }, + "node_modules/lasso/node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/lasso/node_modules/range-parser": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.0.3.tgz", @@ -11749,6 +11858,11 @@ "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" + }, "node_modules/lodash.template": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", @@ -14003,9 +14117,9 @@ } }, "node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dependencies": { "ee-first": "1.1.1" }, @@ -15131,12 +15245,12 @@ "integrity": "sha1-I7DIA8jxrIocrmfZpjiLSRYcl1g=" }, "node_modules/raw-body": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", - "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", "dependencies": { "bytes": "3.1.2", - "http-errors": "1.8.1", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" }, @@ -16048,23 +16162,23 @@ "dev": true }, "node_modules/send": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", - "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", "dependencies": { "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", + "depd": "2.0.0", + "destroy": "1.2.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "1.8.1", + "http-errors": "2.0.0", "mime": "1.6.0", "ms": "2.1.3", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "range-parser": "~1.2.1", - "statuses": "~1.5.0" + "statuses": "2.0.1" }, "engines": { "node": ">= 0.8.0" @@ -16083,10 +16197,13 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, - "node_modules/send/node_modules/destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + "node_modules/send/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } }, "node_modules/send/node_modules/ms": { "version": "2.1.3", @@ -16102,14 +16219,14 @@ } }, "node_modules/serve-static": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", - "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", "dependencies": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.17.2" + "send": "0.18.0" }, "engines": { "node": ">= 0.8.0" @@ -16509,11 +16626,11 @@ "integrity": "sha512-h88QkzREN/hy8eRdyNhhsO7RSJ5oyTqxxmmn0dzBIMUclZsjpfmrsg81vp8mjjAs2vAZ72nyWxRUwSwmh0e4xg==" }, "node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "engines": { - "node": ">= 0.6" + "node": ">= 0.8" } }, "node_modules/stream-browserify": { @@ -16677,22 +16794,21 @@ } }, "node_modules/superagent": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-7.1.2.tgz", - "integrity": "sha512-o9/fP6dww7a4xmEF5a484o2rG34UUGo8ztDlv7vbCWuqPhpndMi0f7eXxdlryk5U12Kzy46nh8eNpLAJ93Alsg==", - "deprecated": "Deprecated due to bug in CI build https://github.com/visionmedia/superagent/pull/1677\\#issuecomment-1081361876", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-7.1.3.tgz", + "integrity": "sha512-WA6et4nAvgBCS73lJvv1D0ssI5uk5Gh+TGN/kNe+B608EtcVs/yzfl+OLXTzDs7tOBDIpvgh/WUs1K2OK1zTeQ==", "dependencies": { "component-emitter": "^1.3.0", "cookiejar": "^2.1.3", - "debug": "^4.3.3", + "debug": "^4.3.4", "fast-safe-stringify": "^2.1.1", "form-data": "^4.0.0", "formidable": "^2.0.1", "methods": "^1.1.2", "mime": "^2.5.0", - "qs": "^6.10.1", + "qs": "^6.10.3", "readable-stream": "^3.6.0", - "semver": "^7.3.5" + "semver": "^7.3.7" }, "engines": { "node": ">=6.4.0 <13 || >=14" @@ -16805,13 +16921,13 @@ } }, "node_modules/terser": { - "version": "5.12.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.12.1.tgz", - "integrity": "sha512-NXbs+7nisos5E+yXwAD+y7zrcTkMqb0dEJxIGtSKPdCBzopf7ni4odPul2aechpV7EXNvOudYOX2bb5tln1jbQ==", + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.13.0.tgz", + "integrity": "sha512-sgQ99P+fRBM1jAYzN9RTnD/xEWx/7LZgYTCRgmYriSq1wxxqiQPJgXkkLBBuwySDWJ2PP0PnVQyuf4xLUuH4Ng==", "dependencies": { "acorn": "^8.5.0", "commander": "^2.20.0", - "source-map": "~0.7.2", + "source-map": "~0.8.0-beta.0", "source-map-support": "~0.5.20" }, "bin": { @@ -16905,13 +17021,39 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, "node_modules/terser/node_modules/source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "version": "0.8.0-beta.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", + "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", + "dependencies": { + "whatwg-url": "^7.0.0" + }, "engines": { "node": ">= 8" } }, + "node_modules/terser/node_modules/tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/terser/node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + }, + "node_modules/terser/node_modules/whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -17046,9 +17188,9 @@ } }, "node_modules/ts-loader": { - "version": "9.2.8", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.2.8.tgz", - "integrity": "sha512-gxSak7IHUuRtwKf3FIPSW1VpZcqF9+MBrHOvBp9cjHh+525SjtCIJKVGjRKIAfxBwDGDGCFF00rTfzB1quxdSw==", + "version": "9.2.9", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.2.9.tgz", + "integrity": "sha512-b0+vUY2/enb0qYtDQuNlDnJ9900NTiPiJcDJ6sY7ax1CCCwXfYIqPOMm/BwW7jsF1km+Oz8W9s31HLuD+FLIMg==", "dependencies": { "chalk": "^4.1.0", "enhanced-resolve": "^5.0.0", @@ -18258,11 +18400,12 @@ }, "dependencies": { "@ampproject/remapping": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.2.tgz", - "integrity": "sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", "requires": { - "@jridgewell/trace-mapping": "^0.3.0" + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" } }, "@babel/code-frame": { @@ -19445,11 +19588,25 @@ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true }, + "@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "requires": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "@jridgewell/resolve-uri": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.6.tgz", "integrity": "sha512-R7xHtBSNm+9SyvpJkdQl+qrM3Hm2fea3Ef197M3mUug+v+yR+Rhfbs7PBtcBUVnIWJ4JcAdjvij+c8hXS9p5aw==" }, + "@jridgewell/set-array": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.0.tgz", + "integrity": "sha512-SfJxIxNVYLTsKwzB3MoOQ1yxf4w/E6MdkvTgrgAt1bfxjSrLUoHMKrDOykwN14q65waezZIdqDneUIPh4/sKxg==" + }, "@jridgewell/sourcemap-codec": { "version": "1.4.11", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", @@ -20842,9 +20999,9 @@ } }, "@types/node": { - "version": "17.0.26", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.26.tgz", - "integrity": "sha512-z/FG/6DUO7pnze3AE3TBGIjGGKkvCcGcWINe1C7cADY8hKLJPDYpzsNE37uExQ4md5RFtTCvg+M8Mu1Enyeg2A==" + "version": "17.0.29", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.29.tgz", + "integrity": "sha512-tx5jMmMFwx7wBwq/V7OohKDVb/JwJU5qCVkeLMh1//xycAJ/ESuw9aJ9SEtlCZDYi2pBfe4JkisSoAtbOsBNAA==" }, "@types/node-fetch": { "version": "3.0.2", @@ -22737,20 +22894,22 @@ "optional": true }, "body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", + "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", "requires": { "bytes": "3.1.2", "content-type": "~1.0.4", "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.8.1", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.9.7", - "raw-body": "2.4.3", - "type-is": "~1.6.18" + "on-finished": "2.4.1", + "qs": "6.10.3", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" }, "dependencies": { "debug": { @@ -22761,15 +22920,15 @@ "ms": "2.0.0" } }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==" } } }, @@ -23522,9 +23681,9 @@ } }, "cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==" + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" }, "cookie-signature": { "version": "1.0.6", @@ -23924,9 +24083,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { - "version": "1.4.118", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.118.tgz", - "integrity": "sha512-maZIKjnYDvF7Fs35nvVcyr44UcKNwybr93Oba2n3HkKDFAtk0svERkLN/HyczJDS3Fo4wU9th9fUQd09ZLtj1w==" + "version": "1.4.123", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.123.tgz", + "integrity": "sha512-0pHGE53WkYoFbsgwYcVKEpWa6jbzlvkohIEA2CUoZ9b5KC+w/zlMiQHvW/4IBcOh7YoEFqRNavgTk02TBoUTUw==" }, "elliptic": { "version": "6.5.4", @@ -24004,6 +24163,11 @@ "ws": "~8.2.3" }, "dependencies": { + "cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==" + }, "ws": { "version": "8.2.3", "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", @@ -24621,37 +24785,38 @@ } }, "express": { - "version": "4.17.3", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", - "integrity": "sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.0.tgz", + "integrity": "sha512-EJEXxiTQJS3lIPrU1AE2vRuT7X7E+0KBbpm5GSoK524yl0K8X+er8zS2P14E64eqsVNoWbMCT7MpmQ+ErAhgRg==", "requires": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.19.2", + "body-parser": "1.20.0", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.4.2", + "cookie": "0.5.0", "cookie-signature": "1.0.6", "debug": "2.6.9", - "depd": "~1.1.2", + "depd": "2.0.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "~1.1.2", + "finalhandler": "1.2.0", "fresh": "0.5.2", + "http-errors": "2.0.0", "merge-descriptors": "1.0.1", "methods": "~1.1.2", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", "proxy-addr": "~2.0.7", - "qs": "6.9.7", + "qs": "6.10.3", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.17.2", - "serve-static": "1.14.2", + "send": "0.18.0", + "serve-static": "1.15.0", "setprototypeof": "1.2.0", - "statuses": "~1.5.0", + "statuses": "2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" @@ -24665,15 +24830,15 @@ "ms": "2.0.0" } }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==" } } }, @@ -24950,16 +25115,16 @@ "dev": true }, "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", "requires": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "parseurl": "~1.3.3", - "statuses": "~1.5.0", + "statuses": "2.0.1", "unpipe": "~1.0.0" }, "dependencies": { @@ -25555,6 +25720,12 @@ "request-oauth": "^1.0.1" }, "dependencies": { + "cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "optional": true + }, "cookie-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.0.tgz", @@ -25761,6 +25932,25 @@ "requires": { "deep-equal": "~1.0.1", "http-errors": "~1.8.0" + }, + "dependencies": { + "http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + } } }, "http-cache-semantics": { @@ -25770,15 +25960,22 @@ "dev": true }, "http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "requires": { - "depd": "~1.1.2", + "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", + "statuses": "2.0.1", "toidentifier": "1.0.1" + }, + "dependencies": { + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + } } }, "http-proxy-agent": { @@ -26709,6 +26906,30 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "dependencies": { + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + } + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" } } }, @@ -26837,6 +27058,14 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=" }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, "range-parser": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.0.3.tgz", @@ -27518,6 +27747,11 @@ "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" + }, "lodash.template": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", @@ -29281,9 +29515,9 @@ } }, "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "requires": { "ee-first": "1.1.1" } @@ -30149,12 +30383,12 @@ "integrity": "sha1-I7DIA8jxrIocrmfZpjiLSRYcl1g=" }, "raw-body": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", - "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", "requires": { "bytes": "3.1.2", - "http-errors": "1.8.1", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" } @@ -30855,23 +31089,23 @@ "dev": true }, "send": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", - "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", "requires": { "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", + "depd": "2.0.0", + "destroy": "1.2.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "1.8.1", + "http-errors": "2.0.0", "mime": "1.6.0", "ms": "2.1.3", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "range-parser": "~1.2.1", - "statuses": "~1.5.0" + "statuses": "2.0.1" }, "dependencies": { "debug": { @@ -30889,10 +31123,10 @@ } } }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" }, "ms": { "version": "2.1.3", @@ -30910,14 +31144,14 @@ } }, "serve-static": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", - "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", "requires": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.17.2" + "send": "0.18.0" } }, "set-blocking": { @@ -31227,9 +31461,9 @@ "integrity": "sha512-h88QkzREN/hy8eRdyNhhsO7RSJ5oyTqxxmmn0dzBIMUclZsjpfmrsg81vp8mjjAs2vAZ72nyWxRUwSwmh0e4xg==" }, "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" }, "stream-browserify": { "version": "2.0.2", @@ -31358,21 +31592,21 @@ } }, "superagent": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-7.1.2.tgz", - "integrity": "sha512-o9/fP6dww7a4xmEF5a484o2rG34UUGo8ztDlv7vbCWuqPhpndMi0f7eXxdlryk5U12Kzy46nh8eNpLAJ93Alsg==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-7.1.3.tgz", + "integrity": "sha512-WA6et4nAvgBCS73lJvv1D0ssI5uk5Gh+TGN/kNe+B608EtcVs/yzfl+OLXTzDs7tOBDIpvgh/WUs1K2OK1zTeQ==", "requires": { "component-emitter": "^1.3.0", "cookiejar": "^2.1.3", - "debug": "^4.3.3", + "debug": "^4.3.4", "fast-safe-stringify": "^2.1.1", "form-data": "^4.0.0", "formidable": "^2.0.1", "methods": "^1.1.2", "mime": "^2.5.0", - "qs": "^6.10.1", + "qs": "^6.10.3", "readable-stream": "^3.6.0", - "semver": "^7.3.5" + "semver": "^7.3.7" }, "dependencies": { "form-data": { @@ -31452,13 +31686,13 @@ } }, "terser": { - "version": "5.12.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.12.1.tgz", - "integrity": "sha512-NXbs+7nisos5E+yXwAD+y7zrcTkMqb0dEJxIGtSKPdCBzopf7ni4odPul2aechpV7EXNvOudYOX2bb5tln1jbQ==", + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.13.0.tgz", + "integrity": "sha512-sgQ99P+fRBM1jAYzN9RTnD/xEWx/7LZgYTCRgmYriSq1wxxqiQPJgXkkLBBuwySDWJ2PP0PnVQyuf4xLUuH4Ng==", "requires": { "acorn": "^8.5.0", "commander": "^2.20.0", - "source-map": "~0.7.2", + "source-map": "~0.8.0-beta.0", "source-map-support": "~0.5.20" }, "dependencies": { @@ -31468,9 +31702,35 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" + "version": "0.8.0-beta.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", + "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", + "requires": { + "whatwg-url": "^7.0.0" + } + }, + "tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "requires": { + "punycode": "^2.1.0" + } + }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + }, + "whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } } } }, @@ -31621,9 +31881,9 @@ "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=" }, "ts-loader": { - "version": "9.2.8", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.2.8.tgz", - "integrity": "sha512-gxSak7IHUuRtwKf3FIPSW1VpZcqF9+MBrHOvBp9cjHh+525SjtCIJKVGjRKIAfxBwDGDGCFF00rTfzB1quxdSw==", + "version": "9.2.9", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.2.9.tgz", + "integrity": "sha512-b0+vUY2/enb0qYtDQuNlDnJ9900NTiPiJcDJ6sY7ax1CCCwXfYIqPOMm/BwW7jsF1km+Oz8W9s31HLuD+FLIMg==", "requires": { "chalk": "^4.1.0", "enhanced-resolve": "^5.0.0", diff --git a/packages/adapter-commons/src/declarations.ts b/packages/adapter-commons/src/declarations.ts index 6ac368e1a2..7a077596be 100644 --- a/packages/adapter-commons/src/declarations.ts +++ b/packages/adapter-commons/src/declarations.ts @@ -31,7 +31,7 @@ export interface AdapterServiceOptions { /** * Pagination settings for this service */ - paginate?: PaginationOptions + paginate?: PaginationParams; /** * A list of additional property query operators to allow in a query */ @@ -51,12 +51,17 @@ export interface AdapterServiceOptions { whitelist?: string[]; } -export interface AdapterOptions extends Pick { - Model?: M; +export interface AdapterQuery extends Query { + $limit?: number, + $skip?: number, + $select?: string[], + $sort?: { [key: string]: 1|-1 } } - -export interface AdapterParams extends Params { - adapter?: Partial>; +/** + * Additional `params` that can be passed to an adapter service method call. + */ +export interface AdapterParams = Partial> extends Params { + adapter?: A; paginate?: PaginationParams; } diff --git a/packages/adapter-commons/src/service.ts b/packages/adapter-commons/src/service.ts index 68040cbdd6..715a57e59a 100644 --- a/packages/adapter-commons/src/service.ts +++ b/packages/adapter-commons/src/service.ts @@ -17,9 +17,9 @@ export abstract class AdapterBase< T = any, D = Partial, P extends AdapterParams = AdapterParams, - O extends Partial = Partial - > implements InternalServiceMethods { - options: AdapterServiceOptions & O; + O extends AdapterServiceOptions = AdapterServiceOptions +> implements InternalServiceMethods { + options: O; constructor (options: O) { this.options = { @@ -70,7 +70,7 @@ export abstract class AdapterBase< * @param params The parameters for the service method call * @returns The actual options for this call */ - getOptions (params: P): AdapterServiceOptions { + getOptions (params: P): O { const paginate = params.paginate !== undefined ? params.paginate : this.options.paginate; return { diff --git a/packages/adapter-commons/test/fixture.ts b/packages/adapter-commons/test/fixture.ts index efa639f212..2c3a0a5190 100644 --- a/packages/adapter-commons/test/fixture.ts +++ b/packages/adapter-commons/test/fixture.ts @@ -1,5 +1,5 @@ import { AdapterBase, AdapterParams, InternalServiceMethods, PaginationOptions } from '../src'; -import { Id, NullableId, Paginated, Query } from '@feathersjs/feathers'; +import { Id, NullableId, Paginated } from '@feathersjs/feathers'; export type Data = { id: Id @@ -71,7 +71,7 @@ export class MethodBase extends AdapterBase, AdapterParams> } export class MethodService extends MethodBase { - find (params?: AdapterParams): Promise> { + find (params?: AdapterParams): Promise> { return this._find(params); } diff --git a/packages/adapter-commons/test/service.test.ts b/packages/adapter-commons/test/service.test.ts index 59db52e530..ff49616f03 100644 --- a/packages/adapter-commons/test/service.test.ts +++ b/packages/adapter-commons/test/service.test.ts @@ -69,14 +69,14 @@ describe('@feathersjs/adapter-commons/service', () => { }); assert.deepStrictEqual(await service.sanitizeQuery({ - query: { $limit: '10', test: 'me' } + query: { $limit: '10', test: 'me' } as any }), { $limit: 10, test: 'me' }); assert.deepStrictEqual(await service.sanitizeQuery({ adapter: { paginate: { max: 2 } }, - query: { $limit: '10', test: 'me' } + query: { $limit: '10', test: 'me' } as any }), { $limit: 2, test: 'me' }); await assert.rejects(() => service.sanitizeQuery({ diff --git a/packages/memory/src/index.ts b/packages/memory/src/index.ts index 178f0d9963..054ce03949 100644 --- a/packages/memory/src/index.ts +++ b/packages/memory/src/index.ts @@ -1,6 +1,6 @@ import { NotFound } from '@feathersjs/errors'; import { _ } from '@feathersjs/commons'; -import { sorter, select, AdapterBase, AdapterServiceOptions, PaginationOptions } from '@feathersjs/adapter-commons'; +import { sorter, select, AdapterBase, AdapterServiceOptions, PaginationOptions, AdapterParams } from '@feathersjs/adapter-commons'; import sift from 'sift'; import { NullableId, Id, Params, ServiceMethods, Paginated } from '@feathersjs/feathers'; @@ -9,8 +9,8 @@ export interface MemoryServiceStore { } export interface MemoryServiceOptions extends AdapterServiceOptions { - store: MemoryServiceStore; - startId: number; + store?: MemoryServiceStore; + startId?: number; matcher?: (query: any) => any; sorter?: (sort: any) => any; } @@ -25,7 +25,7 @@ export class MemoryAdapter, P extends Params = Params> e store: MemoryServiceStore; _uId: number; - constructor (options: Partial> = {}) { + constructor (options: MemoryServiceOptions = {}) { super({ id: 'id', matcher: sift, @@ -184,7 +184,7 @@ export class MemoryAdapter, P extends Params = Params> e } } -export class MemoryService, P extends Params = Params> +export class MemoryService, P extends AdapterParams = AdapterParams> extends MemoryAdapter implements ServiceMethods, D, P> { async find (params?: P & { paginate?: PaginationOptions }): Promise>; async find (params?: P & { paginate: false }): Promise; diff --git a/packages/mongodb/src/adapter.ts b/packages/mongodb/src/adapter.ts index d2b14f363a..65f12b85e3 100644 --- a/packages/mongodb/src/adapter.ts +++ b/packages/mongodb/src/adapter.ts @@ -1,28 +1,26 @@ import { - ObjectId, Collection, CollationOptions, Hint, FindOptions, BulkWriteOptions, - InsertOneOptions, UpdateOptions, DeleteOptions, CountDocumentsOptions, ReplaceOptions + ObjectId, Collection, FindOptions, BulkWriteOptions, + InsertOneOptions, DeleteOptions, CountDocumentsOptions, ReplaceOptions } from 'mongodb' -import { BadRequest, MethodNotAllowed, NotFound } from '@feathersjs/errors' +import { NotFound } from '@feathersjs/errors' import { _ } from '@feathersjs/commons' -import { AdapterBase, select, AdapterParams, AdapterServiceOptions, PaginationOptions } from '@feathersjs/adapter-commons' +import { AdapterBase, select, AdapterParams, AdapterServiceOptions, PaginationOptions, AdapterQuery } from '@feathersjs/adapter-commons' import { NullableId, Query, Id, Paginated } from '@feathersjs/feathers' import { errorHandler } from './error-handler' -export type MongoDBAdapterOptions = { - Model: Collection - disableObjectify?: boolean +export interface MongoDBAdapterOptions extends AdapterServiceOptions { + Model: Collection|Promise, + disableObjectify?: boolean, useEstimatedDocumentCount?: boolean -} & AdapterServiceOptions +} export interface MongoDBAdapterParams extends AdapterParams { - mongodb?: Partial - options?: BulkWriteOptions|FindOptions|InsertOneOptions|DeleteOptions|CountDocumentsOptions|ReplaceOptions - collation?: CollationOptions - hint?: Hint + mongodb?: BulkWriteOptions|FindOptions|InsertOneOptions|DeleteOptions|CountDocumentsOptions|ReplaceOptions } // Create the service. -export class MongoDbAdapter, P extends MongoDBAdapterParams = MongoDBAdapterParams> extends AdapterBase { +export class MongoDbAdapter, P extends MongoDBAdapterParams = MongoDBAdapterParams> + extends AdapterBase { constructor (options: MongoDBAdapterOptions) { if (!options) { throw new Error('MongoDB options have to be provided') @@ -42,7 +40,7 @@ export class MongoDbAdapter, P extends MongoDBAdapterParams = this.options.Model = value } - _objectifyId (id: Id|ObjectId) { + getObjectId (id: Id|ObjectId) { if (this.options.disableObjectify) { return id } @@ -54,29 +52,24 @@ export class MongoDbAdapter, P extends MongoDBAdapterParams = return id } - _multiOptions (id: NullableId|ObjectId, params: MongoDBAdapterParams = {}) { - const { query } = this.filterQuery(params) - const options = Object.assign({ multi: true }, params.mongodb || params.options) + filterQuery (id: NullableId, params: P) { + const { $select, $sort, $limit, $skip, ...query } = (params.query || {}) as AdapterQuery; if (id !== null) { - options.multi = false - query.$and = (query.$and || []).concat({ [this.id]: this._objectifyId(id) }) + query.$and = (query.$and || []).concat({ [this.id]: this.getObjectId(id) }) } - if (params.collation != null) { - query.collation = params.collation + if (query[this.id]) { + query[this.id] = this.getObjectId(query[this.id]) } - return { query, options } - } - - _options (params: MongoDBAdapterParams = {}) { - const { filters, query, paginate } = this.filterQuery(params) - const options = Object.assign({}, params.mongodb || params.options) - return { filters, query, paginate, options } + return { + filters: { $select, $sort, $limit, $skip }, + query + } } - _getSelect (select: string[]|{ [key: string]: number }) { + getSelect (select: string[]|{ [key: string]: number }) { if (Array.isArray(select)) { return select.reduce<{ [key: string]: number }>((value, name) => ({ ...value, @@ -88,10 +81,10 @@ export class MongoDbAdapter, P extends MongoDBAdapterParams = } async _findOrGet (id: NullableId, params: P) { - return id === null ? await this._find(params) : await this._get(id, params) + return id === null ? await this.$find(params) : await this.$get(id, params) } - _normalizeId (id: NullableId, data: Partial) { + _normalizeId (id: NullableId, data: Partial): Partial { if (this.id === '_id') { // Default Mongo IDs cannot be updated. The Mongo library handles // this automatically. @@ -131,95 +124,82 @@ export class MongoDbAdapter, P extends MongoDBAdapterParams = return data } - async _find (params?: P & { paginate?: PaginationOptions }): Promise>; - async _find (params?: P & { paginate: false }): Promise; - async _find (params?: P): Promise|T[]>; - async _find (params: P = {} as P): Promise|T[]> { - // Start with finding all, and limit when necessary. - const { filters, query, paginate, options } = this._options(params) - - if (query[this.id]) { - query[this.id] = this._objectifyId(query[this.id]) + async $get (id: Id, params: P = {} as P): Promise { + const { Model } = this.getOptions(params); + const { query, filters: { $select } } = this.filterQuery(id, params); + const projection = $select ? { + projection: { + ...this.getSelect($select), + [this.id]: 1 + } + } : {} + const findOptions: FindOptions = { + ...params.mongodb, + ...projection } - const q = this.Model.find(query, options as FindOptions) - - if (filters.$select) { - q.project(this._getSelect(filters.$select)) - } + return Promise.resolve(Model).then(model => model.findOne(query, findOptions)) + .then(data => { + if (data == null) { + throw new NotFound(`No record found for id '${id}'`) + } - if (filters.$sort) { - q.sort(filters.$sort) - } + return data + }) + .catch(errorHandler) + } - if (params.collation != null) { - q.collation(params.collation) + async $find (params?: P & { paginate?: PaginationOptions }): Promise>; + async $find (params?: P & { paginate: false }): Promise; + async $find (params?: P): Promise|T[]>; + async $find (params: P = {} as P): Promise|T[]> { + const { filters, query } = this.filterQuery(null, params) + const { paginate, Model, useEstimatedDocumentCount } = this.getOptions(params) + const findOptions = { ...params.mongodb } + const model = await Promise.resolve(Model) + const q = model.find(query, findOptions) + + if (filters.$select !== undefined) { + q.project(this.getSelect(filters.$select)) } - if (params.hint) { - q.hint(params.hint) + if (filters.$sort !== undefined) { + q.sort(filters.$sort) } - if (filters.$limit) { + if (filters.$limit !== undefined) { q.limit(filters.$limit) } - if (filters.$skip) { + if (filters.$skip !== undefined) { q.skip(filters.$skip) } - let runQuery = async (total: number) => { - return await q.toArray().then((data: any) => { - return { - total, - limit: filters.$limit, - skip: filters.$skip || 0, - data: data as T[] - } - }) - } - - if (filters.$limit === 0) { - runQuery = async total => { - return await Promise.resolve({ - total, - limit: filters.$limit, - skip: filters.$skip || 0, - data: [] - }) - } - } + const runQuery = async (total: number) => ({ + total, + limit: filters.$limit, + skip: filters.$skip || 0, + data: filters.$limit === 0 ? [] : (await q.toArray()) as any as T[] + }) if (paginate && paginate.default) { - if (this.options.useEstimatedDocumentCount && (typeof this.Model.estimatedDocumentCount === 'function')) { - return this.Model.estimatedDocumentCount().then(runQuery) + if (useEstimatedDocumentCount && (typeof model.estimatedDocumentCount === 'function')) { + return model.estimatedDocumentCount().then(runQuery) } - return this.Model.countDocuments(query, options as CountDocumentsOptions).then(runQuery) + return model.countDocuments(query, findOptions).then(runQuery) } return runQuery(0).then(page => page.data) } - async _get (id: Id, params: P = {} as P): Promise { - const { query, options } = this._options(params) - - query.$and = (query.$and || []).concat({ [this.id]: this._objectifyId(id) }) - - return this.Model.findOne(query, options as FindOptions).then(data => { - if (data == null) { - throw new NotFound(`No record found for id '${id}'`) - } - - return data - }).then(select(params, this.id)).catch(errorHandler) - } - - async _create (data: Partial, params?: P): Promise; - async _create (data: Partial[], params?: P): Promise; - async _create (data: Partial|Partial[], _params?: P): Promise; - async _create (data: Partial|Partial[], params: P = {} as P): Promise { - const { options } = this._options(params) + async $create (data: Partial, params?: P): Promise; + async $create (data: Partial[], params?: P): Promise; + async $create (data: Partial|Partial[], _params?: P): Promise; + async $create (data: Partial|Partial[], params: P = {} as P): Promise { + const writeOptions = params.mongodb + const { Model } = this.getOptions(params) + const model = await Promise.resolve(Model) const setId = (item: any) => { const entry = Object.assign({}, item) @@ -233,35 +213,29 @@ export class MongoDbAdapter, P extends MongoDBAdapterParams = return entry } - - if (Array.isArray(data) && !this.allowsMulti('create', params)) { - throw new MethodNotAllowed('Can not create multiple entries') - } - const promise = Array.isArray(data) - ? this.Model.insertMany(data.map(setId), options as BulkWriteOptions).then(async result => - await Promise.all(Object.values(result.insertedIds).map(async _id => await this.Model.findOne({ _id }, options as FindOptions))) + ? model.insertMany(data.map(setId), writeOptions).then(async result => + Promise.all(Object.values(result.insertedIds).map(async _id => await model.findOne({ _id }))) ) - : this.Model.insertOne(setId(data), options as InsertOneOptions).then(async result => - await this.Model.findOne({ _id: result.insertedId }, options as FindOptions) + : model.insertOne(setId(data), writeOptions).then(async result => + await model.findOne({ _id: result.insertedId }) ) return promise.then(select(params, this.id)).catch(errorHandler) } - async _patch (id: null, data: Partial, params?: P): Promise; - async _patch (id: Id, data: Partial, params?: P): Promise; - async _patch (id: NullableId, data: Partial, _params?: P): Promise; - async _patch (id: NullableId, data: Partial, params: P = {} as P): Promise { - const { query, options } = this._multiOptions(id, params) - - if (id === null && !this.allowsMulti('patch', params)) { - throw new MethodNotAllowed('Can not patch multiple entries') - } - + async $patch (id: null, data: Partial, params?: P): Promise; + async $patch (id: Id, data: Partial, params?: P): Promise; + async $patch (id: NullableId, data: Partial, _params?: P): Promise; + async $patch (id: NullableId, data: Partial, params: P = {} as P): Promise { + const { Model } = this.getOptions(params) + const model = await Promise.resolve(Model) + const { query } = this.filterQuery(id, params) + const updateOptions = { ...params.mongodb } const remapModifier = this._remapModifiers(this._normalizeId(id, data)) const idParams = { ...params, + query, paginate: false } const originalItems = await this._findOrGet(id, idParams) @@ -273,47 +247,43 @@ export class MongoDbAdapter, P extends MongoDBAdapterParams = query: { [this.id]: { $in: idList } } } - await this.Model.updateMany(query, remapModifier, options as UpdateOptions) + await model.updateMany(query, remapModifier, updateOptions) return this._findOrGet(id, findParams) .then(select(params, this.id)) .catch(errorHandler) } - async _update (id: Id, data: D, params: P = {} as P): Promise { - if (Array.isArray(data) || id === null) { - return await Promise.reject( - new BadRequest('Not replacing multiple records. Did you mean `patch`?') - ) - } - - const { query, options } = this._multiOptions(id, params) + async $update (id: Id, data: D, params: P = {} as P): Promise { + const { Model } = this.getOptions(params) + const model = await Promise.resolve(Model) + const { query } = this.filterQuery(id, params) + const replaceOptions = { ...params.mongodb } - await this.Model.replaceOne(query, this._normalizeId(id, data), options as ReplaceOptions) + await model.replaceOne(query, this._normalizeId(id, data), replaceOptions) return this._findOrGet(id, params) .then(select(params, this.id)) .catch(errorHandler) } - async _remove (id: null, params?: P): Promise; - async _remove (id: Id, params?: P): Promise; - async _remove (id: NullableId, _params?: P): Promise; - async _remove (id: NullableId, params: P = {} as P): Promise { - const { query, options } = this._multiOptions(id, params) - - if (id === null && !this.allowsMulti('remove', params)) { - throw new MethodNotAllowed('Can not remove multiple entries') - } - - const findParams = Object.assign({}, params, { + async $remove (id: null, params?: P): Promise; + async $remove (id: Id, params?: P): Promise; + async $remove (id: NullableId, _params?: P): Promise; + async $remove (id: NullableId, params: P = {} as P): Promise { + const { Model } = this.getOptions(params) + const model = await Promise.resolve(Model) + const { query } = this.filterQuery(id, params) + const deleteOptions = { ...params.mongodb } + const findParams = { + ...params, paginate: false, - query: params.query - }) + query + } return this._findOrGet(id, findParams) .then(async items => { - await this.Model.deleteMany(query, options as DeleteOptions) + await model.deleteMany(query, deleteOptions) return items }) .then(select(params, this.id)) diff --git a/packages/mongodb/src/error-handler.ts b/packages/mongodb/src/error-handler.ts index 9c1b60dbae..1eac24b4c1 100644 --- a/packages/mongodb/src/error-handler.ts +++ b/packages/mongodb/src/error-handler.ts @@ -1,7 +1,7 @@ import errors from '@feathersjs/errors' import { MongoError } from 'mongodb' -export function errorHandler (error: MongoError) { +export function errorHandler (error: MongoError): any { // See https://github.com/mongodb/mongo/blob/master/docs/errors.md if (error.name === 'MongoError') { throw new errors.GeneralError(error, { diff --git a/packages/mongodb/src/index.ts b/packages/mongodb/src/index.ts index 63f659f54e..c1c32dff98 100644 --- a/packages/mongodb/src/index.ts +++ b/packages/mongodb/src/index.ts @@ -11,32 +11,32 @@ export class MongoDBService, P extends MongoDBAdapterPar async find (params?: P & { paginate: false }): Promise; async find (params?: P): Promise|T[]>; async find (params?: P): Promise|T[]> { - return await this._find(params) + return this._find(params) as any } async get (id: Id, params?: P): Promise { - return await this._get(id, params) + return this._get(id, params) } async create (data: Partial, params?: P): Promise; async create (data: Partial[], params?: P): Promise; async create (data: Partial|Partial[], params?: P): Promise { - return await this._create(data, params) + return this._create(data, params) } async update (id: Id, data: D, params?: P): Promise { - return await this._update(id, data, params) + return this._update(id, data, params) } async patch (id: Id, data: Partial, params?: P): Promise; async patch (id: null, data: Partial, params?: P): Promise; async patch (id: NullableId, data: Partial, params?: P): Promise { - return await this._patch(id, data, params) + return this._patch(id, data, params) } async remove (id: Id, params?: P): Promise; async remove (id: null, params?: P): Promise; async remove (id: NullableId, params?: P): Promise { - return await this._remove(id, params) + return this._remove(id, params) } } diff --git a/packages/mongodb/test/index.test.ts b/packages/mongodb/test/index.test.ts index b4ab04d15a..533d4a750f 100644 --- a/packages/mongodb/test/index.test.ts +++ b/packages/mongodb/test/index.test.ts @@ -15,6 +15,12 @@ const testSuite = adapterTests([ '._update', '._patch', '._remove', + '.$get', + '.$find', + '.$create', + '.$update', + '.$patch', + '.$remove', '.get', '.get + $select', '.get + id + query', @@ -135,10 +141,10 @@ describe('Feathers MongoDB Service', () => { }) describe('Service utility functions', () => { - describe('objectifyId', () => { + describe('getObjectId', () => { it('returns an ObjectID instance for a valid ID', () => { const id = new ObjectId() - const objectify = app.service('people')._objectifyId(id.toString()) + const objectify = app.service('people').getObjectId(id.toString()) assert.ok(objectify instanceof ObjectId) assert.strictEqual(objectify.toString(), id.toString()) @@ -146,81 +152,12 @@ describe('Feathers MongoDB Service', () => { it('returns an ObjectID instance for a valid ID', () => { const id = 'non-valid object id' - const objectify = app.service('people')._objectifyId(id.toString()) + const objectify = app.service('people').getObjectId(id.toString()) assert.ok(!(objectify instanceof ObjectId)) assert.strictEqual(objectify, id) }) }) - - describe('_multiOptions', () => { - const params = { - query: { - age: 21 - }, - options: { - limit: 5 - } - } - - it('returns valid result when passed an ID', () => { - const id = new ObjectId() - const result = app.service('people')._multiOptions(id, params) - - assert.deepStrictEqual(result.query, { - ...params.query, - $and: [{ _id: id }] - }) - assert.deepStrictEqual(result.options, { - ...params.options, - multi: false - }) - }) - - it('returns original object', () => { - const result = app.service('people')._multiOptions(null, params) - - assert.deepStrictEqual(result.query, params.query) - assert.deepStrictEqual(result.options, { - ...params.options, - multi: true - }) - }) - }) - - describe('_options', () => { - const params = { - query: { - age: 21 - }, - options: { - limit: 5 - } - } - - it('returns original object', () => { - const result = app.service('people')._options(params) - - assert.deepStrictEqual(result.options, params.options) - }) - }) - - describe('getSelect', () => { - const projectFields = { name: 1, age: 1 } - const selectFields = ['name', 'age'] - - it('returns Mongo project object when an array is passed', () => { - const result = app.service('people')._getSelect(selectFields) - - assert.deepStrictEqual(result, projectFields) - }) - - it('returns original object', () => { - const result = app.service('people')._getSelect(projectFields) - - assert.deepStrictEqual(result, projectFields) - }) - }) }) describe('Special collation param', () => { @@ -293,11 +230,11 @@ describe('Feathers MongoDB Service', () => { assert.ok(indexOfName(results, 'aaa') < indexOfName(results, 'AAA')) }) - it.skip('sorts using collation param if present', async () => { + it('sorts using collation param if present', async () => { const results = await peopleService.find({ paginate: false, query: { $sort: { name: -1 } }, - collation: { locale: 'en', strength: 1 } + mongodb: { collation: { locale: 'en', strength: 1 } } }) assert.ok(indexOfName(results, 'aaa') > indexOfName(results, 'AAA')) @@ -313,14 +250,15 @@ describe('Feathers MongoDB Service', () => { }) it('removes using collation param if present', async () => { - await peopleService.remove(null, { - query: { name: { $gt: 'AAA' } }, - collation: { locale: 'en', strength: 1 } + const removed = await peopleService.remove(null, { + query: { name: 'AAA' }, + mongodb: { collation: { locale: 'en', strength: 1 } } }) - const results = await peopleService.find({ paginate: false }) - assert.strictEqual(results.length, 3) + assert.strictEqual(removed.length, 2) + assert.strictEqual(results[0].name, 'ccc') + assert.strictEqual(results.length, 1) }) it('updates with default behavior without collation param', async () => { @@ -337,7 +275,7 @@ describe('Feathers MongoDB Service', () => { it('updates using collation param if present', async () => { const result = await peopleService.patch(null, { age: 110 }, { query: { name: { $gt: 'AAA' } }, - collation: { locale: 'en', strength: 1 } + mongodb: { collation: { locale: 'en', strength: 1 } } }) assert.strictEqual(result.length, 1) @@ -364,9 +302,10 @@ describe('Feathers MongoDB Service', () => { const result = await peopleService.find({ paginate: false, query: {}, - hint: { name: 1 } + mongodb: { hint: { name: 1 } } }) + assert.strictEqual(result[0].name, 'Indexed') assert.strictEqual(result.length, 1) await peopleService.remove(indexed._id) From bf16fb0f9b64a4e756575efecac2be89e7e4f7b4 Mon Sep 17 00:00:00 2001 From: daffl Date: Fri, 29 Apr 2022 11:55:00 -0700 Subject: [PATCH 3/6] Additoinal Mongodb adapter tweaks --- packages/mongodb/src/adapter.ts | 101 +++++++++++--------------- packages/mongodb/src/error-handler.ts | 6 +- packages/mongodb/test/index.test.ts | 22 +++++- 3 files changed, 65 insertions(+), 64 deletions(-) diff --git a/packages/mongodb/src/adapter.ts b/packages/mongodb/src/adapter.ts index 65f12b85e3..566f60cd40 100644 --- a/packages/mongodb/src/adapter.ts +++ b/packages/mongodb/src/adapter.ts @@ -32,14 +32,6 @@ export class MongoDbAdapter, P extends MongoDBAdapterParams = }) } - get Model () { - return this.options.Model - } - - set Model (value) { - this.options.Model = value - } - getObjectId (id: Id|ObjectId) { if (this.options.disableObjectify) { return id @@ -80,11 +72,11 @@ export class MongoDbAdapter, P extends MongoDBAdapterParams = return select } - async _findOrGet (id: NullableId, params: P) { + async $findOrGet (id: NullableId, params: P) { return id === null ? await this.$find(params) : await this.$get(id, params) } - _normalizeId (id: NullableId, data: Partial): Partial { + normalizeId (id: NullableId, data: Partial): Partial { if (this.id === '_id') { // Default Mongo IDs cannot be updated. The Mongo library handles // this automatically. @@ -100,30 +92,6 @@ export class MongoDbAdapter, P extends MongoDBAdapterParams = return data } - // Map stray records into $set - _remapModifiers (data: { [key: string]: any }) { - let set: { [key: string]: any } = {} - // Step through the rooot - for (const key of Object.keys(data)) { - // Check for keys that aren't modifiers - if (key.charAt(0) !== '$') { - // Move them to set, and remove their record - set[key] = data[key] - delete data[key] - } - // If the '$set' modifier is used, add that to the temp variable - if (key === '$set') { - set = Object.assign(set, data[key]) - delete data[key] - } - } - // If we have a $set, then attach to the data object - if (Object.keys(set).length > 0) { - (data as any).$set = set - } - return data - } - async $get (id: Id, params: P = {} as P): Promise { const { Model } = this.getOptions(params); const { query, filters: { $select } } = this.filterQuery(id, params); @@ -215,10 +183,10 @@ export class MongoDbAdapter, P extends MongoDBAdapterParams = } const promise = Array.isArray(data) ? model.insertMany(data.map(setId), writeOptions).then(async result => - Promise.all(Object.values(result.insertedIds).map(async _id => await model.findOne({ _id }))) + Promise.all(Object.values(result.insertedIds).map(async _id => model.findOne({ _id }))) ) : model.insertOne(setId(data), writeOptions).then(async result => - await model.findOne({ _id: result.insertedId }) + model.findOne({ _id: result.insertedId }) ) return promise.then(select(params, this.id)).catch(errorHandler) @@ -227,31 +195,49 @@ export class MongoDbAdapter, P extends MongoDBAdapterParams = async $patch (id: null, data: Partial, params?: P): Promise; async $patch (id: Id, data: Partial, params?: P): Promise; async $patch (id: NullableId, data: Partial, _params?: P): Promise; - async $patch (id: NullableId, data: Partial, params: P = {} as P): Promise { + async $patch (id: NullableId, _data: Partial, params: P = {} as P): Promise { + const data = this.normalizeId(id, _data) const { Model } = this.getOptions(params) const model = await Promise.resolve(Model) - const { query } = this.filterQuery(id, params) + const { query, filters: { $select, $limit } } = this.filterQuery(id, params) const updateOptions = { ...params.mongodb } - const remapModifier = this._remapModifiers(this._normalizeId(id, data)) - const idParams = { + const modifier = Object.keys(data).reduce((current, key) => { + const value = (data as any)[key] + + if (key.charAt(0) !== '$') { + current.$set = { + ...current.$set, + [key]: value + } + } else { + current[key] = value + } + + return current + }, {} as any) + const originalIds = await this.$findOrGet(id, { ...params, - query, + query: { + ...query, + $select: [ this.id ] + }, paginate: false - } - const originalItems = await this._findOrGet(id, idParams) - const items = Array.isArray(originalItems) ? originalItems : [originalItems] + }) + const items = (Array.isArray(originalIds) ? originalIds : [originalIds]) const idList = items.map((item: any) => item[this.id]) const findParams = { ...params, paginate: false, - query: { [this.id]: { $in: idList } } + query: { + ...($limit === 0 ? { $limit: 0 } : {}), + [this.id]: { $in: idList }, + $select + } } - await model.updateMany(query, remapModifier, updateOptions) + await model.updateMany(query, modifier, updateOptions) - return this._findOrGet(id, findParams) - .then(select(params, this.id)) - .catch(errorHandler) + return this.$findOrGet(id, findParams).catch(errorHandler) } async $update (id: Id, data: D, params: P = {} as P): Promise { @@ -260,11 +246,9 @@ export class MongoDbAdapter, P extends MongoDBAdapterParams = const { query } = this.filterQuery(id, params) const replaceOptions = { ...params.mongodb } - await model.replaceOne(query, this._normalizeId(id, data), replaceOptions) + await model.replaceOne(query, this.normalizeId(id, data), replaceOptions) - return this._findOrGet(id, params) - .then(select(params, this.id)) - .catch(errorHandler) + return this.$findOrGet(id, params).catch(errorHandler) } async $remove (id: null, params?: P): Promise; @@ -273,20 +257,23 @@ export class MongoDbAdapter, P extends MongoDBAdapterParams = async $remove (id: NullableId, params: P = {} as P): Promise { const { Model } = this.getOptions(params) const model = await Promise.resolve(Model) - const { query } = this.filterQuery(id, params) + const { query, filters: { $select, $limit } } = this.filterQuery(id, params) const deleteOptions = { ...params.mongodb } const findParams = { ...params, paginate: false, - query + query: { + ...query, + ...($limit === 0 ? { $limit: 0 } : {}), + $select + } } - return this._findOrGet(id, findParams) + return this.$findOrGet(id, findParams) .then(async items => { await model.deleteMany(query, deleteOptions) return items }) - .then(select(params, this.id)) .catch(errorHandler) } } diff --git a/packages/mongodb/src/error-handler.ts b/packages/mongodb/src/error-handler.ts index 1eac24b4c1..3a1967aea2 100644 --- a/packages/mongodb/src/error-handler.ts +++ b/packages/mongodb/src/error-handler.ts @@ -1,10 +1,10 @@ -import errors from '@feathersjs/errors' +import { GeneralError } from '@feathersjs/errors' import { MongoError } from 'mongodb' export function errorHandler (error: MongoError): any { // See https://github.com/mongodb/mongo/blob/master/docs/errors.md - if (error.name === 'MongoError') { - throw new errors.GeneralError(error, { + if (error && error.name && error.name.startsWith('Mongo')) { + throw new GeneralError(error, { name: error.name, code: error.code }) diff --git a/packages/mongodb/test/index.test.ts b/packages/mongodb/test/index.test.ts index 533d4a750f..675a55424d 100644 --- a/packages/mongodb/test/index.test.ts +++ b/packages/mongodb/test/index.test.ts @@ -1,11 +1,13 @@ import { Db, MongoClient, ObjectId } from 'mongodb' import adapterTests from '@feathersjs/adapter-tests' import assert from 'assert' +import { MongoMemoryServer } from 'mongodb-memory-server'; import { feathers } from '@feathersjs/feathers' import errors from '@feathersjs/errors' import { MongoDBService } from '../src' + const testSuite = adapterTests([ '.options', '.events', @@ -106,15 +108,18 @@ describe('Feathers MongoDB Service', () => { let db: Db let mongoClient: MongoClient + let mongod: MongoMemoryServer before(async () => { - const client = await MongoClient.connect('mongodb://localhost:27017/feathers-test') + mongod = await MongoMemoryServer.create(); + + const client = await MongoClient.connect(mongod.getUri()) mongoClient = client db = client.db('feathers-test') app.use('people', new MongoDBService({ - Model: db.collection('people-customid'), + Model: db.collection('people'), events: ['testing'] })) app.use('people-customid', new MongoDBService({ @@ -123,8 +128,6 @@ describe('Feathers MongoDB Service', () => { events: ['testing'] })) - app.service('people').Model = db.collection('people') - db.collection('people-customid').deleteMany({}) db.collection('people').deleteMany({}) db.collection('todos').deleteMany({}) @@ -138,6 +141,7 @@ describe('Feathers MongoDB Service', () => { after(async () => { await db.dropDatabase(); await mongoClient.close(); + await mongod.stop(); }) describe('Service utility functions', () => { @@ -261,6 +265,16 @@ describe('Feathers MongoDB Service', () => { assert.strictEqual(results.length, 1) }) + it('handles errors', async () => { + await assert.rejects(() => peopleService.create({ + name: 'Dave' + }, { + mongodb: { collation: { locale: 'fdsfdsfds', strength: 1 } } + }), { + name: 'GeneralError' + }) + }) + it('updates with default behavior without collation param', async () => { const query = { name: { $gt: 'AAA' } } From f318352cd6daf1e528fc8a24e83b2f96d2aa87aa Mon Sep 17 00:00:00 2001 From: daffl Date: Fri, 29 Apr 2022 11:58:33 -0700 Subject: [PATCH 4/6] Use MongoDB memory server for tests --- package-lock.json | 289 ++++++++++++++++++++++++++++++++-- packages/mongodb/package.json | 5 +- 2 files changed, 281 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index 539e092609..12b02de80b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -54,6 +54,7 @@ "mocha": "^9.2.2", "mocha-puppeteer": "^0.14.0", "mongodb": "^4.4.1", + "mongodb-memory-server": "^8.5.2", "node-fetch": "^2.6.1", "qs": "^6.10.3", "rxjs": "^7.5.5", @@ -3500,6 +3501,11 @@ "@types/node": "*" } }, + "node_modules/@types/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-dDZH/tXzwjutnuk4UacGgFRwV+JSLaXL1ikvidfJprkb7L9Nx1njcRHHmi3Dsvt7pgqqTEeucQuOrWHPFgzVHA==" + }, "node_modules/@types/uuid": { "version": "8.3.4", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", @@ -3945,7 +3951,6 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, "dependencies": { "debug": "4" }, @@ -4360,6 +4365,19 @@ "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" }, + "node_modules/async-mutex": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.3.2.tgz", + "integrity": "sha512-HuTK7E7MT7jZEh1P9GtRW9+aTWiDWWi9InbZ5hjxrnRa39KS4BW04+xLBhYNS2aXhHUIKZSw3gj4Pn1pj+qGAA==", + "dependencies": { + "tslib": "^2.3.1" + } + }, + "node_modules/async-mutex/node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -7296,7 +7314,6 @@ "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, "dependencies": { "once": "^1.4.0" } @@ -8736,6 +8753,11 @@ "node": ">= 0.6" } }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, "node_modules/fs-extra": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", @@ -8960,7 +8982,6 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/get-port/-/get-port-5.1.1.tgz", "integrity": "sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==", - "dev": true, "engines": { "node": ">=8" }, @@ -9679,7 +9700,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, "dependencies": { "agent-base": "6", "debug": "4" @@ -12101,6 +12121,17 @@ "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==" }, + "node_modules/md5-file": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/md5-file/-/md5-file-5.0.0.tgz", + "integrity": "sha512-xbEFXCYVWrSx/gEKS1VPlg84h/4L20znVIulKw6kMfmBUAZNAnF00eczz9ICMl+/hjQGo5KSXRxbL/47X3rmMw==", + "bin": { + "md5-file": "cli.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -12972,6 +13003,77 @@ "node": ">=12" } }, + "node_modules/mongodb-memory-server": { + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/mongodb-memory-server/-/mongodb-memory-server-8.5.2.tgz", + "integrity": "sha512-+4/zxz9TxpPMxaUEm0axQvSf+tS6GtPyc5MEjwkiprBGsH7aTe9GEjuHKnXGP8ObarHFpgW3kV4C4oEzYvxQIQ==", + "hasInstallScript": true, + "dependencies": { + "mongodb-memory-server-core": "8.5.2", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/mongodb-memory-server-core": { + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/mongodb-memory-server-core/-/mongodb-memory-server-core-8.5.2.tgz", + "integrity": "sha512-JVQWZ0ZRWsEeX23cAxhetaJ9q5eILU01dKHrJBwHmMc79BKLdUI2iyIiGve6vyyzYNh4amBcUiWpnbgLmiTlrQ==", + "dependencies": { + "@types/tmp": "^0.2.3", + "async-mutex": "^0.3.2", + "camelcase": "^6.3.0", + "debug": "^4.3.4", + "find-cache-dir": "^3.3.2", + "get-port": "^5.1.1", + "https-proxy-agent": "^5.0.1", + "md5-file": "^5.0.0", + "mongodb": "^4.5.0", + "new-find-package-json": "^1.1.0", + "semver": "^7.3.7", + "tar-stream": "^2.1.4", + "tmp": "^0.2.1", + "tslib": "^2.3.1", + "uuid": "^8.3.1", + "yauzl": "^2.10.0" + }, + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/mongodb-memory-server-core/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mongodb-memory-server-core/node_modules/tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dependencies": { + "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=8.17.0" + } + }, + "node_modules/mongodb-memory-server-core/node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, + "node_modules/mongodb-memory-server/node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -13041,6 +13143,23 @@ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" }, + "node_modules/new-find-package-json": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/new-find-package-json/-/new-find-package-json-1.1.0.tgz", + "integrity": "sha512-KOH3BNZcTKPzEkaJgG2iSUaurxKmefqRKmCOYH+8xqJytNIgjqU4J88BHfK+gy/UlEzlhccLyuJDJAcCgexSwA==", + "dependencies": { + "debug": "^4.3.2", + "tslib": "^2.3.0" + }, + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/new-find-package-json/node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, "node_modules/node-fetch": { "version": "2.6.7", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", @@ -15970,7 +16089,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, "dependencies": { "glob": "^7.1.3" }, @@ -16885,6 +17003,31 @@ "node": ">= 10" } }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar-stream/node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, "node_modules/temp-dir": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz", @@ -21051,6 +21194,11 @@ "@types/node": "*" } }, + "@types/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-dDZH/tXzwjutnuk4UacGgFRwV+JSLaXL1ikvidfJprkb7L9Nx1njcRHHmi3Dsvt7pgqqTEeucQuOrWHPFgzVHA==" + }, "@types/uuid": { "version": "8.3.4", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", @@ -21378,7 +21526,6 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, "requires": { "debug": "4" } @@ -21711,6 +21858,21 @@ "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" }, + "async-mutex": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.3.2.tgz", + "integrity": "sha512-HuTK7E7MT7jZEh1P9GtRW9+aTWiDWWi9InbZ5hjxrnRa39KS4BW04+xLBhYNS2aXhHUIKZSw3gj4Pn1pj+qGAA==", + "requires": { + "tslib": "^2.3.1" + }, + "dependencies": { + "tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + } + } + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -24141,7 +24303,6 @@ "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" } @@ -25270,6 +25431,11 @@ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, "fs-extra": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", @@ -25457,8 +25623,7 @@ "get-port": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/get-port/-/get-port-5.1.1.tgz", - "integrity": "sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==", - "dev": true + "integrity": "sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==" }, "get-stdin": { "version": "8.0.0", @@ -26004,7 +26169,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, "requires": { "agent-base": "6", "debug": "4" @@ -27937,6 +28101,11 @@ "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==" }, + "md5-file": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/md5-file/-/md5-file-5.0.0.tgz", + "integrity": "sha512-xbEFXCYVWrSx/gEKS1VPlg84h/4L20znVIulKw6kMfmBUAZNAnF00eczz9ICMl+/hjQGo5KSXRxbL/47X3rmMw==" + }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -28608,6 +28777,65 @@ } } }, + "mongodb-memory-server": { + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/mongodb-memory-server/-/mongodb-memory-server-8.5.2.tgz", + "integrity": "sha512-+4/zxz9TxpPMxaUEm0axQvSf+tS6GtPyc5MEjwkiprBGsH7aTe9GEjuHKnXGP8ObarHFpgW3kV4C4oEzYvxQIQ==", + "requires": { + "mongodb-memory-server-core": "8.5.2", + "tslib": "^2.3.1" + }, + "dependencies": { + "tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + } + } + }, + "mongodb-memory-server-core": { + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/mongodb-memory-server-core/-/mongodb-memory-server-core-8.5.2.tgz", + "integrity": "sha512-JVQWZ0ZRWsEeX23cAxhetaJ9q5eILU01dKHrJBwHmMc79BKLdUI2iyIiGve6vyyzYNh4amBcUiWpnbgLmiTlrQ==", + "requires": { + "@types/tmp": "^0.2.3", + "async-mutex": "^0.3.2", + "camelcase": "^6.3.0", + "debug": "^4.3.4", + "find-cache-dir": "^3.3.2", + "get-port": "^5.1.1", + "https-proxy-agent": "^5.0.1", + "md5-file": "^5.0.0", + "mongodb": "^4.5.0", + "new-find-package-json": "^1.1.0", + "semver": "^7.3.7", + "tar-stream": "^2.1.4", + "tmp": "^0.2.1", + "tslib": "^2.3.1", + "uuid": "^8.3.1", + "yauzl": "^2.10.0" + }, + "dependencies": { + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==" + }, + "tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "requires": { + "rimraf": "^3.0.0" + } + }, + "tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + } + } + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -28661,6 +28889,22 @@ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" }, + "new-find-package-json": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/new-find-package-json/-/new-find-package-json-1.1.0.tgz", + "integrity": "sha512-KOH3BNZcTKPzEkaJgG2iSUaurxKmefqRKmCOYH+8xqJytNIgjqU4J88BHfK+gy/UlEzlhccLyuJDJAcCgexSwA==", + "requires": { + "debug": "^4.3.2", + "tslib": "^2.3.0" + }, + "dependencies": { + "tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + } + } + }, "node-fetch": { "version": "2.6.7", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", @@ -30959,7 +31203,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, "requires": { "glob": "^7.1.3" } @@ -31658,6 +31901,30 @@ "yallist": "^4.0.0" } }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "dependencies": { + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + } + } + }, "temp-dir": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz", diff --git a/packages/mongodb/package.json b/packages/mongodb/package.json index cad9336b3c..ad8d95a96b 100644 --- a/packages/mongodb/package.json +++ b/packages/mongodb/package.json @@ -50,10 +50,10 @@ "access": "public" }, "dependencies": { - "@feathersjs/feathers": "^5.0.0-pre.18", "@feathersjs/adapter-commons": "^5.0.0-pre.18", "@feathersjs/commons": "^5.0.0-pre.18", - "@feathersjs/errors": "^5.0.0-pre.18" + "@feathersjs/errors": "^5.0.0-pre.18", + "@feathersjs/feathers": "^5.0.0-pre.18" }, "peerDependencies": { "mongodb": "^4.5.0" @@ -63,6 +63,7 @@ "@types/mocha": "^9.1.0", "@types/node": "^17.0.23", "mocha": "^9.2.2", + "mongodb-memory-server": "^8.5.2", "shx": "^0.3.4", "typescript": "^4.6.3" } From b64913da6f0fd84fca9bceb89fa885293bf60ced Mon Sep 17 00:00:00 2001 From: daffl Date: Fri, 29 Apr 2022 12:39:49 -0700 Subject: [PATCH 5/6] Update Codeclimate settings for TypeScript interface duplication --- .codeclimate.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.codeclimate.yml b/.codeclimate.yml index 4343c26245..31a39c5772 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -34,7 +34,7 @@ plugins: duplication: enabled: true config: - count_threshold: 3 + count_threshold: 4 exclude_patterns: - "**/test/*" - "**/adapter-tests/*" From 512f6393810ccb4a6a48080b8a577d7c2f622da5 Mon Sep 17 00:00:00 2001 From: daffl Date: Fri, 29 Apr 2022 15:13:40 -0700 Subject: [PATCH 6/6] Fix query type --- packages/mongodb/src/adapter.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/mongodb/src/adapter.ts b/packages/mongodb/src/adapter.ts index 566f60cd40..8ee888dd3a 100644 --- a/packages/mongodb/src/adapter.ts +++ b/packages/mongodb/src/adapter.ts @@ -5,7 +5,7 @@ import { import { NotFound } from '@feathersjs/errors' import { _ } from '@feathersjs/commons' import { AdapterBase, select, AdapterParams, AdapterServiceOptions, PaginationOptions, AdapterQuery } from '@feathersjs/adapter-commons' -import { NullableId, Query, Id, Paginated } from '@feathersjs/feathers' +import { NullableId, Id, Paginated } from '@feathersjs/feathers' import { errorHandler } from './error-handler' export interface MongoDBAdapterOptions extends AdapterServiceOptions { @@ -14,7 +14,7 @@ export interface MongoDBAdapterOptions extends AdapterServiceOptions { useEstimatedDocumentCount?: boolean } -export interface MongoDBAdapterParams extends AdapterParams { +export interface MongoDBAdapterParams extends AdapterParams> { mongodb?: BulkWriteOptions|FindOptions|InsertOneOptions|DeleteOptions|CountDocumentsOptions|ReplaceOptions }