UNPKG

j2s

Version:

JSON to SQL, build RESTful API server on the fly, which accespts JSON describing SQL query statements, support (almost) full SQL functionality, with configurable access control & pluggable middlewares

1,339 lines (1,061 loc) 105 kB
'use strict'; function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } var _isString = _interopRequireDefault(require("lodash/isString")); var _isPlainObject = _interopRequireDefault(require("lodash/isPlainObject")); var _isArray = _interopRequireDefault(require("lodash/isArray")); var _isNumber = _interopRequireDefault(require("lodash/isNumber")); var _isEmpty = _interopRequireDefault(require("lodash/isEmpty")); var _isNil = _interopRequireDefault(require("lodash/isNil")); var _includes = _interopRequireDefault(require("lodash/includes")); var _uniq = _interopRequireDefault(require("lodash/uniq")); var _forIn = _interopRequireDefault(require("lodash/forIn")); var _forEach = _interopRequireDefault(require("lodash/forEach")); var _each = _interopRequireDefault(require("lodash/each")); var _has = _interopRequireDefault(require("lodash/has")); var _omit = _interopRequireDefault(require("lodash/omit")); var _pick = _interopRequireDefault(require("lodash/pick")); var _find = _interopRequireDefault(require("lodash/find")); var _keys3 = _interopRequireDefault(require("lodash/keys")); var _merge = _interopRequireDefault(require("lodash/merge")); var _map = _interopRequireDefault(require("lodash/map")); var _koaRouter = _interopRequireDefault(require("koa-router")); var _bluebird = _interopRequireDefault(require("bluebird")); var _logging = require("./logging"); var core = _interopRequireWildcard(require("./core")); var errors = _interopRequireWildcard(require("./errors")); var _relation = require("./relation"); function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } 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"); } } 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); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } require('@babel/polyfill'); var methods = ['C', 'R', 'U', 'D']; var configProps = ['access', 'identity', 'admin', 'middlewares']; function setDefaultOpts(content) { var obj = {}; (0, _each["default"])(methods, function (method) { obj[method] = content; }); return obj; } function setOptions(res, defaultOpts) { (0, _each["default"])(configProps, function (prop) { if ((0, _has["default"])(defaultOpts, prop) && !(0, _isNil["default"])(defaultOpts, prop)) { if ((0, _isPlainObject["default"])(defaultOpts[prop])) { (0, _each["default"])(methods, function (method) { res[prop][method] = defaultOpts[prop][method]; }); } else { res[prop] = setDefaultOpts(defaultOpts[prop]); } } }); return res; } function resolveOptions(defaultOpts, route) { var res = { access: setDefaultOpts(core.ALLOW), identity: setDefaultOpts(defaultOpts.identity), // identity could not be optional admin: setDefaultOpts(function () { return _bluebird["default"].resolve(false); }), middlewares: setDefaultOpts([]) }; res = setOptions(res, defaultOpts); if ((0, _isPlainObject["default"])(route)) { res.model = route.model; res = setOptions(res, route); } else { res.model = route; } var emptyInstance = res.model.forge(); res.tableName = emptyInstance.tableName; return res; } function chainFuncs(_x, _x2, _x3) { return _chainFuncs.apply(this, arguments); } function _chainFuncs() { _chainFuncs = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee16(ctx, instances, funcs) { var func, results, i, res; return regeneratorRuntime.wrap(function _callee16$(_context16) { while (1) { switch (_context16.prev = _context16.next) { case 0: if (!(funcs.length > 0)) { _context16.next = 12; break; } func = funcs.shift(); _context16.next = 4; return _bluebird["default"].all(instances.invokeMap(func, ctx)); case 4: results = _context16.sent; for (i = 0; i < instances.length; i++) { instances.at(i).set(func, results[i]); } _context16.next = 8; return chainFuncs(ctx, instances, funcs); case 8: res = _context16.sent; return _context16.abrupt("return", res); case 12: return _context16.abrupt("return", instances); case 13: case "end": return _context16.stop(); } } }, _callee16); })); return _chainFuncs.apply(this, arguments); } function chainClauses(_x4, _x5, _x6, _x7) { return _chainClauses.apply(this, arguments); } function _chainClauses() { _chainClauses = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee17(model, clauses, ctx, query) { var clause, modifiedQuery, res, _keys2, key, value, _modifiedQuery, _res; return regeneratorRuntime.wrap(function _callee17$(_context17) { while (1) { switch (_context17.prev = _context17.next) { case 0: if (!(clauses.length > 0)) { _context17.next = 35; break; } clause = clauses.shift(); if (!(0, _isString["default"])(clause)) { _context17.next = 15; break; } if ((0, _has["default"])(model, clause)) { _context17.next = 5; break; } throw errors.FnErrClauseNotExists(clause); case 5: _context17.next = 7; return model[clause](ctx, query); case 7: modifiedQuery = _context17.sent; _context17.next = 10; return chainClauses(model, clauses, ctx, modifiedQuery); case 10: res = _context17.sent; ; return _context17.abrupt("return", res); case 15: if (!(0, _isPlainObject["default"])(clause)) { _context17.next = 32; break; } _keys2 = (0, _keys3["default"])(clause); if (!(_keys2.length !== 1)) { _context17.next = 19; break; } throw errors.FnErrClauseObjectShouldHaveExactlyOneKey(_keys2); case 19: key = _keys2[0]; value = clause[key]; if ((0, _has["default"])(model, key)) { _context17.next = 23; break; } throw errors.FnErrClauseNotExists(key); case 23: _context17.next = 25; return model[key](ctx, query, value); case 25: _modifiedQuery = _context17.sent; _context17.next = 28; return chainClauses(model, clauses, ctx, _modifiedQuery); case 28: _res = _context17.sent; return _context17.abrupt("return", _res); case 32: throw errors.ErrAddClauseElementShouldBeStringOrObject; case 33: _context17.next = 36; break; case 35: return _context17.abrupt("return", query); case 36: case "end": return _context17.stop(); } } }, _callee17); })); return _chainClauses.apply(this, arguments); } var J2S = /*#__PURE__*/function () { function J2S(defaultOpts) { _classCallCheck(this, J2S); defaultOpts = defaultOpts || {}; this.prefix = defaultOpts.prefix || ''; this.routes = defaultOpts.routes; this.bookshelf = defaultOpts.bookshelf; this.forbids = defaultOpts.forbids || []; if (defaultOpts.log) { _logging.logger.configure((0, _merge["default"])(_logging.config, { level: defaultOpts.log })); } this.controller = new _koaRouter["default"]({ prefix: this.prefix }); this.allResolvedOpts = {}; delete this.routes["default"]; var j2s = this; (0, _forEach["default"])(j2s.routes, function (route, path) { j2s.allResolvedOpts[path] = resolveOptions(defaultOpts, route); }); (0, _forEach["default"])((0, _keys3["default"])(j2s.routes), function (path) { j2s.setupController(path); }); } _createClass(J2S, [{ key: "getOpts", value: function getOpts(path) { return this.allResolvedOpts[path]; } }, { key: "getOptsWithModel", value: function getOptsWithModel(model) { return (0, _find["default"])(this.allResolvedOpts, function (opt) { return opt.model === model; }); } // setup all the controllers for each routes }, { key: "setupController", value: function setupController(path) { var j2s = this; var opts = this.allResolvedOpts[path]; var errHandler = function errHandler(err) { if (err instanceof errors.J2SError) { throw err; } else { throw errors.FnErrDatabaseOperationError(err.message); } }; var getOne = /*#__PURE__*/function () { var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(ctx, next) { var query, instances, instance; return regeneratorRuntime.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: query = {}; if (ctx.request.query.query) { query = JSON.parse(ctx.request.query.query); } if ((0, _isPlainObject["default"])(query)) { _context.next = 4; break; } throw errors.ErrQueryShouldBeJsonObject; case 4: if (!(0, _has["default"])(query, 'where')) { _context.next = 6; break; } throw errors.ErrWhereKeywordWhenGetWithIdForbidden; case 6: query.where = { id: ctx.params.id }; _context.next = 9; return j2s.getInstances(ctx, query, opts); case 9: instances = _context.sent; instance = instances.toJSON(); if (instance.length > 0) { instance = instance[0]; } ctx.body = { data: instance }; case 13: case "end": return _context.stop(); } } }, _callee); })); return function getOne(_x8, _x9) { return _ref.apply(this, arguments); }; }(); var get = /*#__PURE__*/function () { var _ref2 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(ctx, next) { var query, instances; return regeneratorRuntime.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: query = {}; if (ctx.request.query.query) { query = JSON.parse(ctx.request.query.query); } if ((0, _isPlainObject["default"])(query)) { _context2.next = 4; break; } throw errors.ErrQueryShouldBeJsonObject; case 4: _context2.next = 6; return j2s.getInstances(ctx, query, opts); case 6: instances = _context2.sent; ctx.body = { data: instances }; case 8: case "end": return _context2.stop(); } } }, _callee2); })); return function get(_x10, _x11) { return _ref2.apply(this, arguments); }; }(); var post = /*#__PURE__*/function () { var _ref3 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3(ctx, next) { var data, instances; return regeneratorRuntime.wrap(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: data = ctx.request.body.data; if (!(0, _isArray["default"])(data)) { data = [data]; } _context3.next = 4; return j2s.createInstances(ctx, data, opts); case 4: instances = _context3.sent; ctx.body = { data: instances }; case 6: case "end": return _context3.stop(); } } }, _callee3); })); return function post(_x12, _x13) { return _ref3.apply(this, arguments); }; }(); var putOne = /*#__PURE__*/function () { var _ref4 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee4(ctx, next) { var query, data, res; return regeneratorRuntime.wrap(function _callee4$(_context4) { while (1) { switch (_context4.prev = _context4.next) { case 0: query = {}; if (ctx.request.body.query) { query = JSON.parse(ctx.request.body.query); } if ((0, _isPlainObject["default"])(query)) { _context4.next = 4; break; } throw errors.ErrQueryShouldBeJsonObject; case 4: if (!(0, _has["default"])(query, 'where')) { _context4.next = 6; break; } throw errors.ErrWhereKeywordWhenPutWithIdForbidden; case 6: data = ctx.request.body.data; if ((0, _isPlainObject["default"])(data)) { _context4.next = 9; break; } throw errors.ErrDataShouldBeJsonObject; case 9: query.where = { id: ctx.params.id }; _context4.next = 12; return j2s.updateInstances(ctx, query, data, opts); case 12: res = _context4.sent; ctx.body = { data: res }; case 14: case "end": return _context4.stop(); } } }, _callee4); })); return function putOne(_x14, _x15) { return _ref4.apply(this, arguments); }; }(); var put = /*#__PURE__*/function () { var _ref5 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee5(ctx, next) { var query, data, res; return regeneratorRuntime.wrap(function _callee5$(_context5) { while (1) { switch (_context5.prev = _context5.next) { case 0: query = ctx.request.body.query; if ((0, _isPlainObject["default"])(query)) { _context5.next = 3; break; } throw errors.ErrQueryShouldBeJsonObject; case 3: data = ctx.request.body.data; if ((0, _isPlainObject["default"])(data)) { _context5.next = 6; break; } throw errors.ErrDataShouldBeJsonObject; case 6: _context5.next = 8; return j2s.updateInstances(ctx, query, data, opts); case 8: res = _context5.sent; ctx.body = { data: res }; case 10: case "end": return _context5.stop(); } } }, _callee5); })); return function put(_x16, _x17) { return _ref5.apply(this, arguments); }; }(); var delOne = /*#__PURE__*/function () { var _ref6 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee6(ctx, next) { var query, instances, check, res; return regeneratorRuntime.wrap(function _callee6$(_context6) { while (1) { switch (_context6.prev = _context6.next) { case 0: query = {}; if (ctx.request.body.query) { query = JSON.parse(ctx.request.body.query); } if ((0, _isPlainObject["default"])(query)) { _context6.next = 4; break; } throw errors.ErrQueryShouldBeJsonObject; case 4: if (!(0, _has["default"])(query, 'where')) { _context6.next = 6; break; } throw errors.ErrWhereKeywordWhenDeleteWithIdForbidden; case 6: query.where = { id: ctx.params.id }; _context6.next = 9; return core.query(j2s.bookshelf, opts.model, query).fetch(); case 9: instances = _context6.sent; _context6.next = 12; return core.check(ctx, opts.identity.D, opts.admin.D, instances, opts.access.D); case 12: check = _context6.sent; if (check) { _context6.next = 15; break; } throw errors.ErrOperationNotAuthorized; case 15: _context6.next = 17; return instances.invokeThen('destroy'); case 17: res = _context6.sent; if (!(res.length == 0)) { _context6.next = 20; break; } throw errors.ErrResourceNotFound; case 20: ctx.body = { success: true }; case 21: case "end": return _context6.stop(); } } }, _callee6); })); return function delOne(_x18, _x19) { return _ref6.apply(this, arguments); }; }(); var del = /*#__PURE__*/function () { var _ref7 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee7(ctx, next) { var query, count, instances, check, res; return regeneratorRuntime.wrap(function _callee7$(_context7) { while (1) { switch (_context7.prev = _context7.next) { case 0: query = ctx.request.body.query; if ((0, _isPlainObject["default"])(query)) { _context7.next = 3; break; } throw errors.ErrQueryShouldBeJsonObject; case 3: _context7.next = 5; return core.query(j2s.bookshelf, opts.model, query).count(); case 5: count = _context7.sent; if (!(count > 1)) { _context7.next = 8; break; } throw errors.ErrDeletionNotAllowed; case 8: _context7.next = 10; return core.query(j2s.bookshelf, opts.model, query).fetch(); case 10: instances = _context7.sent; _context7.next = 13; return core.check(ctx, opts.identity.D, opts.admin.D, instances, opts.access.D); case 13: check = _context7.sent; if (check) { _context7.next = 16; break; } throw errors.ErrOperationNotAuthorized; case 16: _context7.next = 18; return instances.invokeThen('destroy'); case 18: res = _context7.sent; if (!(res.length == 0)) { _context7.next = 21; break; } throw errors.ErrResourceNotFound; case 21: ctx.body = { success: true }; case 22: case "end": return _context7.stop(); } } }, _callee7); })); return function del(_x20, _x21) { return _ref7.apply(this, arguments); }; }(); this.controller.get.apply(this.controller, [path + '/:id'].concat(opts.middlewares.R).concat([getOne])); this.controller.get.apply(this.controller, [path].concat(opts.middlewares.R).concat([get])); this.controller.post.apply(this.controller, [path].concat(opts.middlewares.C).concat([post])); this.controller.put.apply(this.controller, [path + '/:id'].concat(opts.middlewares.U).concat([putOne])); this.controller.put.apply(this.controller, [path].concat(opts.middlewares.U).concat([put])); this.controller["delete"].apply(this.controller, [path + '/:id'].concat(opts.middlewares.D).concat([delOne])); this.controller["delete"].apply(this.controller, [path].concat(opts.middlewares.D).concat([del])); } }, { key: "getInstances", value: function () { var _getInstances = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee9(ctx, query, opts) { var j2s, fetchOpts, populate, clauses, instances, check; return regeneratorRuntime.wrap(function _callee9$(_context9) { while (1) { switch (_context9.prev = _context9.next) { case 0: j2s = this; (0, _each["default"])((0, _keys3["default"])(query), function (key) { if ((0, _includes["default"])(j2s.forbids, key)) { throw errors.FnErrKeyForbidden(key); } }); fetchOpts = {}; if (!(0, _has["default"])(query, 'populate')) { _context9.next = 10; break; } if ((0, _isArray["default"])(query.populate)) { _context9.next = 6; break; } throw errors.ErrPopulateShouldBeList; case 6: _context9.next = 8; return _bluebird["default"].map(query.populate, /*#__PURE__*/function () { var _ref8 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee8(population) { var _keys, key, populateQuery, res, relations, targetModel, relatedData, relationName, relation, targetTable, foreignKey, clauses, limit, offset, orderBy; return regeneratorRuntime.wrap(function _callee8$(_context8) { while (1) { switch (_context8.prev = _context8.next) { case 0: if (!(0, _isPlainObject["default"])(population)) { _context8.next = 26; break; } _keys = (0, _keys3["default"])(population); if (!(_keys.length != 1)) { _context8.next = 4; break; } throw errors.ErrPopulateObjectShouldHaveExactlyOneKey; case 4: key = _keys[0]; populateQuery = population[key]; res = {}; res[key] = function (builder) { core.builderQuery(j2s.bookshelf.knex, builder, populateQuery); }; if (!((0, _has["default"])(populateQuery, 'add_clause') || (0, _has["default"])(populateQuery, 'limit') || (0, _has["default"])(populateQuery, 'offset'))) { _context8.next = 23; break; } relations = key.split('.'); targetModel = opts.model; relatedData = null; while (relations.length > 0) { relationName = relations.shift(); relation = targetModel.forge()[relationName](); relatedData = relation.relatedData; targetModel = relatedData.target; } targetTable = targetModel.forge().tableName; foreignKey = relatedData.foreignKey; if (!(0, _has["default"])(populateQuery, 'add_clause')) { _context8.next = 22; break; } clauses = populateQuery.add_clause; if ((0, _isArray["default"])(clauses)) { _context8.next = 19; break; } throw errors.ErrAddClauseShouldBeList; case 19: _context8.next = 21; return chainClauses(targetModel, clauses, ctx, populateQuery); case 21: populateQuery = _context8.sent; case 22: if (((0, _has["default"])(populateQuery, 'limit') || (0, _has["default"])(populateQuery, 'offset')) && (0, _has["default"])(populateQuery, 'order_by')) { limit = populateQuery.limit; offset = populateQuery.offset || 0; orderBy = populateQuery.order_by; delete populateQuery.limit; delete populateQuery.offset; res[key] = function (builder) { builder["with"](targetTable, function (qb) { core.builderQuery(j2s.bookshelf.knex, qb, populateQuery); qb.select(j2s.bookshelf.knex.raw("*, rank() over (partition by ".concat(foreignKey, " order by ").concat(orderBy[0], " ").concat(orderBy[1], ") as rank from ").concat(targetTable))); }).select('*').from(targetTable); builder.where('rank', '>', offset); if (limit) { builder.andWhere('rank', '<=', limit + offset); } }; } case 23: return _context8.abrupt("return", res); case 26: if (!(0, _isString["default"])(population)) { _context8.next = 30; break; } return _context8.abrupt("return", population); case 30: throw errors.ErrPopulateElementShouldBeStringOrObject; case 31: case "end": return _context8.stop(); } } }, _callee8); })); return function (_x25) { return _ref8.apply(this, arguments); }; }()); case 8: populate = _context9.sent; fetchOpts = { withRelated: populate }; case 10: if (!(0, _has["default"])(query, 'add_clause')) { _context9.next = 17; break; } clauses = query.add_clause; if ((0, _isArray["default"])(clauses)) { _context9.next = 14; break; } throw errors.ErrAddClauseShouldBeList; case 14: _context9.next = 16; return chainClauses(opts.model, clauses, ctx, query); case 16: query = _context9.sent; case 17: _context9.next = 19; return core.query(j2s.bookshelf, opts.model, query).fetch(fetchOpts); case 19: instances = _context9.sent; _context9.next = 22; return core.check(ctx, opts.identity.R, opts.admin.R, instances, opts.access.R); case 22: check = _context9.sent; if (check) { _context9.next = 25; break; } throw errors.ErrOperationNotAuthorized; case 25: if (!(0, _has["default"])(query, 'add_attr')) { _context9.next = 29; break; } _context9.next = 28; return chainFuncs(ctx, instances, query.add_attr); case 28: instances = _context9.sent; case 29: return _context9.abrupt("return", instances); case 30: case "end": return _context9.stop(); } } }, _callee9, this); })); function getInstances(_x22, _x23, _x24) { return _getInstances.apply(this, arguments); } return getInstances; }() }, { key: "createInstances", value: function () { var _createInstances = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee12(ctx, data, opts) { var j2s, modelCollection, relationKeys, createdInstances; return regeneratorRuntime.wrap(function _callee12$(_context12) { while (1) { switch (_context12.prev = _context12.next) { case 0: j2s = this; modelCollection = j2s.bookshelf.Collection.extend({ model: opts.model }); relationKeys = []; _context12.next = 5; return j2s.bookshelf.transaction( /*#__PURE__*/function () { var _ref9 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee11(trx) { var emptyInstance, relationNames, instances; return regeneratorRuntime.wrap(function _callee11$(_context11) { while (1) { switch (_context11.prev = _context11.next) { case 0: emptyInstance = opts.model.forge(); relationNames = (0, _relation.getRelationNames)(j2s.bookshelf, emptyInstance, opts.model); _context11.next = 4; return _bluebird["default"].map(data, /*#__PURE__*/function () { var _ref10 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee10(obj) { var attrs, instance, check, savedInstance, relationPayload, key; return regeneratorRuntime.wrap(function _callee10$(_context10) { while (1) { switch (_context10.prev = _context10.next) { case 0: attrs = (0, _omit["default"])(obj, relationNames); instance = opts.model.forge(attrs); _context10.next = 4; return core.check(ctx, opts.identity.C, opts.admin.C, [instance], opts.access.C); case 4: check = _context10.sent; if (check) { _context10.next = 7; break; } throw errors.ErrOperationNotAuthorized; case 7: _context10.next = 9; return instance.save(null, { transacting: trx, method: 'insert', require: true, patch: false }); case 9: savedInstance = _context10.sent; relationPayload = (0, _pick["default"])(obj, relationNames); if (!(0, _isEmpty["default"])(relationPayload)) { _context10.next = 13; break; } return _context10.abrupt("return", savedInstance); case 13: _context10.t0 = regeneratorRuntime.keys(relationPayload); case 14: if ((_context10.t1 = _context10.t0()).done) { _context10.next = 23; break; } key = _context10.t1.value; relationKeys.push(key); if (!(0, _isEmpty["default"])(relationPayload[key])) { _context10.next = 19; break; } return _context10.abrupt("continue", 14); case 19: _context10.next = 21; return (0, _relation.modifyRelation)(ctx, j2s.bookshelf, savedInstance, opts.model, key, relationPayload[key], trx, j2s.allResolvedOpts); case 21: _context10.next = 14; break; case 23: return _context10.abrupt("return", savedInstance); case 24: case "end": return _context10.stop(); } } }, _callee10); })); return function (_x30) { return _ref10.apply(this, arguments); }; }()); case 4: instances = _context11.sent; return _context11.abrupt("return", opts.model.collection(instances)); case 6: case "end": return _context11.stop(); } } }, _callee11); })); return function (_x29) { return _ref9.apply(this, arguments); }; }()); case 5: createdInstances = _context12.sent; relationKeys = (0, _uniq["default"])(relationKeys); if (!(relationKeys.length != 0)) { _context12.next = 10; break; } _context12.next = 10; return createdInstances.invokeThen('refresh', { withRelated: relationKeys }); case 10: return _context12.abrupt("return", createdInstances); case 11: case "end": return _context12.stop(); } } }, _callee12, this); })); function createInstances(_x26, _x27, _x28) { return _createInstances.apply(this, arguments); } return createInstances; }() }, { key: "updateInstances", value: function () { var _updateInstances = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee15(ctx, query, data, opts) { var j2s, instances, check, emptyInstance, relationNames, attrs, relationPayload, relationKeys, modifiedInstances; return regeneratorRuntime.wrap(function _callee15$(_context15) { while (1) { switch (_context15.prev = _context15.next) { case 0: j2s = this; if (!((0, _isEmpty["default"])(query) || (0, _isEmpty["default"])(query.where))) { _context15.next = 3; break; } throw errors.ErrNoQueryOrWhereSupplied; case 3: _context15.next = 5; return core.query(j2s.bookshelf, opts.model, query).fetch(); case 5: instances = _context15.sent; if (!(!instances || instances.length == 0)) { _context15.next = 8; break; } throw errors.ErrResourceNotFound; case 8: _context15.next = 10; return core.check(ctx, opts.identity.U, opts.admin.U, instances, opts.access.U); case 10: check = _context15.sent; if (check) { _context15.next = 13; break; } throw errors.ErrOperationNotAuthorized; case 13: emptyInstance = opts.model.forge(); relationNames = (0, _relation.getRelationNames)(j2s.bookshelf, emptyInstance, opts.model); attrs = (0, _omit["default"])(data, relationNames); relationPayload = (0, _pick["default"])(data, relationNames); relationKeys = (0, _keys3["default"])(relationPayload); _context15.next = 20; return j2s.bookshelf.transaction( /*#__PURE__*/function () { var _ref11 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee14(trx) { var insts; return regeneratorRuntime.wrap(function _callee14$(_context14) { while (1) { switch (_context14.prev = _context14.next) { case 0: if ((0, _isEmpty["default"])(attrs)) { _context14.next = 3; break; } _context14.next = 3; return instances.invokeThen('save', attrs, { transacting: trx, method: 'update', patch: true, require: true }); case 3: if (!(0, _isEmpty["default"])(relationPayload)) { _context14.next = 5; break; } return _context14.abrupt("return", instances); case 5: _context14.next = 7; return _bluebird["default"].map(instances.toArray(), /*#__PURE__*/function () { var _ref12 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee13(instance) { var key; return regeneratorRuntime.wrap(function _callee13$(_context13) { while (1) { switch (_context13.prev = _context13.next) { case 0: _context13.t0 = regeneratorRuntime.keys(relationPayload); case 1: if ((_context13.t1 = _context13.t0()).done) { _context13.next = 9; break; } key = _context13.t1.value; if (!(0, _isNil["default"])(relationPayload[key])) { _context13.next = 5; break; } return _context13.abrupt("return", instance); case 5: _context13.next = 7; return (0, _relation.modifyRelation)(ctx, j2s.bookshelf, instance, opts.model, key, relationPayload[key], trx, j2s.allResolvedOpts); case 7: _context13.next = 1; break; case 9: return _context13.abrupt("return", instance); case 10: case "end": return _context13.stop(); } } }, _callee13); })); return function (_x36) { return _ref12.apply(this, arguments); }; }()); case 7: insts = _context14.sent; return _context14.abrupt("return", opts.model.collection(insts)); case 9: case "end": return _context14.stop(); } } }, _callee14); })); return function (_x35) { return _ref11.apply(this, arguments); }; }()); case 20: modifiedInstances = _context15.sent; if ((0, _isEmpty["default"])(relationPayload)) { _context15.next = 24; break; } _context15.next = 24; return modifiedInstances.invokeThen('refresh', { withRelated: relationKeys }); case 24: return _context15.abrupt("return", modifiedInstances); case 25: case "end": return _context15.stop(); } } }, _callee15, this); })); function updateInstances(_x31, _x32, _x33, _x34) { return _updateInstances.apply(this, arguments); } return updateInstances; }() }], [{ key: "ALLOW", get: function get() { return core.ALLOW; } }, { key: "DENY", get: function get() { return core.DENY; } }, { key: "errors", get: function get() { return errors; } }, { key: "builderQuery", get: function get() { return core.builderQuery; } }]); return J2S; }(); module.exports = J2S; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9pbmRleC5qcyJdLCJuYW1lcyI6WyJyZXF1aXJlIiwibWV0aG9kcyIsImNvbmZpZ1Byb3BzIiwic2V0RGVmYXVsdE9wdHMiLCJjb250ZW50Iiwib2JqIiwibWV0aG9kIiwic2V0T3B0aW9ucyIsInJlcyIsImRlZmF1bHRPcHRzIiwicHJvcCIsInJlc29sdmVPcHRpb25zIiwicm91dGUiLCJhY2Nlc3MiLCJjb3JlIiwiQUxMT1ciLCJpZGVudGl0eSIsImFkbWluIiwiUHJvbWlzZSIsInJlc29sdmUiLCJtaWRkbGV3YXJlcyIsIm1vZGVsIiwiZW1wdHlJbnN0YW5jZSIsImZvcmdlIiwidGFibGVOYW1lIiwiY2hhaW5GdW5jcyIsImN0eCIsImluc3RhbmNlcyIsImZ1bmNzIiwibGVuZ3RoIiwiZnVuYyIsInNoaWZ0IiwiYWxsIiwiaW52b2tlTWFwIiwicmVzdWx0cyIsImkiLCJhdCIsInNldCIsImNoYWluQ2xhdXNlcyIsImNsYXVzZXMiLCJxdWVyeSIsImNsYXVzZSIsImVycm9ycyIsIkZuRXJyQ2xhdXNlTm90RXhpc3RzIiwibW9kaWZpZWRRdWVyeSIsImtleXMiLCJGbkVyckNsYXVzZU9iamVjdFNob3VsZEhhdmVFeGFjdGx5T25lS2V5Iiwia2V5IiwidmFsdWUiLCJFcnJBZGRDbGF1c2VFbGVtZW50U2hvdWxkQmVTdHJpbmdPck9iamVjdCIsIkoyUyIsInByZWZpeCIsInJvdXRlcyIsImJvb2tzaGVsZiIsImZvcmJpZHMiLCJsb2ciLCJsb2dnZXIiLCJjb25maWd1cmUiLCJsb2dDb25maWciLCJsZXZlbCIsImNvbnRyb2xsZXIiLCJSb3V0ZXIiLCJhbGxSZXNvbHZlZE9wdHMiLCJqMnMiLCJwYXRoIiwic2V0dXBDb250cm9sbGVyIiwib3B0Iiwib3B0cyIsImVyckhhbmRsZXIiLCJlcnIiLCJKMlNFcnJvciIsIkZuRXJyRGF0YWJhc2VPcGVyYXRpb25FcnJvciIsIm1lc3NhZ2UiLCJnZXRPbmUiLCJuZXh0IiwicmVxdWVzdCIsIkpTT04iLCJwYXJzZSIsIkVyclF1ZXJ5U2hvdWxkQmVKc29uT2JqZWN0IiwiRXJyV2hlcmVLZXl3b3JkV2hlbkdldFdpdGhJZEZvcmJpZGRlbiIsIndoZXJlIiwiaWQiLCJwYXJhbXMiLCJnZXRJbnN0YW5jZXMiLCJpbnN0YW5jZSIsInRvSlNPTiIsImJvZHkiLCJkYXRhIiwiZ2V0IiwicG9zdCIsImNyZWF0ZUluc3RhbmNlcyIsInB1dE9uZSIsIkVycldoZXJlS2V5d29yZFdoZW5QdXRXaXRoSWRGb3JiaWRkZW4iLCJFcnJEYXRhU2hvdWxkQmVKc29uT2JqZWN0IiwidXBkYXRlSW5zdGFuY2VzIiwicHV0IiwiZGVsT25lIiwiRXJyV2hlcmVLZXl3b3JkV2hlbkRlbGV0ZVdpdGhJZEZvcmJpZGRlbiIsImZldGNoIiwiY2hlY2siLCJEIiwiRXJyT3BlcmF0aW9uTm90QXV0aG9yaXplZCIsImludm9rZVRoZW4iLCJFcnJSZXNvdXJjZU5vdEZvdW5kIiwic3VjY2VzcyIsImRlbCIsImNvdW50IiwiRXJyRGVsZXRpb25Ob3RBbGxvd2VkIiwiYXBwbHkiLCJjb25jYXQiLCJSIiwiQyIsIlUiLCJGbkVycktleUZvcmJpZGRlbiIsImZldGNoT3B0cyIsInBvcHVsYXRlIiwiRXJyUG9wdWxhdGVTaG91bGRCZUxpc3QiLCJtYXAiLCJwb3B1bGF0aW9uIiwiRXJyUG9wdWxhdGVPYmplY3RTaG91bGRIYXZlRXhhY3RseU9uZUtleSIsInBvcHVsYXRlUXVlcnkiLCJidWlsZGVyIiwiY