@actonate/mirkwood
Version:
GraphQL based Rapid Server-side Development framework
502 lines (417 loc) • 13.8 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _mongodb = require('mongodb');
var _mongodb2 = _interopRequireDefault(_mongodb);
var _flat = require('flat');
var _flat2 = _interopRequireDefault(_flat);
var _lodash = require('lodash');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var MongoClient = _mongodb2.default.MongoClient;
var ObjectID = _mongodb2.default.ObjectID;
var MongoDbDatabaseAdapter = function () {
function MongoDbDatabaseAdapter(connection) {
var _this = this;
_classCallCheck(this, MongoDbDatabaseAdapter);
this.create = function (datasource, document, args) {
var self = _this;
var dbPromise = new Promise(function (resolve, reject) {
_this.client.then(function (db) {
var collectionName = datasource.collection || datasource.table;
var collection = db.collection(collectionName);
return collection.insertOne(document);
}).then(function (res) {
var find = { _id: res.insertedId.toString() };
return self.one(datasource, { find: find });
}).then(resolve).catch(reject);
});
return dbPromise;
};
this.client = MongoClient.connect(this._uri(connection));
}
_createClass(MongoDbDatabaseAdapter, [{
key: '_uri',
value: function _uri(connection) {
return 'mongodb://' + connection.host + ':' + connection.port + '/' + connection.database;
}
}, {
key: '_resolveQuery',
value: function _resolveQuery(query) {
var _this2 = this;
if (query.and) {
return {
$and: (0, _lodash.map)(query.and, function (subQuery) {
return _this2._resolveQuery(subQuery);
})
};
}
if (query.or) {
return {
$or: (0, _lodash.map)(query.or, function (subQuery) {
return _this2._resolveQuery(subQuery);
})
};
}
if (query.not) {
return {
$not: (0, _lodash.map)(query.not, function (subQuery) {
return _this2._resolveQuery(subQuery);
})
};
}
if (query.nor) {
return {
$nor: (0, _lodash.map)(query.or, function (subQuery) {
return _this2._resolveQuery(subQuery);
})
};
}
var keyCount = (0, _lodash.keys)(query.fields).length;
var resolvedSubQueries = [];
// flattening
var flatFind = function flatFind(fields, keys, schema) {
keys = keys ? keys : [];
schema = schema ? schema : {};
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = Object.keys(fields)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var key = _step.value;
var field = fields[key];
if (!field.operator) {
schema = flatFind(field, keys.concat([key]), schema);
} else {
schema[keys.concat([key]).join('.')] = fields[key];
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return schema;
};
query.fields = flatFind(query.fields);
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = Object.keys(query.fields)[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var key = _step2.value;
var subQuery = query.fields[key];
if (key === '_id') {
subQuery.value = new ObjectID(subQuery.value);
subQuery.values = subQuery.values.map(function (value) {
return new ObjectID(value);
});
}
var subQueryValue = subQuery.value;
if (subQuery.operator === '$in' && Array.isArray(subQuery.values)) {
subQueryValue = subQuery.values;
}
if (subQuery.operator === '$nin' && Array.isArray(subQuery.values)) {
subQueryValue = subQuery.values;
}
if (subQuery.operator === '$exists') {
subQuery.value = true;
}
if (subQuery.operator === '$iregex') {
subQuery.operator = '$regex';
subQuery.options = subQuery.options || {
match: 'i'
};
}
var resolvedSubQuery = {};
resolvedSubQuery[key] = {};
resolvedSubQuery[key][subQuery.operator] = subQueryValue;
// add support for regex options
if (subQuery.operator === '$regex' && subQuery.options && subQuery.options.match) {
resolvedSubQuery[key]['$options'] = subQuery.options.match;
}
if (keyCount === 1) {
return resolvedSubQuery;
} else {
resolvedSubQueries.push(resolvedSubQuery);
}
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
return {
$and: resolvedSubQueries
};
}
}, {
key: '_resolveFind',
value: function _resolveFind(find) {
var findQuery = _extends({}, find);
// convert all collections (array of objects) to objects
var _iteratorNormalCompletion3 = true;
var _didIteratorError3 = false;
var _iteratorError3 = undefined;
try {
for (var _iterator3 = Object.keys(find)[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
var key = _step3.value;
var findField = findQuery[key];
if (Array.isArray(findField) && findField.length > 0 && _typeof(findField[0]) === 'object') {
findQuery[key] = findField[0];
}
}
// flatten all keys
} catch (err) {
_didIteratorError3 = true;
_iteratorError3 = err;
} finally {
try {
if (!_iteratorNormalCompletion3 && _iterator3.return) {
_iterator3.return();
}
} finally {
if (_didIteratorError3) {
throw _iteratorError3;
}
}
}
findQuery = (0, _flat2.default)(findQuery);
return (0, _lodash.mapValues)(findQuery, function (query) {
if (Array.isArray(query)) {
query = {
$in: query
};
}
return query;
});
}
}, {
key: 'all',
value: function all(datasource, args) {
var _this3 = this;
var dbPromise = new Promise(function (resolve, reject) {
_this3.client.then(function (db) {
var collectionName = datasource.collection || datasource.table;
var collection = db.collection(collectionName);
// resolve find arg
var find = args.find || {};
var resolvedFind = _this3._resolveFind(find);
if (resolvedFind._id) {
resolvedFind._id = new ObjectID(resolvedFind._id);
}
// resolve query arg
var query = args.query || false;
// override resovledFind if query is specified
if (args.query) {
resolvedFind = _this3._resolveQuery(query);
}
args.sort = args.sort ? args.sort : {};
var sort = {};
if (args.sort && args.sort.field) {
sort[args.sort.field] = args.sort.order === 'asc' ? 1 : -1;
}
if (args.orderBy && args.orderBy.length > 0) {
args.orderBy.map(function (orderBy) {
sort[orderBy.field] = orderBy.order === 'asc' ? 1 : -1;
});
}
// handle soft deletion
if (datasource.skip_deleted) {
resolvedFind._deleted = { $not: { $eq: true } };
}
return collection.find(resolvedFind).sort(sort).skip(args.skip).limit(args.limit).toArray();
}).then(function (res) {
resolve(res);
}).catch(function (err) {
reject(err);
});
});
return dbPromise;
}
}, {
key: 'count',
value: function count(datasource, args) {
var _this4 = this;
var dbPromise = new Promise(function (resolve, reject) {
_this4.client.then(function (db) {
var collectionName = datasource.collection || datasource.table;
var collection = db.collection(collectionName);
var find = args.find || {};
var resolvedFind = _this4._resolveFind(find);
if (resolvedFind._id) {
resolvedFind._id = new ObjectID(resolvedFind._id);
}
// resolve query arg
var query = args.query || false;
// override resovledFind if query is specified
if (args.query) {
resolvedFind = _this4._resolveQuery(query);
}
// handle soft deletion
if (datasource.skip_deleted) {
resolvedFind._deleted = { $not: { $eq: true } };
}
return collection.count(resolvedFind);
}).then(function (res) {
resolve(res);
}).catch(function (err) {
reject(err);
});
});
return dbPromise;
}
}, {
key: 'one',
value: function one(datasource, args) {
var _this5 = this;
var dbPromise = new Promise(function (resolve, reject) {
_this5.client.then(function (db) {
var find = args.find;
var collectionName = datasource.collection || datasource.table;
var collection = db.collection(collectionName);
var resolvedFind = _this5._resolveFind(find || {});
if (resolvedFind._id) {
resolvedFind._id = new ObjectID(resolvedFind._id);
}
// resolve query arg
var query = args.query || false;
// override resovledFind if query is specified
if (args.query) {
resolvedFind = _this5._resolveQuery(query);
}
// handle soft deletion
if (datasource.skip_deleted) {
resolvedFind._deleted = { $not: { $eq: true } };
}
return collection.findOne(resolvedFind);
}).then(function (res) {
resolve(res);
}).catch(function (err) {
reject(err);
});
});
return dbPromise;
}
}, {
key: 'destroy',
value: function destroy(datasource, find, args) {
var _this6 = this;
var dbPromise = new Promise(function (resolve, reject) {
_this6.client.then(function (db) {
var collectionName = datasource.collection || datasource.table;
var collection = db.collection(collectionName);
if (find._id) {
find._id = new ObjectID(find._id);
}
return collection.deleteOne(find);
}).then(function (res) {
if (res.result.ok) {
resolve(true);
} else {
resolve(false);
}
}).catch(function (err) {
reject(err);
});
});
return dbPromise;
}
}, {
key: 'createMany',
value: function createMany(datasource, documents, args) {
var _this7 = this;
var dbPromise = new Promise(function (resolve, reject) {
_this7.client.then(function (db) {
var collectionName = datasource.collection || datasource.table;
var collection = db.collection(collectionName);
return collection.insertMany(documents);
}).then(function (res) {
resolve(res.insertedCount);
}).catch(function (err) {
reject(err);
});
});
return dbPromise;
}
}, {
key: 'update',
value: function update(datasource, find, document, args) {
var _this8 = this;
var dbPromise = new Promise(function (resolve, reject) {
_this8.client.then(function (db) {
var collectionName = datasource.collection || datasource.table;
var collection = db.collection(collectionName);
if (find._id) {
find._id = new ObjectID(find._id);
}
return collection.updateOne(find, { $set: document }, {
upsert: true
});
}).then(function (res) {
if (res.modifiedCount > 0) {
resolve(true);
} else {
resolve(false);
}
}).catch(function (err) {
reject(err);
});
});
return dbPromise;
}
}, {
key: 'delete',
value: function _delete(datasource, find, document, args) {
var _this9 = this;
var dbPromise = new Promise(function (resolve, reject) {
_this9.client.then(function (db) {
var collectionName = datasource.collection || datasource.table;
var collection = db.collection(collectionName);
if (find._id) {
find._id = new ObjectID(find._id);
}
return collection.updateOne(find, { $set: {
_deleted: true
}
}, {
upsert: true
});
}).then(function (res) {
if (res.modifiedCount > 0) {
resolve(true);
} else {
resolve(false);
}
}).catch(function (err) {
reject(err);
});
});
return dbPromise;
}
}]);
return MongoDbDatabaseAdapter;
}();
exports.default = MongoDbDatabaseAdapter;