From 9b4f04e6d848268e66e8b6244741e515c8bc9a36 Mon Sep 17 00:00:00 2001 From: vanpho93 Date: Tue, 13 Dec 2022 09:23:20 +0700 Subject: [PATCH 1/7] fix: unable to start mongodb on circleci test Signed-off-by: vanpho93 --- .circleci/config.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index bbd469a5b3b..0964e9c7cae 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -182,10 +182,13 @@ jobs: VERSION=$(cat ./apps/reaction/package.json | grep -m 1 version | sed 's/[^0-9.]//g') docker build --no-cache -t ${DOCKER_REPOSITORY}:${VERSION} -t ${DOCKER_REPOSITORY}:latest -f ./apps/reaction/Dockerfile . - run: - name: Copy env file + name: Create .env file command: | - cp ./apps/reaction/.env.example ./.env + touch .env + echo "MONGO_URL=mongodb://mongo.reaction.localhost:27017/reaction?&replicaSet=rs0" >> .env + echo "ROOT_URL=http://localhost:3000" >> .env echo "STORE_URL=http://localhost:4000" >> .env + echo "STRIPE_API_KEY=YOUR_PRIVATE_STRIPE_API_KEY" >> .env - run: name: Create reaction.localhost network command: docker network create "reaction.localhost" || true From 6afa3cd000a5d7109390f371298c458a6d6ff4d8 Mon Sep 17 00:00:00 2001 From: vanpho93 Date: Mon, 24 Oct 2022 15:28:08 +0700 Subject: [PATCH 2/7] feat: upgrade mongodb to version 4.4 Signed-off-by: vanpho93 --- packages/api-core/package.json | 2 +- packages/api-core/src/ReactionAPICore.js | 148 +++++++++++++----- packages/api-core/src/ReactionAPICore.test.js | 88 +++++++++++ .../src/util/mongoConnectWithRetry.js | 2 +- pnpm-lock.yaml | 82 ++++++---- 5 files changed, 250 insertions(+), 72 deletions(-) diff --git a/packages/api-core/package.json b/packages/api-core/package.json index dd2628c8734..c15ed79eea5 100644 --- a/packages/api-core/package.json +++ b/packages/api-core/package.json @@ -67,7 +67,7 @@ "express": "^4.17.1", "graphql-iso-date": "^3.6.1", "lodash": "^4.17.15", - "mongodb": "3.6.2", + "mongodb": "4.4.1", "promise-retry": "^1.1.1", "simpl-schema": "^1.7.0" }, diff --git a/packages/api-core/src/ReactionAPICore.js b/packages/api-core/src/ReactionAPICore.js index 8c6a6b7cc28..395645d2424 100644 --- a/packages/api-core/src/ReactionAPICore.js +++ b/packages/api-core/src/ReactionAPICore.js @@ -1,9 +1,10 @@ +/* eslint-disable no-extra-bind */ import { createServer } from "http"; import { createRequire } from "module"; import diehard from "diehard"; import express from "express"; import _ from "lodash"; -import mongodb from "mongodb"; +import * as mongodb from "mongodb"; import SimpleSchema from "simpl-schema"; import collectionIndex from "@reactioncommerce/api-utils/collectionIndex.js"; import getAbsoluteUrl from "@reactioncommerce/api-utils/getAbsoluteUrl.js"; @@ -276,43 +277,9 @@ export default class ReactionAPICore { // Add the collection instance to `context.collections`. // If the collection already exists, we need to modify it instead of calling // `createCollection`, in order to add validation options. - const getCollectionPromise = new Promise((resolve, reject) => { - this.db.collection( - collectionConfig.name, - { strict: true }, - (error, collection) => { - if (error) { - // Collection with this name doesn't yet exist - this.db - .createCollection( - collectionConfig.name, - collectionOptions - ) - .then((newCollection) => { - resolve(newCollection); - return null; - }) - .catch(reject); - } else { - // Collection with this name exists, so modify before resolving - this.db - .command({ - collMod: collectionConfig.name, - ...collectionOptions - }) - .then(() => { - resolve(collection); - return null; - }) - .catch(reject); - } - } - ); - }); - - /* eslint-enable promise/no-promise-in-callback */ - - this.collections[collectionKey] = await getCollectionPromise; // eslint-disable-line no-await-in-loop + // eslint-disable-next-line no-await-in-loop + this.collections[collectionKey] = await this.getCollection(collectionConfig, collectionOptions); + this.applyMongoV3BackwardCompatible(this.collections[collectionKey]); // If the collection config has `indexes` key, define all requested indexes if (Array.isArray(collectionConfig.indexes)) { @@ -330,6 +297,111 @@ export default class ReactionAPICore { } } + /** + * @summary Get legacy collection object + * @param {Object} collectionConfig - The collection config + * @param {Object} collectionOptions - The collection options + * @returns {Object} - legacy collection + */ + async getCollection(collectionConfig, collectionOptions) { + try { + return this.db.collection(collectionConfig.name, collectionOptions); + } catch { + return this.db + .command({ collMod: collectionConfig.name, ...collectionOptions }); + } + } + + /** + * @summary Apply MongoV3 backward compatible + * @param {Object} collection - The legacy collection object + * @returns {undefined} Nothing + */ + applyMongoV3BackwardCompatible(collection) { + const prevFind = collection.find.bind(collection); + collection.find = ((...args) => { + const result = prevFind(...args); + result.cmd = { query: result[Reflect.ownKeys(result).find((symbol) => String(symbol) === "Symbol(filter)")] }; + result.options = { db: collection.s.db }; + result.ns = `${collection.s.namespace.db}.${collection.s.namespace.collection}`; + return result; + }).bind(collection); + + const acknowledgedToOk = (acknowledged) => (acknowledged ? 1 : 0); + + const prevDeleteOne = collection.deleteOne.bind(collection); + collection.deleteOne = (async (...args) => { + const response = await prevDeleteOne(...args); + // eslint-disable-next-line id-length + return { ...response, result: { n: response.deletedCount, ok: acknowledgedToOk(response.acknowledged) } }; + }).bind(collection); + + collection.removeOne = collection.deleteOne.bind(collection); + + const prevUpdateMany = collection.updateMany.bind(collection); + collection.updateMany = (async (...args) => { + const response = await prevUpdateMany(...args); + // eslint-disable-next-line id-length + return { ...response, result: { n: response.modifiedCount, ok: acknowledgedToOk(response.acknowledged) } }; + }).bind(collection); + + const prevInsertOne = collection.insertOne.bind(collection); + collection.insertOne = (async (...args) => { + const response = await prevInsertOne(...args); + // eslint-disable-next-line id-length + return { ...response, result: { n: response.acknowledged ? 1 : 0, ok: acknowledgedToOk(response.acknowledged) } }; + }).bind(collection); + + const prevFindOneAndUpdate = collection.findOneAndUpdate.bind(collection); + collection.findOneAndUpdate = (async (...args) => { + const options = args[2]; + if (options && typeof options.returnOriginal !== "undefined") { + args[2].returnDocument = options.returnOriginal ? mongodb.ReturnDocument.BEFORE : mongodb.ReturnDocument.AFTER; + } + const response = await prevFindOneAndUpdate(...args); + return { ...response, modifiedCount: response.lastErrorObject.n }; + }).bind(collection); + + const prevReplaceOne = collection.replaceOne.bind(collection); + collection.replaceOne = (async (...args) => { + const response = await prevReplaceOne(...args); + // eslint-disable-next-line id-length + return { ...response, result: { n: response.modifiedCount, ok: acknowledgedToOk(response.acknowledged) } }; + }).bind(collection); + + const prevUpdateOne = collection.updateOne.bind(collection); + collection.updateOne = (async (...args) => { + const response = await prevUpdateOne(...args); + // eslint-disable-next-line id-length + return { ...response, result: { n: response.modifiedCount, ok: acknowledgedToOk(response.acknowledged) } }; + }).bind(collection); + + const prevBulkWrite = collection.bulkWrite.bind(collection); + collection.bulkWrite = (async (...args) => { + const response = await prevBulkWrite(...args); + const { + nInserted, + nUpserted, + nMatched, + nModified, + nRemoved + } = response.result; + return { + ...response, + nInserted, + nUpserted, + nMatched, + nModified, + nRemoved, + insertedCount: nInserted, + matchedCount: nMatched, + modifiedCount: nModified, + deletedCount: nRemoved, + upsertedCount: nUpserted + }; + }).bind(collection); + } + /** * @summary Given a MongoDB URL, creates a connection to it, sets `this.mongoClient`, * calls `this.setMongoDatabase` with the database instance, and then diff --git a/packages/api-core/src/ReactionAPICore.test.js b/packages/api-core/src/ReactionAPICore.test.js index 8524536ab23..830e1a6c7eb 100644 --- a/packages/api-core/src/ReactionAPICore.test.js +++ b/packages/api-core/src/ReactionAPICore.test.js @@ -1,3 +1,5 @@ +/* eslint-disable id-length */ + import importAsString from "@reactioncommerce/api-utils/importAsString.js"; import ReactionAPICore from "./ReactionAPICore.js"; import appEvents from "./util/appEvents.js"; @@ -57,3 +59,89 @@ test("throws error if appEvents is missing any props", () => { expect(error.message).toBe("appEvents is missing the following required function properties: emit, on, resume, stop"); } }); + +test("getCollection should return correct values", async () => { + const collectionConfig = { name: "Test" }; + const mockCollection = { + find: jest.fn().mockReturnValue({}), + deleteOne: jest.fn().mockReturnValue({ deletedCount: 1, acknowledged: true }), + updateMany: jest.fn().mockReturnValue({ modifiedCount: 2, acknowledged: true }), + insertOne: jest.fn().mockReturnValue({ acknowledged: true }), + findOneAndUpdate: jest.fn().mockReturnValue({ ok: 1, lastErrorObject: { n: 1 } }), + replaceOne: jest.fn().mockReturnValue({ modifiedCount: 1, acknowledged: true }), + updateOne: jest.fn().mockReturnValue({ modifiedCount: 1, acknowledged: true }), + bulkWrite: jest.fn().mockReturnValue({ + result: { + ok: 1, + writeErrors: [], + writeConcernErrors: [], + nInserted: 1, + nUpserted: 2, + nMatched: 3, + nModified: 4, + nRemoved: 5 + } + }), + // eslint-disable-next-line id-length + s: { + db: jest.fn(), + namespace: { + db: "test_db", + collection: "test_collection" + } + } + }; + + const api = new ReactionAPICore(); + + api.db = { + collection: () => ({ ...mockCollection }), + command: jest.fn() + }; + + const collection = await api.getCollection(collectionConfig, {}); + api.applyMongoV3BackwardCompatible(collection); + + collection.find({}); + expect(mockCollection.find).toBeCalled(); + + const deleteOneResult = await collection.deleteOne({}); + expect(mockCollection.deleteOne).toBeCalled(); + expect(deleteOneResult).toEqual({ ...deleteOneResult, result: { n: 1, ok: 1 } }); + + const updateManyResult = await collection.updateMany({}); + expect(mockCollection.updateMany).toBeCalled(); + expect(updateManyResult).toEqual({ ...updateManyResult, result: { n: 2, ok: 1 } }); + + const insertOneResult = await collection.insertOne({}); + expect(mockCollection.insertOne).toBeCalled(); + expect(insertOneResult).toEqual({ ...insertOneResult, result: { n: 1, ok: 1 } }); + + const findOneAndUpdateResult = await collection.findOneAndUpdate({}); + expect(mockCollection.findOneAndUpdate).toBeCalled(); + expect(findOneAndUpdateResult).toEqual({ ...findOneAndUpdateResult, modifiedCount: 1 }); + + const replaceOneResult = await collection.replaceOne({}); + expect(mockCollection.replaceOne).toBeCalled(); + expect(replaceOneResult).toEqual({ ...replaceOneResult, result: { n: 1, ok: 1 } }); + + const updateOneResult = await collection.updateOne({}); + expect(mockCollection.updateOne).toBeCalled(); + expect(updateOneResult).toEqual({ ...updateOneResult, result: { n: 1, ok: 1 } }); + + const bulkWriteResult = await collection.bulkWrite({}); + expect(mockCollection.updateOne).toBeCalled(); + expect(bulkWriteResult).toEqual({ + ...bulkWriteResult, + nInserted: 1, + nUpserted: 2, + nMatched: 3, + nModified: 4, + nRemoved: 5, + insertedCount: 1, + upsertedCount: 2, + matchedCount: 3, + modifiedCount: 4, + deletedCount: 5 + }); +}); diff --git a/packages/api-core/src/util/mongoConnectWithRetry.js b/packages/api-core/src/util/mongoConnectWithRetry.js index e5b877b51e3..2ad0d504ccf 100644 --- a/packages/api-core/src/util/mongoConnectWithRetry.js +++ b/packages/api-core/src/util/mongoConnectWithRetry.js @@ -1,5 +1,5 @@ import Logger from "@reactioncommerce/logger"; -import mongodb from "mongodb"; +import * as mongodb from "mongodb"; import promiseRetry from "promise-retry"; import config from "../config.js"; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f6db6eebd2d..abae6fb034c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -166,6 +166,7 @@ importers: '@reactioncommerce/api-plugin-payments-stripe-sca': 1.0.2 '@reactioncommerce/api-plugin-pricing-simple': 1.0.7 '@reactioncommerce/api-plugin-products': 1.3.1 + '@reactioncommerce/api-plugin-sample-data': 1.0.0 '@reactioncommerce/api-plugin-settings': 1.0.7 '@reactioncommerce/api-plugin-shipments': 1.0.3 '@reactioncommerce/api-plugin-shipments-flat-rate': 1.0.10 @@ -226,6 +227,7 @@ importers: '@reactioncommerce/api-plugin-payments-stripe-sca': link:../../packages/api-plugin-payments-stripe-sca '@reactioncommerce/api-plugin-pricing-simple': link:../../packages/api-plugin-pricing-simple '@reactioncommerce/api-plugin-products': link:../../packages/api-plugin-products + '@reactioncommerce/api-plugin-sample-data': link:../../packages/api-plugin-sample-data '@reactioncommerce/api-plugin-settings': link:../../packages/api-plugin-settings '@reactioncommerce/api-plugin-shipments': link:../../packages/api-plugin-shipments '@reactioncommerce/api-plugin-shipments-flat-rate': link:../../packages/api-plugin-shipments-flat-rate @@ -291,7 +293,7 @@ importers: graphql: 14.7.0 graphql-iso-date: ^3.6.1 lodash: ^4.17.15 - mongodb: 3.6.2 + mongodb: 4.4.1 promise-retry: ^1.1.1 simpl-schema: ^1.7.0 dependencies: @@ -315,7 +317,7 @@ importers: express: 4.18.1 graphql-iso-date: 3.6.1_graphql@14.7.0 lodash: 4.17.21 - mongodb: 3.6.2 + mongodb: 4.4.1 promise-retry: 1.1.1 simpl-schema: 1.12.3 devDependencies: @@ -4639,7 +4641,7 @@ packages: dependencies: eslint: 8.23.1 eslint-plugin-import: 2.25.4_eslint@8.23.1 - eslint-plugin-jest: 26.9.0_2ex7m26yair3ztqnyc2u7licva + eslint-plugin-jest: 26.9.0_eslint@8.23.1 eslint-plugin-jsx-a11y: 6.5.1_eslint@8.23.1 eslint-plugin-node: 11.1.0_eslint@8.23.1 eslint-plugin-promise: 6.0.1_eslint@8.23.1 @@ -4964,6 +4966,26 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true + /@typescript-eslint/typescript-estree/5.37.0: + resolution: {integrity: sha512-JkFoFIt/cx59iqEDSgIGnQpCTRv96MQnXCYvJi7QhBC24uyuzbD8wVbajMB1b9x4I0octYFJ3OwjAwNqk1AjDA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 5.37.0 + '@typescript-eslint/visitor-keys': 5.37.0 + debug: 4.3.4 + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.3.7 + tsutils: 3.21.0 + transitivePeerDependencies: + - supports-color + dev: true + /@typescript-eslint/typescript-estree/5.37.0_typescript@2.9.2: resolution: {integrity: sha512-JkFoFIt/cx59iqEDSgIGnQpCTRv96MQnXCYvJi7QhBC24uyuzbD8wVbajMB1b9x4I0octYFJ3OwjAwNqk1AjDA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -4985,7 +5007,7 @@ packages: - supports-color dev: true - /@typescript-eslint/utils/5.37.0_2ex7m26yair3ztqnyc2u7licva: + /@typescript-eslint/utils/5.37.0_eslint@8.23.1: resolution: {integrity: sha512-jUEJoQrWbZhmikbcWSMDuUSxEE7ID2W/QCV/uz10WtQqfOuKZUqFGjqLJ+qhDd17rjgp+QJPqTdPIBWwoob2NQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -4994,7 +5016,7 @@ packages: '@types/json-schema': 7.0.11 '@typescript-eslint/scope-manager': 5.37.0 '@typescript-eslint/types': 5.37.0 - '@typescript-eslint/typescript-estree': 5.37.0_typescript@2.9.2 + '@typescript-eslint/typescript-estree': 5.37.0 eslint: 8.23.1 eslint-scope: 5.1.1 eslint-utils: 3.0.0_eslint@8.23.1 @@ -7762,7 +7784,7 @@ packages: - supports-color dev: true - /eslint-plugin-jest/26.9.0_2ex7m26yair3ztqnyc2u7licva: + /eslint-plugin-jest/26.9.0_eslint@8.23.1: resolution: {integrity: sha512-TWJxWGp1J628gxh2KhaH1H1paEdgE2J61BBF1I59c6xWeL5+D1BzMxGDN/nXAfX+aSkR5u80K+XhskK6Gwq9ng==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -7775,7 +7797,7 @@ packages: jest: optional: true dependencies: - '@typescript-eslint/utils': 5.37.0_2ex7m26yair3ztqnyc2u7licva + '@typescript-eslint/utils': 5.37.0_eslint@8.23.1 eslint: 8.23.1 transitivePeerDependencies: - supports-color @@ -11341,19 +11363,6 @@ packages: whatwg-url: 11.0.0 dev: false - /mongodb/3.6.2: - resolution: {integrity: sha512-sSZOb04w3HcnrrXC82NEh/YGCmBuRgR+C1hZgmmv4L6dBz4BkRse6Y8/q/neXer9i95fKUBbFi4KgeceXmbsOA==} - engines: {node: '>=4'} - dependencies: - bl: 2.2.1 - bson: 1.1.6 - denque: 1.5.1 - require_optional: 1.0.1 - safe-buffer: 5.2.1 - optionalDependencies: - saslprep: 1.0.3 - dev: false - /mongodb/3.7.3: resolution: {integrity: sha512-Psm+g3/wHXhjBEktkxXsFMZvd3nemI0r3IPsE0bU+4//PnvNWKkzhZcEsbPcYiWqe8XqXJJEg4Tgtr7Raw67Yw==} engines: {node: '>=4'} @@ -11387,6 +11396,18 @@ packages: saslprep: 1.0.3 dev: false + /mongodb/4.4.1: + resolution: {integrity: sha512-IAD3nFtCR4s22vi5qjqkCBnuyDDrOW8WVSSmgHquOvGaP1iTD+XpC5tr8wAUbZ2EeZkaswwBKQFHDvl4qYcKqQ==} + engines: {node: '>=12.9.0'} + dependencies: + bson: 4.7.0 + denque: 2.1.0 + mongodb-connection-string-url: 2.5.3 + socks: 2.7.0 + optionalDependencies: + saslprep: 1.0.3 + dev: false + /mongodb/4.9.1: resolution: {integrity: sha512-ZhgI/qBf84fD7sI4waZBoLBNJYPQN5IOC++SBCiPiyhzpNKOxN/fi0tBHvH2dEC42HXtNEbFB0zmNz4+oVtorQ==} engines: {node: '>=12.9.0'} @@ -12668,13 +12689,6 @@ packages: /require-main-filename/2.0.0: resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} - /require_optional/1.0.1: - resolution: {integrity: sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==} - dependencies: - resolve-from: 2.0.0 - semver: 5.7.1 - dev: false - /requires-port/1.0.0: resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} dev: false @@ -12686,11 +12700,6 @@ packages: resolve-from: 5.0.0 dev: true - /resolve-from/2.0.0: - resolution: {integrity: sha512-qpFcKaXsq8+oRoLilkwyc7zHGF5i9Q2/25NIgLQQ/+VVv9rU4qvr6nXVAw1DsnXJyQkZsR4Ytfbtg5ehfcUssQ==} - engines: {node: '>=0.10.0'} - dev: false - /resolve-from/3.0.0: resolution: {integrity: sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==} engines: {node: '>=4'} @@ -13819,6 +13828,15 @@ packages: /tslib/2.4.0: resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} + /tsutils/3.21.0: + resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} + engines: {node: '>= 6'} + peerDependencies: + typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' + dependencies: + tslib: 1.14.1 + dev: true + /tsutils/3.21.0_typescript@2.9.2: resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} engines: {node: '>= 6'} From 881b807325aabdd8fb9828a015ecedcdcfec97b9 Mon Sep 17 00:00:00 2001 From: vanpho93 Date: Mon, 24 Oct 2022 15:41:28 +0700 Subject: [PATCH 3/7] feat: remove gridfs-stream Signed-off-by: Brian Nguyen Signed-off-by: vanpho93 --- .../file-collections-sa-gridfs/package.json | 3 +-- .../src/GridFSStore.js | 26 ++++++++----------- pnpm-lock.yaml | 4 --- 3 files changed, 12 insertions(+), 21 deletions(-) diff --git a/packages/file-collections-sa-gridfs/package.json b/packages/file-collections-sa-gridfs/package.json index 1da8eca5e22..0361f6b81c0 100644 --- a/packages/file-collections-sa-gridfs/package.json +++ b/packages/file-collections-sa-gridfs/package.json @@ -68,8 +68,7 @@ "dependencies": { "@babel/runtime-corejs2": "^7.14.8", "@reactioncommerce/file-collections-sa-base": "^0.2.2", - "debug": "^4.3.2", - "gridfs-stream": "^1.1.1" + "debug": "^4.3.2" }, "devDependencies": { "@babel/cli": "^7.10.5", diff --git a/packages/file-collections-sa-gridfs/src/GridFSStore.js b/packages/file-collections-sa-gridfs/src/GridFSStore.js index f10f3df3516..913143d16b5 100644 --- a/packages/file-collections-sa-gridfs/src/GridFSStore.js +++ b/packages/file-collections-sa-gridfs/src/GridFSStore.js @@ -1,4 +1,3 @@ -import Grid from "gridfs-stream"; import StorageAdapter from "@reactioncommerce/file-collections-sa-base"; import debug from "./debug"; @@ -25,7 +24,7 @@ export default class GridFSStore extends StorageAdapter { this.chunkSize = chunkSize; this.collectionName = `${collectionPrefix}${name}`.trim(); - this.grid = Grid(db, mongodb); + this.grid = new mongodb.GridFSBucket(db); this.mongodb = mongodb; } @@ -42,37 +41,34 @@ export default class GridFSStore extends StorageAdapter { } _getReadStream(fileKey, { start: startPos, end: endPos } = {}) { - const opts = { _id: fileKey._id, root: this.collectionName }; + const opts = {}; // Add range if this should be a partial read if (typeof startPos === "number" && typeof endPos === "number") { - opts.range = { startPos, endPos }; + opts.start = startPos; + opts.end = endPos; } debug("GridFSStore _getReadStream opts:", opts); - return this.grid.createReadStream(opts); + const _id = new this.mongodb.ObjectId(fileKey._id); + return this.grid.openDownloadStream(_id, opts); } _getWriteStream(fileKey, options = {}) { const opts = { - chunk_size: this.chunkSize, // eslint-disable-line camelcase - content_type: "application/octet-stream", // eslint-disable-line camelcase - filename: fileKey.filename, - mode: "w", // overwrite any existing data - root: this.collectionName, + chunkSizeBytes: this.chunkSize, + contentType: "application/octet-stream", ...options }; - if (fileKey._id) opts._id = fileKey._id; - debug("GridFSStore _getWriteStream opts:", opts); - const writeStream = this.grid.createWriteStream(opts); + const writeStream = this.grid.openUploadStream(fileKey.filename, opts); - writeStream.on("close", (file) => { + writeStream.on("finish", (file) => { if (!file) { - // gridfs-stream will emit "close" without passing a file + // gridfs will emit "finish" without passing a file // if there is an error. We can simply exit here because // the "error" listener will also be called in this case. return; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index abae6fb034c..b6495ab672e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -166,7 +166,6 @@ importers: '@reactioncommerce/api-plugin-payments-stripe-sca': 1.0.2 '@reactioncommerce/api-plugin-pricing-simple': 1.0.7 '@reactioncommerce/api-plugin-products': 1.3.1 - '@reactioncommerce/api-plugin-sample-data': 1.0.0 '@reactioncommerce/api-plugin-settings': 1.0.7 '@reactioncommerce/api-plugin-shipments': 1.0.3 '@reactioncommerce/api-plugin-shipments-flat-rate': 1.0.10 @@ -227,7 +226,6 @@ importers: '@reactioncommerce/api-plugin-payments-stripe-sca': link:../../packages/api-plugin-payments-stripe-sca '@reactioncommerce/api-plugin-pricing-simple': link:../../packages/api-plugin-pricing-simple '@reactioncommerce/api-plugin-products': link:../../packages/api-plugin-products - '@reactioncommerce/api-plugin-sample-data': link:../../packages/api-plugin-sample-data '@reactioncommerce/api-plugin-settings': link:../../packages/api-plugin-settings '@reactioncommerce/api-plugin-shipments': link:../../packages/api-plugin-shipments '@reactioncommerce/api-plugin-shipments-flat-rate': link:../../packages/api-plugin-shipments-flat-rate @@ -1464,12 +1462,10 @@ importers: '@reactioncommerce/file-collections-sa-base': ^0.2.2 babel-core: ^7.0.0-bridge.0 debug: ^4.3.2 - gridfs-stream: ^1.1.1 dependencies: '@babel/runtime-corejs2': 7.19.0 '@reactioncommerce/file-collections-sa-base': link:../file-collections-sa-base debug: 4.3.4 - gridfs-stream: 1.1.1 devDependencies: '@babel/cli': 7.18.10_@babel+core@7.19.0 '@babel/core': 7.19.0 From d33456aea66278a60387af2a4d451cb8d1e55152 Mon Sep 17 00:00:00 2001 From: vanpho93 Date: Mon, 24 Oct 2022 16:16:43 +0700 Subject: [PATCH 4/7] feat: add mongodb as peerDependencies for file collection gridfs package Signed-off-by: Brian Nguyen Signed-off-by: vanpho93 --- .changeset/nasty-camels-beam.md | 6 ++++++ packages/file-collections-sa-gridfs/package.json | 3 +++ pnpm-lock.yaml | 2 ++ 3 files changed, 11 insertions(+) create mode 100644 .changeset/nasty-camels-beam.md diff --git a/.changeset/nasty-camels-beam.md b/.changeset/nasty-camels-beam.md new file mode 100644 index 00000000000..3962ea9f967 --- /dev/null +++ b/.changeset/nasty-camels-beam.md @@ -0,0 +1,6 @@ +--- +"@reactioncommerce/api-core": patch +"@reactioncommerce/file-collections-sa-gridfs": patch +--- + +feat: upgrade mongodb to 4.4 diff --git a/packages/file-collections-sa-gridfs/package.json b/packages/file-collections-sa-gridfs/package.json index 0361f6b81c0..808040bff83 100644 --- a/packages/file-collections-sa-gridfs/package.json +++ b/packages/file-collections-sa-gridfs/package.json @@ -86,6 +86,9 @@ "@babel/preset-env": "^7.10.4", "babel-core": "^7.0.0-bridge.0" }, + "peerDependencies": { + "mongodb": "4.4.1" + }, "publishConfig": { "access": "public" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b6495ab672e..ac43089bfbe 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1462,10 +1462,12 @@ importers: '@reactioncommerce/file-collections-sa-base': ^0.2.2 babel-core: ^7.0.0-bridge.0 debug: ^4.3.2 + mongodb: 4.4.1 dependencies: '@babel/runtime-corejs2': 7.19.0 '@reactioncommerce/file-collections-sa-base': link:../file-collections-sa-base debug: 4.3.4 + mongodb: 4.4.1 devDependencies: '@babel/cli': 7.18.10_@babel+core@7.19.0 '@babel/core': 7.19.0 From 9d26f05286a43d99f4b8a2924b5a0644a5a03ccc Mon Sep 17 00:00:00 2001 From: Brian Nguyen Date: Mon, 24 Oct 2022 16:31:12 +0700 Subject: [PATCH 5/7] Create sweet-dolphins-wonder.md Signed-off-by: vanpho93 --- .changeset/sweet-dolphins-wonder.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/sweet-dolphins-wonder.md diff --git a/.changeset/sweet-dolphins-wonder.md b/.changeset/sweet-dolphins-wonder.md new file mode 100644 index 00000000000..2f78bacbd3a --- /dev/null +++ b/.changeset/sweet-dolphins-wonder.md @@ -0,0 +1,6 @@ +--- +"@reactioncommerce/api-core": minor +"@reactioncommerce/file-collections-sa-gridfs": minor +--- + +feat: upgrade mongodb to 4.4 From d710812ec7fe3004b24846daba80ef1be45c2323 Mon Sep 17 00:00:00 2001 From: Brian Nguyen Date: Mon, 24 Oct 2022 16:36:11 +0700 Subject: [PATCH 6/7] Delete nasty-camels-beam.md Signed-off-by: vanpho93 --- .changeset/nasty-camels-beam.md | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 .changeset/nasty-camels-beam.md diff --git a/.changeset/nasty-camels-beam.md b/.changeset/nasty-camels-beam.md deleted file mode 100644 index 3962ea9f967..00000000000 --- a/.changeset/nasty-camels-beam.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@reactioncommerce/api-core": patch -"@reactioncommerce/file-collections-sa-gridfs": patch ---- - -feat: upgrade mongodb to 4.4 From 87fea304e53cac127a27d4922fbb3676cf3455bc Mon Sep 17 00:00:00 2001 From: vanpho93 Date: Tue, 13 Dec 2022 10:31:34 +0700 Subject: [PATCH 7/7] feat: add range for mongo peer-deps on file-colletion-sa-gridfs Signed-off-by: vanpho93 --- .../file-collections-sa-gridfs/package.json | 2 +- pnpm-lock.yaml | 43 +++---------------- 2 files changed, 8 insertions(+), 37 deletions(-) diff --git a/packages/file-collections-sa-gridfs/package.json b/packages/file-collections-sa-gridfs/package.json index 808040bff83..36182869694 100644 --- a/packages/file-collections-sa-gridfs/package.json +++ b/packages/file-collections-sa-gridfs/package.json @@ -87,7 +87,7 @@ "babel-core": "^7.0.0-bridge.0" }, "peerDependencies": { - "mongodb": "4.4.1" + "mongodb": ">= 4.4.1 < 5" }, "publishConfig": { "access": "public" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ac43089bfbe..25110f48c08 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1462,12 +1462,12 @@ importers: '@reactioncommerce/file-collections-sa-base': ^0.2.2 babel-core: ^7.0.0-bridge.0 debug: ^4.3.2 - mongodb: 4.4.1 + mongodb: '>= 4.4.1 < 5' dependencies: '@babel/runtime-corejs2': 7.19.0 '@reactioncommerce/file-collections-sa-base': link:../file-collections-sa-base debug: 4.3.4 - mongodb: 4.4.1 + mongodb: 4.9.1 devDependencies: '@babel/cli': 7.18.10_@babel+core@7.19.0 '@babel/core': 7.19.0 @@ -4639,7 +4639,7 @@ packages: dependencies: eslint: 8.23.1 eslint-plugin-import: 2.25.4_eslint@8.23.1 - eslint-plugin-jest: 26.9.0_eslint@8.23.1 + eslint-plugin-jest: 26.9.0_2ex7m26yair3ztqnyc2u7licva eslint-plugin-jsx-a11y: 6.5.1_eslint@8.23.1 eslint-plugin-node: 11.1.0_eslint@8.23.1 eslint-plugin-promise: 6.0.1_eslint@8.23.1 @@ -4964,26 +4964,6 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@typescript-eslint/typescript-estree/5.37.0: - resolution: {integrity: sha512-JkFoFIt/cx59iqEDSgIGnQpCTRv96MQnXCYvJi7QhBC24uyuzbD8wVbajMB1b9x4I0octYFJ3OwjAwNqk1AjDA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/types': 5.37.0 - '@typescript-eslint/visitor-keys': 5.37.0 - debug: 4.3.4 - globby: 11.1.0 - is-glob: 4.0.3 - semver: 7.3.7 - tsutils: 3.21.0 - transitivePeerDependencies: - - supports-color - dev: true - /@typescript-eslint/typescript-estree/5.37.0_typescript@2.9.2: resolution: {integrity: sha512-JkFoFIt/cx59iqEDSgIGnQpCTRv96MQnXCYvJi7QhBC24uyuzbD8wVbajMB1b9x4I0octYFJ3OwjAwNqk1AjDA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -5005,7 +4985,7 @@ packages: - supports-color dev: true - /@typescript-eslint/utils/5.37.0_eslint@8.23.1: + /@typescript-eslint/utils/5.37.0_2ex7m26yair3ztqnyc2u7licva: resolution: {integrity: sha512-jUEJoQrWbZhmikbcWSMDuUSxEE7ID2W/QCV/uz10WtQqfOuKZUqFGjqLJ+qhDd17rjgp+QJPqTdPIBWwoob2NQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -5014,7 +4994,7 @@ packages: '@types/json-schema': 7.0.11 '@typescript-eslint/scope-manager': 5.37.0 '@typescript-eslint/types': 5.37.0 - '@typescript-eslint/typescript-estree': 5.37.0 + '@typescript-eslint/typescript-estree': 5.37.0_typescript@2.9.2 eslint: 8.23.1 eslint-scope: 5.1.1 eslint-utils: 3.0.0_eslint@8.23.1 @@ -7782,7 +7762,7 @@ packages: - supports-color dev: true - /eslint-plugin-jest/26.9.0_eslint@8.23.1: + /eslint-plugin-jest/26.9.0_2ex7m26yair3ztqnyc2u7licva: resolution: {integrity: sha512-TWJxWGp1J628gxh2KhaH1H1paEdgE2J61BBF1I59c6xWeL5+D1BzMxGDN/nXAfX+aSkR5u80K+XhskK6Gwq9ng==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -7795,7 +7775,7 @@ packages: jest: optional: true dependencies: - '@typescript-eslint/utils': 5.37.0_eslint@8.23.1 + '@typescript-eslint/utils': 5.37.0_2ex7m26yair3ztqnyc2u7licva eslint: 8.23.1 transitivePeerDependencies: - supports-color @@ -13826,15 +13806,6 @@ packages: /tslib/2.4.0: resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} - /tsutils/3.21.0: - resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} - engines: {node: '>= 6'} - peerDependencies: - typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' - dependencies: - tslib: 1.14.1 - dev: true - /tsutils/3.21.0_typescript@2.9.2: resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} engines: {node: '>= 6'}