├── .gitignore ├── README.md └── code-examples ├── .gitignore ├── code-sharing ├── browserbuild │ ├── basic │ │ ├── a.js │ │ ├── b.js │ │ └── dist │ │ │ └── hello.js │ └── nodeonly │ │ ├── dist │ │ └── nodeonly.js │ │ └── nodeonly.js ├── exposing-modules │ └── add.js └── inheritance │ └── inherits.js ├── connect ├── basic-auth │ ├── package.json │ └── server.js ├── body-parser │ ├── Hello.txt │ ├── package.json │ ├── server.js │ └── static │ │ └── index.html ├── introduction │ ├── connect │ │ ├── package.json │ │ ├── server.js │ │ └── website │ │ │ ├── images │ │ │ ├── 1.jpg │ │ │ ├── 2.jpg │ │ │ ├── 3.jpg │ │ │ ├── 4.jpg │ │ │ └── LICENSE │ │ │ └── index.html │ └── http │ │ ├── images │ │ ├── 1.jpg │ │ ├── 2.jpg │ │ ├── 3.jpg │ │ ├── 4.jpg │ │ └── LICENSE │ │ ├── index.html │ │ └── server.js ├── logger │ ├── package.json │ ├── server.js │ └── website │ │ ├── images │ │ ├── 1.jpg │ │ ├── 2.jpg │ │ ├── 3.jpg │ │ ├── 4.jpg │ │ └── LICENSE │ │ └── index.html ├── method-override │ ├── package.json │ ├── server-swapped.js │ └── server.js ├── own-middleware │ ├── package.json │ ├── request-time.js │ └── server.js └── session │ ├── package.json │ ├── server.js │ └── users.json ├── express └── simple-app │ ├── step-1 │ └── package.json │ ├── step-2 │ └── views │ │ ├── index.ejs │ │ └── search.ejs │ ├── step-3 │ ├── server.js │ └── views │ │ ├── index.ejs │ │ └── search.ejs │ ├── step-4 │ ├── server.js │ └── views │ │ ├── index.ejs │ │ └── search.ejs │ └── step-5 │ ├── search.js │ ├── server.js │ └── views │ ├── index.ejs │ └── search.ejs ├── file-explorer ├── argv │ ├── example-2.js │ └── example.js ├── package.json ├── step-1 │ ├── npm-debug.log │ └── package.json ├── step-2 │ ├── index.js │ └── package.json ├── step-3 │ ├── example-1.js │ └── example-2.js ├── step-4 │ ├── index.js │ └── package.json ├── step-5 │ ├── index.js │ └── package.json └── step-6 │ ├── index.js │ ├── package.json │ └── test │ ├── a.txt │ └── b.txt ├── http ├── example-1 │ └── server.js ├── example-2 │ └── server.js ├── example-3 │ └── server.js ├── example-4 │ └── server.js ├── form-processor │ ├── step-1 │ │ └── package.json │ ├── step-2 │ │ ├── package.json │ │ └── server.js │ ├── step-3 │ │ ├── package.json │ │ └── server.js │ ├── step-4 │ │ ├── package.json │ │ ├── qs-example.js │ │ └── server.js │ ├── step-5 │ │ ├── package.json │ │ └── server.js │ └── step-6 │ │ ├── package.json │ │ └── server.js └── tweets │ ├── step-1 │ └── package.json │ ├── step-2 │ ├── client.js │ ├── package.json │ └── server.js │ ├── step-3 │ ├── client.js │ ├── package.json │ └── server.js │ └── step-4 │ └── tweets.js ├── introduction ├── index.js └── my-web-server.js ├── io ├── timeouts.js └── uncaught-http.js ├── mongodb ├── auth │ ├── step-1 │ │ └── package.json │ ├── step-2 │ │ ├── package.json │ │ ├── server.js │ │ └── views │ │ │ ├── index.jade │ │ │ ├── layout.jade │ │ │ ├── login.jade │ │ │ └── signup.jade │ ├── step-3 │ │ ├── package.json │ │ ├── server.js │ │ └── views │ │ │ ├── index.jade │ │ │ ├── layout.jade │ │ │ ├── login.jade │ │ │ └── signup.jade │ ├── step-4 │ │ ├── package.json │ │ ├── server.js │ │ └── views │ │ │ ├── index.jade │ │ │ ├── layout.jade │ │ │ ├── login.jade │ │ │ └── signup.jade │ ├── step-5 │ │ ├── package.json │ │ ├── server.js │ │ └── views │ │ │ ├── index.jade │ │ │ ├── layout.jade │ │ │ ├── login.jade │ │ │ └── signup.jade │ └── step-6 │ │ ├── package.json │ │ ├── server.js │ │ └── views │ │ ├── index.jade │ │ ├── layout.jade │ │ ├── login.jade │ │ └── signup.jade └── blog │ ├── package.json │ ├── server.js │ ├── step-final │ ├── blogpost.js │ ├── package.json │ └── server.js │ └── views │ ├── index.jade │ ├── layout.jade │ ├── login.jade │ └── signup.jade ├── mysql ├── node-mysql │ ├── step-1 │ │ └── package.json │ ├── step-2 │ │ ├── package.json │ │ └── server.js │ ├── step-3 │ │ ├── package.json │ │ └── server.js │ ├── step-4 │ │ ├── config.json │ │ ├── package.json │ │ ├── server.js │ │ └── setup.js │ ├── step-5 │ │ ├── config.json │ │ ├── package.json │ │ ├── server.js │ │ ├── setup.js │ │ └── views │ │ │ ├── index.jade │ │ │ ├── item.jade │ │ │ └── layout.jade │ └── step-6 │ │ ├── config.json │ │ ├── package.json │ │ ├── server.js │ │ ├── setup.js │ │ └── views │ │ ├── index.jade │ │ ├── item.jade │ │ └── layout.jade └── sequelize │ ├── step-1 │ └── package.json │ ├── step-2 │ ├── package.json │ ├── public │ │ └── js │ │ │ └── main.js │ ├── server.js │ └── views │ │ ├── index.jade │ │ ├── layout.jade │ │ └── tasks.jade │ ├── step-3 │ ├── package.json │ ├── public │ │ └── js │ │ │ └── main.js │ ├── server.js │ └── views │ │ ├── index.jade │ │ ├── layout.jade │ │ └── tasks.jade │ ├── step-4 │ ├── package.json │ ├── public │ │ └── js │ │ │ └── main.js │ ├── server.js │ └── views │ │ ├── index.jade │ │ ├── layout.jade │ │ └── tasks.jade │ └── step-5 │ ├── package.json │ ├── public │ └── js │ │ └── main.js │ ├── server.js │ └── views │ ├── index.jade │ ├── layout.jade │ └── tasks.jade ├── nodejs ├── 1 │ ├── main.js │ ├── module_a.js │ └── module_b.js ├── 2 │ ├── index.js │ └── module_a.js ├── 3 │ ├── index.js │ └── person.js └── 4 │ ├── index.js │ └── logo.png ├── redis ├── social-graph │ ├── step-1 │ │ └── package.json │ ├── step-2 │ │ ├── app.js │ │ └── package.json │ ├── step-3 │ │ ├── app.js │ │ └── package.json │ └── step-4 │ │ ├── model.js │ │ ├── package.json │ │ └── test.js └── test │ ├── model.js │ └── test.js ├── socket.io ├── public │ ├── chat.js │ └── index.html └── server.js ├── tcp ├── chat │ ├── step-1 │ │ ├── index.js │ │ └── package.json │ ├── step-2 │ │ ├── index.js │ │ └── package.json │ ├── step-3 │ │ ├── index.js │ │ └── package.json │ ├── step-4 │ │ ├── index.js │ │ └── package.json │ └── step-5 │ │ ├── index.js │ │ └── package.json ├── introduction │ └── web-server.js └── irc │ └── index.js ├── testing ├── mocha │ ├── bdd │ │ └── bdd.js │ ├── browser │ │ ├── expect.js │ │ ├── index.html │ │ ├── jquery.js │ │ ├── mocha.css │ │ ├── mocha.js │ │ └── my-test.js │ ├── tdd │ │ └── tdd.js │ └── test.js └── simple-testing │ ├── assert-example.js │ └── test-program │ ├── express-app │ ├── search.js │ ├── server.js │ └── views │ │ ├── index.ejs │ │ └── search.ejs │ └── test.js └── websocket ├── cursors ├── step-1 │ └── package.json ├── step-2 │ ├── package.json │ └── server.js └── step-3 │ ├── package.json │ ├── public │ └── index.html │ └── server.js └── echo ├── step-1 └── package.json ├── step-2 ├── package.json └── server.js └── step-3 ├── package.json ├── public ├── cursor.png └── index.html └── server.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | smashingnode 2 | ============ 3 | 4 | Repository for my book "Smashing Node". 5 | It will host: 6 | 7 | - The website http://smashingnode.com 8 | - Code examples 9 | - Interaction area 10 | - and more! -------------------------------------------------------------------------------- /code-examples/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /code-examples/code-sharing/browserbuild/basic/a.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = require('./b')('world'); 3 | -------------------------------------------------------------------------------- /code-examples/code-sharing/browserbuild/basic/b.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = function (str) { 3 | return str; 4 | } 5 | -------------------------------------------------------------------------------- /code-examples/code-sharing/browserbuild/basic/dist/hello.js: -------------------------------------------------------------------------------- 1 | (function () { function require(p){ var path = require.resolve(p) , mod = require.modules[path]; if (!mod) throw new Error('failed to require "' + p + '"'); if (!mod.exports) { mod.exports = {}; mod.call(mod.exports, mod, mod.exports, require.relative(path)); } return mod.exports;}require.modules = {};require.resolve = function(path){ var orig = path , reg = path + '.js' , index = path + '/index.js'; return require.modules[reg] && reg || require.modules[index] && index || orig;};require.register = function(path, fn){ require.modules[path] = fn;};require.relative = function(parent) { return function(p){ if ('.' != p.charAt(0)) return require(p); var path = parent.split('/') , segs = p.split('/'); path.pop(); for (var i = 0; i < segs.length; i++) { var seg = segs[i]; if ('..' == seg) path.pop(); else if ('.' != seg) path.push(seg); } return require(path.join('/')); };};require.register("a.js", function(module, exports, require){ 2 | 3 | module.exports = require('./b')('world'); 4 | 5 | });require.register("b.js", function(module, exports, require){ 6 | 7 | module.exports = function (str) { 8 | return str; 9 | } 10 | 11 | });require.register("dist/basic.js", function(module, exports, require){ 12 | (function () { function require(p){ var path = require.resolve(p) , mod = require.modules[path]; if (!mod) throw new Error('failed to require "' + p + '"'); if (!mod.exports) { mod.exports = {}; mod.call(mod.exports, mod, mod.exports, require.relative(path)); } return mod.exports;}require.modules = {};require.resolve = function(path){ var orig = path , reg = path + '.js' , index = path + '/index.js'; return require.modules[reg] && reg || require.modules[index] && index || orig;};require.register = function(path, fn){ require.modules[path] = fn;};require.relative = function(parent) { return function(p){ if ('.' != p.charAt(0)) return require(p); var path = parent.split('/') , segs = p.split('/'); path.pop(); for (var i = 0; i < segs.length; i++) { var seg = segs[i]; if ('..' == seg) path.pop(); else if ('.' != seg) path.push(seg); } return require(path.join('/')); };};require.register("a.js", function(module, exports, require){ 13 | 14 | exports.hello = require('./b')('world'); 15 | 16 | });require.register("b.js", function(module, exports, require){ 17 | 18 | module.exports = function (str) { 19 | return str; 20 | } 21 | 22 | });hello = require('a.js'); 23 | })(); 24 | });hello = require('a.js'); 25 | })(); -------------------------------------------------------------------------------- /code-examples/code-sharing/browserbuild/nodeonly/dist/nodeonly.js: -------------------------------------------------------------------------------- 1 | (function () { function require(p){ var path = require.resolve(p) , mod = require.modules[path]; if (!mod) throw new Error('failed to require "' + p + '"'); if (!mod.exports) { mod.exports = {}; mod.call(mod.exports, mod, mod.exports, require.relative(path)); } return mod.exports;}require.modules = {};require.resolve = function(path){ var orig = path , reg = path + '.js' , index = path + '/index.js'; return require.modules[reg] && reg || require.modules[index] && index || orig;};require.register = function(path, fn){ require.modules[path] = fn;};require.relative = function(parent) { return function(p){ if ('.' != p.charAt(0)) return require(p); var path = parent.split('/') , segs = p.split('/'); path.pop(); for (var i = 0; i < segs.length; i++) { var seg = segs[i]; if ('..' == seg) path.pop(); else if ('.' != seg) path.push(seg); } return require(path.join('/')); };};require.register("nodeonly.js", function(module, exports, require){ 2 | 3 | 4 | 5 | 6 | 7 | console.log('browser and node'); 8 | 9 | });nodeonly = require('nodeonly'); 10 | })(); -------------------------------------------------------------------------------- /code-examples/code-sharing/browserbuild/nodeonly/nodeonly.js: -------------------------------------------------------------------------------- 1 | 2 | // if node 3 | process.exit(1); 4 | // end 5 | 6 | console.log('browser and node'); 7 | -------------------------------------------------------------------------------- /code-examples/code-sharing/exposing-modules/add.js: -------------------------------------------------------------------------------- 1 | (function (module) { 2 | if ('undefined' == typeof module) { 3 | module = { exports: {} }; 4 | } 5 | 6 | module.exports = function (a, b) { 7 | return a + b; 8 | } 9 | 10 | if ('undefined' != typeof window) { 11 | window.add = module.exports; 12 | } 13 | })(module); 14 | -------------------------------------------------------------------------------- /code-examples/code-sharing/inheritance/inherits.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Inheritance utility. 4 | * 5 | * @param {Function} constructor 6 | * @param {Function} constructor we inherit from 7 | * @api private 8 | */ 9 | 10 | function inherits (a, b) { 11 | function c () {}; 12 | c.prototype = b.prototype; 13 | a.prototype = new c; 14 | }; 15 | -------------------------------------------------------------------------------- /code-examples/connect/basic-auth/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "method-override" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "connect": "1.8.1" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /code-examples/connect/basic-auth/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var connect = require('connect') 7 | 8 | /** 9 | * Create server 10 | */ 11 | 12 | process.stdin.resume(); 13 | process.stdin.setEncoding('ascii'); 14 | 15 | var server = connect( 16 | connect.basicAuth(function (user, pass, fn) { 17 | process.stdout.write('Allow user \033[96m' + user + '\033[39m ' 18 | + 'with pass \033[90m' + pass + '\033[39m ? [y/n]: '); 19 | process.stdin.once('data', function (data) { 20 | if (data[0] == 'y') { 21 | fn(null, { username: user }); 22 | } 23 | else fn(new Error('Unauthorized')); 24 | }); 25 | }) 26 | , function (req, res) { 27 | res.writeHead(200); 28 | res.end('Welcome to the protected area, ' + req.remoteUser.username); 29 | } 30 | ); 31 | 32 | /** 33 | * Listen 34 | */ 35 | 36 | server.listen(3000); 37 | -------------------------------------------------------------------------------- /code-examples/connect/body-parser/Hello.txt: -------------------------------------------------------------------------------- 1 | This file is Hello.txt 2 | -------------------------------------------------------------------------------- /code-examples/connect/body-parser/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "body-parser" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "connect": "1.8.1" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /code-examples/connect/body-parser/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module requirements. 4 | */ 5 | 6 | var connect = require('connect') 7 | , fs = require('fs') 8 | 9 | /** 10 | * Create server 11 | */ 12 | 13 | var server = connect( 14 | connect.bodyParser() 15 | , connect.static('static') 16 | , function (req, res, next) { 17 | if ('POST' == req.method && req.body.file) { 18 | fs.readFile(req.body.file.path, 'utf8', function (err, data) { 19 | if (err) { 20 | res.writeHead(500); 21 | res.end('Error!'); 22 | return; 23 | } 24 | 25 | res.writeHead(200, { 'Content-Type': 'text/html' }); 26 | res.end([ 27 | '

File: ' + req.body.file.name + '

' 28 | , '

Type: ' + req.body.file.type + '

' 29 | , '

Contents:

' + data + '
' 30 | ].join('')); 31 | }); 32 | } else { 33 | next(); 34 | } 35 | } 36 | ); 37 | 38 | /** 39 | * Listen. 40 | */ 41 | 42 | server.listen(3000); 43 | -------------------------------------------------------------------------------- /code-examples/connect/body-parser/static/index.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 | 5 |
6 | -------------------------------------------------------------------------------- /code-examples/connect/introduction/connect/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-website" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "connect": "1.8.1" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /code-examples/connect/introduction/connect/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var connect = require('connect') 7 | 8 | /** 9 | * Create server. 10 | */ 11 | 12 | var server = connect.createServer(); 13 | 14 | /** 15 | * Handle static files. 16 | */ 17 | 18 | server.use(connect.static(__dirname + '/website')); 19 | 20 | /** 21 | * Listen. 22 | */ 23 | 24 | server.listen(3000); 25 | -------------------------------------------------------------------------------- /code-examples/connect/introduction/connect/website/images/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/smashingnode/3ca42801b584bcb9f210ad13f42e58c5cf75dc67/code-examples/connect/introduction/connect/website/images/1.jpg -------------------------------------------------------------------------------- /code-examples/connect/introduction/connect/website/images/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/smashingnode/3ca42801b584bcb9f210ad13f42e58c5cf75dc67/code-examples/connect/introduction/connect/website/images/2.jpg -------------------------------------------------------------------------------- /code-examples/connect/introduction/connect/website/images/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/smashingnode/3ca42801b584bcb9f210ad13f42e58c5cf75dc67/code-examples/connect/introduction/connect/website/images/3.jpg -------------------------------------------------------------------------------- /code-examples/connect/introduction/connect/website/images/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/smashingnode/3ca42801b584bcb9f210ad13f42e58c5cf75dc67/code-examples/connect/introduction/connect/website/images/4.jpg -------------------------------------------------------------------------------- /code-examples/connect/introduction/connect/website/images/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | The images used in this example were released under "CC Attribution 2.0 Generic" 3 | license, and are part of the public domain [1] 4 | 5 | 1.jpg: http://www.flickr.com/photos/fritography/4524444398/ 6 | 2.jpg: http://www.flickr.com/photos/pargon/2461131176/ 7 | 3.jpg: http://www.flickr.com/photos/usnavy/6219970385/ 8 | 4.jpg: http://www.flickr.com/photos/butlerphotography/4201634265/ 9 | 10 | [1] http://creativecommons.org/licenses/by/2.0/deed.en 11 | -------------------------------------------------------------------------------- /code-examples/connect/introduction/connect/website/index.html: -------------------------------------------------------------------------------- 1 | 2 |

My website

3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /code-examples/connect/introduction/http/images/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/smashingnode/3ca42801b584bcb9f210ad13f42e58c5cf75dc67/code-examples/connect/introduction/http/images/1.jpg -------------------------------------------------------------------------------- /code-examples/connect/introduction/http/images/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/smashingnode/3ca42801b584bcb9f210ad13f42e58c5cf75dc67/code-examples/connect/introduction/http/images/2.jpg -------------------------------------------------------------------------------- /code-examples/connect/introduction/http/images/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/smashingnode/3ca42801b584bcb9f210ad13f42e58c5cf75dc67/code-examples/connect/introduction/http/images/3.jpg -------------------------------------------------------------------------------- /code-examples/connect/introduction/http/images/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/smashingnode/3ca42801b584bcb9f210ad13f42e58c5cf75dc67/code-examples/connect/introduction/http/images/4.jpg -------------------------------------------------------------------------------- /code-examples/connect/introduction/http/images/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | The images used in this example were released under "CC Attribution 2.0 Generic" 3 | license, and are part of the public domain [1] 4 | 5 | 1.jpg: http://www.flickr.com/photos/fritography/4524444398/ 6 | 2.jpg: http://www.flickr.com/photos/pargon/2461131176/ 7 | 3.jpg: http://www.flickr.com/photos/usnavy/6219970385/ 8 | 4.jpg: http://www.flickr.com/photos/butlerphotography/4201634265/ 9 | 10 | [1] http://creativecommons.org/licenses/by/2.0/deed.en 11 | -------------------------------------------------------------------------------- /code-examples/connect/introduction/http/index.html: -------------------------------------------------------------------------------- 1 | 2 |

My website

3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /code-examples/connect/introduction/http/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var http = require('http') 7 | , fs = require('fs') 8 | 9 | /** 10 | * Create our server. 11 | */ 12 | 13 | var server = http.createServer(function (req, res) { 14 | if ('GET' == req.method && '/images' == req.url.substr(0, 7) 15 | && '.jpg' == req.url.substr(-4)) { 16 | fs.stat(__dirname + req.url, function (err, stat) { 17 | if (err || !stat.isFile()) { 18 | res.writeHead(404); 19 | res.end('Not Found'); 20 | return; 21 | } 22 | serve(__dirname + req.url, 'application/jpg'); 23 | }); 24 | } else if ('GET' == req.method && '/' == req.url) { 25 | serve(__dirname + '/index.html', 'text/html'); 26 | } else { 27 | res.writeHead(404); 28 | res.end('Not found'); 29 | } 30 | 31 | function serve (path, type) { 32 | res.writeHead(200, { 'Content-Type': type }); 33 | fs.createReadStream(path).pipe(res); 34 | } 35 | }); 36 | 37 | /** 38 | * Listen. 39 | */ 40 | 41 | server.listen(3000); 42 | -------------------------------------------------------------------------------- /code-examples/connect/logger/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-website" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "connect": "1.7.1" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /code-examples/connect/logger/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var connect = require('connect') 7 | 8 | /** 9 | * Create server. 10 | */ 11 | 12 | var server = connect.createServer(); 13 | 14 | /** 15 | * Perform logging. 16 | */ 17 | 18 | server.use(connect.logger({ format: 'type is :res[content-type], length is ' 19 | + ':res[content-length] and it took :response-time ms.', immediate: false })); 20 | 21 | /** 22 | * Handle static files. 23 | */ 24 | 25 | server.use(connect.static(__dirname + '/website')); 26 | 27 | /** 28 | * Listen. 29 | */ 30 | 31 | server.listen(3000); 32 | -------------------------------------------------------------------------------- /code-examples/connect/logger/website/images/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/smashingnode/3ca42801b584bcb9f210ad13f42e58c5cf75dc67/code-examples/connect/logger/website/images/1.jpg -------------------------------------------------------------------------------- /code-examples/connect/logger/website/images/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/smashingnode/3ca42801b584bcb9f210ad13f42e58c5cf75dc67/code-examples/connect/logger/website/images/2.jpg -------------------------------------------------------------------------------- /code-examples/connect/logger/website/images/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/smashingnode/3ca42801b584bcb9f210ad13f42e58c5cf75dc67/code-examples/connect/logger/website/images/3.jpg -------------------------------------------------------------------------------- /code-examples/connect/logger/website/images/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/smashingnode/3ca42801b584bcb9f210ad13f42e58c5cf75dc67/code-examples/connect/logger/website/images/4.jpg -------------------------------------------------------------------------------- /code-examples/connect/logger/website/images/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | The images used in this example were released under "CC Attribution 2.0 Generic" 3 | license, and are part of the public domain [1] 4 | 5 | 1.jpg: http://www.flickr.com/photos/fritography/4524444398/ 6 | 2.jpg: http://www.flickr.com/photos/pargon/2461131176/ 7 | 3.jpg: http://www.flickr.com/photos/usnavy/6219970385/ 8 | 4.jpg: http://www.flickr.com/photos/butlerphotography/4201634265/ 9 | 10 | [1] http://creativecommons.org/licenses/by/2.0/deed.en 11 | -------------------------------------------------------------------------------- /code-examples/connect/logger/website/index.html: -------------------------------------------------------------------------------- 1 | 2 |

My website

3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /code-examples/connect/method-override/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "method-override" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "connect": "1.8.1" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /code-examples/connect/method-override/server-swapped.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var connect = require('connect') 7 | 8 | /** 9 | * Create server 10 | */ 11 | 12 | var server = connect( 13 | connect.methodOverride() 14 | , connect.logger('dev') 15 | ); 16 | 17 | /** 18 | * Listen 19 | */ 20 | 21 | server.listen(3000); 22 | -------------------------------------------------------------------------------- /code-examples/connect/method-override/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var connect = require('connect') 7 | 8 | /** 9 | * Create server 10 | */ 11 | 12 | var server = connect( 13 | connect.logger('dev') 14 | , connect.methodOverride() 15 | ); 16 | 17 | /** 18 | * Listen 19 | */ 20 | 21 | server.listen(3000); 22 | -------------------------------------------------------------------------------- /code-examples/connect/own-middleware/package.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | "name": "own-middleware-test" 4 | , "version": "0.0.1" 5 | , "dependencies": { 6 | "connect": "1.8.1" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /code-examples/connect/own-middleware/request-time.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Request time middleware. 4 | * 5 | * Options: 6 | * - `time` (`Number`): number of ms after which we log (100) 7 | * 8 | * @param {Object} options 9 | * @api public 10 | */ 11 | 12 | module.exports = function (opts) { 13 | 14 | var time = opts.time || 100; 15 | 16 | return function (req, res, next) { 17 | var timer = setTimeout(function () { 18 | console.log( 19 | '\033[90m%s %s\033[39m \033[91mis taking too long!\033[39m' 20 | , req.method 21 | , req.url 22 | ); 23 | }, time); 24 | 25 | var end = res.end; 26 | res.end = function (chunk, encoding) { 27 | res.end = end; 28 | res.end(chunk, encoding); 29 | clearTimeout(timer); 30 | }; 31 | 32 | next(); 33 | }; 34 | 35 | }; 36 | -------------------------------------------------------------------------------- /code-examples/connect/own-middleware/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var connect = require('connect') 7 | , time = require('./request-time') 8 | 9 | /** 10 | * Create server. 11 | */ 12 | 13 | var server = connect.createServer(); 14 | 15 | /** 16 | * Log requests. 17 | */ 18 | 19 | server.use(connect.logger('dev')); 20 | 21 | /** 22 | * Implement time middleware. 23 | */ 24 | 25 | server.use(time({ time: 500 })); 26 | 27 | /** 28 | * Fast response. 29 | */ 30 | 31 | server.use(function (req, res, next) { 32 | if ('/a' == req.url) { 33 | res.writeHead(200); 34 | res.end('Fast!'); 35 | } else { 36 | next(); 37 | } 38 | }); 39 | 40 | 41 | /** 42 | * Slow response. 43 | */ 44 | 45 | server.use(function (req, res, next) { 46 | if ('/b' == req.url) { 47 | setTimeout(function () { 48 | res.writeHead(200); 49 | res.end('Slow!'); 50 | }, 1000); 51 | } else { 52 | next(); 53 | } 54 | }); 55 | 56 | /** 57 | * Listen. 58 | */ 59 | 60 | server.listen(3000); 61 | -------------------------------------------------------------------------------- /code-examples/connect/session/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "session-example" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "connect": "1.8.1" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /code-examples/connect/session/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies 4 | */ 5 | 6 | var connect = require('connect') 7 | , users = require('./users') 8 | 9 | /** 10 | * Create server 11 | */ 12 | 13 | var server = connect( 14 | connect.logger('dev') 15 | , connect.bodyParser() 16 | , connect.cookieParser() 17 | , connect.session({ secret: 'my app secret' }) 18 | , function (req, res, next) { 19 | if ('/' == req.url && req.session.logged_in) { 20 | res.writeHead(200, { 'Content-Type': 'text/html' }); 21 | res.end( 22 | 'Welcome back, ' + req.session.name + '. ' 23 | + 'Logout' 24 | ); 25 | } else { 26 | next(); 27 | } 28 | } 29 | , function (req, res, next) { 30 | if ('/' == req.url && 'GET' == req.method) { 31 | res.writeHead(200, { 'Content-Type': 'text/html' }); 32 | res.end([ 33 | '
' 34 | , '
' 35 | , 'Please log in' 36 | , '

User:

' 37 | , '

Password:

' 38 | , '' 39 | , '
' 40 | , '
' 41 | ].join('')); 42 | } else { 43 | next(); 44 | } 45 | } 46 | , function (req, res, next) { 47 | if ('/login' == req.url && 'POST' == req.method) { 48 | res.writeHead(200); 49 | if (!users[req.body.user] || req.body.password != users[req.body.user].password) { 50 | res.end('Bad username/password'); 51 | } else { 52 | req.session.logged_in = true; 53 | req.session.name = users[req.body.user].name; 54 | res.end('Authenticated!'); 55 | } 56 | } else { 57 | next(); 58 | } 59 | } 60 | , function (req, res, next) { 61 | if ('/logout' == req.url) { 62 | req.session.logged_in = false; 63 | res.writeHead(200); 64 | res.end('Logged out!'); 65 | } else { 66 | next(); 67 | } 68 | } 69 | ); 70 | 71 | /** 72 | * Listen. 73 | */ 74 | 75 | server.listen(3000); 76 | -------------------------------------------------------------------------------- /code-examples/connect/session/users.json: -------------------------------------------------------------------------------- 1 | { 2 | "tobi": { 3 | "password": "ferret" 4 | , "name": "Tobi Holowaychuk" 5 | } 6 | , "manny": { 7 | "password": "cat" 8 | , "name": "Manny Thecat" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /code-examples/express/simple-app/step-1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "express-tweet" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "express": "2.5.1" 6 | , "ejs": "0.4.2" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /code-examples/express/simple-app/step-2/views/index.ejs: -------------------------------------------------------------------------------- 1 | 2 |

Twitter app

3 | 4 |

Please enter your search term:

5 |
6 | 7 |

' 12 | , '' 13 | ].join('')); 14 | }).listen(3000); 15 | -------------------------------------------------------------------------------- /code-examples/http/form-processor/step-3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "http-form" 3 | , "description": "An HTTP server that processes forms" 4 | , "version": "0.0.1" 5 | } 6 | -------------------------------------------------------------------------------- /code-examples/http/form-processor/step-3/server.js: -------------------------------------------------------------------------------- 1 | 2 | require('http').createServer(function (req, res) { 3 | if ('/' == req.url) { 4 | res.writeHead(200, { 'Content-Type': 'text/html' }); 5 | res.end([ 6 | '
' 7 | , '

My form

' 8 | , '
' 9 | , '' 10 | , '

What is your name?

' 11 | , '' 12 | , '

' 13 | , '' 14 | ].join('')); 15 | } else if ('/url' == req.url) { 16 | res.writeHead(200, { 'Content-Type': 'text/html' }); 17 | res.end('You sent a ' + req.method + ' request'); 18 | } 19 | }).listen(3000); 20 | -------------------------------------------------------------------------------- /code-examples/http/form-processor/step-4/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "http-form" 3 | , "description": "An HTTP server that processes forms" 4 | , "version": "0.0.1" 5 | } 6 | -------------------------------------------------------------------------------- /code-examples/http/form-processor/step-4/qs-example.js: -------------------------------------------------------------------------------- 1 | 2 | console.log(require('querystring').parse('name=Guillermo')); 3 | console.log(require('querystring').parse('q=guillermo+rauch')); 4 | -------------------------------------------------------------------------------- /code-examples/http/form-processor/step-4/server.js: -------------------------------------------------------------------------------- 1 | 2 | require('http').createServer(function (req, res) { 3 | if ('/' == req.url) { 4 | res.writeHead(200, { 'Content-Type': 'text/html' }); 5 | res.end([ 6 | '
' 7 | , '

My form

' 8 | , '
' 9 | , '' 10 | , '

What is your name?

' 11 | , '' 12 | , '

' 13 | , '' 14 | ].join('')); 15 | } else if ('/url' == req.url && 'POST' == req.method) { 16 | var body = ''; 17 | 18 | req.on('data', function (chunk) { 19 | body += chunk; 20 | }); 21 | 22 | req.on('end', function () { 23 | res.writeHead(200, { 'Content-Type': 'text/html' }); 24 | res.end('

Content-Type: ' + req.headers['content-type'] + '

' 25 | + '

Data:

' + body + '
'); 26 | }); 27 | } 28 | }).listen(3000); 29 | -------------------------------------------------------------------------------- /code-examples/http/form-processor/step-5/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "http-form" 3 | , "description": "An HTTP server that processes forms" 4 | , "version": "0.0.1" 5 | } 6 | -------------------------------------------------------------------------------- /code-examples/http/form-processor/step-5/server.js: -------------------------------------------------------------------------------- 1 | 2 | var qs = require('querystring'); 3 | 4 | require('http').createServer(function (req, res) { 5 | if ('/' == req.url) { 6 | res.writeHead(200, { 'Content-Type': 'text/html' }); 7 | res.end([ 8 | '
' 9 | , '

My form

' 10 | , '
' 11 | , '' 12 | , '

What is your name?

' 13 | , '' 14 | , '

' 15 | , '' 16 | ].join('')); 17 | } else if ('/url' == req.url && 'POST' == req.method) { 18 | var body = ''; 19 | 20 | req.on('data', function (chunk) { 21 | body += chunk; 22 | }); 23 | 24 | req.on('end', function () { 25 | res.writeHead(200, { 'Content-Type': 'text/html' }); 26 | res.end('

Your name is ' + qs.parse(body).name + '

'); 27 | }); 28 | } 29 | }).listen(3000); 30 | -------------------------------------------------------------------------------- /code-examples/http/form-processor/step-6/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "http-form" 3 | , "description": "An HTTP server that processes forms" 4 | , "version": "0.0.1" 5 | } 6 | -------------------------------------------------------------------------------- /code-examples/http/form-processor/step-6/server.js: -------------------------------------------------------------------------------- 1 | 2 | var qs = require('querystring'); 3 | 4 | require('http').createServer(function (req, res) { 5 | if ('/' == req.url) { 6 | res.writeHead(200, { 'Content-Type': 'text/html' }); 7 | res.end([ 8 | '
' 9 | , '

My form

' 10 | , '
' 11 | , '' 12 | , '

What is your name?

' 13 | , '' 14 | , '

' 15 | , '' 16 | ].join('')); 17 | } else if ('/url' == req.url && 'POST' == req.method) { 18 | var body = ''; 19 | 20 | req.on('data', function (chunk) { 21 | body += chunk; 22 | }); 23 | 24 | req.on('end', function () { 25 | res.writeHead(200, { 'Content-Type': 'text/html' }); 26 | res.end('

Your name is ' + qs.parse(body).name + '

'); 27 | }); 28 | } else { 29 | res.writeHead(404); 30 | res.end('Not Found'); 31 | } 32 | }).listen(3000); 33 | -------------------------------------------------------------------------------- /code-examples/http/tweets/step-1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tweet-client" 3 | , "description": "An HTTP tweets client" 4 | , "version": "0.0.1" 5 | } 6 | -------------------------------------------------------------------------------- /code-examples/http/tweets/step-2/client.js: -------------------------------------------------------------------------------- 1 | 2 | require('http').request({ host: '127.0.0.1', port: 3000, url: '/', method: 'GET' }, function (res) { 3 | var body = ''; 4 | res.setEncoding('utf8'); 5 | res.on('data', function (chunk) { 6 | body += chunk; 7 | }); 8 | res.on('end', function () { 9 | console.log('\n We got: \033[96m' + body + '\033[39m\n'); 10 | }); 11 | }).end(); 12 | -------------------------------------------------------------------------------- /code-examples/http/tweets/step-2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tweet-client" 3 | , "description": "An HTTP tweets client" 4 | , "version": "0.0.1" 5 | } 6 | -------------------------------------------------------------------------------- /code-examples/http/tweets/step-2/server.js: -------------------------------------------------------------------------------- 1 | 2 | require('http').createServer(function (req, res) { 3 | res.writeHead(200); 4 | res.end('Hello World'); 5 | }).listen(3000); 6 | -------------------------------------------------------------------------------- /code-examples/http/tweets/step-3/client.js: -------------------------------------------------------------------------------- 1 | 2 | var http = require('http') 3 | , qs = require('querystring') 4 | 5 | function send (theName) { 6 | http.request({ host: '127.0.0.1', port: 3000, url: '/', method: 'POST' }, function (res) { 7 | res.setEncoding('utf8'); 8 | res.on('end', function () { 9 | console.log('\n \033[90m✔ request complete!\033[39m'); 10 | process.stdout.write('\n your name: '); 11 | }); 12 | }).end(qs.stringify({ name: theName })); 13 | } 14 | 15 | process.stdout.write('\n your name: '); 16 | process.stdin.resume(); 17 | process.stdin.setEncoding('utf-8'); 18 | process.stdin.on('data', function (name) { 19 | send(name.replace('\n', '')); 20 | }); 21 | -------------------------------------------------------------------------------- /code-examples/http/tweets/step-3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tweet-client" 3 | , "description": "An HTTP tweets client" 4 | , "version": "0.0.1" 5 | } 6 | -------------------------------------------------------------------------------- /code-examples/http/tweets/step-3/server.js: -------------------------------------------------------------------------------- 1 | 2 | var qs = require('querystring'); 3 | 4 | require('http').createServer(function (req, res) { 5 | var body = ''; 6 | 7 | req.on('data', function (chunk) { 8 | body += chunk; 9 | }); 10 | 11 | req.on('end', function () { 12 | res.writeHead(200); 13 | res.end('Done'); 14 | 15 | console.log('\n got name \033[90m' + qs.parse(body).name + '\033[39m\n'); 16 | }); 17 | }).listen(3000); 18 | -------------------------------------------------------------------------------- /code-examples/http/tweets/step-4/tweets.js: -------------------------------------------------------------------------------- 1 | 2 | var qs = require('querystring') 3 | , http = require('http') 4 | 5 | var search = process.argv.slice(2).join(' ').trim() 6 | 7 | if (!search.length) { 8 | return console.log('\n Usage: node tweets \n'); 9 | } 10 | 11 | console.log('\n searching for: \033[96m' + search + '\033[39m\n'); 12 | 13 | http.request({ 14 | host: 'search.twitter.com' 15 | , path: '/search.json?' + qs.stringify({ q: search }) 16 | }, function (res) { 17 | var body = ''; 18 | res.setEncoding('utf8'); 19 | res.on('data', function (chunk) { 20 | body += chunk; 21 | }); 22 | res.on('end', function () { 23 | var obj = JSON.parse(body); 24 | obj.results.forEach(function (tweet) { 25 | console.log(' \033[90m' + tweet.text + '\033[39m'); 26 | console.log(' \033[94m' + tweet.from_user + '\033[39m'); 27 | console.log('--'); 28 | }); 29 | }); 30 | }).end() 31 | -------------------------------------------------------------------------------- /code-examples/introduction/index.js: -------------------------------------------------------------------------------- 1 | require('colors'); 2 | console.log('smashing node'.rainbow); 3 | 4 | -------------------------------------------------------------------------------- /code-examples/introduction/my-web-server.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | var serv = http.createServer(function (req, res) { 3 | res.writeHead(200, { 'Content-Type': 'text/html' }); 4 | res.end('Smashing Node!'); 5 | }); 6 | serv.listen(3000); 7 | 8 | -------------------------------------------------------------------------------- /code-examples/io/timeouts.js: -------------------------------------------------------------------------------- 1 | var start = Date.now(); 2 | 3 | setTimeout(function () { 4 | console.log(1000); 5 | 6 | for (var i = 0; i < 2000000000; i++){} 7 | }, 1000); 8 | 9 | setTimeout(function () { 10 | console.log(Date.now() - start); 11 | }, 2000); 12 | -------------------------------------------------------------------------------- /code-examples/io/uncaught-http.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | 3 | http.createServer(function () { 4 | throw new Error('This will be uncaught') 5 | }).listen(3000) 6 | 7 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "user-auth-example" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "express": "2.5.2" 6 | , "mongodb": "0.9.7" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "user-auth-example" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "express": "2.5.2" 6 | , "mongodb": "0.9.7" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-2/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var express = require('express') 7 | , mongodb = require('mongodb') 8 | 9 | /** 10 | * Set up application. 11 | */ 12 | 13 | app = express.createServer() 14 | 15 | /** 16 | * Middleware. 17 | */ 18 | 19 | app.use(express.bodyParser()); 20 | app.use(express.cookieParser()); 21 | app.use(express.session({ secret: 'my secret' })); 22 | 23 | /** 24 | * Specifiy our views options. 25 | */ 26 | 27 | app.set('view engine', 'jade'); 28 | 29 | /** 30 | * Default route 31 | */ 32 | 33 | app.get('/', function (req, res) { 34 | res.render('index', { authenticated: false }); 35 | }); 36 | 37 | /** 38 | * Login route 39 | */ 40 | 41 | app.get('/login', function (req, res) { 42 | res.render('login'); 43 | }); 44 | 45 | /** 46 | * Signup route 47 | */ 48 | 49 | app.get('/signup', function (req, res) { 50 | res.render('signup'); 51 | }); 52 | 53 | /** 54 | * Listen 55 | */ 56 | 57 | app.listen(3000, function () { 58 | console.log('\033[96m + \033[39m app listening on *:3000'); 59 | }); 60 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-2/views/index.jade: -------------------------------------------------------------------------------- 1 | 2 | if (authenticated) 3 | p Welcome back, #{me.name} 4 | a(href="/logout") Logout 5 | else 6 | p Welcome new visitor! 7 | ul 8 | li: a(href="/login") Login 9 | li: a(href="/signup") Signup 10 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-2/views/layout.jade: -------------------------------------------------------------------------------- 1 | doctype 5 2 | html 3 | head 4 | title MongoDB example 5 | body 6 | h1 My first MongoDB app 7 | hr 8 | != body 9 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-2/views/login.jade: -------------------------------------------------------------------------------- 1 | 2 | form(action="/login", method="POST") 3 | fieldset 4 | legend Log in 5 | p 6 | label Email 7 | input(name="user[email]", type="text") 8 | p 9 | label Password 10 | input(name="user[password]", type="password") 11 | p 12 | button Submit 13 | p 14 | a(href="/") Go back 15 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-2/views/signup.jade: -------------------------------------------------------------------------------- 1 | 2 | form(action="/signup", method="POST") 3 | fieldset 4 | legend Sign up 5 | p 6 | label First 7 | input(name="user[first]", type="text") 8 | p 9 | label Last 10 | input(name="user[last]", type="text") 11 | p 12 | label Email 13 | input(name="user[email]", type="text") 14 | p 15 | label Password 16 | input(name="user[password]", type="password") 17 | p 18 | button Submit 19 | p 20 | a(href="/") Go back 21 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "user-auth-example" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "express": "2.5.2" 6 | , "mongodb": "0.9.7" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-3/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var express = require('express') 7 | , mongodb = require('mongodb') 8 | 9 | /** 10 | * Set up application. 11 | */ 12 | 13 | app = express.createServer() 14 | 15 | /** 16 | * Middleware. 17 | */ 18 | 19 | app.use(express.bodyParser()); 20 | app.use(express.cookieParser()); 21 | app.use(express.session({ secret: 'my secret' })); 22 | 23 | /** 24 | * Specifiy our views options. 25 | */ 26 | 27 | app.set('view engine', 'jade'); 28 | 29 | /** 30 | * Default route 31 | */ 32 | 33 | app.get('/', function (req, res) { 34 | res.render('index', { authenticated: false }); 35 | }); 36 | 37 | /** 38 | * Login route 39 | */ 40 | 41 | app.get('/login', function (req, res) { 42 | res.render('login'); 43 | }); 44 | 45 | /** 46 | * Signup route 47 | */ 48 | 49 | app.get('/signup', function (req, res) { 50 | res.render('signup'); 51 | }); 52 | 53 | /** 54 | * Connect to the database. 55 | */ 56 | 57 | var server = new mongodb.Server('127.0.0.1', 27017) 58 | new mongodb.Db('my-website', server).open(function (err, client) { 59 | // don't allow our app to start if there was an error 60 | if (err) throw err; 61 | 62 | console.log('\033[96m + \033[39m connected to mongodb'); 63 | 64 | // set up collection shortcuts 65 | app.users = new mongodb.Collection(client, 'users'); 66 | 67 | // listen 68 | app.listen(3000, function () { 69 | console.log('\033[96m + \033[39m app listening on *:3000'); 70 | }); 71 | }); 72 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-3/views/index.jade: -------------------------------------------------------------------------------- 1 | 2 | if (authenticated) 3 | p Welcome back, #{me.name} 4 | a(href="/logout") Logout 5 | else 6 | p Welcome new visitor! 7 | ul 8 | li: a(href="/login") Login 9 | li: a(href="/signup") Signup 10 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-3/views/layout.jade: -------------------------------------------------------------------------------- 1 | doctype 5 2 | html 3 | head 4 | title MongoDB example 5 | body 6 | h1 My first MongoDB app 7 | hr 8 | != body 9 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-3/views/login.jade: -------------------------------------------------------------------------------- 1 | 2 | form(action="/login", method="POST") 3 | fieldset 4 | legend Log in 5 | p 6 | label Email 7 | input(name="user[email]", type="text") 8 | p 9 | label Password 10 | input(name="user[password]", type="password") 11 | p 12 | button Submit 13 | p 14 | a(href="/") Go back 15 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-3/views/signup.jade: -------------------------------------------------------------------------------- 1 | 2 | form(action="/signup", method="POST") 3 | fieldset 4 | legend Sign up 5 | p 6 | label First 7 | input(name="user[first]", type="text") 8 | p 9 | label Last 10 | input(name="user[last]", type="text") 11 | p 12 | label Email 13 | input(name="user[email]", type="text") 14 | p 15 | label Password 16 | input(name="user[password]", type="password") 17 | p 18 | button Submit 19 | p 20 | a(href="/") Go back 21 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-4/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "user-auth-example" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "express": "2.5.2" 6 | , "mongodb": "0.9.7" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-4/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var express = require('express') 7 | , mongodb = require('mongodb') 8 | 9 | /** 10 | * Set up application. 11 | */ 12 | 13 | app = express.createServer() 14 | 15 | /** 16 | * Middleware. 17 | */ 18 | 19 | app.use(express.bodyParser()); 20 | app.use(express.cookieParser()); 21 | app.use(express.session({ secret: 'my secret' })); 22 | 23 | /** 24 | * Specifiy our views options. 25 | */ 26 | 27 | app.set('view engine', 'jade'); 28 | 29 | /** 30 | * Default route 31 | */ 32 | 33 | app.get('/', function (req, res) { 34 | res.render('index', { authenticated: false }); 35 | }); 36 | 37 | /** 38 | * Login route 39 | */ 40 | 41 | app.get('/login/:signup-email', function (req, res) { 42 | res.render('login', { signupEmail: req.params.signupEmail }); 43 | }); 44 | 45 | /** 46 | * Signup route 47 | */ 48 | 49 | app.get('/signup', function (req, res) { 50 | res.render('signup'); 51 | }); 52 | 53 | /** 54 | * Signup processing route 55 | */ 56 | 57 | app.post('/signup', function (req, res, next) { 58 | app.users.insert(req.body.user, function (err, doc) { 59 | if (err) return next(err); 60 | res.redirect('/login/' + doc[0].email); 61 | }); 62 | }); 63 | 64 | /** 65 | * Connect to the database. 66 | */ 67 | 68 | var server = new mongodb.Server('127.0.0.1', 27017) 69 | new mongodb.Db('my-website', server).open(function (err, client) { 70 | // don't allow our app to start if there was an error 71 | if (err) throw err; 72 | 73 | console.log('\033[96m + \033[39m connected to mongodb'); 74 | 75 | // set up collection shortcuts 76 | app.users = new mongodb.Collection(client, 'users'); 77 | 78 | // listen 79 | app.listen(3000, function () { 80 | console.log('\033[96m + \033[39m app listening on *:3000'); 81 | }); 82 | }); 83 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-4/views/index.jade: -------------------------------------------------------------------------------- 1 | 2 | if (authenticated) 3 | p Welcome back, #{me.name} 4 | a(href="/logout") Logout 5 | else 6 | p Welcome new visitor! 7 | ul 8 | li: a(href="/login") Login 9 | li: a(href="/signup") Signup 10 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-4/views/layout.jade: -------------------------------------------------------------------------------- 1 | doctype 5 2 | html 3 | head 4 | title MongoDB example 5 | body 6 | h1 My first MongoDB app 7 | hr 8 | != body 9 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-4/views/login.jade: -------------------------------------------------------------------------------- 1 | 2 | if (signupEmail) 3 | p Congratulations on signing up! Please login below. 4 | 5 | form(action="/login", method="POST") 6 | fieldset 7 | legend Log in 8 | p 9 | label Email 10 | input(name="user[email]", type="text", value=signupEmail) 11 | p 12 | label Password 13 | input(name="user[password]", type="password") 14 | p 15 | button Submit 16 | p 17 | a(href="/") Go back 18 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-4/views/signup.jade: -------------------------------------------------------------------------------- 1 | 2 | form(action="/signup", method="POST") 3 | fieldset 4 | legend Sign up 5 | p 6 | label First 7 | input(name="user[first]", type="text") 8 | p 9 | label Last 10 | input(name="user[last]", type="text") 11 | p 12 | label Email 13 | input(name="user[email]", type="text") 14 | p 15 | label Password 16 | input(name="user[password]", type="password") 17 | p 18 | button Submit 19 | p 20 | a(href="/") Go back 21 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-5/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "user-auth-example" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "express": "2.5.2" 6 | , "mongodb": "0.9.7" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-5/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var express = require('express') 7 | , mongodb = require('mongodb') 8 | 9 | /** 10 | * Set up application. 11 | */ 12 | 13 | app = express.createServer() 14 | 15 | /** 16 | * Middleware. 17 | */ 18 | 19 | app.use(express.bodyParser()); 20 | app.use(express.cookieParser()); 21 | app.use(express.session({ secret: 'my secret' })); 22 | 23 | /** 24 | * Specifiy our views options. 25 | */ 26 | 27 | app.set('view engine', 'jade'); 28 | 29 | /** 30 | * Default route 31 | */ 32 | 33 | app.get('/', function (req, res) { 34 | res.render('index', { authenticated: false }); 35 | }); 36 | 37 | /** 38 | * Login route 39 | */ 40 | 41 | app.get('/login/:signup-email', function (req, res) { 42 | res.render('login', { signupEmail: req.params.signupEmail }); 43 | }); 44 | 45 | /** 46 | * Login process route 47 | */ 48 | 49 | app.post('/login', function (req, res) { 50 | app.users.findOne(req.body.user, function (err, doc) { 51 | if (err) return next(err); 52 | if (!doc) return res.send('

User not found. Go back and try again'); 53 | req.session.loggedIn = doc._id; 54 | res.redirect('/'); 55 | }); 56 | }); 57 | 58 | /** 59 | * Signup route 60 | */ 61 | 62 | app.get('/signup', function (req, res) { 63 | res.render('signup'); 64 | }); 65 | 66 | /** 67 | * Signup processing route 68 | */ 69 | 70 | app.post('/signup', function (req, res, next) { 71 | app.users.insert(req.body.user, function (err, doc) { 72 | if (err) return next(err); 73 | res.redirect('/login/' + doc[0].email); 74 | }); 75 | }); 76 | 77 | /** 78 | * Logout route. 79 | */ 80 | 81 | app.get('/logout', function (req, res) { 82 | req.session.loggedIn = null; 83 | res.redirect('/'); 84 | }); 85 | 86 | /** 87 | * Connect to the database. 88 | */ 89 | 90 | var server = new mongodb.Server('127.0.0.1', 27017) 91 | new mongodb.Db('my-website', server).open(function (err, client) { 92 | // don't allow our app to start if there was an error 93 | if (err) throw err; 94 | 95 | console.log('\033[96m + \033[39m connected to mongodb'); 96 | 97 | // set up collection shortcuts 98 | app.users = new mongodb.Collection(client, 'users'); 99 | 100 | client.ensureIndex('users', 'email', function (err) { 101 | if (err) throw err; 102 | client.ensureIndex('users', 'password', function (err) { 103 | if (err) throw err; 104 | 105 | console.log('\033[96m + \033[39m ensured indexes'); 106 | 107 | // listen 108 | app.listen(3000, function () { 109 | console.log('\033[96m + \033[39m app listening on *:3000'); 110 | }); 111 | }); 112 | }); 113 | }); 114 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-5/views/index.jade: -------------------------------------------------------------------------------- 1 | 2 | if (authenticated) 3 | p Welcome back, #{me.name} 4 | a(href="/logout") Logout 5 | else 6 | p Welcome new visitor! 7 | ul 8 | li: a(href="/login") Login 9 | li: a(href="/signup") Signup 10 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-5/views/layout.jade: -------------------------------------------------------------------------------- 1 | doctype 5 2 | html 3 | head 4 | title MongoDB example 5 | body 6 | h1 My first MongoDB app 7 | hr 8 | != body 9 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-5/views/login.jade: -------------------------------------------------------------------------------- 1 | 2 | if (signupEmail) 3 | p Congratulations on signing up! Please login below. 4 | 5 | form(action="/login", method="POST") 6 | fieldset 7 | legend Log in 8 | p 9 | label Email 10 | input(name="user[email]", type="text", value=signupEmail) 11 | p 12 | label Password 13 | input(name="user[password]", type="password") 14 | p 15 | button Submit 16 | p 17 | a(href="/") Go back 18 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-5/views/signup.jade: -------------------------------------------------------------------------------- 1 | 2 | form(action="/signup", method="POST") 3 | fieldset 4 | legend Sign up 5 | p 6 | label First 7 | input(name="user[first]", type="text") 8 | p 9 | label Last 10 | input(name="user[last]", type="text") 11 | p 12 | label Email 13 | input(name="user[email]", type="text") 14 | p 15 | label Password 16 | input(name="user[password]", type="password") 17 | p 18 | button Submit 19 | p 20 | a(href="/") Go back 21 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-6/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "user-auth-example" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "express": "2.5.2" 6 | , "mongodb": "0.9.9" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-6/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var express = require('express') 7 | , mongodb = require('mongodb') 8 | 9 | /** 10 | * Set up application. 11 | */ 12 | 13 | app = express.createServer() 14 | 15 | /** 16 | * Middleware. 17 | */ 18 | 19 | app.use(express.bodyParser()); 20 | app.use(express.cookieParser()); 21 | app.use(express.session({ secret: 'my secret' })); 22 | 23 | /** 24 | * Specifiy our views options. 25 | */ 26 | 27 | app.set('view engine', 'jade'); 28 | app.set('view options', { layout: false }); 29 | 30 | /** 31 | * Authentication middleware. 32 | */ 33 | 34 | app.use(function (req, res, next) { 35 | if (req.session.loggedIn) { 36 | res.local('authenticated', true); 37 | app.users.findOne({ _id: mongodb.ObjectID.createFromHexString(req.session.loggedIn) }, function (err, doc) { 38 | if (err) return next(err); 39 | res.local('me', doc); 40 | next(); 41 | }); 42 | } else { 43 | res.local('authenticated', false); 44 | next(); 45 | } 46 | }); 47 | 48 | /** 49 | * Default route 50 | */ 51 | 52 | app.get('/', function (req, res) { 53 | res.render('index'); 54 | }); 55 | 56 | /** 57 | * Login route 58 | */ 59 | 60 | app.get('/login/:signupEmail?', function (req, res) { 61 | res.render('login', { signupEmail: req.params.signupEmail }); 62 | }); 63 | 64 | /** 65 | * Login process route 66 | */ 67 | 68 | app.post('/login', function (req, res) { 69 | app.users.findOne(req.body.user, function (err, doc) { 70 | if (err) return next(err); 71 | if (!doc) return res.send('

User not found. Go back and try again'); 72 | req.session.loggedIn = doc._id.toString(); 73 | res.redirect('/'); 74 | }); 75 | }); 76 | 77 | /** 78 | * Signup route 79 | */ 80 | 81 | app.get('/signup', function (req, res) { 82 | res.render('signup'); 83 | }); 84 | 85 | /** 86 | * Signup processing route 87 | */ 88 | 89 | app.post('/signup', function (req, res, next) { 90 | app.users.insert(req.body.user, function (err, doc) { 91 | if (err) return next(err); 92 | res.redirect('/login/' + doc[0].email); 93 | }); 94 | }); 95 | 96 | /** 97 | * Logout route. 98 | */ 99 | 100 | app.get('/logout', function (req, res) { 101 | req.session.loggedIn = null; 102 | res.redirect('/'); 103 | }); 104 | 105 | /** 106 | * Connect to the database. 107 | */ 108 | 109 | var server = new mongodb.Server('127.0.0.1', 27017) 110 | new mongodb.Db('my-website', server).open(function (err, client) { 111 | // don't allow our app to start if there was an error 112 | if (err) throw err; 113 | 114 | console.log('\033[96m + \033[39m connected to mongodb'); 115 | 116 | // set up collection shortcuts 117 | app.users = new mongodb.Collection(client, 'users'); 118 | 119 | client.ensureIndex('users', 'email', function (err) { 120 | if (err) throw err; 121 | client.ensureIndex('users', 'password', function (err) { 122 | if (err) throw err; 123 | 124 | console.log('\033[96m + \033[39m ensured indexes'); 125 | 126 | // listen 127 | app.listen(3000, function () { 128 | console.log('\033[96m + \033[39m app listening on *:3000'); 129 | }); 130 | }); 131 | }); 132 | }); 133 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-6/views/index.jade: -------------------------------------------------------------------------------- 1 | 2 | extends layout 3 | block body 4 | if (authenticated) 5 | p Welcome back, #{me.first} 6 | a(href="/logout") Logout 7 | else 8 | p Welcome new visitor! 9 | ul 10 | li: a(href="/login") Login 11 | li: a(href="/signup") Signup 12 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-6/views/layout.jade: -------------------------------------------------------------------------------- 1 | doctype 5 2 | html 3 | head 4 | title MongoDB example 5 | body 6 | h1 My first MongoDB app 7 | hr 8 | block body 9 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-6/views/login.jade: -------------------------------------------------------------------------------- 1 | 2 | extends layout 3 | block body 4 | if (signupEmail) 5 | p Congratulations on signing up! Please login below. 6 | 7 | form(action="/login", method="POST") 8 | fieldset 9 | legend Log in 10 | p 11 | label Email 12 | input(name="user[email]", type="text", value=signupEmail) 13 | p 14 | label Password 15 | input(name="user[password]", type="password") 16 | p 17 | button Submit 18 | p 19 | a(href="/") Go back 20 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-6/views/signup.jade: -------------------------------------------------------------------------------- 1 | 2 | extends layout 3 | block body 4 | form(action="/signup", method="POST") 5 | fieldset 6 | legend Sign up 7 | p 8 | label First 9 | input(name="user[first]", type="text") 10 | p 11 | label Last 12 | input(name="user[last]", type="text") 13 | p 14 | label Email 15 | input(name="user[email]", type="text") 16 | p 17 | label Password 18 | input(name="user[password]", type="password") 19 | p 20 | button Submit 21 | p 22 | a(href="/") Go back 23 | -------------------------------------------------------------------------------- /code-examples/mongodb/blog/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mongoose-example" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "express": "2.5.2" 6 | , "mongoose": "2.5.10" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /code-examples/mongodb/blog/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var express = require('express') 7 | , mongoose = require('mongoose') 8 | 9 | /** 10 | * Set up application. 11 | */ 12 | 13 | app = express.createServer() 14 | 15 | /** 16 | * Middleware. 17 | */ 18 | 19 | app.use(express.bodyParser()); 20 | app.use(express.cookieParser()); 21 | app.use(express.session({ secret: 'my secret' })); 22 | 23 | /** 24 | * Specifiy our views options. 25 | */ 26 | 27 | app.set('view engine', 'jade'); 28 | app.set('view options', { layout: false }); 29 | 30 | /** 31 | * Authentication middleware. 32 | */ 33 | 34 | app.use(function (req, res, next) { 35 | if (req.session.loggedIn) { 36 | res.local('authenticated', true); 37 | User.findById(req.session.loggedIn, function (err, doc) { 38 | if (err) return next(err); 39 | res.local('me', doc); 40 | next(); 41 | }); 42 | } else { 43 | res.local('authenticated', false); 44 | next(); 45 | } 46 | }); 47 | 48 | /** 49 | * Default route 50 | */ 51 | 52 | app.get('/', function (req, res) { 53 | res.render('index'); 54 | }); 55 | 56 | /** 57 | * Login route 58 | */ 59 | 60 | app.get('/login/:signupEmail?', function (req, res) { 61 | res.render('login', { signupEmail: req.params.signupEmail }); 62 | }); 63 | 64 | /** 65 | * Login process route 66 | */ 67 | 68 | app.post('/login', function (req, res) { 69 | User.findOne({ email: req.body.user.email, password: req.body.user.password }, function (err, doc) { 70 | if (err) return next(err); 71 | if (!doc) return res.send('

User not found. Go back and try again'); 72 | req.session.loggedIn = doc._id.toString(); 73 | res.redirect('/'); 74 | }); 75 | }); 76 | 77 | /** 78 | * Signup route 79 | */ 80 | 81 | app.get('/signup', function (req, res) { 82 | res.render('signup'); 83 | }); 84 | 85 | /** 86 | * Signup processing route 87 | */ 88 | 89 | app.post('/signup', function (req, res, next) { 90 | var user = new User(req.body.user); 91 | user.save(function (err) { 92 | if (err) return next(err); 93 | res.redirect('/login/' + user.email); 94 | }); 95 | }); 96 | 97 | /** 98 | * Logout route. 99 | */ 100 | 101 | app.get('/logout', function (req, res) { 102 | req.session.loggedIn = null; 103 | res.redirect('/'); 104 | }); 105 | 106 | /** 107 | * Connect to the database. 108 | */ 109 | 110 | mongoose.connect('mongodb://127.0.0.1/my-website'); 111 | app.listen(3000, function () { 112 | console.log('\033[96m + \033[39m app listening on *:3000'); 113 | }); 114 | 115 | /** 116 | * Define model. 117 | */ 118 | 119 | var Schema = mongoose.Schema 120 | 121 | var User = mongoose.model('User', new Schema({ 122 | first: String 123 | , last: String 124 | , email: { type: String, unique: true } 125 | , password: { type: String, index: true } 126 | })); 127 | -------------------------------------------------------------------------------- /code-examples/mongodb/blog/step-final/blogpost.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var mongoose = require('mongoose') 7 | , Schema = mongoose.Schema 8 | 9 | /** 10 | * Module exports. 11 | */ 12 | 13 | var BlogPost = module.exports = new Schema({ 14 | 15 | 16 | }); 17 | -------------------------------------------------------------------------------- /code-examples/mongodb/blog/step-final/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mongoose-blog" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "express": "2.5.2" 6 | , "mongoose": "2.5.10" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /code-examples/mongodb/blog/step-final/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var express = require('express') 7 | , mongoose = require('mongoose') 8 | 9 | /** 10 | * Create app 11 | */ 12 | 13 | app = require('express').createServer(); 14 | 15 | /** 16 | * Connect to mongoose 17 | */ 18 | 19 | mongoose.connect('mongodb://localhost/my-blog'); 20 | 21 | /** 22 | * Define our model. 23 | */ 24 | 25 | var BlogPost = mongoose.model('BlogPost', require('./blogpost')); 26 | -------------------------------------------------------------------------------- /code-examples/mongodb/blog/views/index.jade: -------------------------------------------------------------------------------- 1 | 2 | extends layout 3 | block body 4 | if (authenticated) 5 | p Welcome back, #{me.first} 6 | a(href="/logout") Logout 7 | else 8 | p Welcome new visitor! 9 | ul 10 | li: a(href="/login") Login 11 | li: a(href="/signup") Signup 12 | -------------------------------------------------------------------------------- /code-examples/mongodb/blog/views/layout.jade: -------------------------------------------------------------------------------- 1 | doctype 5 2 | html 3 | head 4 | title MongoDB example 5 | body 6 | h1 My first MongoDB app 7 | hr 8 | block body 9 | -------------------------------------------------------------------------------- /code-examples/mongodb/blog/views/login.jade: -------------------------------------------------------------------------------- 1 | 2 | extends layout 3 | block body 4 | if (signupEmail) 5 | p Congratulations on signing up! Please login below. 6 | 7 | form(action="/login", method="POST") 8 | fieldset 9 | legend Log in 10 | p 11 | label Email 12 | input(name="user[email]", type="text", value=signupEmail) 13 | p 14 | label Password 15 | input(name="user[password]", type="password") 16 | p 17 | button Submit 18 | p 19 | a(href="/") Go back 20 | -------------------------------------------------------------------------------- /code-examples/mongodb/blog/views/signup.jade: -------------------------------------------------------------------------------- 1 | 2 | extends layout 3 | block body 4 | form(action="/signup", method="POST") 5 | fieldset 6 | legend Sign up 7 | p 8 | label First 9 | input(name="user[first]", type="text") 10 | p 11 | label Last 12 | input(name="user[last]", type="text") 13 | p 14 | label Email 15 | input(name="user[email]", type="text") 16 | p 17 | label Password 18 | input(name="user[password]", type="password") 19 | p 20 | button Submit 21 | p 22 | a(href="/") Go back 23 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shopping-cart-example" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "express": "2.5.2" 6 | , "jade": "0.19.0" 7 | , "node-mysql": "0.9.5" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shopping-cart-example" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "express": "2.5.2" 6 | , "jade": "0.19.0" 7 | , "node-mysql": "0.9.5" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-2/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var express = require('express') 7 | 8 | /** 9 | * Create app. 10 | */ 11 | 12 | app = express.createServer(); 13 | 14 | /** 15 | * Configure app. 16 | */ 17 | 18 | app.set('view engine', 'jade'); 19 | app.set('views', __dirname + '/views'); 20 | 21 | /** 22 | * Main route 23 | */ 24 | 25 | app.get('/', function (req, res, next) { 26 | res.render('index'); 27 | }); 28 | 29 | /** 30 | * Item creation route. 31 | */ 32 | 33 | app.post('/create', function (req, res, next) { 34 | }); 35 | 36 | /** 37 | * Item route. 38 | */ 39 | 40 | app.get('/item/:id', function (req, res, next) { 41 | res.render('item'); 42 | }); 43 | 44 | /** 45 | * Item review creation route. 46 | */ 47 | 48 | app.post('/item/:id/review', function (req, res, next) { 49 | }); 50 | 51 | /** 52 | * Listen. 53 | */ 54 | 55 | app.listen(3000, function () { 56 | console.log(' - listening on http://*:3000'); 57 | }); 58 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shopping-cart-example" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "express": "2.5.2" 6 | , "jade": "0.19.0" 7 | , "node-mysql": "0.9.5" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-3/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var express = require('express') 7 | , mysql = require('mysql') 8 | 9 | /** 10 | * Create app. 11 | */ 12 | 13 | app = express.createServer(); 14 | 15 | /** 16 | * Configure app. 17 | */ 18 | 19 | app.set('view engine', 'jade'); 20 | app.set('views', __dirname + '/views'); 21 | 22 | /** 23 | * Main route 24 | */ 25 | 26 | app.get('/', function (req, res, next) { 27 | res.render('index'); 28 | }); 29 | 30 | /** 31 | * Item creation route. 32 | */ 33 | 34 | app.post('/create', function (req, res, next) { 35 | }); 36 | 37 | /** 38 | * Item route. 39 | */ 40 | 41 | app.get('/item/:id', function (req, res, next) { 42 | res.render('item'); 43 | }); 44 | 45 | /** 46 | * Item review creation route. 47 | */ 48 | 49 | app.post('/item/:id/review', function (req, res, next) { 50 | }); 51 | 52 | /** 53 | * Connect to MySQL 54 | */ 55 | 56 | var db = mysql.createClient({ 57 | host: 'localhost' 58 | , database: 'cart-example' 59 | }); 60 | 61 | /** 62 | * Listen. 63 | */ 64 | 65 | app.listen(3000, function () { 66 | console.log(' - listening on http://*:3000'); 67 | }); 68 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-4/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "host": "localhost" 3 | , "database": "cart-example" 4 | } 5 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-4/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shopping-cart-example" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "express": "2.5.2" 6 | , "jade": "0.19.0" 7 | , "node-mysql": "0.9.5" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-4/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var express = require('express') 7 | , mysql = require('mysql') 8 | , config = require('./config') 9 | 10 | /** 11 | * Create app. 12 | */ 13 | 14 | app = express.createServer(); 15 | 16 | /** 17 | * Configure app. 18 | */ 19 | 20 | app.set('view engine', 'jade'); 21 | app.set('views', __dirname + '/views'); 22 | 23 | /** 24 | * Main route 25 | */ 26 | 27 | app.get('/', function (req, res, next) { 28 | res.render('index'); 29 | }); 30 | 31 | /** 32 | * Item creation route. 33 | */ 34 | 35 | app.post('/create', function (req, res, next) { 36 | }); 37 | 38 | /** 39 | * Item route. 40 | */ 41 | 42 | app.get('/item/:id', function (req, res, next) { 43 | res.render('item'); 44 | }); 45 | 46 | /** 47 | * Item review creation route. 48 | */ 49 | 50 | app.post('/item/:id/review', function (req, res, next) { 51 | }); 52 | 53 | /** 54 | * Connect to MySQL 55 | */ 56 | 57 | var db = mysql.createClient(config); 58 | 59 | /** 60 | * Listen. 61 | */ 62 | 63 | app.listen(3000, function () { 64 | console.log(' - listening on http://*:3000'); 65 | }); 66 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-4/setup.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var mysql = require('mysql') 7 | , config = require('./config') 8 | 9 | /** 10 | * Initialize client. 11 | */ 12 | 13 | var db = mysql.createClient(config); 14 | 15 | /** 16 | * Create database. 17 | */ 18 | 19 | db.query('CREATE DATABASE cart-example'); 20 | 21 | /** 22 | * Create tables. 23 | */ 24 | 25 | db.query('CREATE TABLE item (' + 26 | 'id INT(11) AUTO_INCREMENT,' + 27 | 'title VARCHAR(255),' + 28 | 'description TEXT,' + 29 | 'created DATETIME,' + 30 | 'PRIMARY KEY (id))'); 31 | 32 | db.query('CREATE TABLE review (' + 33 | 'id INT(11) AUTO_INCREMENT,' + 34 | 'item_id INT(11),' + 35 | 'text TEXT,' + 36 | 'stars INT(1),' + 37 | 'created DATETIME,' + 38 | 'PRIMARY KEY (id))'); 39 | 40 | /** 41 | * Close client. 42 | */ 43 | 44 | db.end(); 45 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-5/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "host": "localhost" 3 | , "database": "cart-example" 4 | } 5 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-5/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shopping-cart-example" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "express": "2.5.2" 6 | , "jade": "0.19.0" 7 | , "mysql": "0.9.5" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-5/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var express = require('express') 7 | , mysql = require('mysql') 8 | , config = require('./config') 9 | 10 | /** 11 | * Create app. 12 | */ 13 | 14 | app = express.createServer(); 15 | 16 | /** 17 | * Middleware. 18 | */ 19 | 20 | app.use(express.bodyParser()); 21 | 22 | /** 23 | * Configure app. 24 | */ 25 | 26 | app.set('view engine', 'jade'); 27 | app.set('views', __dirname + '/views'); 28 | 29 | /** 30 | * Main route 31 | */ 32 | 33 | app.get('/', function (req, res, next) { 34 | res.render('index', { items: [] }); 35 | }); 36 | 37 | /** 38 | * Item creation route. 39 | */ 40 | 41 | app.post('/create', function (req, res, next) { 42 | db.query('INSERT INTO item SET title = ?, description = ?', 43 | [req.body.title, req.body.description], function (err, info) { 44 | if (err) return next(err); 45 | console.log(' - item created with id %s', info.insertId); 46 | res.redirect('/'); 47 | }); 48 | }); 49 | 50 | /** 51 | * Item route. 52 | */ 53 | 54 | app.get('/item/:id', function (req, res, next) { 55 | res.render('item'); 56 | }); 57 | 58 | /** 59 | * Item review creation route. 60 | */ 61 | 62 | app.post('/item/:id/review', function (req, res, next) { 63 | db.query('INSERT INTO review SET item_id = ?, stars = ?, text = ?', 64 | [req.params.id, req.body.stars, req.body.text], function (err, info) { 65 | if (err) return next(err); 66 | console.log(' - review created with id %s', info.insertId); 67 | res.redirect('/item/' + req.params.id); 68 | }); 69 | }); 70 | 71 | /** 72 | * Connect to MySQL 73 | */ 74 | 75 | var db = mysql.createClient(config); 76 | 77 | /** 78 | * Listen. 79 | */ 80 | 81 | app.listen(3000, function () { 82 | console.log(' - listening on http://*:3000'); 83 | }); 84 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-5/setup.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var mysql = require('mysql') 7 | , config = require('./config') 8 | 9 | /** 10 | * Initialize client. 11 | */ 12 | 13 | var db = mysql.createClient(config); 14 | 15 | /** 16 | * Create database. 17 | */ 18 | 19 | db.query('CREATE DATABASE cart-example'); 20 | 21 | /** 22 | * Create tables. 23 | */ 24 | 25 | db.query('CREATE TABLE item (' + 26 | 'id INT(11) AUTO_INCREMENT,' + 27 | 'title VARCHAR(255),' + 28 | 'description TEXT,' + 29 | 'created DATETIME,' + 30 | 'PRIMARY KEY (id))'); 31 | 32 | db.query('CREATE TABLE review (' + 33 | 'id INT(11) AUTO_INCREMENT,' + 34 | 'item_id INT(11),' + 35 | 'text TEXT,' + 36 | 'stars INT(1),' + 37 | 'created DATETIME,' + 38 | 'PRIMARY KEY (id))'); 39 | 40 | /** 41 | * Close client. 42 | */ 43 | 44 | db.end(); 45 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-5/views/index.jade: -------------------------------------------------------------------------------- 1 | 2 | h2 All items 3 | 4 | if (items.length) 5 | ul 6 | each item in items 7 | li 8 | h3: a(href="/item/#{item.id}")= item.title 9 | = item.description 10 | else 11 | p No items to show 12 | 13 | h2 Create new item 14 | 15 | form(action="/create", method="POST") 16 | p 17 | label Title 18 | input(type="text", name="title") 19 | p 20 | label Description 21 | textarea(name="description") 22 | p 23 | button Submit 24 | 25 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-5/views/item.jade: -------------------------------------------------------------------------------- 1 | 2 | extends layout 3 | 4 | block body 5 | a(href="/") Go back 6 | 7 | h2= item.title 8 | p= item.description 9 | 10 | h3 User reviews 11 | 12 | if (reviews.length) 13 | each review in reviews 14 | .review 15 | b #{review.stars} stars 16 | p= review.text 17 | hr 18 | else 19 | p No reviews to show. Write one! 20 | 21 | h4 Create review 22 | form(action="/item/#{item.id}/review", method="POST") 23 | p 24 | label Stars 25 | select 26 | option 1 27 | option 2 28 | option 3 29 | option 4 30 | option 5 31 | p 32 | label Review 33 | textarea(name="text") 34 | p 35 | submit Send 36 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-5/views/layout.jade: -------------------------------------------------------------------------------- 1 | doctype 5 2 | html 3 | head 4 | title My shopping cart 5 | body 6 | h1 My shopping cart 7 | #cart!= body 8 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-6/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "host": "localhost" 3 | , "database": "cart-example" 4 | } 5 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-6/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shopping-cart-example" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "express": "2.5.9" 6 | , "jade": "0.19.0" 7 | , "mysql": "0.9.5" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-6/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var express = require('express') 7 | , mysql = require('mysql') 8 | , config = require('./config') 9 | 10 | /** 11 | * Create app. 12 | */ 13 | 14 | app = express.createServer(); 15 | 16 | /** 17 | * Middleware. 18 | */ 19 | 20 | app.use(express.bodyParser()); 21 | 22 | /** 23 | * Configure app. 24 | */ 25 | 26 | app.set('view engine', 'jade'); 27 | app.set('views', __dirname + '/views'); 28 | 29 | /** 30 | * Main route 31 | */ 32 | 33 | app.get('/', function (req, res, next) { 34 | db.query('SELECT id, title, description FROM item', function (err, results) { 35 | res.render('index', { items: results }); 36 | }); 37 | }); 38 | 39 | /** 40 | * Item creation route. 41 | */ 42 | 43 | app.post('/create', function (req, res, next) { 44 | db.query('INSERT INTO item SET title = ?, description = ?', 45 | [req.body.title, req.body.description], function (err, info) { 46 | if (err) return next(err); 47 | console.log(' - item created with id %s', info.insertId); 48 | res.redirect('/'); 49 | }); 50 | }); 51 | 52 | /** 53 | * Item route. 54 | */ 55 | 56 | app.get('/item/:id', function (req, res, next) { 57 | function getItem () { 58 | db.query('SELECT id, title, description FROM item WHERE id = ? LIMIT 1', 59 | [req.params.id], function (err, results) { 60 | if (err) return next(err); 61 | var item = results[0]; 62 | if (!item) return res.send(404); 63 | fn({ id: item[0], title: item[1], description: item[2] }); 64 | }); 65 | } 66 | 67 | function getReviews (item_id) { 68 | db.query('SELECT text, stars FROM review WHERE item_id = ?', 69 | [item_id], function (err, results) { 70 | if (err) return next(err); 71 | fn(results.map(function (res) { 72 | return { text: res[0], stars: res[1] }; 73 | })); 74 | }); 75 | } 76 | 77 | getItem(function (item) { 78 | getReviews(item.id, function (reviews) { 79 | res.render('item', { item: item, reviews: reviews }); 80 | }); 81 | }); 82 | }); 83 | 84 | /** 85 | * Item review creation route. 86 | */ 87 | 88 | app.post('/item/:id/review', function (req, res, next) { 89 | db.query('INSERT INTO review SET item_id = ?, stars = ?, text = ?', 90 | [req.params.id, req.body.stars, req.body.text], function (err, info) { 91 | if (err) return next(err); 92 | console.log(' - review created with id %s', info.insertId); 93 | res.redirect('/item/' + req.params.id); 94 | }); 95 | }); 96 | 97 | /** 98 | * Connect to MySQL 99 | */ 100 | 101 | var db = mysql.createClient(config); 102 | 103 | /** 104 | * Listen. 105 | */ 106 | 107 | app.listen(3000, function () { 108 | console.log(' - listening on http://*:3000'); 109 | }); 110 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-6/setup.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var mysql = require('mysql') 7 | , config = require('./config') 8 | 9 | /** 10 | * Initialize client. 11 | */ 12 | 13 | var db = mysql.createClient(config); 14 | 15 | /** 16 | * Create database. 17 | */ 18 | 19 | db.query('CREATE DATABASE IF NOT EXISTS `cart-example`'); 20 | db.query('USE `cart-example`'); 21 | 22 | /** 23 | * Create tables. 24 | */ 25 | 26 | db.query('DROP TABLE IF EXISTS item'); 27 | db.query('CREATE TABLE item (' + 28 | 'id INT(11) AUTO_INCREMENT,' + 29 | 'title VARCHAR(255),' + 30 | 'description TEXT,' + 31 | 'created DATETIME,' + 32 | 'PRIMARY KEY (id))'); 33 | 34 | db.query('DROP TABLE IF EXISTS review'); 35 | db.query('CREATE TABLE review (' + 36 | 'id INT(11) AUTO_INCREMENT,' + 37 | 'item_id INT(11),' + 38 | 'text TEXT,' + 39 | 'stars INT(1),' + 40 | 'created DATETIME,' + 41 | 'PRIMARY KEY (id))'); 42 | 43 | /** 44 | * Close client. 45 | */ 46 | 47 | db.end(); 48 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-6/views/index.jade: -------------------------------------------------------------------------------- 1 | 2 | h2 All items 3 | 4 | if (items.length) 5 | ul 6 | each item in items 7 | li 8 | h3: a(href="/item/#{item.id}")= item.title 9 | = item.description 10 | else 11 | p No items to show 12 | 13 | h2 Create new item 14 | 15 | form(action="/create", method="POST") 16 | p 17 | label Title 18 | input(type="text", name="title") 19 | p 20 | label Description 21 | textarea(name="description") 22 | p 23 | button Submit 24 | 25 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-6/views/item.jade: -------------------------------------------------------------------------------- 1 | 2 | a(href="/") Go back 3 | 4 | h2= item.title 5 | p= item.description 6 | 7 | h3 User reviews 8 | 9 | if (reviews.length) 10 | each review in reviews 11 | .review 12 | b #{review.stars} stars 13 | p= review.text 14 | hr 15 | else 16 | p No reviews to show. Write one! 17 | 18 | h4 Create review 19 | form(action="/item/#{item.id}/review", method="POST") 20 | p 21 | label Stars 22 | select 23 | option 1 24 | option 2 25 | option 3 26 | option 4 27 | option 5 28 | p 29 | label Review 30 | textarea(name="text") 31 | p 32 | submit Send 33 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-6/views/layout.jade: -------------------------------------------------------------------------------- 1 | doctype 5 2 | html 3 | head 4 | title My shopping cart 5 | body 6 | h1 My shopping cart 7 | #cart!= body 8 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "todo-list-example" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "express": "2.5.2" 6 | , "jade": "0.19.0" 7 | , "sequelize": "1.2.1" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "todo-list-example" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "express": "2.5.2" 6 | , "jade": "0.19.0" 7 | , "sequelize": "1.2.1" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-2/public/js/main.js: -------------------------------------------------------------------------------- 1 | 2 | $(function () { 3 | 4 | }); 5 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-2/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var express = require('express') 7 | 8 | /** 9 | * Create app. 10 | */ 11 | 12 | app = express.createServer(); 13 | 14 | /** 15 | * Configure app. 16 | */ 17 | 18 | app.set('view engine', 'jade'); 19 | app.set('views', __dirname + '/views'); 20 | app.set('view options', { layout: false }); 21 | 22 | /** 23 | * Main route 24 | */ 25 | 26 | app.get('/', function (req, res, next) { 27 | res.render('index'); 28 | }); 29 | 30 | /** 31 | * Project deletion route. 32 | */ 33 | 34 | app.del('/project/:id', function (req, res, next) { 35 | }); 36 | 37 | /** 38 | * Project creation route. 39 | */ 40 | 41 | app.post('/projects', function (req, res, next) { 42 | }); 43 | 44 | /** 45 | * Show tasks for project. 46 | */ 47 | 48 | app.get('/project/:id/items', function (req, res, next) { 49 | }); 50 | 51 | /** 52 | * Add tassk for project. 53 | */ 54 | 55 | app.post('/project/:id/items', function (req, res, next) { 56 | }); 57 | 58 | /** 59 | * Item route. 60 | */ 61 | 62 | app.del('/item/:id', function (req, res, next) { 63 | }); 64 | /** 65 | * Listen. 66 | */ 67 | 68 | app.listen(3000, function () { 69 | console.log(' - listening on http://*:3000'); 70 | }); 71 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-2/views/index.jade: -------------------------------------------------------------------------------- 1 | 2 | h2 Projects 3 | 4 | #list 5 | ul#projects-list 6 | each project in projects 7 | li 8 | a(href="/project/#{project.id}")= project.title 9 | a.delete(href="/project/:id") x 10 | 11 | form#add(action="/projects", method="POST") 12 | input(type="text", name="item") 13 | button Add 14 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-2/views/layout.jade: -------------------------------------------------------------------------------- 1 | doctype 5 2 | html 3 | head 4 | title TODO list app 5 | script(src="http://code.jquery.com/jquery-1.6.1.js") 6 | script(src="/js/main.js") 7 | body 8 | h1 TODO list app 9 | #todo= body 10 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-2/views/tasks.jade: -------------------------------------------------------------------------------- 1 | 2 | 3 | h2 Tasks for project #{project.title} 4 | 5 | #list 6 | ul#tasks-list 7 | each task in tasks 8 | li 9 | span= task.title 10 | a.delete(href="/task/:id") x 11 | 12 | form#add(action="/project/#{project.id}/tasks", method="POST") 13 | input(type="text", name="item") 14 | button Add 15 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "todo-list-example" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "express": "2.5.2" 6 | , "jade": "0.19.0" 7 | , "sequelize": "1.2.1" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-3/public/js/main.js: -------------------------------------------------------------------------------- 1 | 2 | $(function () { 3 | 4 | }); 5 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-3/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var express = require('express') 7 | , Sequelize = require('sequelize') 8 | 9 | /** 10 | * Create app. 11 | */ 12 | 13 | app = express.createServer(); 14 | 15 | /** 16 | * Instantiate sequelize. 17 | */ 18 | 19 | var sequelize = new Sequelize('todo-example') 20 | 21 | /** 22 | * Configure app. 23 | */ 24 | 25 | app.set('view engine', 'jade'); 26 | app.set('views', __dirname + '/views'); 27 | 28 | /** 29 | * Main route 30 | */ 31 | 32 | app.get('/', function (req, res, next) { 33 | res.render('index'); 34 | }); 35 | 36 | /** 37 | * Project deletion route. 38 | */ 39 | 40 | app.del('/project/:id', function (req, res, next) { 41 | }); 42 | 43 | /** 44 | * Project creation route. 45 | */ 46 | 47 | app.post('/projects', function (req, res, next) { 48 | }); 49 | 50 | /** 51 | * Show tasks for project. 52 | */ 53 | 54 | app.get('/project/:id/items', function (req, res, next) { 55 | }); 56 | 57 | /** 58 | * Add tassk for project. 59 | */ 60 | 61 | app.post('/project/:id/items', function (req, res, next) { 62 | }); 63 | 64 | /** 65 | * Item route. 66 | */ 67 | 68 | app.del('/item/:id', function (req, res, next) { 69 | }); 70 | /** 71 | * Listen. 72 | */ 73 | 74 | app.listen(3000, function () { 75 | console.log(' - listening on http://*:3000'); 76 | }); 77 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-3/views/index.jade: -------------------------------------------------------------------------------- 1 | 2 | h2 Projects 3 | 4 | #list 5 | ul#projects-list 6 | each project in projects 7 | li 8 | a(href="/project/#{project.id}")= project.title 9 | a.delete(href="/project/:id") x 10 | 11 | form#add(action="/projects", method="POST") 12 | input(type="text", name="item") 13 | button Add 14 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-3/views/layout.jade: -------------------------------------------------------------------------------- 1 | doctype 5 2 | html 3 | head 4 | title TODO list app 5 | script(src="http://code.jquery.com/jquery-1.6.1.js") 6 | script(src="/js/main.js") 7 | body 8 | h1 TODO list app 9 | #todo= body 10 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-3/views/tasks.jade: -------------------------------------------------------------------------------- 1 | 2 | 3 | h2 Tasks for project #{project.title} 4 | 5 | #list 6 | ul#tasks-list 7 | each task in tasks 8 | li 9 | span= task.title 10 | a.delete(href="/task/:id") x 11 | 12 | form#add(action="/project/#{project.id}/tasks", method="POST") 13 | input(type="text", name="item") 14 | button Add 15 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-4/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "todo-list-example" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "express": "2.5.2" 6 | , "jade": "0.19.0" 7 | , "sequelize": "1.2.1" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-4/public/js/main.js: -------------------------------------------------------------------------------- 1 | 2 | $(function () { 3 | 4 | }); 5 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-4/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var express = require('express') 7 | , Sequelize = require('sequelize') 8 | 9 | /** 10 | * Create app. 11 | */ 12 | 13 | app = express.createServer(); 14 | 15 | /** 16 | * Instantiate sequelize. 17 | */ 18 | 19 | var sequelize = new Sequelize('todo-example') 20 | 21 | /** 22 | * Define project model. 23 | */ 24 | 25 | var Project = sequelize.define('Project', { 26 | title: sequelize.STRING 27 | , description: sequelize.TEXT 28 | , created: sequelize.DATE 29 | }); 30 | 31 | /** 32 | * Define task model. 33 | */ 34 | 35 | var Task = sequelize.define('Task', { 36 | title: sequelize.STRING 37 | }); 38 | 39 | /** 40 | * Set up association. 41 | */ 42 | 43 | Task.belongsTo(Project); 44 | 45 | /** 46 | * Synchronize. 47 | */ 48 | 49 | sequelize.sync({ force: 'production' != process.env.NODE_ENV }); 50 | 51 | /** 52 | * Configure app. 53 | */ 54 | 55 | app.set('view engine', 'jade'); 56 | app.set('views', __dirname + '/views'); 57 | 58 | /** 59 | * Main route 60 | */ 61 | 62 | app.get('/', function (req, res, next) { 63 | res.render('index'); 64 | }); 65 | 66 | /** 67 | * Project deletion route. 68 | */ 69 | 70 | app.del('/project/:id', function (req, res, next) { 71 | }); 72 | 73 | /** 74 | * Project creation route. 75 | */ 76 | 77 | app.post('/projects', function (req, res, next) { 78 | }); 79 | 80 | /** 81 | * Show tasks for project. 82 | */ 83 | 84 | app.get('/project/:id/items', function (req, res, next) { 85 | }); 86 | 87 | /** 88 | * Add tassk for project. 89 | */ 90 | 91 | app.post('/project/:id/items', function (req, res, next) { 92 | }); 93 | 94 | /** 95 | * Item route. 96 | */ 97 | 98 | app.del('/item/:id', function (req, res, next) { 99 | }); 100 | /** 101 | * Listen. 102 | */ 103 | 104 | app.listen(3000, function () { 105 | console.log(' - listening on http://*:3000'); 106 | }); 107 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-4/views/index.jade: -------------------------------------------------------------------------------- 1 | 2 | h2 Projects 3 | 4 | #list 5 | ul#projects-list 6 | each project in projects 7 | li 8 | a(href="/project/#{project.id}")= project.title 9 | a.delete(href="/project/:id") x 10 | 11 | form#add(action="/projects", method="POST") 12 | input(type="text", name="item") 13 | button Add 14 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-4/views/layout.jade: -------------------------------------------------------------------------------- 1 | doctype 5 2 | html 3 | head 4 | title TODO list app 5 | script(src="http://code.jquery.com/jquery-1.6.1.js") 6 | script(src="/js/main.js") 7 | body 8 | h1 TODO list app 9 | #todo= body 10 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-4/views/tasks.jade: -------------------------------------------------------------------------------- 1 | 2 | 3 | h2 Tasks for project #{project.title} 4 | 5 | #list 6 | ul#tasks-list 7 | each task in tasks 8 | li 9 | span= task.title 10 | a.delete(href="/task/:id") x 11 | 12 | form#add(action="/project/#{project.id}/tasks", method="POST") 13 | input(type="text", name="item") 14 | button Add 15 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-5/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "todo-list-example" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "express": "2.5.2" 6 | , "jade": "0.19.0" 7 | , "sequelize": "1.3.7" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-5/public/js/main.js: -------------------------------------------------------------------------------- 1 | 2 | $(function () { 3 | $('form').submit(function (ev) { 4 | ev.preventDefault(); 5 | var form = $(this); 6 | $.ajax({ 7 | url: form.attr('action') 8 | , type: 'POST' 9 | , data: form.serialize() 10 | , success: function (obj) { 11 | var el = $('

  • '); 12 | if ($('#projects-list').length) { 13 | el 14 | .append($('').attr('href', '/project/' + obj.id 15 | + '/tasks').text(obj.title + ' ')) 16 | .append($('').attr('href', '/project/' + obj.id) 17 | .attr('class', 'delete').text('x')); 18 | } else { 19 | el 20 | .append($('').text(obj.title + ' ')) 21 | .append($('').attr('href', '/task/' + obj.id) 22 | .attr('class', 'delete').text('x')); 23 | } 24 | $('ul').append(el); 25 | } 26 | }); 27 | form.find('input').val(''); // clear the input 28 | }); 29 | 30 | $('ul').delegate('a.delete', 'click', function (ev) { 31 | ev.preventDefault(); 32 | var li = $(this).closest('li'); 33 | $.ajax({ 34 | url: $(this).attr('href') 35 | , type: 'DELETE' 36 | , success: function () { 37 | li.remove(); 38 | } 39 | }); 40 | }); 41 | }); 42 | 43 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-5/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var express = require('express') 7 | , Sequelize = require('sequelize') 8 | 9 | /** 10 | * Create app. 11 | */ 12 | 13 | app = express.createServer(); 14 | 15 | /** 16 | * Instantiate sequelize. 17 | */ 18 | 19 | var sequelize = new Sequelize('todo-example', 'root') 20 | 21 | /** 22 | * Define project model. 23 | */ 24 | 25 | var Project = sequelize.define('Project', { 26 | title: Sequelize.STRING 27 | , description: Sequelize.TEXT 28 | , created: Sequelize.DATE 29 | }); 30 | 31 | /** 32 | * Define task model. 33 | */ 34 | 35 | var Task = sequelize.define('Task', { 36 | title: Sequelize.STRING 37 | }); 38 | 39 | /** 40 | * Set up association. 41 | */ 42 | 43 | Task.belongsTo(Project); 44 | Project.hasMany(Task); 45 | 46 | /** 47 | * Synchronize. 48 | */ 49 | 50 | sequelize.sync(); 51 | 52 | /** 53 | * Configure app. 54 | */ 55 | 56 | app.set('view engine', 'jade'); 57 | app.set('view options', { layout: false }); 58 | app.set('views', __dirname + '/views'); 59 | 60 | /** 61 | * Middleware 62 | */ 63 | 64 | app.use(express.static(__dirname + '/public')); 65 | app.use(express.bodyParser()); 66 | 67 | /** 68 | * Main route 69 | */ 70 | 71 | app.get('/', function (req, res, next) { 72 | Project.findAll() 73 | .success(function (projects) { 74 | res.render('index', { projects: projects }); 75 | }) 76 | .error(next); 77 | }); 78 | 79 | /** 80 | * Project deletion route. 81 | */ 82 | 83 | app.del('/project/:id', function (req, res, next) { 84 | Project.find(Number(req.params.id)).success(function (proj) { 85 | proj.destroy() 86 | .success(function () { 87 | res.send(200); 88 | }) 89 | .error(next); 90 | }).error(next); 91 | }); 92 | 93 | /** 94 | * Project creation route. 95 | */ 96 | 97 | app.post('/projects', function (req, res, next) { 98 | Project.build(req.body).save() 99 | .success(function (obj) { 100 | res.send(obj.values); 101 | }) 102 | .error(next) 103 | }); 104 | 105 | /** 106 | * Show tasks for project. 107 | */ 108 | 109 | app.get('/project/:id/tasks', function (req, res, next) { 110 | Project.find(Number(req.params.id)) 111 | .success(function (project) { 112 | project.getTasks().on('success', function (tasks) { 113 | res.render('tasks', { project: project, tasks: tasks }); 114 | }) 115 | }) 116 | .error(next) 117 | }); 118 | 119 | /** 120 | * Add tassk for project. 121 | */ 122 | 123 | app.post('/project/:id/tasks', function (req, res, next) { 124 | req.body.ProjectId = req.params.id; 125 | Task.build(req.body).save() 126 | .success(function (obj) { 127 | res.send(obj.values); 128 | }) 129 | .error(next) 130 | }); 131 | 132 | /** 133 | * Item route. 134 | */ 135 | 136 | app.del('/task/:id', function (req, res, next) { 137 | Task.find(Number(req.params.id)).success(function (task) { 138 | task.destroy() 139 | .success(function () { 140 | res.send(200); 141 | }) 142 | .error(next) 143 | }).error(next); 144 | }); 145 | 146 | /** 147 | * Listen. 148 | */ 149 | 150 | app.listen(3000, function () { 151 | console.log(' - listening on http://*:3000'); 152 | }); 153 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-5/views/index.jade: -------------------------------------------------------------------------------- 1 | 2 | extends layout 3 | 4 | block body 5 | h2 Projects 6 | 7 | #list 8 | ul#projects-list 9 | each project in projects 10 | li 11 | a(href="/project/#{project.id}")= project.title 12 | a.delete(href="/project/:id") x 13 | 14 | form#add(action="/projects", method="POST") 15 | input(type="text", name="title") 16 | button Add 17 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-5/views/layout.jade: -------------------------------------------------------------------------------- 1 | doctype 5 2 | html 3 | head 4 | title TODO list app 5 | script(src="http://code.jquery.com/jquery-1.7.2.js") 6 | script(src="/js/main.js") 7 | body 8 | h1 TODO list app 9 | #todo 10 | block body 11 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-5/views/tasks.jade: -------------------------------------------------------------------------------- 1 | 2 | extends layout 3 | 4 | block body 5 | h2 Tasks for project #{project.title} 6 | 7 | #list 8 | ul#tasks-list 9 | each task in tasks 10 | li 11 | span= task.title 12 | a.delete(href="/task/:id") x 13 | 14 | form#add(action="/project/#{project.id}/tasks", method="POST") 15 | input(type="text", name="title") 16 | button Add 17 | -------------------------------------------------------------------------------- /code-examples/nodejs/1/main.js: -------------------------------------------------------------------------------- 1 | require('module_a'); 2 | require('module_b'); 3 | -------------------------------------------------------------------------------- /code-examples/nodejs/1/module_a.js: -------------------------------------------------------------------------------- 1 | console.log('this is a'); 2 | -------------------------------------------------------------------------------- /code-examples/nodejs/1/module_b.js: -------------------------------------------------------------------------------- 1 | console.log('this is b'); 2 | -------------------------------------------------------------------------------- /code-examples/nodejs/2/index.js: -------------------------------------------------------------------------------- 1 | var a = require('./module_a'); 2 | console.log(a.name); 3 | console.log(a.data); 4 | console.log(a.getPrivate()); 5 | -------------------------------------------------------------------------------- /code-examples/nodejs/2/module_a.js: -------------------------------------------------------------------------------- 1 | exports.name = 'john'; 2 | exports.data = 'this is some data'; 3 | 4 | var privateVariable = 5; 5 | 6 | exports.getPrivate = function () { 7 | return privateVariable; 8 | }; 9 | -------------------------------------------------------------------------------- /code-examples/nodejs/3/index.js: -------------------------------------------------------------------------------- 1 | var Person = require('./person'); 2 | var john = new Person('john'); 3 | john.talk(); 4 | -------------------------------------------------------------------------------- /code-examples/nodejs/3/person.js: -------------------------------------------------------------------------------- 1 | module.exports = Person; 2 | 3 | function Person (name) { 4 | this.name = name; 5 | }; 6 | 7 | Person.prototype.talk = function () { 8 | console.log('my name is', this.name); 9 | }; 10 | -------------------------------------------------------------------------------- /code-examples/nodejs/4/index.js: -------------------------------------------------------------------------------- 1 | var mybuffer = new Buffer('==ii1j2i3h1i23h', 'base64'); 2 | console.log(mybuffer); 3 | require('fs').writeFile('logo.png', mybuffer); 4 | -------------------------------------------------------------------------------- /code-examples/nodejs/4/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/smashingnode/3ca42801b584bcb9f210ad13f42e58c5cf75dc67/code-examples/nodejs/4/logo.png -------------------------------------------------------------------------------- /code-examples/redis/social-graph/step-1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sample-social-graph" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "redis": "0.7.1" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /code-examples/redis/social-graph/step-2/app.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var redis = require('redis') 7 | 8 | /** 9 | * Create client. 10 | */ 11 | 12 | var client = redis.createClient(); 13 | 14 | /** 15 | * User model 16 | */ 17 | 18 | function User (id, data) { 19 | this.id = id; 20 | this.data = data; 21 | } 22 | 23 | User.prototype.save = function (fn) { 24 | if (!this.id) { 25 | this.id = String(Math.random()).substr(3); 26 | } 27 | 28 | client.hmset('user:' + this.id + ':data', this.id, fn) 29 | }; 30 | 31 | User.prototype.follow = function (user_id, fn) { 32 | client.multi() 33 | .sadd('user:' + user_id + ':followers', this.id) 34 | .sadd('user:' + this.id + ':follows', user_id); 35 | .exec(fn); 36 | }; 37 | 38 | User.prototype.unfollow = function (user_id, fn) { 39 | client.multi() 40 | .srem('user:' + user_id + ':followers', this.id) 41 | .srem('user:' + this.id + ':follows', user_id); 42 | .exec(fn); 43 | }; 44 | 45 | User.prototype.getFollowers = function (fn) { 46 | client.smembers('user:' + this.id + ':followers', fn); 47 | }); 48 | 49 | User.prototype.getFollowers = function (fn) { 50 | client.smembers('user:' + this.id + ':follows', fn); 51 | }); 52 | 53 | User.prototype.getFriends = function (fn) { 54 | client.sinter('user:' + this.id + ':follows', 'user:' + this.id + ':followers', fn); 55 | }); 56 | 57 | User.find = function (id, fn) { 58 | client.hgetall('user:' + id + ':data', function (err, obj) { 59 | if (err) return fn(err); 60 | fn(new User(id, obj)); 61 | }); 62 | } 63 | 64 | -------------------------------------------------------------------------------- /code-examples/redis/social-graph/step-2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sample-social-graph" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "redis": "0.7.1" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /code-examples/redis/social-graph/step-3/app.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var redis = require('redis') 7 | 8 | /** 9 | * Create client. 10 | */ 11 | 12 | var client = redis.createClient(); 13 | 14 | /** 15 | * User model 16 | */ 17 | 18 | function User (id, data) { 19 | this.id = id; 20 | this.data = data; 21 | } 22 | 23 | User.prototype.save = function (fn) { 24 | if (!this.id) { 25 | this.id = String(Math.random()).substr(3); 26 | } 27 | 28 | client.hmset('user:' + this.id + ':data', this.id, fn) 29 | }; 30 | 31 | User.prototype.follow = function (user_id, fn) { 32 | client.multi() 33 | .sadd('user:' + user_id + ':followers', this.id) 34 | .sadd('user:' + this.id + ':follows', user_id); 35 | .exec(fn); 36 | }; 37 | 38 | User.prototype.unfollow = function (user_id, fn) { 39 | client.multi() 40 | .srem('user:' + user_id + ':followers', this.id) 41 | .srem('user:' + this.id + ':follows', user_id); 42 | .exec(fn); 43 | }; 44 | 45 | User.prototype.getFollowers = function (fn) { 46 | client.smembers('user:' + this.id + ':followers', fn); 47 | }); 48 | 49 | User.prototype.getFollowers = function (fn) { 50 | client.smembers('user:' + this.id + ':follows', fn); 51 | }); 52 | 53 | User.prototype.getFriends = function (fn) { 54 | client.sinter('user:' + this.id + ':follows', 'user:' + this.id + ':followers', fn); 55 | }); 56 | 57 | User.find = function (id, fn) { 58 | client.hgetall('user:' + id + ':data', function (err, obj) { 59 | if (err) return fn(err); 60 | fn(new User(id, obj)); 61 | }); 62 | } 63 | 64 | -------------------------------------------------------------------------------- /code-examples/redis/social-graph/step-3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sample-social-graph" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "redis": "0.7.1" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /code-examples/redis/social-graph/step-4/model.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var redis = require('redis') 7 | 8 | /** 9 | * Create client. 10 | */ 11 | 12 | var client = redis.createClient(); 13 | 14 | /** 15 | * User model 16 | */ 17 | 18 | function User (id, data) { 19 | this.id = id; 20 | this.data = data; 21 | } 22 | 23 | User.prototype.save = function (fn) { 24 | if (!this.id) { 25 | this.id = String(Math.random()).substr(3); 26 | } 27 | 28 | client.hmset('user:' + this.id + ':data', this.data, fn) 29 | }; 30 | 31 | User.prototype.follow = function (user_id, fn) { 32 | client.multi() 33 | .sadd('user:' + user_id + ':followers', this.id) 34 | .sadd('user:' + this.id + ':follows', user_id) 35 | .exec(fn); 36 | }; 37 | 38 | User.prototype.unfollow = function (user_id, fn) { 39 | client.multi() 40 | .srem('user:' + user_id + ':followers', this.id) 41 | .srem('user:' + this.id + ':follows', user_id) 42 | .exec(fn); 43 | }; 44 | 45 | User.prototype.getFollowers = function (fn) { 46 | client.smembers('user:' + this.id + ':followers', fn); 47 | }; 48 | 49 | User.prototype.getFollorws = function (fn) { 50 | client.smembers('user:' + this.id + ':follows', fn); 51 | }; 52 | 53 | User.prototype.getFriends = function (fn) { 54 | client.sinter('user:' + this.id + ':follows', 'user:' + this.id + ':followers', fn); 55 | }; 56 | 57 | User.find = function (id, fn) { 58 | client.hgetall('user:' + id + ':data', function (err, obj) { 59 | if (err) return fn(err); 60 | fn(null, new User(id, obj)); 61 | }); 62 | }; 63 | 64 | /** 65 | * Module exports 66 | */ 67 | 68 | module.exports = User; 69 | -------------------------------------------------------------------------------- /code-examples/redis/social-graph/step-4/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sample-social-graph" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "redis": "0.7.1" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /code-examples/redis/social-graph/step-4/test.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies 4 | */ 5 | 6 | var User = require('./model') 7 | 8 | /** 9 | * Create test users 10 | */ 11 | 12 | var testUsers = { 13 | 'mark@facebook.com': { name: 'Mark Zuckerberg' } 14 | , 'bill@microsoft.com': { name: 'Bill Gates' } 15 | , 'jeff@amazon.com': { name: 'Jeff Bezos' } 16 | , 'fred@fedex.com': { name: 'Fred Smith' } 17 | }; 18 | 19 | /** 20 | * Create users function 21 | */ 22 | 23 | function create (users, fn) { 24 | var total = Object.keys(users).length; 25 | for (var i in users) { 26 | (function (email, data) { 27 | var user = new User(email, data); 28 | user.save(function (err) { 29 | if (err) throw err; 30 | --total || fn(); 31 | }); 32 | })(i, users[i]); 33 | } 34 | } 35 | 36 | /** 37 | * Hydrate users function 38 | */ 39 | 40 | function hydrate (users, fn) { 41 | var total = Object.keys(users).length; 42 | for (var i in users) { 43 | (function (email) { 44 | User.find(email, function (err, user) { 45 | if (err) throw err; 46 | users[email] = user; 47 | --total || fn(); 48 | }); 49 | })(i); 50 | } 51 | } 52 | 53 | /** 54 | * Create test users. 55 | */ 56 | 57 | create(testUsers, function () { 58 | hydrate(testUsers, function () { 59 | 60 | testUsers['bill@microsoft.com'].follow('jeff@amazon.com', function (err) { 61 | if (err) throw err; 62 | console.log('+ bill followed jeff'); 63 | 64 | testUsers['jeff@amazon.com'].getFollowers(function (err, users) { 65 | if (err) throw err; 66 | console.log("jeff's followers", users); 67 | 68 | testUsers['jeff@amazon.com'].getFriends(function (err, users) { 69 | if (err) throw err; 70 | console.log("jeff's friends", users); 71 | 72 | testUsers['jeff@amazon.com'].follow('bill@microsoft.com', function (err) { 73 | if (err) throw err; 74 | 75 | console.log('+ jeffed follow bill'); 76 | 77 | testUsers['jeff@amazon.com'].getFriends(function (err, users) { 78 | if (err) throw err; 79 | 80 | console.log("jeff's friends", users); 81 | process.exit(0); 82 | }); 83 | }); 84 | }); 85 | }); 86 | }); 87 | 88 | }); 89 | }); 90 | -------------------------------------------------------------------------------- /code-examples/redis/test/model.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module dependencies. 3 | */ 4 | 5 | var redis = require('redis') 6 | 7 | /** 8 | * Module exports 9 | */ 10 | 11 | module.exports = User; 12 | 13 | /** 14 | * Create client. 15 | */ 16 | 17 | var client = redis.createClient(); 18 | 19 | /** 20 | * User model 21 | */ 22 | 23 | function User (id, data) { 24 | this.id = id; 25 | this.data = data; 26 | } 27 | 28 | User.prototype.save = function (fn) { 29 | if (!this.id) { 30 | this.id = String(Math.random()).substr(3); 31 | } 32 | 33 | client.hmset('user:' + this.id + ':data', this.data, fn) 34 | }; 35 | 36 | User.prototype.follow = function (user_id, fn) { 37 | client.multi() 38 | .sadd('user:' + user_id + ':followers', this.id) 39 | .sadd('user:' + this.id + ':follows', user_id) 40 | .exec(fn); 41 | }; 42 | 43 | User.prototype.unfollow = function (user_id, fn) { 44 | client.multi() 45 | .srem('user:' + user_id + ':followers', this.id) 46 | .srem('user:' + this.id + ':follows', user_id) 47 | .exec(fn); 48 | }; 49 | 50 | User.prototype.getFollowers = function (fn) { 51 | client.smembers('user:' + this.id + ':followers', fn); 52 | }; 53 | 54 | User.prototype.getFollorws = function (fn) { 55 | client.smembers('user:' + this.id + ':follows', fn); 56 | }; 57 | 58 | User.prototype.getFriends = function (fn) { 59 | client.sinter('user:' + this.id + ':follows', 'user:' + this.id + ':followers', fn); 60 | }; 61 | 62 | User.find = function (id, fn) { 63 | client.hgetall('user:' + id + ':data', function (err, obj) { 64 | if (err) return fn(err); 65 | fn(null, new User(id, obj)); 66 | }); 67 | }; 68 | 69 | -------------------------------------------------------------------------------- /code-examples/redis/test/test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module dependencies 3 | */ 4 | 5 | var User = require('./model') 6 | 7 | /** 8 | * Create test users 9 | */ 10 | 11 | var testUsers = { 12 | 'mark@facebook.com': { name: 'Mark Zuckerberg' } 13 | , 'bill@microsoft.com': { name: 'Bill Gates' } 14 | , 'jeff@amazon.com': { name: 'Jeff Bezos' } 15 | , 'fred@fedex.com': { name: 'Fred Smith' } 16 | }; 17 | 18 | /** 19 | * Create users function 20 | */ 21 | 22 | function create (users, fn) { 23 | var total = Object.keys(users).length; 24 | for (var i in users) { 25 | (function (email, data) { 26 | var user = new User(email, data); 27 | user.save(function (err) { 28 | if (err) throw err; 29 | --total || fn(); 30 | }); 31 | })(i, users[i]); 32 | } 33 | } 34 | 35 | /** 36 | * Hydrate users function 37 | */ 38 | 39 | function hydrate (users, fn) { 40 | var total = Object.keys(users).length; 41 | for (var i in users) { 42 | (function (email) { 43 | User.find(email, function (err, user) { 44 | if (err) throw err; 45 | users[email] = user; 46 | --total || fn(); 47 | }); 48 | })(i); 49 | } 50 | } 51 | 52 | /** 53 | * Create test users. 54 | */ 55 | 56 | create(testUsers, function () { 57 | hydrate(testUsers, function () { 58 | testUsers['bill@microsoft.com'].follow('jeff@amazon.com', function (err) { 59 | if (err) throw err; 60 | console.log('+ bill followed jeff'); 61 | 62 | testUsers['jeff@amazon.com'].getFollowers(function (err, users) { 63 | if (err) throw err; 64 | console.log("jeff's followers", users); 65 | 66 | testUsers['jeff@amazon.com'].getFriends(function (err, users) { 67 | if (err) throw err; 68 | console.log("jeff's friends", users); 69 | 70 | testUsers['jeff@amazon.com'].follow('bill@microsoft.com' 71 | , function (err) { 72 | if (err) throw err; 73 | 74 | console.log('+ jeffed follow bill'); 75 | 76 | testUsers['jeff@amazon.com'].getFriends(function (err, users) { 77 | if (err) throw err; 78 | 79 | console.log("jeff's friends", users); 80 | process.exit(0); 81 | }); 82 | }); 83 | }); 84 | }); 85 | }); 86 | }); 87 | }); 88 | 89 | 90 | -------------------------------------------------------------------------------- /code-examples/socket.io/public/chat.js: -------------------------------------------------------------------------------- 1 | window.onload = function () { 2 | var socket = io.connect(); 3 | socket.on('connect', function () { 4 | // send a join event with your name 5 | socket.emit('join', prompt('What is your nickname?')); 6 | 7 | // show the chat 8 | document.getElementById('chat').style.display = 'block'; 9 | 10 | socket.on('announcement', function (msg) { 11 | var li = document.createElement('li'); 12 | li.className = 'announcement'; 13 | li.innerHTML = msg; 14 | document.getElementById('messages').appendChild(li); 15 | }); 16 | }); 17 | 18 | function addMessage (from, text) { 19 | var li = document.createElement('li'); 20 | li.className = 'message'; 21 | li.innerHTML = '' + from + ': ' + text; 22 | document.getElementById('messages').appendChild(li); 23 | } 24 | 25 | var input = document.getElementById('input'); 26 | document.getElementById('form').onsubmit = function () { 27 | addMessage('me', input.value); 28 | socket.emit('text', input.value); 29 | 30 | // reset the input 31 | input.value = ''; 32 | input.focus(); 33 | 34 | return false; 35 | } 36 | 37 | socket.on('text', addMessage); 38 | 39 | // plays a song 40 | var playing = document.getElementById('playing'); 41 | function play (song) { 42 | if (!song) return; 43 | playing.innerHTML = '
    Now Playing: ' 44 | + song.ArtistName + ' ' + song.SongName + '
    '; 45 | 46 | var iframe = document.createElement('iframe'); 47 | iframe.frameborder = 0; 48 | iframe.src = song.Url; 49 | playing.appendChild(iframe); 50 | }; 51 | socket.on('song', play); 52 | 53 | // search form 54 | var form = document.getElementById('dj'); 55 | var results = document.getElementById('results'); 56 | form.style.display = 'block'; 57 | form.onsubmit = function () { 58 | results.innerHTML = ''; 59 | socket.emit('search', document.getElementById('s').value, function (songs) { 60 | for (var i = 0, l = songs.length; i < l; i++) { 61 | (function (song) { 62 | var result = document.createElement('li'); 63 | result.innerHTML = song.ArtistName + ' - ' + song.SongName + ' '; 64 | var a = document.createElement('a'); 65 | a.href = '#'; 66 | a.innerHTML = 'Select'; 67 | a.onclick = function () { 68 | socket.emit('song', song); 69 | play(song); 70 | return false; 71 | } 72 | result.appendChild(a); 73 | results.appendChild(result); 74 | })(songs[i]); 75 | } 76 | }); 77 | return false; 78 | }; 79 | 80 | socket.on('elected', function () { 81 | form.className = 'isDJ'; 82 | }); 83 | } 84 | 85 | -------------------------------------------------------------------------------- /code-examples/socket.io/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Socket.IO chat 5 | 6 | 7 | 8 | 9 | 10 |
    11 |
      12 |
      13 | 14 | 15 |
      16 |
      17 | 18 |
      19 |

      Search songs

      20 | 21 |
        22 | 23 |
        24 |
        25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /code-examples/socket.io/server.js: -------------------------------------------------------------------------------- 1 | var express = require('express') 2 | , sio = require('socket.io') 3 | , request = require('superagent') 4 | 5 | app = express.createServer( 6 | express.bodyParser() 7 | , express.static('public') 8 | ); 9 | 10 | app.listen(3000); 11 | 12 | var io = sio.listen(app) 13 | , apiKey = 'cc78b550effeea0edb929ada1e9d0729' 14 | , currentSong 15 | , dj 16 | 17 | function elect (socket) { 18 | dj = socket; 19 | io.sockets.emit('announcement', socket.nickname + ' is the new dj'); 20 | socket.emit('elected'); 21 | socket.dj = true; 22 | socket.on('disconnect', function () { 23 | dj = null; 24 | io.sockets.emit('announcement', 'the dj left - next one to join becomes dj'); 25 | }); 26 | } 27 | 28 | io.sockets.on('connection', function (socket) { 29 | socket.on('join', function (name) { 30 | socket.nickname = name; 31 | socket.broadcast.emit('announcement', name + ' joined the chat.'); 32 | if (!dj) { 33 | elect(socket); 34 | } else { 35 | socket.emit('song', currentSong); 36 | } 37 | }); 38 | 39 | socket.on('song', function (song) { 40 | if (socket.dj) { 41 | currentSong = song; 42 | socket.broadcast.emit('song', song); 43 | } 44 | }); 45 | 46 | socket.on('search', function (q, fn) { 47 | request('http://tinysong.com/s/' + encodeURIComponent(q) 48 | + '?key=' + apiKey + '&format=json', function (res) { 49 | if (200 == res.status) fn(JSON.parse(res.text)); 50 | }); 51 | }); 52 | 53 | socket.on('text', function (msg) { 54 | socket.broadcast.emit('text', socket.nickname, msg); 55 | }); 56 | }); 57 | 58 | -------------------------------------------------------------------------------- /code-examples/tcp/chat/step-1/index.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var net = require('net') 7 | 8 | /** 9 | * Create server. 10 | */ 11 | 12 | var server = net.createServer(function (conn) { 13 | // handle connection 14 | console.log('\033[90m new connection!\033[39m'); 15 | }); 16 | 17 | /** 18 | * Listen. 19 | */ 20 | 21 | server.listen(3000, function () { 22 | console.log('\033[96m server listening on *:3000\033[39m'); 23 | }); 24 | -------------------------------------------------------------------------------- /code-examples/tcp/chat/step-1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tcp-chat" 3 | , "description": "Our first TCP server" 4 | , "version": "0.0.1" 5 | } 6 | -------------------------------------------------------------------------------- /code-examples/tcp/chat/step-2/index.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var net = require('net') 7 | 8 | /** 9 | * Keep track of connections. 10 | */ 11 | 12 | var count = 0; 13 | 14 | /** 15 | * Create server. 16 | */ 17 | 18 | var server = net.createServer(function (conn) { 19 | conn.write( 20 | '\n > welcome to \033[92mnode-chat\033[39m!' 21 | + '\n > ' + count + ' other people are connected at this time.' 22 | + '\n > please write your name and press enter: ' 23 | ); 24 | count++; 25 | conn.on('close', function () { 26 | count--; 27 | }); 28 | }); 29 | 30 | /** 31 | * Listen. 32 | */ 33 | 34 | server.listen(3000, function () { 35 | console.log('\033[96m server listening on *:3000\033[39m'); 36 | }); 37 | -------------------------------------------------------------------------------- /code-examples/tcp/chat/step-2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tcp-chat" 3 | , "description": "Our first TCP server" 4 | , "version": "0.0.1" 5 | } 6 | -------------------------------------------------------------------------------- /code-examples/tcp/chat/step-3/index.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var net = require('net') 7 | 8 | /** 9 | * Keep track of connections. 10 | */ 11 | 12 | var count = 0; 13 | 14 | /** 15 | * Create server. 16 | */ 17 | 18 | var server = net.createServer(function (conn) { 19 | conn.write( 20 | '\n > welcome to \033[92mnode-chat\033[39m!' 21 | + '\n > ' + count + ' other people are connected at this time.' 22 | + '\n > please write your name and press enter: ' 23 | ); 24 | count++; 25 | 26 | conn.setEncoding('utf8'); 27 | conn.on('data', function (data) { 28 | console.log(data); 29 | }); 30 | conn.on('close', function () { 31 | count--; 32 | }); 33 | }); 34 | 35 | /** 36 | * Listen. 37 | */ 38 | 39 | server.listen(3000, function () { 40 | console.log('\033[96m server listening on *:3000\033[39m'); 41 | }); 42 | -------------------------------------------------------------------------------- /code-examples/tcp/chat/step-3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tcp-chat" 3 | , "description": "Our first TCP server" 4 | , "version": "0.0.1" 5 | } 6 | -------------------------------------------------------------------------------- /code-examples/tcp/chat/step-4/index.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var net = require('net') 7 | 8 | /** 9 | * Keep track of connections. 10 | */ 11 | 12 | var count = 0 13 | , users = {} 14 | 15 | /** 16 | * Create server. 17 | */ 18 | 19 | var server = net.createServer(function (conn) { 20 | conn.write( 21 | '\n > welcome to \033[92mnode-chat\033[39m!' 22 | + '\n > ' + count + ' other people are connected at this time.' 23 | + '\n > please write your name and press enter: ' 24 | ); 25 | count++; 26 | 27 | conn.setEncoding('utf8'); 28 | 29 | // the nickname for the current connection 30 | var nickname; 31 | 32 | conn.on('data', function (data) { 33 | // we remove the "enter" character 34 | data = data.replace('\r\n', ''); 35 | 36 | // the first piece of data we expect is the nickname 37 | if (!nickname) { 38 | if (users[data]) { 39 | conn.write('\033[93m > nickname already in use. try again:\033[39m '); 40 | return; 41 | } else { 42 | nickname = data; 43 | users[nickname] = conn; 44 | 45 | for (var i in users) { 46 | users[i].write('\033[90m > ' + nickname + ' joined the room\033[39m\n'); 47 | } 48 | } 49 | } else { 50 | // otherwise we consider it a chat message 51 | for (var i in users) { 52 | if (i != nickname) { 53 | users[i].write('\033[96m > ' + nickname + ':\033[39m ' + data + '\n'); 54 | } 55 | } 56 | } 57 | }); 58 | 59 | conn.on('close', function () { 60 | count--; 61 | }); 62 | }); 63 | 64 | /** 65 | * Listen. 66 | */ 67 | 68 | server.listen(3000, function () { 69 | console.log('\033[96m server listening on *:3000\033[39m'); 70 | }); 71 | -------------------------------------------------------------------------------- /code-examples/tcp/chat/step-4/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tcp-chat" 3 | , "description": "Our first TCP server" 4 | , "version": "0.0.1" 5 | } 6 | -------------------------------------------------------------------------------- /code-examples/tcp/chat/step-5/index.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var net = require('net') 7 | 8 | /** 9 | * Keep track of connections. 10 | */ 11 | 12 | var count = 0 13 | , users = {} 14 | 15 | /** 16 | * Create server. 17 | */ 18 | 19 | var server = net.createServer(function (conn) { 20 | conn.write( 21 | '\n > welcome to \033[92mnode-chat\033[39m!' 22 | + '\n > ' + count + ' other people are connected at this time.' 23 | + '\n > please write your name and press enter: ' 24 | ); 25 | count++; 26 | 27 | conn.setEncoding('utf8'); 28 | 29 | // the nickname for the current connection 30 | var nickname; 31 | 32 | function broadcast (msg, exceptMyself) { 33 | for (var i in users) { 34 | if (!exceptMyself || i != nickname) { 35 | users[i].write(msg); 36 | } 37 | } 38 | } 39 | 40 | conn.on('data', function (data) { 41 | // we remove the "enter" character 42 | data = data.replace('\r\n', ''); 43 | 44 | // the first piece of data we expect is the nickname 45 | if (!nickname) { 46 | if (users[data]) { 47 | conn.write('\033[93m > nickname already in use. try again:\033[39m '); 48 | return; 49 | } else { 50 | nickname = data; 51 | users[nickname] = conn; 52 | 53 | broadcast('\033[90m > ' + nickname + ' joined the room\033[39m\n'); 54 | } 55 | } else { 56 | // otherwise we consider it a chat message 57 | broadcast('\033[96m > ' + nickname + ':\033[39m ' + data + '\n', true); 58 | } 59 | }); 60 | 61 | conn.on('close', function () { 62 | count--; 63 | delete users[nickname]; 64 | broadcast('\033[90m > ' + nickname + ' left the room\033[39m\n'); 65 | }); 66 | }); 67 | 68 | /** 69 | * Listen. 70 | */ 71 | 72 | server.listen(3000, function () { 73 | console.log('\033[96m server listening on *:3000\033[39m'); 74 | }); 75 | -------------------------------------------------------------------------------- /code-examples/tcp/chat/step-5/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tcp-chat" 3 | , "description": "Our first TCP server" 4 | , "version": "0.0.1" 5 | } 6 | -------------------------------------------------------------------------------- /code-examples/tcp/introduction/web-server.js: -------------------------------------------------------------------------------- 1 | require('http').createServer(function (req, res) { 2 | res.writeHead(200, { 'Content-Type': 'text/html' }); 3 | res.end('

        Hello world

        '); 4 | }).listen(3000); 5 | -------------------------------------------------------------------------------- /code-examples/tcp/irc/index.js: -------------------------------------------------------------------------------- 1 | 2 | var net = require('net'); 3 | 4 | var client = net.createConnection(6667, 'irc.freenode.net') 5 | client.setEncoding('utf-8') 6 | 7 | client.on('connect', function () { 8 | client.write('NICK mynick\r\n'); 9 | client.write('USER mynick 0 * :realname\r\n'); 10 | client.write('JOIN #node.js\r\n'); 11 | }); 12 | 13 | -------------------------------------------------------------------------------- /code-examples/testing/mocha/bdd/bdd.js: -------------------------------------------------------------------------------- 1 | 2 | var expect = require('expect.js') 3 | , jade = require('jade') 4 | 5 | describe('jade.render', function () { 6 | it('should render a paragraph', function () { 7 | expect(jade.render('p A paragraph')).to.be('

        A paragraph

        '); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /code-examples/testing/mocha/browser/expect.js: -------------------------------------------------------------------------------- 1 | 2 | (function (global, module) { 3 | 4 | if ('undefined' == typeof module) { 5 | var module = { exports: {} } 6 | , exports = module.exports 7 | } 8 | 9 | /** 10 | * Exports. 11 | */ 12 | 13 | module.exports = expect; 14 | expect.Assertion = Assertion; 15 | 16 | /** 17 | * Exports version. 18 | */ 19 | 20 | expect.version = '0.1.1'; 21 | 22 | /** 23 | * Possible assertion flags. 24 | */ 25 | 26 | var flags = { 27 | not: ['to', 'be', 'have', 'include', 'only'] 28 | , to: ['be', 'have', 'include', 'only', 'not'] 29 | , only: ['have'] 30 | , have: ['own'] 31 | , be: ['an'] 32 | }; 33 | 34 | function expect (obj) { 35 | return new Assertion(obj); 36 | } 37 | 38 | /** 39 | * Constructor 40 | * 41 | * @api private 42 | */ 43 | 44 | function Assertion (obj, flag, parent) { 45 | this.obj = obj; 46 | this.flags = {}; 47 | 48 | if (undefined != parent) { 49 | this.flags[flag] = true; 50 | 51 | for (var i in parent.flags) { 52 | if (parent.flags.hasOwnProperty(i)) { 53 | this.flags[i] = true; 54 | } 55 | } 56 | } 57 | 58 | var $flags = flag ? flags[flag] : keys(flags) 59 | , self = this 60 | 61 | if ($flags) { 62 | for (var i = 0, l = $flags.length; i < l; i++) { 63 | // avoid recursion 64 | if (this.flags[$flags[i]]) continue; 65 | 66 | var name = $flags[i] 67 | , assertion = new Assertion(this.obj, name, this) 68 | 69 | if ('function' == typeof Assertion.prototype[name]) { 70 | // clone the function, make sure we dont touch the prot reference 71 | var old = this[name]; 72 | this[name] = function () { 73 | return old.apply(self, arguments); 74 | } 75 | 76 | for (var fn in Assertion.prototype) { 77 | if (Assertion.prototype.hasOwnProperty(fn) && fn != name) { 78 | this[name][fn] = bind(assertion[fn], assertion); 79 | } 80 | } 81 | } else { 82 | this[name] = assertion; 83 | } 84 | } 85 | } 86 | }; 87 | 88 | /** 89 | * Performs an assertion 90 | * 91 | * @api private 92 | */ 93 | 94 | Assertion.prototype.assert = function (truth, msg, error) { 95 | var msg = this.flags.not ? error : msg 96 | , ok = this.flags.not ? !truth : truth; 97 | 98 | if (!ok) { 99 | throw new Error(msg); 100 | } 101 | 102 | this.and = new Assertion(this.obj); 103 | }; 104 | 105 | /** 106 | * Check if the value is truthy 107 | * 108 | * @api public 109 | */ 110 | 111 | Assertion.prototype.ok = function () { 112 | this.assert( 113 | !!this.obj 114 | , 'expected ' + i(this.obj) + ' to be truthy' 115 | , 'expected ' + i(this.obj) + ' to be falsy'); 116 | }; 117 | 118 | /** 119 | * Asser that the function throws. 120 | */ 121 | 122 | Assertion.prototype.throwException = function () { 123 | expect(this.obj).to.be.a('function'); 124 | 125 | var thrown = false; 126 | 127 | try { 128 | this.obj(); 129 | } catch (e) { 130 | thrown = true; 131 | } 132 | 133 | var name = this.obj.name || 'fn'; 134 | this.assert( 135 | thrown 136 | , 'expected ' + name + ' to throw an exception' 137 | , 'expected ' + name + ' not to throw an exception'); 138 | }; 139 | 140 | /** 141 | * Checks if the array is empty. 142 | * 143 | * @api public 144 | */ 145 | 146 | Assertion.prototype.empty = function () { 147 | expect(this.obj).to.have.property('length'); 148 | this.assert( 149 | 0 === this.obj.length 150 | , 'expected ' + i(this.obj) + ' to be empty' 151 | , 'expected ' + i(this.obj) + ' to not be empty'); 152 | return this; 153 | }; 154 | 155 | /** 156 | * Checks if the obj exactly equals another. 157 | * 158 | * @api public 159 | */ 160 | 161 | Assertion.prototype.be = 162 | Assertion.prototype.equal = function (obj) { 163 | this.assert( 164 | obj === this.obj 165 | , 'expected ' + i(this.obj) + ' to equal ' + i(obj) 166 | , 'expected ' + i(this.obj) + ' to not equal ' + i(obj)); 167 | return this; 168 | }; 169 | 170 | /** 171 | * Checks if the obj sortof equals another. 172 | * 173 | * @api public 174 | */ 175 | 176 | Assertion.prototype.eql = function (obj) { 177 | this.assert( 178 | expect.eql(obj, this.obj) 179 | , 'expected ' + i(this.obj) + ' to sort of equal ' + i(obj) 180 | , 'expected ' + i(this.obj) + ' to sort of not equal ' + i(obj)); 181 | return this; 182 | }; 183 | 184 | /** 185 | * Assert within start to finish (inclusive). 186 | * 187 | * @param {Number} start 188 | * @param {Number} finish 189 | * @api public 190 | */ 191 | 192 | Assertion.prototype.within = function (start, finish) { 193 | var range = start + '..' + finish; 194 | this.assert( 195 | this.obj >= start && this.obj <= finish 196 | , 'expected ' + i(this.obj) + ' to be within ' + range 197 | , 'expected ' + i(this.obj) + ' to not be within ' + range); 198 | return this; 199 | }; 200 | 201 | /** 202 | * Assert typeof / instance of 203 | * 204 | * @api public 205 | */ 206 | 207 | Assertion.prototype.a = 208 | Assertion.prototype.an = function (type) { 209 | if ('string' == typeof type) { 210 | // typeof with support for 'array' 211 | this.assert( 212 | 'array' == type ? isArray(this.obj) : type == typeof this.obj 213 | , 'expected ' + i(this.obj) + ' to be a ' + type 214 | , 'expected ' + i(this.obj) + ' not to be a ' + type); 215 | } else { 216 | // instanceof 217 | var name = type.name || 'supplied constructor'; 218 | this.assert( 219 | this.obj instanceof type 220 | , 'expected ' + i(this.obj) + ' to be an instance of ' + name 221 | , 'expected ' + i(this.obj) + ' not to be an instance of ' + name); 222 | } 223 | 224 | return this; 225 | }; 226 | 227 | /** 228 | * Assert numeric value above _n_. 229 | * 230 | * @param {Number} n 231 | * @api public 232 | */ 233 | 234 | Assertion.prototype.greaterThan = 235 | Assertion.prototype.above = function (n) { 236 | this.assert( 237 | this.obj > n 238 | , 'expected ' + i(this.obj) + ' to be above ' + n 239 | , 'expected ' + i(this.obj) + ' to be below ' + n); 240 | return this; 241 | }; 242 | 243 | /** 244 | * Assert numeric value below _n_. 245 | * 246 | * @param {Number} n 247 | * @api public 248 | */ 249 | 250 | Assertion.prototype.lessThan = 251 | Assertion.prototype.below = function (n) { 252 | this.assert( 253 | this.obj < n 254 | , 'expected ' + i(this.obj) + ' to be below ' + n 255 | , 'expected ' + i(this.obj) + ' to be above ' + n); 256 | return this; 257 | }; 258 | 259 | /** 260 | * Assert string value matches _regexp_. 261 | * 262 | * @param {RegExp} regexp 263 | * @api public 264 | */ 265 | 266 | Assertion.prototype.match = function (regexp) { 267 | this.assert( 268 | regexp.exec(this.obj) 269 | , 'expected ' + i(this.obj) + ' to match ' + regexp 270 | , 'expected ' + i(this.obj) + ' not to match ' + regexp); 271 | return this; 272 | }; 273 | 274 | /** 275 | * Assert property "length" exists and has value of _n_. 276 | * 277 | * @param {Number} n 278 | * @api public 279 | */ 280 | 281 | Assertion.prototype.length = function (n) { 282 | expect(this.obj).to.have.property('length'); 283 | var len = this.obj.length; 284 | this.assert( 285 | n == len 286 | , 'expected ' + i(this.obj) + ' to have a length of ' + n + ' but got ' + len 287 | , 'expected ' + i(this.obj) + ' to not have a length of ' + len); 288 | return this; 289 | }; 290 | 291 | /** 292 | * Assert property _name_ exists, with optional _val_. 293 | * 294 | * @param {String} name 295 | * @param {Mixed} val 296 | * @api public 297 | */ 298 | 299 | Assertion.prototype.property = function (name, val) { 300 | if (this.flags.own) { 301 | this.assert( 302 | Object.prototype.hasOwnProperty.call(this.obj, name) 303 | , 'expected ' + i(this.obj) + ' to have own property ' + i(name) 304 | , 'expected ' + i(this.obj) + ' to not have own property ' + i(name)); 305 | return this; 306 | } 307 | 308 | if (this.flags.not && undefined !== val) { 309 | if (undefined === this.obj[name]) { 310 | throw new Error(i(this.obj) + ' has no property ' + i(name)); 311 | } 312 | } else { 313 | this.assert( 314 | undefined !== this.obj[name] 315 | , 'expected ' + i(this.obj) + ' to have a property ' + i(name) 316 | , 'expected ' + i(this.obj) + ' to not have a property ' + i(name)); 317 | } 318 | 319 | if (undefined !== val) { 320 | this.assert( 321 | val === this.obj[name] 322 | , 'expected ' + i(this.obj) + ' to have a property ' + i(name) 323 | + ' of ' + i(val) + ', but got ' + i(this.obj[name]) 324 | , 'expected ' + i(this.obj) + ' to not have a property ' + i(name) 325 | + ' of ' + i(val)); 326 | } 327 | 328 | this.obj = this.obj[name]; 329 | return this; 330 | }; 331 | 332 | /** 333 | * Assert that the array contains _obj_ or string contains _obj_. 334 | * 335 | * @param {Mixed} obj|string 336 | * @api public 337 | */ 338 | 339 | Assertion.prototype.string = 340 | Assertion.prototype.contain = function (obj) { 341 | if ('string' == typeof this.obj) { 342 | this.assert( 343 | ~this.obj.indexOf(obj) 344 | , 'expected ' + i(this.obj) + ' to contain ' + i(obj) 345 | , 'expected ' + i(this.obj) + ' to not contain ' + i(obj)); 346 | } else { 347 | this.assert( 348 | ~indexOf(this.obj, obj) 349 | , 'expected ' + i(this.obj) + ' to contain ' + i(obj) 350 | , 'expected ' + i(this.obj) + ' to not contain ' + i(obj)); 351 | } 352 | return this; 353 | }; 354 | 355 | /** 356 | * Assert exact keys or inclusion of keys by using 357 | * the `.own` modifier. 358 | * 359 | * @param {Array|String ...} keys 360 | * @api public 361 | */ 362 | 363 | Assertion.prototype.key = 364 | Assertion.prototype.keys = function ($keys) { 365 | var str 366 | , ok = true; 367 | 368 | $keys = isArray($keys) 369 | ? $keys 370 | : Array.prototype.slice.call(arguments); 371 | 372 | if (!$keys.length) throw new Error('keys required'); 373 | 374 | var actual = keys(this.obj) 375 | , len = $keys.length; 376 | 377 | // Inclusion 378 | ok = every($keys, function (key) { 379 | return ~indexOf(actual, key); 380 | }); 381 | 382 | // Strict 383 | if (!this.flags.not && this.flags.only) { 384 | ok = ok && $keys.length == actual.length; 385 | } 386 | 387 | // Key string 388 | if (len > 1) { 389 | $keys = map($keys, function (key) { 390 | return i(key); 391 | }); 392 | var last = $keys.pop(); 393 | str = $keys.join(', ') + ', and ' + last; 394 | } else { 395 | str = i($keys[0]); 396 | } 397 | 398 | // Form 399 | str = (len > 1 ? 'keys ' : 'key ') + str; 400 | 401 | // Have / include 402 | str = (!this.flags.only ? 'include ' : 'only have ') + str; 403 | 404 | // Assertion 405 | this.assert( 406 | ok 407 | , 'expected ' + i(this.obj) + ' to ' + str 408 | , 'expected ' + i(this.obj) + ' to not ' + str); 409 | 410 | return this; 411 | }; 412 | 413 | /** 414 | * Function bind implementation. 415 | */ 416 | 417 | function bind (fn, scope) { 418 | return function () { 419 | return fn.apply(scope, arguments); 420 | } 421 | } 422 | 423 | /** 424 | * Array every compatibility 425 | * 426 | * @see bit.ly/5Fq1N2 427 | * @api public 428 | */ 429 | 430 | function every (arr, fn, thisObj) { 431 | var scope = thisObj || global; 432 | for (var i = 0, j = arr.length; i < j; ++i) { 433 | if (!fn.call(scope, arr[i], i, arr)) { 434 | return false; 435 | } 436 | } 437 | return true; 438 | }; 439 | 440 | /** 441 | * Array indexOf compatibility. 442 | * 443 | * @see bit.ly/a5Dxa2 444 | * @api public 445 | */ 446 | 447 | function indexOf (arr, o, i) { 448 | if (Array.prototype.indexOf) { 449 | return Array.prototype.indexOf.call(arr, o, i); 450 | } 451 | 452 | for (var j = arr.length, i = i < 0 ? i + j < 0 ? 0 : i + j : i || 0 453 | ; i < j && arr[i] !== o; i++); 454 | 455 | return j <= i ? -1 : i; 456 | }; 457 | 458 | /** 459 | * Inspects an object. 460 | * 461 | * @see taken from node.js `util` module (copyright Joyent, MIT license) 462 | * @api private 463 | */ 464 | 465 | function i (obj, showHidden, depth) { 466 | var seen = []; 467 | 468 | function stylize (str) { 469 | return str; 470 | }; 471 | 472 | function format (value, recurseTimes) { 473 | // Provide a hook for user-specified inspect functions. 474 | // Check that value is an object with an inspect function on it 475 | if (value && typeof value.inspect === 'function' && 476 | // Filter out the util module, it's inspect function is special 477 | value !== exports && 478 | // Also filter out any prototype objects using the circular check. 479 | !(value.constructor && value.constructor.prototype === value)) { 480 | return value.inspect(recurseTimes); 481 | } 482 | 483 | // Primitive types cannot have properties 484 | switch (typeof value) { 485 | case 'undefined': 486 | return stylize('undefined', 'undefined'); 487 | 488 | case 'string': 489 | var simple = '\'' + json.stringify(value).replace(/^"|"$/g, '') 490 | .replace(/'/g, "\\'") 491 | .replace(/\\"/g, '"') + '\''; 492 | return stylize(simple, 'string'); 493 | 494 | case 'number': 495 | return stylize('' + value, 'number'); 496 | 497 | case 'boolean': 498 | return stylize('' + value, 'boolean'); 499 | } 500 | // For some reason typeof null is "object", so special case here. 501 | if (value === null) { 502 | return stylize('null', 'null'); 503 | } 504 | 505 | // Look up the keys of the object. 506 | var visible_keys = keys(value); 507 | var $keys = showHidden ? Object.getOwnPropertyNames(value) : visible_keys; 508 | 509 | // Functions without properties can be shortcutted. 510 | if (typeof value === 'function' && $keys.length === 0) { 511 | if (isRegExp(value)) { 512 | return stylize('' + value, 'regexp'); 513 | } else { 514 | var name = value.name ? ': ' + value.name : ''; 515 | return stylize('[Function' + name + ']', 'special'); 516 | } 517 | } 518 | 519 | // Dates without properties can be shortcutted 520 | if (isDate(value) && $keys.length === 0) { 521 | return stylize(value.toUTCString(), 'date'); 522 | } 523 | 524 | var base, type, braces; 525 | // Determine the object type 526 | if (isArray(value)) { 527 | type = 'Array'; 528 | braces = ['[', ']']; 529 | } else { 530 | type = 'Object'; 531 | braces = ['{', '}']; 532 | } 533 | 534 | // Make functions say that they are functions 535 | if (typeof value === 'function') { 536 | var n = value.name ? ': ' + value.name : ''; 537 | base = (isRegExp(value)) ? ' ' + value : ' [Function' + n + ']'; 538 | } else { 539 | base = ''; 540 | } 541 | 542 | // Make dates with properties first say the date 543 | if (isDate(value)) { 544 | base = ' ' + value.toUTCString(); 545 | } 546 | 547 | if ($keys.length === 0) { 548 | return braces[0] + base + braces[1]; 549 | } 550 | 551 | if (recurseTimes < 0) { 552 | if (isRegExp(value)) { 553 | return stylize('' + value, 'regexp'); 554 | } else { 555 | return stylize('[Object]', 'special'); 556 | } 557 | } 558 | 559 | seen.push(value); 560 | 561 | var output = map($keys, function (key) { 562 | var name, str; 563 | if (value.__lookupGetter__) { 564 | if (value.__lookupGetter__(key)) { 565 | if (value.__lookupSetter__(key)) { 566 | str = stylize('[Getter/Setter]', 'special'); 567 | } else { 568 | str = stylize('[Getter]', 'special'); 569 | } 570 | } else { 571 | if (value.__lookupSetter__(key)) { 572 | str = stylize('[Setter]', 'special'); 573 | } 574 | } 575 | } 576 | if (indexOf(visible_keys, key) < 0) { 577 | name = '[' + key + ']'; 578 | } 579 | if (!str) { 580 | if (indexOf(seen, value[key]) < 0) { 581 | if (recurseTimes === null) { 582 | str = format(value[key]); 583 | } else { 584 | str = format(value[key], recurseTimes - 1); 585 | } 586 | if (str.indexOf('\n') > -1) { 587 | if (isArray(value)) { 588 | str = map(str.split('\n'), function (line) { 589 | return ' ' + line; 590 | }).join('\n').substr(2); 591 | } else { 592 | str = '\n' + map(str.split('\n'), function (line) { 593 | return ' ' + line; 594 | }).join('\n'); 595 | } 596 | } 597 | } else { 598 | str = stylize('[Circular]', 'special'); 599 | } 600 | } 601 | if (typeof name === 'undefined') { 602 | if (type === 'Array' && key.match(/^\d+$/)) { 603 | return str; 604 | } 605 | name = json.stringify('' + key); 606 | if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { 607 | name = name.substr(1, name.length - 2); 608 | name = stylize(name, 'name'); 609 | } else { 610 | name = name.replace(/'/g, "\\'") 611 | .replace(/\\"/g, '"') 612 | .replace(/(^"|"$)/g, "'"); 613 | name = stylize(name, 'string'); 614 | } 615 | } 616 | 617 | return name + ': ' + str; 618 | }); 619 | 620 | seen.pop(); 621 | 622 | var numLinesEst = 0; 623 | var length = reduce(output, function (prev, cur) { 624 | numLinesEst++; 625 | if (indexOf(cur, '\n') >= 0) numLinesEst++; 626 | return prev + cur.length + 1; 627 | }, 0); 628 | 629 | if (length > 50) { 630 | output = braces[0] + 631 | (base === '' ? '' : base + '\n ') + 632 | ' ' + 633 | output.join(',\n ') + 634 | ' ' + 635 | braces[1]; 636 | 637 | } else { 638 | output = braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; 639 | } 640 | 641 | return output; 642 | } 643 | return format(obj, (typeof depth === 'undefined' ? 2 : depth)); 644 | }; 645 | 646 | function isArray (ar) { 647 | return Object.prototype.toString.call(ar) == '[object Array]'; 648 | }; 649 | 650 | function isRegExp(re) { 651 | var s = '' + re; 652 | return re instanceof RegExp || // easy case 653 | // duck-type for context-switching evalcx case 654 | typeof(re) === 'function' && 655 | re.constructor.name === 'RegExp' && 656 | re.compile && 657 | re.test && 658 | re.exec && 659 | s.match(/^\/.*\/[gim]{0,3}$/); 660 | }; 661 | 662 | function isDate(d) { 663 | if (d instanceof Date) return true; 664 | return false; 665 | }; 666 | 667 | function keys (obj) { 668 | if (Object.keys) { 669 | return Object.keys(obj); 670 | } 671 | 672 | var keys = []; 673 | 674 | for (var i in obj) { 675 | if (Object.prototype.hasOwnProperty.call(obj, i)) { 676 | keys.push(i); 677 | } 678 | } 679 | 680 | return keys; 681 | } 682 | 683 | function map (arr, mapper, that) { 684 | if (Array.prototype.map) { 685 | return Array.prototype.map.call(arr, mapper, that); 686 | } 687 | 688 | var other= new Array(arr.length); 689 | 690 | for (var i= 0, n = arr.length; i= 2) { 716 | var rv = arguments[1]; 717 | } else { 718 | do { 719 | if (i in this) { 720 | rv = this[i++]; 721 | break; 722 | } 723 | 724 | // if array contains no values, no initial value to return 725 | if (++i >= len) 726 | throw new TypeError(); 727 | } while (true); 728 | } 729 | 730 | for (; i < len; i++) { 731 | if (i in this) 732 | rv = fun.call(null, rv, this[i], i, this); 733 | } 734 | 735 | return rv; 736 | }; 737 | 738 | /** 739 | * Asserts deep equality 740 | * 741 | * @see taken from node.js `assert` module (copyright Joyent, MIT license) 742 | * @api private 743 | */ 744 | 745 | expect.eql = function eql (actual, expected) { 746 | // 7.1. All identical values are equivalent, as determined by ===. 747 | if (actual === expected) { 748 | return true; 749 | } else if ('undefined' != typeof Buffer 750 | && Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) { 751 | if (actual.length != expected.length) return false; 752 | 753 | for (var i = 0; i < actual.length; i++) { 754 | if (actual[i] !== expected[i]) return false; 755 | } 756 | 757 | return true; 758 | 759 | // 7.2. If the expected value is a Date object, the actual value is 760 | // equivalent if it is also a Date object that refers to the same time. 761 | } else if (actual instanceof Date && expected instanceof Date) { 762 | return actual.getTime() === expected.getTime(); 763 | 764 | // 7.3. Other pairs that do not both pass typeof value == "object", 765 | // equivalence is determined by ==. 766 | } else if (typeof actual != 'object' && typeof expected != 'object') { 767 | return actual == expected; 768 | 769 | // 7.4. For all other Object pairs, including Array objects, equivalence is 770 | // determined by having the same number of owned properties (as verified 771 | // with Object.prototype.hasOwnProperty.call), the same set of keys 772 | // (although not necessarily the same order), equivalent values for every 773 | // corresponding key, and an identical "prototype" property. Note: this 774 | // accounts for both named and indexed properties on Arrays. 775 | } else { 776 | return objEquiv(actual, expected); 777 | } 778 | } 779 | 780 | function isUndefinedOrNull (value) { 781 | return value === null || value === undefined; 782 | } 783 | 784 | function isArguments (object) { 785 | return Object.prototype.toString.call(object) == '[object Arguments]'; 786 | } 787 | 788 | function objEquiv (a, b) { 789 | if (isUndefinedOrNull(a) || isUndefinedOrNull(b)) 790 | return false; 791 | // an identical "prototype" property. 792 | if (a.prototype !== b.prototype) return false; 793 | //~~~I've managed to break Object.keys through screwy arguments passing. 794 | // Converting to array solves the problem. 795 | if (isArguments(a)) { 796 | if (!isArguments(b)) { 797 | return false; 798 | } 799 | a = pSlice.call(a); 800 | b = pSlice.call(b); 801 | return expect.eql(a, b); 802 | } 803 | try{ 804 | var ka = keys(a), 805 | kb = keys(b), 806 | key, i; 807 | } catch (e) {//happens when one is a string literal and the other isn't 808 | return false; 809 | } 810 | // having the same number of owned properties (keys incorporates hasOwnProperty) 811 | if (ka.length != kb.length) 812 | return false; 813 | //the same set of keys (although not necessarily the same order), 814 | ka.sort(); 815 | kb.sort(); 816 | //~~~cheap key test 817 | for (i = ka.length - 1; i >= 0; i--) { 818 | if (ka[i] != kb[i]) 819 | return false; 820 | } 821 | //equivalent values for every corresponding key, and 822 | //~~~possibly expensive deep test 823 | for (i = ka.length - 1; i >= 0; i--) { 824 | key = ka[i]; 825 | if (!expect.eql(a[key], b[key])) 826 | return false; 827 | } 828 | return true; 829 | } 830 | 831 | var json = (function () { 832 | "use strict"; 833 | 834 | if ('object' == typeof JSON && JSON.parse && JSON.stringify) { 835 | return { 836 | parse: nativeJSON.parse 837 | , stringify: nativeJSON.stringify 838 | } 839 | } 840 | 841 | var JSON = {}; 842 | 843 | function f(n) { 844 | // Format integers to have at least two digits. 845 | return n < 10 ? '0' + n : n; 846 | } 847 | 848 | function date(d, key) { 849 | return isFinite(d.valueOf()) ? 850 | d.getUTCFullYear() + '-' + 851 | f(d.getUTCMonth() + 1) + '-' + 852 | f(d.getUTCDate()) + 'T' + 853 | f(d.getUTCHours()) + ':' + 854 | f(d.getUTCMinutes()) + ':' + 855 | f(d.getUTCSeconds()) + 'Z' : null; 856 | }; 857 | 858 | var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, 859 | escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, 860 | gap, 861 | indent, 862 | meta = { // table of character substitutions 863 | '\b': '\\b', 864 | '\t': '\\t', 865 | '\n': '\\n', 866 | '\f': '\\f', 867 | '\r': '\\r', 868 | '"' : '\\"', 869 | '\\': '\\\\' 870 | }, 871 | rep; 872 | 873 | 874 | function quote(string) { 875 | 876 | // If the string contains no control characters, no quote characters, and no 877 | // backslash characters, then we can safely slap some quotes around it. 878 | // Otherwise we must also replace the offending characters with safe escape 879 | // sequences. 880 | 881 | escapable.lastIndex = 0; 882 | return escapable.test(string) ? '"' + string.replace(escapable, function (a) { 883 | var c = meta[a]; 884 | return typeof c === 'string' ? c : 885 | '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); 886 | }) + '"' : '"' + string + '"'; 887 | } 888 | 889 | 890 | function str(key, holder) { 891 | 892 | // Produce a string from holder[key]. 893 | 894 | var i, // The loop counter. 895 | k, // The member key. 896 | v, // The member value. 897 | length, 898 | mind = gap, 899 | partial, 900 | value = holder[key]; 901 | 902 | // If the value has a toJSON method, call it to obtain a replacement value. 903 | 904 | if (value instanceof Date) { 905 | value = date(key); 906 | } 907 | 908 | // If we were called with a replacer function, then call the replacer to 909 | // obtain a replacement value. 910 | 911 | if (typeof rep === 'function') { 912 | value = rep.call(holder, key, value); 913 | } 914 | 915 | // What happens next depends on the value's type. 916 | 917 | switch (typeof value) { 918 | case 'string': 919 | return quote(value); 920 | 921 | case 'number': 922 | 923 | // JSON numbers must be finite. Encode non-finite numbers as null. 924 | 925 | return isFinite(value) ? String(value) : 'null'; 926 | 927 | case 'boolean': 928 | case 'null': 929 | 930 | // If the value is a boolean or null, convert it to a string. Note: 931 | // typeof null does not produce 'null'. The case is included here in 932 | // the remote chance that this gets fixed someday. 933 | 934 | return String(value); 935 | 936 | // If the type is 'object', we might be dealing with an object or an array or 937 | // null. 938 | 939 | case 'object': 940 | 941 | // Due to a specification blunder in ECMAScript, typeof null is 'object', 942 | // so watch out for that case. 943 | 944 | if (!value) { 945 | return 'null'; 946 | } 947 | 948 | // Make an array to hold the partial results of stringifying this object value. 949 | 950 | gap += indent; 951 | partial = []; 952 | 953 | // Is the value an array? 954 | 955 | if (Object.prototype.toString.apply(value) === '[object Array]') { 956 | 957 | // The value is an array. Stringify every element. Use null as a placeholder 958 | // for non-JSON values. 959 | 960 | length = value.length; 961 | for (i = 0; i < length; i += 1) { 962 | partial[i] = str(i, value) || 'null'; 963 | } 964 | 965 | // Join all of the elements together, separated with commas, and wrap them in 966 | // brackets. 967 | 968 | v = partial.length === 0 ? '[]' : gap ? 969 | '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' : 970 | '[' + partial.join(',') + ']'; 971 | gap = mind; 972 | return v; 973 | } 974 | 975 | // If the replacer is an array, use it to select the members to be stringified. 976 | 977 | if (rep && typeof rep === 'object') { 978 | length = rep.length; 979 | for (i = 0; i < length; i += 1) { 980 | if (typeof rep[i] === 'string') { 981 | k = rep[i]; 982 | v = str(k, value); 983 | if (v) { 984 | partial.push(quote(k) + (gap ? ': ' : ':') + v); 985 | } 986 | } 987 | } 988 | } else { 989 | 990 | // Otherwise, iterate through all of the keys in the object. 991 | 992 | for (k in value) { 993 | if (Object.prototype.hasOwnProperty.call(value, k)) { 994 | v = str(k, value); 995 | if (v) { 996 | partial.push(quote(k) + (gap ? ': ' : ':') + v); 997 | } 998 | } 999 | } 1000 | } 1001 | 1002 | // Join all of the member texts together, separated with commas, 1003 | // and wrap them in braces. 1004 | 1005 | v = partial.length === 0 ? '{}' : gap ? 1006 | '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' : 1007 | '{' + partial.join(',') + '}'; 1008 | gap = mind; 1009 | return v; 1010 | } 1011 | } 1012 | 1013 | // If the JSON object does not yet have a stringify method, give it one. 1014 | 1015 | JSON.stringify = function (value, replacer, space) { 1016 | 1017 | // The stringify method takes a value and an optional replacer, and an optional 1018 | // space parameter, and returns a JSON text. The replacer can be a function 1019 | // that can replace values, or an array of strings that will select the keys. 1020 | // A default replacer method can be provided. Use of the space parameter can 1021 | // produce text that is more easily readable. 1022 | 1023 | var i; 1024 | gap = ''; 1025 | indent = ''; 1026 | 1027 | // If the space parameter is a number, make an indent string containing that 1028 | // many spaces. 1029 | 1030 | if (typeof space === 'number') { 1031 | for (i = 0; i < space; i += 1) { 1032 | indent += ' '; 1033 | } 1034 | 1035 | // If the space parameter is a string, it will be used as the indent string. 1036 | 1037 | } else if (typeof space === 'string') { 1038 | indent = space; 1039 | } 1040 | 1041 | // If there is a replacer, it must be a function or an array. 1042 | // Otherwise, throw an error. 1043 | 1044 | rep = replacer; 1045 | if (replacer && typeof replacer !== 'function' && 1046 | (typeof replacer !== 'object' || 1047 | typeof replacer.length !== 'number')) { 1048 | throw new Error('JSON.stringify'); 1049 | } 1050 | 1051 | // Make a fake root object containing our value under the key of ''. 1052 | // Return the result of stringifying the value. 1053 | 1054 | return str('', {'': value}); 1055 | }; 1056 | 1057 | // If the JSON object does not yet have a parse method, give it one. 1058 | 1059 | JSON.parse = function (text, reviver) { 1060 | // The parse method takes a text and an optional reviver function, and returns 1061 | // a JavaScript value if the text is a valid JSON text. 1062 | 1063 | var j; 1064 | 1065 | function walk(holder, key) { 1066 | 1067 | // The walk method is used to recursively walk the resulting structure so 1068 | // that modifications can be made. 1069 | 1070 | var k, v, value = holder[key]; 1071 | if (value && typeof value === 'object') { 1072 | for (k in value) { 1073 | if (Object.prototype.hasOwnProperty.call(value, k)) { 1074 | v = walk(value, k); 1075 | if (v !== undefined) { 1076 | value[k] = v; 1077 | } else { 1078 | delete value[k]; 1079 | } 1080 | } 1081 | } 1082 | } 1083 | return reviver.call(holder, key, value); 1084 | } 1085 | 1086 | 1087 | // Parsing happens in four stages. In the first stage, we replace certain 1088 | // Unicode characters with escape sequences. JavaScript handles many characters 1089 | // incorrectly, either silently deleting them, or treating them as line endings. 1090 | 1091 | text = String(text); 1092 | cx.lastIndex = 0; 1093 | if (cx.test(text)) { 1094 | text = text.replace(cx, function (a) { 1095 | return '\\u' + 1096 | ('0000' + a.charCodeAt(0).toString(16)).slice(-4); 1097 | }); 1098 | } 1099 | 1100 | // In the second stage, we run the text against regular expressions that look 1101 | // for non-JSON patterns. We are especially concerned with '()' and 'new' 1102 | // because they can cause invocation, and '=' because it can cause mutation. 1103 | // But just to be safe, we want to reject all unexpected forms. 1104 | 1105 | // We split the second stage into 4 regexp operations in order to work around 1106 | // crippling inefficiencies in IE's and Safari's regexp engines. First we 1107 | // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we 1108 | // replace all simple value tokens with ']' characters. Third, we delete all 1109 | // open brackets that follow a colon or comma or that begin the text. Finally, 1110 | // we look to see that the remaining characters are only whitespace or ']' or 1111 | // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. 1112 | 1113 | if (/^[\],:{}\s]*$/ 1114 | .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') 1115 | .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') 1116 | .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { 1117 | 1118 | // In the third stage we use the eval function to compile the text into a 1119 | // JavaScript structure. The '{' operator is subject to a syntactic ambiguity 1120 | // in JavaScript: it can begin a block or an object literal. We wrap the text 1121 | // in parens to eliminate the ambiguity. 1122 | 1123 | j = eval('(' + text + ')'); 1124 | 1125 | // In the optional fourth stage, we recursively walk the new structure, passing 1126 | // each name/value pair to a reviver function for possible transformation. 1127 | 1128 | return typeof reviver === 'function' ? 1129 | walk({'': j}, '') : j; 1130 | } 1131 | 1132 | // If the text is not JSON parseable, then a SyntaxError is thrown. 1133 | 1134 | throw new SyntaxError('JSON.parse'); 1135 | }; 1136 | 1137 | return JSON; 1138 | })(); 1139 | 1140 | if ('undefined' != typeof window) { 1141 | window.expect = module.exports; 1142 | } 1143 | 1144 | })( 1145 | this 1146 | , 'undefined' != typeof module ? module : {} 1147 | , 'undefined' != typeof exports ? exports : {} 1148 | ); 1149 | -------------------------------------------------------------------------------- /code-examples/testing/mocha/browser/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | my tests 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
        14 | 15 | 16 | -------------------------------------------------------------------------------- /code-examples/testing/mocha/browser/mocha.css: -------------------------------------------------------------------------------- 1 | 2 | body { 3 | font: 20px/1.5 "Helvetica Neue", Helvetica, Aria;, sans-serif; 4 | padding: 60px 50px; 5 | } 6 | 7 | #mocha h1, h2 { 8 | margin: 0; 9 | } 10 | 11 | #mocha h1 { 12 | font-size: 1em; 13 | font-weight: 200; 14 | } 15 | 16 | #mocha .suite .suite h1 { 17 | font-size: .8em; 18 | } 19 | 20 | #mocha h2 { 21 | font-size: 12px; 22 | font-weight: normal; 23 | cursor: pointer; 24 | } 25 | 26 | #mocha .suite { 27 | margin-left: 15px; 28 | } 29 | 30 | #mocha .test { 31 | margin-left: 15px; 32 | } 33 | 34 | #mocha .test:hover h2::after { 35 | position: relative; 36 | top: 0; 37 | right: -10px; 38 | content: '(view source)'; 39 | font-size: 12px; 40 | color: #888; 41 | } 42 | 43 | #mocha .test.pass::before { 44 | content: '✓'; 45 | font-size: 12px; 46 | display: block; 47 | float: left; 48 | margin-right: 5px; 49 | color: #00c41c; 50 | } 51 | 52 | #mocha .test.pending { 53 | color: #0b97c4; 54 | } 55 | 56 | #mocha .test.pending::before { 57 | content: '◦'; 58 | color: #0b97c4; 59 | } 60 | 61 | #mocha .test.fail { 62 | color: #c00; 63 | } 64 | 65 | #mocha .test.fail pre { 66 | color: black; 67 | } 68 | 69 | #mocha .test.fail::before { 70 | content: '✖'; 71 | font-size: 12px; 72 | display: block; 73 | float: left; 74 | margin-right: 5px; 75 | color: #c00; 76 | } 77 | 78 | #mocha .test pre.error { 79 | color: #c00; 80 | } 81 | 82 | #mocha .test pre { 83 | display: inline-block; 84 | font: 12px/1.5 monaco, monospace; 85 | margin: 5px; 86 | padding: 15px; 87 | border: 1px solid #eee; 88 | border-bottom-color: #ddd; 89 | -webkit-border-radius: 3px; 90 | -webkit-box-shadow: 0 1px 3px #eee; 91 | } 92 | 93 | #error { 94 | color: #c00; 95 | font-size: 1.5 em; 96 | font-weight: 100; 97 | letter-spacing: 1px; 98 | } 99 | 100 | #stats { 101 | position: fixed; 102 | top: 30px; 103 | right: 30px; 104 | font-size: 12px; 105 | margin: 0; 106 | color: #888; 107 | } 108 | 109 | #stats .progress { 110 | margin-bottom: 10px; 111 | } 112 | 113 | #stats em { 114 | color: black; 115 | } 116 | 117 | #stats li { 118 | list-style: none; 119 | } -------------------------------------------------------------------------------- /code-examples/testing/mocha/browser/my-test.js: -------------------------------------------------------------------------------- 1 | describe('my tests', function () { 2 | it('should not throw', function () { 3 | expect(1 + 1).to.be(2); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /code-examples/testing/mocha/tdd/tdd.js: -------------------------------------------------------------------------------- 1 | 2 | suite('net', function () { 3 | 4 | suite('Stream', function () { 5 | 6 | var client; 7 | 8 | suiteSetup(function () { 9 | client = net.connect(3000, 'localhost'); 10 | }); 11 | 12 | test('connect event', function (done) { 13 | client.on('connect', done); 14 | }); 15 | 16 | test('receiving data', function (done) { 17 | client.write(''); 18 | client.once('data', done); 19 | }); 20 | 21 | suiteTeardown(function () { 22 | client.end(); 23 | }); 24 | 25 | }); 26 | 27 | }); 28 | -------------------------------------------------------------------------------- /code-examples/testing/mocha/test.js: -------------------------------------------------------------------------------- 1 | describe('a topic', function () { 2 | 3 | it('should test something', function () { 4 | 5 | }); 6 | 7 | describe('another topic', function () { 8 | 9 | it('should test something else', function () { 10 | 11 | }); 12 | 13 | }); 14 | 15 | }); 16 | -------------------------------------------------------------------------------- /code-examples/testing/simple-testing/assert-example.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var assert = require('assert'); 7 | 8 | /** 9 | * Assert condition 10 | */ 11 | 12 | var now = Date.now() 13 | console.log(now); 14 | assert.ok(now % 2 == 0); 15 | -------------------------------------------------------------------------------- /code-examples/testing/simple-testing/test-program/express-app/search.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var qs = require('querystring') 7 | , http = require('http') 8 | 9 | /** 10 | * Search function. 11 | * 12 | * @param {String} search query 13 | * @param {Function} callback 14 | * @api public 15 | */ 16 | 17 | module.exports = function search (query, fn) { 18 | http.request({ 19 | host: 'search.twitter.com' 20 | , path: '/search.json?' + qs.stringify({ q: query }) 21 | }, function (res) { 22 | res.setEncoding('utf8'); 23 | 24 | var body = ''; 25 | 26 | res.on('data', function (chunk) { 27 | body += chunk; 28 | }); 29 | 30 | res.on('end', function () { 31 | try { 32 | var obj = JSON.parse(body); 33 | } catch (e) { 34 | return fn(new Error('Bad twitter response')); 35 | } 36 | 37 | fn(null, obj.results); 38 | }); 39 | }).end() 40 | }; 41 | -------------------------------------------------------------------------------- /code-examples/testing/simple-testing/test-program/express-app/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module requirements. 4 | */ 5 | 6 | var express = require('express') 7 | , search = require('./search') 8 | 9 | /** 10 | * Create app. 11 | */ 12 | 13 | var app = express.createServer() // NOTE: express3 is express() 14 | 15 | /** 16 | * Configuration 17 | */ 18 | 19 | app.set('view engine', 'ejs'); 20 | app.set('views', __dirname + '/views'); 21 | app.set('view options', { layout: false }); // NOTE: express3 remove 22 | 23 | /** 24 | * Routes 25 | */ 26 | 27 | app.get('/', function (req, res) { 28 | res.render('index'); 29 | }); 30 | 31 | app.get('/search', function (req, res, next) { 32 | search(req.query.q, function (err, tweets) { 33 | if (err) return next(err); 34 | res.render('search', { results: tweets, search: req.query.q }); 35 | }); 36 | }); 37 | 38 | /** 39 | * Listen 40 | */ 41 | 42 | app.listen(3000); 43 | -------------------------------------------------------------------------------- /code-examples/testing/simple-testing/test-program/express-app/views/index.ejs: -------------------------------------------------------------------------------- 1 | 2 |

        Twitter app

        3 | 4 |

        Please enter your search term:

        5 |
        6 | 7 |
        43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /code-examples/websocket/echo/step-3/server.js: -------------------------------------------------------------------------------- 1 | var express = require('express') 2 | , wsio = require('websocket.io') 3 | 4 | /** 5 | * Create express app. 6 | */ 7 | 8 | var app = express.createServer(); 9 | 10 | /** 11 | * Attach websocket server. 12 | */ 13 | 14 | var ws = wsio.attach(app); 15 | 16 | /** 17 | * Serve our code 18 | */ 19 | 20 | app.use(express.static('public')) 21 | 22 | /** 23 | * Listening on connections 24 | */ 25 | 26 | ws.on('connection', function (socket) { 27 | socket.on('message', function (msg) { 28 | console.log(' \033[96mgot:\033[39m ' + msg); 29 | socket.send(msg); 30 | }); 31 | }); 32 | 33 | /** 34 | * Listen 35 | */ 36 | 37 | app.listen(3000); 38 | --------------------------------------------------------------------------------