UNPKG

sails-arangojs

Version:

A sails-arangojs adapter for Sails / Waterline

381 lines (327 loc) 11 kB
function getObject(globalId) { return `//${`${globalId}Dbo`.toUpperCase()} \n ${String(global[`${globalId}Dbo`])}`; } module.exports = ({ globalId, keyProps, modelDefaults, modelAttributes }) => { const globalid = `${globalId}`.toLocaleLowerCase(); const methods = () => ({ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // STATIC METHODS // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - globalId: `"${globalId}"`, keyProps: JSON.stringify(keyProps), modelDefaults: JSON.stringify(modelDefaults || {}), modelAttributes: JSON.stringify(modelAttributes || {}), validateParams: function (docParams) { const attributes = globalIdDbo.modelAttributes; for (let key in attributes) { if (key === 'id') { continue; } const type = attributes[key].type === 'json' ? 'object' : attributes[key].type; const required = attributes[key].required; const isIn = attributes[key].isIn; const rules = attributes[key].rules || {}; if ( Object.keys(docParams).includes(key) && docParams[key] !== null && typeof docParams[key] !== type ) { throw new Error( `${key} attribute in ${ globalIdDbo.globalId } should be of type ${type} - ${docParams._key || ''}` ); } if ( (!Object.keys(docParams).includes(key) || docParams[key] === null) && required ) { throw new Error( `${key} attribute in ${globalIdDbo.globalId} is required - ${ docParams._key || '' }` ); } if (isIn && type === 'string' && !isIn.includes(docParams[key])) { throw new Error( `${key} attribute (${type}) in ${ globalIdDbo.globalId } should be one of ${isIn.join(', ')}. But found ${ docParams[key] } - ${docParams._key || ''}` ); } if (isIn && type === 'object') { _.each(docParams[key], (str) => { if (!isIn.includes(str)) { throw new Error( `${key} attribute (${type}) in ${ globalIdDbo.globalId } should be one of ${isIn.join(', ')}. But found ${str} - ${ docParams._key || '' }` ); } }); } for (rule in rules) { if (rule === 'minimum') { if (docParams[key] < rules[rule]) { throw new Error( `${key} should not be less than ${rules[rule]} - its ${ docParams[key] } in ${docParams._key || ''}` ); } } if (rule === 'maximum') { if (docParams[key] > rules[rule]) { throw new Error( `${key} should not be more than ${rules[rule]} - its ${ docParams[key] } in ${docParams._key || ''}` ); } } if (rule === 'required') { if (typeof docParams[key] === 'object') { for (let requiredkey of rules[rule]) { if (!Object.keys(docParams[key]).includes(requiredkey)) { throw new Error( `${requiredkey} is required in ${key} - ${JSON.stringify( docParams )}` ); } } } } } } return true; }, create: function (...params) { let docParams; if (params.length > 2) { docParams = { ...globalIdDbo.modelDefaults, ...params[2], createdAt: params[2].createdAt || Date.now(), }; globalIdDbo.validateParams(docParams); params[2] = docParams; params[3] = { returnNew: true }; } else { if (Array.isArray(params[0])) { throw new Error(`Arrays are not supported`); } else { docParams = { ...globalIdDbo.modelDefaults, ...params[0], createdAt: Date.now(), }; globalIdDbo.validateParams(docParams); params[0] = docParams; params[1] = { returnNew: true }; } } try { const doc = db.globalid.insert(...params).new; const docObj = globalIdDbo.initialize(doc, true); return docObj; } catch (error) { const response = error.response || {}; throw new Error( `Error saving doc in globalid \n\n${error.toString()}\n\n ${JSON.stringify( docParams )}\n\n` ); } }, getDocument: function (params, options = { fireOnGetOne: true }) { const doc = db.globalid.document(params); const docObj = globalIdDbo.initialize(doc, options.fireOnGetOne); return docObj; }, find: function (params = {}, options = {}) { const { getAndStatement, getLetStatements } = dbmodules.filterStatement(); // Execute aql using the driver acquired dbConnectio. let aql = `FOR record in globalid \n`; if (options.let) { aql = `${aql}${getLetStatements(options.let)} \n`; } if (!_.isEmpty(params)) { aql = `${aql} FILTER ${getAndStatement(params)} \n`; } if (options.sort) { let str = ''; _.each(options.sort, (value, key) => { str += `record.${key} ${value}`; }); aql = `${aql} SORT ${str} \n`; } if (options.limit) { if (options.skip) { aql = `${aql} LIMIT ${options.skip}, ${options.limit} \n`; } else { aql = `${aql} LIMIT ${options.limit} \n`; } } aql = `${aql} return record`; return db._query(aql); }, findOne: function (params, options = { fireOnGetOne: true }) { const { getAndStatement, getLetStatements } = dbmodules.filterStatement(); const aql = `FOR record in globalid FILTER ${getAndStatement( params )} RETURN record`; const results = db._query(aql).toArray(); if (results.length > 1) { throw new Error(`More than one record found`); } if (results[0]) { const docObj = globalIdDbo.initialize(results[0], options.fireOnGetOne); return docObj; } return null; }, firstExample: function (params, options = { fireOnGetOne: true }) { const doc = db.globalid.firstExample(params); if (doc) { const docObj = globalIdDbo.initialize(doc, options.fireOnGetOne); return docObj; } return null; }, initialize: function (doc, fireOnGetOne = false) { if (doc instanceof globalIdDbo) { //Re Initialize doc.reInitialize(doc); return doc; } const obj = new globalIdDbo(); for (let key of Object.keys(doc)) { obj[key] = doc[key]; obj.id = doc._key; } Object.defineProperty(obj, 'globalId', { get: () => { return globalIdDbo.globalId; }, }); Object.defineProperty(obj, 'instanceName', { get: () => { return 'globalIdDbo'; }, }); Object.defineProperty(obj, 'keyProps', { get: () => { return obj.getKeyProps(); }, }); if (typeof obj.afterInitialize === 'function') { obj.afterInitialize(); } if (fireOnGetOne && typeof obj.onGetOne === 'function') { obj.onGetOne(); } return obj; }, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // PROTOTYPES // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - }); const prototypes = () => ({ getKeyProps: function getKeyProps() { let props = {}; for (let prop of this.constructor.keyProps) { props[prop] = this[prop]; } return { ...props, id: this._key, _id: this._id, }; }, reInitialize: function (doc) { for (let key of Object.keys(doc)) { this[key] = doc[key]; } }, update: function (callback) { if (typeof callback === 'function') { const updateValues = callback(this); try { globalIdDbo.validateParams({ ...this, ...updateValues, updatedAt: Date.now(), }); const updatedDoc = db._update( this, { ...updateValues, updatedAt: Date.now() }, { returnNew: true } ).new; this.reInitialize(updatedDoc); } catch (error) { throw new Error( `updating doc ${JSON.stringify({ ...this, ...updateValues, updatedAt: Date.now(), })} ${error.toString()}` ); } } else if (typeof callback === 'object') { try { globalIdDbo.validateParams({ ...this, ...callback, updatedAt: Date.now(), }); const updatedDoc = db._update( this, { ...callback, updatedAt: Date.now() }, { returnNew: true } ).new; this.reInitialize(updatedDoc); } catch (error) { throw new Error( `updating doc ${JSON.stringify(callback)} ${error.toString()}` ); } } else { throw new Error(`Dbo update function expects a callback`); } }, }); Object.assign(global[`${globalId}Dbo`], methods()); Object.assign(global[`${globalId}Dbo`].prototype, prototypes()); const objString = `${getObject(globalId)}\n`; let methodsString = ''; for (let key in global[`${globalId}Dbo`]) { methodsString = `${methodsString}${key}: ${String( global[`${globalId}Dbo`][key] )},\n`; } methodsString = `${methodsString}`.replace(/globalIdDbo/g, `${globalId}Dbo`); methodsString = `${methodsString}`.replace(/globalid/g, `${globalid}`); methodsString = `const ${globalId}StaticMethods = {\n${methodsString}\n}\n\nObject.assign(${globalId}Dbo, ${globalId}StaticMethods);\n`; let protypesString = ''; for (let key in global[`${globalId}Dbo`].prototype) { protypesString = `${protypesString}${globalId}Dbo.prototype.${key} = ${String( global[`${globalId}Dbo`].prototype[key] )}\n`; } protypesString = `${protypesString}`.replace( /globalIdDbo/g, `${globalId}Dbo` ); protypesString = `${protypesString}`.replace(/globalid/g, `${globalid}`); // console.log('===================================='); // console.log(`${objString}${methodsString}${protypesString}`); // console.log('===================================='); return `${objString}${methodsString}${protypesString}`; };