Stackedit/couchdb/setup-db.js

145 lines
3.0 KiB
JavaScript
Raw Normal View History

2014-09-09 23:37:21 +00:00
var request = require('request');
var async = require('async');
var validate = function(newDoc) {
Object.keys(newDoc).forEach(function(key) {
if(key[0] !== '_' && [
'updated',
'tags',
'title'
].indexOf(key) === -1) {
throw({forbidden: 'Unknown document attribute: ' + key});
}
});
var toString = Object.prototype.toString;
if(toString.call(newDoc._id) !== '[object String]') {
throw({forbidden: 'ID must be a string.'});
}
if(!newDoc._id.match(/[a-zA-Z0-9]{24}/)) {
throw({forbidden: 'Invalid ID format.'});
}
if(toString.call(newDoc.updated) !== '[object Number]') {
throw({forbidden: 'Update time must be an integer.'});
}
if(newDoc.updated > Date.now() + 60000) {
throw({forbidden: 'Update time is in the future, please check your clock!'});
}
if(toString.call(newDoc.title) !== '[object String]') {
throw({forbidden: 'Title must be a string.'});
}
if(!newDoc.title) {
throw({forbidden: 'Title is empty.'});
}
if(newDoc.title.length >= 256) {
throw({forbidden: 'Title too long.'});
}
if(newDoc.tags !== undefined) {
if(toString.call(newDoc.tags) !== '[object Array]') {
throw({forbidden: 'Tags must be an array.'});
}
if(newDoc.tags.length >= 16) {
throw({forbidden: 'Too many tags.'});
}
newDoc.tags.forEach(function(tag) {
if(toString.call(tag) !== '[object String]') {
throw({forbidden: 'Tags must contain strings only.'});
}
if(!tag) {
throw({forbidden: 'Tag is empty.'});
}
if(tag.length > 32) {
throw({forbidden: 'Tag is too long.'});
}
});
}
var attachment = (newDoc._attachments || {}).content;
if(!attachment) {
throw({forbidden: 'Missing attached content.'});
}
if(attachment.content_type != 'text/plain') {
throw({forbidden: 'Invalid content type.'});
}
if(Object.keys(newDoc._attachments).length > 1) {
throw({forbidden: 'Too many attachments.'});
}
};
var byUpdate = function(doc) {
emit(doc.updated, null);
};
var byTagAndUpdate = function(doc) {
doc.tags && doc.tags.forEach(function(tag) {
emit([
tag,
doc.updated
], null);
});
};
if(process.argv.length < 3) {
console.error('Missing URL parameter');
process.exit(-1);
}
var url = process.argv[2];
var ddocs = [
{
path: '/_design/validate',
body: {
validate_doc_update: validate.toString()
}
},
{
path: '/_design/by_update',
body: {
views: {
default: {
map: byUpdate.toString()
}
}
}
},
{
path: '/_design/by_tag_and_update',
body: {
views: {
default: {
map: byTagAndUpdate.toString()
}
}
}
}
];
async.each(ddocs, function(ddoc, cb) {
request.get(url + ddoc.path, function(err, res) {
if(res && res.body) {
ddoc.body._rev = JSON.parse(res.body)._rev;
}
request.put({
url: url + ddoc.path,
json: true,
body: ddoc.body
}, function(err, res) {
if(err) {
return cb(res);
}
if(res.statusCode >= 300) {
return cb(res.body);
}
cb();
});
});
}, function(err) {
if(err) {
console.error(err);
} else {
console.log('All design documents updated successfully');
}
});