Permalink
Browse files

initial commit

  • Loading branch information...
aheckmann committed Feb 8, 2012
0 parents commit 0614f10d9076ab1e13e1148c2b3ff5da19b93bfd
Showing with 278 additions and 0 deletions.
  1. +2 −0 .gitignore
  2. +5 −0 History.md
  3. +22 −0 LICENSE
  4. +7 −0 Makefile
  5. +72 −0 README.md
  6. +1 −0 index.js
  7. +54 −0 lib/index.js
  8. +21 −0 package.json
  9. +94 −0 test/index.js
@@ -0,0 +1,2 @@
+*.sw*
+node_modules/
@@ -0,0 +1,5 @@
+
+0.0.1 / 02-08-2012
+==================
+
+ * initial release
22 LICENSE
@@ -0,0 +1,22 @@
+(The MIT License)
+
+Copyright (c) 2012 [Aaron Heckmann](aaron.heckmann+github@gmail.com)
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,7 @@
+
+TESTS = test/*.js
+
+test:
+ @./node_modules/.bin/mocha --reporter list --require should $(TESTFLAGS) $(TESTS)
+
+.PHONY: test
@@ -0,0 +1,72 @@
+#Mongoose-keywordize Plugin
+
+Provides keyword derivation for [Mongoose](http://mongoosejs.com) documents.
+
+[![Build Status](https://secure.travis-ci.org/aheckmann/mongoose-keywordize.png)](http://travis-ci.org/aheckmann/mongoose-keywordize)
+
+Options:
+
+ - fields: an array of paths you want watched and converted into keywords
+ - fn: a custom function to execute when keywordize() runs
+
+Example:
+
+```js
+var schema = new Schema({ name: String, title: String });
+schema.plugin(keywordize, { fields: 'name title'.split(' ') });
+```
+
+This will introduce a new `keywordize()` document method which detects if any of the passed fields have been modified and updates the new `keywords` property appropriately.
+
+Example:
+
+```js
+var Person = mongoose.model('Person', schema);
+var me = new Person({ name: 'aaron' });
+me.keywordize();
+console.log(me.keywords) // ['aaron']
+```
+
+The `keywordize` method is always called upon saving each document, auto-updating to the latest keywords.
+
+```js
+me.title = 'Mr';
+me.save(function (err) {
+ console.log(me.keywords) // ['aaron', 'Mr']
+})
+```
+
+One may also pass an optional function to run custom logic within the call to `keywordize`.
+
+```js
+
+var opts = {};
+opts.fields = ['name', 'title']
+opts.fn = function custom () {
+ if ('Mister' === this.title) {
+ return 'Mr';
+ }
+}
+var schema = new Schema({ name: String, title: String });
+schema.plugin(keywordize, opts);
+
+var Person = mongoose.model('Person', schema);
+var me = new Person({ name: 'aaron' });
+me.title = 'Mister';
+me.keywordize();
+console.log(me.keywords) // ['aaron', 'Mister', 'Mr']
+```
+
+The optional function will be executed within the context of the document meaning we have access to the documents properties through the `this` keyword.
+
+Either a an Array or single string may be returned from the function and will be pushed onto the keywords array.
+
+## Mongoose Version
+>= 2.x
+
+[LICENCE](https://github.com/aheckmann/mongoose-keywordize/blob/master/LICENSE)
+
+
+
+
+
@@ -0,0 +1 @@
+module.exports = exports = require('./lib');
@@ -0,0 +1,54 @@
+// mongoose-keywordize
+
+module.exports = exports = function keywordize (schema, options) {
+ if (!Array.isArray(options.fields)) options.fields = [options.fields];
+
+ var fields = options.fields.slice()
+ , fn = 'function' == typeof options.fn && options.fn
+
+ schema.add({ keywords: [String] });
+
+ schema.methods.keywordize = function () {
+ var self = this;
+
+ var values = fields.map(function (field) {
+ return self.get(field);
+ });
+
+ var keywords = [];
+ var i = values.length;
+
+ while (i--) {
+ var val = (values[i] || '').split(/\s/);
+ val.forEach(function (v) {
+ v = v.trim();
+ if (v) keywords.push(v);
+ })
+ }
+
+ if (fn) {
+ var res = fn.call(self);
+ if (undefined !== res) {
+ if (!Array.isArray(res)) res = [res]
+ val.forEach(function (v) {
+ if (!v) return;
+ v = v.trim();
+ if (v) keywords.push(v);
+ })
+ }
+ }
+
+ this.keywords = keywords;
+ }
+
+ schema.pre('save', function (next) {
+ var self = this;
+
+ var changed = this.isNew || fields.some(function (field) {
+ return self.isModified(field);
+ });
+
+ if (changed) this.keywordize();
+ next();
+ });
+}
@@ -0,0 +1,21 @@
+{
+ "author": "Aaron Heckmann <aaron.heckmann+github@gmail.com>",
+ "name": "mongoose-keywordize",
+ "description": "creates keywords from document properties",
+ "version": "0.0.1",
+ "repository": {
+ "url": ""
+ },
+ "scripts": {
+ "test": "make test"
+ },
+ "engines": {
+ "node": "~0.4.x < 0.7.0"
+ },
+ "dependencies": {},
+ "devDependencies": {
+ "mongoose": "2.5.5",
+ "mocha": "0.10.1",
+ "should": "0.5.1"
+ }
+}
@@ -0,0 +1,94 @@
+
+var mongoose = require('mongoose')
+ , Schema = mongoose.Schema
+ , keywords = require('../')
+ , should = require('should')
+
+mongoose.connect('localhost', 'mongoose_keywordize');
+
+var schema = new Schema({
+ name: { first: String, last: String }
+ , tags: [String]
+});
+
+var opts = {};
+opts.fields = ['name.first', 'name.last'];
+opts.fn = function () {
+ if (this.isModified('tags')) {
+ return this.tags[1];
+ }
+}
+
+schema.plugin(keywords, opts);
+
+var Person = mongoose.model('Person', schema);
+
+describe('plugin', function () {
+ before(function (next) {
+ mongoose.connection.on('open', next);
+ });
+
+ it('should create a keywords property of type array', function () {
+ Person.schema.path('keywords').casterConstructor.name.should.equal('SchemaString');
+ var p = new Person;
+ Array.isArray(p.keywords).should.be.true;
+ });
+
+ it('should add a keywordize method to the schema', function () {
+ Person.prototype.keywordize.should.be.a('function');
+ });
+
+ describe('keywordize', function () {
+ it('should populate the keywords', function () {
+ var p = new Person({ name: { last: 'heckmann' }});
+ p.keywords.length.should.equal(0);
+ p.keywordize();
+ p.keywords.length.should.equal(1);
+ p.name.first = 'aaron';
+ p.keywordize();
+ p.keywords.length.should.equal(2);
+ p.tags = "one two three".split(" ");
+ p.keywordize();
+ p.keywords.length.should.equal(3);
+ p.keywordize();
+ p.keywords.length.should.equal(3);
+ });
+ });
+
+ describe('hooks', function () {
+ it('should add the keywords when new', function (next) {
+ var p = new Person({ name: { last: 'heckmann' }});
+ p.keywords.length.should.equal(0);
+ p.save(function (err) {
+ if (err) return next(err);
+ p.keywords.length.should.equal(1);
+ p.keywords[0].should.equal('heckmann');
+ next();
+ });
+ });
+
+ it('should update the keywords if any field changed', function (next) {
+ var p = new Person({ name: { last: 'heckmann' }});
+ p.keywords.length.should.equal(0);
+ p.save(function (err) {
+ if (err) return next(err);
+ p.keywords.length.should.equal(1);
+ p.keywords[0].should.equal('heckmann');
+ p.name.last = 'fuerstenau';
+ p.save(function (err) {
+ if (err) return next(err);
+ p.keywords.length.should.equal(1);
+ p.keywords[0].should.equal('fuerstenau');
+ next();
+ });
+ });
+ });
+ });
+
+ after(function () {
+ mongoose.disconnect();
+ });
+
+});
+
+

0 comments on commit 0614f10

Please sign in to comment.