UNPKG

@webiny/commodo-fields-storage-db-proxy

Version:

A MongoDB driver for the [fields-storage](../fields-storage) package.

256 lines (210 loc) 7.05 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _lambda = _interopRequireDefault(require("aws-sdk/clients/lambda")); var _bson = require("bson"); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } const MONGO_CONNECTION_ERRORS = ["MongoServerSelectionError", "MongoNetworkError"]; class DbProxyClient { constructor({ dbProxyFunction }) { (0, _defineProperty2.default)(this, "dbProxyFunction", void 0); this.dbProxyFunction = dbProxyFunction; } async runOperation(requestPayload) { const singleOperation = !Array.isArray(requestPayload); const Lambda = new _lambda.default({ region: process.env.AWS_REGION }); const { Payload } = await Lambda.invoke({ FunctionName: this.dbProxyFunction, Payload: JSON.stringify({ body: _bson.EJSON.stringify({ operations: singleOperation ? [requestPayload] : requestPayload }) }) }).promise(); let parsedPayload; try { parsedPayload = JSON.parse(Payload); } catch (e) { throw new Error("Could not JSON.parse DB Proxy's response."); } if (parsedPayload.error) { console.log("[commodo-fields-storage-db-proxy error:]", parsedPayload.error); if (MONGO_CONNECTION_ERRORS.includes(parsedPayload.error.name)) { throw new Error(`Could not connect to the MongoDB server, make sure the connection string is correct and that the database server allows outside connections. Check https://docs.webiny.com/docs/get-started/quick-start#3-setup-database-connection for more information.`); } throw new Error(`${parsedPayload.error.name}: ${parsedPayload.error.message}`); } if (!parsedPayload.response) { throw new Error(`Missing "response" key in received DB Proxy's response.`); } const { results } = _bson.EJSON.parse(parsedPayload.response); if (singleOperation) { return results[0]; } return results; } } class DbProxyDriver { constructor({ dbProxyFunction = process.env.DB_PROXY_FUNCTION } = {}) { (0, _defineProperty2.default)(this, "client", void 0); this.client = new DbProxyClient({ dbProxyFunction }); } async create(items) { const payload = items.map(({ name, data }) => { return { collection: this.getCollectionName(name), operation: ["insertOne", data] }; }); await this.client.runOperation(payload); return true; } async update(items) { const payload = items.map(({ name, query, data }) => { return { collection: this.getCollectionName(name), operation: ["updateOne", query, { $set: data }] }; }); await this.client.runOperation(payload); return true; } async delete({ name, options }) { const clonedOptions = _objectSpread({}, options); DbProxyDriver.__prepareSearchOption(clonedOptions); await this.client.runOperation({ collection: this.getCollectionName(name), operation: ["deleteMany", clonedOptions.query] }); return true; } async find({ name, options }) { const clonedOptions = _objectSpread({ limit: 0, offset: 0 }, options); DbProxyDriver.__prepareSearchOption(clonedOptions); DbProxyDriver.__prepareProjectFields(clonedOptions); const results = await this.client.runOperation({ collection: this.getCollectionName(name), operation: ["find", clonedOptions.query, { limit: clonedOptions.limit, sort: clonedOptions.sort, offset: clonedOptions.offset, project: clonedOptions.project }] }); return [!Array.isArray(results) ? [] : results, {}]; } async findOne({ name, options }) { const clonedOptions = _objectSpread({}, options); DbProxyDriver.__prepareSearchOption(clonedOptions); DbProxyDriver.__prepareProjectFields(clonedOptions); // Get first documents from cursor using each const results = await this.client.runOperation({ collection: this.getCollectionName(name), operation: ["find", clonedOptions.query, { limit: 1, sort: clonedOptions.sort, project: clonedOptions.project }] }); return results[0]; } async count({ name, options }) { const clonedOptions = _objectSpread({}, options); DbProxyDriver.__prepareSearchOption(clonedOptions); // Get first documents from cursor using each return await this.client.runOperation({ collection: this.getCollectionName(name), operation: ["count", clonedOptions.query] }); } getCollectionName(name) { return name; } getClient() { return this.client; } static __prepareSearchOption(options) { // Here we handle search (if passed) - we transform received arguments into linked LIKE statements. if (options.search && options.search.query) { const { query, operator, fields } = options.search; const searches = []; fields.forEach(field => { searches.push({ [field]: { $regex: `.*${query}.*`, $options: "i" } }); }); const search = { [operator === "and" ? "$and" : "$or"]: searches }; if (options.query instanceof Object) { options.query = { $and: [search, options.query] }; } else { options.query = search; } delete options.search; } } static __prepareProjectFields(options) { // Here we convert requested fields into a "project" parameter if (options.fields) { options.project = options.fields.reduce((acc, item) => { acc[item] = 1; return acc; }, { id: 1 }); delete options.fields; } } } var _default = DbProxyDriver; exports.default = _default; //# sourceMappingURL=DbProxyDriver.js.map