Permalink
Browse files

add example app

  • Loading branch information...
1 parent 77e3d7c commit a31eab213fc39c75e36fb84226da5f33e8a6425f @fjakobs fjakobs committed Nov 28, 2012
View
@@ -1,2 +1,3 @@
.c9revisions/
node_modules/
+example/node_modules
View
@@ -0,0 +1,85 @@
+var frontdoor = require("../../frontdoor");
+var errors = require("http-error");
+
+module.exports = function() {
+ var api = frontdoor("TODO app");
+
+ var todo = new Todo();
+ todo.add({description: "get a hair cut"}, function() {});
+ todo.add({description: "buy milk"}, function() {});
+ todo.update({id: 1, done: true}, function() {});
+
+ api.section("todo")
+ .get("/", todo.list.bind(todo))
+ .put("/", {
+ params: {
+ description: {
+ type: "string",
+ source: "body"
+ }
+ }
+ }, todo.add.bind(todo))
+ .post("/:id", {
+ params: {
+ id: "int",
+ done: {
+ type: "boolean",
+ source: "body",
+ optional: true
+ },
+ description: {
+ type: "string",
+ source: "body",
+ optional: true
+ }
+ }
+ }, todo.update.bind(todo))
+ .delete("/:id", {
+ params: { id: "int" }
+ }, todo.remove.bind(todo));
+
+ api.get("/inspect.json", frontdoor.mw.describeApi(api));
+
+ return api;
+};
+
+function Todo() {
+ this.items = {};
+ this._id = 1;
+}
+Todo.prototype.list = function(params, callback) {
+ var res = { items: [] };
+ for (var id in this.items)
+ res.items.push(this.items[id]);
+ callback(null, res);
+};
+Todo.prototype.add = function(params, callback) {
+ var id = this._id++;
+ this.items[id] = {
+ id: id,
+ done: false,
+ description: params.description
+ };
+ callback(null, this.items[id]);
+};
+Todo.prototype.update = function(params, callback) {
+ var item = this.items[params.id];
+ if (!item)
+ return callback(new errors.NotFound("No such entry " + params.id));
+
+ if ("done" in params)
+ item.done = params.done;
+
+ if ("description" in params)
+ item.description = params.description;
+
+ callback(null, { id: params.id });
+};
+Todo.prototype.remove = function(params, callback) {
+ var item = this.items[params.id];
+ if (!item)
+ return callback(new errors.NotFound("No such entry " + params.id));
+
+ delete this.items[params.id];
+ callback(null, { id: params.id });
+};
View
@@ -0,0 +1,36 @@
+
+/**
+ * Module dependencies.
+ */
+
+var express = require('express');
+var http = require('http');
+var path = require('path');
+var api = require("./api");
+
+var app = express();
+
+app.configure(function(){
+ app.set('port', process.env.PORT || 3000);
+ app.set('views', __dirname + '/views');
+ app.set('view engine', 'ejs');
+ app.use(express.favicon());
+ app.use(express.logger('dev'));
+ app.use(express.bodyParser());
+ app.use(express.methodOverride());
+ app.use(app.router);
+ app.use("/api", api());
+ app.use(express.static(path.join(__dirname, 'public')));
+});
+
+app.configure('development', function(){
+ app.use(express.errorHandler());
+});
+
+app.get('/', function(req, res){
+ res.render('index', { title: 'TODO' });
+});
+
+http.createServer(app).listen(app.get('port'), function(){
+ console.log("Express server listening on port " + app.get('port'));
+});
View
@@ -0,0 +1,12 @@
+{
+ "name": "application-name",
+ "version": "0.0.1",
+ "private": true,
+ "scripts": {
+ "start": "node app"
+ },
+ "dependencies": {
+ "express": "3.0.3",
+ "ejs": "*"
+ }
+}
@@ -0,0 +1,53 @@
+(function() {
+
+ refresh();
+
+ function refresh() {
+ $.ajax("/api/todo").done(function(data) {
+ var list = $("#list");
+ list.empty();
+
+ for (var i = 0; i < data.items.length; i++) {
+ var item = data.items[i];
+ var id = item.id;
+ var listItem = $("<li>").text(item.description).addClass(item.done ? "done": "");
+ listItem.append($("<button class='doneBtn'>").text("done").click(doneItem.bind(this, id)));
+ listItem.append($("<button class='delBtn'>").text("x").click(deleteItem.bind(this, id)));
+ list.append(listItem);
+ }
+ });
+ }
+
+ function doneItem(id) {
+ $.ajax({
+ url: "/api/todo/" + id,
+ type: "POST",
+ contentType: "application/json",
+ dataType: "json",
+ data: JSON.stringify({
+ done: true
+ })
+ }).done(refresh);
+ }
+
+ function deleteItem(id) {
+ $.ajax({
+ url: "/api/todo/" + id,
+ type: "DELETE",
+ dataType: "json"
+ }).done(refresh);
+ }
+
+ $("#add").click(function() {
+ $.ajax({
+ url: "/api/todo",
+ type: "PUT",
+ dataType: "json",
+ contentType: "application/json",
+ data: JSON.stringify({
+ description: $("#desc").val()
+ })
+ }).done(refresh);
+ });
+
+})(window);
@@ -0,0 +1,16 @@
+body {
+ padding: 50px;
+ font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
+}
+
+a {
+ color: #00B7FF;
+}
+
+.done {
+ text-decoration: line-through;
+}
+
+.done .doneBtn {
+ display: none;
+}
View
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title><%= title %></title>
+ <link rel='stylesheet' href='/stylesheets/style.css' />
+ </head>
+ <body>
+ <h1><%= title %></h1>
+
+ <ul id='list'>
+ </ul>
+
+ <input id='desc'><button id="add">Add</button>
+
+ <script type='text/javascript' src='https://c9.io/site/wp-content/themes/cloud9/js/jquery-1.6.2.min.js?ver=3.2.3'></script>
+ <script type='text/javascript' src='/javascripts/todo.js'></script>
+ </body>
+</html>
View
@@ -210,7 +210,7 @@ function Route(route, options, handler, types) {
function normalizePath(path, keys, params) {
for (var name in params) {
var param = params[name];
- if (typeof param == "string")
+ if (typeof param == "string" || param instanceof RegExp)
params[name] = { type: param};
}
View
@@ -360,9 +360,7 @@ module.exports = {
"test regexp types": function() {
var route = new api.Route("/users/:uid", {
params: {
- uid: {
- type: /u\d+/
- }
+ uid: /u\d+/
}
}, sinon.stub());
@@ -406,6 +404,9 @@ module.exports = {
return new Date(parseInt(string, 10));
},
+// parseJson = function(json) {
+// return new Date(json);
+// }
check: function(value) {
return value instanceof Date;
}

0 comments on commit a31eab2

Please sign in to comment.