Notch
Notch is a command line tool and library for building, deploying and administering CouchApps with Node.js.
Install
You need Node.js, npm and of course CouchDB (preferably >= 1.1) installed first.
To use Notch:
$ npm install notch
To hack Notch, first get the source:
$ git clone git://github.com/christiansmith/notch
$ cd notch
$ npm link
Then link notch into your project:
$ notch init -d path/to/project
$ cd path/to/project
$ npm link notch
CLI Usage
$ notch [command] [args] [options]
Commands:
init [-d directory] [-s skeleton]
Copies a default or optional skeleton from ~/.notch/closet into the
current or optional directory. Create your own project skeletons and
add them to the closet.
push <ddoc> [-t target]
Deploy a named CouchApp to a CouchDB target. If there is only one app
in your project, <ddoc> is "app".
$ notch push app -t production
draft <file> [-m model]
Generate a new json document and save it to a file. If a model is
specified, draft will prompt you to use defaults from a json-schema
or walk through the schema properties.
publish <file> [-t target] [-m model]
PUT a json document in a file to the server. By default, nothc keeps
these documents in a directory called data. The document _id and _rev
from the server response are saved along with timestamps.
fetch <id> [-t target] [-m model]
GET a document from a target server and write it to a file.
retract <file> [-t target] [-m model]
DEL a document from a target, but not the file. _id and _rev are removed.
Options
-h help
-v version
-d directory
-s skeleton
-m model
-t target
Tutorial
Initialize an app:
$ notch init -d myapp
$ cd myapp
Edit config.json to point to your database:
{
"targets": {
"development": {
"url": "http://localhost:5984/db",
"auth": "user:pwd"
}
},
"models": "lib/models.js"
}
Add some code to ddoc.js (see API description below):
ddoc.view('tagged', {
map: function (doc) {
if (doc.type == 'post' && doc.tags) {
doc.tags.forEach(function (tag) {
emit([tag, doc.published_at], doc);
});
}
}
});
Push it to your database:
$ notch push app
Now lets put some data in there:
$ notch draft newdoc
This generates data/newdoc.json. Add some valid JSON and then put it on the server:
$ notch publish data/newdoc.json
The complete features of notch aren''t all covered here. The project is in active development and everything is subject to change.
Project Structure
The default Notch project structure looks something like this:
_attachments/
config.json
data/
ddoc.js
You can also manage multiple apps per project, like so:
config.json
apps/blog/_attachments/
apps/blog/ddoc.js
apps/blog/lib
...
apps/admin/_attachments/
apps/admin/ddic.js
...
etc.
API description
Doc is the foundational abstraction of Notch. Doc has static methods to read from the filesystem, get from the server, and spawn from a schema. Doc can also be extended.
Doc.read('file.json');
Doc.get(id, target, callback);
Doc.spawn(schema);
Doc.extend(proto, static);
Doc instances can be initialized from an object.
var doc = new Doc({ foo: 'bar' });
Once initialized, an instance can read from a file, validate itself against a json-schema, generate a url for itself from a target object, write to a file, or put/del to a server. Of course, an extended Doc can override any or all of this.
doc.read('file.json', ['prop1','prop2']); // leave off the second arg to get everything
doc.validate(schema);
doc.url(target);
doc.write(file);
doc.put(target, function (err, res, body) { ... });
doc.del(target, function (err, res, body) { ... });
DDoc extends Doc to make it easy to build design documents. Here''s an example:
var notch = require('notch')
, ddoc = notch.createDDoc('blog');
// load some external stuff into the app
ddoc.load('_attachments');
ddoc.load({ json: 'schemas' });
ddoc.load({ json: 'info.json' });
ddoc.load({ modules: 'lib' });
ddoc.load({ modules: 'vendor' });
ddoc.load({ modules: 'templates', locals: ddoc.info });
// add some rewrites
ddoc.rewrite({
from: '/posts/tagged/:tag',
to: '_list/posts/tagged',
query: {
startkey: [':tag', {}],
endkey: [':tag'],
descending: 'true',
limit: (ddoc.info.pagesize + 1).toString()
}
});
// validation
ddoc.validate(function (newDoc, oldDoc, userCtx) {
var validate = require('vendor/json-schema').validate
, schema = this.schemas[newDoc.type];
if (!userCtx.name) {
throw { forbidden: 'Please log in first' };
}
if (oldDoc && newDoc.type !== oldDoc.type) {
throw { forbidden: 'Can\'t change document type' };
}
if (schema) {
var report = validate(newDoc, schema);
if (!report.valid) {
throw { forbidden: report };
}
}
});
// add a view
ddoc.view('tagged', {
map: function (doc) {
// ...
}
});
Similarly,
ddoc.show('name', function (doc, req) {...});
ddoc.list('name', function (head, req) {...});
You can extend Doc or DDoc if you want. For an example of this, see Hekyll.
License
Copyright (c) 2011 Christian Smith MIT License
Contact
Message me on GitHub.
Known Issues
Notch is a work in progress. Use it at your own risk. I would love to find a few collaborators to work on notch or jump into a similar effort.
Credit and Acknowledgements
Inspired by couchapp, node.couchapp.js, soca, and a very long list of tools I've found useful, like npm, git, leiningen, sinatra and countless others...