Skip to content

Commit

Permalink
Initial commit.
Browse files Browse the repository at this point in the history
  • Loading branch information
zeekay committed Jul 18, 2012
0 parents commit ee209a0
Show file tree
Hide file tree
Showing 8 changed files with 192 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
@@ -0,0 +1,3 @@
node_modules/
npm-debug.log
lib/
4 changes: 4 additions & 0 deletions .npmignore
@@ -0,0 +1,4 @@
node_modules/
Cakefile
test/
src/
20 changes: 20 additions & 0 deletions Cakefile
@@ -0,0 +1,20 @@
{exec} = require './src/utils'

task 'build', 'compile src/*.coffee to lib/*.js', ->
console.log 'Compiling src/*.coffee to lib/*.js'
exec './node_modules/.bin/coffee -bc -o lib/ src/'

task 'gh-pages', 'Publish docs to gh-pages', ->
brief = require('brief')
quiet: false
brief.updateGithubPages()

task 'test', 'Run tests', ->
exec './node_modules/.bin/mocha ./test --compilers coffee:coffee-script -R spec -t 5000 -c'

task 'publish', 'publish current version to NPM', ->
exec [
'./node_modules/.bin/coffee -bc -o lib/ src/'
'git push'
'npm publish'
]
20 changes: 20 additions & 0 deletions LICENSE
@@ -0,0 +1,20 @@
Copyright (c) 2012 Zach Kelling

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.
12 changes: 12 additions & 0 deletions README.md
@@ -0,0 +1,12 @@
## Introduction

Ex is a razor-sharp DSL for [Express][express] inspired by [Zappa][zappa].

## Install

```bash
npm install ex
```

[express]: http://expressjs.com
[zappa]: https://github.com/mauricemach/zappa
40 changes: 40 additions & 0 deletions package.json
@@ -0,0 +1,40 @@
{
"name": "ex",
"description": "Razor-sharp DSL for express inspired by Zappa.",
"version": "0.1",
"repository": {
"type": "git",
"url": "git://github.com/zeekay/ex.git"
},
"keywords": [
"application",
"bundle",
"express",
"requisite",
"server"
],
"author": {
"name": "Zach Kelling",
"email": "zeekayy@gmail.com",
"url": "https://whatit.is"
},
"homepage": "https://github.com/zeekay/ex",
"licenses": [
{
"type": "MIT",
"url": "https://github.com/zeekay/ex/blob/master/LICENSE"
}
],
"main": "lib/",
"dependencies": {
"express": "~2.5.10",
},
"devDependencies": {
"chai": "*",
"mocha": "*",
"supertest": "*"
},
"engines": {
"node": ">=0.6.0"
}
}
69 changes: 69 additions & 0 deletions src/index.coffee
@@ -0,0 +1,69 @@
{patcher} = require './utils'

# Extend an express app with a zappa-ish DSL
module.exports = (app, func) ->

# create monkey patching utilities
{patch, unpatch} = patcher app

# configuration shortcuts
configure = null
patch 'configure', (original) ->
# Save a reference for the other helper methods
configure = original
(env, func) ->
if func
original env, ->
func.call app
else
original ->
env.call app

for env in ['development', 'production', 'test']
patch env, ->
do (env) ->
(func) ->
configure.call app, env, ->
func.call app

# setup specialized route handlers
for verb in ['all', 'get', 'post', 'put', 'del']
patch verb, (original) ->
(path, handler) ->
original path, (req, res, next) ->
ctx =
app: app
body: req.body
next: next
params: req.params
query: req.query
req: req
res: res
session: req.session
settings: app.settings
json: -> res.json.apply res, arguments
redirect: -> res.redirect.apply res, arguments
render: -> res.render.apply res, arguments
send: -> res.send.apply res, arguments
handler.apply ctx, req.params

# Expose middleware
patch 'middleware', -> require './middleware'

# Helper method
patch 'apply', ->
(funcs) ->
if not Array.isArray funcs
funcs = [funcs]

for _func in funcs
_func.call app

# Extend app using func
func.call app

# Unpatch app
unpatch()

# Return extended app
app
24 changes: 24 additions & 0 deletions src/utils.coffee
@@ -0,0 +1,24 @@
# Monkey-patch, unpatch existing object.
exports.patcher = (obj) ->
patched = []
patcher =
patch: (name, func) ->
original = obj[name]
if typeof original is 'function'
wrapper = ->
original.apply obj, arguments
replacement = func wrapper
else
replacement = func original
obj[name] = replacement
patched.push [name, original]
return

unpatch: ->
while patched.length
[name, original] = patched.pop()
if original
obj[name] = original
else
delete obj[name]
return

0 comments on commit ee209a0

Please sign in to comment.