UNPKG

sails-arangojs

Version:

A sails-arangojs adapter for Sails / Waterline

425 lines (374 loc) 11.2 kB
const _ = require('@sailshq/lodash'); const util = require('util'); String.prototype.capitalizeCollection = function () { return this.charAt(0).toUpperCase() + this.slice(1); }; if (!global.getDocument) { global.getDocument = async function getDocument(searchValue, merchantcode) { try { let _id = ''; if (_.isString(searchValue) && `${searchValue}`.includes('/')) { _id = searchValue; } if ( _.isObject(searchValue) && searchValue._id && `${searchValue._id}`.includes('/') ) { _id = `${searchValue._id}`; } if (!_id) { throw new Error( `_id attribute should either be an object or a string in ${tableName}` ); } const tableName = `${_id}`.split('/')[0].capitalizeCollection(); if (!global[tableName]) { throw new Error( `Global object for ${tableName} not found in getDocument` ); } let obj; if (merchantcode) { obj = await global[`${tableName}Object`][`getOne`]( { _id: _id, }, merchantcode ); return obj; } obj = await global[`${tableName}Object`][`getOne`]({ _id: _id, }); return obj; } catch (error) { throw error; } }; } module.exports = ({ globalId, tableName, keyProps, cache, gIds, modelDefaults, }) => { const create = async function (params, dsName) { try { if (params.Email) { params.Email = `${params.Email}`.toLowerCase().trim(); } const doc = await global[`${globalId}Object`].findOne( { id: params.id, }, dsName ); if (doc) { throw new Error(`Document with same id already exists`); } let newdoc; if (dsName) { newdoc = await global[`_${globalId}`](dsName).create(params).fetch(); } else { newdoc = await global[globalId].create(params).fetch(); } return newdoc; } catch (error) { throw error; } }; const findOne = async function (params, dsName) { try { const { id, _id, ...otherprops } = params || {}; let doc; if (id) { if (dsName) { doc = await global[`_${globalId}`](dsName).findOne({ id: id }); } else { doc = await global[`${globalId}`].findOne({ id: id }); } } if (!doc && _id) { if (dsName) { doc = await global[`_${globalId}`](dsName).findOne({ _id: _id }); } else { doc = await global[`${globalId}`].findOne({ _id: _id }); } } if (!doc) { for (let prop in otherprops) { if (!keyProps.includes(prop) || Boolean(doc)) { // throw new Error(`${prop} is not a key props`); continue; } if (['string', 'number'].includes(typeof otherprops[prop])) { if (dsName) { doc = await global[`_${globalId}`](dsName).findOne({ [prop]: otherprops[prop], }); } else { doc = await global[`${globalId}`].findOne({ [prop]: otherprops[prop], }); } } } } return doc; } catch (error) { throw error; } }; const findDocument = async function (params, dsName) { try { const { id, ...otherprops } = params || {}; if (cache) { if (dsName) { if ( id && global[`${globalId}Object`][`Available${globalId}s`][ `${dsName}/${id}` ] ) { return global[`${globalId}Object`][`Available${globalId}s`][ `${dsName}/${id}` ]; } } else { if (id && global[`${globalId}Object`][`Available${globalId}s`][id]) { return global[`${globalId}Object`][`Available${globalId}s`][id]; } } } let doc; if (id) { if (dsName) { doc = await global[`_${globalId}`](dsName).findOne({ id: id }).meta({ fireOnGetOne: false, }); } else { doc = await global[`${globalId}`].findOne({ id: id }).meta({ fireOnGetOne: false, }); } } if (!doc) { for (let prop in otherprops) { if (['string', 'number'].includes(typeof otherprops[prop])) { if (dsName) { doc = await global[`_${globalId}`](dsName) .findOne({ [prop]: otherprops[prop], }) .meta({ fireOnGetOne: false, }); } else { doc = await global[`${globalId}`] .findOne({ [prop]: otherprops[prop], }) .meta({ fireOnGetOne: false, }); } } } } return doc; } catch (error) { throw error; } }; const getOne = async function (params, dsName) { try { const { id } = params || {}; if (cache) { if (dsName) { if ( id && global[`${globalId}Object`][`Available${globalId}s`][ `${dsName}/${id}` ] ) { return global[`${globalId}Object`][`Available${globalId}s`][ `${dsName}/${id}` ]; } } else { if (id && global[`${globalId}Object`][`Available${globalId}s`][id]) { return global[`${globalId}Object`][`Available${globalId}s`][id]; } } } const obj = await global[`${globalId}Object`].findOne(params, dsName); if (obj && obj.id) { obj.saveToCache(); } else { throw new Error( `\n\n${globalId} not available in ${ dsName || 'default' } datastore\n\n` ); } return obj; } catch (error) { throw error; } }; return { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // STATIC METHODS // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - globalId, tableName: `${tableName}`.toLowerCase(), keyProps, modelDefaults, cache, [`Available${globalId}s`]: {}, findOneOrCreate: async function (params, dsName) { try { let doc; if (dsName) { doc = await global[`_${globalId}`](dsName).findOne(params); if (!doc) { doc = await global[`_${globalId}`](dsName).create(params).fetch(); } } else { doc = await global[`${globalId}`].findOne(params); if (!doc) { doc = await global[`${globalId}`].create(params).fetch(); } } return doc; } catch (error) { throw error; } }, initialize: function initialize(doc, dsName, initOne) { try { if (!doc._id || !`${doc._id}`.includes(tableName)) { throw new Error(`INVALID DOCUMENT INITIALIZED`); } if (doc instanceof global[`${globalId}Object`]) { if (dsName && dsName !== doc.tenantcode) { return global[`${globalId}Object`].initialize({ ...doc }, dsName); } doc.reInitialize(doc); return doc; } let docObj; if (doc) { if (dsName) { docObj = new global[`${globalId}Object`](dsName); } else { docObj = new global[`${globalId}Object`](); } for (let key of Object.keys(doc)) { docObj[key] = doc[key]; if (doc.id) { docObj._key = doc.id; } if (doc._key) { docObj.id = doc._key; } } Object.defineProperty(docObj, 'tableName', { get: () => { return `${globalId}`.toLowerCase(); }, }); Object.defineProperty(docObj, 'cache', { get: () => { return cache; }, }); Object.defineProperty(docObj, 'globalId', { get: () => { return globalId; }, }); Object.defineProperty(docObj, '_Transaction', { get: () => { if (docObj.tenantcode) { return sails.getDatastore(docObj.tenantcode).manager .Transaction; } return sails.getDatastore().manager.Transaction; }, }); if (gIds) { _.each(gIds, (gId) => { Object.defineProperty(docObj, `_${gId}`, { get: () => { if (docObj.tenantcode) { return global[`_${gId}`](docObj.tenantcode); } return global[gId]; }, }); }); } if (typeof docObj.loadCalculatedProps === 'function') { docObj.loadCalculatedProps(); } if (docObj.saveToCache) { docObj.saveToCache(); } if (initOne) { if (typeof docObj.onGetOne === 'function') { const strFn = String(docObj.onGetOne); if ( strFn.includes('getOne') || strFn.includes('.onGetOne') || strFn.includes('findOne') || strFn.includes('getDocument') || strFn.includes(`'onGetOne'`) || strFn.includes(`"onGetOne"`) ) { const e = `Invalid function implementation onGetOne inside ${docObj.globalId}. The following functions cannot be called inside a ONGETONE(onGetOne) method: onGetOne getOne findOne getDocument This is to avoid infinite loops. Consider using .findDocument`; console.log('===================================='); console.log(e); console.log('===================================='); throw new Error(e); } if ( docObj.onGetOne.constructor.name === 'AsyncFunction' || util.types.isAsyncFunction(docObj.onGetOne) ) { return new Promise(async (resolve) => { await docObj.onGetOne(); resolve(docObj); }); } else { docObj.onGetOne(); } } } } return docObj; } catch (error) { throw error; } }, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // ALIASES // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - findDocument, findOne, getOne, create, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // PROTOTYPES // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - }; };