-
Notifications
You must be signed in to change notification settings - Fork 3
/
index.js
94 lines (77 loc) · 2.55 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
'use strict';
var mongoose = require('mongoose'),
_ = require('lodash'),
inflection = require('inflection'),
slugs = require('slugs');
function slugify(model, options){
var slugParts = _.values(_.pick(model, options.source));
return slugs(slugParts.join(' '));
}
function getModel(document, options){
var modelName = options.modelName || inflection.singularize(inflection.camelize(document.collection.name));
return document.collection.conn.model(modelName);
}
function incrementAndSave(document, options, cb){
var Model = getModel(document, options);
var params = {};
var slugbaseKey = options.slugBase;
var itKey = options.slugIt;
params[slugbaseKey] = document[slugbaseKey];
Model.findOne(params).sort('-'+itKey).exec(function(e, doc){
if(e) return cb(e);
var it = (doc[itKey] || 0) + Math.ceil(Math.random()*10);
document[itKey] = it;
document[options.slugName] = document[slugbaseKey]+'-'+it;
document.markModified(slugbaseKey);
_.forEach(options.source, function(item){
document.markModified(item);
});
return document.save(cb);
});
}
function Slugin(schema, options){
options = _.defaults(options || {}, Slugin.defaultOptions);
if(_.isString(options.source))
options.source = [options.source];
options.slugIt = options.slugName + '_it';
options.slugBase = options.slugName + '_base';
var fields = {};
fields[options.slugName] = {
type : String,
unique: true
};
fields[options.slugBase] = {
type: String,
index:true
};
fields[options.slugIt] = {
type: Number
};
schema.add(fields);
schema.pre('save', function(next){
var self = this;
var slugBase = slugify(this,options);
if(this[options.slugBase] !== slugBase){
this[options.slugName] = slugBase;
this[options.slugBase] = slugBase;
delete this[options.slugIt];
}
next();
});
schema.methods.save = function(cb){
var self = this;
mongoose.Model.prototype.save.call(self, function(e, model, num){
if(e && (e.code === 11000 || e.code === 11001) && !!~e.err.indexOf(self[options.slugName])){
incrementAndSave(self, options, cb);
}else{
cb(e,model,num);
}
});
};
}
Slugin.defaultOptions = {
slugName : 'slug',
source : 'title',
modelName : null
};
module.exports = Slugin;