Skip to content
Browse files

Initial commit

  • Loading branch information...
0 parents commit 1e6a9c8f9cc5549215a267334e01ef74802a628f @tj committed
Showing with 405 additions and 0 deletions.
  1. +12 −0 .gitmodules
  2. +2 −0 .npmignore
  3. +5 −0 History.md
  4. +9 −0 Makefile
  5. +199 −0 Readme.md
  6. +87 −0 index.js
  7. +8 −0 package.json
  8. +1 −0 support/connect
  9. +1 −0 support/ejs
  10. +1 −0 support/express
  11. +1 −0 support/expresso
  12. +79 −0 test/configure.test.js
12 .gitmodules
@@ -0,0 +1,12 @@
+[submodule "support/expresso"]
+ path = support/expresso
+ url = git://github.com/visionmedia/expresso.git
+[submodule "support/express"]
+ path = support/express
+ url = git://github.com/visionmedia/express.git
+[submodule "support/ejs"]
+ path = support/ejs
+ url = git://github.com/visionmedia/ejs.git
+[submodule "support/connect"]
+ path = support/connect
+ url = git://github.com/senchalabs/connect.git
2 .npmignore
@@ -0,0 +1,2 @@
+support
+test
5 History.md
@@ -0,0 +1,5 @@
+
+0.0.1 / 2010-09-06
+==================
+
+ * Initial release
9 Makefile
@@ -0,0 +1,9 @@
+
+test:
+ @./support/expresso/bin/expresso \
+ -I support/connect/lib \
+ -I support/ejs \
+ -I support \
+ --serial
+
+.PHONY: test
199 Readme.md
@@ -0,0 +1,199 @@
+
+# Express Contrib
+
+ [Express](http://expressjs.com) utilities which do not belong in core, however prove useful.
+
+## Installation
+
+npm:
+
+ $ npm install express-contrib
+
+## Modules
+
+ * Flash notification rendering (_express-messages_)
+
+## Module Usage
+
+You may either require the specific module, for example:
+
+ var messages = require('express-contrib/messages');
+
+or access via the main _express-contrib_ module which is useful when
+utilizing many of the modules:
+
+ var contrib = require('express-contrib');
+ var messages = contrib.messages;
+
+## express-messages
+
+The _express-messages_ module provides flash notification rendering. To use simply assign it to a dynamic helper:
+
+ app.dynamicHelpers({ messages: require('express-contrib/messages') });
+
+Then in a view you may output the notifications:
+
+ <%- messages() %>
+
+Which outputs HTML as shown below:
+
+ <div id="messages">
+ <ul class="info">
+ <li>Email queued</li>
+ <li>Email sent</li>
+ </ul>
+ <ul class="error">
+ <li>Email delivery failed</li>
+ </ul>
+ </div>
+
+## express-namespace
+
+The _express-namespace_ module provides namespace capabilities to express. The example below may respond to any of the following requests:
+
+ GET /forum/12
+ GET /forum/12/view
+ GET /forum/12/edit
+ GET /forum/12/thread/5
+ DELETE /forum/12
+
+To utilize this module simply `require('express-contrib')`, or if you prefer to __only__ utilize namespacing `require('express-contrib/namespace')`, and `app.namespace()` will automatically be available to you.
+
+Usage is as follows, simply pass a callback function and route to the method, after each callback invocation is complete, the namespace is restored to it's previous state.
+
+ app.namespace('/forum/:id', function(){
+ app.get('/(view)?', function(req, res){
+ res.send('GET forum ' + req.params.id);
+ });
+
+ app.get('/edit', function(req, res){
+ res.send('GET forum ' + req.params.id + ' edit page');
+ });
+
+ app.namespace('/thread', function(){
+ app.get('/:tid', function(req, res){
+ res.send('GET forum ' + req.params.id + ' thread ' + req.params.tid);
+ });
+ });
+
+ app.del('/', function(req, res){
+ res.send('DELETE forum ' + req.params.id);
+ });
+ });
+
+You can also access the current namespace via `app.currentNamespace`;
+
+## express-resource
+
+Provides resourceful routing, for example a module or object can be defined as shown in the example below, where all methods or "actions" are optional:
+
+
+ exports.index = function(req, res){
+ res.send('forum index');
+ };
+
+ exports.new = function(req, res){
+ res.send('new forum');
+ };
+
+ exports.create = function(req, res){
+ res.send('create forum');
+ };
+
+ exports.show = function(req, res){
+ res.send('show forum ' + req.params.id);
+ };
+
+ exports.edit = function(req, res){
+ res.send('edit forum ' + req.params.id);
+ };
+
+ exports.update = function(req, res){
+ res.send('update forum ' + req.params.id);
+ };
+
+ exports.destroy = function(req, res){
+ res.send('destroy forum ' + req.params.id);
+ };
+
+The _id_ option can be specified to prevent collisions:
+
+ exports.id = 'uid';
+
+ exports.destroy = function(req, res) {
+ res.send('destroy user ' + req.params.uid);
+ };
+
+The `app.resource()` method will create and return a new `Resource`:
+
+ var contrib = require('express-contrib')
+ , Resource = contrib.Resource
+ , app = express.createServer();
+
+ app.resource('forums', require('./forum'));
+
+Actions are then mapped as follows (by default):
+
+ GET /forums -> index
+ GET /forums/new -> new
+ POST /forums -> create
+ GET /forums/:id -> show
+ GET /forums/:id/edit -> edit
+ PUT /forums/:id -> update
+ DELETE /forums/:id -> destroy
+
+__NOTE:__ this functionality will surely grow with time, and as data store clients evolve we can provide close integration.
+
+## express-configure
+
+Ever wanted to boot your Express app settings using Redis or a similar key/value store? well now it is easy, all you need to do is either `require('express-configure')` or `require('express-contrib')` and callback a function in `configure()`:
+
+ app.configure(function(done){
+ redis.hmget('settings', function(err, obj){
+ for (var key in obj) app.set(key, obj[key]);
+ done();
+ });
+ });
+
+ app.listen(3000);
+
+## Contributors
+
+The following are the major contributors of Express Contrib (in no specific order).
+
+ * TJ Holowaychuk ([visionmedia](http://github.com/visionmedia))
+
+## Running Tests
+
+First make sure you have the submodules:
+
+ $ git submodule update --init
+
+Then run the tests:
+
+ $ make test
+
+## License
+
+(The MIT License)
+
+Copyright (c) 2010 TJ Holowaychuk &lt;tj@vision-media.ca&gt;
+
+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.
87 index.js
@@ -0,0 +1,87 @@
+
+/*!
+ * Express - Contrib - configure
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var express = require('express')
+ , Server = express.Server;
+
+// Proxy listen
+
+var listen = Server.prototype.listen;
+
+/**
+ * Proxy listen() to provide async support.
+ *
+ * @api public
+ */
+
+Server.prototype.listen = function(){
+ if (this.__config) {
+ this.__listen = arguments;
+ } else {
+ listen.apply(this, arguments);
+ }
+};
+
+// Proxy listenFD
+
+var listenFD = Server.prototype.listenFD;
+
+/**
+ * Proxy listen() to provide async support.
+ *
+ * @api public
+ */
+
+Server.prototype.listenFD = function(){
+ if (this.__config) {
+ this.__listenFD = arguments;
+ } else {
+ listenFD.apply(this, arguments);
+ }
+};
+
+// Proxy configure
+
+var configure = Server.prototype.configure;
+
+/**
+ * Proxy configure() to provide async support.
+ *
+ * @api public
+ */
+
+Server.prototype.configure = function(env, fn){
+ var self = this;
+ this.__config = this.__config || 0
+
+ if (typeof env === 'function') {
+ fn = env, env = 'all';
+ }
+
+ if ('all' == env || env == this.settings.env) {
+ if (fn.length) {
+ ++this.__config;
+ fn.call(this, function(err){
+ if (err) throw err;
+ if (!--self.__config) {
+ if (self.__listen) {
+ listen.apply(self, self.__listen);
+ } else if (self.__listenFD) {
+ listenFD.apply(self, self.__listenFD);
+ }
+ }
+ });
+ } else {
+ fn.call(this);
+ }
+ }
+ return this;
+};
8 package.json
@@ -0,0 +1,8 @@
+{ "name": "express-configure"
+ , "description": "Express async configuration support"
+ , "version": "0.0.1"
+ , "author": "TJ Holowaychuk <tj@vision-media.ca>"
+ , "keywords": ["express"]
+ , "main": "index"
+ , "engines": { "node": ">= 0.2.0" }
+}
1 support/connect
@@ -0,0 +1 @@
+Subproject commit 3a8f695fc4654c0c9314893d0d3893a7dd494b21
1 support/ejs
@@ -0,0 +1 @@
+Subproject commit 76cf94870e91f9e8ac73c219d4991f0cac7af661
1 support/express
@@ -0,0 +1 @@
+Subproject commit 5e0a80f227063fb7441ad8f7c36414f2b24dffe5
1 support/expresso
@@ -0,0 +1 @@
+Subproject commit d05bb65b69c80a7e11ce9953489dc742ac25c9ce
79 test/configure.test.js
@@ -0,0 +1,79 @@
+
+/**
+ * Module dependencies.
+ */
+
+var express = require('express')
+ , config = require('../')
+ , assert = require('assert');
+
+// Faux redis
+
+var redis = {
+ store: {},
+ hmget: function(key, fn){
+ var self = this;
+ process.nextTick(function(){
+ fn(null, self.store[key]);
+ });
+ },
+
+ hmset: function(key, obj, fn){
+ var self = this;
+ process.nextTick(function(){
+ self.store[key] = obj;
+ fn();
+ });
+ }
+}
+
+module.exports = {
+ setup: function(done){
+ redis.hmset('settings', {
+ title: 'Async example'
+ , foo: 'bar'
+ , bar: 'baz'
+ }, done);
+ },
+
+ 'test async configure()': function(){
+ var app = express.createServer()
+ , order = [];
+
+ app.configure(function(done){
+ redis.hmget('settings', function(err, obj){
+ for (var key in obj) {
+ app.set(key, obj[key]);
+ }
+ order.push('async 1');
+ done();
+ });
+ });
+
+ app.configure(function(done){
+ process.nextTick(function(){
+ order.push('async 2');
+ app.set('tobi', 'is cool');
+ done();
+ });
+ });
+
+ app.configure(function(){
+ order.push('sync');
+ app.enable('sync');
+ });
+
+ app.on('listening', function(){
+ assert.deepEqual(['sync', 'async 1', 'async 2'], order);
+ assert.strictEqual(true, app.set('sync'), 'sync configure() never called');
+ assert.equal('is cool', app.set('tobi'));
+ assert.equal('Async example', app.set('title'));
+ assert.equal('bar', app.set('foo'));
+ assert.equal('baz', app.set('bar'));
+ app.close();
+ });
+
+ app.listen(9999);
+ assert.ok(!app.fd, 'listen() was not deferred');
+ }
+};

0 comments on commit 1e6a9c8

Please sign in to comment.
Something went wrong with that request. Please try again.