sg-node-api
Advanced tools
Comparing version 1.1.21 to 1.1.22
"use strict"; | ||
const req = require('../utils/req') | ||
const errors = require('../errors') | ||
function Base () { | ||
function Base (data) { | ||
let self = this | ||
@@ -13,3 +14,3 @@ | ||
self.attributes = { | ||
apiPath: '' | ||
apiPath: null | ||
} | ||
@@ -21,3 +22,3 @@ | ||
* @param data - Объект ключей и их значений | ||
* @returns {Goal} | ||
* @returns {Base} | ||
*/ | ||
@@ -54,2 +55,25 @@ self.set = (data) => { | ||
/** | ||
* Сортирует массив объектов по какому-то ключевому полю | ||
* | ||
* @param items - Массив объектов | ||
* @param key - Ключ сортировки, по умолчанию createdAt | ||
* @param dir - Направление сортировки : 'asc', default - по возрастанию или 'desc' - по убыванию | ||
* @returns {Array} | ||
*/ | ||
self.sortItems = (items, key, dir) => { | ||
return (items || []).sort((a, b) => { | ||
const dateA = a.get(key || 'createdAt') | ||
const dateB = b.get(key || 'createdAt') | ||
let comparison = 0 | ||
if (dateA > dateB) { | ||
comparison = dir === 'asc' ? 1 : -1 | ||
} else if (dateA < dateB) { | ||
comparison = dir === 'asc' ? -1 : 1 | ||
} | ||
return comparison | ||
}) | ||
} | ||
/** | ||
* Возвращает объект модели по его идентификатору | ||
@@ -62,40 +86,167 @@ * | ||
self.findById = async(ctx, id) => { | ||
const ret = await req.make(ctx, self.get('apiPath') + '/' + id, { | ||
method: 'GET', | ||
}).then( response => { | ||
self.set(response) | ||
return true | ||
}).catch( reason => { | ||
console.error(reason) | ||
return false | ||
}) | ||
const apiPath = self.get('apiPath') | ||
let result = { success: false } | ||
if (!apiPath || apiPath === '') { | ||
result.error = errors.getByCode(1001) // Wrong or undefined apiPath | ||
} else { | ||
const response = await req.make(ctx, apiPath + '/' + id, { | ||
method: 'GET', | ||
}).then( response => { | ||
self.set(response) | ||
return true | ||
}).catch( reason => { | ||
result.error = Object.assign( | ||
{ object: reason }, | ||
errors.getByCode(1002) // Exception caught in model Base::findById() | ||
) | ||
console.error(result.error.message) | ||
console.log(result.error.object) | ||
return false | ||
}) | ||
if (response === true) { | ||
result = self | ||
} | ||
} | ||
return ret ? self : null | ||
return result | ||
} | ||
/** | ||
* Сортирует массив объектов по какому-то ключевому полю | ||
* Возвращает все имеющиеся объекты модели | ||
* | ||
* @param commits - Массив объектов | ||
* @param key - Ключ сортировки, по умолчанию createdAt | ||
* @param asc - Направление сортировки : true (по возрастанию) или false (по убыванию) | ||
* @returns {Array.<T>} | ||
* @param ctx - Контекст приложения | ||
* @returns {Promise.<*>} | ||
*/ | ||
self.sortBy = (commits, key, asc) => { | ||
return (commits || []).sort((a, b) => { | ||
const dateA = a.get(key || 'createdAt') | ||
const dateB = b.get(key || 'createdAt') | ||
let comparison = 0 | ||
if (dateA > dateB) { | ||
comparison = asc ? 1 : -1 | ||
} else if (dateA < dateB) { | ||
comparison = asc ? -1 : 1 | ||
self.findAll = async (ctx) => { | ||
const apiPath = self.get('apiPath') | ||
let result = { success: false } | ||
if (!apiPath || apiPath === '') { | ||
result.error = errors.getByCode(1001) // Wrong or undefined apiPath | ||
} else { | ||
await req.make(ctx, apiPath + '/', { | ||
method: 'GET' | ||
}).then( response => { | ||
result.success = true | ||
result.items = [] | ||
for (let i = 0; i < response.length; i++) { | ||
result.items.push((new self.constructor).set(response[i])) | ||
} | ||
return true | ||
}).catch( reason => { | ||
result.error = Object.assign( | ||
{ object: reason }, | ||
errors.getByCode(1003) // Exception caught in model Base::search() | ||
) | ||
console.error(result.error.message) | ||
console.log(result.error.object) | ||
return false | ||
}) | ||
} | ||
return result | ||
} | ||
/** | ||
* Возвращает массив всех объектов в соответствии с текстовым запросом | ||
* | ||
* @param ctx - Контекст приложения | ||
* @param query - Текстовый запрос | ||
* @param opts - Опции поиска | ||
* @returns {Promise.<*>} | ||
*/ | ||
self.search = async (ctx, query, opts) => { | ||
const apiPath = self.get('apiPath') | ||
let result = { success: false } | ||
if (!apiPath || apiPath === '') { | ||
result.error = errors.getByCode(1001) // Wrong or undefined apiPath | ||
} else { | ||
await req.make(ctx, apiPath + '/search/' + query, { | ||
method: 'GET' | ||
}).then( async (response) => { | ||
result.success = true | ||
result.items = [] | ||
for (let i = 0; i < response.length; i++) { | ||
result.items.push((new self.constructor).set(response[i])) | ||
} | ||
return true | ||
}).catch( reason => { | ||
result.error = Object.assign( | ||
{ object: reason }, | ||
errors.getByCode(1003) // Exception caught in model Base::search() | ||
) | ||
console.error(result.error.message) | ||
return false | ||
}) | ||
} | ||
return result | ||
} | ||
/** | ||
* Сохраняет объект в БД. Апдейтит существующую запись или вставляет новую в зависимости от поля self.id | ||
* | ||
* @param ctx - Контекст приложения | ||
* @returns {Promise.<*>} | ||
*/ | ||
self.save = async(ctx) => { | ||
const apiPath = self.get('apiPath') | ||
let result = { success: false } | ||
if (!apiPath || apiPath === '') { | ||
result.error = errors.getByCode(1001) // Wrong or undefined apiPath | ||
} else { | ||
// Определяем данные для вставки или апдейта | ||
const data = self.get() | ||
data.owner = { id: ctx.session.user.get('id')} | ||
if (self.get('id') !== null && typeof self.get('id') !== 'undefined') { | ||
// Если был определен айдишник - это апдейт, используем метод PUT | ||
await req.make(ctx, self.get('apiPath') + '/' + self.get('id'), Object.assign({}, self.get(), { | ||
method: 'PUT', | ||
})).then( response => { | ||
result.success = true | ||
self.set(response) | ||
return true | ||
}).catch( reason => { | ||
result.error = Object.assign( | ||
{ object: reason }, | ||
errors.getByCode(1004) // Exception caught in model Base::save() | ||
) | ||
console.error(result.error.message) | ||
return false | ||
}) | ||
} else { | ||
// Если не был определен айдишник - это вставка, используем метод POST | ||
await req.make(ctx, self.get('apiPath'), Object.assign({}, self.get(), { | ||
method: 'POST', | ||
})).then( response => { | ||
result.success = true | ||
self.set(response) | ||
return true | ||
}).catch( reason => { | ||
result.error = Object.assign( | ||
{ object: reason }, | ||
errors.getByCode(1004) // Exception caught in model Base::save() | ||
) | ||
console.error(result.error.message) | ||
return false | ||
}) | ||
} | ||
return comparison | ||
}) | ||
} | ||
return self | ||
} | ||
// Устанавливаем атрибуты модели, встроенные и переданные | ||
self.set(data || {}) | ||
return self | ||
} | ||
module.exports = Base |
@@ -6,2 +6,3 @@ "use strict"; | ||
const moment = require('moment') | ||
const errors = require('../errors') | ||
@@ -80,3 +81,3 @@ /** | ||
let commits = response.map((commit) => (new Commit()).set(commit)) | ||
commits = self.sortBy(commits, 'createdAt', false) | ||
commits = self.sortItems(commits, 'createdAt', 'desc') | ||
return self.formatFields(commits) | ||
@@ -103,3 +104,3 @@ }).catch( reason => { | ||
let commits = response.map((commit) => (new Commit()).set(commit)) | ||
commits = self.sortBy(commits, 'createdAt', false) | ||
commits = self.sortItems(commits, 'createdAt', 'desc') | ||
return self.formatFields(commits) | ||
@@ -123,3 +124,3 @@ }).catch( reason => { | ||
commit.set({ | ||
createdAt_human: moment(commit.get('createdAt')).format('DD.MM'), | ||
createdAt_human: moment(commit.get('createdAt')).fromNow(), // format('DD.MM.YYYY HH:mm'), | ||
duration_human: commit.formatDuration('duration') | ||
@@ -147,3 +148,3 @@ }) | ||
*/ | ||
self.save = async(ctx) => { | ||
self.save2 = async(ctx) => { | ||
// Определяем данные для вставки или апдейта | ||
@@ -161,3 +162,3 @@ self.set({owner: { id: ctx.session.user.get('id')}}) | ||
// Если был определен айдишник - это апдейт, используем метод PUT | ||
await req.make(ctx, '/commits/' + self.get('id'), Object.assign({}, data, { | ||
await req.make(ctx, self.get('apiPath') + '/' + self.get('id'), Object.assign({}, data, { | ||
method: 'PUT', | ||
@@ -172,3 +173,3 @@ })).then( response => { | ||
// Если не был определен айдишник - это вставка, используем метод POST | ||
await req.make(ctx, '/commits', Object.assign({}, data, { | ||
await req.make(ctx, self.get('apiPath'), Object.assign({}, data, { | ||
method: 'POST', | ||
@@ -203,3 +204,3 @@ })).then( response => { | ||
Commit.prototype = Object.create(Base.prototype) | ||
Commit.prototype.constructor = Base | ||
Commit.prototype.constructor = Commit | ||
@@ -206,0 +207,0 @@ console.log('🔸️ Commit model initiated') |
"use strict"; | ||
const Base = require('./Base') | ||
const moment = require('moment') | ||
const req = require('../utils/req') | ||
const errors = require('../errors') | ||
@@ -73,3 +75,3 @@ /** | ||
let ret | ||
// ret = await req.make(ctx, 'contracts/validate/' + encodeURIComponent(txt), { | ||
// ret = await req.make(ctx, self.get('apiPath') + 'validate/' + encodeURIComponent(txt), { | ||
// method: 'GET', | ||
@@ -168,3 +170,25 @@ // }).then( (response) => response.data) | ||
}).then( response => { | ||
return response.map((contract) => (new Contract()).set(contract)) | ||
return response.map((contract) => { | ||
let c = (new Contract()).set(contract) | ||
let progress = 0 | ||
if (c.get('deadlineAt')) { | ||
progress = moment().startOf('day').diff(c.get('createdAt')) / moment(c.get('deadlineAt')).startOf('day').diff(c.get('createdAt')) * 100 | ||
c.set({ | ||
deadlineAt_human: moment(c.get('deadlineAt')), | ||
percent_completed: progress | ||
}) | ||
if (progress > 100) { | ||
c.set({overdue_days: moment().startOf('day').from(c.get('deadlineAt'), true)}) | ||
} | ||
} | ||
c.set({ | ||
state: c.get('completed') === true | ||
? 'Completed' | ||
: (c.get('archived') === true | ||
? 'Archived' | ||
: (progress === 100 ? 'Done' : (progress < 100 ? 'Active' : 'Overdue')) | ||
) | ||
}) | ||
return c | ||
}) | ||
}).catch( reason => { | ||
@@ -204,6 +228,6 @@ console.error(reason) | ||
* @param owner - Идентификатор заданного пользователя | ||
* @returns {Promise.<TResult>} | ||
* @returns {Promise.<*>} | ||
*/ | ||
self.findByGoalAndOwner = async(ctx, goal, owner) => { | ||
return await req.make(ctx, '/contracts/' + goal + '/' + owner, { | ||
return await req.make(ctx, self.get('apiPath') + '/' + goal + '/' + owner, { | ||
method: 'GET', | ||
@@ -231,38 +255,2 @@ }).then( response => { | ||
/** | ||
* Сохраняет объект в БД. Апдейтит существующую запись или вставляет новую в зависимости от поля self.id | ||
* | ||
* @param ctx - Контекст приложения | ||
* @returns {Promise.<Goal>} | ||
*/ | ||
self.save = async(ctx) => { | ||
// Определяем данные для вставки или апдейта | ||
const data = self.get() | ||
data.owner = { id: ctx.session.user.get('id')} | ||
if (self.get('id') !== null && typeof self.get('id') !== 'undefined') { | ||
// Если был определен айдишник - это апдейт, используем метод PUT | ||
await req.make(ctx, '/contracts/' + self.get('id'), Object.assign({}, self.get(), { | ||
method: 'PUT', | ||
})).then( response => { | ||
self.set(response) | ||
}).catch( reason => { | ||
console.error(reason) | ||
return false | ||
}) | ||
} else { | ||
// Если не был определен айдишник - это вставка, используем метод POST | ||
await req.make(ctx, '/contracts', Object.assign({}, self.get(), { | ||
method: 'POST', | ||
})).then( response => { | ||
self.set(response) | ||
}).catch( reason => { | ||
console.error(reason) | ||
return false | ||
}) | ||
} | ||
return self | ||
} | ||
// Устанавливаем атрибуты модели, встроенные и переданные | ||
@@ -290,3 +278,3 @@ self.set(Object.assign({ | ||
Contract.prototype = Object.create(Base.prototype) | ||
Contract.prototype.constructor = Base | ||
Contract.prototype.constructor = Contract | ||
@@ -293,0 +281,0 @@ console.log('🔸️ Contract model initiated') |
@@ -8,2 +8,3 @@ "use strict"; | ||
const Contract = require('./Contract') | ||
const errors = require('../errors') | ||
@@ -48,14 +49,21 @@ /** | ||
*/ | ||
self.findAll = async(ctx, user_id) => { | ||
user_id = (user_id && user_id.id) || user_id || ctx.session.user.get('id') | ||
const ret = await req.make(ctx, '/users/' + user_id + '/goals', { | ||
method: 'GET' | ||
}).then(async(response) => { | ||
let goals = [], goal | ||
if (!response || response.length === 0) { | ||
console.error('Нет целей') | ||
return null | ||
} else { | ||
self.findByUser = async (ctx, user_id) => { | ||
const apiPath = self.get('apiPath') | ||
let result = { success: false } | ||
if (!apiPath || apiPath === '') { | ||
result.error = errors.getByCode(1001) // Wrong or undefined apiPath | ||
} else { | ||
user_id = (user_id && user_id.id) || user_id || ctx.session.user.get('id') | ||
await req.make(ctx, '/users/' + user_id + '/goals', { | ||
method: 'GET' | ||
}).then( async response => { | ||
let goal | ||
result.success = true | ||
result.items = [] | ||
for (let i = 0; i < response.length; i++) { | ||
goal = (new Goal()).set(response[i]) | ||
let contract = await (new Contract()).findByGoalAndOwner(ctx, goal.get('id'), user_id) | ||
goal.set({ | ||
@@ -65,15 +73,19 @@ createdAt_human: moment(goal.get('createdAt')), | ||
deadlineAt_human: goal.get('deadlineAt') ? moment(goal.get('deadlineAt')) : null, | ||
contract: await (new Contract()) | ||
.findByGoalAndOwner(ctx, goal.get('id'), user_id) | ||
contract: contract.get() | ||
}) | ||
goals.push(goal) | ||
result.items.push(goal) | ||
} | ||
} | ||
return goals | ||
}).catch( reason => { | ||
console.error(reason) | ||
return false | ||
}) | ||
return ret || null | ||
return true | ||
}).catch( reason => { | ||
result.error = Object.assign( | ||
{ object: reason }, | ||
errors.getByCode(1103) // Exception caught in model Goal::findByUser() | ||
) | ||
console.error(result.error.message) | ||
console.log(result.error.object) | ||
return false | ||
}) | ||
} | ||
return result | ||
} | ||
@@ -121,3 +133,3 @@ | ||
opts = opts || {} | ||
const ret = await req.make(ctx, '/goals/' + id, { | ||
const ret = await req.make(ctx, self.get('apiPath') + '/' + id, { | ||
method: 'GET' | ||
@@ -139,4 +151,5 @@ }).then( response => { | ||
}) | ||
let progress = 0 | ||
if (self.get('deadlineAt')) { | ||
const progress = moment().startOf('day').diff(self.get('createdAt')) / moment(self.get('deadlineAt')).startOf('day').diff(self.get('createdAt')) * 100 | ||
progress = moment().startOf('day').diff(self.get('createdAt')) / moment(self.get('deadlineAt')).startOf('day').diff(self.get('createdAt')) * 100 | ||
self.set({ | ||
@@ -146,5 +159,2 @@ deadlineAt_human: moment(self.get('deadlineAt')), | ||
}) | ||
self.set({ | ||
state: progress === 100 ? 'Done' : (progress < 100 ? 'Active' : 'Overdue') | ||
}) | ||
if (progress > 100) { | ||
@@ -154,2 +164,10 @@ self.set({overdue_days: moment().startOf('day').from(self.get('deadlineAt'), true)}) | ||
} | ||
self.set({ | ||
state: self.get('completed') === true | ||
? 'Completed' | ||
: (self.get('archived') === true | ||
? 'Archived' | ||
: (progress === 100 ? 'Done' : (progress < 100 ? 'Active' : 'Overdue')) | ||
) | ||
}) | ||
} | ||
@@ -201,38 +219,2 @@ return self | ||
/** | ||
* Сохраняет объект в БД. Апдейтит существующую запись или вставляет новую в зависимости от поля self.id | ||
* | ||
* @param ctx - Контекст приложения | ||
* @returns {Promise.<Goal>} | ||
*/ | ||
self.save = async(ctx) => { | ||
// Определяем данные для вставки или апдейта | ||
const data = self.get() | ||
data.owner = { id: ctx.session.user.get('id')} | ||
if (self.get('id') !== null && typeof self.get('id') !== 'undefined') { | ||
// Если был определен айдишник - это апдейт, используем метод PUT | ||
await req.make(ctx, '/goals/' + self.get('id'), Object.assign({}, self.get(), { | ||
method: 'PUT', | ||
})).then( response => { | ||
self.set(response) | ||
}).catch( reason => { | ||
console.error(reason) | ||
return false | ||
}) | ||
} else { | ||
// Если не был определен айдишник - это вставка, используем метод POST | ||
await req.make(ctx, '/goals', Object.assign({}, self.get(), { | ||
method: 'POST', | ||
})).then( response => { | ||
self.set(response) | ||
}).catch( reason => { | ||
console.error(reason) | ||
return false | ||
}) | ||
} | ||
return self | ||
} | ||
// Устанавливаем атрибуты модели, встроенные и переданные | ||
@@ -259,3 +241,3 @@ self.set(Object.assign({ | ||
Goal.prototype = Object.create(Base.prototype) | ||
Goal.prototype.constructor = Base | ||
Goal.prototype.constructor = Goal | ||
@@ -262,0 +244,0 @@ console.log('🔸️ Goal model initiated') |
@@ -5,2 +5,3 @@ "use strict"; | ||
const req = require('../utils/req') | ||
const errors = require('../errors') | ||
@@ -52,3 +53,3 @@ /** | ||
self.get('auth').push(data) | ||
const ret = await req.make(ctx, '/users/' + self.get('id'), { | ||
const ret = await req.make(ctx, self.get('apiPath') + '/' + self.get('id'), { | ||
method: 'PUT', | ||
@@ -67,28 +68,2 @@ auth: self.get('auth') | ||
/** | ||
* Возвращает массив всех пользователей | ||
* | ||
* @param ctx - Контекст приложения | ||
* @returns {Promise.<TResult>} | ||
*/ | ||
self.findAll = async (ctx) => { | ||
return await req.make(ctx, '/users', { | ||
method: 'GET' | ||
}).then( async (response) => { | ||
let users = [] | ||
if (!response || response.length === 0) { | ||
console.error(ctx, 'Нет пользователей') | ||
return null | ||
} else { | ||
for (let i = 0; i < response.length; i++) { | ||
users.push((new User()).set(response[i])) | ||
} | ||
} | ||
return users | ||
}).catch( reason => { | ||
console.error(reason) | ||
return null | ||
}) | ||
} | ||
/** | ||
* Возвращает массив всех пользователей в соответствии с текстовым запросом | ||
@@ -99,25 +74,16 @@ * | ||
* @param opts - Опции поиска | ||
* @returns {Promise.<TResult>} | ||
* @type {(function(*=, *=, *=))|*} | ||
* @private | ||
*/ | ||
self.search = async (ctx, query, opts) => { | ||
self._search = self.search ; self.search = async (ctx, query, opts) => { | ||
opts = opts || {} | ||
return await req.make(ctx, '/users/search/' + query, { | ||
method: 'GET' | ||
}).then( async (response) => { | ||
let users = [] | ||
if (!response || response.length === 0) { | ||
console.error(ctx, 'Нет пользователей') | ||
return null | ||
} else { | ||
for (let i = 0; i < response.length; i++) { | ||
if (opts.skip_my !== true || response[i].id !== ctx.session.user.get('id')) { | ||
users.push((new User()).set(response[i])) | ||
} | ||
} | ||
} | ||
return users | ||
}).catch( reason => { | ||
console.error(reason) | ||
return null | ||
}) | ||
// Вызываем дефолтный базовый метод .search() | ||
let result = await self._search(ctx, query, opts || {}) | ||
// Если результат валидный и была опция исключить текущего пользователя - фильтруем по сессионному ключу | ||
if (result.success === true && opts.skip_my === true) { | ||
result.items = result.items.filter( item => item.get('id') !== ctx.session.user.get('id') ) | ||
} | ||
return result | ||
} | ||
@@ -133,3 +99,3 @@ | ||
self.findByEmail = async (ctx, email) => { | ||
const ret = await req.make(ctx, '/users/email/' + encodeURIComponent(email), { | ||
const ret = await req.make(ctx, self.get('apiPath') + '/email/' + encodeURIComponent(email), { | ||
method: 'GET' | ||
@@ -196,24 +162,2 @@ }).then( response => { | ||
/** | ||
* Сохраняет объект в БД, апдейтя существующую запись | ||
* | ||
* @param ctx - Контекст приложения | ||
* @returns {Promise.<Goal>} | ||
*/ | ||
self.save = async(ctx) => { | ||
// Определяем данные для апдейта | ||
const data = self.get() | ||
await req.make(ctx, '/users/' + self.get('id'), Object.assign({}, self.get(), { | ||
method: 'PUT', | ||
})).then( response => { | ||
self.set(response) | ||
}).catch( reason => { | ||
console.error(reason) | ||
return false | ||
}) | ||
return self | ||
} | ||
/** | ||
* Обновляет объект юзера в сессии по данным из БД | ||
@@ -248,3 +192,3 @@ * | ||
User.prototype = Object.create(Base.prototype) | ||
User.prototype.constructor = Base | ||
User.prototype.constructor = User | ||
@@ -251,0 +195,0 @@ console.log('🔸️ User model initiated') |
{ | ||
"name": "sg-node-api", | ||
"version": "1.1.21", | ||
"version": "1.1.22", | ||
"description": "Shared Goals API implemented as Node.JS library. API for telegram bot, www-clients and other usages", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -61,3 +61,4 @@ "use strict"; | ||
} | ||
return new Promise((resolve, reject) => { | ||
return new Promise( async (resolve, reject) => { | ||
let user = SESSION_USER | ||
@@ -96,3 +97,3 @@ | ||
} | ||
// Осуществляем запрос | ||
@@ -99,0 +100,0 @@ request(opt, (error, response, body) => { |
Sorry, the diff of this file is not supported yet
90650
19
1186