horde-storage
Version:
HORDE storage
123 lines (113 loc) • 3.5 kB
JavaScript
;
const _ = require('lodash');
const uuid = require('an-uuid');
const Joi = require('joi');
const horde = require('horde-lib');
const JSData = require('js-data');
const DSRethinkDbAdapter = require('js-data-rethinkdb');
const $ = horde.internal(this);
const store = new JSData.DS();
let storage;
const schema = {
user: {
login: Joi.string().regex(/^[a-z0-9]{2,16}$/, 'login').required(),
token: Joi.string().regex(/[0-9a-f]{128}/, 'keccak').required(),
phone: Joi.string().regex(/\+{0,1}\d{11}/, 'cell number').required(),
},
device: {
type: Joi.string().regex(/^dinstar$|^goip$/, 'type').required(),
user: Joi.string().guid().required(),
},
channel: {
device: Joi.string().guid().required(),
password: Joi.string().min(3, 'ascii').max(36, 'ascii'),
},
};
const vopts = { allowUnknown: true };
module.exports = (options) => {
if (_.isNil(storage)) {
const adapter = new DSRethinkDbAdapter(options);
store.registerAdapter('rethinkdb', adapter, { default: true });
const User = store.defineResource({
name: 'user',
relations: {
hasMany: {
device: {
localField: 'devices',
foreignKey: 'user',
},
},
},
beforeDestroy(User, user, callback) {
store.destroyAll('device', { where: { user: { '===': user.id }}})
.then(() => callback(null, user), (error) => callback(error));
},
validate: (User, user, callback) => {
Joi.validate(user, schema.user, vopts, (error, value) => {
if (error) {
callback(error);
} else {
store.findAll('user', {
where: { login: { '===': user.login },},
}).then((users) => {
if (users.length) {
callback(horde.error(409, 'duplicate login'));
} else {
callback(null, user);
}
}).catch((error) => {
callback(error);
});
}
});
},});
const Device = store.defineResource({
name: 'device',
relations: {
hasMany: {
device: {
localField: 'channels',
foreignKey: 'device',
},
},
},
beforeDestroy(Device, device, callback) {
store.destroyAll('channel', { where: { device: { '===': device.id }}})
.then(() => callback(null, device), (error) => callback(error));
},
validate: (Device, device, callback) => {
Joi.validate(device, schema.device, vopts, (error, value) => {
if (error) {
callback(error);
} else {
store.find('user', device.user).then((user) => {
callback(null, device);
}).catch((error) => callback(error));
}
});
},
afterValidate: (Device, device, callback) => {
callback(null, device);
},
});
const Channel = store.defineResource({
name: 'channel',
validate: (Channel, channel, callback) => {
Joi.validate(channel, schema.channel, vopts, (error, value) => {
if (error) {
callback(error);
} else {
callback(null, channel);
}
});
},
});
return storage = {
store, User, Device, Channel,
schema: (s) => {
return _.isNil(schema[s]) ? {} : schema[s];
},
getDevices: () => Device.findAll(),
};
};
};