{"_id":"appex","_rev":"241-b004834771a6031869a78b3976c973db","name":"appex","dist-tags":{"latest":"0.6.9"},"versions":{"0.0.1":{"name":"appex","version":"0.0.1","keywords":["appex"],"author":{"name":"sinclair"},"_id":"appex@0.0.1","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"5bfffc96e115fb15e7dea7473e1320ed4eec7f02","tarball":"https://registry.npmjs.org/appex/-/appex-0.0.1.tgz","integrity":"sha512-WIuG0NAZZaG1HWvmd2F55a/1b1PG6dBPK4FVuxEXI0JZPvF8UyQnY/ay/dH9NvD3rH+2+4z2llybd+ngb/6c2w==","signatures":[{"sig":"MEUCIQDcXNDVDkAQJwg/G7Ezz2MGxIOI0f8uq0I4UcdI19HmlAIgblO6+N1ovPM00TheyL6M1XlW+HJTcgNt+rRrHKpn6WM=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"# appex\r\n\r\nwork in progress.\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"http://www.apache.org/licenses/LICENSE-2.0.html","type":"Apache 2.0"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"a work in progress","directories":{},"dependencies":{},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.0.2":{"name":"appex","version":"0.0.2","keywords":["appex","typescript"],"author":{"name":"sinclair"},"_id":"appex@0.0.2","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"34133fa53b1e6b016e6e095259d620cb8b7ea807","tarball":"https://registry.npmjs.org/appex/-/appex-0.0.2.tgz","integrity":"sha512-ZGvtX2eRmWSLeonnPU5q9KOMKvrvUVmAl+9FFixC7wysbN7XBGX47DtIUcdqw12jXb91+zu7pbdM8rwD7viDnA==","signatures":[{"sig":"MEYCIQCSajCD2SP1fwxzJOoOB5/DqRd9ulUVTFVp0ENj+Mz5BwIhAMmY4hSu8oSZ4uhp1TXr7Jgh/z/dAp/JciTT8e1vWGJ6","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"﻿# appex\r\n\r\ntypescript + nodejs = \\o/\r\n\r\n## install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n\r\n## example usage\r\n\r\n```javascript\r\n\r\n// app.js\r\n\r\nvar appex = require('appex');\r\n \r\nvar compiler = new appex.Compiler();\r\n\r\ncompiler.compile(\"./program.ts\", function(compilation) {\r\n    \r\n\tvar module = new appex.Module(compilation.script, compilation.reflection);\r\n\r\n\tfor(var n in module.handles) {\r\n\r\n\t\tconsole.log( module.handles[n] ); // write type information to the console.\r\n\t}\r\n\r\n});\r\n\r\n```\r\n\r\n```javascript\r\n\r\n// program.ts\r\n\r\nexport module application {\r\n\r\n\texport class Program {\r\n\r\n\t\tconstructor() {\r\n\t\t\t\r\n\t\t\t\r\n\t\t}\r\n\t}\r\n\r\n}\r\n\r\n```","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"http://www.apache.org/licenses/LICENSE-2.0.html","type":"Apache 2.0"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"nodejs + typescript","directories":{},"dependencies":{"typescript.api":"0.5.1"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.1.1":{"name":"appex","version":"0.1.1","keywords":["typescript","web services","http","compiler","rest"],"author":{"name":"sinclair"},"_id":"appex@0.1.1","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"eb192ce5f1fcc7004219c8636a97a61a152f2a92","tarball":"https://registry.npmjs.org/appex/-/appex-0.1.1.tgz","integrity":"sha512-UWhpDsZXxAIt/bJKljruNlJI/AIhiVTTUiisT0aGh2efJi7unRT+aU2vykq71y7YizHg2VQLl36f+7ZqHUyJkg==","signatures":[{"sig":"MEYCIQC4lytowW77QfkvI39Ju/tW2Bq99HvF8uFt+tgaiyGzdwIhAJ4I2BhLdKEMHaW+oYA4rbVtGI/nG6EZSrLxMafojvTy","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/assets/logo.jpg)\r\n\r\n### nodejs web services with the typescript programming language\r\n\r\n## install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n\r\n* [overview](#overview)\r\n* [function signatures](#function_signatures)\r\n\t* [http handler](#function_signatures_http_handler)\r\n\t* [json handler](#function_signatures_json_handler)\r\n* [function visibility](#function_visibility)\r\n* [function routing](#function_routing)\r\n\r\n\r\n<a name=\"overview\" />\r\n## overview\r\n\r\nAppex is a nodejs web application and service framework built on top of the TypeScript programming language. Appex \r\nenables nodejs developers to expose typescript functions as http endpoints as well as generate meaningful service\r\nmeta data for clients who consume them. \r\n\r\n### typescript\r\n\r\n```javascript\r\n// program.ts\r\n\r\ndeclare var require; \r\n\r\n// url: http://localhost:1337/\r\nexport function index (context:any): void { \r\n  \r\n    context.response.write('home');\r\n\r\n    context.response.end(); \r\n}\r\n\r\n// url: http://localhost:1337/about\r\nexport function about (context:any): void { \r\n\t\r\n    context.response.write('about');\r\n\r\n    context.response.end();\r\n}\r\n\r\nexport module services {\r\n\r\n    // url: http://localhost:1337/services/dir\r\n    export function dir(context:any, path:string, callback:(contents:string[]) => void) {\r\n        \r\n        require('fs').readdir(path || './', (error, contents) => {\r\n            \r\n            callback(contents);\r\n\r\n        });\r\n    }\r\n}\r\n\r\n```\r\n\r\n### javascript\r\n\r\n```javascript\r\n// app.js\r\n\r\nvar appex   = require('appex');\r\n\r\nvar runtime = appex.runtime ({ source : './program.ts', devmode : true });\r\n\r\nrequire('http').createServer( function(request, response) {\r\n    \r\n    runtime(request, response);\r\n    \r\n}).listen(5444);\r\n```\r\n<a name=\"function_signatures\" />\r\n## function signatures\r\n\r\nAppex supports two distinct function signatures. http handler signatures and json handler signatures.\r\n\r\n<a name=\"function_signatures_http_handler\" />\r\n### http handler signature\r\n\r\nA http handler method can be created with the following function signature. The context\r\nargument contains the http request and response objects.\r\n\r\n```javascript\r\nexport function method(context:any) : void {\r\n\r\n\tcontext.response.write('hello world');\r\n\t\r\n\tcontext.response.end();\r\n\r\n}\r\n```\r\n<a name=\"function_signatures_json_handler\" />\r\n### json handler signature\r\n\r\nA json handler function is a function which will automatically accept a HTTP POST'ed json string and \r\npass it to the function as a object parameter. in addition, json handler functions also require that \r\na response object be returned on the callback, which in turn will be passed back as a http response\r\nas a json string.\r\n\r\nA http handler method can be created with the following function signature. The context\r\nargument contains the http request and response objects.\r\n\r\n```javascript\r\nexport function method(context:any, request:any, callback:(response:any) => void) {\r\n\r\n\tcallback(request); // echo\r\n\r\n}\r\n```\r\n<a name=\"function_routing\" />\r\n## function routing\r\n\r\nAppex creates url routing tables based on a function name and module scope. For example consider the following...\r\n\r\n```javascript\r\nexport function index   (context:any) { }\r\n\r\nexport function about   (context:any) { }\r\n\r\nexport function contact (context:any) { }\r\n\r\nexport module services.customers {\r\n\r\n\texport function insert(context:any) : void { }\r\n\t\r\n\texport function update(context:any) : void { }\r\n\t\r\n\texport function delete(context:any) : void { }\r\n}\r\n```\r\n\r\nwill create the following routes:\r\n\r\n```javascript\r\nhttp://[host]:[port]/\r\n\r\nhttp://[host]:[port]/about\r\n\r\nhttp://[host]:[port]/contact\r\n\r\nhttp://[host]:[port]/services/customers/insert\r\n\r\nhttp://[host]:[port]/services/customers/update\r\n\r\nhttp://[host]:[port]/services/customers/delete\r\n```\r\n<a name=\"function_visibility\" />\r\n## function visibility\r\n\r\nAppex only exposes 'exported' functions over http. From this developers infer notions of public and private over http. \r\n\r\nConsider the following example:\r\n\r\n```javascript\r\n\r\nmodule private_module {\r\n\r\n\texport function public_method () {\r\n\t\r\n\t\t// this function is exported, but as this module is \r\n\t\t\r\n\t\t// not exported, neither is this method.\r\n\t}\r\n}\r\n\r\nfunction private_function() {\r\n\r\n\t// this method is private\r\n}\r\n\r\nexport function public_function   (context:any) { \r\n\r\n\tprivate_function(); // ok\r\n\t\r\n\tprivate_module.public_method(); // ok\r\n}\r\n```\r\n\r\nwill result in the following routes.\r\n\r\n```javascript\r\nhttp://[host]:[port]/public_function\r\n```\r\n\r\n\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"http://www.apache.org/licenses/LICENSE-2.0.html","type":"Apache 2.0"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"develop nodejs web services with the typescript programming language.","directories":{},"dependencies":{"typescript.api":"0.5.1"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.1.2":{"name":"appex","version":"0.1.2","keywords":["typescript","web services","http","compiler","rest"],"author":{"name":"sinclair"},"_id":"appex@0.1.2","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"3daf304b1bc5d2a8159cd4d40f265d1f6e62c1e6","tarball":"https://registry.npmjs.org/appex/-/appex-0.1.2.tgz","integrity":"sha512-yBb3uaoP/GSaJBhRxe44diTjC0AjB5QfZJOccartPURDGNJKh4/Ai6bLG6BQhP52q85LuvCu7BTreC+q7r1fBg==","signatures":[{"sig":"MEQCIEwVpKrUYGC73iCDZ2ZcWZ7YLlygLKfjAVHFzPwN3cEoAiAm0LZhBsGN9dEoJkyKa85RdQ2zZzD9VvgPztUUPPElgw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/assets/logo.jpg)\r\n\r\n### develop nodejs web services with typescript\r\n\r\n## install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n\r\n* [overview](#overview)\r\n* [getting started](#getting_started)\r\n* [getting started on express](#getting_started_on_express)\r\n* [function signatures](#function_signatures)\r\n\t* [http handler](#function_signatures_http_handler)\r\n\t* [json handler](#function_signatures_json_handler)\r\n* [function visibility](#function_visibility)\r\n* [function routing](#function_routing)\r\n\r\n\r\n<a name=\"overview\" />\r\n## overview\r\n\r\nAppex is a nodejs web application and service framework built on top of the TypeScript programming language. Appex \r\nenables nodejs developers to expose typescript functions as http endpoints as well as generate meaningful service\r\nmeta data for clients who consume them. \r\n\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n```javascript\r\n//----------------------------------------------\r\n// file: program.ts\r\n//----------------------------------------------\r\nexport module services {\r\n\t\r\n\t// url: http://localhost:3000/services/message\r\n\texport function message (context:any): void { \r\n\t\t\r\n\t\tcontext.response.write('hello typescript');\r\n\r\n\t\tcontext.response.end(); \r\n\t}\r\n}\r\n//----------------------------------------------\r\n// file: app.js\r\n//----------------------------------------------\r\n\r\nvar appex   = require('appex');\r\n\r\nvar runtime = appex.runtime ({ source : './program.ts', devmode : true });\r\n\r\nrequire('http').createServer( runtime ).listen(3000);\r\n```\r\n<a name=\"getting_started_on_express\" />\r\n## getting started on express\r\n```javascript\r\n//----------------------------------------------\r\n// file: program.ts\r\n//----------------------------------------------\r\nexport module services {\r\n\t\r\n\t// url: http://localhost:3000/services/message\r\n\texport function message (context:any): void { \r\n\t\t\r\n\t\tcontext.response.write('hello typescript');\r\n\r\n\t\tcontext.response.end(); \r\n\t}\r\n}\r\n\r\n//----------------------------------------------\r\n// file: app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex.runtime( { source:'./program.ts', devmode:true } ) );\r\n\r\napp.get('/', function(req, res){\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"function_signatures\" />\r\n## function signatures\r\n\r\nAppex supports two distinct function signatures. http handler signatures and json handler signatures.\r\n\r\n<a name=\"function_signatures_http_handler\" />\r\n### http handler signature\r\n\r\nA http handler method can be created with the following function signature. The context\r\nargument contains the http request and response objects.\r\n\r\n```javascript\r\nexport function method(context:any) : void {\r\n\r\n\tcontext.response.write('hello world');\r\n\t\r\n\tcontext.response.end();\r\n\r\n}\r\n```\r\n<a name=\"function_signatures_json_handler\" />\r\n### json handler signature\r\n\r\nA json handler function is a function which will automatically accept a HTTP POST'ed json string and \r\npass it to the function as a object parameter. in addition, json handler functions also require that \r\na response object be returned on the callback, which in turn will be passed back as a http response\r\nas a json string.\r\n\r\nA http handler method can be created with the following function signature. The context\r\nargument contains the http request and response objects.\r\n\r\n```javascript\r\nexport function method(context:any, request:any, callback:(response:any) => void) {\r\n\r\n\tcallback(request); // echo\r\n\r\n}\r\n```\r\n<a name=\"function_routing\" />\r\n## function routing\r\n\r\nAppex creates url routing tables based on a function name and module scope. For example consider the following...\r\n\r\n```javascript\r\nexport function index   (context:any) { }\r\n\r\nexport function about   (context:any) { }\r\n\r\nexport function contact (context:any) { }\r\n\r\nexport module services.customers {\r\n\r\n\texport function insert(context:any) : void { }\r\n\t\r\n\texport function update(context:any) : void { }\r\n\t\r\n\texport function delete(context:any) : void { }\r\n}\r\n```\r\n\r\nwill create the following routes:\r\n\r\n```javascript\r\nhttp://[host]:[port]/\r\n\r\nhttp://[host]:[port]/about\r\n\r\nhttp://[host]:[port]/contact\r\n\r\nhttp://[host]:[port]/services/customers/insert\r\n\r\nhttp://[host]:[port]/services/customers/update\r\n\r\nhttp://[host]:[port]/services/customers/delete\r\n```\r\n<a name=\"function_visibility\" />\r\n## function visibility\r\n\r\nAppex only exposes 'exported' functions over http. From this developers infer notions of public and private over http. \r\n\r\nConsider the following example:\r\n\r\n```javascript\r\n\r\nmodule private_module {\r\n\r\n\texport function public_method () {\r\n\t\r\n\t\t// this function is exported, but as this module is \r\n\t\t\r\n\t\t// not exported, neither is this method.\r\n\t}\r\n}\r\n\r\nfunction private_function() {\r\n\r\n\t// this method is private\r\n}\r\n\r\nexport function public_function   (context:any) { \r\n\r\n\tprivate_function(); // ok\r\n\t\r\n\tprivate_module.public_method(); // ok\r\n}\r\n```\r\n\r\nwill result in the following routes.\r\n\r\n```javascript\r\nhttp://[host]:[port]/public_function\r\n```\r\n\r\n\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"http://www.apache.org/licenses/LICENSE-2.0.html","type":"Apache 2.0"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"develop nodejs web services with the typescript programming language.","directories":{},"dependencies":{"typescript.api":"0.5.1"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.2.0":{"name":"appex","version":"0.2.0","keywords":["typescript","web services","http","compiler","rest"],"author":{"name":"sinclair"},"_id":"appex@0.2.0","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"bf2d6c26f473fd39ec5068f467a7d599949e38af","tarball":"https://registry.npmjs.org/appex/-/appex-0.2.0.tgz","integrity":"sha512-k6jq69iRAcehboMLXsipMEymcE98tXk6fLHk8K419/2QWyxMiTHiFgPhG/DxgHjQi/Q95kyBG5vTOZNz/iiwHA==","signatures":[{"sig":"MEQCIDBJDxRajHO8cOXO8wuu+gIT845SOX9mar/GaIaj0fH/AiBHGFuOI8ugh1oT4CUlIC25QqoCmim70kkloEzFIWzBHw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/assets/logo.jpg)\r\n\r\n### develop nodejs web services with [typescript](http://www.typescriptlang.org/)\r\n\r\n## install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n\r\n* [overview](#overview)\r\n* [getting started](#getting_started)\r\n* [getting started on express](#getting_started_on_express)\r\n* [developing with appex](#development_mode)\r\n* [functions](#functions)\r\n\t* [http handler function](#http_handler_function)\r\n\t* [json handler function](#json_handler_function)\r\n\t* [public and private functions](#public_private_functions)\r\n\t* [the index function](#the_index_function)\t\r\n\t* [routing with modules and functions](#function_routing)\r\n* [structuring projects](#structuring_projects)\r\n* [typescript resources](#resources)\r\n\r\n<a name=\"overview\" />\r\n## overview\r\n\r\nAppex is a nodejs web application and service framework built on top of the TypeScript programming language. Appex \r\nenables nodejs developers to expose typescript functions as http endpoints as well as generate meaningful service\r\nmeta data for clients to consume.\r\n\r\nAppex also provides a dynamic compilation environment for typescript to aid in development. Appex will effeciently \r\nmanage compilation in the background without the need to restart the web server, or use addition modules.\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n```javascript\r\n//----------------------------------------------\r\n// file: program.ts\r\n//----------------------------------------------\r\nexport module services {\r\n\t\r\n\t// url: http://localhost:3000/services/message\r\n\texport function message (context) { \r\n\t\t\r\n\t\tcontext.response.write('hello typescript');\r\n\r\n\t\tcontext.response.end(); \r\n\t}\r\n}\r\n//----------------------------------------------\r\n// file: app.js\r\n//----------------------------------------------\r\n\r\nvar appex   = require('appex');\r\n\r\nvar runtime = appex.runtime ({ source : './program.ts', devmode : true });\r\n\r\nrequire('http').createServer( runtime ).listen(3000);\r\n```\r\n<a name=\"getting_started_on_express\" />\r\n## getting started on express\r\n```javascript\r\n//----------------------------------------------\r\n// file: program.ts\r\n//----------------------------------------------\r\n\r\nexport module services {\r\n\t\r\n\t// url: http://localhost:3000/services/message\r\n\texport function message (context) { \r\n\t\t\r\n\t\tcontext.response.write('hello typescript');\r\n\r\n\t\tcontext.response.end(); \r\n\t}\r\n}\r\n\r\n//----------------------------------------------\r\n// file: app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex.runtime( { source:'./program.ts', devmode:true } ) );\r\n\r\napp.get('/', function(req, res){\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"development_mode\" />\r\n## developing with appex\r\n\r\nTo enable development mode, set the devmode option to true on the runtime option parameter.\r\n\r\n```javascript \r\n// enable dynamic compilations with the devmode option.\r\nvar runtime = appex.runtime ({ source : './program.ts', devmode : true }); \r\n```\r\n\r\nAppex is built directly on top of the Microsoft TypeScript 0.9 compiler and leverages it for tight\r\nintegration with the nodejs platform. By enabling the 'devmode' option will have the compiler\r\neffiecently rebuild typescript source code on each request made to the server. \r\n\r\nAppex achieves performance in this regard by leveraging features introduced in\r\nTS 0.9 which allows incremental building / caching of typescript compilation units.\r\n\r\nIn addition to this, compilations are run in a background worker process to ensure they do interupt\r\nrequests being served on the web process.\r\n\r\n![](https://raw.github.com/sinclairzx81/appex/master/assets/devmode.jpg)\r\n\r\nThe benefit to this is that updates can be made to source files without needing to restart the web process. Additionally, \r\nsyntactic errors made in typescript source code do not bring the web process. Everything stays running (excluding runtime \r\nerrors).\r\n\r\nAppex will output detailed syntax and type errors on the main process stdout stream, as well as a http response.\r\n\r\n<a name=\"functions\" />\r\n## functions\r\n\r\nAppex supports two types of functions, http handler functions, and json handler functions. \r\n\r\nAppex will only create http handlers for functions a specific signature, these are outlined below.\r\n\r\n<a name=\"http_handler_function\" />\r\n### http handler function\r\n\r\nA http handler method can be created with the following function signature.\r\n\r\n* arg0 - the http context which contains the  http request and response.\r\n\r\nThe return type is optional. http handler functions should complete the http request.\r\n\r\n```javascript\r\nexport function method(context:any) : void {\r\n\r\n\tcontext.response.write('hello world');\r\n\t\r\n\tcontext.response.end();\r\n\r\n}\r\n```\r\n<a name=\"json_handler_function\" />\r\n### json handler function\r\n\r\nA json handler is a function which will accept HTTP POST'ed json strings and \r\npass it to the function as a object. A json handler has three distinct arguments: \r\n\r\n* arg0 - the http context which contains the  http request and response.\r\n* arg1 - the json request object \r\n* arg2 - a typescript callback with a single argument for the object response. \r\n\r\nThe return type is optional. json handler functions \"must\" call the callback to\r\ncomplete the request.\r\n\r\n```javascript\r\nexport function method(context:any, request:any, callback:(response:any) => void) : void {\r\n\r\n\tcallback(request); // echo the object back.\r\n\r\n}\r\n```\r\n\r\n<a name=\"public_private_functions\" />\r\n### public and private functions\r\n\r\nAppex extends TypeScripts concept of visibility to include visibility over http. From this\r\ndevelopers and control which functions are exported as http handlers.  \r\n\r\nAppex will create routes only for functions marked with export and for functions that reside\r\nwithing modules with export.\r\n\r\nConsider the following example:\r\n\r\n```javascript\r\n\r\nmodule private_module {\r\n\r\n\texport function public_method () {\r\n\t\r\n\t\t// this function is exported, but as this module is \r\n\t\t\r\n\t\t// not exported, neither is this method.\r\n\t}\r\n}\r\n\r\nfunction private_function() {\r\n\r\n\t// this method is private\r\n}\r\n\r\nexport function public_function   (context:any) { \r\n\r\n\tprivate_function(); // ok\r\n\t\r\n\tprivate_module.public_method(); // ok\r\n}\r\n```\r\n\r\nwhich will result in a single route.\r\n\r\n```javascript\r\nhttp://[host]:[port]/public_function\r\n```\r\n<a name=\"the_index_function\" />\r\n### the index function\r\n\r\nAppex denotes that functions named 'index' route to the current module scope. As demonstrated below. \r\n\r\n```javascript\r\nexport function index(context) {}\r\nexport module blogs {\r\n\texport function index (context) { }\r\n\texport function get   (context) { }\r\n}\r\n\r\n// results in the following routes\r\n// http://[host]:[port]/\r\n// http://[host]:[port]/blogs\r\n// http://[host]:[port]/blogs/get\r\n```\r\n\r\n<a name=\"function_routing\" />\r\n### routing with modules and functions\r\n\r\nAppex creates url routing tables based on function name and module scope. For example consider the following...\r\n\r\n```javascript\r\nexport function index   (context:any) { }\r\nexport function about   (context:any) { }\r\nexport function contact (context:any) { }\r\nexport module services.customers {\r\n\texport function insert(context:any) : void { }\r\n\texport function update(context:any) : void { }\r\n\texport function delete(context:any) : void { }\r\n}\r\n\r\n// results in the following routes\r\n// http://[host]:[port]/\r\n// http://[host]:[port]/about\r\n// http://[host]:[port]/contact\r\n// http://[host]:[port]/services/customers/insert\r\n// http://[host]:[port]/services/customers/update\r\n// http://[host]:[port]/services/customers/delete\r\n```\r\n\r\n<a name=\"structuring_projects\" />\r\n## structuring projects\r\n\r\nAppex leverages TypeScript's ability to reference source files with the <reference> element. Appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nrequire('http').createServer(  appex.runtime ({ source : './index.ts', devmode : true }) ).listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"pages.ts\" />\r\n/// <reference path=\"users.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\nexport function index   (context) { /* handle request */ }\r\nexport function about   (context) { /* handle request */ }\r\nexport function contact (context) { /* handle request */ }\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\r\n\texport function login  (context) { /* handle request */ }\r\n\texport function logout (context) { /* handle request */ }\r\n}\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## typescript resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"http://www.apache.org/licenses/LICENSE-2.0.html","type":"Apache 2.0"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"develop nodejs web services with the typescript programming language.","directories":{},"dependencies":{"typescript.api":"0.5.1"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.2.1":{"name":"appex","version":"0.2.1","keywords":["typescript","web services","http","compiler","rest"],"author":{"name":"sinclair"},"_id":"appex@0.2.1","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"19184344b968e237c3b5fc0670d7b68ae7244091","tarball":"https://registry.npmjs.org/appex/-/appex-0.2.1.tgz","integrity":"sha512-90rrnD8tSsiciYQ+CnMrS40gCdESKr9ztuX1bh2YlpzMVRBRDSTTxRbqPl6kmOgDpifomwdEnM4RjM37iHeKdg==","signatures":[{"sig":"MEUCIQCnsCMWqzyS5Rk6C1SuclbW2tH8QYPAjyQOYtCETfyAKwIgfa3mfusfT8XwrvhB3tIWQHBEkycqrhdYe4PAodZNmqM=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/assets/logo.jpg)\r\n\r\n### develop nodejs web services with [typescript](http://www.typescriptlang.org/)\r\n\r\n## install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n\r\n* [overview](#overview)\r\n* [getting started](#getting_started)\r\n* [getting started on express](#getting_started_on_express)\r\n* [developing with appex](#development_mode)\r\n* [functions](#functions)\r\n\t* [http handler function](#http_handler_function)\r\n\t* [json handler function](#json_handler_function)\r\n\t* [public and private functions](#public_private_functions)\r\n\t* [the index function](#the_index_function)\t\r\n\t* [routing with modules and functions](#function_routing)\r\n* [structuring projects](#structuring_projects)\r\n* [typescript resources](#resources)\r\n\r\n<a name=\"overview\" />\r\n## overview\r\n\r\nAppex is a nodejs web application and service framework built on top of the TypeScript programming language. Appex \r\nenables nodejs developers to expose typescript functions as http endpoints as well as generate meaningful service\r\nmeta data for clients to consume.\r\n\r\nAppex also provides a dynamic compilation environment for typescript to aid in development. Appex will effeciently \r\nmanage compilation in the background without the need to restart the web server, or use addition modules.\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n```javascript\r\n//----------------------------------------------\r\n// file: program.ts\r\n//----------------------------------------------\r\nexport module services {\r\n\t\r\n\t// url: http://localhost:3000/services/message\r\n\texport function message (context) { \r\n\t\t\r\n\t\tcontext.response.write('hello typescript');\r\n\r\n\t\tcontext.response.end(); \r\n\t}\r\n}\r\n//----------------------------------------------\r\n// file: app.js\r\n//----------------------------------------------\r\n\r\nvar appex   = require('appex');\r\n\r\nvar runtime = appex.runtime ({ source : './program.ts', devmode : true });\r\n\r\nrequire('http').createServer( runtime ).listen(3000);\r\n```\r\n<a name=\"getting_started_on_express\" />\r\n## getting started on express\r\n```javascript\r\n//----------------------------------------------\r\n// file: program.ts\r\n//----------------------------------------------\r\n\r\nexport module services {\r\n\t\r\n\t// url: http://localhost:3000/services/message\r\n\texport function message (context) { \r\n\t\t\r\n\t\tcontext.response.write('hello typescript');\r\n\r\n\t\tcontext.response.end(); \r\n\t}\r\n}\r\n\r\n//----------------------------------------------\r\n// file: app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex.runtime( { source:'./program.ts', devmode:true } ) );\r\n\r\napp.get('/', function(req, res){\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"development_mode\" />\r\n## developing with appex\r\n\r\nTo enable development mode, set the devmode option to true on the runtime option parameter.\r\n\r\n```javascript \r\n// enable dynamic compilations with the devmode option.\r\nvar runtime = appex.runtime ({ source : './program.ts', devmode : true }); \r\n```\r\n\r\nAppex is built directly on top of the Microsoft TypeScript 0.9 compiler and leverages it for tight\r\nintegration with the nodejs platform. By enabling the 'devmode' option will have the compiler\r\neffiecently rebuild typescript source code on each request made to the server. \r\n\r\nAppex achieves performance in this regard by leveraging features introduced in\r\nTS 0.9 which allows incremental building / caching of typescript compilation units.\r\n\r\nIn addition to this, compilations are run in a background worker process to ensure they do interupt\r\nrequests being served on the web process.\r\n\r\n![](https://raw.github.com/sinclairzx81/appex/master/assets/devmode.jpg)\r\n\r\nThe benefit to this is that updates can be made to source files without needing to restart the web process. Additionally, \r\nsyntactic errors made in typescript source code do not bring the web process. Everything stays running (excluding runtime \r\nerrors).\r\n\r\nAppex will output detailed syntax and type errors on the main process stdout stream, as well as a http response.\r\n\r\n<a name=\"functions\" />\r\n## functions\r\n\r\nAppex supports two types of functions, http handler functions, and json handler functions. \r\n\r\nAppex will only create http handlers for functions a specific signature, these are outlined below.\r\n\r\n<a name=\"http_handler_function\" />\r\n### http handler function\r\n\r\nA http handler method can be created with the following function signature.\r\n\r\n* arg0 - the http context which contains the  http request and response.\r\n\r\nThe return type is optional. http handler functions should complete the http request.\r\n\r\n```javascript\r\nexport function method(context:any) : void {\r\n\r\n\tcontext.response.write('hello world');\r\n\t\r\n\tcontext.response.end();\r\n\r\n}\r\n```\r\n<a name=\"json_handler_function\" />\r\n### json handler function\r\n\r\nA json handler is a function which will accept HTTP POST'ed json strings and \r\npass it to the function as a object. A json handler has three distinct arguments: \r\n\r\n* arg0 - the http context which contains the  http request and response.\r\n* arg1 - the json request object \r\n* arg2 - a typescript callback with a single argument for the object response. \r\n\r\nThe return type is optional. json handler functions \"must\" call the callback to\r\ncomplete the request.\r\n\r\n```javascript\r\nexport function method(context:any, request:any, callback:(response:any) => void) : void {\r\n\r\n\tcallback(request); // echo the object back.\r\n\r\n}\r\n```\r\n\r\n<a name=\"public_private_functions\" />\r\n### public and private functions\r\n\r\nAppex extends TypeScripts concept of visibility to include visibility over http. From this\r\ndevelopers and control which functions are exported as http handlers.  \r\n\r\nAppex will create routes only for functions marked with export and for functions that reside\r\nwithing modules with export.\r\n\r\nConsider the following example:\r\n\r\n```javascript\r\n\r\nmodule private_module {\r\n\r\n\texport function public_method () {\r\n\t\r\n\t\t// this function is exported, but as this module is \r\n\t\t\r\n\t\t// not exported, neither is this method.\r\n\t}\r\n}\r\n\r\nfunction private_function() {\r\n\r\n\t// this method is private\r\n}\r\n\r\nexport function public_function   (context:any) { \r\n\r\n\tprivate_function(); // ok\r\n\t\r\n\tprivate_module.public_method(); // ok\r\n}\r\n```\r\n\r\nwhich will result in a single route.\r\n\r\n```javascript\r\nhttp://[host]:[port]/public_function\r\n```\r\n<a name=\"the_index_function\" />\r\n### the index function\r\n\r\nAppex denotes that functions named 'index' route to the current module scope. As demonstrated below. \r\n\r\n```javascript\r\nexport function index(context) {}\r\nexport module blogs {\r\n\texport function index (context) { }\r\n\texport function get   (context) { }\r\n}\r\n\r\n// results in the following routes\r\n// http://[host]:[port]/\r\n// http://[host]:[port]/blogs\r\n// http://[host]:[port]/blogs/get\r\n```\r\n\r\n<a name=\"function_routing\" />\r\n### routing with modules and functions\r\n\r\nAppex creates url routing tables based on function name and module scope. For example consider the following...\r\n\r\n```javascript\r\nexport function index   (context:any) { }\r\nexport function about   (context:any) { }\r\nexport function contact (context:any) { }\r\nexport module services.customers {\r\n\texport function insert(context:any) : void { }\r\n\texport function update(context:any) : void { }\r\n\texport function delete(context:any) : void { }\r\n}\r\n\r\n// results in the following routes\r\n// http://[host]:[port]/\r\n// http://[host]:[port]/about\r\n// http://[host]:[port]/contact\r\n// http://[host]:[port]/services/customers/insert\r\n// http://[host]:[port]/services/customers/update\r\n// http://[host]:[port]/services/customers/delete\r\n```\r\n\r\n<a name=\"structuring_projects\" />\r\n## structuring projects\r\n\r\nAppex leverages TypeScript's ability to reference source files with the <reference> element. Appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar runtime = appex.runtime ({ source : './index.ts', devmode : true });\r\n\r\nrequire('http').createServer( runtime  ).listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"pages.ts\" />\r\n/// <reference path=\"users.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\nexport function index   (context) { /* handle request */ }\r\nexport function about   (context) { /* handle request */ }\r\nexport function contact (context) { /* handle request */ }\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\r\n\texport function login  (context) { /* handle request */ }\r\n\texport function logout (context) { /* handle request */ }\r\n}\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## typescript resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"http://www.apache.org/licenses/LICENSE-2.0.html","type":"Apache 2.0"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"develop nodejs web services with the typescript programming language.","directories":{},"dependencies":{"typescript.api":"0.5.1"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.2.2":{"name":"appex","version":"0.2.2","keywords":["typescript","web services","http","compiler","rest"],"author":{"name":"sinclair"},"_id":"appex@0.2.2","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"70fe7a116435fdafbbb50bf81563419c78b707f7","tarball":"https://registry.npmjs.org/appex/-/appex-0.2.2.tgz","integrity":"sha512-McGy4Ust25640YnAiVUa7+9Hxty3LsOtgdKDvhsEd3SqfYvk2vQ01PoyY3O922p41dMMEDWf46jLgrt8LeChcw==","signatures":[{"sig":"MEUCIQCowxjAXz4LcoPSgd7vvbSHWdkNCa7yzkUgyLGXzrjlzgIga1mRhounUKttFvirEHIZU/thT39NSR6g0OAInKAP+sU=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/assets/logo.jpg)\r\n\r\n### develop nodejs web services with [typescript](http://www.typescriptlang.org/)\r\n\r\n## install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n\r\n* [overview](#overview)\r\n* [getting started](#getting_started)\r\n* [getting started on express](#getting_started_on_express)\r\n* [developing with appex](#development_mode)\r\n* [functions](#functions)\r\n\t* [http handler function](#http_handler_function)\r\n\t* [json handler function](#json_handler_function)\r\n\t* [public and private functions](#public_private_functions)\r\n\t* [the index function](#the_index_function)\t\r\n\t* [routing with modules and functions](#function_routing)\r\n* [structuring projects](#structuring_projects)\r\n* [typescript resources](#resources)\r\n\r\n<a name=\"overview\" />\r\n## overview\r\n\r\nAppex is a nodejs web application and service framework built on top of the TypeScript programming language. Appex \r\nenables nodejs developers to expose typescript functions as http endpoints as well as generate meaningful service\r\nmeta data for clients to consume.\r\n\r\nAppex also provides a dynamic compilation environment for typescript to aid in development. Appex will effeciently \r\nmanage compilation in the background without the need to restart the web server, or use addition modules.\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n```javascript\r\n//----------------------------------------------\r\n// file: program.ts\r\n//----------------------------------------------\r\nexport module services {\r\n\t\r\n\t// url: http://localhost:3000/services/message\r\n\texport function message (context) { \r\n\t\t\r\n\t\tcontext.response.write('hello typescript');\r\n\r\n\t\tcontext.response.end(); \r\n\t}\r\n}\r\n//----------------------------------------------\r\n// file: app.js\r\n//----------------------------------------------\r\n\r\nvar appex   = require('appex');\r\n\r\nvar runtime = appex.runtime ({ source : './program.ts', devmode : true });\r\n\r\nrequire('http').createServer( runtime ).listen(3000);\r\n```\r\n<a name=\"getting_started_on_express\" />\r\n## getting started on express\r\n```javascript\r\n//----------------------------------------------\r\n// file: program.ts\r\n//----------------------------------------------\r\n\r\nexport module services {\r\n\t\r\n\t// url: http://localhost:3000/services/message\r\n\texport function message (context) { \r\n\t\t\r\n\t\tcontext.response.write('hello typescript');\r\n\r\n\t\tcontext.response.end(); \r\n\t}\r\n}\r\n\r\n//----------------------------------------------\r\n// file: app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex.runtime( { source:'./program.ts', devmode:true } ) );\r\n\r\napp.get('/', function(req, res){\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"development_mode\" />\r\n## developing with appex\r\n\r\nTo enable development mode, set the devmode option to true on the runtime option parameter.\r\n\r\n```javascript \r\n// enable dynamic compilations with the devmode option.\r\nvar runtime = appex.runtime ({ source : './program.ts', devmode : true }); \r\n```\r\n\r\nAppex is built directly on top of the Microsoft TypeScript 0.9 compiler and leverages it for tight\r\nintegration with the nodejs platform. By enabling the 'devmode' option will have the compiler\r\neffiecently rebuild typescript source code on each request made to the server. \r\n\r\nAppex achieves performance in this regard by leveraging features introduced in\r\nTS 0.9 which allows incremental building / caching of typescript compilation units.\r\n\r\nIn addition to this, compilations are run in a background worker process to ensure they do interupt\r\nrequests being served on the web process.\r\n\r\n![](https://raw.github.com/sinclairzx81/appex/master/assets/devmode.jpg)\r\n\r\nThe benefit to this is that updates can be made to source files without needing to restart the web process. Additionally, \r\nsyntactic errors made in typescript source code do not bring the web process. Everything stays running (excluding runtime \r\nerrors).\r\n\r\nAppex will output detailed syntax and type errors on the main process stdout stream, as well as a http response.\r\n\r\n<a name=\"functions\" />\r\n## functions\r\n\r\nAppex supports two types of functions, http handler functions, and json handler functions. \r\n\r\nAppex will only create http handlers for functions a specific signature, these are outlined below.\r\n\r\n<a name=\"http_handler_function\" />\r\n### http handler function\r\n\r\nA http handler method can be created with the following function signature.\r\n\r\n* arg0 - the http context which contains the  http request and response.\r\n\r\nThe return type is optional. http handler functions should complete the http request.\r\n\r\n```javascript\r\nexport function method(context:any) : void {\r\n\r\n\tcontext.response.write('hello world');\r\n\t\r\n\tcontext.response.end();\r\n\r\n}\r\n```\r\n<a name=\"json_handler_function\" />\r\n### json handler function\r\n\r\nA json handler is a function which will accept HTTP POST'ed json strings and \r\npass it to the function as a object. A json handler has three distinct arguments: \r\n\r\n* arg0 - the http context which contains the  http request and response.\r\n* arg1 - the json request object \r\n* arg2 - a typescript callback with a single argument for the object response. \r\n\r\nThe return type is optional. json handler functions \"must\" call the callback to\r\ncomplete the request.\r\n\r\n```javascript\r\nexport function method(context:any, request:any, callback:(response:any) => void) : void {\r\n\r\n\tcallback(request); // echo the object back.\r\n\r\n}\r\n```\r\n\r\n<a name=\"public_private_functions\" />\r\n### public and private functions\r\n\r\nAppex extends TypeScripts concept of visibility to include visibility over http. From this\r\ndevelopers and control which functions are exported as http handlers.  \r\n\r\nAppex will create routes only for functions marked with export and for functions that reside\r\nwithing modules with export.\r\n\r\nConsider the following example:\r\n\r\n```javascript\r\n\r\nmodule private_module {\r\n\r\n\texport function public_method () {\r\n\t\r\n\t\t// this function is exported, but as this module is \r\n\t\t\r\n\t\t// not exported, neither is this method.\r\n\t}\r\n}\r\n\r\nfunction private_function() {\r\n\r\n\t// this method is private\r\n}\r\n\r\nexport function public_function   (context:any) { \r\n\r\n\tprivate_function(); // ok\r\n\t\r\n\tprivate_module.public_method(); // ok\r\n}\r\n```\r\n\r\nwhich will result in a single route.\r\n\r\n```javascript\r\nhttp://[host]:[port]/public_function\r\n```\r\n<a name=\"the_index_function\" />\r\n### the index function\r\n\r\nAppex denotes that functions named 'index' route to the current module scope. As demonstrated below. \r\n\r\n```javascript\r\nexport function index(context) {}\r\nexport module blogs {\r\n\texport function index (context) { }\r\n\texport function get   (context) { }\r\n}\r\n\r\n// results in the following routes\r\n// http://[host]:[port]/\r\n// http://[host]:[port]/blogs\r\n// http://[host]:[port]/blogs/get\r\n```\r\n\r\n<a name=\"function_routing\" />\r\n### routing with modules and functions\r\n\r\nAppex creates url routing tables based on function name and module scope. For example consider the following...\r\n\r\n```javascript\r\nexport function index   (context:any) { }\r\nexport function about   (context:any) { }\r\nexport function contact (context:any) { }\r\nexport module services.customers {\r\n\texport function insert(context:any) : void { }\r\n\texport function update(context:any) : void { }\r\n\texport function delete(context:any) : void { }\r\n}\r\n\r\n// results in the following routes\r\n// http://[host]:[port]/\r\n// http://[host]:[port]/about\r\n// http://[host]:[port]/contact\r\n// http://[host]:[port]/services/customers/insert\r\n// http://[host]:[port]/services/customers/update\r\n// http://[host]:[port]/services/customers/delete\r\n```\r\n\r\n<a name=\"structuring_projects\" />\r\n## structuring projects\r\n\r\nAppex leverages TypeScript's ability to reference source files with the <reference> element. Appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar runtime = appex.runtime ({ source : './index.ts', devmode : true });\r\n\r\nrequire('http').createServer( runtime  ).listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"pages.ts\" />\r\n/// <reference path=\"users.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\nexport function index   (context) { /* handle request */ }\r\nexport function about   (context) { /* handle request */ }\r\nexport function contact (context) { /* handle request */ }\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\r\n\texport function login  (context) { /* handle request */ }\r\n\texport function logout (context) { /* handle request */ }\r\n}\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## typescript resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"http://www.apache.org/licenses/LICENSE-2.0.html","type":"Apache 2.0"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"develop nodejs web services with the typescript programming language.","directories":{},"dependencies":{"typescript.api":"0.5.1"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.2.3":{"name":"appex","version":"0.2.3","keywords":["typescript","web services","http","compiler","rest"],"author":{"name":"sinclair"},"_id":"appex@0.2.3","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"547d9e25e4ef04af1d09c3fcf1148f4382cb420d","tarball":"https://registry.npmjs.org/appex/-/appex-0.2.3.tgz","integrity":"sha512-a7VU4z9dpRqhAHdJlc5NDy9MLr8pNPovSnkJAtS0D5LZi8//kMRGR4ZeWoyH5js5IgNv67xq6to13Cx8dUAwhg==","signatures":[{"sig":"MEUCIQDZK98YUb0MRMiq56klFgz5meVdHg8FfXQzOgqVlR7cEAIgNfQoH3vA0uisIJe3YGGK/ngaLQQ4fdI2LTXqkDSt6sI=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/assets/logo.jpg)\r\n\r\n### develop nodejs web services with [typescript](http://www.typescriptlang.org/)\r\n\r\n## install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n\r\n* [overview](#overview)\r\n* [getting started](#getting_started)\r\n* [getting started on express](#getting_started_on_express)\r\n* [developing with appex](#development_mode)\r\n* [functions](#functions)\r\n\t* [http handler function](#http_handler_function)\r\n\t* [json handler function](#json_handler_function)\r\n\t* [public and private functions](#public_private_functions)\r\n\t* [the index function](#the_index_function)\t\r\n\t* [routing with modules and functions](#function_routing)\r\n* [structuring projects](#structuring_projects)\r\n* [typescript resources](#resources)\r\n\r\n<a name=\"overview\" />\r\n## overview\r\n\r\nAppex is a nodejs web application and service framework built on top of the TypeScript programming language. Appex \r\nenables nodejs developers to expose typescript functions as http endpoints as well as generate meaningful service\r\nmeta data for clients to consume.\r\n\r\nAppex also provides a dynamic compilation environment for typescript to aid in development. Appex will effeciently \r\nmanage compilation in the background without the need to restart the web server, or use addition modules.\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n```javascript\r\n//----------------------------------------------\r\n// file: program.ts\r\n//----------------------------------------------\r\nexport module services {\r\n\t\r\n\t// url: http://localhost:3000/services/message\r\n\texport function message (context) { \r\n\t\t\r\n\t\tcontext.response.write('hello typescript');\r\n\r\n\t\tcontext.response.end(); \r\n\t}\r\n}\r\n//----------------------------------------------\r\n// file: app.js\r\n//----------------------------------------------\r\n\r\nvar appex   = require('appex');\r\n\r\nvar runtime = appex.runtime ({ source : './program.ts', devmode : true });\r\n\r\nrequire('http').createServer( runtime ).listen(3000);\r\n```\r\n<a name=\"getting_started_on_express\" />\r\n## getting started on express\r\n```javascript\r\n//----------------------------------------------\r\n// file: program.ts\r\n//----------------------------------------------\r\n\r\nexport module services {\r\n\t\r\n\t// url: http://localhost:3000/services/message\r\n\texport function message (context) { \r\n\t\t\r\n\t\tcontext.response.write('hello typescript');\r\n\r\n\t\tcontext.response.end(); \r\n\t}\r\n}\r\n\r\n//----------------------------------------------\r\n// file: app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex.runtime( { source:'./program.ts', devmode:true } ) );\r\n\r\napp.get('/', function(req, res){\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"development_mode\" />\r\n## developing with appex\r\n\r\nTo enable development mode, set the devmode option to true on the runtime option parameter.\r\n\r\n```javascript \r\n// enable dynamic compilations with the devmode option.\r\nvar runtime = appex.runtime ({ source : './program.ts', devmode : true }); \r\n```\r\n\r\nAppex is built directly on top of the Microsoft TypeScript 0.9 compiler and leverages it for tight\r\nintegration with the nodejs platform. By enabling the 'devmode' option will have the compiler\r\neffiecently rebuild typescript source code on each request made to the server. \r\n\r\nAppex achieves performance in this regard by leveraging features introduced in\r\nTS 0.9 which allows incremental building / caching of typescript compilation units.\r\n\r\nIn addition to this, compilations are run in a background worker process to ensure they do interupt\r\nrequests being served on the web process.\r\n\r\n![](https://raw.github.com/sinclairzx81/appex/master/assets/devmode.jpg)\r\n\r\nThe benefit to this is that updates can be made to source files without needing to restart the web process. Additionally, \r\nsyntactic errors made in typescript source code do not bring the web process. Everything stays running (excluding runtime \r\nerrors).\r\n\r\nAppex will output detailed syntax and type errors on the main process stdout stream, as well as a http response.\r\n\r\n<a name=\"functions\" />\r\n## functions\r\n\r\nAppex supports two types of functions, http handler functions, and json handler functions. \r\n\r\nAppex will only create http handlers for functions a specific signature, these are outlined below.\r\n\r\n<a name=\"http_handler_function\" />\r\n### http handler function\r\n\r\nA http handler method can be created with the following function signature.\r\n\r\n* arg0 - the http context which contains the  http request and response.\r\n\r\nThe return type is optional. http handler functions should complete the http request.\r\n\r\n```javascript\r\nexport function method(context:any) : void {\r\n\r\n\tcontext.response.write('hello world');\r\n\t\r\n\tcontext.response.end();\r\n\r\n}\r\n```\r\n<a name=\"json_handler_function\" />\r\n### json handler function\r\n\r\nA json handler is a function which will accept HTTP POST'ed json strings and \r\npass it to the function as a object. A json handler has three distinct arguments: \r\n\r\n* arg0 - the http context which contains the  http request and response.\r\n* arg1 - the json request object \r\n* arg2 - a typescript callback with a single argument for the object response. \r\n\r\nThe return type is optional. json handler functions \"must\" call the callback to\r\ncomplete the request.\r\n\r\n```javascript\r\nexport function method(context:any, request:any, callback:(response:any) => void) : void {\r\n\r\n\tcallback(request); // echo the object back.\r\n\r\n}\r\n```\r\n\r\n<a name=\"public_private_functions\" />\r\n### public and private functions\r\n\r\nAppex extends TypeScripts concept of visibility to include visibility over http. From this\r\ndevelopers and control which functions are exported as http handlers.  \r\n\r\nAppex will create routes only for functions marked with export and for functions that reside\r\nwithing modules with export.\r\n\r\nConsider the following example:\r\n\r\n```javascript\r\n\r\nmodule private_module {\r\n\r\n\texport function public_method () {\r\n\t\r\n\t\t// this function is exported, but as this module is \r\n\t\t\r\n\t\t// not exported, neither is this method.\r\n\t}\r\n}\r\n\r\nfunction private_function() {\r\n\r\n\t// this method is private\r\n}\r\n\r\nexport function public_function   (context:any) { \r\n\r\n\tprivate_function(); // ok\r\n\t\r\n\tprivate_module.public_method(); // ok\r\n}\r\n```\r\n\r\nwhich will result in a single route.\r\n\r\n```javascript\r\nhttp://[host]:[port]/public_function\r\n```\r\n<a name=\"the_index_function\" />\r\n### the index function\r\n\r\nAppex denotes that functions named 'index' route to the current module scope. As demonstrated below. \r\n\r\n```javascript\r\nexport function index(context) {}\r\nexport module blogs {\r\n\texport function index (context) { }\r\n\texport function get   (context) { }\r\n}\r\n\r\n// results in the following routes\r\n// http://[host]:[port]/\r\n// http://[host]:[port]/blogs\r\n// http://[host]:[port]/blogs/get\r\n```\r\n\r\n<a name=\"function_routing\" />\r\n### routing with modules and functions\r\n\r\nAppex creates url routing tables based on function name and module scope. For example consider the following...\r\n\r\n```javascript\r\nexport function index   (context:any) { }\r\nexport function about   (context:any) { }\r\nexport function contact (context:any) { }\r\nexport module services.customers {\r\n\texport function insert(context:any) : void { }\r\n\texport function update(context:any) : void { }\r\n\texport function delete(context:any) : void { }\r\n}\r\n\r\n// results in the following routes\r\n// http://[host]:[port]/\r\n// http://[host]:[port]/about\r\n// http://[host]:[port]/contact\r\n// http://[host]:[port]/services/customers/insert\r\n// http://[host]:[port]/services/customers/update\r\n// http://[host]:[port]/services/customers/delete\r\n```\r\n\r\n<a name=\"structuring_projects\" />\r\n## structuring projects\r\n\r\nAppex leverages TypeScript's ability to reference source files with the <reference> element. Appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar runtime = appex.runtime ({ source : './index.ts', devmode : true });\r\n\r\nrequire('http').createServer( runtime  ).listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"pages.ts\" />\r\n/// <reference path=\"users.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\nexport function index   (context) { /* handle request */ }\r\nexport function about   (context) { /* handle request */ }\r\nexport function contact (context) { /* handle request */ }\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\r\n\texport function login  (context) { /* handle request */ }\r\n\texport function logout (context) { /* handle request */ }\r\n}\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## typescript resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"http://www.apache.org/licenses/LICENSE-2.0.html","type":"Apache 2.0"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"develop nodejs web services with the typescript programming language.","directories":{},"dependencies":{"typescript.api":"0.5.1"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.2.4":{"name":"appex","version":"0.2.4","keywords":["typescript","web services","http","compiler","rest"],"author":{"name":"sinclair"},"_id":"appex@0.2.4","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"168af67693e00532b63b608746f5268a2444299a","tarball":"https://registry.npmjs.org/appex/-/appex-0.2.4.tgz","integrity":"sha512-37EN50nv480t9n+Vx6paASHN3qD93Kh8L7+rjJs5U6WMe5SKe7OCmNTDSNA1Ph5vj0ozKIYcXNf8iG5BZI/LHw==","signatures":[{"sig":"MEUCIQDHu4XwZ+7oNLTxvPFhtI1jkVZe30+vnxceY4+cF/LxNAIgXuTJHpvep/ia9MOnjWyct8DWergi6FHhhUWyyOQQd/8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/assets/logo.jpg)\r\n\r\n### develop nodejs web services with [typescript](http://www.typescriptlang.org/)\r\n\r\n## install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n\r\n* [overview](#overview)\r\n* [getting started](#getting_started)\r\n* [getting started on express](#getting_started_on_express)\r\n* [developing with appex](#development_mode)\r\n* [functions](#functions)\r\n\t* [http handler function](#http_handler_function)\r\n\t* [json handler function](#json_handler_function)\r\n\t* [public and private functions](#public_private_functions)\r\n\t* [the index function](#the_index_function)\t\r\n\t* [routing with modules and functions](#function_routing)\r\n* [structuring projects](#structuring_projects)\r\n* [typescript resources](#resources)\r\n\r\n<a name=\"overview\" />\r\n## overview\r\n\r\nAppex is a nodejs web application and service framework built on top of the TypeScript programming language. Appex \r\nenables nodejs developers to expose typescript functions as http endpoints as well as generate meaningful service\r\nmeta data for clients to consume.\r\n\r\nAppex also provides a dynamic compilation environment for typescript to aid in development. Appex will effeciently \r\nmanage compilation in the background without the need to restart the web server, or use addition modules.\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n```javascript\r\n//----------------------------------------------\r\n// file: program.ts\r\n//----------------------------------------------\r\nexport module services {\r\n\t\r\n\t// url: http://localhost:3000/services/message\r\n\texport function message (context) { \r\n\t\t\r\n\t\tcontext.response.write('hello typescript');\r\n\r\n\t\tcontext.response.end(); \r\n\t}\r\n}\r\n//----------------------------------------------\r\n// file: app.js\r\n//----------------------------------------------\r\n\r\nvar appex   = require('appex');\r\n\r\nvar runtime = appex.runtime ({ source : './program.ts', devmode : true });\r\n\r\nrequire('http').createServer( runtime ).listen(3000);\r\n```\r\n<a name=\"getting_started_on_express\" />\r\n## getting started on express\r\n```javascript\r\n//----------------------------------------------\r\n// file: program.ts\r\n//----------------------------------------------\r\n\r\nexport module services {\r\n\t\r\n\t// url: http://localhost:3000/services/message\r\n\texport function message (context) { \r\n\t\t\r\n\t\tcontext.response.write('hello typescript');\r\n\r\n\t\tcontext.response.end(); \r\n\t}\r\n}\r\n\r\n//----------------------------------------------\r\n// file: app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex.runtime( { source:'./program.ts', devmode:true } ) );\r\n\r\napp.get('/', function(req, res){\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"development_mode\" />\r\n## developing with appex\r\n\r\nTo enable development mode, set the devmode option to true on the runtime option parameter.\r\n\r\n```javascript \r\n// enable dynamic compilations with the devmode option.\r\nvar runtime = appex.runtime ({ source : './program.ts', devmode : true }); \r\n```\r\n\r\nAppex is built directly on top of the Microsoft TypeScript 0.9 compiler and leverages it for tight\r\nintegration with the nodejs platform. By enabling the 'devmode' option will have the compiler\r\neffiecently rebuild typescript source code on each request made to the server. \r\n\r\nAppex achieves performance in this regard by leveraging features introduced in\r\nTS 0.9 which allows incremental building / caching of typescript compilation units.\r\n\r\nIn addition to this, compilations are run in a background worker process to ensure they do interupt\r\nrequests being served on the web process.\r\n\r\n![](https://raw.github.com/sinclairzx81/appex/master/assets/devmode.jpg)\r\n\r\nThe benefit to this is that updates can be made to source files without needing to restart the web process. Additionally, \r\nsyntactic errors made in typescript source code do not bring the web process. Everything stays running (excluding runtime \r\nerrors).\r\n\r\nAppex will output detailed syntax and type errors on the main process stdout stream, as well as a http response.\r\n\r\n<a name=\"functions\" />\r\n## functions\r\n\r\nAppex supports two types of functions, http handler functions, and json handler functions. \r\n\r\nAppex will only create http handlers for functions a specific signature, these are outlined below.\r\n\r\n<a name=\"http_handler_function\" />\r\n### http handler function\r\n\r\nA http handler method can be created with the following function signature.\r\n\r\n* arg0 - the http context which contains the  http request and response.\r\n\r\nThe return type is optional. http handler functions should complete the http request.\r\n\r\n```javascript\r\nexport function method(context:any) : void {\r\n\r\n\tcontext.response.write('hello world');\r\n\t\r\n\tcontext.response.end();\r\n\r\n}\r\n```\r\n<a name=\"json_handler_function\" />\r\n### json handler function\r\n\r\nA json handler is a function which will accept HTTP POST'ed json strings and \r\npass it to the function as a object. A json handler has three distinct arguments: \r\n\r\n* arg0 - the http context which contains the  http request and response.\r\n* arg1 - the json request object \r\n* arg2 - a typescript callback with a single argument for the object response. \r\n\r\nThe return type is optional. json handler functions \"must\" call the callback to\r\ncomplete the request.\r\n\r\n```javascript\r\nexport function method(context:any, request:any, callback:(response:any) => void) : void {\r\n\r\n\tcallback(request); // echo the object back.\r\n\r\n}\r\n```\r\n\r\n<a name=\"public_private_functions\" />\r\n### public and private functions\r\n\r\nAppex extends TypeScripts concept of visibility to include visibility over http. From this\r\ndevelopers and control which functions are exported as http handlers.  \r\n\r\nAppex will create routes only for functions marked with export and for functions that reside\r\nwithing modules with export.\r\n\r\nConsider the following example:\r\n\r\n```javascript\r\n\r\nmodule private_module {\r\n\r\n\texport function public_method () {\r\n\t\r\n\t\t// this function is exported, but as this module is \r\n\t\t\r\n\t\t// not exported, neither is this method.\r\n\t}\r\n}\r\n\r\nfunction private_function() {\r\n\r\n\t// this method is private\r\n}\r\n\r\nexport function public_function   (context:any) { \r\n\r\n\tprivate_function(); // ok\r\n\t\r\n\tprivate_module.public_method(); // ok\r\n}\r\n```\r\n\r\nwhich will result in a single route.\r\n\r\n```javascript\r\nhttp://[host]:[port]/public_function\r\n```\r\n<a name=\"the_index_function\" />\r\n### the index function\r\n\r\nAppex denotes that functions named 'index' route to the current module scope. As demonstrated below. \r\n\r\n```javascript\r\nexport function index(context) {}\r\nexport module blogs {\r\n\texport function index (context) { }\r\n\texport function get   (context) { }\r\n}\r\n\r\n// results in the following routes\r\n// http://[host]:[port]/\r\n// http://[host]:[port]/blogs\r\n// http://[host]:[port]/blogs/get\r\n```\r\n\r\n<a name=\"function_routing\" />\r\n### routing with modules and functions\r\n\r\nAppex creates url routing tables based on function name and module scope. For example consider the following...\r\n\r\n```javascript\r\nexport function index   (context:any) { }\r\nexport function about   (context:any) { }\r\nexport function contact (context:any) { }\r\nexport module services.customers {\r\n\texport function insert(context:any) : void { }\r\n\texport function update(context:any) : void { }\r\n\texport function delete(context:any) : void { }\r\n}\r\n\r\n// results in the following routes\r\n// http://[host]:[port]/\r\n// http://[host]:[port]/about\r\n// http://[host]:[port]/contact\r\n// http://[host]:[port]/services/customers/insert\r\n// http://[host]:[port]/services/customers/update\r\n// http://[host]:[port]/services/customers/delete\r\n```\r\n\r\n<a name=\"structuring_projects\" />\r\n## structuring projects\r\n\r\nAppex leverages TypeScript's ability to reference source files with the <reference> element. Appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar runtime = appex.runtime ({ source : './index.ts', devmode : true });\r\n\r\nrequire('http').createServer( runtime  ).listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"pages.ts\" />\r\n/// <reference path=\"users.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\nexport function index   (context) { /* handle request */ }\r\nexport function about   (context) { /* handle request */ }\r\nexport function contact (context) { /* handle request */ }\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\r\n\texport function login  (context) { /* handle request */ }\r\n\texport function logout (context) { /* handle request */ }\r\n}\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## typescript resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"http://www.apache.org/licenses/LICENSE-2.0.html","type":"Apache 2.0"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"develop nodejs web services with the typescript programming language.","directories":{},"dependencies":{"typescript.api":"0.5.1"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.2.5":{"name":"appex","version":"0.2.5","keywords":["typescript","web services","http","compiler","rest"],"author":{"name":"sinclair"},"_id":"appex@0.2.5","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"0a9760b877372cf58af4135a422c4a3f5d8936f8","tarball":"https://registry.npmjs.org/appex/-/appex-0.2.5.tgz","integrity":"sha512-S5S50aWDuxUUlTgsKyPlA9uYelqXSV71OEbC0U0XQJSO21MJIZ4DMGUO8y9bgYdKo/NQHPjkqKG/Cm9SE++46A==","signatures":[{"sig":"MEYCIQDkPA9HVZ9lidxrteHWW8+5ncCdy6RVsff2+ilKAaLwxwIhAPI9dR6JZ4rf7yW8bYpKi0wV0QmtI9KUSEn2OCiT9Abz","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/assets/logo.jpg)\r\n\r\n### develop nodejs web services with [typescript](http://www.typescriptlang.org/)\r\n\r\n## install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n\r\n* [overview](#overview)\r\n* [getting started](#getting_started)\r\n* [getting started on express](#getting_started_on_express)\r\n* [developing with appex](#development_mode)\r\n* [functions](#functions)\r\n\t* [http handler function](#http_handler_function)\r\n\t* [json handler function](#json_handler_function)\r\n\t* [public and private functions](#public_private_functions)\r\n\t* [the index function](#the_index_function)\t\r\n\t* [routing with modules and functions](#function_routing)\r\n* [structuring projects](#structuring_projects)\r\n* [typescript resources](#resources)\r\n\r\n<a name=\"overview\" />\r\n## overview\r\n\r\nAppex is a nodejs web application and service framework built on top of the TypeScript programming language. Appex \r\nenables nodejs developers to expose typescript functions as http endpoints as well as generate meaningful service\r\nmeta data for clients to consume.\r\n\r\nAppex also provides a dynamic compilation environment for typescript to aid in development. Appex will effeciently \r\nmanage compilation in the background without the need to restart the web server, or use addition modules.\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n```javascript\r\n//----------------------------------------------\r\n// file: program.ts\r\n//----------------------------------------------\r\nexport module services {\r\n\t\r\n\t// url: http://localhost:3000/services/message\r\n\texport function message (context) { \r\n\t\t\r\n\t\tcontext.response.write('hello typescript');\r\n\r\n\t\tcontext.response.end(); \r\n\t}\r\n}\r\n//----------------------------------------------\r\n// file: app.js\r\n//----------------------------------------------\r\n\r\nvar appex   = require('appex');\r\n\r\nvar runtime = appex.runtime ({ source : './program.ts', devmode : true });\r\n\r\nrequire('http').createServer( runtime ).listen(3000);\r\n```\r\n<a name=\"getting_started_on_express\" />\r\n## getting started on express\r\n```javascript\r\n//----------------------------------------------\r\n// file: program.ts\r\n//----------------------------------------------\r\n\r\nexport module services {\r\n\t\r\n\t// url: http://localhost:3000/services/message\r\n\texport function message (context) { \r\n\t\t\r\n\t\tcontext.response.write('hello typescript');\r\n\r\n\t\tcontext.response.end(); \r\n\t}\r\n}\r\n\r\n//----------------------------------------------\r\n// file: app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex.runtime( { source:'./program.ts', devmode:true } ) );\r\n\r\napp.get('/', function(req, res){\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"development_mode\" />\r\n## developing with appex\r\n\r\nTo enable development mode, set the devmode option to true on the runtime option parameter.\r\n\r\n```javascript \r\n// enable dynamic compilations with the devmode option.\r\nvar runtime = appex.runtime ({ source : './program.ts', devmode : true }); \r\n```\r\n\r\nAppex is built directly on top of the Microsoft TypeScript 0.9 compiler and leverages it for tight\r\nintegration with the nodejs platform. By enabling the 'devmode' option will have the compiler\r\neffiecently rebuild typescript source code on each request made to the server. \r\n\r\nAppex achieves performance in this regard by leveraging features introduced in\r\nTS 0.9 which allows incremental building / caching of typescript compilation units.\r\n\r\nIn addition to this, compilations are run in a background worker process to ensure they do interupt\r\nrequests being served on the web process.\r\n\r\n![](https://raw.github.com/sinclairzx81/appex/master/assets/devmode.jpg)\r\n\r\nThe benefit to this is that updates can be made to source files without needing to restart the web process. Additionally, \r\nsyntactic errors made in typescript source code do not bring the web process. Everything stays running (excluding runtime \r\nerrors).\r\n\r\nAppex will output detailed syntax and type errors on the main process stdout stream, as well as a http response.\r\n\r\n<a name=\"functions\" />\r\n## functions\r\n\r\nAppex supports two types of functions, http handler functions, and json handler functions. \r\n\r\nAppex will only create http handlers for functions a specific signature, these are outlined below.\r\n\r\n<a name=\"http_handler_function\" />\r\n### http handler function\r\n\r\nA http handler method can be created with the following function signature.\r\n\r\n* arg0 - the http context which contains the  http request and response.\r\n\r\nThe return type is optional. http handler functions should complete the http request.\r\n\r\n```javascript\r\nexport function method(context:any) : void {\r\n\r\n\tcontext.response.write('hello world');\r\n\t\r\n\tcontext.response.end();\r\n\r\n}\r\n```\r\n<a name=\"json_handler_function\" />\r\n### json handler function\r\n\r\nA json handler is a function which will accept HTTP POST'ed json strings and \r\npass it to the function as a object. A json handler has three distinct arguments: \r\n\r\n* arg0 - the http context which contains the  http request and response.\r\n* arg1 - the json request object \r\n* arg2 - a typescript callback with a single argument for the object response. \r\n\r\nThe return type is optional. json handler functions \"must\" call the callback to\r\ncomplete the request.\r\n\r\n```javascript\r\nexport function method(context:any, request:any, callback:(response:any) => void) : void {\r\n\r\n\tcallback(request); // echo the object back.\r\n\r\n}\r\n```\r\n\r\n<a name=\"public_private_functions\" />\r\n### public and private functions\r\n\r\nAppex extends TypeScripts concept of visibility to include visibility over http. From this\r\ndevelopers and control which functions are exported as http handlers.  \r\n\r\nAppex will create routes only for functions marked with export and for functions that reside\r\nwithing modules with export.\r\n\r\nConsider the following example:\r\n\r\n```javascript\r\n\r\nmodule private_module {\r\n\r\n\texport function public_method () {\r\n\t\r\n\t\t// this function is exported, but as this module is \r\n\t\t\r\n\t\t// not exported, neither is this method.\r\n\t}\r\n}\r\n\r\nfunction private_function() {\r\n\r\n\t// this method is private\r\n}\r\n\r\nexport function public_function   (context:any) { \r\n\r\n\tprivate_function(); // ok\r\n\t\r\n\tprivate_module.public_method(); // ok\r\n}\r\n```\r\n\r\nwhich will result in a single route.\r\n\r\n```javascript\r\nhttp://[host]:[port]/public_function\r\n```\r\n<a name=\"the_index_function\" />\r\n### the index function\r\n\r\nAppex denotes that functions named 'index' route to the current module scope. As demonstrated below. \r\n\r\n```javascript\r\nexport function index(context) {}\r\nexport module blogs {\r\n\texport function index (context) { }\r\n\texport function get   (context) { }\r\n}\r\n\r\n// results in the following routes\r\n// http://[host]:[port]/\r\n// http://[host]:[port]/blogs\r\n// http://[host]:[port]/blogs/get\r\n```\r\n\r\n<a name=\"function_routing\" />\r\n### routing with modules and functions\r\n\r\nAppex creates url routing tables based on function name and module scope. For example consider the following...\r\n\r\n```javascript\r\nexport function index   (context:any) { }\r\nexport function about   (context:any) { }\r\nexport function contact (context:any) { }\r\nexport module services.customers {\r\n\texport function insert(context:any) : void { }\r\n\texport function update(context:any) : void { }\r\n\texport function delete(context:any) : void { }\r\n}\r\n\r\n// results in the following routes\r\n// http://[host]:[port]/\r\n// http://[host]:[port]/about\r\n// http://[host]:[port]/contact\r\n// http://[host]:[port]/services/customers/insert\r\n// http://[host]:[port]/services/customers/update\r\n// http://[host]:[port]/services/customers/delete\r\n```\r\n\r\n<a name=\"structuring_projects\" />\r\n## structuring projects\r\n\r\nAppex leverages TypeScript's ability to reference source files with the <reference> element. Appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar runtime = appex.runtime ({ source : './index.ts', devmode : true });\r\n\r\nrequire('http').createServer( runtime  ).listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"pages.ts\" />\r\n/// <reference path=\"users.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\nexport function index   (context) { /* handle request */ }\r\nexport function about   (context) { /* handle request */ }\r\nexport function contact (context) { /* handle request */ }\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\r\n\texport function login  (context) { /* handle request */ }\r\n\texport function logout (context) { /* handle request */ }\r\n}\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## typescript resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"http://www.apache.org/licenses/LICENSE-2.0.html","type":"Apache 2.0"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"develop nodejs web services with the typescript programming language.","directories":{},"dependencies":{"typescript.api":"0.5.1"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.2.6":{"name":"appex","version":"0.2.6","keywords":["typescript","web services","http","compiler","rest"],"author":{"name":"sinclair"},"_id":"appex@0.2.6","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"ecdfac2a89e880d4019ed57fe85e052b23138874","tarball":"https://registry.npmjs.org/appex/-/appex-0.2.6.tgz","integrity":"sha512-laTyn9Bx0seDEjUNJBWkw6W+8KN1eTeIfIXgd+h74tuHuZlUYbpjnlhTvrbYMyX0teIEFCyMWtf0KlkAEqxRZw==","signatures":[{"sig":"MEYCIQCme29QqCEroZLanvebKVt9Mq2wyHeJhDQRJznNoMLhaAIhAKSasv6W+JZOyAMkRJl8UZLamJcEjSed6Pgsfs7a16+W","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/assets/logo.jpg)\r\n\r\n### develop nodejs web services with [typescript](http://www.typescriptlang.org/)\r\n\r\n## install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n\r\n* [overview](#overview)\r\n* [getting started](#getting_started)\r\n\t* [the appex runtime](#runtime)\r\n\t* [runtime options](#options)\r\n\t* [binding to an http server](#http_server)\r\n\t* [binding to an express instance](#express_server)\r\n* [creating services with typescript](#creating_services)\r\n\t* [appex context](#appex_context)\r\n\t* [appex http handlers](#appex_http_handlers)\r\n\t* [appex json handlers](#appex_json_handlers)\r\n\t* [appex signatures](#appex_signatures)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [routing functions](#routing_functions)\r\n\t* [index functions](#index_functions)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [development mode](#development_mode)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n\r\n<a name=\"overview\" />\r\n## overview\r\n\r\nAppex is a nodejs web service framework built on top of the TypeScript programming language. Appex \r\nenables nodejs developers to expose typescript functions as http endpoints as well as generate meaningful service\r\nmeta data for clients to consume.\r\n\r\nAppex also provides a dynamic compilation environment for typescript to aid in development. Appex will effeciently \r\nmanage compilation in the background without the need to restart the web server, or use addition modules.\r\n\r\nAppex is designed to operate as both a standalone web service solution or a compliment an existing applications written\r\nin frameworks such as express / connect.\r\n\r\nAppex makes writing http endpoints as easy as writing a functions. \r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following outlines setting the Appex runtime. \r\n\r\n<a name=\"runtime\" />\r\n### the appex runtime\r\n\r\nThe Appex runtime is compilation engine that handles compiling typescript code, mapping routes to functions and \r\ninvocation. Appex provides a utility method to setting for setting up the runtime, as described below.\r\n\r\n```javascript\r\nvar http    = require('http');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar runtime = appex.runtime ( { sourcefile : './program.ts' } );\r\n\r\nvar server  = http.createServer( runtime );\r\n\r\nserver.listen(3000);\r\n```\r\n\r\nThe appex.runtime() method returns a http handler function which is both compatable with nodejs' \r\nhttp server as well as connect middleware. This is the recommended means of creating runtimes, \r\nHowever, if you need to access the runtime directly or are simply curious, you can also setup \r\nthe runtime in the following way...\r\n\r\n```javascript\r\nvar http    = require('http');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar runtime = new appex.Runtime ( { sourcefile : './program.ts' } );\r\n\r\nvar server  = http.createServer( function(req, res) {\r\n    \r\n\tconsole.log(runtime); // investigate the runtime.\r\n\r\n    runtime.request_handler(req, res, function() { \r\n\r\n\t\t// request was not handled...\r\n\r\n\t});  \r\n});\r\n\r\nserver.listen(3000)\r\n```\r\n\r\n<a name=\"options\" />\r\n### runtime options\r\n\r\nThe appex runtime accepts the following options.\r\n\r\n```javascript\r\nvar options = { \r\n\tsourcefile : './program.ts', // (required) location of source file.\r\n    devmode    : true,           // (optional) recompile on request. \r\n    logging    : true,           // (optional) write requests to stdout.\r\n\tstdout     : process.stdout, // (optional) output stream. default is process.stdout\r\n\tstderr     : process.stderr, // (optional) error  stream. default is process.stderr\r\n};\r\n\r\nvar runtime = appex.runtime ( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### binding to an http server\r\n\r\nSetting up on a nodejs http server.\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// file: program.ts\r\n//----------------------------------------------\r\nexport module services {\r\n\t\r\n\t// url: http://localhost:3000/services/message\r\n\texport function message (context) { \r\n\t\t\r\n\t\tcontext.response.write('hello typescript');\r\n\r\n\t\tcontext.response.end(); \r\n\t}\r\n}\r\n\r\n//----------------------------------------------\r\n// file: app.js\r\n//----------------------------------------------\r\n\r\nvar http    = require('http');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar runtime = appex.runtime ( { sourcefile : './program.ts' } );\r\n\r\nvar server  = http.createServer( runtime );\r\n\r\nserver.listen(3000);\r\n```\r\n<a name=\"express_server\" />\r\n### binding to an express instance\r\n\r\nThe following illistrates setting up appex on an express instance.\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// file: program.ts\r\n//----------------------------------------------\r\n\r\nexport module services {\r\n\t\r\n\t// url: http://localhost:3000/services/message\r\n\texport function message (context) { \r\n\t\t\r\n\t\tcontext.response.write('hello typescript');\r\n\r\n\t\tcontext.response.end(); \r\n\t}\r\n}\r\n\r\n//----------------------------------------------\r\n// file: app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex.runtime ( { sourcefile : './program.ts' } ) );\r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"creating_services\" />\r\n## creating services with typescript\r\n\r\nAppex enables developers to write http endpoints by writing typescript functions. \r\n\r\nThe following section describes how to write http accessible functions. \r\n\r\n<a name=\"appex_context\" />\r\n### appex_context\r\n\r\nAll appex functions are passed a object context as the first argument. The context object encapulates\r\nthe http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the context object\r\nexport function method(context) {\r\n\t// context.request    - the http request object.\r\n\t// context.response   - the http response object.\r\n\t// context.reflection - appex runtime type information.\r\n\t// context.routes     - appex routing tables.\r\n\t// context.exports    - appex module exports. \r\n}\r\n```\r\n\r\n<a name=\"appex_http_handlers\" />\r\n### appex http handlers\r\n\r\nA appex http handler is defined with the following signature.\r\n\r\n* argument[0] - the appex context\r\n* returns     - void (optional)\r\n\r\nhttp handler functions need to complete the http request.\r\n\r\n```javascript\r\nexport function method(context) : void {\r\n\r\n\tcontext.response.write('hello world');\r\n\t\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"appex_json_handlers\" />\r\n### appex json handlers\r\n\r\nA appex json handler is a function suited to handling json based http requests. appex json handlers\r\nare invoked via HTTP POST and expect JSON to be subbmited with the request. Passing null or invalid\r\nJSON results in the request argument being null.\r\n\r\nA appex json handler requires the following signature.\r\n\r\n* argument[0] - the appex context\r\n* argument[1] - A optionally typed json request object. \r\n* argument[2] - a optionally typed optypescript callback with a single argument for the object response.\r\n* returns     - void (optional) \r\n\r\nThe return type is optional. json handler functions \"must\" invoke the callback to complete the request.\r\n\r\n```javascript\r\nexport function method(context, request, callback:(response) => void) : void {\r\n\r\n\tcallback(request); // echo the object back.\r\n\r\n}\r\n```\r\n<a name=\"appex_signatures\" />\r\n### appex signatures\r\n\r\nAppex only supports two function signatures for http binding. Functions that do not conform to these\r\nsignatures will be ignored as http endpoints.\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting_functions\r\n\r\nAppex extends TypeScripts concept of visibility to include visibility over http. From this\r\ndevelopers and control which functions are exported as http handlers.  \r\n\r\nIn order to make a function accessible over http, you must explicitly \"export\" this function. \r\n\r\nConsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.write('testing');\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\nThe above will result in the following route being created:\r\n\r\n```javascript\r\nhttp://[host]:[port]/public_function\r\n```\r\n\r\n<a name=\"routing_functions\" />\r\n### routing functions\r\n\r\nAppex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\nexport function index   (context:any) { }\r\n\r\nexport function about   (context:any) { }\r\n\r\nexport function contact (context:any) { }\r\n\r\nexport module services.customers {\r\n\r\n\texport function insert(context:any) : void { }\r\n\r\n\texport function update(context:any) : void { }\r\n\r\n\texport function delete(context:any) : void { }\r\n}\r\n\r\n// results in the following routes\r\n// http://[host]:[port]/\r\n// http://[host]:[port]/about\r\n// http://[host]:[port]/contact\r\n// http://[host]:[port]/services/customers/insert\r\n// http://[host]:[port]/services/customers/update\r\n// http://[host]:[port]/services/customers/delete\r\n```\r\n\r\n<a name=\"index_functions\" />\r\n### index_functions\r\n\r\nAppex denotes that functions named 'index' resolve to the current module scope. As demonstrated below: \r\n\r\n```javascript\r\nexport function index(context) { }\r\n\r\nexport module blogs {\r\n\r\n\texport function index (context) { }\r\n\r\n\texport function get   (context) { }\r\n}\r\n\r\n// results in the following routes\r\n// http://[host]:[port]/\r\n// http://[host]:[port]/blogs\r\n// http://[host]:[port]/blogs/get\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\nAppex enables nodejs developers to write applications in TypeScript as though it were native to nodejs. The following\r\nsection outlines how to effeciently with Appex and the TypeScript programming language.\r\n\r\n<a name=\"development_mode\" />\r\n### development_mode\r\n\r\n```javascript \r\n// enable dynamic compilations with the devmode option.\r\nvar runtime = appex.runtime ({ sourcefile : './program.ts', devmode : true, logging: true }); \r\n```\r\nAppex is built directly on top of the Microsoft TypeScript 0.9 compiler and leverages it for tight\r\nintegration with the nodejs platform. By enabling the 'devmode' option, Appex will efficiently\r\nrebuild your source code on each request made to the server. \r\n\r\nAppex achieves performance in this regard by leveraging features available in\r\nTypeScript compiler which facilitate incremental building / caching of typescript \r\ncompilation units. \r\n\r\nIn addition to this, compilations are run as a background worker process to ensure they \r\ndo interupt requests being served on the parent web process. \r\n\r\nAppex will output syntax and type errors to the stdout and http response. Syntax errors \r\nwill not bring down the web process. And you won't need to restart on code updates.\r\n\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nAppex leverages TypeScript's ability to reference source files with the 'reference' element. Appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar runtime = appex.runtime ({ sourcefile : './index.ts' });\r\n\r\nrequire('http').createServer( runtime  ).listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"pages.ts\" />\r\n/// <reference path=\"users.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\nexport function index   (context) { /* handle request */ }\r\nexport function about   (context) { /* handle request */ }\r\nexport function contact (context) { /* handle request */ }\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\r\n\texport function login  (context) { /* handle request */ }\r\n\texport function logout (context) { /* handle request */ }\r\n}\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"http://www.apache.org/licenses/LICENSE-2.0.html","type":"Apache 2.0"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"develop nodejs web services with the typescript programming language.","directories":{},"dependencies":{"typescript.api":"0.5.1"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.2.7":{"name":"appex","version":"0.2.7","keywords":["typescript","web app","compiler"],"author":{"name":"sinclair"},"_id":"appex@0.2.7","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"f7b52cd8aaf2cf7827c5202bc225298272a79fad","tarball":"https://registry.npmjs.org/appex/-/appex-0.2.7.tgz","integrity":"sha512-zBZ2kaNMLi7LxC1K1l30gAx4rE9bLxu9YqjBWV7j2A37E1qt7cpW0ZipkcFsWEnxW9OuIkioboh3KEPTK7G1jA==","signatures":[{"sig":"MEYCIQCZd18tN0cMQGfKExiNkxE6zG50UniwiJnjRTZXrhP/5QIhAJ0WdhCRyEKq5IU7VeNiLS3S4J7dFiCasipl46ZWL8Yj","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/assets/logo.jpg)\r\n\r\n### nodejs web apps with [typescript](http://www.typescriptlang.org/)\r\n\r\n```javascript\r\nexport module app.services {\r\n\r\n\t// http://[host]:[port]/app/services/message\r\n\texport function message(context) {\r\n\r\n\t\tcontext.response.write('hello world!!');\r\n\r\n\t\tcontext.response.end();\r\n\t}\r\n}\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n\r\n* [overview](#overview)\r\n* [getting started](#getting_started)\r\n\t* [the appex runtime](#runtime)\r\n\t* [runtime options](#options)\r\n\t* [binding to an http server](#http_server)\r\n\t* [binding to an express instance](#express_server)\r\n* [creating services with typescript](#creating_services)\r\n\t* [appex context](#appex_context)\r\n\t* [appex http handlers](#appex_http_handlers)\r\n\t* [appex json handlers](#appex_json_handlers)\r\n\t* [appex signatures](#appex_signatures)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [routing functions](#routing_functions)\r\n\t* [index functions](#index_functions)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [development mode](#development_mode)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n\r\n<a name=\"overview\" />\r\n## overview\r\n\r\nAppex is a nodejs web service framework built on top of the TypeScript programming language. Appex \r\nenables nodejs developers to expose typescript functions as http endpoints as well as generate meaningful service\r\nmeta data for clients to consume.\r\n\r\nAppex also provides a dynamic compilation environment for typescript to aid in development. Appex will effeciently \r\nmanage compilation in the background without the need to restart the web server, or use additional modules.\r\n\r\nAppex is designed to operate as both a standalone web service solution or a compliment an existing applications written\r\nin frameworks such as express / connect.\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline getting up and running with Appex. \r\n\r\n<a name=\"runtime\" />\r\n### the appex runtime\r\n\r\nThe Appex runtime is compilation engine that handles compiling typescript code, mapping routes and function \r\ninvocation. Appex provides a utility method for setting up the runtime, as described below.\r\n\r\n```javascript\r\nvar http    = require('http');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar runtime = appex.runtime ( { sourcefile : './program.ts' } ); // create the runtime.\r\n\r\nvar server  = http.createServer( runtime ); // bind to the http server.\r\n\r\nserver.listen(3000);\r\n```\r\n\r\nThe appex.runtime() method returns a http handler function which is both compatable with nodejs' \r\nhttp server as well as connect middleware. This is the recommended approach of creating runtimes, \r\nHowever, if you need to access the runtime directly or are simply curious, you can also setup \r\nthe runtime as follows..\r\n\r\n```javascript\r\nvar http    = require('http');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar runtime = new appex.Runtime ( { sourcefile : './program.ts' } );\r\n\r\nvar server  = http.createServer( function(req, res) {\r\n    \r\n\tconsole.log(runtime); // investigate the runtime.\r\n\r\n    runtime.request_handler(req, res, function() { \r\n\r\n\t\t// request was not handled...\r\n\r\n\t});  \r\n});\r\n\r\nserver.listen(3000)\r\n```\r\n\r\n<a name=\"options\" />\r\n### runtime options\r\n\r\nThe appex runtime accepts the following options.\r\n\r\n```javascript\r\nvar options = { \r\n\tsourcefile : './program.ts', // (required) location of source file.\r\n    devmode    : true,           // (optional) recompile on request. \r\n    logging    : true,           // (optional) write requests to stdout.\r\n\tstdout     : process.stdout, // (optional) output stream. default is process.stdout\r\n\tstderr     : process.stderr, // (optional) error  stream. default is process.stderr\r\n};\r\n\r\nvar runtime = appex.runtime ( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### binding to an http server\r\n\r\nSetting up on a nodejs http server.\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// file: program.ts\r\n//----------------------------------------------\r\nexport module services {\r\n\t\r\n\t// url: http://localhost:3000/services/message\r\n\texport function message (context) { \r\n\t\t\r\n\t\tcontext.response.write('hello typescript');\r\n\r\n\t\tcontext.response.end(); \r\n\t}\r\n}\r\n\r\n//----------------------------------------------\r\n// file: app.js\r\n//----------------------------------------------\r\n\r\nvar http    = require('http');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar runtime = appex.runtime ( { sourcefile : './program.ts' } );\r\n\r\nvar server  = http.createServer( runtime );\r\n\r\nserver.listen(3000);\r\n```\r\n<a name=\"express_server\" />\r\n### binding to an express instance\r\n\r\nThe following illistrates setting up appex on an express instance.\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// file: program.ts\r\n//----------------------------------------------\r\n\r\nexport module services {\r\n\t\r\n\t// url: http://localhost:3000/services/message\r\n\texport function message (context) { \r\n\t\t\r\n\t\tcontext.response.write('hello typescript');\r\n\r\n\t\tcontext.response.end(); \r\n\t}\r\n}\r\n\r\n//----------------------------------------------\r\n// file: app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex.runtime ( { sourcefile : './program.ts' } ) );\r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"creating_services\" />\r\n## creating services with typescript\r\n\r\nAppex enables developers to write http endpoints by writing typescript functions. \r\n\r\nThe following section describes how to write http accessible functions. \r\n\r\n<a name=\"appex_context\" />\r\n### appex_context\r\n\r\nAll appex functions are passed a object context as the first argument. The context object encapulates\r\nthe http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the context object\r\nexport function method(context) {\r\n\t// context.request    - the http request object.\r\n\t// context.response   - the http response object.\r\n\t// context.reflection - appex runtime type information.\r\n\t// context.routes     - appex routing tables.\r\n\t// context.exports    - appex module exports. \r\n}\r\n```\r\n\r\n<a name=\"appex_http_handlers\" />\r\n### appex http handlers\r\n\r\nA appex http handler is defined with the following signature.\r\n\r\n* argument[0] - the appex context\r\n* returns     - void (optional)\r\n\r\nhttp handler functions need to complete the http request.\r\n\r\n```javascript\r\nexport function method(context) : void {\r\n\r\n\tcontext.response.write('hello world');\r\n\t\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"appex_json_handlers\" />\r\n### appex json handlers\r\n\r\nA appex json handler is a function suited to handling json based http requests. appex json handlers\r\nare invoked via HTTP POST and expect JSON to be subbmited with the request. Passing null or invalid\r\nJSON results in the request argument being null.\r\n\r\nA appex json handler requires the following signature.\r\n\r\n* argument[0] - the appex context\r\n* argument[1] - A optionally typed json request object. \r\n* argument[2] - a optionally typed optypescript callback with a single argument for the object response.\r\n* returns     - void (optional) \r\n\r\nThe return type is optional. json handler functions \"must\" invoke the callback to complete the request.\r\n\r\n```javascript\r\nexport function method(context, request, callback:(response) => void) : void {\r\n\r\n\tcallback(request); // echo the object back.\r\n\r\n}\r\n```\r\n<a name=\"appex_signatures\" />\r\n### appex signatures\r\n\r\nAppex only supports two function signatures for http binding. Functions that do not conform to these\r\nsignatures will be ignored as http endpoints.\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting_functions\r\n\r\nAppex extends TypeScripts concept of visibility to include visibility over http. From this\r\ndevelopers and control which functions are exported as http handlers.  \r\n\r\nIn order to make a function accessible over http, you must explicitly \"export\" this function. \r\n\r\nConsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.write('testing');\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\nThe above will result in the following route being created:\r\n\r\n```javascript\r\nhttp://[host]:[port]/public_function\r\n```\r\n\r\n<a name=\"routing_functions\" />\r\n### routing functions\r\n\r\nAppex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\nexport function index   (context:any) { }\r\n\r\nexport function about   (context:any) { }\r\n\r\nexport function contact (context:any) { }\r\n\r\nexport module services.customers {\r\n\r\n\texport function insert(context:any) : void { }\r\n\r\n\texport function update(context:any) : void { }\r\n\r\n\texport function delete(context:any) : void { }\r\n}\r\n\r\n// results in the following routes\r\n// http://[host]:[port]/\r\n// http://[host]:[port]/about\r\n// http://[host]:[port]/contact\r\n// http://[host]:[port]/services/customers/insert\r\n// http://[host]:[port]/services/customers/update\r\n// http://[host]:[port]/services/customers/delete\r\n```\r\n\r\n<a name=\"index_functions\" />\r\n### index_functions\r\n\r\nAppex denotes that functions named 'index' resolve to the current module scope. As demonstrated below: \r\n\r\n```javascript\r\nexport function index(context) { }\r\n\r\nexport module blogs {\r\n\r\n\texport function index (context) { }\r\n\r\n\texport function get   (context) { }\r\n}\r\n\r\n// results in the following routes\r\n// http://[host]:[port]/\r\n// http://[host]:[port]/blogs\r\n// http://[host]:[port]/blogs/get\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\nAppex enables nodejs developers to write applications in TypeScript as though it were native to nodejs. The following\r\nsection outlines how to effeciently with Appex and the TypeScript programming language.\r\n\r\n<a name=\"development_mode\" />\r\n### development_mode\r\n\r\n```javascript \r\n// enable dynamic compilations with the devmode option.\r\nvar runtime = appex.runtime ({ sourcefile : './program.ts', devmode : true, logging: true }); \r\n```\r\nAppex is built directly on top of the Microsoft TypeScript 0.9 compiler and leverages it for tight\r\nintegration with the nodejs platform. By enabling the 'devmode' option, Appex will efficiently\r\nrebuild your source code on each request made to the server. \r\n\r\nAppex achieves performance in this regard by leveraging features available in\r\nTypeScript compiler which facilitate incremental building / caching of typescript \r\ncompilation units. \r\n\r\nIn addition to this, compilations are run as a background worker process to ensure they \r\ndo interupt requests being served on the parent web process. \r\n\r\nAppex will output syntax and type errors to the stdout and http response. Syntax errors \r\nwill not bring down the web process. And you won't need to restart on code updates.\r\n\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nAppex leverages TypeScript's ability to reference source files with the 'reference' element. Appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar runtime = appex.runtime ({ sourcefile : './index.ts' });\r\n\r\nrequire('http').createServer( runtime  ).listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"pages.ts\" />\r\n/// <reference path=\"users.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\nexport function index   (context) { /* handle request */ }\r\nexport function about   (context) { /* handle request */ }\r\nexport function contact (context) { /* handle request */ }\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\r\n\texport function login  (context) { /* handle request */ }\r\n\texport function logout (context) { /* handle request */ }\r\n}\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"http://www.apache.org/licenses/LICENSE-2.0.html","type":"Apache 2.0"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"nodejs web apps with","directories":{},"dependencies":{"typescript.api":"0.5.1"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.2.8":{"name":"appex","version":"0.2.8","keywords":["typescript","web app","compiler"],"author":{"name":"sinclair"},"_id":"appex@0.2.8","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"0555bad9994bdec5a06ad9cb4544392063d8c790","tarball":"https://registry.npmjs.org/appex/-/appex-0.2.8.tgz","integrity":"sha512-XoUuPr4GQXmdV6uA4pOjY1qXUhCELOY2CWadUdN3E4lBaW13StaGBGkFnlSkP2+oYUAHWNGoHzejhrx+piXJ8w==","signatures":[{"sig":"MEYCIQCxeqje9YMi4URnkE0RrxwErTiYfi2V+mQa5Y3S7L/jjwIhAMKUH31fr77eZ6WhX2iPjpGh0DGbV4NBof5PTz54RwWG","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/assets/logo.jpg)\r\n\r\n### nodejs web apps with [typescript](http://www.typescriptlang.org/)\r\n\r\n```javascript\r\nexport module app.services {\r\n\r\n\t// http://[host]:[port]/app/services/message\r\n\texport function message(context) {\r\n\r\n\t\tcontext.response.write('hello world!!');\r\n\r\n\t\tcontext.response.end();\r\n\t}\r\n}\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n\r\n* [overview](#overview)\r\n* [getting started](#getting_started)\r\n\t* [the appex runtime](#runtime)\r\n\t* [runtime options](#options)\r\n\t* [binding to an http server](#http_server)\r\n\t* [binding to an express instance](#express_server)\r\n* [creating services with typescript](#creating_services)\r\n\t* [appex context](#appex_context)\r\n\t* [appex http handlers](#appex_http_handlers)\r\n\t* [appex json handlers](#appex_json_handlers)\r\n\t* [appex signatures](#appex_signatures)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [routing functions](#routing_functions)\r\n\t* [index functions](#index_functions)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [development mode](#development_mode)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n\r\n<a name=\"overview\" />\r\n## overview\r\n\r\nAppex is a nodejs web service framework built on top of the TypeScript programming language. Appex \r\nenables nodejs developers to expose typescript functions as http endpoints as well as generate meaningful service\r\nmeta data for clients to consume.\r\n\r\nAppex also provides a dynamic compilation environment for typescript to aid in development. Appex will effeciently \r\nmanage compilation in the background without the need to restart the web server, or use additional modules.\r\n\r\nAppex is designed to operate as both a standalone web service solution or a compliment an existing applications written\r\nin frameworks such as express / connect.\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline getting up and running with Appex. \r\n\r\n<a name=\"runtime\" />\r\n### the appex runtime\r\n\r\nThe Appex runtime is compilation engine that handles compiling typescript code, mapping routes and function \r\ninvocation. Appex provides a utility method for setting up the runtime, as described below.\r\n\r\n```javascript\r\nvar http    = require('http');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar runtime = appex.runtime ( { sourcefile : './program.ts' } ); // create the runtime.\r\n\r\nvar server  = http.createServer( runtime ); // bind to the http server.\r\n\r\nserver.listen(3000);\r\n```\r\n\r\nThe appex.runtime() method returns a http handler function which is both compatable with nodejs' \r\nhttp server as well as connect middleware. This is the recommended approach of creating runtimes, \r\nHowever, if you need to access the runtime directly or are simply curious, you can also setup \r\nthe runtime as follows..\r\n\r\n```javascript\r\nvar http    = require('http');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar runtime = new appex.Runtime ( { sourcefile : './program.ts' } );\r\n\r\nvar server  = http.createServer( function(req, res) {\r\n    \r\n\tconsole.log(runtime); // investigate the runtime.\r\n\r\n    runtime.request_handler(req, res, function() { \r\n\r\n\t\t// request was not handled...\r\n\r\n\t});  \r\n});\r\n\r\nserver.listen(3000)\r\n```\r\n\r\n<a name=\"options\" />\r\n### runtime options\r\n\r\nThe appex runtime accepts the following options.\r\n\r\n```javascript\r\nvar options = { \r\n\tsourcefile : './program.ts', // (required) location of source file.\r\n    devmode    : true,           // (optional) recompile on request. \r\n    logging    : true,           // (optional) write requests to stdout.\r\n\tstdout     : process.stdout, // (optional) output stream. default is process.stdout\r\n\tstderr     : process.stderr, // (optional) error  stream. default is process.stderr\r\n};\r\n\r\nvar runtime = appex.runtime ( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### binding to an http server\r\n\r\nSetting up on a nodejs http server.\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// file: program.ts\r\n//----------------------------------------------\r\nexport module services {\r\n\t\r\n\t// url: http://localhost:3000/services/message\r\n\texport function message (context) { \r\n\t\t\r\n\t\tcontext.response.write('hello typescript');\r\n\r\n\t\tcontext.response.end(); \r\n\t}\r\n}\r\n\r\n//----------------------------------------------\r\n// file: app.js\r\n//----------------------------------------------\r\n\r\nvar http    = require('http');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar runtime = appex.runtime ( { sourcefile : './program.ts' } );\r\n\r\nvar server  = http.createServer( runtime );\r\n\r\nserver.listen(3000);\r\n```\r\n<a name=\"express_server\" />\r\n### binding to an express instance\r\n\r\nThe following illistrates setting up appex on an express instance.\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// file: program.ts\r\n//----------------------------------------------\r\n\r\nexport module services {\r\n\t\r\n\t// url: http://localhost:3000/services/message\r\n\texport function message (context) { \r\n\t\t\r\n\t\tcontext.response.write('hello typescript');\r\n\r\n\t\tcontext.response.end(); \r\n\t}\r\n}\r\n\r\n//----------------------------------------------\r\n// file: app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex.runtime ( { sourcefile : './program.ts' } ) );\r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"creating_services\" />\r\n## creating services with typescript\r\n\r\nAppex enables developers to write http endpoints by writing typescript functions. \r\n\r\nThe following section describes how to write http accessible functions. \r\n\r\n<a name=\"appex_context\" />\r\n### appex_context\r\n\r\nAll appex functions are passed a object context as the first argument. The context object encapulates\r\nthe http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the context object\r\nexport function method(context) {\r\n\t// context.request    - the http request object.\r\n\t// context.response   - the http response object.\r\n\t// context.reflection - appex runtime type information.\r\n\t// context.routes     - appex routing tables.\r\n\t// context.exports    - appex module exports. \r\n}\r\n```\r\n\r\n<a name=\"appex_http_handlers\" />\r\n### appex http handlers\r\n\r\nA appex http handler is defined with the following signature.\r\n\r\n* argument[0] - the appex context\r\n* returns     - void (optional)\r\n\r\nhttp handler functions need to complete the http request.\r\n\r\n```javascript\r\nexport function method(context) : void {\r\n\r\n\tcontext.response.write('hello world');\r\n\t\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"appex_json_handlers\" />\r\n### appex json handlers\r\n\r\nA appex json handler is a function suited to handling json based http requests. appex json handlers\r\nare invoked via HTTP POST and expect JSON to be subbmited with the request. Passing null or invalid\r\nJSON results in the request argument being null.\r\n\r\nA appex json handler requires the following signature.\r\n\r\n* argument[0] - the appex context\r\n* argument[1] - A optionally typed json request object. \r\n* argument[2] - a optionally typed optypescript callback with a single argument for the object response.\r\n* returns     - void (optional) \r\n\r\nThe return type is optional. json handler functions \"must\" invoke the callback to complete the request.\r\n\r\n```javascript\r\nexport function method(context, request, callback:(response) => void) : void {\r\n\r\n\tcallback(request); // echo the object back.\r\n\r\n}\r\n```\r\n<a name=\"appex_signatures\" />\r\n### appex signatures\r\n\r\nAppex only supports two function signatures for http binding. Functions that do not conform to these\r\nsignatures will be ignored as http endpoints.\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting_functions\r\n\r\nAppex extends TypeScripts concept of visibility to include visibility over http. From this\r\ndevelopers and control which functions are exported as http handlers.  \r\n\r\nIn order to make a function accessible over http, you must explicitly \"export\" this function. \r\n\r\nConsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.write('testing');\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\nThe above will result in the following route being created:\r\n\r\n```javascript\r\nhttp://[host]:[port]/public_function\r\n```\r\n\r\n<a name=\"routing_functions\" />\r\n### routing functions\r\n\r\nAppex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\nexport function index   (context:any) { }\r\n\r\nexport function about   (context:any) { }\r\n\r\nexport function contact (context:any) { }\r\n\r\nexport module services.customers {\r\n\r\n\texport function insert(context:any) : void { }\r\n\r\n\texport function update(context:any) : void { }\r\n\r\n\texport function delete(context:any) : void { }\r\n}\r\n\r\n// results in the following routes\r\n// http://[host]:[port]/\r\n// http://[host]:[port]/about\r\n// http://[host]:[port]/contact\r\n// http://[host]:[port]/services/customers/insert\r\n// http://[host]:[port]/services/customers/update\r\n// http://[host]:[port]/services/customers/delete\r\n```\r\n\r\n<a name=\"index_functions\" />\r\n### index_functions\r\n\r\nAppex denotes that functions named 'index' resolve to the current module scope. As demonstrated below: \r\n\r\n```javascript\r\nexport function index(context) { }\r\n\r\nexport module blogs {\r\n\r\n\texport function index (context) { }\r\n\r\n\texport function get   (context) { }\r\n}\r\n\r\n// results in the following routes\r\n// http://[host]:[port]/\r\n// http://[host]:[port]/blogs\r\n// http://[host]:[port]/blogs/get\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\nAppex enables nodejs developers to write applications in TypeScript as though it were native to nodejs. The following\r\nsection outlines how to effeciently with Appex and the TypeScript programming language.\r\n\r\n<a name=\"development_mode\" />\r\n### development_mode\r\n\r\n```javascript \r\n// enable dynamic compilations with the devmode option.\r\nvar runtime = appex.runtime ({ sourcefile : './program.ts', devmode : true, logging: true }); \r\n```\r\nAppex is built directly on top of the Microsoft TypeScript 0.9 compiler and leverages it for tight\r\nintegration with the nodejs platform. By enabling the 'devmode' option, Appex will efficiently\r\nrebuild your source code on each request made to the server. \r\n\r\nAppex achieves performance in this regard by leveraging features available in\r\nTypeScript compiler which facilitate incremental building / caching of typescript \r\ncompilation units. \r\n\r\nIn addition to this, compilations are run as a background worker process to ensure they \r\ndo interupt requests being served on the parent web process. \r\n\r\nAppex will output syntax and type errors to the stdout and http response. Syntax errors \r\nwill not bring down the web process. And you won't need to restart on code updates.\r\n\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nAppex leverages TypeScript's ability to reference source files with the 'reference' element. Appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar runtime = appex.runtime ({ sourcefile : './index.ts' });\r\n\r\nrequire('http').createServer( runtime  ).listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"pages.ts\" />\r\n/// <reference path=\"users.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\nexport function index   (context) { /* handle request */ }\r\nexport function about   (context) { /* handle request */ }\r\nexport function contact (context) { /* handle request */ }\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\r\n\texport function login  (context) { /* handle request */ }\r\n\texport function logout (context) { /* handle request */ }\r\n}\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"http://www.apache.org/licenses/LICENSE-2.0.html","type":"Apache 2.0"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"nodejs web apps with typescript","directories":{},"dependencies":{"typescript.api":"0.5.1"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.2.9":{"name":"appex","version":"0.2.9","keywords":["typescript","web app","compiler"],"author":{"name":"sinclair"},"_id":"appex@0.2.9","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"8838852937bafc2306d0ba0fb91f63aac8334c35","tarball":"https://registry.npmjs.org/appex/-/appex-0.2.9.tgz","integrity":"sha512-Cfq+1dlEX/07G054c2PtDoi73XyvxaTBN0MXbQ/oxWY1TZvb9QFH7KwmUuLOtIVonxhP7UHbEfe9hno4oWK2FQ==","signatures":[{"sig":"MEYCIQCXc1xGhf23qoPzQj97t5ngnEv5du3jFeLyssT8wRuWygIhAOuOPJyQqxIo8zeG2EU6xGius3gIZDdrsRI7XRACUZpT","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/assets/logo.jpg)\r\n\r\n### nodejs web apps with [typescript](http://www.typescriptlang.org/)\r\n\r\n```javascript\r\nexport module app.services {\r\n\r\n\t// http://[host]:[port]/app/services/message\r\n\texport function message(context) {\r\n\r\n\t\tcontext.response.write('hello world!!');\r\n\r\n\t\tcontext.response.end();\r\n\t}\r\n}\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n\r\n* [overview](#overview)\r\n* [getting started](#getting_started)\r\n\t* [the appex runtime](#runtime)\r\n\t* [runtime options](#options)\r\n\t* [binding to an http server](#http_server)\r\n\t* [binding to an express instance](#express_server)\r\n* [creating services with typescript](#creating_services)\r\n\t* [appex context](#appex_context)\r\n\t* [appex http handlers](#appex_http_handlers)\r\n\t* [appex json handlers](#appex_json_handlers)\r\n\t* [appex signatures](#appex_signatures)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [routing functions](#routing_functions)\r\n\t* [index functions](#index_functions)\r\n\t* [wildcard functions](#wildcard_functions)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [development mode](#development_mode)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n\r\n<a name=\"overview\" />\r\n## overview\r\n\r\nAppex is a nodejs web service framework built on top of the TypeScript programming language. Appex \r\nenables nodejs developers to expose typescript functions as http endpoints as well as generate meaningful service\r\nmeta data for clients to consume.\r\n\r\nAppex also provides a dynamic compilation environment for typescript to aid in development. Appex will effeciently \r\nmanage compilation in the background without the need to restart the web server, or use additional modules.\r\n\r\nAppex is designed to operate as both a standalone web service solution or a compliment an existing applications written\r\nin frameworks such as express / connect.\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline getting up and running with Appex. \r\n\r\n<a name=\"runtime\" />\r\n### the appex runtime\r\n\r\nThe Appex runtime is compilation engine that handles compiling typescript code, mapping routes and function \r\ninvocation. Appex provides a utility method for setting up the runtime, as described below.\r\n\r\n```javascript\r\nvar http    = require('http');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar runtime = appex.runtime ( { sourcefile : './program.ts' } ); // create the runtime.\r\n\r\nvar server  = http.createServer( runtime ); // bind to the http server.\r\n\r\nserver.listen(3000);\r\n```\r\n\r\nThe appex.runtime() method returns a http handler function which is both compatable with nodejs' \r\nhttp server as well as connect middleware. This is the recommended approach of creating runtimes, \r\nHowever, if you need to access the runtime directly or are simply curious, you can also setup \r\nthe runtime as follows..\r\n\r\n```javascript\r\nvar http    = require('http');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar runtime = new appex.Runtime ( { sourcefile : './program.ts' } );\r\n\r\nvar server  = http.createServer( function(req, res) {\r\n    \r\n\tconsole.log(runtime); // investigate the runtime.\r\n\r\n    runtime.request_handler(req, res, function() { \r\n\r\n\t\t// request was not handled...\r\n\r\n\t});  \r\n});\r\n\r\nserver.listen(3000)\r\n```\r\n\r\n<a name=\"options\" />\r\n### runtime options\r\n\r\nThe appex runtime accepts the following options.\r\n\r\n```javascript\r\nvar options = { \r\n\tsourcefile : './program.ts', // (required) location of source file.\r\n    devmode    : true,           // (optional) recompile on request. \r\n    logging    : true,           // (optional) write requests to stdout.\r\n\tstdout     : process.stdout, // (optional) output stream. default is process.stdout\r\n\tstderr     : process.stderr, // (optional) error  stream. default is process.stderr\r\n};\r\n\r\nvar runtime = appex.runtime ( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### binding to an http server\r\n\r\nSetting up on a nodejs http server.\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// file: program.ts\r\n//----------------------------------------------\r\nexport module services {\r\n\t\r\n\t// url: http://localhost:3000/services/message\r\n\texport function message (context) { \r\n\t\t\r\n\t\tcontext.response.write('hello typescript');\r\n\r\n\t\tcontext.response.end(); \r\n\t}\r\n}\r\n\r\n//----------------------------------------------\r\n// file: app.js\r\n//----------------------------------------------\r\n\r\nvar http    = require('http');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar runtime = appex.runtime ( { sourcefile : './program.ts' } );\r\n\r\nvar server  = http.createServer( runtime );\r\n\r\nserver.listen(3000);\r\n```\r\n<a name=\"express_server\" />\r\n### binding to an express instance\r\n\r\nThe following illistrates setting up appex on an express instance.\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// file: program.ts\r\n//----------------------------------------------\r\n\r\nexport module services {\r\n\t\r\n\t// url: http://localhost:3000/services/message\r\n\texport function message (context) { \r\n\t\t\r\n\t\tcontext.response.write('hello typescript');\r\n\r\n\t\tcontext.response.end(); \r\n\t}\r\n}\r\n\r\n//----------------------------------------------\r\n// file: app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex.runtime ( { sourcefile : './program.ts' } ) );\r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"creating_services\" />\r\n## creating services with typescript\r\n\r\nAppex enables developers to write http endpoints by writing typescript functions. \r\n\r\nThe following section describes how to write http accessible functions. \r\n\r\n<a name=\"appex_context\" />\r\n### appex_context\r\n\r\nAll appex functions are passed a object context as the first argument. The context object encapulates\r\nthe http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the context object\r\nexport function method(context) {\r\n\t// context.request    - the http request object.\r\n\t// context.response   - the http response object.\r\n\t// context.reflection - appex runtime type information.\r\n\t// context.routes     - appex routing tables.\r\n\t// context.exports    - appex module exports. \r\n}\r\n```\r\n\r\n<a name=\"appex_http_handlers\" />\r\n### appex http handlers\r\n\r\nA appex http handler is defined with the following signature.\r\n\r\n* argument[0] - the appex context\r\n* returns     - void (optional)\r\n\r\nhttp handler functions need to complete the http request.\r\n\r\n```javascript\r\nexport function method(context) : void {\r\n\r\n\tcontext.response.write('hello world');\r\n\t\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"appex_json_handlers\" />\r\n### appex json handlers\r\n\r\nA appex json handler is a function suited to handling json based http requests. appex json handlers\r\nare invoked via HTTP POST and expect JSON to be subbmited with the request. Passing null or invalid\r\nJSON results in the request argument being null.\r\n\r\nA appex json handler requires the following signature.\r\n\r\n* argument[0] - the appex context\r\n* argument[1] - A optionally typed json request object. \r\n* argument[2] - a optionally typed optypescript callback with a single argument for the object response.\r\n* returns     - void (optional) \r\n\r\nThe return type is optional. json handler functions \"must\" invoke the callback to complete the request.\r\n\r\n```javascript\r\nexport function method(context, request, callback:(response) => void) : void {\r\n\r\n\tcallback(request); // echo the object back.\r\n\r\n}\r\n```\r\n<a name=\"appex_signatures\" />\r\n### appex signatures\r\n\r\nAppex only supports two function signatures for http binding. Functions that do not conform to these\r\nsignatures will be ignored as http endpoints.\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting_functions\r\n\r\nAppex extends TypeScripts concept of visibility to include visibility over http. From this\r\ndevelopers and control which functions are exported as http handlers.  \r\n\r\nIn order to make a function accessible over http, you must explicitly \"export\" this function. \r\n\r\nConsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.write('testing');\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\nThe above will result in the following route being created:\r\n\r\n```javascript\r\nhttp://[host]:[port]/public_function\r\n```\r\n\r\n<a name=\"routing_functions\" />\r\n### routing functions\r\n\r\nAppex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\nexport function index   (context:any) { }\r\n\r\nexport function about   (context:any) { }\r\n\r\nexport function contact (context:any) { }\r\n\r\nexport module services.customers {\r\n\r\n\texport function insert(context:any) : void { }\r\n\r\n\texport function update(context:any) : void { }\r\n\r\n\texport function delete(context:any) : void { }\r\n}\r\n\r\n// results in the following routes\r\n// http://[host]:[port]/\r\n// http://[host]:[port]/about\r\n// http://[host]:[port]/contact\r\n// http://[host]:[port]/services/customers/insert\r\n// http://[host]:[port]/services/customers/update\r\n// http://[host]:[port]/services/customers/delete\r\n```\r\n\r\n<a name=\"index_functions\" />\r\n### index_functions\r\n\r\nAppex denotes that functions named 'index' resolve to the current module scope. As demonstrated below: \r\n\r\n```javascript\r\nexport function index(context) { }\r\n\r\nexport module blogs {\r\n\r\n\texport function index (context) { }\r\n\r\n\texport function get   (context) { }\r\n}\r\n\r\n// results in the following routes\r\n// http://[host]:[port]/\r\n// http://[host]:[port]/blogs\r\n// http://[host]:[port]/blogs/get\r\n```\r\n<a name=\"wildcard_functions\" />\r\n### wildcard_functions\r\n\r\nAppex supports wildcard/ url parameter arguments with functions named 'wildcard'. Wildcard are special \r\nin the regard they support more than one augment other than the context, for which url arguments will \r\nbe mapped.\r\n\r\n```javascript\r\nexport module blogs {\r\n    \r\n\t// url : http://[host]:[port]/blogs\r\n    export function index(context) {\r\n    \r\n        context.response.write('blogs index')\r\n\r\n        context.response.end();       \r\n    }\r\n\t\r\n\t// url : http://[host]:[port]/blogs/:year/:month/:day\r\n    export function wildcard(context, year, month, day) {\r\n\r\n        context.response.write('blogs ' + year + ' ' + month + ' ' + day)\r\n\r\n        context.response.end(); \r\n    }\r\n}\r\n```\r\n\r\nnote: wildcard functions should be declared last in any module scope. this way, specific route declared in this scope\r\nwill be resolved first.\r\n\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\nAppex enables nodejs developers to write applications in TypeScript as though it were native to nodejs. The following\r\nsection outlines how to effeciently with Appex and the TypeScript programming language.\r\n\r\n<a name=\"development_mode\" />\r\n### development_mode\r\n\r\n```javascript \r\n// enable dynamic compilations with the devmode option.\r\nvar runtime = appex.runtime ({ sourcefile : './program.ts', devmode : true, logging: true }); \r\n```\r\nAppex is built directly on top of the Microsoft TypeScript 0.9 compiler and leverages it for tight\r\nintegration with the nodejs platform. By enabling the 'devmode' option, Appex will efficiently\r\nrebuild your source code on each request made to the server. \r\n\r\nAppex achieves performance in this regard by leveraging features available in\r\nTypeScript compiler which facilitate incremental building / caching of typescript \r\ncompilation units. \r\n\r\nIn addition to this, compilations are run as a background worker process to ensure they \r\ndo interupt requests being served on the parent web process. \r\n\r\nAppex will output syntax and type errors to the stdout and http response. Syntax errors \r\nwill not bring down the web process. And you won't need to restart on code updates.\r\n\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nAppex leverages TypeScript's ability to reference source files with the 'reference' element. Appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar runtime = appex.runtime ({ sourcefile : './index.ts' });\r\n\r\nrequire('http').createServer( runtime  ).listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"pages.ts\" />\r\n/// <reference path=\"users.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\nexport function index   (context) { /* handle request */ }\r\nexport function about   (context) { /* handle request */ }\r\nexport function contact (context) { /* handle request */ }\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\r\n\texport function login  (context) { /* handle request */ }\r\n\texport function logout (context) { /* handle request */ }\r\n}\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"http://www.apache.org/licenses/LICENSE-2.0.html","type":"Apache 2.0"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"nodejs web apps with typescript","directories":{},"dependencies":{"typescript.api":"0.5.1"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.3.0":{"name":"appex","version":"0.3.0","keywords":["typescript","web app","compiler"],"author":{"name":"sinclair"},"_id":"appex@0.3.0","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"decc7238dd3aad65719a5422a6e9e1071f8d79e1","tarball":"https://registry.npmjs.org/appex/-/appex-0.3.0.tgz","integrity":"sha512-Ms0u0LMMiy7GTF3U7G4ACwQL+SY4VOs+SCrTpVm+Fy1ZEfFvcV7YUuWoeOFw48ltepChoyHjTlAPw98D3mcazQ==","signatures":[{"sig":"MEYCIQDb8DxWMaPbSZ4EXt7qYlUitIRMCw8L7IGJVTyd0+Y33wIhAKQix8jARUFFD3BTMldYT5DmZv0n7OcT12783ZAwvc+q","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/assets/logo.jpg)\r\n\r\n### nodejs web apps with [typescript](http://www.typescriptlang.org/)\r\n\r\n```javascript\r\nexport module app.services {\r\n\r\n\t// http://[host]:[port]/app/services/message\r\n\texport function message(context) {\r\n\r\n\t\tcontext.response.write('hello world!!');\r\n\r\n\t\tcontext.response.end();\r\n\t}\r\n}\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n\r\n* [overview](#overview)\r\n* [getting started](#getting_started)\r\n\t* [the appex runtime](#runtime)\r\n\t* [runtime options](#options)\r\n\t* [binding to an http server](#http_server)\r\n\t* [binding to an express instance](#express_server)\r\n* [creating services with typescript](#creating_services)\r\n\t* [appex context](#appex_context)\r\n\t* [appex http handlers](#appex_http_handlers)\r\n\t* [appex json handlers](#appex_json_handlers)\r\n\t* [appex signatures](#appex_signatures)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [routing functions](#routing_functions)\r\n\t* [index functions](#index_functions)\r\n\t* [wildcard functions](#wildcard_functions)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [development mode](#development_mode)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n\r\n<a name=\"overview\" />\r\n## overview\r\n\r\nAppex is a nodejs web service framework built on top of the TypeScript programming language. Appex \r\nenables nodejs developers to expose typescript functions as http endpoints as well as generate meaningful service\r\nmeta data for clients to consume.\r\n\r\nAppex also provides a dynamic compilation environment for typescript to aid in development. Appex will effeciently \r\nmanage compilation in the background without the need to restart the web server, or use additional modules.\r\n\r\nAppex is designed to operate as both a standalone web service solution or compliment an existing application written\r\nin frameworks such as express / connect.\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline getting up and running with Appex. \r\n\r\n<a name=\"runtime\" />\r\n### the appex runtime\r\n\r\nThe Appex runtime is compilation engine that handles compiling typescript code, mapping routes and function \r\ninvocation. Appex provides a utility method for setting up the runtime, as described below.\r\n\r\n```javascript\r\nvar http    = require('http');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar runtime = appex.runtime ( { sourcefile : './program.ts' } ); // create the runtime.\r\n\r\nvar server  = http.createServer( runtime ); // bind to the http server.\r\n\r\nserver.listen(3000);\r\n```\r\n\r\nThe appex.runtime() method returns a http handler function which is both compatable with nodejs' \r\nhttp server as well as connect middleware. This is the recommended approach of creating runtimes, \r\nHowever, if you need to access the runtime directly or are simply curious, you can also setup \r\nthe runtime as follows..\r\n\r\n```javascript\r\nvar http    = require('http');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar runtime = new appex.Runtime ( { sourcefile : './program.ts' } );\r\n\r\nvar server  = http.createServer( function(req, res) {\r\n    \r\n\tconsole.log(runtime); // investigate the runtime.\r\n\r\n    runtime.request_handler(req, res, function() { \r\n\r\n\t\t// request was not handled...\r\n\r\n\t});  \r\n});\r\n\r\nserver.listen(3000)\r\n```\r\n\r\n<a name=\"options\" />\r\n### runtime options\r\n\r\nThe appex runtime accepts the following options.\r\n\r\n```javascript\r\nvar options = { \r\n\tsourcefile : './program.ts', // (required) location of source file.\r\n    devmode    : true,           // (optional) recompile on request. \r\n    logging    : true,           // (optional) write requests to stdout.\r\n\tstdout     : process.stdout, // (optional) output stream. default is process.stdout\r\n\tstderr     : process.stderr, // (optional) error  stream. default is process.stderr\r\n};\r\n\r\nvar runtime = appex.runtime ( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### binding to an http server\r\n\r\nSetting up on a nodejs http server.\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// file: program.ts\r\n//----------------------------------------------\r\nexport module services {\r\n\t\r\n\t// url: http://localhost:3000/services/message\r\n\texport function message (context) { \r\n\t\t\r\n\t\tcontext.response.write('hello typescript');\r\n\r\n\t\tcontext.response.end(); \r\n\t}\r\n}\r\n\r\n//----------------------------------------------\r\n// file: app.js\r\n//----------------------------------------------\r\n\r\nvar http    = require('http');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar runtime = appex.runtime ( { sourcefile : './program.ts' } );\r\n\r\nvar server  = http.createServer( runtime );\r\n\r\nserver.listen(3000);\r\n```\r\n<a name=\"express_server\" />\r\n### binding to an express instance\r\n\r\nThe following illistrates setting up appex on an express instance.\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// file: program.ts\r\n//----------------------------------------------\r\n\r\nexport module services {\r\n\t\r\n\t// url: http://localhost:3000/services/message\r\n\texport function message (context) { \r\n\t\t\r\n\t\tcontext.response.write('hello typescript');\r\n\r\n\t\tcontext.response.end(); \r\n\t}\r\n}\r\n\r\n//----------------------------------------------\r\n// file: app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex.runtime ( { sourcefile : './program.ts' } ) );\r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"creating_services\" />\r\n## creating services with typescript\r\n\r\nAppex enables developers to write http endpoints by writing typescript functions. \r\n\r\nThe following section describes how to write http accessible functions. \r\n\r\n<a name=\"appex_context\" />\r\n### appex_context\r\n\r\nAll appex functions are passed a object context as the first argument. The context object encapulates\r\nthe http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the context object\r\nexport function method(context) {\r\n\t// context.request    - the http request object.\r\n\t// context.response   - the http response object.\r\n\t// context.reflection - appex runtime type information.\r\n\t// context.routes     - appex routing tables.\r\n\t// context.exports    - appex module exports. \r\n}\r\n```\r\n\r\n<a name=\"appex_http_handlers\" />\r\n### appex http handlers\r\n\r\nA appex http handler is defined with the following signature.\r\n\r\n* argument[0] - the appex context\r\n* returns     - void (optional)\r\n\r\nhttp handler functions need to complete the http request.\r\n\r\n```javascript\r\nexport function method(context) : void {\r\n\r\n\tcontext.response.write('hello world');\r\n\t\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"appex_json_handlers\" />\r\n### appex json handlers\r\n\r\nA appex json handler is a function suited to handling json based http requests. appex json handlers\r\nare invoked via HTTP POST and expect JSON to be subbmited with the request. Passing null or invalid\r\nJSON results in the request argument being null.\r\n\r\nA appex json handler requires the following signature.\r\n\r\n* argument[0] - the appex context\r\n* argument[1] - A optionally typed json request object. \r\n* argument[2] - a optionally typed optypescript callback with a single argument for the object response.\r\n* returns     - void (optional) \r\n\r\nThe return type is optional. json handler functions \"must\" invoke the callback to complete the request.\r\n\r\n```javascript\r\nexport function method(context, request, callback:(response) => void) : void {\r\n\r\n\tcallback(request); // echo the object back.\r\n\r\n}\r\n```\r\n<a name=\"appex_signatures\" />\r\n### appex signatures\r\n\r\nAppex only supports two function signatures for http binding. Functions that do not conform to these\r\nsignatures will be ignored as http endpoints.\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting_functions\r\n\r\nAppex extends TypeScripts concept of visibility to include visibility over http. From this\r\ndevelopers and control which functions are exported as http handlers.  \r\n\r\nIn order to make a function accessible over http, you must explicitly \"export\" this function. \r\n\r\nConsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.write('testing');\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\nThe above will result in the following route being created:\r\n\r\n```javascript\r\nhttp://[host]:[port]/public_function\r\n```\r\n\r\n<a name=\"routing_functions\" />\r\n### routing functions\r\n\r\nAppex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\nexport function index   (context:any) { }\r\n\r\nexport function about   (context:any) { }\r\n\r\nexport function contact (context:any) { }\r\n\r\nexport module services.customers {\r\n\r\n\texport function insert(context:any) : void { }\r\n\r\n\texport function update(context:any) : void { }\r\n\r\n\texport function delete(context:any) : void { }\r\n}\r\n\r\n// results in the following routes\r\n// http://[host]:[port]/\r\n// http://[host]:[port]/about\r\n// http://[host]:[port]/contact\r\n// http://[host]:[port]/services/customers/insert\r\n// http://[host]:[port]/services/customers/update\r\n// http://[host]:[port]/services/customers/delete\r\n```\r\n\r\n<a name=\"index_functions\" />\r\n### index_functions\r\n\r\nAppex denotes that functions named 'index' resolve to the current module scope. As demonstrated below: \r\n\r\n```javascript\r\nexport function index(context) { }\r\n\r\nexport module blogs {\r\n\r\n\texport function index (context) { }\r\n\r\n\texport function get   (context) { }\r\n}\r\n\r\n// results in the following routes\r\n// http://[host]:[port]/\r\n// http://[host]:[port]/blogs\r\n// http://[host]:[port]/blogs/get\r\n```\r\n<a name=\"wildcard_functions\" />\r\n### wildcard_functions\r\n\r\nAppex supports typed url arguments on functions named 'wildcard'. Wildcard functions are special in the regard \r\nthey support more than one argument (other than the context) for which url parameters will be mapped.\r\n\r\nAppex currently supports only numeric type annotations on wildcard arguments. All other types will mapped as strings.\r\nif a argument is annotated with 'number', then only numeric are matched. \r\n\r\n```javascript\r\nexport module blogs {\r\n    \r\n\t// url : http://[host]:[port]/blogs\r\n    export function index(context) {\r\n    \r\n        context.response.write('blogs index')\r\n\r\n        context.response.end();       \r\n    }\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11  - matched\r\n\t// url : http://[host]:[port]/blogs/2013/01/11 - matched\r\n\t// url : http://[host]:[port]/blogs/cat/01/11  - not matched\r\n    export function wildcard(context, year:number, month:number, day:number) {\r\n\r\n        context.response.write('blogs ' + year + ' ' + month + ' ' + day)\r\n\r\n        context.response.end(); \r\n    }\r\n}\r\n```\r\n\r\nnote: wildcard functions should be declared last in any module scope. this way, other function types in this scope\r\nwill be resolved first.\r\n\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\nAppex enables nodejs developers to write applications in TypeScript as though it were native to nodejs. The following\r\nsection outlines how to effeciently with Appex and the TypeScript programming language.\r\n\r\n<a name=\"development_mode\" />\r\n### development_mode\r\n\r\n```javascript \r\n// enable dynamic compilations with the devmode option.\r\nvar runtime = appex.runtime ({ sourcefile : './program.ts', devmode : true, logging: true }); \r\n```\r\nAppex is built directly on top of the Microsoft TypeScript 0.9 compiler and leverages it for tight\r\nintegration with the nodejs platform. By enabling the 'devmode' option, Appex will efficiently\r\nrebuild your source code on each request made to the server. \r\n\r\nAppex achieves performance in this regard by leveraging features available in\r\nTypeScript compiler which facilitate incremental building / caching of typescript \r\ncompilation units. \r\n\r\nIn addition to this, compilations are run as a background worker process to ensure they \r\ndo interupt requests being served on the parent web process. \r\n\r\nAppex will output syntax and type errors to the stdout and http response. Syntax errors \r\nwill not bring down the web process. And you won't need to restart on code updates.\r\n\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nAppex leverages TypeScript's ability to reference source files with the 'reference' element. Appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar runtime = appex.runtime ({ sourcefile : './index.ts' });\r\n\r\nrequire('http').createServer( runtime  ).listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"pages.ts\" />\r\n/// <reference path=\"users.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\nexport function index   (context) { /* handle request */ }\r\nexport function about   (context) { /* handle request */ }\r\nexport function contact (context) { /* handle request */ }\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\r\n\texport function login  (context) { /* handle request */ }\r\n\texport function logout (context) { /* handle request */ }\r\n}\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"http://www.apache.org/licenses/LICENSE-2.0.html","type":"Apache 2.0"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"nodejs web apps with typescript","directories":{},"dependencies":{"typescript.api":"0.5.1"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.3.1":{"name":"appex","version":"0.3.1","keywords":["typescript","web app","compiler"],"author":{"name":"sinclair"},"_id":"appex@0.3.1","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"ba7388b158a4b98ac22f05e81c2ef2a6a51ea64d","tarball":"https://registry.npmjs.org/appex/-/appex-0.3.1.tgz","integrity":"sha512-1GzTL2Tz+jv/WAxRG2Pxmp4bzncrKAEqPM6DtPG6D4JBQC0U5hLshTjGX6gzfxn8eRGc+f8mviDySyDFKzn2Aw==","signatures":[{"sig":"MEYCIQCkvqwdiDgam05YNM3XsLrVlnCUHPeX1GuhydJ3nOHFHAIhAL+JmJXfBcFBk2uMaFBU+jND/OmQktKtO11x8Cp3pyo+","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/assets/logo.jpg)\r\n\r\n### nodejs web apps with [typescript](http://www.typescriptlang.org/)\r\n\r\n```javascript\r\nexport module app.services {\r\n\r\n\t// http://[host]:[port]/app/services/message\r\n\texport function message(context) {\r\n\r\n\t\tcontext.response.write('hello world!!');\r\n\r\n\t\tcontext.response.end();\r\n\t}\r\n}\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n\r\n* [overview](#overview)\r\n* [getting started](#getting_started)\r\n\t* [the appex runtime](#runtime)\r\n\t* [runtime options](#options)\r\n\t* [binding to an http server](#http_server)\r\n\t* [binding to an express instance](#express_server)\r\n* [creating services with typescript](#creating_services)\r\n\t* [appex context](#appex_context)\r\n\t* [appex http handlers](#appex_http_handlers)\r\n\t* [appex json handlers](#appex_json_handlers)\r\n\t* [index functions](#index_functions)\r\n\t* [wildcard functions](#wildcard_functions)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [routing functions](#routing_functions)\r\n\t* [handling 404](#handling_404)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [development mode](#development_mode)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n\r\n<a name=\"overview\" />\r\n## overview\r\n\r\nappex is a nodejs web service framework built on top of the TypeScript programming language. appex \r\nenables nodejs developers to expose typescript functions as http endpoints as well as generate meaningful service\r\nmeta data for clients to consume.\r\n\r\nappex also provides a dynamic compilation environment for typescript to aid in development. appex will effeciently \r\nmanage compilation in the background without the need to restart the web server, or use additional modules.\r\n\r\nappex is designed to operate as both a standalone web service solution or as a complement to existing applications\r\nwritten in frameworks such as express / connect that wish to extend their projects with typed web api's. \r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline configuring appex.\r\n\r\n<a name=\"runtime\" />\r\n### the appex runtime\r\n\r\nThe appex runtime is compilation engine that handles dynamic compilation, route mapping and function \r\ninvocation. appex provides a simple utility method for setting up the runtime, as described below.\r\n\r\n```javascript\r\nvar http    = require('http');\r\n\r\nvar appex   = require('appex');\r\n\r\n// create the runtime.\r\nvar runtime = appex.runtime ( { sourcefile : './program.ts' } ); \r\n\r\n// bind to the http server.\r\nvar server  = http.createServer( runtime ); \r\n\r\nserver.listen(3000);\r\n```\r\n\r\nThe appex.runtime() method returns a http handler function which is both compatable with nodejs' \r\nhttp server as well as connect middleware. This is the recommended approach of creating runtimes, \r\nHowever, if you need to access the runtime directly or are simply curious, you can also setup \r\nthe runtime as follows..\r\n\r\n```javascript\r\nvar http    = require('http');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar runtime = new appex.Runtime ( { sourcefile : './program.ts' } );\r\n\r\nvar server  = http.createServer( function(req, res) {\r\n    \r\n\tconsole.log(runtime); // investigate the runtime.\r\n\r\n    runtime.request_handler(req, res, function() { \r\n\r\n\t\t// request was not handled...\r\n\r\n\t});  \r\n});\r\n\r\nserver.listen(3000)\r\n```\r\n\r\n<a name=\"options\" />\r\n### runtime options\r\n\r\nThe appex runtime accepts the following options.\r\n\r\n```javascript\r\nvar options = { \r\n\r\n\tsourcefile : './program.ts', // (required) location of source file.\r\n\r\n    devmode    : true,           // (optional) recompile on request. \r\n\r\n    logging    : true,           // (optional) write requests to stdout.\r\n\r\n\tstdout     : process.stdout, // (optional) output stream. default is process.stdout\r\n\r\n\tstderr     : process.stderr, // (optional) error  stream. default is process.stderr\r\n};\r\n\r\nvar runtime = appex.runtime ( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### binding to an http server\r\n\r\nSetting up appex on a nodejs http server.\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// file: program.ts\r\n//----------------------------------------------\r\n\r\nexport function index (context) { \r\n\t\t\r\n\tcontext.response.write('hello world');\r\n\r\n\tcontext.response.end(); \r\n}\r\n\r\n\r\n//----------------------------------------------\r\n// file: app.js\r\n//----------------------------------------------\r\n\r\nvar http    = require('http');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar runtime = appex.runtime ( { sourcefile : './program.ts' } );\r\n\r\nvar server  = http.createServer( runtime );\r\n\r\nserver.listen(3000);\r\n```\r\n<a name=\"express_server\" />\r\n### binding to an express instance\r\n\r\nThe following illistrates setting up appex on an express instance.\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// file: program.ts\r\n//----------------------------------------------\r\n\r\n// http://localhost:3000/about\r\nexport function about (context) { \r\n\r\n\tcontext.response.write('about page');\r\n\r\n\tcontext.response.end(); \r\n}\r\n\r\n\r\n//----------------------------------------------\r\n// file: app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex.runtime ( { sourcefile : './program.ts' } ) );\r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"creating_services\" />\r\n## creating services with typescript\r\n\r\nappex enables developers to write http endpoints by writing typescript functions. \r\n\r\nThe following section describes how to write http accessible functions. \r\n\r\n<a name=\"appex_context\" />\r\n### appex context\r\n\r\nAll appex functions are passed a context object as the first argument. The context object encapulates\r\nthe http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the context object\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.reflection - appex runtime type information.\r\n\r\n\t// context.routes     - appex routing tables.\r\n\r\n\t// context.exports    - appex module exports handles.\r\n\r\n\t// context.mime       - appex mime utility.\r\n}\r\n```\r\n\r\n<a name=\"appex_http_handlers\" />\r\n### appex http handlers\r\n\r\nA appex http handler is defined with the following signature.\r\n\r\n* argument[0] - the appex context\r\n* returns     - void (optional)\r\n\r\nhttp handler functions need to complete the http request.\r\n\r\n```javascript\r\n\r\n// url: http://[host]:[port]/method\r\nexport function method(context) : void {\r\n\r\n\tcontext.response.write('hello world');\r\n\t\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"appex_json_handlers\" />\r\n### appex json handlers\r\n\r\nA appex json handler is a function suited to handling json based http requests. appex json handlers\r\nare invoked via HTTP POST and expect JSON to be submitted with the request. POSTing null or invalid\r\nJSON results in the request argument being null.\r\n\r\nA appex json handler requires the following signature.\r\n\r\n* argument[0] - the appex context\r\n* argument[1] - A optionally typed json request object. \r\n* argument[2] - a optionally typed typescript callback with a single argument for the object response.\r\n* returns     - void (optional) \r\n\r\nThe return type is optional. json handler functions \"must\" invoke the callback to complete the request.\r\n\r\n```javascript\r\nexport function method(context, request, callback:(response) => void) : void {\r\n\r\n\tcallback(request); // echo\r\n\r\n}\r\n```\r\n\r\n<a name=\"index_functions\" />\r\n### index functions\r\n\r\nappex denotes that functions named 'index' resolve to the current module scope. As demonstrated below: \r\n\r\n```javascript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { }\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) { }\r\n\t\r\n\t// url: http://[host]:[port]/blogs/submit\r\n\texport function submit (context) { }\r\n}\r\n```\r\n<a name=\"wildcard_functions\" />\r\n### wildcard functions\r\n\r\nappex supports url wildcard routing by way of wildcard functions. Wildcard functions are special in the regard \r\nthey support more than one argument (other than the context) for which url parameters will be mapped.\r\n\r\nappex currently supports the type 'any' (or none), string and number type annotations on wildcard arguments. \r\nif a wildcard argument specifies any other type, the wildcard function will not be routed. \r\n\r\nif no type annotation is specified, appex will pass a string value.\r\n\r\n```javascript\r\nexport module blogs {\r\n    \r\n\t// url : http://[host]:[port]/blogs\r\n    export function index (context) { /* handle request */ }\r\n\t\r\n\t// http://[host]:[port]/blogs/submit\r\n\texport function submit (context) { /* handle request */ }\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11  - matched\r\n\t// url : http://[host]:[port]/blogs/2013/01/11 - matched\r\n\t// url : http://[host]:[port]/blogs/cat/01/11  - not matched\r\n    export function wildcard(context, year:number, month:number, day:number) {\r\n\r\n        context.response.write('blogs ' + year + ' ' + month + ' ' + day)\r\n\r\n        context.response.end(); \r\n    }\r\n}\r\n```\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex extends TypeScripts concept of visibility to include visibility over http. From this\r\ndevelopers and control which functions are exported as http endpoints.  \r\n\r\nIn order to make a function accessible over http, you must explicitly \"export\" the function. \r\n\r\nconsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.write('testing');\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"routing_functions\" />\r\n### routing functions\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context:any) { }\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context:any) { }\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context:any) { }\r\n\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context:any) : void { }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context:any) : void { }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context:any) : void { }\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```javascript\r\n// http:[host]:[port]/\r\nexport function index   (context) { \r\n\tcontext.response.writeHead(404, {'content-type' : 'text/plain'});\r\n\tcontext.response.write('home page');\r\n\tcontext.response.end();\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\tcontext.response.writeHead(404, {'content-type' : 'text/plain'});\r\n\tcontext.response.write(path + ' page not found');\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\nappex enables nodejs developers to write applications in pure TypeScript. The following\r\nsection outlines how to effeciently develop with appex and the TypeScript programming language.\r\n\r\n<a name=\"development_mode\" />\r\n### development mode\r\n\r\n```javascript \r\n// enable compilation on request with the devmode option.\r\nvar runtime = appex.runtime ({ sourcefile : './program.ts', \r\n\t\t\t\t\t\t\t   devmode    : true, \r\n\t\t\t\t\t\t\t   logging    : true }); \r\n\r\n```\r\nappex is built directly on top of the Microsoft TypeScript 0.9 compiler and leverages it for tight\r\nintegration with the nodejs platform. By enabling the 'devmode' option on a appex runtime, appex \r\nwill rebuild your source code on each request made to the server. \r\n\r\nappex achieves performance in this regard by leveraging features available in\r\nTypeScript compiler which facilitate incremental building / caching of typescript \r\ncompilation units. request compilation in devmode typically take tens of milliseconds \r\nto complete for modest size projects.\r\n\r\nIn addition to this, compilations are run as a background worker process to ensure they \r\ndo not interupt requests being served on the parent process. \r\n\r\nappex will output syntax and type errors to the runtime stdout as well as the http response. \r\nSyntax errors will not bring down the web process. And you won't need to restart on code \r\nupdates.\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar runtime = appex.runtime ({ sourcefile : './index.ts' });\r\n\r\nrequire('http').createServer( runtime  ).listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"pages.ts\" />\r\n/// <reference path=\"users.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { /* handle request */ }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { /* handle request */ }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { /* handle request */ }\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { /* handle request */ }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { /* handle request */ }\r\n}\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"http://www.apache.org/licenses/LICENSE-2.0.html","type":"Apache 2.0"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"nodejs web apps with typescript","directories":{},"dependencies":{"typescript.api":"0.5.1"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.3.2":{"name":"appex","version":"0.3.2","keywords":["typescript","web app","compiler"],"author":{"name":"sinclair"},"_id":"appex@0.3.2","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"9b8965e4d360ec9e5c961388c44d8a6778ad619a","tarball":"https://registry.npmjs.org/appex/-/appex-0.3.2.tgz","integrity":"sha512-v1xyCvbG+u2/CSctx5YIyhSid8DsbwPHimXq4tSyf8QqMw2RcQH12Wy30Ae5pxCtRIe3JhftwlY4SERiNtCkXQ==","signatures":[{"sig":"MEQCID4LKRJEq3ADlRJmmrYedqmhF/3OYBNUn10tnncgv2WCAiAq/4nEtRP4QL9XuLSktnJXJEe+AwlKJe2MdA6frKBBwg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/assets/logo.jpg)\r\n\r\n### nodejs web apps with [typescript](http://www.typescriptlang.org/)\r\n\r\n```javascript\r\nexport module app.services {\r\n\r\n\t// http://[host]:[port]/app/services/message\r\n\texport function message(context) {\r\n\r\n\t\tcontext.response.write('hello world!!');\r\n\r\n\t\tcontext.response.end();\r\n\t}\r\n}\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n\r\n* [overview](#overview)\r\n* [getting started](#getting_started)\r\n\t* [the appex runtime](#runtime)\r\n\t* [runtime options](#options)\r\n\t* [binding to an http server](#http_server)\r\n\t* [binding to an express instance](#express_server)\r\n* [creating services with typescript](#creating_services)\r\n\t* [appex context](#appex_context)\r\n\t* [appex http handlers](#appex_http_handlers)\r\n\t* [appex json handlers](#appex_json_handlers)\r\n\t* [index functions](#index_functions)\r\n\t* [wildcard functions](#wildcard_functions)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [routing functions](#routing_functions)\r\n\t* [handling 404](#handling_404)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [development mode](#development_mode)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n\r\n<a name=\"overview\" />\r\n## overview\r\n\r\nappex is a nodejs web service framework built on top of the TypeScript programming language. appex \r\nenables nodejs developers to expose typescript functions as http endpoints as well as generate meaningful service\r\nmeta data for clients to consume.\r\n\r\nappex also provides a dynamic compilation environment for typescript to aid in development. appex will effeciently \r\nmanage compilation in the background without the need to restart the web server, or use additional modules.\r\n\r\nappex is designed to operate as both a standalone web service solution or as a complement to existing applications\r\nwritten in frameworks such as express / connect that wish to extend their projects with typed web api's. \r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline configuring appex.\r\n\r\n<a name=\"runtime\" />\r\n### the appex runtime\r\n\r\nThe appex runtime is compilation engine that handles dynamic compilation, route mapping and function \r\ninvocation. appex provides a simple utility method for setting up the runtime, as described below.\r\n\r\n```javascript\r\nvar http    = require('http');\r\n\r\nvar appex   = require('appex');\r\n\r\n// create the runtime.\r\nvar runtime = appex.runtime ( { sourcefile : './program.ts' } ); \r\n\r\n// bind to the http server.\r\nvar server  = http.createServer( runtime ); \r\n\r\nserver.listen(3000);\r\n```\r\n\r\nThe appex.runtime() method returns a http handler function which is both compatable with nodejs' \r\nhttp server as well as connect middleware. This is the recommended approach of creating runtimes, \r\nHowever, if you need to access the runtime directly or are simply curious, you can also setup \r\nthe runtime as follows..\r\n\r\n```javascript\r\nvar http    = require('http');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar runtime = new appex.Runtime ( { sourcefile : './program.ts' } );\r\n\r\nvar server  = http.createServer( function(req, res) {\r\n    \r\n\tconsole.log(runtime); // investigate the runtime.\r\n\r\n    runtime.request_handler(req, res, function() { \r\n\r\n\t\t// request was not handled...\r\n\r\n\t});  \r\n});\r\n\r\nserver.listen(3000)\r\n```\r\n\r\n<a name=\"options\" />\r\n### runtime options\r\n\r\nThe appex runtime accepts the following options.\r\n\r\n```javascript\r\nvar options = { \r\n\r\n\tsourcefile : './program.ts', // (required) location of source file.\r\n\r\n    devmode    : true,           // (optional) recompile on request. \r\n\r\n    logging    : true,           // (optional) write requests to stdout.\r\n\r\n\tstdout     : process.stdout, // (optional) output stream. default is process.stdout\r\n\r\n\tstderr     : process.stderr, // (optional) error  stream. default is process.stderr\r\n};\r\n\r\nvar runtime = appex.runtime ( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### binding to an http server\r\n\r\nSetting up appex on a nodejs http server.\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// file: program.ts\r\n//----------------------------------------------\r\n\r\nexport function index (context) { \r\n\t\t\r\n\tcontext.response.write('hello world');\r\n\r\n\tcontext.response.end(); \r\n}\r\n\r\n\r\n//----------------------------------------------\r\n// file: app.js\r\n//----------------------------------------------\r\n\r\nvar http    = require('http');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar runtime = appex.runtime ( { sourcefile : './program.ts' } );\r\n\r\nvar server  = http.createServer( runtime );\r\n\r\nserver.listen(3000);\r\n```\r\n<a name=\"express_server\" />\r\n### binding to an express instance\r\n\r\nThe following illistrates setting up appex on an express instance.\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// file: program.ts\r\n//----------------------------------------------\r\n\r\n// http://localhost:3000/about\r\nexport function about (context) { \r\n\r\n\tcontext.response.write('about page');\r\n\r\n\tcontext.response.end(); \r\n}\r\n\r\n\r\n//----------------------------------------------\r\n// file: app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex.runtime ( { sourcefile : './program.ts' } ) );\r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"creating_services\" />\r\n## creating services with typescript\r\n\r\nappex enables developers to write http endpoints by writing typescript functions. \r\n\r\nThe following section describes how to write http accessible functions. \r\n\r\n<a name=\"appex_context\" />\r\n### appex context\r\n\r\nAll appex functions are passed a context object as the first argument. The context object encapulates\r\nthe http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the context object\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.reflection - appex runtime type information.\r\n\r\n\t// context.routes     - appex routing tables.\r\n\r\n\t// context.exports    - appex module exports handles.\r\n\r\n\t// context.mime       - appex mime utility.\r\n}\r\n```\r\n\r\n<a name=\"appex_http_handlers\" />\r\n### appex http handlers\r\n\r\nA appex http handler is defined with the following signature.\r\n\r\n* argument[0] - the appex context\r\n* returns     - void (optional)\r\n\r\nhttp handler functions need to complete the http request.\r\n\r\n```javascript\r\n\r\n// url: http://[host]:[port]/method\r\nexport function method(context) : void {\r\n\r\n\tcontext.response.write('hello world');\r\n\t\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"appex_json_handlers\" />\r\n### appex json handlers\r\n\r\nA appex json handler is a function suited to handling json based http requests. appex json handlers\r\nare invoked via HTTP POST and expect JSON to be submitted with the request. POSTing null or invalid\r\nJSON results in the request argument being null.\r\n\r\nA appex json handler requires the following signature.\r\n\r\n* argument[0] - the appex context\r\n* argument[1] - A optionally typed json request object. \r\n* argument[2] - a optionally typed typescript callback with a single argument for the object response.\r\n* returns     - void (optional) \r\n\r\nThe return type is optional. json handler functions \"must\" invoke the callback to complete the request.\r\n\r\n```javascript\r\nexport function method(context, request, callback:(response) => void) : void {\r\n\r\n\tcallback(request); // echo\r\n\r\n}\r\n```\r\n\r\n<a name=\"index_functions\" />\r\n### index functions\r\n\r\nappex denotes that functions named 'index' resolve to the current module scope. As demonstrated below: \r\n\r\n```javascript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { }\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) { }\r\n\t\r\n\t// url: http://[host]:[port]/blogs/submit\r\n\texport function submit (context) { }\r\n}\r\n```\r\n<a name=\"wildcard_functions\" />\r\n### wildcard functions\r\n\r\nappex supports url wildcard routing by way of wildcard functions. Wildcard functions are special in the regard \r\nthey support more than one argument (other than the context) for which url parameters will be mapped.\r\n\r\nappex currently supports the type 'any' (or none), string and number type annotations on wildcard arguments. \r\nif a wildcard argument specifies any other type, the wildcard function will not be routed. \r\n\r\nif no type annotation is specified, appex will pass a string value.\r\n\r\n```javascript\r\nexport module blogs {\r\n    \r\n\t// url : http://[host]:[port]/blogs\r\n    export function index (context) { /* handle request */ }\r\n\t\r\n\t// http://[host]:[port]/blogs/submit\r\n\texport function submit (context) { /* handle request */ }\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11  - matched\r\n\t// url : http://[host]:[port]/blogs/2013/01/11 - matched\r\n\t// url : http://[host]:[port]/blogs/cat/01/11  - not matched\r\n    export function wildcard(context, year:number, month:number, day:number) {\r\n\r\n        context.response.write('blogs ' + year + ' ' + month + ' ' + day)\r\n\r\n        context.response.end(); \r\n    }\r\n}\r\n```\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex extends TypeScripts concept of visibility to include visibility over http. From this\r\ndevelopers and control which functions are exported as http endpoints.  \r\n\r\nIn order to make a function accessible over http, you must explicitly \"export\" the function. \r\n\r\nconsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.write('testing');\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"routing_functions\" />\r\n### routing functions\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context:any) { }\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context:any) { }\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context:any) { }\r\n\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context:any) : void { }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context:any) : void { }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context:any) : void { }\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```javascript\r\n// http:[host]:[port]/\r\nexport function index   (context) { \r\n\tcontext.response.writeHead(404, {'content-type' : 'text/plain'});\r\n\tcontext.response.write('home page');\r\n\tcontext.response.end();\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\tcontext.response.writeHead(404, {'content-type' : 'text/plain'});\r\n\tcontext.response.write(path + ' page not found');\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\nappex enables nodejs developers to write applications in pure TypeScript. The following\r\nsection outlines how to effeciently develop with appex and the TypeScript programming language.\r\n\r\n<a name=\"development_mode\" />\r\n### development mode\r\n\r\n```javascript \r\n// enable compilation on request with the devmode option.\r\nvar runtime = appex.runtime ({ sourcefile : './program.ts', \r\n\t\t\t\t\t\t\t   devmode    : true, \r\n\t\t\t\t\t\t\t   logging    : true }); \r\n\r\n```\r\nappex is built directly on top of the Microsoft TypeScript 0.9 compiler and leverages it for tight\r\nintegration with the nodejs platform. By enabling the 'devmode' option on a appex runtime, appex \r\nwill rebuild your source code on each request made to the server. \r\n\r\nappex achieves performance in this regard by leveraging features available in\r\nTypeScript compiler which facilitate incremental building / caching of typescript \r\ncompilation units. request compilation in devmode typically take tens of milliseconds \r\nto complete for modest size projects.\r\n\r\nIn addition to this, compilations are run as a background worker process to ensure they \r\ndo not interupt requests being served on the parent process. \r\n\r\nappex will output syntax and type errors to the runtime stdout as well as the http response. \r\nSyntax errors will not bring down the web process. And you won't need to restart on code \r\nupdates.\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar runtime = appex.runtime ({ sourcefile : './index.ts' });\r\n\r\nrequire('http').createServer( runtime  ).listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"pages.ts\" />\r\n/// <reference path=\"users.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { /* handle request */ }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { /* handle request */ }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { /* handle request */ }\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { /* handle request */ }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { /* handle request */ }\r\n}\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"http://www.apache.org/licenses/LICENSE-2.0.html","type":"Apache 2.0"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"nodejs web apps with typescript","directories":{},"dependencies":{"typescript.api":"0.5.2"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.3.3":{"name":"appex","version":"0.3.3","keywords":["typescript","web app","compiler"],"author":{"name":"sinclair"},"_id":"appex@0.3.3","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"83d18f1963d8f0c182b5e1740d204fb829b45a2c","tarball":"https://registry.npmjs.org/appex/-/appex-0.3.3.tgz","integrity":"sha512-k7eRioSbYJZ4wP1pGA8foMkbnWojJhUUHG/ETYpOWfsJElKPQ+EnxybTixW6keRTTJ3BlVYl063kyWncdadxrA==","signatures":[{"sig":"MEQCICy8oEpOrnBjkE32r2y3LzsDs/1NPCbgue3TxmX8btvjAiAmpB2uP/gJVFMu+bBZBuho0yXqAKqcgCiCM1h8FGbyug==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/assets/logo.jpg)\r\n\r\n### nodejs web apps with [typescript](http://www.typescriptlang.org/)\r\n\r\n```javascript\r\nexport module app.services {\r\n\r\n\t// http://[host]:[port]/app/services/message\r\n\texport function message(context) {\r\n\r\n\t\tcontext.response.write('hello world!!');\r\n\r\n\t\tcontext.response.end();\r\n\t}\r\n}\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n\r\n* [overview](#overview)\r\n* [getting started](#getting_started)\r\n\t* [the appex runtime](#runtime)\r\n\t* [runtime options](#options)\r\n\t* [binding to an http server](#http_server)\r\n\t* [binding to an express instance](#express_server)\r\n* [creating services with typescript](#creating_services)\r\n\t* [appex context](#appex_context)\r\n\t* [appex http handlers](#appex_http_handlers)\r\n\t* [appex json handlers](#appex_json_handlers)\r\n\t* [index functions](#index_functions)\r\n\t* [wildcard functions](#wildcard_functions)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [routing functions](#routing_functions)\r\n\t* [handling 404](#handling_404)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [development mode](#development_mode)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n\r\n<a name=\"overview\" />\r\n## overview\r\n\r\nappex is a nodejs web service framework built on top of the TypeScript programming language. appex \r\nenables nodejs developers to expose typescript functions as http endpoints as well as generate meaningful service\r\nmeta data for clients to consume.\r\n\r\nappex also provides a dynamic compilation environment for typescript to aid in development. appex will effeciently \r\nmanage compilation in the background without the need to restart the web server, or use additional modules.\r\n\r\nappex is designed to operate as both a standalone web service solution or as a complement to existing applications\r\nwritten in frameworks such as express / connect that wish to extend their projects with typed web api's. \r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline configuring appex.\r\n\r\n<a name=\"runtime\" />\r\n### the appex runtime\r\n\r\nThe appex runtime is compilation engine that handles dynamic compilation, route mapping and function \r\ninvocation. appex provides a simple utility method for setting up the runtime, as described below.\r\n\r\n```javascript\r\nvar http    = require('http');\r\n\r\nvar appex   = require('appex');\r\n\r\n// create the runtime.\r\nvar runtime = appex.runtime ( { sourcefile : './program.ts' } ); \r\n\r\n// bind to the http server.\r\nvar server  = http.createServer( runtime ); \r\n\r\nserver.listen(3000);\r\n```\r\n\r\nThe appex.runtime() method returns a http handler function which is both compatable with nodejs' \r\nhttp server as well as connect middleware. This is the recommended approach of creating runtimes, \r\nHowever, if you need to access the runtime directly or are simply curious, you can also setup \r\nthe runtime as follows..\r\n\r\n```javascript\r\nvar http    = require('http');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar runtime = new appex.Runtime ( { sourcefile : './program.ts' } );\r\n\r\nvar server  = http.createServer( function(req, res) {\r\n    \r\n\tconsole.log(runtime); // investigate the runtime.\r\n\r\n    runtime.request_handler(req, res, function() { \r\n\r\n\t\t// request was not handled...\r\n\r\n\t});  \r\n});\r\n\r\nserver.listen(3000)\r\n```\r\n\r\n<a name=\"options\" />\r\n### runtime options\r\n\r\nThe appex runtime accepts the following options.\r\n\r\n```javascript\r\nvar options = { \r\n\r\n\tsourcefile : './program.ts', // (required) location of source file.\r\n\r\n    devmode    : true,           // (optional) recompile on request. \r\n\r\n    logging    : true,           // (optional) write requests to stdout.\r\n\r\n\tstdout     : process.stdout, // (optional) output stream. default is process.stdout\r\n\r\n\tstderr     : process.stderr, // (optional) error  stream. default is process.stderr\r\n};\r\n\r\nvar runtime = appex.runtime ( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### binding to an http server\r\n\r\nSetting up appex on a nodejs http server.\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// file: program.ts\r\n//----------------------------------------------\r\n\r\nexport function index (context) { \r\n\t\t\r\n\tcontext.response.write('hello world');\r\n\r\n\tcontext.response.end(); \r\n}\r\n\r\n\r\n//----------------------------------------------\r\n// file: app.js\r\n//----------------------------------------------\r\n\r\nvar http    = require('http');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar runtime = appex.runtime ( { sourcefile : './program.ts' } );\r\n\r\nvar server  = http.createServer( runtime );\r\n\r\nserver.listen(3000);\r\n```\r\n<a name=\"express_server\" />\r\n### binding to an express instance\r\n\r\nThe following illistrates setting up appex on an express instance.\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// file: program.ts\r\n//----------------------------------------------\r\n\r\n// http://localhost:3000/about\r\nexport function about (context) { \r\n\r\n\tcontext.response.write('about page');\r\n\r\n\tcontext.response.end(); \r\n}\r\n\r\n\r\n//----------------------------------------------\r\n// file: app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex.runtime ( { sourcefile : './program.ts' } ) );\r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"creating_services\" />\r\n## creating services with typescript\r\n\r\nappex enables developers to write http endpoints by writing typescript functions. \r\n\r\nThe following section describes how to write http accessible functions. \r\n\r\n<a name=\"appex_context\" />\r\n### appex context\r\n\r\nAll appex functions are passed a context object as the first argument. The context object encapulates\r\nthe http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the context object\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.reflection - appex runtime type information.\r\n\r\n\t// context.routes     - appex routing tables.\r\n\r\n\t// context.exports    - appex module exports handles.\r\n\r\n\t// context.mime       - appex mime utility.\r\n}\r\n```\r\n\r\n<a name=\"appex_http_handlers\" />\r\n### appex http handlers\r\n\r\nA appex http handler is defined with the following signature.\r\n\r\n* argument[0] - the appex context\r\n* returns     - void (optional)\r\n\r\nhttp handler functions need to complete the http request.\r\n\r\n```javascript\r\n\r\n// url: http://[host]:[port]/method\r\nexport function method(context) : void {\r\n\r\n\tcontext.response.write('hello world');\r\n\t\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"appex_json_handlers\" />\r\n### appex json handlers\r\n\r\nA appex json handler is a function suited to handling json based http requests. appex json handlers\r\nare invoked via HTTP POST and expect JSON to be submitted with the request. POSTing null or invalid\r\nJSON results in the request argument being null.\r\n\r\nA appex json handler requires the following signature.\r\n\r\n* argument[0] - the appex context\r\n* argument[1] - A optionally typed json request object. \r\n* argument[2] - a optionally typed typescript callback with a single argument for the object response.\r\n* returns     - void (optional) \r\n\r\nThe return type is optional. json handler functions \"must\" invoke the callback to complete the request.\r\n\r\n```javascript\r\nexport function method(context, request, callback:(response) => void) : void {\r\n\r\n\tcallback(request); // echo\r\n\r\n}\r\n```\r\n\r\n<a name=\"index_functions\" />\r\n### index functions\r\n\r\nappex denotes that functions named 'index' resolve to the current module scope. As demonstrated below: \r\n\r\n```javascript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { }\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) { }\r\n\t\r\n\t// url: http://[host]:[port]/blogs/submit\r\n\texport function submit (context) { }\r\n}\r\n```\r\n<a name=\"wildcard_functions\" />\r\n### wildcard functions\r\n\r\nappex supports url wildcard routing by way of wildcard functions. Wildcard functions are special in the regard \r\nthey support more than one argument (other than the context) for which url parameters will be mapped.\r\n\r\nappex currently supports the type 'any' (or none), string and number type annotations on wildcard arguments. \r\nif a wildcard argument specifies any other type, the wildcard function will not be routed. \r\n\r\nif no type annotation is specified, appex will pass a string value.\r\n\r\n```javascript\r\nexport module blogs {\r\n    \r\n\t// url : http://[host]:[port]/blogs\r\n    export function index (context) { /* handle request */ }\r\n\t\r\n\t// http://[host]:[port]/blogs/submit\r\n\texport function submit (context) { /* handle request */ }\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11  - matched\r\n\t// url : http://[host]:[port]/blogs/2013/01/11 - matched\r\n\t// url : http://[host]:[port]/blogs/cat/01/11  - not matched\r\n    export function wildcard(context, year:number, month:number, day:number) {\r\n\r\n        context.response.write('blogs ' + year + ' ' + month + ' ' + day)\r\n\r\n        context.response.end(); \r\n    }\r\n}\r\n```\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex extends TypeScripts concept of visibility to include visibility over http. From this\r\ndevelopers and control which functions are exported as http endpoints.  \r\n\r\nIn order to make a function accessible over http, you must explicitly \"export\" the function. \r\n\r\nconsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.write('testing');\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"routing_functions\" />\r\n### routing functions\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context:any) { }\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context:any) { }\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context:any) { }\r\n\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context:any) : void { }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context:any) : void { }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context:any) : void { }\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```javascript\r\n// http:[host]:[port]/\r\nexport function index   (context) { \r\n\tcontext.response.writeHead(404, {'content-type' : 'text/plain'});\r\n\tcontext.response.write('home page');\r\n\tcontext.response.end();\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\tcontext.response.writeHead(404, {'content-type' : 'text/plain'});\r\n\tcontext.response.write(path + ' page not found');\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\nappex enables nodejs developers to write applications in pure TypeScript. The following\r\nsection outlines how to effeciently develop with appex and the TypeScript programming language.\r\n\r\n<a name=\"development_mode\" />\r\n### development mode\r\n\r\n```javascript \r\n// enable compilation on request with the devmode option.\r\nvar runtime = appex.runtime ({ sourcefile : './program.ts', \r\n\t\t\t\t\t\t\t   devmode    : true, \r\n\t\t\t\t\t\t\t   logging    : true }); \r\n\r\n```\r\nappex is built directly on top of the Microsoft TypeScript 0.9 compiler and leverages it for tight\r\nintegration with the nodejs platform. By enabling the 'devmode' option on a appex runtime, appex \r\nwill rebuild your source code on each request made to the server. \r\n\r\nappex achieves performance in this regard by leveraging features available in\r\nTypeScript compiler which facilitate incremental building / caching of typescript \r\ncompilation units. request compilation in devmode typically take tens of milliseconds \r\nto complete for modest size projects.\r\n\r\nIn addition to this, compilations are run as a background worker process to ensure they \r\ndo not interupt requests being served on the parent process. \r\n\r\nappex will output syntax and type errors to the runtime stdout as well as the http response. \r\nSyntax errors will not bring down the web process. And you won't need to restart on code \r\nupdates.\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar runtime = appex.runtime ({ sourcefile : './index.ts' });\r\n\r\nrequire('http').createServer( runtime  ).listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"pages.ts\" />\r\n/// <reference path=\"users.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { /* handle request */ }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { /* handle request */ }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { /* handle request */ }\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { /* handle request */ }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { /* handle request */ }\r\n}\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"http://www.apache.org/licenses/LICENSE-2.0.html","type":"Apache 2.0"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"nodejs web apps with typescript","directories":{},"dependencies":{"typescript.api":"0.5.2"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.3.4":{"name":"appex","version":"0.3.4","keywords":["typescript","web api","reflection","compiler"],"author":{"name":"sinclair"},"_id":"appex@0.3.4","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"3e697a1183d0b7e79539ebcc6ac8884df6c5f1f7","tarball":"https://registry.npmjs.org/appex/-/appex-0.3.4.tgz","integrity":"sha512-Euq2zhqcEn07gG6NPnlXI3nap0hPXzN77kSy8wARoIL0PLzZZCNFCoyDsQNpShBou8MIXQdQouDnK0UisQOi6Q==","signatures":[{"sig":"MEQCIF825HaSPvyNrhGxBlRPLCikh8IswLXZQv1D/0woApLvAiApekHMJAbpgSNerZtS/F0ylVJTliIjFpesNAIBGA7UBQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/studio/static/diagrams/logo.jpg)\r\n\r\n### nodejs web api with [typescript](http://www.typescriptlang.org/)\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\r\n\tcontext.response.write('hello world!!');\r\n\r\n\tcontext.response.end();\r\n}\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n## overview\r\n\r\nappex is a nodejs web api framework built on top of the TypeScript programming language. It enables\r\ndevelopers to develop RESTful service endpoints by writing TypeScript functions, as well as providing\r\nreflection / type and interface meta data derived from the languages type system.\r\n\r\n* [getting started](#getting_started)\r\n\t* [application](#application)\r\n\t* [options](#options)\r\n\t* [http server](#http_server)\r\n\t* [express middleware](#express_middleware)\r\n* [creating services with typescript](#creating_services)\r\n\t* [context](#context)\r\n\t* [signatures](#signatures)\r\n\t* [http handlers](#http_handlers)\r\n\t* [json handlers](#json_handlers)\r\n\t* [index handlers](#index_handlers)\r\n\t* [wildcard handlers](#wildcard_handlers)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [routing functions](#routing_functions)\r\n\t* [handling 404](#handling_404)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline configuring appex.\r\n\r\n<a name=\"application\" />\r\n### application\r\n\r\nSetting up. \r\n\r\n```javascript\r\nvar appex   = require('appex');\r\n\r\nvar app   = appex({ program : './program.ts', \r\n                    devmode : true,\r\n                    logging : true });\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"options\" />\r\n### options\r\n\r\nappex accepts the following startup options.\r\n\r\n```javascript\r\nvar options = { \r\n\t// (required) location of source file.\r\n\tprogram    : './program.ts', \r\n\r\n\t// (optional) recompile on request. (default:false) \r\n\tdevmode    : true,          \r\n\r\n\t// (optional) log to stdout. (default:false) \r\n\tlogging    : true,\r\n\r\n\t// (optional) additional objects added on the [context](#context)\r\n\tcontext    : {}\r\n};\r\n\r\nvar app = appex( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### http server\r\n\r\nSetting up appex on a nodejs http server.\r\n\r\n```javascript\r\nvar http = require('http');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\nvar server = http.createServer( app );\r\n\r\nserver.listen(3000);\r\n```\r\n<a name=\"express_middleware\" />\r\n### express middleware\r\n\r\nSetting up as express middleware.\r\n\r\n```javascript\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use(appex({ program : './program.ts' })); \r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"creating_services\" />\r\n## creating services with typescript\r\n\r\nThe following section describes how to write http accessible functions with appex.\r\n\r\n<a name=\"context\" />\r\n### context\r\n\r\nAll appex functions are passed a context object as the first argument. The context object encapulates\r\nthe http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the context object\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.module     - meta information about the appex module.\r\n\r\n\t// context.routes     - appex routing tables.\r\n\r\n\t// context.mime       - appex mime utility.\r\n\r\n\t// context.???        - user defined [options](#options)\r\n}\r\n```\r\n<a name=\"signatures\" />\r\n### signatures\r\n\r\nappex will only setup http routes to functions which conform to the following function signatures. \r\n\r\n<a name=\"http_handlers\" />\r\n### http handlers\r\n\r\nappex http handlers require the following signature:\r\n\r\n* argument[0] - context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\nexport function method(context) {\r\n\r\n\tcontext.response.write('hello world');\r\n\t\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"json_handlers\" />\r\n### json handlers\r\n\r\nappex json handlers are geared towards handling json based http requests. appex json handlers\r\nare invoked via HTTP POST and expect JSON to be submitted with the request. POSTing null or invalid\r\nJSON results in the request argument being null.\r\n\r\nappex json handlers require the following signature:\r\n\r\n* argument[0] - the appex context\r\n* argument[1] - A optionally typed json request object. \r\n* argument[2] - a optionally typed typescript callback with a single argument for the object response.\r\n* returns     - void (optional) \r\n\r\n```javascript\r\nexport function method(context, request, callback:(response) => void) : void {\r\n\r\n\tcallback(request); // echo\r\n\r\n}\r\n```\r\n\r\n<a name=\"index_handlers\" />\r\n### index handlers\r\n\r\nappex index handlers resolve urls to their current module scope. As demonstrated below: \r\n\r\nappex index handlers require the following signature:\r\n\r\n* name        - 'index'\r\n* argument[0] - context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { \r\n\r\n\tcontext.response.write('home page');\r\n\t\r\n\tcontext.response.end();\r\n}\r\n\r\n// url: http://[host]:[port]/home\r\nexport function home(context) {\r\n\r\n\tindex(context)\r\n}\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) { /* handle request */ }\r\n\t\r\n\t// url: http://[host]:[port]/blogs/submit\r\n\texport function submit (context) { /* handle request */ }\r\n}\r\n```\r\n\r\n<a name=\"wildcard_handlers\" />\r\n### wildcard handlers\r\n\r\nappex wildcard handlers allow for wildcard routing at a given module scope. In addition, wildcard handlers\r\nsupport 'typed' url argument mapping, as denoted by the parameter annotation.\r\n\r\nappex wildcard handlers require the following signature:\r\n\r\n* name        - 'wildcard'\r\n* argument[0] - context\r\n* argument[n] - arguments to be mapped from the url\r\n* returns     - void (optional)\r\n\r\n```javascript\r\ndeclare var console;\r\n\r\nexport module blogs {\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11  - matched\r\n\t// url : http://[host]:[port]/blogs/2013/01/11 - matched\r\n\t// url : http://[host]:[port]/blogs/fluff/01/11  - not matched\r\n    export function wildcard(context, year:number, month:number, day:number) {\r\n\t\t\r\n\t\tconsole.log(year); \r\n\r\n\t\tconsole.log(month);\r\n\r\n\t\tconsole.log(day);\r\n\r\n        context.response.write('my blog')\r\n\r\n        context.response.end(); \r\n    }\r\n}\r\n```\r\nnote: appex only supports type any (or none), string and number annotations. specifying any other type result \r\nin this wildcard not being routed.\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex will only export functions prefix with the TypeScript 'export' declaration. Also, exported \r\nfunctions that reside in non exported modules will not be routed. Developers can use this to infer\r\nnotions of public and private at the http level.\r\n\r\nconsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.write('testing');\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"routing_functions\" />\r\n### routing functions\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context:any) { }\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context:any) { }\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context:any) { }\r\n\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context:any) : void { }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context:any) : void { }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context:any) : void { }\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```javascript\r\n// http:[host]:[port]/\r\nexport function index   (context) { \r\n\tcontext.response.writeHead(404, {'content-type' : 'text/plain'});\r\n\tcontext.response.write('home page');\r\n\tcontext.response.end();\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\tcontext.response.writeHead(404, {'content-type' : 'text/plain'});\r\n\tcontext.response.write(path + ' page not found');\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex ({ program : './index.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"pages.ts\" />\r\n/// <reference path=\"users.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { /* handle request */ }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { /* handle request */ }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { /* handle request */ }\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { /* handle request */ }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { /* handle request */ }\r\n}\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"http://www.apache.org/licenses/LICENSE-2.0.html","type":"Apache 2.0"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"nodejs web api with typescript","directories":{},"dependencies":{"typescript.api":"0.5.2"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.3.5":{"name":"appex","version":"0.3.5","keywords":["typescript","web api","reflection","compiler"],"author":{"name":"sinclair"},"_id":"appex@0.3.5","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"af611294f3eac560f3ff4d6b6c120b9e10cd1d1d","tarball":"https://registry.npmjs.org/appex/-/appex-0.3.5.tgz","integrity":"sha512-rAopkat8n49ZLKxxgaDoMmJ2lEYItKKHstg26ItgMjXHUwtnop65fLisDA4/uKj01jrovEBZMqAZaUeIUzcpxA==","signatures":[{"sig":"MEQCIFhy7Q8UKHidTKX99CZVdA+42AbY5WNA0KuDdD2NpHfdAiBZYOnjIhV4toQIyQorixW5hvq3/JjX5sGNFd9fSekhgg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/studio/static/diagrams/logo.jpg)\r\n\r\n### nodejs web api with [typescript](http://www.typescriptlang.org/)\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n\r\nexport function index(context) {\r\n\r\n\tcontext.response.write('hello world!!');\r\n\r\n\tcontext.response.end();\r\n}\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n## overview\r\n\r\nappex is a nodejs web api framework built on top of the TypeScript programming language. It enables\r\ndevelopers to develop RESTful service endpoints by writing TypeScript functions, as well as providing\r\nreflection / type and interface meta data derived from the languages type system.\r\n\r\n* [getting started](#getting_started)\r\n\t* [application](#application)\r\n\t* [options](#options)\r\n\t* [http server](#http_server)\r\n\t* [express middleware](#express_middleware)\r\n* [creating services with typescript](#creating_services)\r\n\t* [context](#context)\r\n\t* [signatures](#signatures)\r\n\t* [attributes](#attributes)\r\n\t* [http handlers](#http_handlers)\r\n\t* [json handlers](#json_handlers)\r\n\t* [index handlers](#index_handlers)\r\n\t* [wildcard handlers](#wildcard_handlers)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [routing functions](#routing_functions)\r\n\t* [handling 404](#handling_404)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline configuring appex.\r\n\r\n<a name=\"application\" />\r\n### application\r\n\r\nSetting up. \r\n\r\n```javascript\r\nvar appex   = require('appex');\r\n\r\nvar app   = appex({ program : './program.ts', \r\n                    devmode : true,\r\n                    logging : true });\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"options\" />\r\n### options\r\n\r\nappex accepts the following startup options.\r\n\r\n```javascript\r\nvar options = { \r\n\t// (required) location of source file.\r\n\tprogram    : './program.ts', \r\n\r\n\t// (optional) recompile on request. (default:false) \r\n\tdevmode    : true,          \r\n\r\n\t// (optional) log to stdout. (default:false) \r\n\tlogging    : true,\r\n\r\n\t// (optional) additional objects added on the [context](#context)\r\n\tcontext    : {}\r\n};\r\n\r\nvar app = appex( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### http server\r\n\r\nSetting up appex on a nodejs http server.\r\n\r\n```javascript\r\nvar http = require('http');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\nvar server = http.createServer( app );\r\n\r\nserver.listen(3000);\r\n```\r\n<a name=\"express_middleware\" />\r\n### express middleware\r\n\r\nSetting up as express middleware.\r\n\r\n```javascript\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use(appex({ program : './program.ts' })); \r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"creating_services\" />\r\n## creating services with typescript\r\n\r\nThe following section describes how to write http accessible functions with appex.\r\n\r\n<a name=\"context\" />\r\n### context\r\n\r\nAll appex functions are passed a context object as the first argument. The context object encapulates\r\nthe http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the context object\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.attribute  - appex attribute.\r\n\r\n\t// context.module     - appex module meta data and reflection.\r\n\r\n\t// context.routes     - appex routing tables.\r\n\r\n\t// context.mime       - appex mime utility.\r\n\r\n\t// context.???        - user defined [options](#options)\r\n}\r\n```\r\n\r\n<a name=\"attributes\" />\r\n### attributes\r\n\r\nappex supports optional declarative attributes on routes defined with appex functions. The concept is analogous to .net \r\nattributes where users can define behavioral characteristics on types. However appex restricts this usage\r\nto exported functions only.\r\n\r\nout of the box, appex can enforce HTTP VERB routing rules with attributes.\r\n\r\n```javascript\r\n\r\nattribute(\"contact\", {  verbs: [\"get\"]  } );\r\n\r\nexport function contact(context) {\r\n\r\n\t// handler will only be invoke on HTTP GET requests\r\n}\r\n\r\nattribute(\"submit\", {  verbs: [\"post\"]  } );\r\n\r\nexport function submit(context) {\r\n\r\n\thandler will only be invoke on HTTP POST requests\r\n}\r\n\r\n```\r\n\r\nIn addition, users can define their own verbs for more complex behaviour, such as roles.\r\n\r\n```javascript\r\n\r\n// example assumes a 'user' as has been applied to the context.\r\n\r\nfunction authorize(context) : boolean {\r\n\r\n\treturn context.user.isInRole(context.attribute.roles);\r\n}\r\n\r\nexport module admin {\r\n\t\r\n\tattribute(\"admin.index\", {  verbs: [\"get\"], roles : ['administrators']  } );\r\n\r\n\texport function index (context) {\r\n\t\t\r\n\t\tif(authorize(context))\r\n\r\n\t\t\t// handle request\r\n\t\t}\r\n\t\telse \r\n\t\t{\r\n\t\t\t// access denied\r\n\t\t}\r\n\t}\r\n\t\r\n\texport module users {\r\n\t\t\r\n\t\tattribute(\"admin.users.delete\", {  verbs: [\"post\"], roles : ['administrators'] } );\r\n\t\t\r\n\t\texport function delete(context) {\r\n\t\t\r\n\t\t\tif(authorize(context))\r\n\t\t\t{\r\n\t\t\t\t// handle request\r\n\t\t\t}\r\n\t\t\telse \r\n\t\t\t{\r\n\t\t\t\t// access denied\r\n\t\t\t}\r\n\t\t}\t\r\n\t}\r\n}\r\n\r\n```\r\n\r\nattributes can also be looked up with attribute().\r\n\r\n```javascript\r\n\r\nexport function index(context) {\r\n    \r\n\tvar info = attribute('other');\r\n\t\r\n\tcontext.response.write( JSON.stringify(info, null, 4) );\r\n\t\r\n\tcontext.response.end();\t\r\n}\r\n\r\nattribute(\"other\", {  verbs: [\"get\"], message:'hello' } );\r\nexport function other(context) {\r\n    \r\n\tcontext.response.write(context.attribute.message);\r\n\t\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n\r\n<a name=\"signatures\" />\r\n### signatures\r\n\r\nappex will only setup http routes to functions which conform to the following function signatures. \r\n\r\n<a name=\"http_handlers\" />\r\n### http handlers\r\n\r\nappex http handlers require the following signature:\r\n\r\n* argument[0] - context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\nexport function method(context) {\r\n\r\n\tcontext.response.write('hello world');\r\n\t\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"json_handlers\" />\r\n### json handlers\r\n\r\nappex json handlers are geared towards handling json based http requests. appex json handlers\r\nare invoked via HTTP POST and expect JSON to be submitted with the request. POSTing null or invalid\r\nJSON results in the request argument being null.\r\n\r\nappex json handlers require the following signature:\r\n\r\n* argument[0] - the appex context\r\n* argument[1] - A optionally typed json request object. \r\n* argument[2] - a optionally typed typescript callback with a single argument for the object response.\r\n* returns     - void (optional) \r\n\r\n```javascript\r\nexport function method(context, request, callback:(response) => void) : void {\r\n\r\n\tcallback(request); // echo\r\n\r\n}\r\n```\r\n\r\n<a name=\"index_handlers\" />\r\n### index handlers\r\n\r\nappex index handlers resolve urls to their current module scope. As demonstrated below: \r\n\r\nappex index handlers require the following signature:\r\n\r\n* name        - 'index'\r\n* argument[0] - context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { \r\n\r\n\tcontext.response.write('home page');\r\n\t\r\n\tcontext.response.end();\r\n}\r\n\r\n// url: http://[host]:[port]/home\r\nexport function home(context) {\r\n\r\n\tindex(context)\r\n}\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) { /* handle request */ }\r\n\t\r\n\t// url: http://[host]:[port]/blogs/submit\r\n\texport function submit (context) { /* handle request */ }\r\n}\r\n```\r\n\r\n<a name=\"wildcard_handlers\" />\r\n### wildcard handlers\r\n\r\nappex wildcard handlers allow for wildcard routing at a given module scope. In addition, wildcard handlers\r\nsupport 'typed' url argument mapping, as denoted by the parameter annotation.\r\n\r\nappex wildcard handlers require the following signature:\r\n\r\n* name        - 'wildcard'\r\n* argument[0] - context\r\n* argument[n] - arguments to be mapped from the url\r\n* returns     - void (optional)\r\n\r\n```javascript\r\ndeclare var console;\r\n\r\nexport module blogs {\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11  - matched\r\n\t// url : http://[host]:[port]/blogs/2013/01/11 - matched\r\n\t// url : http://[host]:[port]/blogs/fluff/01/11  - not matched\r\n    export function wildcard(context, year:number, month:number, day:number) {\r\n\t\t\r\n\t\tconsole.log(year); \r\n\r\n\t\tconsole.log(month);\r\n\r\n\t\tconsole.log(day);\r\n\r\n        context.response.write('my blog')\r\n\r\n        context.response.end(); \r\n    }\r\n}\r\n```\r\nnote: appex only supports type any (or none), string and number annotations. specifying any other type result \r\nin this wildcard not being routed.\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex will only export functions prefix with the TypeScript 'export' declaration. Also, exported \r\nfunctions that reside in non exported modules will not be routed. Developers can use this to infer\r\nnotions of public and private at the http level.\r\n\r\nconsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.write('testing');\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"routing_functions\" />\r\n### routing functions\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context:any) { }\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context:any) { }\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context:any) { }\r\n\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context:any) : void { }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context:any) : void { }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context:any) : void { }\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```javascript\r\n// http:[host]:[port]/\r\nexport function index   (context) { \r\n\tcontext.response.writeHead(404, {'content-type' : 'text/plain'});\r\n\tcontext.response.write('home page');\r\n\tcontext.response.end();\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\tcontext.response.writeHead(404, {'content-type' : 'text/plain'});\r\n\tcontext.response.write(path + ' page not found');\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex ({ program : './index.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"pages.ts\" />\r\n/// <reference path=\"users.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { /* handle request */ }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { /* handle request */ }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { /* handle request */ }\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { /* handle request */ }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { /* handle request */ }\r\n}\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"http://www.apache.org/licenses/LICENSE-2.0.html","type":"Apache 2.0"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"nodejs web api with typescript","directories":{},"dependencies":{"typescript.api":"0.5.2"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.3.6":{"name":"appex","version":"0.3.6","keywords":["typescript","web api","reflection","compiler"],"author":{"name":"sinclair"},"_id":"appex@0.3.6","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"7aee72a19f9b3accd224aaa161d04a37195e887d","tarball":"https://registry.npmjs.org/appex/-/appex-0.3.6.tgz","integrity":"sha512-c+3aJXiCB8XnGIexOyazRxoQrEyu4E7+STcOUTfMk+8XeJArKHtdSyTV+Vt8U5uyv/w3a98nn3dvMsxbpUnrSg==","signatures":[{"sig":"MEUCIG5vv02GQz1fQgNUv8xtYsGN2J/6nJCLB2xHvV0wJFhGAiEAz79gqs7An0x3WLQXErG90ALpgA4RVN6RjoZLMaSIcwE=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/studio/static/diagrams/logo.jpg)\r\n\r\n### nodejs web api with [typescript](http://www.typescriptlang.org/)\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n\r\nexport function index(context) {\r\n\r\n\tcontext.response.write('hello world!!');\r\n\r\n\tcontext.response.end();\r\n}\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n## overview\r\n\r\nappex is a nodejs web api framework built on top of the TypeScript programming language. It enables\r\ndevelopers to develop RESTful service endpoints by writing TypeScript functions, as well as providing\r\nreflection / type and interface meta data derived from the languages type system.\r\n\r\n* [getting started](#getting_started)\r\n\t* [application](#application)\r\n\t* [options](#options)\r\n\t* [http server](#http_server)\r\n\t* [express middleware](#express_middleware)\r\n* [creating services with typescript](#creating_services)\r\n\t* [context](#context)\r\n\t* [signatures](#signatures)\r\n\t* [attributes](#attributes)\r\n\t* [http handlers](#http_handlers)\r\n\t* [json handlers](#json_handlers)\r\n\t* [index handlers](#index_handlers)\r\n\t* [wildcard handlers](#wildcard_handlers)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [routing functions](#routing_functions)\r\n\t* [handling 404](#handling_404)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline configuring appex.\r\n\r\n<a name=\"application\" />\r\n### application\r\n\r\nSetting up. \r\n\r\n```javascript\r\nvar appex   = require('appex');\r\n\r\nvar app   = appex({ program : './program.ts', \r\n                    devmode : true,\r\n                    logging : true });\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"options\" />\r\n### options\r\n\r\nappex accepts the following startup options.\r\n\r\n```javascript\r\nvar options = { \r\n\t// (required) location of source file.\r\n\tprogram    : './program.ts', \r\n\r\n\t// (optional) recompile on request. (default:false) \r\n\tdevmode    : true,          \r\n\r\n\t// (optional) log to stdout. (default:false) \r\n\tlogging    : true,\r\n\r\n\t// (optional) additional objects added on the [context](#context)\r\n\tcontext    : {}\r\n};\r\n\r\nvar app = appex( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### http server\r\n\r\nSetting up appex on a nodejs http server.\r\n\r\n```javascript\r\nvar http = require('http');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\nvar server = http.createServer( app );\r\n\r\nserver.listen(3000);\r\n```\r\n<a name=\"express_middleware\" />\r\n### express middleware\r\n\r\nSetting up as express middleware.\r\n\r\n```javascript\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use(appex({ program : './program.ts' })); \r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"creating_services\" />\r\n## creating services with typescript\r\n\r\nThe following section describes how to write http accessible functions with appex.\r\n\r\n<a name=\"context\" />\r\n### context\r\n\r\nAll appex functions are passed a context object as the first argument. The context object encapulates\r\nthe http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the context object\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.attribute  - appex attribute.\r\n\r\n\t// context.module     - appex module meta data and reflection.\r\n\r\n\t// context.routes     - appex routing tables.\r\n\r\n\t// context.mime       - appex mime utility.\r\n\r\n\t// context.???        - user defined [options](#options)\r\n}\r\n```\r\n\r\n<a name=\"attributes\" />\r\n### attributes\r\n\r\nappex supports optional declarative attributes on 'exported' modules and functions. Attributes are declaritive meta data\r\nyou can associate with appex handlers to describe characteristics on given routes. Attributes are analogous to .net attributes,\r\nhowever, they also have a cascading behaviour that can be used to apply metadata for an entire scope. A concept similar to \r\ncascading stylesheets rules.\r\n\r\nBy default, appex uses attributes for HTTP VERB matching:\r\n\r\n```javascript\r\n\r\ndeclare var attribute;\r\n\r\nattribute(\"contact\", {  verbs: [\"get\"]  } );\r\n\r\nexport function contact(context) {\r\n\r\n\t// handler will only be invoke on HTTP GET requests\r\n}\r\n\r\nattribute(\"submit\", {  verbs: [\"post\"]  } );\r\n\r\nexport function submit(context) {\r\n\r\n\t// handler will only be invoke on HTTP POST requests\r\n}\r\n\r\n```\r\n\r\nthe following demonstrates attribute cascading:\r\n\r\n```javascript\r\ndeclare var attribute;\r\n\r\nattribute('foo', {a : 10})\r\nexport module foo {\r\n\r\n    attribute('foo.bar', {b : 20})\r\n    export module bar {\r\n            \r\n        attribute('foo.bar.index', {c : 30})\r\n        export function index(context) {\r\n        \r\n            //context.attribute\r\n            //{\r\n            //    \"a\": 10,\r\n            //    \"b\": 20,\r\n            //    \"c\": 30\r\n            //}            \r\n\r\n            context.response.writeHead(200, {'content-type' : 'text/plain'});\r\n\t\r\n            context.response.write( JSON.stringify(context.attribute, null, 4) );\r\n\t\r\n            context.response.end();       \r\n        }\r\n    }\r\n}\r\n\r\n```\r\n\r\nand for something more practical..\r\n\r\n```javascript\r\ndeclare var attribute;\r\n\r\nattribute('admin', { roles : ['administrators'] )\r\nexport module admin {\r\n\t\r\n\texport function index(context) {\r\n\t\t\r\n\t\tvar user = context.user;\r\n\r\n\t\tif(!user.isInRole( context.attribute.roles ) ) {\r\n\r\n\t\t\t// access denied!\r\n\r\n\t\t}\r\n\t}\r\n}\r\n\r\n```\r\n\r\nattributes can also be looked up by calling attribute( qualifier ).\r\n\r\n```javascript\r\n\r\ndeclare var attribute;\r\n\r\nexport function index(context) {\r\n    \r\n\tvar info = attribute('other');\r\n\t\r\n\tcontext.response.write( JSON.stringify(info, null, 4) );\r\n\t\r\n\tcontext.response.end();\t\r\n}\r\n\r\nattribute(\"other\", {  verbs: [\"get\"], message:'hello' } );\r\nexport function other(context) {\r\n    \r\n\tcontext.response.write(context.attribute.message);\r\n\t\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"signatures\" />\r\n### signatures\r\n\r\nappex will only setup http routes to functions which conform to the following function signatures. \r\n\r\n<a name=\"http_handlers\" />\r\n### http handlers\r\n\r\nappex http handlers require the following signature:\r\n\r\n* argument[0] - context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\nexport function method(context) {\r\n\r\n\tcontext.response.write('hello world');\r\n\t\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"json_handlers\" />\r\n### json handlers\r\n\r\nappex json handlers are geared towards handling json based http requests. appex json handlers\r\nare invoked via HTTP POST and expect JSON to be submitted with the request. POSTing null or invalid\r\nJSON results in the request argument being null.\r\n\r\nappex json handlers require the following signature:\r\n\r\n* argument[0] - the appex context\r\n* argument[1] - A optionally typed json request object. \r\n* argument[2] - a optionally typed typescript callback with a single argument for the object response.\r\n* returns     - void (optional) \r\n\r\n```javascript\r\nexport function method(context, request, callback:(response) => void) : void {\r\n\r\n\tcallback(request); // echo\r\n\r\n}\r\n```\r\n\r\n<a name=\"index_handlers\" />\r\n### index handlers\r\n\r\nappex index handlers resolve urls to their current module scope. As demonstrated below: \r\n\r\nappex index handlers require the following signature:\r\n\r\n* name        - 'index'\r\n* argument[0] - context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { \r\n\r\n\tcontext.response.write('home page');\r\n\t\r\n\tcontext.response.end();\r\n}\r\n\r\n// url: http://[host]:[port]/home\r\nexport function home(context) {\r\n\r\n\tindex(context)\r\n}\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) { /* handle request */ }\r\n\t\r\n\t// url: http://[host]:[port]/blogs/submit\r\n\texport function submit (context) { /* handle request */ }\r\n}\r\n```\r\n\r\n<a name=\"wildcard_handlers\" />\r\n### wildcard handlers\r\n\r\nappex wildcard handlers allow for wildcard routing at a given module scope. In addition, wildcard handlers\r\nsupport 'typed' url argument mapping, as denoted by the parameter annotation.\r\n\r\nappex wildcard handlers require the following signature:\r\n\r\n* name        - 'wildcard'\r\n* argument[0] - context\r\n* argument[n] - arguments to be mapped from the url\r\n* returns     - void (optional)\r\n\r\n```javascript\r\ndeclare var console;\r\n\r\nexport module blogs {\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11  - matched\r\n\t// url : http://[host]:[port]/blogs/2013/01/11 - matched\r\n\t// url : http://[host]:[port]/blogs/fluff/01/11  - not matched\r\n    export function wildcard(context, year:number, month:number, day:number) {\r\n\t\t\r\n\t\tconsole.log(year); \r\n\r\n\t\tconsole.log(month);\r\n\r\n\t\tconsole.log(day);\r\n\r\n        context.response.write('my blog')\r\n\r\n        context.response.end(); \r\n    }\r\n}\r\n```\r\nnote: appex only supports type any (or none), string and number annotations. specifying any other type result \r\nin this wildcard not being routed.\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex will only export functions prefix with the TypeScript 'export' declaration. Also, exported \r\nfunctions that reside in non exported modules will not be routed. Developers can use this to infer\r\nnotions of public and private at the http level.\r\n\r\nconsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.write('testing');\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"routing_functions\" />\r\n### routing functions\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context:any) { }\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context:any) { }\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context:any) { }\r\n\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context:any) : void { }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context:any) : void { }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context:any) : void { }\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```javascript\r\n// http:[host]:[port]/\r\nexport function index   (context) { \r\n\tcontext.response.writeHead(404, {'content-type' : 'text/plain'});\r\n\tcontext.response.write('home page');\r\n\tcontext.response.end();\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\tcontext.response.writeHead(404, {'content-type' : 'text/plain'});\r\n\tcontext.response.write(path + ' page not found');\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex ({ program : './index.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"pages.ts\" />\r\n/// <reference path=\"users.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { /* handle request */ }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { /* handle request */ }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { /* handle request */ }\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { /* handle request */ }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { /* handle request */ }\r\n}\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"http://www.apache.org/licenses/LICENSE-2.0.html","type":"Apache 2.0"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"nodejs web api with typescript","directories":{},"dependencies":{"typescript.api":"0.5.2"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.3.7":{"name":"appex","version":"0.3.7","keywords":["typescript","web api","reflection","compiler"],"author":{"name":"sinclair"},"_id":"appex@0.3.7","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"6673f119f4b3b26c160f2ffad14068886c1ed6b2","tarball":"https://registry.npmjs.org/appex/-/appex-0.3.7.tgz","integrity":"sha512-P1eBFv3o51hr6cEQC5Dpu5Of/Lwik638+i/4M3o/iBHpYDB28SmU2ezw0g6qr+Xs2ngPAW9pu0N+hZmkKkfktw==","signatures":[{"sig":"MEYCIQCCsQ9wJCOq64zJkjzRjRSRI+jW7lJ3f1ql93EeKdtswwIhAIN3v4KiSaap+HnCzcbo1vdwaTqQcDosQaqQoQ1K3N1N","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/studio/static/diagrams/logo.jpg)\r\n\r\n### nodejs web api with [typescript](http://www.typescriptlang.org/)\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n\r\nexport function index(context) {\r\n\r\n\tcontext.response.write('hello world!!');\r\n\r\n\tcontext.response.end();\r\n}\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n## overview\r\n\r\nappex is a nodejs web api framework built on top of the TypeScript programming language. It enables\r\ndevelopers to develop RESTful service endpoints by writing TypeScript functions, as well as providing\r\nreflection / type and interface meta data derived from the languages type system.\r\n\r\n* [getting started](#getting_started)\r\n\t* [application](#application)\r\n\t* [options](#options)\r\n\t* [http server](#http_server)\r\n\t* [express middleware](#express_middleware)\r\n* [creating services with typescript](#creating_services)\r\n\t* [context](#context)\r\n\t* [signatures](#signatures)\r\n\t* [attributes](#attributes)\r\n\t* [http handlers](#http_handlers)\r\n\t* [index handlers](#index_handlers)\r\n\t* [wildcard handlers](#wildcard_handlers)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [routing functions](#routing_functions)\r\n\t* [handling 404](#handling_404)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline configuring appex.\r\n\r\n<a name=\"application\" />\r\n### application\r\n\r\nSetting up. \r\n\r\n```javascript\r\nvar appex   = require('appex');\r\n\r\nvar app   = appex({ program : './program.ts', \r\n                    devmode : true,\r\n                    logging : true });\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"options\" />\r\n### options\r\n\r\nappex accepts the following startup options.\r\n\r\n```javascript\r\nvar options = { \r\n\t// (required) location of source file.\r\n\tprogram    : './program.ts', \r\n\r\n\t// (optional) recompile on request. (default:false) \r\n\tdevmode    : true,          \r\n\r\n\t// (optional) log to stdout. (default:false) \r\n\tlogging    : true,\r\n\r\n\t// (optional) additional objects added on the [context](#context)\r\n\tcontext    : {}\r\n};\r\n\r\nvar app = appex( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### http server\r\n\r\nSetting up appex on a nodejs http server.\r\n\r\n```javascript\r\nvar http = require('http');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\nvar server = http.createServer( app );\r\n\r\nserver.listen(3000);\r\n```\r\n<a name=\"express_middleware\" />\r\n### express middleware\r\n\r\nSetting up as express middleware.\r\n\r\n```javascript\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use(appex({ program : './program.ts' })); \r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"creating_services\" />\r\n## creating services with typescript\r\n\r\nThe following section describes how to write http accessible functions with appex.\r\n\r\n<a name=\"context\" />\r\n### context\r\n\r\nAll appex functions are passed a context object as the first argument. The context object encapulates\r\nthe http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the context object\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.attribute  - appex attribute.\r\n\r\n\t// context.module     - appex module meta data and reflection.\r\n\r\n\t// context.routes     - appex routing tables.\r\n\r\n\t// context.mime       - appex mime utility.\r\n\r\n\t// context.???        - user defined [options](#options)\r\n}\r\n```\r\n\r\n<a name=\"attributes\" />\r\n### attributes\r\n\r\nappex supports optional declarative attributes on 'exported' modules and functions. Attributes are declaritive meta data\r\nyou can associate with appex handlers to describe characteristics on given routes. Attributes are analogous to .net attributes,\r\nhowever, they also have a cascading behaviour that can be used to apply metadata for an entire scope. A concept similar to \r\ncascading stylesheets rules.\r\n\r\nBy default, appex uses attributes for HTTP VERB matching:\r\n\r\n```javascript\r\n\r\ndeclare var attribute;\r\n\r\nattribute(\"contact\", {  verbs: [\"get\"]  } );\r\n\r\nexport function contact(context) {\r\n\r\n\t// handler will only be invoke on HTTP GET requests\r\n}\r\n\r\nattribute(\"submit\", {  verbs: [\"post\"]  } );\r\n\r\nexport function submit(context) {\r\n\r\n\t// handler will only be invoke on HTTP POST requests\r\n}\r\n\r\n```\r\n\r\nthe following demonstrates attribute cascading:\r\n\r\n```javascript\r\ndeclare var attribute;\r\n\r\nattribute('foo', {a : 10})\r\nexport module foo {\r\n\r\n    attribute('foo.bar', {b : 20})\r\n    export module bar {\r\n            \r\n        attribute('foo.bar.index', {c : 30})\r\n        export function index(context) {\r\n        \r\n            //context.attribute\r\n            //{\r\n            //    \"a\": 10,\r\n            //    \"b\": 20,\r\n            //    \"c\": 30\r\n            //}            \r\n\r\n            context.response.writeHead(200, {'content-type' : 'text/plain'});\r\n\t\r\n            context.response.write( JSON.stringify(context.attribute, null, 4) );\r\n\t\r\n            context.response.end();       \r\n        }\r\n    }\r\n}\r\n\r\n```\r\n\r\nand for something more practical..\r\n\r\n```javascript\r\ndeclare var attribute;\r\n\r\nattribute('admin', { roles : ['administrators'] )\r\nexport module admin {\r\n\t\r\n\texport function index(context) {\r\n\t\t\r\n\t\tvar user = context.user;\r\n\r\n\t\tif(!user.isInRole( context.attribute.roles ) ) {\r\n\r\n\t\t\t// access denied!\r\n\r\n\t\t}\r\n\t}\r\n}\r\n\r\n```\r\n\r\nattributes can also be looked up by calling attribute( qualifier ).\r\n\r\n```javascript\r\n\r\ndeclare var attribute;\r\n\r\nexport function index(context) {\r\n    \r\n\tvar info = attribute('other');\r\n\t\r\n\tcontext.response.write( JSON.stringify(info, null, 4) );\r\n\t\r\n\tcontext.response.end();\t\r\n}\r\n\r\nattribute(\"other\", {  verbs: [\"get\"], message:'hello' } );\r\nexport function other(context) {\r\n    \r\n\tcontext.response.write(context.attribute.message);\r\n\t\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"signatures\" />\r\n### signatures\r\n\r\nappex will only setup http routes to functions which conform to the following function signatures. \r\n\r\n<a name=\"http_handlers\" />\r\n### http handlers\r\n\r\nappex http handlers require the following signature:\r\n\r\n* argument[0] - context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\nexport function method(context) {\r\n\r\n\tcontext.response.write('hello world');\r\n\t\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"index_handlers\" />\r\n### index handlers\r\n\r\nappex index handlers resolve urls to their current module scope. As demonstrated below: \r\n\r\nappex index handlers require the following signature:\r\n\r\n* name        - 'index'\r\n* argument[0] - context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { \r\n\r\n\tcontext.response.write('home page');\r\n\t\r\n\tcontext.response.end();\r\n}\r\n\r\n// url: http://[host]:[port]/home\r\nexport function home(context) {\r\n\r\n\tindex(context)\r\n}\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) { /* handle request */ }\r\n\t\r\n\t// url: http://[host]:[port]/blogs/submit\r\n\texport function submit (context) { /* handle request */ }\r\n}\r\n```\r\n\r\n<a name=\"wildcard_handlers\" />\r\n### wildcard handlers\r\n\r\nappex wildcard handlers allow for wildcard routing at a given module scope. In addition, wildcard handlers\r\nsupport 'typed' url argument mapping, as denoted by the parameter annotation.\r\n\r\nappex wildcard handlers require the following signature:\r\n\r\n* name        - 'wildcard'\r\n* argument[0] - context\r\n* argument[n] - arguments to be mapped from the url\r\n* returns     - void (optional)\r\n\r\n```javascript\r\ndeclare var console;\r\n\r\nexport module blogs {\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11  - matched\r\n\t// url : http://[host]:[port]/blogs/2013/01/11 - matched\r\n\t// url : http://[host]:[port]/blogs/fluff/01/11  - not matched\r\n    export function wildcard(context, year:number, month:number, day:number) {\r\n\t\t\r\n\t\tconsole.log(year); \r\n\r\n\t\tconsole.log(month);\r\n\r\n\t\tconsole.log(day);\r\n\r\n        context.response.write('my blog')\r\n\r\n        context.response.end(); \r\n    }\r\n}\r\n```\r\nnote: appex only supports type any (or none), string and number annotations. specifying any other type result \r\nin this wildcard not being routed.\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex will only export functions prefix with the TypeScript 'export' declaration. Also, exported \r\nfunctions that reside in non exported modules will not be routed. Developers can use this to infer\r\nnotions of public and private at the http level.\r\n\r\nconsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.write('testing');\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"routing_functions\" />\r\n### routing functions\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context:any) { }\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context:any) { }\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context:any) { }\r\n\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context:any) : void { }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context:any) : void { }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context:any) : void { }\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```javascript\r\n// http:[host]:[port]/\r\nexport function index   (context) { \r\n\tcontext.response.writeHead(404, {'content-type' : 'text/plain'});\r\n\tcontext.response.write('home page');\r\n\tcontext.response.end();\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\tcontext.response.writeHead(404, {'content-type' : 'text/plain'});\r\n\tcontext.response.write(path + ' page not found');\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex ({ program : './index.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"pages.ts\" />\r\n/// <reference path=\"users.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { /* handle request */ }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { /* handle request */ }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { /* handle request */ }\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { /* handle request */ }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { /* handle request */ }\r\n}\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"http://www.apache.org/licenses/LICENSE-2.0.html","type":"Apache 2.0"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"nodejs web api with typescript","directories":{},"dependencies":{"typescript.api":"0.5.2"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.3.8":{"name":"appex","version":"0.3.8","keywords":["typescript","web api","reflection","compiler"],"author":{"name":"sinclair"},"_id":"appex@0.3.8","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"74d8984d99ffaa8546c02ef56918d0bb59cae3b4","tarball":"https://registry.npmjs.org/appex/-/appex-0.3.8.tgz","integrity":"sha512-phKOZ64LS9YMbuDQi/O4Mh7OvL+TIT2UbVPMqX7rwMepbKkHSY7072iLHyTXj2HNu6Qxb2zNt+oI8xS216VifA==","signatures":[{"sig":"MEQCIEkL0UG8qzE9bLbw+s/y7cdtdLM3c/gNQHcN5HjHTc2kAiAV2N3+0CLCbw/vArOxgPjL2Z0PKkpIqMnMjF7VC4tcMw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/studio/static/diagrams/logo.jpg)\r\n\r\n### nodejs web api with [typescript](http://www.typescriptlang.org/)\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n\r\nexport function index(context) {\r\n\r\n\tcontext.response.write('hello world!!');\r\n\r\n\tcontext.response.end();\r\n}\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n## overview\r\n\r\nappex is a nodejs web api framework built on top of the TypeScript programming language. It enables\r\ndevelopers to develop RESTful service endpoints by writing TypeScript functions, as well as providing\r\nreflection / type and interface meta data derived from the languages type system.\r\n\r\n* [getting started](#getting_started)\r\n\t* [application](#application)\r\n\t* [options](#options)\r\n\t* [http server](#http_server)\r\n\t* [express middleware](#express_middleware)\r\n* [creating services with typescript](#creating_services)\r\n\t* [context](#context)\r\n\t* [signatures](#signatures)\r\n\t* [attributes](#attributes)\r\n\t* [http handlers](#http_handlers)\r\n\t* [index handlers](#index_handlers)\r\n\t* [wildcard handlers](#wildcard_handlers)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [routing functions](#routing_functions)\r\n\t* [handling 404](#handling_404)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline configuring appex.\r\n\r\n<a name=\"application\" />\r\n### application\r\n\r\nSetting up. \r\n\r\n```javascript\r\nvar appex   = require('appex');\r\n\r\nvar app   = appex({ program : './program.ts', \r\n                    devmode : true,\r\n                    logging : true });\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"options\" />\r\n### options\r\n\r\nappex accepts the following startup options.\r\n\r\n```javascript\r\nvar options = { \r\n\t// (required) location of source file.\r\n\tprogram    : './program.ts', \r\n\r\n\t// (optional) recompile on request. (default:false) \r\n\tdevmode    : true,          \r\n\r\n\t// (optional) log to stdout. (default:false) \r\n\tlogging    : true,\r\n\r\n\t// (optional) additional objects added on the [context](#context)\r\n\tcontext    : {}\r\n};\r\n\r\nvar app = appex( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### http server\r\n\r\nSetting up appex on a nodejs http server.\r\n\r\n```javascript\r\nvar http = require('http');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\nvar server = http.createServer( app );\r\n\r\nserver.listen(3000);\r\n```\r\n<a name=\"express_middleware\" />\r\n### express middleware\r\n\r\nSetting up as express middleware.\r\n\r\n```javascript\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use(appex({ program : './program.ts' })); \r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"creating_services\" />\r\n## creating services with typescript\r\n\r\nThe following section describes how to write http accessible functions with appex.\r\n\r\n<a name=\"context\" />\r\n### context\r\n\r\nAll appex functions are passed a context object as the first argument. The context object encapulates\r\nthe http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the context object\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.attribute  - appex attribute.\r\n\r\n\t// context.module     - appex module meta data and reflection.\r\n\r\n\t// context.routes     - appex routing tables.\r\n\r\n\t// context.mime       - appex mime utility.\r\n\r\n\t// context.???        - user defined [options](#options)\r\n}\r\n```\r\n\r\n<a name=\"attributes\" />\r\n### attributes\r\n\r\nappex supports optional declarative attributes on 'exported' modules and functions. Attributes are declaritive meta data\r\nyou can associate with appex handlers to describe characteristics on given routes. Attributes are analogous to .net attributes,\r\nhowever, they also have a cascading behaviour that can be used to apply metadata for an entire scope. A concept similar to \r\ncascading stylesheets rules.\r\n\r\nBy default, appex uses attributes for HTTP VERB matching:\r\n\r\n```javascript\r\n\r\ndeclare var attribute;\r\n\r\nattribute(\"contact\", {  verbs: [\"get\"]  } );\r\n\r\nexport function contact(context) {\r\n\r\n\t// handler will only be invoke on HTTP GET requests\r\n}\r\n\r\nattribute(\"submit\", {  verbs: [\"post\"]  } );\r\n\r\nexport function submit(context) {\r\n\r\n\t// handler will only be invoke on HTTP POST requests\r\n}\r\n\r\n```\r\n\r\nthe following demonstrates attribute cascading:\r\n\r\n```javascript\r\ndeclare var attribute;\r\n\r\nattribute('foo', {a : 10})\r\nexport module foo {\r\n\r\n    attribute('foo.bar', {b : 20})\r\n    export module bar {\r\n            \r\n        attribute('foo.bar.index', {c : 30})\r\n        export function index(context) {\r\n        \r\n            //context.attribute\r\n            //{\r\n            //    \"a\": 10,\r\n            //    \"b\": 20,\r\n            //    \"c\": 30\r\n            //}            \r\n\r\n            context.response.writeHead(200, {'content-type' : 'text/plain'});\r\n\t\r\n            context.response.write( JSON.stringify(context.attribute, null, 4) );\r\n\t\r\n            context.response.end();       \r\n        }\r\n    }\r\n}\r\n\r\n```\r\n\r\nand for something more practical..\r\n\r\n```javascript\r\ndeclare var attribute;\r\n\r\nattribute('admin', { roles : ['administrators'] )\r\nexport module admin {\r\n\t\r\n\texport function index(context) {\r\n\t\t\r\n\t\tvar user = context.user;\r\n\r\n\t\tif(!user.isInRole( context.attribute.roles ) ) {\r\n\r\n\t\t\t// access denied!\r\n\r\n\t\t}\r\n\t}\r\n}\r\n\r\n```\r\n\r\nattributes can also be looked up by calling attribute( qualifier ).\r\n\r\n```javascript\r\n\r\ndeclare var attribute;\r\n\r\nexport function index(context) {\r\n    \r\n\tvar info = attribute('other');\r\n\t\r\n\tcontext.response.write( JSON.stringify(info, null, 4) );\r\n\t\r\n\tcontext.response.end();\t\r\n}\r\n\r\nattribute(\"other\", {  verbs: [\"get\"], message:'hello' } );\r\nexport function other(context) {\r\n    \r\n\tcontext.response.write(context.attribute.message);\r\n\t\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"signatures\" />\r\n### signatures\r\n\r\nappex will only setup http routes to functions which conform to the following function signatures. \r\n\r\n<a name=\"http_handlers\" />\r\n### http handlers\r\n\r\nappex http handlers require the following signature:\r\n\r\n* argument[0] - context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\nexport function method(context) {\r\n\r\n\tcontext.response.write('hello world');\r\n\t\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"index_handlers\" />\r\n### index handlers\r\n\r\nappex index handlers resolve urls to their current module scope. As demonstrated below: \r\n\r\nappex index handlers require the following signature:\r\n\r\n* name        - 'index'\r\n* argument[0] - context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { \r\n\r\n\tcontext.response.write('home page');\r\n\t\r\n\tcontext.response.end();\r\n}\r\n\r\n// url: http://[host]:[port]/home\r\nexport function home(context) {\r\n\r\n\tindex(context)\r\n}\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) { /* handle request */ }\r\n\t\r\n\t// url: http://[host]:[port]/blogs/submit\r\n\texport function submit (context) { /* handle request */ }\r\n}\r\n```\r\n\r\n<a name=\"wildcard_handlers\" />\r\n### wildcard handlers\r\n\r\nappex wildcard handlers allow for wildcard routing at a given module scope. In addition, wildcard handlers\r\nsupport 'typed' url argument mapping, as denoted by the parameter annotation.\r\n\r\nappex wildcard handlers require the following signature:\r\n\r\n* name        - 'wildcard'\r\n* argument[0] - context\r\n* argument[n] - arguments to be mapped from the url\r\n* returns     - void (optional)\r\n\r\n```javascript\r\ndeclare var console;\r\n\r\nexport module blogs {\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11  - matched\r\n\t// url : http://[host]:[port]/blogs/2013/01/11 - matched\r\n\t// url : http://[host]:[port]/blogs/fluff/01/11  - not matched\r\n    export function wildcard(context, year:number, month:number, day:number) {\r\n\t\t\r\n\t\tconsole.log(year); \r\n\r\n\t\tconsole.log(month);\r\n\r\n\t\tconsole.log(day);\r\n\r\n        context.response.write('my blog')\r\n\r\n        context.response.end(); \r\n    }\r\n}\r\n```\r\nnote: appex only supports type any (or none), string and number annotations. specifying any other type result \r\nin this wildcard not being routed.\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex will only export functions prefix with the TypeScript 'export' declaration. Also, exported \r\nfunctions that reside in non exported modules will not be routed. Developers can use this to infer\r\nnotions of public and private at the http level.\r\n\r\nconsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.write('testing');\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"routing_functions\" />\r\n### routing functions\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context:any) { }\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context:any) { }\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context:any) { }\r\n\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context:any) : void { }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context:any) : void { }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context:any) : void { }\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```javascript\r\n// http:[host]:[port]/\r\nexport function index   (context) { \r\n\tcontext.response.writeHead(404, {'content-type' : 'text/plain'});\r\n\tcontext.response.write('home page');\r\n\tcontext.response.end();\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\tcontext.response.writeHead(404, {'content-type' : 'text/plain'});\r\n\tcontext.response.write(path + ' page not found');\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex ({ program : './index.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"pages.ts\" />\r\n/// <reference path=\"users.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { /* handle request */ }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { /* handle request */ }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { /* handle request */ }\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { /* handle request */ }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { /* handle request */ }\r\n}\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"http://www.apache.org/licenses/LICENSE-2.0.html","type":"Apache 2.0"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"nodejs web api with typescript","directories":{},"dependencies":{"typescript.api":"0.5.4"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.3.9":{"name":"appex","version":"0.3.9","keywords":["typescript","web api","reflection","compiler"],"author":{"name":"sinclair"},"_id":"appex@0.3.9","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"034267b011226812d88ec689b1b34e8c0c57205b","tarball":"https://registry.npmjs.org/appex/-/appex-0.3.9.tgz","integrity":"sha512-7IS4vsjgLkNGvyqM+cueDWX/9n4YkTkxzZ6n8gWq0Oup6S3x35+EcLTmqeZOyehzTUlT1N7C0AwojYmptrO6XA==","signatures":[{"sig":"MEYCIQCvJ1WPW0VWRIiceKODq6FXk4dpml4lMkLjkP3IrAUBeAIhAL32p0OyZNtUBb9c9v3Ec8XKoa+zdpKxV5hszhVkr4CD","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/studio/static/diagrams/logo.jpg)\r\n\r\n### nodejs web api with [typescript](http://www.typescriptlang.org/)\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n\r\nexport function index(context) {\r\n\r\n\tcontext.response.write('hello world!!');\r\n\r\n\tcontext.response.end();\r\n}\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n## overview\r\n\r\nappex is a nodejs web api framework built on top of the TypeScript programming language. It enables\r\ndevelopers to develop RESTful service endpoints by writing TypeScript functions, as well as providing\r\nreflection / type and interface meta data derived from the languages type system.\r\n\r\n* [getting started](#getting_started)\r\n\t* [application](#application)\r\n\t* [options](#options)\r\n\t* [http server](#http_server)\r\n\t* [express middleware](#express_middleware)\r\n* [creating services with typescript](#creating_services)\r\n\t* [context](#context)\r\n\t* [signatures](#signatures)\r\n\t* [attributes](#attributes)\r\n\t* [http handlers](#http_handlers)\r\n\t* [index handlers](#index_handlers)\r\n\t* [wildcard handlers](#wildcard_handlers)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [routing functions](#routing_functions)\r\n\t* [handling 404](#handling_404)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline configuring appex.\r\n\r\n<a name=\"application\" />\r\n### application\r\n\r\nSetting up. \r\n\r\n```javascript\r\nvar appex   = require('appex');\r\n\r\nvar app   = appex({ program : './program.ts', \r\n                    devmode : true,\r\n                    logging : true });\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"options\" />\r\n### options\r\n\r\nappex accepts the following startup options.\r\n\r\n```javascript\r\nvar options = { \r\n\t// (required) location of source file.\r\n\tprogram    : './program.ts', \r\n\r\n\t// (optional) recompile on request. (default:false) \r\n\tdevmode    : true,          \r\n\r\n\t// (optional) log to stdout. (default:false) \r\n\tlogging    : true,\r\n\r\n\t// (optional) additional objects added on the [context](#context)\r\n\tcontext    : {}\r\n};\r\n\r\nvar app = appex( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### http server\r\n\r\nSetting up appex on a nodejs http server.\r\n\r\n```javascript\r\nvar http = require('http');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\nvar server = http.createServer( app );\r\n\r\nserver.listen(3000);\r\n```\r\n<a name=\"express_middleware\" />\r\n### express middleware\r\n\r\nSetting up as express middleware.\r\n\r\n```javascript\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use(appex({ program : './program.ts' })); \r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"creating_services\" />\r\n## creating services with typescript\r\n\r\nThe following section describes how to write http accessible functions with appex.\r\n\r\n<a name=\"context\" />\r\n### context\r\n\r\nAll appex functions are passed a context object as the first argument. The context object encapulates\r\nthe http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the context object\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.attribute  - appex attribute.\r\n\r\n\t// context.module     - appex module meta data and reflection.\r\n\r\n\t// context.routes     - appex routing tables.\r\n\r\n\t// context.mime       - appex mime utility.\r\n\r\n\t// context.???        - user defined [options](#options)\r\n}\r\n```\r\n\r\n<a name=\"attributes\" />\r\n### attributes\r\n\r\nappex supports optional declarative attributes on 'exported' modules and functions. Attributes are declaritive meta data\r\nyou can associate with appex handlers to describe characteristics on given routes. Attributes are analogous to .net attributes,\r\nhowever, they also have a cascading behaviour that can be used to apply metadata for an entire scope. A concept similar to \r\ncascading stylesheets rules.\r\n\r\nBy default, appex uses attributes for HTTP VERB matching:\r\n\r\n```javascript\r\n\r\ndeclare var attribute;\r\n\r\nattribute(\"contact\", {  verbs: [\"get\"]  } );\r\n\r\nexport function contact(context) {\r\n\r\n\t// handler will only be invoke on HTTP GET requests\r\n}\r\n\r\nattribute(\"submit\", {  verbs: [\"post\"]  } );\r\n\r\nexport function submit(context) {\r\n\r\n\t// handler will only be invoke on HTTP POST requests\r\n}\r\n\r\n```\r\n\r\nthe following demonstrates attribute cascading:\r\n\r\n```javascript\r\ndeclare var attribute;\r\n\r\nattribute('foo', {a : 10})\r\nexport module foo {\r\n\r\n    attribute('foo.bar', {b : 20})\r\n    export module bar {\r\n            \r\n        attribute('foo.bar.index', {c : 30})\r\n        export function index(context) {\r\n        \r\n            //context.attribute\r\n            //{\r\n            //    \"a\": 10,\r\n            //    \"b\": 20,\r\n            //    \"c\": 30\r\n            //}            \r\n\r\n            context.response.writeHead(200, {'content-type' : 'text/plain'});\r\n\t\r\n            context.response.write( JSON.stringify(context.attribute, null, 4) );\r\n\t\r\n            context.response.end();       \r\n        }\r\n    }\r\n}\r\n\r\n```\r\n\r\nand for something more practical..\r\n\r\n```javascript\r\ndeclare var attribute;\r\n\r\nattribute('admin', { roles : ['administrators'] )\r\nexport module admin {\r\n\t\r\n\texport function index(context) {\r\n\t\t\r\n\t\tvar user = context.user;\r\n\r\n\t\tif(!user.isInRole( context.attribute.roles ) ) {\r\n\r\n\t\t\t// access denied!\r\n\r\n\t\t}\r\n\t}\r\n}\r\n\r\n```\r\n\r\nattributes can also be looked up by calling attribute( qualifier ).\r\n\r\n```javascript\r\n\r\ndeclare var attribute;\r\n\r\nexport function index(context) {\r\n    \r\n\tvar info = attribute('other');\r\n\t\r\n\tcontext.response.write( JSON.stringify(info, null, 4) );\r\n\t\r\n\tcontext.response.end();\t\r\n}\r\n\r\nattribute(\"other\", {  verbs: [\"get\"], message:'hello' } );\r\nexport function other(context) {\r\n    \r\n\tcontext.response.write(context.attribute.message);\r\n\t\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"signatures\" />\r\n### signatures\r\n\r\nappex will only setup http routes to functions which conform to the following function signatures. \r\n\r\n<a name=\"http_handlers\" />\r\n### http handlers\r\n\r\nappex http handlers require the following signature:\r\n\r\n* argument[0] - context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\nexport function method(context) {\r\n\r\n\tcontext.response.write('hello world');\r\n\t\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"index_handlers\" />\r\n### index handlers\r\n\r\nappex index handlers resolve urls to their current module scope. As demonstrated below: \r\n\r\nappex index handlers require the following signature:\r\n\r\n* name        - 'index'\r\n* argument[0] - context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { \r\n\r\n\tcontext.response.write('home page');\r\n\t\r\n\tcontext.response.end();\r\n}\r\n\r\n// url: http://[host]:[port]/home\r\nexport function home(context) {\r\n\r\n\tindex(context)\r\n}\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) { /* handle request */ }\r\n\t\r\n\t// url: http://[host]:[port]/blogs/submit\r\n\texport function submit (context) { /* handle request */ }\r\n}\r\n```\r\n\r\n<a name=\"wildcard_handlers\" />\r\n### wildcard handlers\r\n\r\nappex wildcard handlers allow for wildcard routing at a given module scope. Wildcard handlers\r\nsupport 'typed' url argument mapping, as denoted by the arguments annotation.\r\n\r\nIn addition, wildcard handlers also support optional arguments. As specific with TypeScript's ? syntax.\r\n\r\nappex wildcard handlers require the following signature:\r\n\r\n* name        - 'wildcard'\r\n* argument[0] - context\r\n* argument[n] - 1 or more arguments to be mapped from the url\r\n* returns     - void (optional)\r\n\r\n```javascript\r\ndeclare var console;\r\n\r\nexport module blogs {\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11   - matched\r\n\t// url : http://[host]:[port]/blogs/2013/01/11  - matched\r\n\t// url : http://[host]:[port]/blogs/2013/01/3rd - not matched - (see number annotation)\r\n\t// url : http://[host]:[port]/blogs/2013/01     - matched     - (see ? annotation)\r\n\t// url : http://[host]:[port]/blogs/2013        - not matched - (month is required)\r\n    export function wildcard(context, year:number, month:number, day?:number) {\r\n\t\t\r\n\t\tconsole.log(year); \r\n\r\n\t\tconsole.log(month);\r\n\r\n\t\tconsole.log(day);\r\n\r\n        context.response.write('my blog')\r\n\r\n        context.response.end(); \r\n    }\r\n}\r\n```\r\nnote: appex supports boolean, number, string and any annotations on wildcard arguments. if no annotation\r\nis specified, appex interprets the argument as a string. the type 'any' is also interpreted as string.\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex will only export functions prefix with the TypeScript 'export' declaration. Also, exported \r\nfunctions that reside in non exported modules will not be routed. Developers can use this to infer\r\nnotions of public and private at the http level.\r\n\r\nconsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.write('testing');\r\n\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"routing_functions\" />\r\n### routing functions\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context:any) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context:any) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context:any) { /* handle route */ }\r\n\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context:any) : void { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context:any) : void { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context:any) : void { /* handle route */ }\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```javascript\r\n// http:[host]:[port]/\r\nexport function index   (context) { \r\n\r\n\tcontext.response.writeHead(404, {'content-type' : 'text/plain'});\r\n\r\n\tcontext.response.write('home page');\r\n\r\n\tcontext.response.end();\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.writeHead(404, {'content-type' : 'text/plain'});\r\n\r\n\tcontext.response.write(path + ' page not found');\r\n\t\r\n\tcontext.response.end();\r\n}\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex ({ program : './index.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"pages.ts\" />\r\n/// <reference path=\"users.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { /* handle request */ }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { /* handle request */ }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { /* handle request */ }\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { /* handle request */ }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { /* handle request */ }\r\n}\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"http://www.apache.org/licenses/LICENSE-2.0.html","type":"Apache 2.0"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"nodejs web api with typescript","directories":{},"dependencies":{"typescript.api":"0.5.4"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.4.0":{"name":"appex","version":"0.4.0","keywords":["typescript","web api","reflection","compiler"],"author":{"name":"sinclair"},"_id":"appex@0.4.0","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"7121488271076d7eb6a96991eab9faefa903eed2","tarball":"https://registry.npmjs.org/appex/-/appex-0.4.0.tgz","integrity":"sha512-uDyRJ5MJ+MpTuPY3N73JlIi5BrsccdPNFFLo1EOGcXPcDhu/raDi4GVfvBBP0DfrdkOAdYFukZAlA1rsn+c99Q==","signatures":[{"sig":"MEUCIEmOP2gAiQ1oBx1fsc7P8iFpWrmRxZci5suCEIH8/lglAiEA8bhikGxpc+mpo5mSRwJYg2w0tmhhskVwRM2CivSNkfo=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/studio/static/diagrams/logo.jpg)\r\n\r\n### nodejs web api with [typescript](http://www.typescriptlang.org/)\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http://localhost:3000/\r\nexport function index(app) {\r\n\r\n\tapp.response.write('home');\r\n\r\n\tapp.response.end();\r\n}\r\n\r\n// http://localhost:3000/about\r\nexport function about(app) {\r\n\r\n\tapp.response.write('about');\r\n\r\n\tapp.response.end();\r\n}\r\n\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n## overview\r\n\r\nappex is a nodejs web api framework built on top of the TypeScript programming language. It enables\r\ndevelopers to develop RESTful service endpoints by writing TypeScript functions, as well as providing\r\nreflection / type and interface meta data derived from the languages type system.\r\n\r\n* [getting started](#getting_started)\r\n\t* [application](#application)\r\n\t* [options](#options)\r\n\t* [http server](#http_server)\r\n\t* [express middleware](#express_middleware)\r\n* [creating services with typescript](#creating_services)\r\n\t* [app context](#app_context)\r\n\t* [routing handlers](#routing_handlers)\r\n\t* [handler signatures](#handler_signatures)\r\n\t* [named handlers](#named_handlers)\r\n\t* [index handlers](#index_handlers)\r\n\t* [wildcard handlers](#wildcard_handlers)\r\n\t* [attributes](#attributes)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [handling 404](#handling_404)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline configuring appex.\r\n\r\n<a name=\"application\" />\r\n### application\r\n\r\nSetting up. \r\n\r\n```javascript\r\nvar appex   = require('appex');\r\n\r\nvar app   = appex({ program : './program.ts', \r\n                    devmode : true,\r\n                    logging : true });\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"options\" />\r\n### options\r\n\r\nappex accepts the following startup options.\r\n\r\n```javascript\r\nvar options = { \r\n\t// (required) location of source file.\r\n\tprogram    : './program.ts', \r\n\r\n\t// (optional) recompile on request. (default:false) \r\n\tdevmode    : true,          \r\n\r\n\t// (optional) log to stdout. (default:false) \r\n\tlogging    : true,\r\n\r\n\t// (optional) user defined objects added to the app context.\r\n\tcontext    : {}\r\n};\r\n\r\nvar app = appex( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### http server\r\n\r\nSetting up appex on a nodejs http server.\r\n\r\n```javascript\r\nvar http = require('http');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\nvar server = http.createServer( app );\r\n\r\nserver.listen(3000);\r\n```\r\n<a name=\"express_middleware\" />\r\n### express middleware\r\n\r\nSetting up as express middleware.\r\n\r\n```javascript\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use(appex({ program : './program.ts' })); \r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"creating_services\" />\r\n## creating services with typescript\r\n\r\nThe following section describes how to write http accessible functions with appex.\r\n\r\n<a name=\"app_context\" />\r\n### app context\r\n\r\nAll appex functions are passed a application context object as their first argument. The app context object \r\nencapulates the http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the app context\r\nexport function method(app) {\r\n\t\r\n\t// app.request    - the http request object.\r\n\r\n\t// app.response   - the http response object.\r\n\r\n\t// app.attribute  - appex attributes.\r\n\r\n\t// app.module     - appex module reflection and meta data.\r\n\r\n\t// app.routes     - appex routing tables.\r\n\r\n\t// app.mime       - appex mime utility.\r\n\r\n\t// app.[custom]   - user defined. (see options.context)\r\n}\r\n```\r\n\r\n<a name=\"routing_handlers\" />\r\n### routing handlers\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(app) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(app) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(app) { /* handle route */ }\r\n}\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (app) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (app) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (app) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/(.*)\r\nexport function wildcard (app, path) { /* handle route */ }\r\n\r\n```\r\n\r\n<a name=\"handler_signatures\" />\r\n### handler signatures\r\n\r\nappex supports three function signatures for http routing (named, index and wildcard). Functions that\r\ndo not apply these signatures will not be routed.\r\n\r\n<a name=\"named_handlers\" />\r\n### named handlers\r\n\r\nNamed handlers resolve urls to their current module scope + the name of the function.\r\n\r\nNamed handlers require the following signature:\r\n\r\n* name        - 'anything'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n\r\n// http://[host]:[port]/about\r\nexport function about(app) {\r\n\r\n\tapp.response.write('about page');\r\n\t\r\n\tapp.response.end();\r\n}\r\n\r\n// http://[host]:[port]/users/login\r\nexport module users {\r\n\r\n\texport function login(app) {\r\n\t\t\r\n\t\tapp.response.write('handle login');\r\n\t\r\n\t\tapp.response.end();\t\t\r\n\t}\r\n}\r\n\r\n```\r\n\r\n<a name=\"index_handlers\" />\r\n### index handlers\r\n\r\nIndex handlers resolve urls to their current module scope.\r\n\r\nIndex handlers require the following signature:\r\n\r\n* name        - 'index'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n// url: http://[host]:[port]/\r\nexport function index(app) { \r\n\r\n\tapp.response.write('home page');\r\n\t\r\n\tapp.response.end();\r\n}\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (app) \r\n\t{\t\r\n\t\tapp.response.write('blog index');\r\n\t\r\n\t\tapp.response.end();\r\n\t}\r\n}\r\n```\r\n\r\n<a name=\"wildcard_handlers\" />\r\n### wildcard handlers\r\n\r\nWildcard handlers resolve their urls to their current module scope + url.\r\n\r\nappex wildcard handlers allow for wildcard routing at a given module scope. Wildcard handlers\r\nsupport 'typed' url argument mapping, as denoted by the arguments annotation.\r\n\r\nIn addition, wildcard handlers also support optional arguments. As specific with TypeScript's '?' on argument names.\r\n\r\nappex wildcard handlers require the following signature:\r\n\r\n* name        - 'wildcard'\r\n* argument[0] - app context\r\n* argument[n] - 1 or more arguments to be mapped from the url\r\n* returns     - void (optional)\r\n\r\n```javascript\r\ndeclare var console;\r\n\r\nexport module blogs {\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11   - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/11  - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/3rd - not matched - (see number annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01     - matched     - (see ? annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013        - not matched - (month is required)\r\n\t\r\n    export function wildcard(app, year:number, month:number, day?:number) {\r\n\t\t\r\n\t\tconsole.log(year); \r\n\r\n\t\tconsole.log(month);\r\n\r\n\t\tconsole.log(day);\r\n\r\n        app.response.write('my blog')\r\n\r\n        app.response.end(); \r\n    }\r\n}\r\n\r\n// url : http://[host]:[port]/\r\nexport function index(app) {\r\n\r\n\tapp.response.write('home page');\r\n\t\r\n\tapp.response.end();\r\n}\r\n\r\n// url : http://[host]:[port]/(.*) \r\nexport function wildcard(app, path) {\r\n\r\n\tapp.response.writeHead(404, {'content-type' : 'text/plain'});\r\n\t\r\n\tapp.response.write(path + ' not found');\r\n\t\r\n\tapp.response.end();\r\n}\r\n\r\n```\r\nnote: appex supports boolean, number, string and any annotations on wildcard arguments. if no annotation\r\nis specified, appex interprets the argument as a string. the type 'any' is also interpreted as string.\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"attributes\" />\r\n### attributes\r\n\r\nappex supports a cascading attributute scheme on modules and functions. Attributes are declaritive meta data\r\nyou can associate with appex handlers to describe characteristics on given routes. Attributes are analogous to .net attributes,\r\nhowever, they also have a cascading behaviour that can be used to apply metadata for an entire scope. A concept similar to \r\ncascading stylesheets rules.\r\n\r\nBy default, appex uses attributes for HTTP VERB matching:\r\n\r\n```javascript\r\n\r\ndeclare var attribute;\r\n\r\nattribute(\"contact\", {  verbs: [\"get\"]  } );\r\n\r\nexport function contact(app) {\r\n\r\n\t// handler will only be invoke on HTTP GET requests\r\n}\r\n\r\nattribute(\"submit\", {  verbs: [\"post\"]  } );\r\n\r\nexport function submit(app) {\r\n\r\n\t// handler will only be invoke on HTTP POST requests\r\n}\r\n\r\n```\r\n\r\nthe following demonstrates attribute cascading behavior.\r\n\r\n```javascript\r\ndeclare var attribute;\r\n\r\nattribute('foo', {a : 10})\r\nexport module foo {\r\n\r\n    attribute('foo.bar', {b : 20})\r\n    export module bar {\r\n            \r\n        attribute('foo.bar.index', {c : 30})\r\n        export function index(app) {\r\n        \r\n            //app.attribute\r\n            //{\r\n            //    \"a\": 10,\r\n            //    \"b\": 20,\r\n            //    \"c\": 30\r\n            //}            \r\n\r\n            app.response.writeHead(200, {'content-type' : 'text/plain'});\r\n\t\r\n            app.response.write( JSON.stringify(app.attribute, null, 4) );\r\n\t\r\n            app.response.end();       \r\n        }\r\n    }\r\n}\r\n\r\n```\r\n\r\nand for something more practical..\r\n\r\n```javascript\r\ndeclare var attribute;\r\n\r\nattribute('admin', { roles : ['administrators'] )\r\nexport module admin {\r\n\t\r\n\texport function index(app) {\r\n\t\t\r\n\t\tvar user = app.user;\r\n\r\n\t\tif(!user.isInRole( app.attribute.roles ) ) {\r\n\r\n\t\t\t// access denied!\r\n\r\n\t\t}\r\n\t}\r\n}\r\n\r\n```\r\n\r\nattributes can also be looked up by calling attribute( qualifier ).\r\n\r\n```javascript\r\n\r\ndeclare var attribute;\r\n\r\nattribute(\"other\", {  verbs: [\"get\"], message:'hello' } );\r\nexport function other(app) {\r\n    \r\n\tapp.response.write(app.attribute.message);\r\n\t\r\n\tapp.response.end();\r\n}\r\n\r\nexport function index(app) {\r\n    \r\n\tvar info = attribute('other'); // look up.\r\n\t\r\n\tapp.response.write( JSON.stringify(info, null, 4) );\r\n\t\r\n\tapp.response.end();\t\r\n}\r\n\r\n```\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex will only route functions prefix with the TypeScript 'export' declarer. This rule\r\nalso applied to modules. Developers can use this to infer notions of public and private \r\nat the http level.\r\n\r\nconsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore publically accessible.\r\nexport function public_function   (app) { \r\n\t\r\n\t// this function can invoke private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tapp.response.write('testing');\r\n\r\n\tapp.response.end();\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```javascript\r\n// http:[host]:[port]/\r\nexport function index   (app) { \r\n\r\n\tapp.response.writeHead(404, {'content-type' : 'text/plain'});\r\n\r\n\tapp.response.write('home page');\r\n\r\n\tapp.response.end();\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(app, path) {\r\n\r\n\tapp.response.writeHead(404, {'content-type' : 'text/plain'});\r\n\r\n\tapp.response.write(path + ' page not found');\r\n\t\r\n\tapp.response.end();\r\n}\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex ({ program : './index.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"pages.ts\" />\r\n/// <reference path=\"users.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (app) { /* handle request */ }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (app) { /* handle request */ }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (app) { /* handle request */ }\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (app) { /* handle request */ }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (app) { /* handle request */ }\r\n}\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"http://www.apache.org/licenses/LICENSE-2.0.html","type":"Apache 2.0"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"nodejs web api with typescript","directories":{},"dependencies":{"typescript.api":"0.5.4"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.4.1":{"name":"appex","version":"0.4.1","keywords":["typescript","web api","reflection","compiler"],"author":{"name":"sinclair"},"_id":"appex@0.4.1","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"67d8074c68986807c432ac199d5f39c40400bb91","tarball":"https://registry.npmjs.org/appex/-/appex-0.4.1.tgz","integrity":"sha512-UM41d9ZuZwg5ImEW+LkiqkI4k4vwrzyC/4HwBxKze4qI+zE3N1opYkU29xv7EIi3EIo6ukrcYyvm4bGcocTO6w==","signatures":[{"sig":"MEQCIHerbop3y2qdk8Ft6W0V0lT/9yLh586gewJ31myDc6noAiBESv0zT0+mNV49FmudZr8VXiCQnoF9Ss4SrW+89QpjaQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/artifacts/logo.jpg)\r\n\r\n### nodejs web api with [typescript](http://www.typescriptlang.org/)\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http://localhost:3000/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// http://localhost:3000/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about');\r\n}\r\n\r\n// http://localhost:3000/(.*)\r\nexport function wildcard (context, path) {\r\n    \r\n    context.response.send(404, path + \"not found\");\r\n}\r\n\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n## overview\r\n\r\nappex is a nodejs web api framework built on top of the TypeScript programming language. It enables\r\ndevelopers to develop RESTful service endpoints by writing TypeScript functions, as well as providing\r\nreflection / type and interface meta data derived from the languages type system.\r\n\r\n* [getting started](#getting_started)\r\n\t* [application](#application)\r\n\t* [options](#options)\r\n\t* [http server](#http_server)\r\n\t* [express middleware](#express_middleware)\r\n* [creating services with typescript](#creating_services)\r\n\t* [app context](#app_context)\r\n\t* [routing handlers](#routing_handlers)\r\n\t* [handler signatures](#handler_signatures)\r\n\t* [named handlers](#named_handlers)\r\n\t* [index handlers](#index_handlers)\r\n\t* [wildcard handlers](#wildcard_handlers)\r\n\t* [cascades](#cascades)\r\n\t* [http verbs](#http_verbs)\r\n\t* [middleware](#middleware)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [handling 404](#handling_404)\r\n\t* [serving static files](#serving_static_files)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [appex.d.ts declaration](#appex_declaration)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline configuring appex.\r\n\r\n<a name=\"application\" />\r\n### application\r\n\r\nSetting up. \r\n\r\n```javascript\r\nvar appex   = require('appex');\r\n\r\nvar app   = appex({ program : './program.ts', \r\n                    devmode : true,\r\n                    logging : true });\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"options\" />\r\n### options\r\n\r\nappex accepts the following startup options.\r\n\r\n```javascript\r\nvar options = { \r\n\t// (required) location of source file.\r\n\tprogram    : './program.ts', \r\n\r\n\t// (optional) recompile on request. (default:false) \r\n\tdevmode    : true,          \r\n\r\n\t// (optional) log to stdout. (default:false) \r\n\tlogging    : true,\r\n\r\n\t// (optional) user defined objects added to the app context.\r\n\tcontext    : {}\r\n};\r\n\r\nvar app = appex( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### http server\r\n\r\nSetting up appex on a nodejs http server.\r\n\r\n```javascript\r\nvar http = require('http');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\nvar server = http.createServer( app );\r\n\r\nserver.listen(3000);\r\n```\r\n<a name=\"express_middleware\" />\r\n### express middleware\r\n\r\nSetting up as express middleware.\r\n\r\n```javascript\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use(appex({ program : './program.ts' })); \r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"creating_services\" />\r\n## creating services with typescript\r\n\r\nThe following section describes how to write http accessible functions with appex.\r\n\r\n<a name=\"app_context\" />\r\n### app context\r\n\r\nAll appex functions are passed a application context object as their first argument. The app context object \r\nencapulates the http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the app context\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.cascade    - appex cascade.\r\n\r\n\t// context.next       - the next function (express middleware)\r\n}\r\n```\r\n\r\n<a name=\"routing_handlers\" />\r\n### routing handlers\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context) { /* handle route */ }\r\n}\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/(.*)\r\nexport function wildcard (context, path) { /* handle route */ }\r\n\r\n```\r\n\r\n<a name=\"handler_signatures\" />\r\n### handler signatures\r\n\r\nappex supports three function signatures for http routing (named, index and wildcard). Functions that\r\ndo not apply these signatures will not be routed.\r\n\r\n<a name=\"named_handlers\" />\r\n### named handlers\r\n\r\nNamed handlers resolve urls to their current module scope + the name of the function.\r\n\r\nNamed handlers require the following signature:\r\n\r\n* name        - 'anything'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n\r\n// http://[host]:[port]/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about page');\r\n}\r\n\r\n// http://[host]:[port]/users/login\r\nexport module users {\r\n\r\n\texport function login(context) {\r\n\t\t\r\n\t\tcontext.response.send('handle login');\t\r\n\t}\r\n}\r\n\r\n```\r\n\r\n<a name=\"index_handlers\" />\r\n### index handlers\r\n\r\nIndex handlers resolve urls to their current module scope.\r\n\r\nIndex handlers require the following signature:\r\n\r\n* name        - 'index'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) \r\n\t{\t\r\n\t\tcontext.response.send('blog index');\r\n\t}\r\n}\r\n```\r\n\r\n<a name=\"wildcard_handlers\" />\r\n### wildcard handlers\r\n\r\nWildcard handlers resolve their urls to their current module scope + url.\r\n\r\nappex wildcard handlers allow for wildcard routing at a given module scope. Wildcard handlers\r\nsupport 'typed' url argument mapping, as denoted by the arguments annotation.\r\n\r\nIn addition, wildcard handlers also support optional arguments. As specific with TypeScript's '?' on argument names.\r\n\r\nappex wildcard handlers require the following signature:\r\n\r\n* name        - 'wildcard'\r\n* argument[0] - app context\r\n* argument[n] - 1 or more arguments to be mapped from the url\r\n* returns     - void (optional)\r\n\r\n```javascript\r\ndeclare var console;\r\n\r\nexport module blogs {\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11   - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/11  - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/3rd - not matched - (see number annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01     - matched     - (see ? annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013        - not matched - (month is required)\r\n\t\r\n    export function wildcard(context, year:number, month:number, day?:number) {\r\n\r\n        context.response.json({ year: year, month: month, day: day})\r\n    }\r\n}\r\n\r\n// url : http://[host]:[port]/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// url : http://[host]:[port]/(.*) \r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, 'not found');\r\n}\r\n\r\n```\r\nnote: appex supports boolean, number, string and any annotations on wildcard arguments. if no annotation\r\nis specified, appex interprets the argument as a string. the type 'any' is also interpreted as string.\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"cascades\" />\r\n### cascades\r\n\r\nappex supports a cascading attribute scheme on modules and functions. With this, developers can apply\r\narbituary meta data for modules and functions that will propagate through scope. appex has two special\r\ncascade properties for middleware and http verb matching, which are described below, however consider\r\nthe following code which illistrates the concept.\r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ncascade({a: 10}); // global.\r\n\r\ncascade('foo', {b : 20})\r\nexport module foo {\r\n\r\n    cascade('foo.bar', {c : 30})\r\n    export module bar {\r\n            \r\n        cascade('foo.bar.index', {d : 40})\r\n        export function index(context) {\r\n        \r\n            //context.attribute\r\n            //{\r\n            //    \"a\": 10,\r\n            //    \"b\": 20,\r\n            //    \"c\": 30,\r\n\t\t\t//    \"d\": 40\r\n            //}\r\n\r\n            context.response.json( context.attribute );       \r\n        }\r\n    }\r\n}\r\n\r\n```\r\n\r\n<a name=\"http_verbs\" />\r\n### http verbs\r\n\r\nappex handles http verb matching with cascades. appex will recognise the \r\n'verbs' property applied to the cascade to match against http verbs.\r\n\r\n```javascript\r\ncascade('index', { verbs: ['get'] })\r\nexport function index (context) { \r\n        \r\n    // only allow HTTP GET requests\r\n    context.response.send('index')\r\n}\r\n\r\ncascade('index', { verbs: ['post', 'put'] })\r\nexport function submit (context) { \r\n    \r\n    // only allow HTTP POST and PUT requests\r\n    context.response.send('submit')\r\n}\r\n```\r\n\r\n\r\n<a name=\"middleware\" />\r\n### middleware\r\n\r\nappex supports middleware with cascades. appex middleware defined with cascades allows\r\ndevelopers to scope middleware on single functions, or entire module scopes. appex will \r\nrecognise the 'use' property applied to the cascade to invoke middleware.\r\n\r\nthe following demonstrates how one might use middleware to secure a site admin.\r\n\r\nnote: middleware 'must' call next or handle the request. \r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ndeclare var console;\r\n\r\nfunction authenticate(context) {\r\n\r\n    console.log('authenticate')\r\n\r\n\t// call next() if authenticated, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\nfunction authorize(context) {\r\n\r\n    console.log('authorize')\r\n\r\n\t// call next() if authorized, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\n// apply security middleware to admin scope.\r\ncascade('admin', {use: [authenticate, authorize]}) \r\nexport module admin {\r\n\r\n    export function index(context) {\r\n        \r\n        console.log(context.cascade); // view cascade\r\n\r\n        context.response.send('access granted!')\r\n    }\r\n}\r\n\r\n// index handler has no middleware applied.\r\nexport function index (context) { \r\n    \r\n    console.log(context.cascade); // view cascade\r\n\r\n    context.response.send('home')\r\n}\r\n```\r\n\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex will only route functions prefix with the TypeScript 'export' declarer. This rule\r\nalso applied to modules. Developers can use this to infer notions of public and private \r\nat the http level.\r\n\r\nconsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.send('public_function');\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```javascript\r\n// http:[host]:[port]/\r\nexport function index (context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard (context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n<a name=\"serving_static_files\" />\r\n## serving static files\r\n\r\nUse wildcard functions with context.response.serve() to serve static content.\r\n\r\n```javascript\r\nexport module static {\r\n\t\r\n\t// http:[host]:[port]/static/(.*)\r\n\texport function wildcard(context, path) {\r\n\r\n\t\tcontext.response.serve('./static/', path);\r\n\t}\r\n}\r\n\r\n// http:[host]:[port]/\r\nexport function index (context) {\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\nThis outlines development with appex.\r\n\r\n<a name=\"appex_declaration\" />\r\n### appex.d.ts declaration\r\n\r\nIf you develop on a TypeScript complicant editor (one that supports TS 0.9), appex comes bundled\r\nwith a declaration file you can reference in your project. If installing appex via npm, your\r\nreference should be as follows.\r\n\r\n```javascript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nexport function index (context:appex.web.IContext) { \r\n    \r\n    context.response.send('hello');\r\n}\r\n\r\nexport function wildcard(context:appex.web.IContext, path:string) {\r\n\r\n    context.response.serve('./', path);\r\n}\r\n```\r\n\r\nBy referencing this in your project, you get the benefits of code completion and static type checking\r\nagainst both appex, and the nodejs core.\r\n\r\n![](https://raw.github.com/sinclairzx81/appex/master/artifacts/code-completion.jpg)\r\n\r\nAdditional declaration files may be obtained from [here](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex ({ program : './index.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"users.ts\" />\r\n/// <reference path=\"pages.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { context.response.send('users.login') }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { context.response.send('users.logout') }\r\n}\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { context.response.send('home') }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { context.response.send('about') }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { context.response.send('contact') }\r\n\r\nexport function wildcard (context, path) { context.response.send(404, ' not found') }\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"http://www.apache.org/licenses/LICENSE-2.0.html","type":"Apache 2.0"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"nodejs web api with typescript","directories":{},"dependencies":{"typescript.api":"0.5.5"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.4.2":{"name":"appex","version":"0.4.2","keywords":["typescript","web api","reflection","compiler"],"author":{"name":"sinclair"},"_id":"appex@0.4.2","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"b394970a56fecd84063fc8d7af4cc2c6786556b7","tarball":"https://registry.npmjs.org/appex/-/appex-0.4.2.tgz","integrity":"sha512-6U3XdRJKwuj1tJgKnyeWZpTIOnjgJaqMfSomJEveFeE4szmOHlHPj3QRTYI3mymn9Zfrz/7HVdj/wCQKxqQGBw==","signatures":[{"sig":"MEUCIFtVwgd5U/rOHQo4GQmRIiGwGVjUPEAjpm5aXdI8c8mpAiEA4yXt6Fe2iYGi4IKlYa0+c08qBiq3nvXV//kDGHe0yok=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/artifacts/logo.jpg)\r\n\r\n### nodejs web api with [typescript](http://www.typescriptlang.org/)\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http://localhost:3000/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// http://localhost:3000/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about');\r\n}\r\n\r\n// http://localhost:3000/(.*)\r\nexport function wildcard (context, path) {\r\n    \r\n    context.response.send(404, path + \"not found\");\r\n}\r\n\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n## overview\r\n\r\nappex is a nodejs web api framework built on top of the TypeScript programming language. It enables\r\ndevelopers to create RESTful service endpoints by writing TypeScript functions, as well as providing\r\nreflection / type meta data derived from the languages type system.\r\n\r\n* [getting started](#getting_started)\r\n\t* [application](#application)\r\n\t* [options](#options)\r\n\t* [http server](#http_server)\r\n\t* [express middleware](#express_middleware)\r\n* [creating services with typescript](#creating_services)\r\n\t* [app context](#app_context)\r\n\t* [routing handlers](#routing_handlers)\r\n\t* [handler signatures](#handler_signatures)\r\n\t* [named handlers](#named_handlers)\r\n\t* [index handlers](#index_handlers)\r\n\t* [wildcard handlers](#wildcard_handlers)\r\n\t* [cascades](#cascades)\r\n\t* [http verbs](#http_verbs)\r\n\t* [middleware](#middleware)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [handling 404](#handling_404)\r\n\t* [serving static files](#serving_static_files)\r\n* [reflection](#reflection)\r\n\t* [reflect everything](#reflect_everything)\r\n\t* [reflect specific types](#reflect_specific_types)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [appex.d.ts declaration](#appex_declaration)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline configuring appex.\r\n\r\n<a name=\"application\" />\r\n### application\r\n\r\nSetting up. \r\n\r\n```javascript\r\nvar appex   = require('appex');\r\n\r\nvar app   = appex({ program : './program.ts', \r\n                    devmode : true,\r\n                    logging : true });\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"options\" />\r\n### options\r\n\r\nappex accepts the following startup options.\r\n\r\n```javascript\r\nvar options = { \r\n\t// (required) location of source file.\r\n\tprogram    : './program.ts', \r\n\r\n\t// (optional) recompile on request. (default:false) \r\n\tdevmode    : true,          \r\n\r\n\t// (optional) log to stdout. (default:false) \r\n\tlogging    : true,\r\n\r\n\t// (optional) user defined objects added to the app context.\r\n\tcontext    : {}\r\n};\r\n\r\nvar app = appex( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### http server\r\n\r\nSetting up appex on a nodejs http server.\r\n\r\n```javascript\r\nvar http = require('http');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\nvar server = http.createServer( app );\r\n\r\nserver.listen(3000);\r\n```\r\n<a name=\"express_middleware\" />\r\n### express middleware\r\n\r\nSetting up as express middleware.\r\n\r\n```javascript\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use(appex({ program : './program.ts' })); \r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"creating_services\" />\r\n## creating services with typescript\r\n\r\nThe following section describes how to write http accessible functions with appex.\r\n\r\n<a name=\"app_context\" />\r\n### app context\r\n\r\nAll appex functions are passed a application context object as their first argument. The app context object \r\nencapulates the http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the app context\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.cascade    - appex cascade.\r\n\r\n\t// context.next       - the next function (express middleware)\r\n}\r\n```\r\n\r\n<a name=\"routing_handlers\" />\r\n### routing handlers\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context) { /* handle route */ }\r\n}\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/(.*)\r\nexport function wildcard (context, path) { /* handle route */ }\r\n\r\n```\r\n\r\n<a name=\"handler_signatures\" />\r\n### handler signatures\r\n\r\nappex supports three function signatures for http routing (named, index and wildcard). Functions that\r\ndo not apply these signatures will not be routed.\r\n\r\n<a name=\"named_handlers\" />\r\n### named handlers\r\n\r\nNamed handlers resolve urls to their current module scope + the name of the function.\r\n\r\nNamed handlers require the following signature:\r\n\r\n* name        - 'anything'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n\r\n// http://[host]:[port]/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about page');\r\n}\r\n\r\n// http://[host]:[port]/users/login\r\nexport module users {\r\n\r\n\texport function login(context) {\r\n\t\t\r\n\t\tcontext.response.send('handle login');\t\r\n\t}\r\n}\r\n\r\n```\r\n\r\n<a name=\"index_handlers\" />\r\n### index handlers\r\n\r\nIndex handlers resolve urls to their current module scope.\r\n\r\nIndex handlers require the following signature:\r\n\r\n* name        - 'index'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) \r\n\t{\t\r\n\t\tcontext.response.send('blog index');\r\n\t}\r\n}\r\n```\r\n\r\n<a name=\"wildcard_handlers\" />\r\n### wildcard handlers\r\n\r\nWildcard handlers resolve their urls to their current module scope + url.\r\n\r\nappex wildcard handlers allow for wildcard routing at a given module scope. Wildcard handlers\r\nsupport 'typed' url argument mapping, as denoted by the arguments annotation.\r\n\r\nIn addition, wildcard handlers also support optional arguments which can be specified with TypeScript's '?' \r\non argument names.\r\n\r\nappex wildcard handlers require the following signature:\r\n\r\n* name        - 'wildcard'\r\n* argument[0] - app context\r\n* argument[n] - 1 or more arguments to be mapped from the url\r\n* returns     - void (optional)\r\n\r\n```javascript\r\ndeclare var console;\r\n\r\nexport module blogs {\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11   - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/11  - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/3rd - not matched - (see number annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01     - matched     - (see ? annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013        - not matched - (month is required)\r\n\t\r\n    export function wildcard(context, year:number, month:number, day?:number) {\r\n\r\n        context.response.json({ year: year, month: month, day: day})\r\n    }\r\n}\r\n\r\n// url : http://[host]:[port]/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// url : http://[host]:[port]/(.*) \r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, 'not found');\r\n}\r\n\r\n```\r\nnote: appex supports boolean, number, string and any annotations on wildcard arguments. if no annotation\r\nis specified, appex interprets the argument as a string. the type 'any' is also interpreted as string.\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"cascades\" />\r\n### cascades\r\n\r\nappex supports a cascading attribute scheme on modules and functions. With this, developers can apply\r\narbituary meta data for modules and functions that will propagate through scope. appex has two special\r\ncascade properties for middleware and http verb matching, which are described below, however consider\r\nthe following code which illustrates the concept.\r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ncascade({a: 10}); // global.\r\n\r\ncascade('foo', {b : 20})\r\nexport module foo {\r\n\r\n    cascade('foo.bar', {c : 30})\r\n    export module bar {\r\n            \r\n        cascade('foo.bar.index', {d : 40})\r\n        export function index(context) {\r\n        \r\n            //context.cascade\r\n            //{\r\n            //    \"a\": 10,\r\n            //    \"b\": 20,\r\n            //    \"c\": 30,\r\n\t\t\t//    \"d\": 40\r\n            //}\r\n\r\n            context.response.json( context.cascade );       \r\n        }\r\n    }\r\n}\r\n\r\n```\r\n\r\n<a name=\"http_verbs\" />\r\n### http verbs\r\n\r\nappex handles http verb matching with cascades. appex will recognise the \r\n'verbs' property applied to the cascade to match against http verbs.\r\n\r\n```javascript\r\ncascade('index', { verbs: ['get'] })\r\nexport function index (context) { \r\n        \r\n    // only allow HTTP GET requests\r\n    context.response.send('index')\r\n}\r\n\r\ncascade('index', { verbs: ['post', 'put'] })\r\nexport function submit (context) { \r\n    \r\n    // only allow HTTP POST and PUT requests\r\n    context.response.send('submit')\r\n}\r\n```\r\n\r\n\r\n<a name=\"middleware\" />\r\n### middleware\r\n\r\nappex supports middleware with cascades. appex middleware defined with cascades allows\r\ndevelopers to scope middleware on single functions, or entire module scopes. appex will \r\nrecognise the 'use' property applied to the cascade to invoke middleware.\r\n\r\nthe following demonstrates how one might use middleware to secure a site admin.\r\n\r\nnote: middleware 'must' call next or handle the request. \r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ndeclare var console;\r\n\r\nfunction authenticate(context) {\r\n\r\n    console.log('authenticate')\r\n\r\n\t// call next() if authenticated, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\nfunction authorize(context) {\r\n\r\n    console.log('authorize')\r\n\r\n\t// call next() if authorized, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\n// apply security middleware to admin scope.\r\ncascade('admin', {use: [authenticate, authorize]}) \r\nexport module admin {\r\n\r\n    export function index(context) {\r\n        \r\n        console.log(context.cascade); // view cascade\r\n\r\n        context.response.send('access granted!')\r\n    }\r\n}\r\n\r\n// index handler has no middleware applied.\r\nexport function index (context) { \r\n    \r\n    console.log(context.cascade); // view cascade\r\n\r\n    context.response.send('home')\r\n}\r\n```\r\n\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex will only route functions prefix with the TypeScript 'export' declarer. This rule\r\nalso applied to modules. Developers can use this to infer notions of public and private \r\nat the http level.\r\n\r\nconsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.send('public_function');\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```javascript\r\n// http:[host]:[port]/\r\nexport function index (context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard (context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n<a name=\"serving_static_files\" />\r\n## serving static files\r\n\r\nUse wildcard functions with context.response.serve() to serve static content.\r\n\r\n```javascript\r\nexport module static {\r\n\t\r\n\t// http:[host]:[port]/static/(.*)\r\n\texport function wildcard(context, path) {\r\n\r\n\t\tcontext.response.serve('./static/', path);\r\n\t}\r\n}\r\n\r\n// http:[host]:[port]/\r\nexport function index (context) {\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n\r\n<a name=\"reflection\" />\r\n## reflection\r\n\r\nappex provides a reflection api derived from TypeScript's type system that developers can \r\nleverage to reflect type information declared throughout their appex modules. \r\n\r\nthe following section outlines how to use the reflection api.\r\n\r\n<a name=\"reflect_everything\" />\r\n### reflect everything\r\n\r\nthe appex reflection api is passed on the context.module.reflection property and is available to all\r\nappex handler methods. The following code will JSON serialize everything declared in your appex\r\nproject and write it to the http response. \r\n\r\n```javascript\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection );\r\n}\r\n```\r\n<a name=\"reflect_specific_types\" />\r\n### reflect specific types\r\n\r\nIn typical scenarios, developers will want to leverage reflection meta data to generate\r\nservice contacts and client side models. the reflection api lets you access meta data \r\nfor the following types declared in your project. \r\n\r\n* modules\r\n* imports\r\n* classes\r\n* interfaces\r\n* functions\r\n* variables\r\n\r\nto access specific type metadata, use the reflection.get([qualifier]) method, as demonstrated below.\r\n\r\n```javascript\r\nexport module models {\r\n    \r\n    export class Customer {\r\n\r\n        public firstname   : string;\r\n\r\n        public lastname    : string;\r\n\r\n        public age         : number;\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('models.Customer') );\r\n}\r\n```\r\nand methods..\r\n\r\n```javascript\r\nfunction some_method(a:string, b:number, c?:boolean) : void { }\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_method') );\r\n}\r\n```\r\n\r\n....and variables...\r\n\r\n```javascript\r\nvar some_variable:number = 10;\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_variable') );\r\n}\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\nThis section outlines development with appex.\r\n\r\n<a name=\"appex_declaration\" />\r\n### appex.d.ts declaration\r\n\r\nIf you develop on a TypeScript complicant editor (one that supports TS 0.9), appex comes bundled\r\nwith a declaration file you can reference in your project. If installing appex via npm, your\r\nreference should be as follows.\r\n\r\n```javascript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nexport function index (context:appex.web.IContext) { \r\n    \r\n    context.response.send('hello');\r\n}\r\n\r\nexport function wildcard(context:appex.web.IContext, path:string) {\r\n\r\n    context.response.serve('./', path);\r\n}\r\n```\r\n\r\nBy referencing this in your project, you get the benefits of code completion and static type checking\r\nagainst both appex, and the nodejs core.\r\n\r\n![](https://raw.github.com/sinclairzx81/appex/master/artifacts/code-completion.jpg)\r\n\r\nAdditional declaration files may be obtained from [here](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex ({ program : './index.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"users.ts\" />\r\n/// <reference path=\"pages.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { context.response.send('users.login') }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { context.response.send('users.logout') }\r\n}\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { context.response.send('home') }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { context.response.send('about') }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { context.response.send('contact') }\r\n\r\nexport function wildcard (context, path) { context.response.send(404, ' not found') }\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"http://www.apache.org/licenses/LICENSE-2.0.html","type":"Apache 2.0"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"nodejs web api with typescript","directories":{},"dependencies":{"typescript.api":"0.5.5"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.4.3":{"name":"appex","version":"0.4.3","keywords":["typescript","web api","reflection","compiler"],"author":{"name":"sinclair"},"_id":"appex@0.4.3","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"415f2fa1c61b1539e0b29fa35cc5bf669e553b04","tarball":"https://registry.npmjs.org/appex/-/appex-0.4.3.tgz","integrity":"sha512-WlOxg82PMcOu1wBtGrRwtP+NJIhdpXCVKF8dgqd7sQ/Mus7gKIo8l4c4iE4dN3Cr1gmklOtukAqQm1ei6idaRg==","signatures":[{"sig":"MEUCIQDhl5+Mm17WTnP/u2f9aFz/x91IYNRBXpjwHaQ3VHfwawIgFjDfDcxonez7CBg6qowXmcHo2Pwpx/KGSTGKqD3vUKs=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/artifacts/logo.jpg)\r\n\r\n### nodejs web api with [typescript](http://www.typescriptlang.org/)\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http://localhost:3000/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// http://localhost:3000/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about');\r\n}\r\n\r\n// http://localhost:3000/(.*)\r\nexport function wildcard (context, path) {\r\n    \r\n    context.response.send(404, path + \"not found\");\r\n}\r\n\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n## overview\r\n\r\nappex is a nodejs web api framework built on top of the TypeScript programming language. It enables\r\ndevelopers to create RESTful service endpoints by writing TypeScript functions, as well as providing\r\nreflection / type meta data derived from the languages type system.\r\n\r\n* [getting started](#getting_started)\r\n\t* [application](#application)\r\n\t* [options](#options)\r\n\t* [http server](#http_server)\r\n\t* [express middleware](#express_middleware)\r\n* [creating services with typescript](#creating_services)\r\n\t* [app context](#app_context)\r\n\t* [routing handlers](#routing_handlers)\r\n\t* [handler signatures](#handler_signatures)\r\n\t* [named handlers](#named_handlers)\r\n\t* [index handlers](#index_handlers)\r\n\t* [wildcard handlers](#wildcard_handlers)\r\n\t* [cascades](#cascades)\r\n\t* [http verbs](#http_verbs)\r\n\t* [middleware](#middleware)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [handling 404](#handling_404)\r\n\t* [serving static files](#serving_static_files)\r\n* [reflection](#reflection)\r\n\t* [reflect everything](#reflect_everything)\r\n\t* [reflect specific types](#reflect_specific_types)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [appex.d.ts declaration](#appex_declaration)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n* [license](#license)\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline configuring appex.\r\n\r\n<a name=\"application\" />\r\n### application\r\n\r\nSetting up. \r\n\r\n```javascript\r\nvar appex   = require('appex');\r\n\r\nvar app   = appex({ program : './program.ts', \r\n                    devmode : true,\r\n                    logging : true });\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"options\" />\r\n### options\r\n\r\nappex accepts the following startup options.\r\n\r\n```javascript\r\nvar options = { \r\n\t// (required) location of source file.\r\n\tprogram    : './program.ts', \r\n\r\n\t// (optional) recompile on request. (default:false) \r\n\tdevmode    : true,          \r\n\r\n\t// (optional) log to stdout. (default:false) \r\n\tlogging    : true,\r\n\r\n\t// (optional) user defined objects added to the app context.\r\n\tcontext    : {}\r\n};\r\n\r\nvar app = appex( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### http server\r\n\r\nSetting up appex on a nodejs http server.\r\n\r\n```javascript\r\nvar http = require('http');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\nvar server = http.createServer( app );\r\n\r\nserver.listen(3000);\r\n```\r\n<a name=\"express_middleware\" />\r\n### express middleware\r\n\r\nappex can run as express middleware. By running appex in this context, it will attempt to match incoming routes. if\r\nnot matched, appex will pass the request on for express handle.\r\n\r\n```javascript\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) ); \r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\nin addition, appex will inheritate the characteristics of existing middleware. consider the following example\r\nwhich defines the express.bodyParser(), which is passed onto the context.request object.\r\n\r\n```javascript\r\n\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar app = express();\r\n\r\napp.configure(function(){\r\n\r\n  app.set('port', process.env.PORT || 3232);\r\n\r\n  app.set('views', __dirname + '/views');\r\n\r\n  app.set('view engine', 'jade');\r\n\r\n  app.use(express.bodyParser());\r\n\r\n  app.use( appex({program:'./program.ts', devmode:true} ));  // inheriates bodyParser().  \r\n\r\n  app.use(app.router);\r\n\r\n  app.use(express.static(path.join(__dirname, 'public')));\r\n});\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n\t//context.request.body <-- available on the context.\r\n\t\r\n\tcontext.response.send('home'); // the express send method.\r\n}\r\n```\r\n\r\n<a name=\"creating_services\" />\r\n## creating services with typescript\r\n\r\nThe following section describes how to write http accessible functions with appex.\r\n\r\n<a name=\"app_context\" />\r\n### app context\r\n\r\nAll appex functions are passed a application context object as their first argument. The app context object \r\nencapulates the http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the app context\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.cascade    - appex cascade.\r\n\r\n\t// context.next       - the next function (express middleware)\r\n\t\r\n\t// context.router     - the appex router\r\n\t\r\n\t// context.module     - the module being run (this module)\r\n\r\n\t// context.mime       - a http mime type utility.\r\n}\r\n```\r\n\r\nit is possible to extend the default objects passed on the context by adding them on the appex startup options. The \r\nfollowing will attach the async module to the context. \r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = appex({ program : './program.ts', \r\n\t\t\t\t  devmode : true, \r\n\t\t\t      context: {\r\n\t\t\t\t\t\tasync : require('async')\r\n\t\t\t\t  }});\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\r\n\t// context.async = passed on the context.\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n```\r\n<a name=\"routing_handlers\" />\r\n### routing handlers\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context) { /* handle route */ }\r\n}\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/(.*)\r\nexport function wildcard (context, path) { /* handle route */ }\r\n\r\n```\r\n\r\n<a name=\"handler_signatures\" />\r\n### handler signatures\r\n\r\nappex supports three function signatures for http routing (named, index and wildcard). Functions that\r\ndo not apply these signatures will not be routed.\r\n\r\n<a name=\"named_handlers\" />\r\n### named handlers\r\n\r\nNamed handlers resolve urls to their current module scope + the name of the function.\r\n\r\nNamed handlers require the following signature:\r\n\r\n* name        - 'anything'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n\r\n// http://[host]:[port]/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about page');\r\n}\r\n\r\n// http://[host]:[port]/users/login\r\nexport module users {\r\n\r\n\texport function login(context) {\r\n\t\t\r\n\t\tcontext.response.send('handle login');\t\r\n\t}\r\n}\r\n\r\n```\r\n\r\n<a name=\"index_handlers\" />\r\n### index handlers\r\n\r\nIndex handlers resolve urls to their current module scope.\r\n\r\nIndex handlers require the following signature:\r\n\r\n* name        - 'index'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) \r\n\t{\t\r\n\t\tcontext.response.send('blog index');\r\n\t}\r\n}\r\n```\r\n\r\n<a name=\"wildcard_handlers\" />\r\n### wildcard handlers\r\n\r\nWildcard handlers resolve their urls to their current module scope + url.\r\n\r\nappex wildcard handlers allow for wildcard routing at a given module scope. Wildcard handlers\r\nsupport 'typed' url argument mapping, as denoted by the arguments annotation.\r\n\r\nIn addition, wildcard handlers also support optional arguments which can be specified with TypeScript's '?' \r\non argument names.\r\n\r\nappex wildcard handlers require the following signature:\r\n\r\n* name        - 'wildcard'\r\n* argument[0] - app context\r\n* argument[n] - 1 or more arguments to be mapped from the url\r\n* returns     - void (optional)\r\n\r\n```javascript\r\ndeclare var console;\r\n\r\nexport module blogs {\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11   - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/11  - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/3rd - not matched - (see number annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01     - matched     - (see ? annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013        - not matched - (month is required)\r\n\t\r\n    export function wildcard(context, year:number, month:number, day?:number) {\r\n\r\n        context.response.json({ year: year, month: month, day: day})\r\n    }\r\n}\r\n\r\n// url : http://[host]:[port]/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// url : http://[host]:[port]/(.*) \r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, 'not found');\r\n}\r\n\r\n```\r\nnote: appex supports boolean, number, string and any annotations on wildcard arguments. if no annotation\r\nis specified, appex interprets the argument as a string. the type 'any' is also interpreted as string.\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"cascades\" />\r\n### cascades\r\n\r\nappex supports a cascading attribute scheme on modules and functions. With this, developers can apply\r\narbituary meta data for modules and functions that will propagate through scope. appex has two special\r\ncascade properties for middleware and http verb matching, which are described below, however consider\r\nthe following code which illustrates the concept.\r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ncascade({a: 10}); // global.\r\n\r\ncascade('foo', {b : 20})\r\nexport module foo {\r\n\r\n    cascade('foo.bar', {c : 30})\r\n    export module bar {\r\n            \r\n        cascade('foo.bar.index', {d : 40})\r\n        export function index(context) {\r\n        \r\n            //context.cascade\r\n            //{\r\n            //    \"a\": 10,\r\n            //    \"b\": 20,\r\n            //    \"c\": 30,\r\n\t\t\t//    \"d\": 40\r\n            //}\r\n\r\n            context.response.json( context.cascade );       \r\n        }\r\n    }\r\n}\r\n\r\n```\r\n\r\n<a name=\"http_verbs\" />\r\n### http verbs\r\n\r\nappex handles http verb matching with cascades. appex will recognise the \r\n'verbs' property applied to the cascade to match against http verbs.\r\n\r\n```javascript\r\ncascade('index', { verbs: ['get'] })\r\nexport function index (context) { \r\n        \r\n    // only allow HTTP GET requests\r\n    context.response.send('index')\r\n}\r\n\r\ncascade('index', { verbs: ['post', 'put'] })\r\nexport function submit (context) { \r\n    \r\n    // only allow HTTP POST and PUT requests\r\n    context.response.send('submit')\r\n}\r\n```\r\n\r\n\r\n<a name=\"middleware\" />\r\n### middleware\r\n\r\nappex supports middleware with cascades. appex middleware defined with cascades allows\r\ndevelopers to scope middleware on single functions, or entire module scopes. appex will \r\nrecognise the 'use' property applied to the cascade to invoke middleware.\r\n\r\nthe following demonstrates how one might use middleware to secure a site admin.\r\n\r\nnote: middleware 'must' call next or handle the request. \r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ndeclare var console;\r\n\r\nfunction authenticate(context) {\r\n\r\n    console.log('authenticate')\r\n\r\n\t// call next() if authenticated, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\nfunction authorize(context) {\r\n\r\n    console.log('authorize')\r\n\r\n\t// call next() if authorized, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\n// apply security middleware to admin scope.\r\ncascade('admin', {use: [authenticate, authorize]}) \r\nexport module admin {\r\n\r\n    export function index(context) {\r\n        \r\n        console.log(context.cascade); // view cascade\r\n\r\n        context.response.send('access granted!')\r\n    }\r\n}\r\n\r\n// index handler has no middleware applied.\r\nexport function index (context) { \r\n    \r\n    console.log(context.cascade); // view cascade\r\n\r\n    context.response.send('home')\r\n}\r\n```\r\n\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex will only route functions prefix with the TypeScript 'export' declarer. This rule\r\nalso applied to modules. Developers can use this to infer notions of public and private \r\nat the http level.\r\n\r\nconsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.send('public_function');\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```javascript\r\n// http:[host]:[port]/\r\nexport function index (context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard (context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n<a name=\"serving_static_files\" />\r\n## serving static files\r\n\r\nUse wildcard functions with context.response.serve() to serve static content.\r\n\r\n```javascript\r\nexport module static {\r\n\t\r\n\t// http:[host]:[port]/static/(.*)\r\n\texport function wildcard(context, path) {\r\n\r\n\t\tcontext.response.serve('./static/', path);\r\n\t}\r\n}\r\n\r\n// http:[host]:[port]/\r\nexport function index (context) {\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n\r\n<a name=\"reflection\" />\r\n## reflection\r\n\r\nappex provides a reflection api derived from TypeScript's type system that developers can \r\nleverage to reflect type information declared throughout their appex modules. \r\n\r\nthe following section outlines how to use the reflection api.\r\n\r\n<a name=\"reflect_everything\" />\r\n### reflect everything\r\n\r\nthe appex reflection api is passed on the context.module.reflection property and is available to all\r\nappex handler methods. The following code will JSON serialize everything declared in your appex\r\nproject and write it to the http response. \r\n\r\n```javascript\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection );\r\n}\r\n```\r\n<a name=\"reflect_specific_types\" />\r\n### reflect specific types\r\n\r\nIn typical scenarios, developers will want to leverage reflection meta data to generate\r\nservice contacts and client side models. the reflection api lets you access meta data \r\nfor the following types declared in your project. \r\n\r\n* modules\r\n* imports\r\n* classes\r\n* interfaces\r\n* functions\r\n* variables\r\n\r\nto access specific type metadata, use the reflection.get([qualifier]) method, as demonstrated below.\r\n\r\n```javascript\r\nexport module models {\r\n    \r\n    export class Customer {\r\n\r\n        public firstname   : string;\r\n\r\n        public lastname    : string;\r\n\r\n        public age         : number;\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('models.Customer') );\r\n}\r\n```\r\nand methods..\r\n\r\n```javascript\r\nfunction some_method(a:string, b:number, c?:boolean) : void { }\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_method') );\r\n}\r\n```\r\n\r\n....and variables...\r\n\r\n```javascript\r\nvar some_variable:number = 10;\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_variable') );\r\n}\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\nThis section outlines development with appex.\r\n\r\n<a name=\"appex_declaration\" />\r\n### appex.d.ts declaration\r\n\r\nIf you develop on a TypeScript complicant editor (one that supports TS 0.9), appex comes bundled\r\nwith a declaration file you can reference in your project. If installing appex via npm, your\r\nreference should be as follows.\r\n\r\n```javascript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nexport function index (context:appex.web.IContext) { \r\n    \r\n    context.response.send('hello');\r\n}\r\n\r\nexport function wildcard(context:appex.web.IContext, path:string) {\r\n\r\n    context.response.serve('./', path);\r\n}\r\n```\r\n\r\nBy referencing this in your project, you get the benefits of code completion and static type checking\r\nagainst both appex, and the nodejs core.\r\n\r\n![](https://raw.github.com/sinclairzx81/appex/master/artifacts/code-completion.jpg)\r\n\r\nAdditional declaration files may be obtained from [here](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex ({ program : './index.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"users.ts\" />\r\n/// <reference path=\"pages.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { context.response.send('users.login') }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { context.response.send('users.logout') }\r\n}\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { context.response.send('home') }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { context.response.send('about') }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { context.response.send('contact') }\r\n\r\nexport function wildcard (context, path) { context.response.send(404, ' not found') }\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"license\" />\r\n## license\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) 2013 Haydn Paterson (sinclair) <haydn.developer@gmail.com>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in\r\nall copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\nTHE SOFTWARE.\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"https://raw.github.com/sinclairzx81/appex/master/license.txt","type":"The MIT License (MIT)"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"nodejs web api with typescript","directories":{},"dependencies":{"typescript.api":"0.5.5"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.4.4":{"name":"appex","version":"0.4.4","keywords":["typescript","web api","reflection","compiler"],"author":{"name":"sinclair"},"_id":"appex@0.4.4","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"8babdef36e459256a8959e6496d65928f801509a","tarball":"https://registry.npmjs.org/appex/-/appex-0.4.4.tgz","integrity":"sha512-fXvQA5nFuetv0JhQ78jjdsCNnLha7H5jIqu+ln1Cfhd9ZoDs8xKCAKtBjwDGiUUdQl4Zi5M/3wQofpB9tHCyVg==","signatures":[{"sig":"MEUCIQCBMLQnS6M/qnOKzySCkWf41KTyK3dVEPW/S1nWHy1Z2wIgOlfaRo4q9gRtjA24RnJPQY5hg6ygzW9RZigoX1+9I9Y=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/artifacts/logo.jpg)\r\n\r\n### nodejs web api with [typescript](http://www.typescriptlang.org/)\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http://localhost:3000/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// http://localhost:3000/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about');\r\n}\r\n\r\n// http://localhost:3000/(.*)\r\nexport function wildcard (context, path) {\r\n    \r\n    context.response.send(404, path + \"not found\");\r\n}\r\n\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n## overview\r\n\r\nappex is a nodejs web api framework built on top of the TypeScript programming language. It enables\r\ndevelopers to create RESTful service endpoints by writing TypeScript functions, as well as providing\r\nreflection / type meta data derived from the languages type system.\r\n\r\n* [getting started](#getting_started)\r\n\t* [application](#application)\r\n\t* [options](#options)\r\n\t* [http server](#http_server)\r\n\t* [express middleware](#express_middleware)\r\n* [creating services with typescript](#creating_services)\r\n\t* [app context](#app_context)\r\n\t* [routing handlers](#routing_handlers)\r\n\t* [handler signatures](#handler_signatures)\r\n\t* [named handlers](#named_handlers)\r\n\t* [index handlers](#index_handlers)\r\n\t* [wildcard handlers](#wildcard_handlers)\r\n\t* [cascades](#cascades)\r\n\t* [http verbs](#http_verbs)\r\n\t* [middleware](#middleware)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [handling 404](#handling_404)\r\n\t* [serving static files](#serving_static_files)\r\n* [reflection](#reflection)\r\n\t* [reflect everything](#reflect_everything)\r\n\t* [reflect specific types](#reflect_specific_types)\r\n\t* [json schema](#json_schema)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [appex.d.ts declaration](#appex_declaration)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n* [license](#license)\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline configuring appex.\r\n\r\n<a name=\"application\" />\r\n### application\r\n\r\nSetting up. \r\n\r\n```javascript\r\nvar appex   = require('appex');\r\n\r\nvar app   = appex({ program : './program.ts', \r\n                    devmode : true,\r\n                    logging : true });\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"options\" />\r\n### options\r\n\r\nappex accepts the following startup options.\r\n\r\n```javascript\r\nvar options = { \r\n\t// (required) location of source file.\r\n\tprogram    : './program.ts', \r\n\r\n\t// (optional) recompile on request. (default:false) \r\n\tdevmode    : true,          \r\n\r\n\t// (optional) log to stdout. (default:false) \r\n\tlogging    : true,\r\n\r\n\t// (optional) user defined objects added to the app context.\r\n\tcontext    : {}\r\n};\r\n\r\nvar app = appex( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### http server\r\n\r\nSetting up appex on a nodejs http server.\r\n\r\n```javascript\r\nvar http = require('http');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\nvar server = http.createServer( app );\r\n\r\nserver.listen(3000);\r\n```\r\n<a name=\"express_middleware\" />\r\n### express middleware\r\n\r\nappex can run as express middleware. By running appex in this context, it will attempt to match incoming routes. if\r\nnot matched, appex will pass the request on for express handle.\r\n\r\n```javascript\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) ); \r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\nin addition, appex will inheritate the characteristics of existing middleware. consider the following example\r\nwhich defines the express.bodyParser(), which is passed onto the context.request object.\r\n\r\n```javascript\r\n\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar app = express();\r\n\r\napp.configure(function(){\r\n\r\n  app.set('port', process.env.PORT || 3232);\r\n\r\n  app.set('views', __dirname + '/views');\r\n\r\n  app.set('view engine', 'jade');\r\n\r\n  app.use(express.bodyParser());\r\n\r\n  app.use( appex({program:'./program.ts', devmode:true} ));  // inheriates bodyParser().  \r\n\r\n  app.use(app.router);\r\n\r\n  app.use(express.static(path.join(__dirname, 'public')));\r\n});\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n\t//context.request.body <-- available on the context.\r\n\t\r\n\tcontext.response.send('home'); // the express send method.\r\n}\r\n```\r\n\r\n<a name=\"creating_services\" />\r\n## creating services with typescript\r\n\r\nThe following section describes how to write http accessible functions with appex.\r\n\r\n<a name=\"app_context\" />\r\n### app context\r\n\r\nAll appex functions are passed a application context object as their first argument. The app context object \r\nencapulates the http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the app context\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.cascade    - appex cascade.\r\n\r\n\t// context.next       - the next function (express middleware)\r\n\t\r\n\t// context.router     - the appex router\r\n\t\r\n\t// context.module     - the module being run (this module)\r\n\r\n\t// context.mime       - a http mime type utility.\r\n}\r\n```\r\n\r\nit is possible to extend the default objects passed on the context by adding them on the appex startup options. The \r\nfollowing will attach the async module to the context. \r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = appex({ program : './program.ts', \r\n\t\t\t\t  devmode : true, \r\n\t\t\t      context: {\r\n\t\t\t\t\t\tasync : require('async')\r\n\t\t\t\t  }});\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\r\n\t// context.async = passed on the context.\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n```\r\n<a name=\"routing_handlers\" />\r\n### routing handlers\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context) { /* handle route */ }\r\n}\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/(.*)\r\nexport function wildcard (context, path) { /* handle route */ }\r\n\r\n```\r\n\r\n<a name=\"handler_signatures\" />\r\n### handler signatures\r\n\r\nappex supports three function signatures for http routing (named, index and wildcard). Functions that\r\ndo not apply these signatures will not be routed.\r\n\r\n<a name=\"named_handlers\" />\r\n### named handlers\r\n\r\nNamed handlers resolve urls to their current module scope + the name of the function.\r\n\r\nNamed handlers require the following signature:\r\n\r\n* name        - 'anything'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n\r\n// http://[host]:[port]/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about page');\r\n}\r\n\r\n// http://[host]:[port]/users/login\r\nexport module users {\r\n\r\n\texport function login(context) {\r\n\t\t\r\n\t\tcontext.response.send('handle login');\t\r\n\t}\r\n}\r\n\r\n```\r\n\r\n<a name=\"index_handlers\" />\r\n### index handlers\r\n\r\nIndex handlers resolve urls to their current module scope.\r\n\r\nIndex handlers require the following signature:\r\n\r\n* name        - 'index'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) \r\n\t{\t\r\n\t\tcontext.response.send('blog index');\r\n\t}\r\n}\r\n```\r\n\r\n<a name=\"wildcard_handlers\" />\r\n### wildcard handlers\r\n\r\nWildcard handlers resolve their urls to their current module scope + url.\r\n\r\nappex wildcard handlers allow for wildcard routing at a given module scope. Wildcard handlers\r\nsupport 'typed' url argument mapping, as denoted by the arguments annotation.\r\n\r\nIn addition, wildcard handlers also support optional arguments which can be specified with TypeScript's '?' \r\non argument names.\r\n\r\nappex wildcard handlers require the following signature:\r\n\r\n* name        - 'wildcard'\r\n* argument[0] - app context\r\n* argument[n] - 1 or more arguments to be mapped from the url\r\n* returns     - void (optional)\r\n\r\n```javascript\r\ndeclare var console;\r\n\r\nexport module blogs {\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11   - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/11  - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/3rd - not matched - (see number annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01     - matched     - (see ? annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013        - not matched - (month is required)\r\n\t\r\n    export function wildcard(context, year:number, month:number, day?:number) {\r\n\r\n        context.response.json({ year: year, month: month, day: day})\r\n    }\r\n}\r\n\r\n// url : http://[host]:[port]/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// url : http://[host]:[port]/(.*) \r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, 'not found');\r\n}\r\n\r\n```\r\nnote: appex supports boolean, number, string and any annotations on wildcard arguments. if no annotation\r\nis specified, appex interprets the argument as a string. the type 'any' is also interpreted as string.\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"cascades\" />\r\n### cascades\r\n\r\nappex supports a cascading attribute scheme on modules and functions. With this, developers can apply\r\narbituary meta data for modules and functions that will propagate through scope. appex has two special\r\ncascade properties for middleware and http verb matching, which are described below, however consider\r\nthe following code which illustrates the concept.\r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ncascade({a: 10}); // global.\r\n\r\ncascade('foo', {b : 20})\r\nexport module foo {\r\n\r\n    cascade('foo.bar', {c : 30})\r\n    export module bar {\r\n            \r\n        cascade('foo.bar.index', {d : 40})\r\n        export function index(context) {\r\n        \r\n            //context.cascade\r\n            //{\r\n            //    \"a\": 10,\r\n            //    \"b\": 20,\r\n            //    \"c\": 30,\r\n\t\t\t//    \"d\": 40\r\n            //}\r\n\r\n            context.response.json( context.cascade );       \r\n        }\r\n    }\r\n}\r\n\r\n```\r\n\r\n<a name=\"http_verbs\" />\r\n### http verbs\r\n\r\nappex handles http verb matching with cascades. appex will recognise the \r\n'verbs' property applied to the cascade to match against http verbs.\r\n\r\n```javascript\r\ncascade('index', { verbs: ['get'] })\r\nexport function index (context) { \r\n        \r\n    // only allow HTTP GET requests\r\n    context.response.send('index')\r\n}\r\n\r\ncascade('index', { verbs: ['post', 'put'] })\r\nexport function submit (context) { \r\n    \r\n    // only allow HTTP POST and PUT requests\r\n    context.response.send('submit')\r\n}\r\n```\r\n\r\n\r\n<a name=\"middleware\" />\r\n### middleware\r\n\r\nappex supports middleware with cascades. appex middleware defined with cascades allows\r\ndevelopers to scope middleware on single functions, or entire module scopes. appex will \r\nrecognise the 'use' property applied to the cascade to invoke middleware.\r\n\r\nthe following demonstrates how one might use middleware to secure a site admin.\r\n\r\nnote: middleware 'must' call next or handle the request. \r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ndeclare var console;\r\n\r\nfunction authenticate(context) {\r\n\r\n    console.log('authenticate')\r\n\r\n\t// call next() if authenticated, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\nfunction authorize(context) {\r\n\r\n    console.log('authorize')\r\n\r\n\t// call next() if authorized, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\n// apply security middleware to admin scope.\r\ncascade('admin', {use: [authenticate, authorize]}) \r\nexport module admin {\r\n\r\n    export function index(context) {\r\n        \r\n        console.log(context.cascade); // view cascade\r\n\r\n        context.response.send('access granted!')\r\n    }\r\n}\r\n\r\n// index handler has no middleware applied.\r\nexport function index (context) { \r\n    \r\n    console.log(context.cascade); // view cascade\r\n\r\n    context.response.send('home')\r\n}\r\n```\r\n\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex will only route functions prefix with the TypeScript 'export' declarer. This rule\r\nalso applied to modules. Developers can use this to infer notions of public and private \r\nat the http level.\r\n\r\nconsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.send('public_function');\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```javascript\r\n// http:[host]:[port]/\r\nexport function index (context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard (context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n<a name=\"serving_static_files\" />\r\n## serving static files\r\n\r\nUse wildcard functions with context.response.serve() to serve static content.\r\n\r\n```javascript\r\nexport module static {\r\n\t\r\n\t// http:[host]:[port]/static/(.*)\r\n\texport function wildcard(context, path) {\r\n\r\n\t\tcontext.response.serve('./static/', path);\r\n\t}\r\n}\r\n\r\n// http:[host]:[port]/\r\nexport function index (context) {\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n\r\n<a name=\"reflection\" />\r\n## reflection\r\n\r\nappex provides a reflection api derived from TypeScript's type system that developers can \r\nleverage to reflect type information declared throughout their appex modules. \r\n\r\nthe following section outlines how to use the reflection api.\r\n\r\n<a name=\"reflect_everything\" />\r\n### reflect everything\r\n\r\nthe appex reflection api is passed on the context.module.reflection property and is available to all\r\nappex handler methods. The following code will JSON serialize everything declared in your appex\r\nproject and write it to the http response. \r\n\r\n```javascript\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection );\r\n}\r\n```\r\n<a name=\"reflect_specific_types\" />\r\n### reflect specific types\r\n\r\nIn typical scenarios, developers will want to leverage reflection meta data to generate\r\nservice contacts and client side models. the reflection api lets you access meta data \r\nfor the following types declared in your project. \r\n\r\n* modules\r\n* imports\r\n* classes\r\n* interfaces\r\n* functions\r\n* variables\r\n\r\nto access specific type metadata, use the reflection.get([qualifier]) method, as demonstrated below.\r\n\r\n```javascript\r\nexport module models {\r\n    \r\n    export class Customer {\r\n\r\n        public firstname   : string;\r\n\r\n        public lastname    : string;\r\n\r\n        public age         : number;\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('models.Customer') );\r\n}\r\n```\r\nand methods..\r\n\r\n```javascript\r\nfunction some_method(a:string, b:number, c?:boolean) : void { }\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_method') );\r\n}\r\n```\r\n\r\n....and variables...\r\n\r\n```javascript\r\nvar some_variable:number = 10;\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_variable') );\r\n}\r\n```\r\n<a name=\"json_schema\" />\r\n## json schema\r\n\r\nappex supports reflecting back basic JSON schema meta data from class and interface definitions. \r\n\r\n```javascript\r\n\r\nexport module models {\r\n\r\n\texport class Address {\r\n\r\n\t\tpublic addressLine1: string;\r\n\t\t\r\n        public addressLine2: string;\r\n\t\t\r\n        public addressLine3: string;\r\n\t}\r\n\t\r\n\texport class User {\r\n\t\t\r\n        public id : string;\r\n\t}\r\n\r\n\texport class Customer extends User {\r\n\r\n\t\tpublic firstname : string;\r\n\t\t\r\n        public lastname  : string;\r\n\t\t\r\n        public age       : number;\r\n\t\t\r\n        public addresses : Address[];\r\n\t}\r\n}\r\n\r\nexport function index (context) {\r\n    \r\n    context.response.json( context.module.reflection.schema('models.Customer') );\r\n}\r\n\r\n```\r\n\r\nnote: this functionality is experimental. \r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\nThis section outlines development with appex.\r\n\r\n<a name=\"appex_declaration\" />\r\n### appex.d.ts declaration\r\n\r\nIf you develop on a TypeScript complicant editor (one that supports TS 0.9), appex comes bundled\r\nwith a declaration file you can reference in your project. If installing appex via npm, your\r\nreference should be as follows.\r\n\r\n```javascript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nexport function index (context:appex.web.IContext) { \r\n    \r\n    context.response.send('hello');\r\n}\r\n\r\nexport function wildcard(context:appex.web.IContext, path:string) {\r\n\r\n    context.response.serve('./', path);\r\n}\r\n```\r\n\r\nBy referencing this in your project, you get the benefits of code completion and static type checking\r\nagainst both appex, and the nodejs core.\r\n\r\n![](https://raw.github.com/sinclairzx81/appex/master/artifacts/code-completion.jpg)\r\n\r\nAdditional declaration files may be obtained from [here](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex ({ program : './index.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"users.ts\" />\r\n/// <reference path=\"pages.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { context.response.send('users.login') }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { context.response.send('users.logout') }\r\n}\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { context.response.send('home') }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { context.response.send('about') }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { context.response.send('contact') }\r\n\r\nexport function wildcard (context, path) { context.response.send(404, ' not found') }\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"license\" />\r\n## license\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) 2013 Haydn Paterson (sinclair) <haydn.developer@gmail.com>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in\r\nall copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\nTHE SOFTWARE.\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"https://raw.github.com/sinclairzx81/appex/master/license.txt","type":"The MIT License (MIT)"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"nodejs web api with typescript","directories":{},"dependencies":{"typescript.api":"0.5.6"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.4.5":{"name":"appex","version":"0.4.5","keywords":["typescript","web api","reflection","compiler","schema"],"author":{"name":"sinclair"},"_id":"appex@0.4.5","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"0a6cd54e7768bc55f409c031b672438b622a0c33","tarball":"https://registry.npmjs.org/appex/-/appex-0.4.5.tgz","integrity":"sha512-VLH7UV0e+PswZliKMiZw2ykhZ4o7CL/j/5wCzXge+YzW1MeKQEjWiKzp8IPn3/2TW/JxyUiFv6JEldnL2WBlBw==","signatures":[{"sig":"MEUCIQDokRd2vV7Ndj+WNVnCHIQ7DUuWxhBHwuQR73kbwDJv1gIgIMUXJtLbxGDmPuO64KgWrA+YRGYbdDu+SETgxMOg0K8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/artifacts/logo.jpg)\r\n\r\n### nodejs web api with [typescript](http://www.typescriptlang.org/)\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http://localhost:3000/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// http://localhost:3000/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about');\r\n}\r\n\r\n// http://localhost:3000/(.*)\r\nexport function wildcard (context, path) {\r\n    \r\n    context.response.send(404, path + \"not found\");\r\n}\r\n\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n## overview\r\n\r\nappex is a nodejs web api framework built on top of the TypeScript programming language. It enables\r\ndevelopers to create RESTful service endpoints by writing TypeScript functions, as well as providing\r\nreflection / type meta data derived from the languages type system.\r\n\r\n* [getting started](#getting_started)\r\n\t* [application](#application)\r\n\t* [options](#options)\r\n\t* [http server](#http_server)\r\n\t* [express middleware](#express_middleware)\r\n* [creating services with typescript](#creating_services)\r\n\t* [app context](#app_context)\r\n\t* [routing handlers](#routing_handlers)\r\n\t* [handler signatures](#handler_signatures)\r\n\t* [named handlers](#named_handlers)\r\n\t* [index handlers](#index_handlers)\r\n\t* [wildcard handlers](#wildcard_handlers)\r\n\t* [cascades](#cascades)\r\n\t* [http verbs](#http_verbs)\r\n\t* [middleware](#middleware)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [handling 404](#handling_404)\r\n\t* [serving static files](#serving_static_files)\r\n* [reflection](#reflection)\r\n\t* [reflect everything](#reflect_everything)\r\n\t* [reflect specific types](#reflect_specific_types)\r\n\t* [json schema](#json_schema)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [appex.d.ts declaration](#appex_declaration)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n* [license](#license)\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following section outlines configuring appex.\r\n\r\n<a name=\"application\" />\r\n### application\r\n\r\nsetting up. \r\n\r\n```javascript\r\nvar appex   = require('appex');\r\n\r\nvar app   = appex({ program : './program.ts', \r\n                    devmode : true,\r\n                    logging : true });\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"options\" />\r\n### options\r\n\r\nthe following lists the appex startup options.\r\n\r\n```javascript\r\nvar options = { \r\n\t// (required) location of source file.\r\n\tprogram    : './program.ts', \r\n\r\n\t// (optional) recompile on request. (default:false) \r\n\tdevmode    : true,          \r\n\r\n\t// (optional) log to stdout. (default:false) \r\n\tlogging    : true,\r\n\r\n\t// (optional) user defined objects added to the app context.\r\n\tcontext    : {}\r\n};\r\n\r\nvar app = appex( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### http server\r\n\r\nsetting up appex on a nodejs http server.\r\n\r\n```javascript\r\nvar http = require('http');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\nvar server = http.createServer( app );\r\n\r\nserver.listen(3000);\r\n```\r\n<a name=\"express_middleware\" />\r\n### express middleware\r\n\r\nappex is allows developers to augment existing express / connect applications by \r\nway of middleware. The following demonstrates setting up appex as express middleware.\r\n\r\n```javascript\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) ); \r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nBy doing this, appex will attempt to intercept incoming requests. if appex cannot find a matching route for \r\nthe request, it will automatically call the \"next\" function to pass the request on to the next middleware or\r\nexpress handler.\r\n\r\nin addition to this, appex may also function as traditional express middleware. the following example sets up a wildcard\r\nfunction (to match all requests), it prints a message to the console on each request and forwards the request on...\r\n\r\n```javascript\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tconsole.log('hello world!!');\r\n\r\n\tcontext.next(); // pass it on!\r\n}\r\n\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) );\r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nIts important to note that appex will also inheriate the characteristics of the request defined by\r\nother middleware in the stack, or configurations made to express prior. consider the following example \r\nin which the jade view engine is configured. appex will inheritate the response.render() method, passing it on the \r\ncontext.response as follows..\r\n\r\n```javascript\r\n\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\napp.configure(function(){\r\n\r\n  app.set('views', __dirname + '/views');\r\n  \r\n  // set up the jade engine.\r\n  app.set('view engine', 'jade'); \r\n  \r\n  // bind appex\r\n  app.use( appex({program:'./program.ts', devmode:true} ));  \r\n});\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/\r\nexport function index(context) {\r\n\t\r\n\t// jade renderer works!\r\n\tcontext.response.render('index', { title: 'Express' }); \r\n}\r\n```\r\n\r\n<a name=\"creating_services\" />\r\n## creating services with typescript\r\n\r\nThe following section describes how to write http accessible functions with appex.\r\n\r\n<a name=\"app_context\" />\r\n### app context\r\n\r\nAll appex functions are passed a application context object as their first argument. The app context object \r\nencapulates the http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the app context\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.cascade    - appex cascade.\r\n\r\n\t// context.next       - the next function (express middleware)\r\n\t\r\n\t// context.router     - the appex router\r\n\t\r\n\t// context.module     - the module being run (this module)\r\n\r\n\t// context.schema     - json schema api.\r\n\r\n\t// context.mime       - a http mime type utility.\r\n}\r\n```\r\n\r\nit is possible to extend the default objects passed on the context by adding them on the appex startup options. The \r\nfollowing will attach the async module to the context. \r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = appex({ program : './program.ts', \r\n\t\t\t\t  devmode : true, \r\n\t\t\t      context: {\r\n\t\t\t\t\t\tasync : require('async')\r\n\t\t\t\t  }});\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\r\n\t// context.async = passed on the context.\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n```\r\n<a name=\"routing_handlers\" />\r\n### routing handlers\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context) { /* handle route */ }\r\n}\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/(.*)\r\nexport function wildcard (context, path) { /* handle route */ }\r\n\r\n```\r\n\r\n<a name=\"handler_signatures\" />\r\n### handler signatures\r\n\r\nappex supports three function signatures for http routing (named, index and wildcard). Functions that\r\ndo not apply these signatures will not be routed.\r\n\r\n<a name=\"named_handlers\" />\r\n### named handlers\r\n\r\nNamed handlers resolve urls to their current module scope + the name of the function.\r\n\r\nNamed handlers require the following signature:\r\n\r\n* name        - 'anything'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n\r\n// http://[host]:[port]/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about page');\r\n}\r\n\r\n// http://[host]:[port]/users/login\r\nexport module users {\r\n\r\n\texport function login(context) {\r\n\t\t\r\n\t\tcontext.response.send('handle login');\t\r\n\t}\r\n}\r\n\r\n```\r\n\r\n<a name=\"index_handlers\" />\r\n### index handlers\r\n\r\nIndex handlers resolve urls to their current module scope.\r\n\r\nIndex handlers require the following signature:\r\n\r\n* name        - 'index'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) \r\n\t{\t\r\n\t\tcontext.response.send('blog index');\r\n\t}\r\n}\r\n```\r\n\r\n<a name=\"wildcard_handlers\" />\r\n### wildcard handlers\r\n\r\nWildcard handlers resolve their urls to their current module scope + url.\r\n\r\nappex wildcard handlers allow for wildcard routing at a given module scope. Wildcard handlers\r\nsupport 'typed' url argument mapping, as denoted by the arguments annotation.\r\n\r\nIn addition, wildcard handlers also support optional arguments which can be specified with TypeScript's '?' \r\non argument names.\r\n\r\nappex wildcard handlers require the following signature:\r\n\r\n* name        - 'wildcard'\r\n* argument[0] - app context\r\n* argument[n] - 1 or more arguments to be mapped from the url\r\n* returns     - void (optional)\r\n\r\n```javascript\r\ndeclare var console;\r\n\r\nexport module blogs {\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11   - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/11  - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/3rd - not matched - (see number annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01     - matched     - (see ? annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013        - not matched - (month is required)\r\n\t\r\n    export function wildcard(context, year:number, month:number, day?:number) {\r\n\r\n        context.response.json({ year: year, month: month, day: day})\r\n    }\r\n}\r\n\r\n// url : http://[host]:[port]/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// url : http://[host]:[port]/(.*) \r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, 'not found');\r\n}\r\n\r\n```\r\nnote: appex supports boolean, number, string and any annotations on wildcard arguments. if no annotation\r\nis specified, appex interprets the argument as a string. the type 'any' is also interpreted as string.\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"cascades\" />\r\n### cascades\r\n\r\nappex supports a cascading attribute scheme on modules and functions. With this, developers can apply\r\narbituary meta data for modules and functions that will propagate through scope. appex has two special\r\ncascade properties for middleware and http verb matching, which are described below, however consider\r\nthe following code which illustrates the concept.\r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ncascade({a: 10}); // global.\r\n\r\ncascade('foo', {b : 20})\r\nexport module foo {\r\n\r\n    cascade('foo.bar', {c : 30})\r\n    export module bar {\r\n            \r\n        cascade('foo.bar.index', {d : 40})\r\n        export function index(context) {\r\n        \r\n            //context.cascade\r\n            //{\r\n            //    \"a\": 10,\r\n            //    \"b\": 20,\r\n            //    \"c\": 30,\r\n\t\t\t//    \"d\": 40\r\n            //}\r\n\r\n            context.response.json( context.cascade );       \r\n        }\r\n    }\r\n}\r\n\r\n```\r\n\r\n<a name=\"http_verbs\" />\r\n### http verbs\r\n\r\nappex handles http verb matching with cascades. appex will recognise the \r\n'verbs' property applied to the cascade to match against http verbs.\r\n\r\n```javascript\r\ncascade('index', { verbs: ['get'] })\r\nexport function index (context) { \r\n        \r\n    // only allow HTTP GET requests\r\n    context.response.send('index')\r\n}\r\n\r\ncascade('index', { verbs: ['post', 'put'] })\r\nexport function submit (context) { \r\n    \r\n    // only allow HTTP POST and PUT requests\r\n    context.response.send('submit')\r\n}\r\n```\r\n\r\n\r\n<a name=\"middleware\" />\r\n### middleware\r\n\r\nappex supports middleware with cascades. appex middleware defined with cascades allows\r\ndevelopers to scope middleware on single functions, or entire module scopes. appex will \r\nrecognise the 'use' property applied to the cascade to invoke middleware.\r\n\r\nthe following demonstrates how one might use middleware to secure a site admin.\r\n\r\nnote: middleware 'must' call next or handle the request. \r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ndeclare var console;\r\n\r\nfunction authenticate(context) {\r\n\r\n    console.log('authenticate')\r\n\r\n\t// call next() if authenticated, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\nfunction authorize(context) {\r\n\r\n    console.log('authorize')\r\n\r\n\t// call next() if authorized, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\n// apply security middleware to admin scope.\r\ncascade('admin', {use: [authenticate, authorize]}) \r\nexport module admin {\r\n\r\n    export function index(context) {\r\n        \r\n        console.log(context.cascade); // view cascade\r\n\r\n        context.response.send('access granted!')\r\n    }\r\n}\r\n\r\n// index handler has no middleware applied.\r\nexport function index (context) { \r\n    \r\n    console.log(context.cascade); // view cascade\r\n\r\n    context.response.send('home')\r\n}\r\n```\r\n\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex will only route functions prefixed with the TypeScript 'export' declarer. This rule\r\nalso applied to modules. Developers can use this to infer notions of public and private \r\nat the http level.\r\n\r\nconsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.send('public_function');\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```javascript\r\n// http:[host]:[port]/\r\nexport function index (context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard (context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n<a name=\"serving_static_files\" />\r\n## serving static files\r\n\r\nUse wildcard functions with context.response.serve() to serve static content.\r\n\r\n```javascript\r\nexport module static {\r\n\t\r\n\t// http:[host]:[port]/static/(.*)\r\n\texport function wildcard(context, path) {\r\n\r\n\t\tcontext.response.serve('./static/', path);\r\n\t}\r\n}\r\n\r\n// http:[host]:[port]/\r\nexport function index (context) {\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n\r\n<a name=\"reflection\" />\r\n## reflection\r\n\r\nappex provides a reflection api derived from TypeScript's type system that developers can \r\nleverage to reflect type information declared throughout their appex modules. \r\n\r\nthe following section outlines how to use the reflection api.\r\n\r\n<a name=\"reflect_everything\" />\r\n### reflect everything\r\n\r\nthe appex reflection api is passed on the context.module.reflection property and is available to all\r\nappex handler methods. The following code will JSON serialize everything declared in your appex\r\nproject and write it to the http response. \r\n\r\n```javascript\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection );\r\n}\r\n```\r\n<a name=\"reflect_specific_types\" />\r\n### reflect specific types\r\n\r\nIn typical scenarios, developers will want to leverage reflection meta data to generate\r\nservice contacts and client side models. the reflection api lets you access meta data \r\nfor the following types declared in your project. \r\n\r\n* modules\r\n* imports\r\n* classes\r\n* interfaces\r\n* functions\r\n* variables\r\n\r\nto access specific type metadata, use the reflection.get([qualifier]) method, as demonstrated below.\r\n\r\n```javascript\r\nexport module models {\r\n    \r\n    export class Customer {\r\n\r\n        public firstname   : string;\r\n\r\n        public lastname    : string;\r\n\r\n        public age         : number;\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('models.Customer') );\r\n}\r\n```\r\nand methods..\r\n\r\n```javascript\r\nfunction some_method(a:string, b:number, c?:boolean) : void { }\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_method') );\r\n}\r\n```\r\n\r\n....and variables...\r\n\r\n```javascript\r\nvar some_variable:number = 10;\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_variable') );\r\n}\r\n```\r\n<a name=\"json_schema\" />\r\n### json schema\r\n\r\nappex supports reflecting back JSON schema meta data from class and interface type definitions. for example, the following\r\nwill output a json schema on the type 'models.Employee'.\r\n\r\n```javascript\r\n\r\nexport module models {\r\n\r\n\texport class Address {\r\n\r\n        /** street */\r\n\t\tpublic addressLine1: string;\r\n        /** suburb */\t\t\r\n        public addressLine2: string;\r\n\t}\r\n\t\r\n\texport class User {\r\n\r\n\t\t/** this users id */\r\n        public id : string;\r\n\t}\r\n\r\n    export class Customer extends User {\r\n        \r\n        /** the customers firstname */\r\n\t\tpublic firstname  : string;\r\n\t\t\r\n        /** the customers lastname */\r\n        public lastname   : string;\r\n    }\r\n\r\n\texport class Employee extends User {\r\n\r\n        /** the employees firstname */\r\n\t\tpublic firstname  : string;\r\n\t\t\r\n        /** the employees lastname */\r\n        public lastname   : string;\r\n\t\t\r\n        /** the employees address */\r\n        public address  : Address;\r\n\r\n        /** this employees customers */\r\n        public customers : Customer[];\r\n\t}\r\n}\r\n\r\nexport function index (context) {\r\n    \r\n    context.response.json( context.schema.get('models.Employee') );\r\n}\r\n\r\n```\r\n\r\nwhich generates the following json schema.\r\n\r\n```javascript\r\n{\r\n    \"id\": \"#models.Employee\",\r\n    \"type\": \"object\",\r\n    \"properties\": {\r\n        \"id\": {\r\n            \"id\": \"id\",\r\n            \"type\": \"string\",\r\n            \"description\": \"this users id\"\r\n        },\r\n        \"firstname\": {\r\n            \"id\": \"firstname\",\r\n            \"type\": \"string\",\r\n            \"description\": \"the employees firstname\"\r\n        },\r\n        \"lastname\": {\r\n            \"id\": \"lastname\",\r\n            \"type\": \"string\",\r\n            \"description\": \"the employees lastname\"\r\n        },\r\n        \"address\": {\r\n            \"id\": \"#models.Address\",\r\n            \"type\": \"object\",\r\n            \"properties\": {\r\n                \"addressLine1\": {\r\n                    \"id\": \"addressLine1\",\r\n                    \"type\": \"string\",\r\n                    \"description\": \"street\"\r\n                },\r\n                \"addressLine2\": {\r\n                    \"id\": \"addressLine2\",\r\n                    \"type\": \"string\",\r\n                    \"description\": \"suburb\"\r\n                }\r\n            }\r\n        },\r\n        \"customers\": {\r\n            \"id\": \"customers\",\r\n            \"type\": \"array\",\r\n            \"items\": {\r\n                \"type\": {\r\n                    \"id\": \"#models.Customer\",\r\n                    \"type\": \"object\",\r\n                    \"properties\": {\r\n                        \"id\": {\r\n                            \"id\": \"id\",\r\n                            \"type\": \"string\",\r\n                            \"description\": \"this users id\"\r\n                        },\r\n                        \"firstname\": {\r\n                            \"id\": \"firstname\",\r\n                            \"type\": \"string\",\r\n                            \"description\": \"the customers firstname\"\r\n                        },\r\n                        \"lastname\": {\r\n                            \"id\": \"lastname\",\r\n                            \"type\": \"string\",\r\n                            \"description\": \"the customers lastname\"\r\n                        }\r\n                    }\r\n                }\r\n            },\r\n            \"description\": \"this employees customers\"\r\n        }\r\n    }\r\n}\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\nThis section outlines development with appex.\r\n\r\n<a name=\"appex_declaration\" />\r\n### appex.d.ts declaration\r\n\r\nIf you develop on a TypeScript complicant editor (one that supports TS 0.9), appex comes bundled\r\nwith a declaration file you can reference in your project. If installing appex via npm, your\r\nreference should be as follows.\r\n\r\n```javascript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nexport function index (context:appex.web.IContext) { \r\n    \r\n    context.response.send('hello');\r\n}\r\n\r\nexport function wildcard(context:appex.web.IContext, path:string) {\r\n\r\n    context.response.serve('./', path);\r\n}\r\n```\r\n\r\nBy referencing this in your project, you get the benefits of code completion and static type checking\r\nagainst both appex, and the nodejs core.\r\n\r\n![](https://raw.github.com/sinclairzx81/appex/master/artifacts/code-completion.jpg)\r\n\r\nAdditional declaration files may be obtained from [here](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex ({ program : './index.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"users.ts\" />\r\n/// <reference path=\"pages.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { context.response.send('users.login') }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { context.response.send('users.logout') }\r\n}\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { context.response.send('home') }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { context.response.send('about') }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { context.response.send('contact') }\r\n\r\nexport function wildcard (context, path) { context.response.send(404, ' not found') }\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"license\" />\r\n## license\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) 2013 Haydn Paterson (sinclair) <haydn.developer@gmail.com>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in\r\nall copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\nTHE SOFTWARE.\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"https://raw.github.com/sinclairzx81/appex/master/license.txt","type":"The MIT License (MIT)"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"nodejs web api with typescript","directories":{},"dependencies":{"typescript.api":"0.5.6"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.4.6":{"name":"appex","version":"0.4.6","keywords":["typescript","web api","reflection","compiler","schema"],"author":{"name":"sinclair"},"_id":"appex@0.4.6","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"fc5fa1355097e76b8e151ccfbdfe2881ffc46e72","tarball":"https://registry.npmjs.org/appex/-/appex-0.4.6.tgz","integrity":"sha512-W1Cd/isphdrfpgX92c0E1gJZgdROOotqwdNILHX5c6YCmxskq2hO58BeCP/7fFeJj8oAoMzwOOq1cFDfIXIdfA==","signatures":[{"sig":"MEQCIEoGekYVK+FKzbW13UKMy8keHl6BfbGFwnm2jAIItxHCAiB8JHwkzF1mTymqmnPJQVduKXrzqxoAtTAwr4ejMLLjpw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/artifacts/logo.jpg)\r\n\r\n### nodejs web api with [typescript](http://www.typescriptlang.org/)\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http://localhost:3000/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// http://localhost:3000/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about');\r\n}\r\n\r\n// http://localhost:3000/(.*)\r\nexport function wildcard (context, path) {\r\n    \r\n    context.response.send(404, path + \"not found\");\r\n}\r\n\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n## overview\r\n\r\nappex is a nodejs web api framework built on top of the TypeScript programming language. It enables\r\ndevelopers to create RESTful service endpoints by writing TypeScript functions, as well as providing\r\nreflection / type meta data derived from the languages type system.\r\n\r\n* [getting started](#getting_started)\r\n\t* [application](#application)\r\n\t* [options](#options)\r\n\t* [http server](#http_server)\r\n\t* [express middleware](#express_middleware)\r\n* [creating services with typescript](#creating_services)\r\n\t* [app context](#app_context)\r\n\t* [routing handlers](#routing_handlers)\r\n\t* [handler signatures](#handler_signatures)\r\n\t* [named handlers](#named_handlers)\r\n\t* [index handlers](#index_handlers)\r\n\t* [wildcard handlers](#wildcard_handlers)\r\n\t* [cascades](#cascades)\r\n\t* [http verbs](#http_verbs)\r\n\t* [middleware](#middleware)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [handling 404](#handling_404)\r\n\t* [serving static files](#serving_static_files)\r\n* [reflection](#reflection)\r\n\t* [reflect everything](#reflect_everything)\r\n\t* [reflect specific types](#reflect_specific_types)\r\n\t* [json schema](#json_schema)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [appex.d.ts declaration](#appex_declaration)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n* [license](#license)\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following section outlines configuring appex.\r\n\r\n<a name=\"application\" />\r\n### application\r\n\r\nsetting up. \r\n\r\n```javascript\r\nvar appex   = require('appex');\r\n\r\nvar app   = appex({ program : './program.ts', \r\n                    devmode : true,\r\n                    logging : true });\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"options\" />\r\n### options\r\n\r\nthe following lists the appex startup options.\r\n\r\n```javascript\r\nvar options = { \r\n\t// (required) location of source file.\r\n\tprogram    : './program.ts', \r\n\r\n\t// (optional) recompile on request. (default:false) \r\n\tdevmode    : true,          \r\n\r\n\t// (optional) log to stdout. (default:false) \r\n\tlogging    : true,\r\n\r\n\t// (optional) user defined objects added to the app context.\r\n\tcontext    : {}\r\n};\r\n\r\nvar app = appex( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### http server\r\n\r\nsetting up appex on a nodejs http server.\r\n\r\n```javascript\r\nvar http = require('http');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\nvar server = http.createServer( app );\r\n\r\nserver.listen(3000);\r\n```\r\n<a name=\"express_middleware\" />\r\n### express middleware\r\n\r\nappex is allows developers to augment existing express / connect applications by \r\nway of middleware. The following demonstrates setting up appex as express middleware.\r\n\r\n```javascript\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) ); \r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nBy doing this, appex will attempt to intercept incoming requests. if appex cannot find a matching route for \r\nthe request, it will automatically call the \"next\" function to pass the request on to the next middleware or\r\nexpress handler.\r\n\r\nin addition to this, appex may also function as traditional express middleware. the following example sets up a wildcard\r\nfunction (to match all requests), it prints a message to the console on each request and forwards the request on...\r\n\r\n```javascript\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tconsole.log('hello world!!');\r\n\r\n\tcontext.next(); // pass it on!\r\n}\r\n\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) );\r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nIts important to note that appex will also inheriate the characteristics of the request defined by\r\nother middleware in the stack, or configurations made to express prior. consider the following example \r\nin which the jade view engine is configured. appex will inheritate the response.render() method, passing it on the \r\ncontext.response as follows..\r\n\r\n```javascript\r\n\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\napp.configure(function(){\r\n\r\n  app.set('views', __dirname + '/views');\r\n  \r\n  // set up the jade engine.\r\n  app.set('view engine', 'jade'); \r\n  \r\n  // bind appex\r\n  app.use( appex({program:'./program.ts', devmode:true} ));  \r\n});\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/\r\nexport function index(context) {\r\n\t\r\n\t// jade renderer works!\r\n\tcontext.response.render('index', { title: 'Express' }); \r\n}\r\n```\r\n\r\n<a name=\"creating_services\" />\r\n## creating services with typescript\r\n\r\nThe following section describes how to write http accessible functions with appex.\r\n\r\n<a name=\"app_context\" />\r\n### app context\r\n\r\nAll appex functions are passed a application context object as their first argument. The app context object \r\nencapulates the http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the app context\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.cascade    - appex cascade.\r\n\r\n\t// context.next       - the next function (express middleware)\r\n\t\r\n\t// context.router     - the appex router\r\n\t\r\n\t// context.module     - the module being run (this module)\r\n\r\n\t// context.schema     - json schema api.\r\n\r\n\t// context.mime       - a http mime type utility.\r\n}\r\n```\r\n\r\nit is possible to extend the default objects passed on the context by adding them on the appex startup options. The \r\nfollowing will attach the async module to the context. \r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = appex({ program : './program.ts', \r\n\t\t\t\t  devmode : true, \r\n\t\t\t      context: {\r\n\t\t\t\t\t\tasync : require('async')\r\n\t\t\t\t  }});\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\r\n\t// context.async = passed on the context.\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n```\r\n<a name=\"routing_handlers\" />\r\n### routing handlers\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context) { /* handle route */ }\r\n}\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/(.*)\r\nexport function wildcard (context, path) { /* handle route */ }\r\n\r\n```\r\n\r\n<a name=\"handler_signatures\" />\r\n### handler signatures\r\n\r\nappex supports three function signatures for http routing (named, index and wildcard). Functions that\r\ndo not apply these signatures will not be routed.\r\n\r\n<a name=\"named_handlers\" />\r\n### named handlers\r\n\r\nNamed handlers resolve urls to their current module scope + the name of the function.\r\n\r\nNamed handlers require the following signature:\r\n\r\n* name        - 'anything'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n\r\n// http://[host]:[port]/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about page');\r\n}\r\n\r\n// http://[host]:[port]/users/login\r\nexport module users {\r\n\r\n\texport function login(context) {\r\n\t\t\r\n\t\tcontext.response.send('handle login');\t\r\n\t}\r\n}\r\n\r\n```\r\n\r\n<a name=\"index_handlers\" />\r\n### index handlers\r\n\r\nIndex handlers resolve urls to their current module scope.\r\n\r\nIndex handlers require the following signature:\r\n\r\n* name        - 'index'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) \r\n\t{\t\r\n\t\tcontext.response.send('blog index');\r\n\t}\r\n}\r\n```\r\n\r\n<a name=\"wildcard_handlers\" />\r\n### wildcard handlers\r\n\r\nWildcard handlers resolve their urls to their current module scope + url.\r\n\r\nappex wildcard handlers allow for wildcard routing at a given module scope. Wildcard handlers\r\nsupport 'typed' url argument mapping, as denoted by the arguments annotation.\r\n\r\nIn addition, wildcard handlers also support optional arguments which can be specified with TypeScript's '?' \r\non argument names.\r\n\r\nappex wildcard handlers require the following signature:\r\n\r\n* name        - 'wildcard'\r\n* argument[0] - app context\r\n* argument[n] - 1 or more arguments to be mapped from the url\r\n* returns     - void (optional)\r\n\r\n```javascript\r\ndeclare var console;\r\n\r\nexport module blogs {\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11   - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/11  - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/3rd - not matched - (see number annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01     - matched     - (see ? annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013        - not matched - (month is required)\r\n\t\r\n    export function wildcard(context, year:number, month:number, day?:number) {\r\n\r\n        context.response.json({ year: year, month: month, day: day})\r\n    }\r\n}\r\n\r\n// url : http://[host]:[port]/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// url : http://[host]:[port]/(.*) \r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, 'not found');\r\n}\r\n\r\n```\r\nnote: appex supports boolean, number, string and any annotations on wildcard arguments. if no annotation\r\nis specified, appex interprets the argument as a string. the type 'any' is also interpreted as string.\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"cascades\" />\r\n### cascades\r\n\r\nappex supports a cascading attribute scheme on modules and functions. With this, developers can apply\r\narbituary meta data for modules and functions that will propagate through scope. appex has two special\r\ncascade properties for middleware and http verb matching, which are described below, however consider\r\nthe following code which illustrates the concept.\r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ncascade({a: 10}); // global.\r\n\r\ncascade('foo', {b : 20})\r\nexport module foo {\r\n\r\n    cascade('foo.bar', {c : 30})\r\n    export module bar {\r\n            \r\n        cascade('foo.bar.index', {d : 40})\r\n        export function index(context) {\r\n        \r\n            //context.cascade\r\n            //{\r\n            //    \"a\": 10,\r\n            //    \"b\": 20,\r\n            //    \"c\": 30,\r\n\t\t\t//    \"d\": 40\r\n            //}\r\n\r\n            context.response.json( context.cascade );       \r\n        }\r\n    }\r\n}\r\n\r\n```\r\n\r\n<a name=\"http_verbs\" />\r\n### http verbs\r\n\r\nappex handles http verb matching with cascades. appex will recognise the \r\n'verbs' property applied to the cascade to match against http verbs.\r\n\r\n```javascript\r\ncascade('index', { verbs: ['get'] })\r\nexport function index (context) { \r\n        \r\n    // only allow HTTP GET requests\r\n    context.response.send('index')\r\n}\r\n\r\ncascade('index', { verbs: ['post', 'put'] })\r\nexport function submit (context) { \r\n    \r\n    // only allow HTTP POST and PUT requests\r\n    context.response.send('submit')\r\n}\r\n```\r\n\r\n\r\n<a name=\"middleware\" />\r\n### middleware\r\n\r\nappex supports middleware with cascades. appex middleware defined with cascades allows\r\ndevelopers to scope middleware on single functions, or entire module scopes. appex will \r\nrecognise the 'use' property applied to the cascade to invoke middleware.\r\n\r\nthe following demonstrates how one might use middleware to secure a site admin.\r\n\r\nnote: middleware 'must' call next or handle the request. \r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ndeclare var console;\r\n\r\nfunction authenticate(context) {\r\n\r\n    console.log('authenticate')\r\n\r\n\t// call next() if authenticated, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\nfunction authorize(context) {\r\n\r\n    console.log('authorize')\r\n\r\n\t// call next() if authorized, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\n// apply security middleware to admin scope.\r\ncascade('admin', {use: [authenticate, authorize]}) \r\nexport module admin {\r\n\r\n    export function index(context) {\r\n        \r\n        console.log(context.cascade); // view cascade\r\n\r\n        context.response.send('access granted!')\r\n    }\r\n}\r\n\r\n// index handler has no middleware applied.\r\nexport function index (context) { \r\n    \r\n    console.log(context.cascade); // view cascade\r\n\r\n    context.response.send('home')\r\n}\r\n```\r\n\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex will only route functions prefixed with the TypeScript 'export' declarer. This rule\r\nalso applied to modules. Developers can use this to infer notions of public and private \r\nat the http level.\r\n\r\nconsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.send('public_function');\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```javascript\r\n// http:[host]:[port]/\r\nexport function index (context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard (context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n<a name=\"serving_static_files\" />\r\n## serving static files\r\n\r\nUse wildcard functions with context.response.serve() to serve static content.\r\n\r\n```javascript\r\nexport module static {\r\n\t\r\n\t// http:[host]:[port]/static/(.*)\r\n\texport function wildcard(context, path) {\r\n\r\n\t\tcontext.response.serve('./static/', path);\r\n\t}\r\n}\r\n\r\n// http:[host]:[port]/\r\nexport function index (context) {\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n\r\n<a name=\"reflection\" />\r\n## reflection\r\n\r\nappex provides a reflection api derived from TypeScript's type system that developers can \r\nleverage to reflect type information declared throughout their appex modules. \r\n\r\nthe following section outlines how to use the reflection api.\r\n\r\n<a name=\"reflect_everything\" />\r\n### reflect everything\r\n\r\nthe appex reflection api is passed on the context.module.reflection property and is available to all\r\nappex handler methods. The following code will JSON serialize everything declared in your appex\r\nproject and write it to the http response. \r\n\r\n```javascript\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection );\r\n}\r\n```\r\n<a name=\"reflect_specific_types\" />\r\n### reflect specific types\r\n\r\nIn typical scenarios, developers will want to leverage reflection meta data to generate\r\nservice contacts and client side models. the reflection api lets you access meta data \r\nfor the following types declared in your project. \r\n\r\n* modules\r\n* imports\r\n* classes\r\n* interfaces\r\n* functions\r\n* variables\r\n\r\nto access specific type metadata, use the reflection.get([qualifier]) method, as demonstrated below.\r\n\r\n```javascript\r\nexport module models {\r\n    \r\n    export class Customer {\r\n\r\n        public firstname   : string;\r\n\r\n        public lastname    : string;\r\n\r\n        public age         : number;\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('models.Customer') );\r\n}\r\n```\r\nand methods..\r\n\r\n```javascript\r\nfunction some_method(a:string, b:number, c?:boolean) : void { }\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_method') );\r\n}\r\n```\r\n\r\n....and variables...\r\n\r\n```javascript\r\nvar some_variable:number = 10;\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_variable') );\r\n}\r\n```\r\n<a name=\"json_schema\" />\r\n### json schema\r\n\r\nappex supports reflecting back JSON schema meta data from class and interface type definitions. for example, the following\r\nwill output a json schema on the type 'models.Employee'.\r\n\r\n```javascript\r\n\r\nexport module models {\r\n\r\n\texport class Address {\r\n\r\n        /** street */\r\n\t\tpublic addressLine1: string;\r\n        /** suburb */\t\t\r\n        public addressLine2: string;\r\n\t}\r\n\t\r\n\texport class User {\r\n\r\n\t\t/** this users id */\r\n        public id : string;\r\n\t}\r\n\r\n    export class Customer extends User {\r\n        \r\n        /** the customers firstname */\r\n\t\tpublic firstname  : string;\r\n\t\t\r\n        /** the customers lastname */\r\n        public lastname   : string;\r\n    }\r\n\r\n\texport class Employee extends User {\r\n\r\n        /** the employees firstname */\r\n\t\tpublic firstname  : string;\r\n\t\t\r\n        /** the employees lastname */\r\n        public lastname   : string;\r\n\t\t\r\n        /** the employees address */\r\n        public address  : Address;\r\n\r\n        /** this employees customers */\r\n        public customers : Customer[];\r\n\t}\r\n}\r\n\r\nexport function index (context) {\r\n    \r\n    context.response.json( context.schema.get('models.Employee') );\r\n}\r\n\r\n```\r\n\r\nwhich generates the following json schema.\r\n\r\n```javascript\r\n{\r\n    \"id\": \"#models.Employee\",\r\n    \"type\": \"object\",\r\n    \"properties\": {\r\n        \"id\": {\r\n            \"id\": \"id\",\r\n            \"type\": \"string\",\r\n            \"description\": \"this users id\"\r\n        },\r\n        \"firstname\": {\r\n            \"id\": \"firstname\",\r\n            \"type\": \"string\",\r\n            \"description\": \"the employees firstname\"\r\n        },\r\n        \"lastname\": {\r\n            \"id\": \"lastname\",\r\n            \"type\": \"string\",\r\n            \"description\": \"the employees lastname\"\r\n        },\r\n        \"address\": {\r\n            \"id\": \"#models.Address\",\r\n            \"type\": \"object\",\r\n            \"properties\": {\r\n                \"addressLine1\": {\r\n                    \"id\": \"addressLine1\",\r\n                    \"type\": \"string\",\r\n                    \"description\": \"street\"\r\n                },\r\n                \"addressLine2\": {\r\n                    \"id\": \"addressLine2\",\r\n                    \"type\": \"string\",\r\n                    \"description\": \"suburb\"\r\n                }\r\n            }\r\n        },\r\n        \"customers\": {\r\n            \"id\": \"customers\",\r\n            \"type\": \"array\",\r\n            \"items\": {\r\n                \"type\": {\r\n                    \"id\": \"#models.Customer\",\r\n                    \"type\": \"object\",\r\n                    \"properties\": {\r\n                        \"id\": {\r\n                            \"id\": \"id\",\r\n                            \"type\": \"string\",\r\n                            \"description\": \"this users id\"\r\n                        },\r\n                        \"firstname\": {\r\n                            \"id\": \"firstname\",\r\n                            \"type\": \"string\",\r\n                            \"description\": \"the customers firstname\"\r\n                        },\r\n                        \"lastname\": {\r\n                            \"id\": \"lastname\",\r\n                            \"type\": \"string\",\r\n                            \"description\": \"the customers lastname\"\r\n                        }\r\n                    }\r\n                }\r\n            },\r\n            \"description\": \"this employees customers\"\r\n        }\r\n    }\r\n}\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\nThis section outlines development with appex.\r\n\r\n<a name=\"appex_declaration\" />\r\n### appex.d.ts declaration\r\n\r\nIf you develop on a TypeScript complicant editor (one that supports TS 0.9), appex comes bundled\r\nwith a declaration file you can reference in your project. If installing appex via npm, your\r\nreference should be as follows.\r\n\r\n```javascript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nexport function index (context:appex.web.IContext) { \r\n    \r\n    context.response.send('hello');\r\n}\r\n\r\nexport function wildcard(context:appex.web.IContext, path:string) {\r\n\r\n    context.response.serve('./', path);\r\n}\r\n```\r\n\r\nBy referencing this in your project, you get the benefits of code completion and static type checking\r\nagainst both appex, and the nodejs core.\r\n\r\n![](https://raw.github.com/sinclairzx81/appex/master/artifacts/code-completion.jpg)\r\n\r\nAdditional declaration files may be obtained from [here](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex ({ program : './index.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"users.ts\" />\r\n/// <reference path=\"pages.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { context.response.send('users.login') }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { context.response.send('users.logout') }\r\n}\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { context.response.send('home') }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { context.response.send('about') }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { context.response.send('contact') }\r\n\r\nexport function wildcard (context, path) { context.response.send(404, ' not found') }\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"license\" />\r\n## license\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) 2013 Haydn Paterson (sinclair) <haydn.developer@gmail.com>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in\r\nall copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\nTHE SOFTWARE.\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"https://raw.github.com/sinclairzx81/appex/master/license.txt","type":"The MIT License (MIT)"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"nodejs web api with typescript","directories":{},"dependencies":{"typescript.api":"0.5.7"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.4.7":{"name":"appex","version":"0.4.7","keywords":["typescript","web api","reflection","compiler","schema"],"author":{"name":"sinclair"},"_id":"appex@0.4.7","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"c441eae276d4cad8034359e055c3ed77aa45a1bd","tarball":"https://registry.npmjs.org/appex/-/appex-0.4.7.tgz","integrity":"sha512-CgRiFZDQ9/aSxUwFmkKYYODB1rY/0g7z/Bb0gFFIWEmeqcBxNGJqRP+sC6G2+bL4teKMcehTSq+NnVkt7nkE2g==","signatures":[{"sig":"MEUCIDxkh3mQ1anLbsTZH1Xsnu4gKO90y5ajRb/Qx84UhvQMAiEAwxtmjqNndHzqqTGHUzx1I9pQ4t8GT5zzE5TG3LeqPr0=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/artifacts/logo.jpg)\r\n\r\n### nodejs web api with [typescript](http://www.typescriptlang.org/)\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http://localhost:3000/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// http://localhost:3000/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about');\r\n}\r\n\r\n// http://localhost:3000/(.*)\r\nexport function wildcard (context, path) {\r\n    \r\n    context.response.send(404, path + \"not found\");\r\n}\r\n\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n## overview\r\n\r\nappex is a nodejs web api framework built on top of the TypeScript programming language. It enables\r\ndevelopers to create RESTful service endpoints by writing TypeScript functions, as well as providing\r\nreflection / type meta data derived from the languages type system.\r\n\r\n* [getting started](#getting_started)\r\n\t* [application](#application)\r\n\t* [options](#options)\r\n\t* [http server](#http_server)\r\n\t* [express middleware](#express_middleware)\r\n* [creating services with typescript](#creating_services)\r\n\t* [app context](#app_context)\r\n\t* [routing handlers](#routing_handlers)\r\n\t* [handler signatures](#handler_signatures)\r\n\t* [named handlers](#named_handlers)\r\n\t* [index handlers](#index_handlers)\r\n\t* [wildcard handlers](#wildcard_handlers)\r\n\t* [cascades](#cascades)\r\n\t* [http verbs](#http_verbs)\r\n\t* [middleware](#middleware)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [handling 404](#handling_404)\r\n\t* [serving static files](#serving_static_files)\r\n* [reflection](#reflection)\r\n\t* [reflect everything](#reflect_everything)\r\n\t* [reflect specific types](#reflect_specific_types)\r\n\t* [json schema](#json_schema)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [appex.d.ts declaration](#appex_declaration)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n* [license](#license)\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following section outlines configuring appex.\r\n\r\n<a name=\"application\" />\r\n### application\r\n\r\nsetting up. \r\n\r\n```javascript\r\nvar appex   = require('appex');\r\n\r\nvar app   = appex({ program : './program.ts', \r\n                    devmode : true,\r\n                    logging : true });\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"options\" />\r\n### options\r\n\r\nthe following lists the appex startup options.\r\n\r\n```javascript\r\nvar options = { \r\n\t// (required) location of source file.\r\n\tprogram    : './program.ts', \r\n\r\n\t// (optional) recompile on request. (default:false) \r\n\tdevmode    : true,          \r\n\r\n\t// (optional) log to stdout. (default:false) \r\n\tlogging    : true,\r\n\r\n\t// (optional) user defined objects added to the app context.\r\n\tcontext    : {}\r\n};\r\n\r\nvar app = appex( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### http server\r\n\r\nsetting up appex on a nodejs http server.\r\n\r\n```javascript\r\nvar http = require('http');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\nvar server = http.createServer( app );\r\n\r\nserver.listen(3000);\r\n```\r\n<a name=\"express_middleware\" />\r\n### express middleware\r\n\r\nappex is allows developers to augment existing express / connect applications by \r\nway of middleware. The following demonstrates setting up appex as express middleware.\r\n\r\n```javascript\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) ); \r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nBy doing this, appex will attempt to intercept incoming requests. if appex cannot find a matching route for \r\nthe request, it will automatically call the \"next\" function to pass the request on to the next middleware or\r\nexpress handler.\r\n\r\nin addition to this, appex may also function as traditional express middleware. the following example sets up a wildcard\r\nfunction (to match all requests), it prints a message to the console on each request and forwards the request on...\r\n\r\n```javascript\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tconsole.log('hello world!!');\r\n\r\n\tcontext.next(); // pass it on!\r\n}\r\n\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) );\r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nIts important to note that appex will also inheriate the characteristics of the request defined by\r\nother middleware in the stack, or configurations made to express prior. consider the following example \r\nin which the jade view engine is configured. appex will inheritate the response.render() method, passing it on the \r\ncontext.response as follows..\r\n\r\n```javascript\r\n\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\napp.configure(function(){\r\n\r\n  app.set('views', __dirname + '/views');\r\n  \r\n  // set up the jade engine.\r\n  app.set('view engine', 'jade'); \r\n  \r\n  // bind appex\r\n  app.use( appex({program:'./program.ts', devmode:true} ));  \r\n});\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/\r\nexport function index(context) {\r\n\t\r\n\t// jade renderer works!\r\n\tcontext.response.render('index', { title: 'Express' }); \r\n}\r\n```\r\n\r\n<a name=\"creating_services\" />\r\n## creating services with typescript\r\n\r\nThe following section describes how to write http accessible functions with appex.\r\n\r\n<a name=\"app_context\" />\r\n### app context\r\n\r\nAll appex functions are passed a application context object as their first argument. The app context object \r\nencapulates the http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the app context\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.cascade    - appex cascade.\r\n\r\n\t// context.next       - the next function (express middleware)\r\n\t\r\n\t// context.router     - the appex router\r\n\t\r\n\t// context.module     - the module being run (this module)\r\n\r\n\t// context.schema     - json schema api.\r\n\r\n\t// context.mime       - a http mime type utility.\r\n}\r\n```\r\n\r\nit is possible to extend the default objects passed on the context by adding them on the appex startup options. The \r\nfollowing will attach the async module to the context. \r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = appex({ program : './program.ts', \r\n\t\t\t\t  devmode : true, \r\n\t\t\t      context: {\r\n\t\t\t\t\t\tasync : require('async')\r\n\t\t\t\t  }});\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\r\n\t// context.async = passed on the context.\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n```\r\n<a name=\"routing_handlers\" />\r\n### routing handlers\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context) { /* handle route */ }\r\n}\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/(.*)\r\nexport function wildcard (context, path) { /* handle route */ }\r\n\r\n```\r\n\r\n<a name=\"handler_signatures\" />\r\n### handler signatures\r\n\r\nappex supports three function signatures for http routing (named, index and wildcard). Functions that\r\ndo not apply these signatures will not be routed.\r\n\r\n<a name=\"named_handlers\" />\r\n### named handlers\r\n\r\nNamed handlers resolve urls to their current module scope + the name of the function.\r\n\r\nNamed handlers require the following signature:\r\n\r\n* name        - 'anything'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n\r\n// http://[host]:[port]/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about page');\r\n}\r\n\r\n// http://[host]:[port]/users/login\r\nexport module users {\r\n\r\n\texport function login(context) {\r\n\t\t\r\n\t\tcontext.response.send('handle login');\t\r\n\t}\r\n}\r\n\r\n```\r\n\r\n<a name=\"index_handlers\" />\r\n### index handlers\r\n\r\nIndex handlers resolve urls to their current module scope.\r\n\r\nIndex handlers require the following signature:\r\n\r\n* name        - 'index'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) \r\n\t{\t\r\n\t\tcontext.response.send('blog index');\r\n\t}\r\n}\r\n```\r\n\r\n<a name=\"wildcard_handlers\" />\r\n### wildcard handlers\r\n\r\nWildcard handlers resolve their urls to their current module scope + url.\r\n\r\nappex wildcard handlers allow for wildcard routing at a given module scope. Wildcard handlers\r\nsupport 'typed' url argument mapping, as denoted by the arguments annotation.\r\n\r\nIn addition, wildcard handlers also support optional arguments which can be specified with TypeScript's '?' \r\non argument names.\r\n\r\nappex wildcard handlers require the following signature:\r\n\r\n* name        - 'wildcard'\r\n* argument[0] - app context\r\n* argument[n] - 1 or more arguments to be mapped from the url\r\n* returns     - void (optional)\r\n\r\n```javascript\r\ndeclare var console;\r\n\r\nexport module blogs {\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11   - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/11  - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/3rd - not matched - (see number annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01     - matched     - (see ? annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013        - not matched - (month is required)\r\n\t\r\n    export function wildcard(context, year:number, month:number, day?:number) {\r\n\r\n        context.response.json({ year: year, month: month, day: day})\r\n    }\r\n}\r\n\r\n// url : http://[host]:[port]/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// url : http://[host]:[port]/(.*) \r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, 'not found');\r\n}\r\n\r\n```\r\nnote: appex supports boolean, number, string and any annotations on wildcard arguments. if no annotation\r\nis specified, appex interprets the argument as a string. the type 'any' is also interpreted as string.\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"cascades\" />\r\n### cascades\r\n\r\nappex supports a cascading attribute scheme on modules and functions. With this, developers can apply\r\narbituary meta data for modules and functions that will propagate through scope. appex has two special\r\ncascade properties for middleware and http verb matching, which are described below, however consider\r\nthe following code which illustrates the concept.\r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ncascade({a: 10}); // global.\r\n\r\ncascade('foo', {b : 20})\r\nexport module foo {\r\n\r\n    cascade('foo.bar', {c : 30})\r\n    export module bar {\r\n            \r\n        cascade('foo.bar.index', {d : 40})\r\n        export function index(context) {\r\n        \r\n            //context.cascade\r\n            //{\r\n            //    \"a\": 10,\r\n            //    \"b\": 20,\r\n            //    \"c\": 30,\r\n\t\t\t//    \"d\": 40\r\n            //}\r\n\r\n            context.response.json( context.cascade );       \r\n        }\r\n    }\r\n}\r\n\r\n```\r\n\r\n<a name=\"http_verbs\" />\r\n### http verbs\r\n\r\nappex handles http verb matching with cascades. appex will recognise the \r\n'verbs' property applied to the cascade to match against http verbs.\r\n\r\n```javascript\r\ncascade('index', { verbs: ['get'] })\r\nexport function index (context) { \r\n        \r\n    // only allow HTTP GET requests\r\n    context.response.send('index')\r\n}\r\n\r\ncascade('index', { verbs: ['post', 'put'] })\r\nexport function submit (context) { \r\n    \r\n    // only allow HTTP POST and PUT requests\r\n    context.response.send('submit')\r\n}\r\n```\r\n\r\n\r\n<a name=\"middleware\" />\r\n### middleware\r\n\r\nappex supports middleware with cascades. appex middleware defined with cascades allows\r\ndevelopers to scope middleware on single functions, or entire module scopes. appex will \r\nrecognise the 'use' property applied to the cascade to invoke middleware.\r\n\r\nthe following demonstrates how one might use middleware to secure a site admin.\r\n\r\nnote: middleware 'must' call next or handle the request. \r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ndeclare var console;\r\n\r\nfunction authenticate(context) {\r\n\r\n    console.log('authenticate')\r\n\r\n\t// call next() if authenticated, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\nfunction authorize(context) {\r\n\r\n    console.log('authorize')\r\n\r\n\t// call next() if authorized, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\n// apply security middleware to admin scope.\r\ncascade('admin', {use: [authenticate, authorize]}) \r\nexport module admin {\r\n\r\n    export function index(context) {\r\n        \r\n        console.log(context.cascade); // view cascade\r\n\r\n        context.response.send('access granted!')\r\n    }\r\n}\r\n\r\n// index handler has no middleware applied.\r\nexport function index (context) { \r\n    \r\n    console.log(context.cascade); // view cascade\r\n\r\n    context.response.send('home')\r\n}\r\n```\r\n\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex will only route functions prefixed with the TypeScript 'export' declarer. This rule\r\nalso applied to modules. Developers can use this to infer notions of public and private \r\nat the http level.\r\n\r\nconsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.send('public_function');\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```javascript\r\n// http:[host]:[port]/\r\nexport function index (context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard (context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n<a name=\"serving_static_files\" />\r\n## serving static files\r\n\r\nUse wildcard functions with context.response.serve() to serve static content.\r\n\r\n```javascript\r\nexport module static {\r\n\t\r\n\t// http:[host]:[port]/static/(.*)\r\n\texport function wildcard(context, path) {\r\n\r\n\t\tcontext.response.serve('./static/', path);\r\n\t}\r\n}\r\n\r\n// http:[host]:[port]/\r\nexport function index (context) {\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n\r\n<a name=\"reflection\" />\r\n## reflection\r\n\r\nappex provides a reflection api derived from TypeScript's type system that developers can \r\nleverage to reflect type information declared throughout their appex modules. \r\n\r\nthe following section outlines how to use the reflection api.\r\n\r\n<a name=\"reflect_everything\" />\r\n### reflect everything\r\n\r\nthe appex reflection api is passed on the context.module.reflection property and is available to all\r\nappex handler methods. The following code will JSON serialize everything declared in your appex\r\nproject and write it to the http response. \r\n\r\n```javascript\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection );\r\n}\r\n```\r\n<a name=\"reflect_specific_types\" />\r\n### reflect specific types\r\n\r\nIn typical scenarios, developers will want to leverage reflection meta data to generate\r\nservice contacts and client side models. the reflection api lets you access meta data \r\nfor the following types declared in your project. \r\n\r\n* modules\r\n* imports\r\n* classes\r\n* interfaces\r\n* functions\r\n* variables\r\n\r\nto access specific type metadata, use the reflection.get([qualifier]) method, as demonstrated below.\r\n\r\n```javascript\r\nexport module models {\r\n    \r\n    export class Customer {\r\n\r\n        public firstname   : string;\r\n\r\n        public lastname    : string;\r\n\r\n        public age         : number;\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('models.Customer') );\r\n}\r\n```\r\nand methods..\r\n\r\n```javascript\r\nfunction some_method(a:string, b:number, c?:boolean) : void { }\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_method') );\r\n}\r\n```\r\n\r\n....and variables...\r\n\r\n```javascript\r\nvar some_variable:number = 10;\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_variable') );\r\n}\r\n```\r\n<a name=\"json_schema\" />\r\n### json schema\r\n\r\nappex supports reflecting back JSON schema meta data from class and interface type definitions. for example, the following\r\nwill output a json schema on the type 'models.Employee'.\r\n\r\n```javascript\r\n\r\nexport module models {\r\n\r\n\texport class Address {\r\n\r\n        /** street */\r\n\t\tpublic addressLine1: string;\r\n        /** suburb */\t\t\r\n        public addressLine2: string;\r\n\t}\r\n\t\r\n\texport class User {\r\n\r\n\t\t/** this users id */\r\n        public id : string;\r\n\t}\r\n\r\n    export class Customer extends User {\r\n        \r\n        /** the customers firstname */\r\n\t\tpublic firstname  : string;\r\n\t\t\r\n        /** the customers lastname */\r\n        public lastname   : string;\r\n    }\r\n\r\n\texport class Employee extends User {\r\n\r\n        /** the employees firstname */\r\n\t\tpublic firstname  : string;\r\n\t\t\r\n        /** the employees lastname */\r\n        public lastname   : string;\r\n\t\t\r\n        /** the employees address */\r\n        public address  : Address;\r\n\r\n        /** this employees customers */\r\n        public customers : Customer[];\r\n\t}\r\n}\r\n\r\nexport function index (context) {\r\n    \r\n    context.response.json( context.schema.get('models.Employee') );\r\n}\r\n\r\n```\r\n\r\nwhich generates the following json schema.\r\n\r\n```javascript\r\n{\r\n    \"id\": \"#models.Employee\",\r\n    \"type\": \"object\",\r\n    \"properties\": {\r\n        \"id\": {\r\n            \"id\": \"id\",\r\n            \"type\": \"string\",\r\n            \"description\": \"this users id\"\r\n        },\r\n        \"firstname\": {\r\n            \"id\": \"firstname\",\r\n            \"type\": \"string\",\r\n            \"description\": \"the employees firstname\"\r\n        },\r\n        \"lastname\": {\r\n            \"id\": \"lastname\",\r\n            \"type\": \"string\",\r\n            \"description\": \"the employees lastname\"\r\n        },\r\n        \"address\": {\r\n            \"id\": \"#models.Address\",\r\n            \"type\": \"object\",\r\n            \"properties\": {\r\n                \"addressLine1\": {\r\n                    \"id\": \"addressLine1\",\r\n                    \"type\": \"string\",\r\n                    \"description\": \"street\"\r\n                },\r\n                \"addressLine2\": {\r\n                    \"id\": \"addressLine2\",\r\n                    \"type\": \"string\",\r\n                    \"description\": \"suburb\"\r\n                }\r\n            }\r\n        },\r\n        \"customers\": {\r\n            \"id\": \"customers\",\r\n            \"type\": \"array\",\r\n            \"items\": {\r\n                \"type\": {\r\n                    \"id\": \"#models.Customer\",\r\n                    \"type\": \"object\",\r\n                    \"properties\": {\r\n                        \"id\": {\r\n                            \"id\": \"id\",\r\n                            \"type\": \"string\",\r\n                            \"description\": \"this users id\"\r\n                        },\r\n                        \"firstname\": {\r\n                            \"id\": \"firstname\",\r\n                            \"type\": \"string\",\r\n                            \"description\": \"the customers firstname\"\r\n                        },\r\n                        \"lastname\": {\r\n                            \"id\": \"lastname\",\r\n                            \"type\": \"string\",\r\n                            \"description\": \"the customers lastname\"\r\n                        }\r\n                    }\r\n                }\r\n            },\r\n            \"description\": \"this employees customers\"\r\n        }\r\n    }\r\n}\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\nThis section outlines development with appex.\r\n\r\n<a name=\"appex_declaration\" />\r\n### appex.d.ts declaration\r\n\r\nIf you develop on a TypeScript complicant editor (one that supports TS 0.9), appex comes bundled\r\nwith a declaration file you can reference in your project. If installing appex via npm, your\r\nreference should be as follows.\r\n\r\n```javascript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nexport function index (context:appex.web.IContext) { \r\n    \r\n    context.response.send('hello');\r\n}\r\n\r\nexport function wildcard(context:appex.web.IContext, path:string) {\r\n\r\n    context.response.serve('./', path);\r\n}\r\n```\r\n\r\nBy referencing this in your project, you get the benefits of code completion and static type checking\r\nagainst both appex, and the nodejs core.\r\n\r\n![](https://raw.github.com/sinclairzx81/appex/master/artifacts/code-completion.jpg)\r\n\r\nAdditional declaration files may be obtained from [here](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex ({ program : './index.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"users.ts\" />\r\n/// <reference path=\"pages.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { context.response.send('users.login') }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { context.response.send('users.logout') }\r\n}\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { context.response.send('home') }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { context.response.send('about') }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { context.response.send('contact') }\r\n\r\nexport function wildcard (context, path) { context.response.send(404, ' not found') }\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"license\" />\r\n## license\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) 2013 Haydn Paterson (sinclair) <haydn.developer@gmail.com>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in\r\nall copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\nTHE SOFTWARE.\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"https://raw.github.com/sinclairzx81/appex/master/license.txt","type":"The MIT License (MIT)"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"nodejs web api with typescript","directories":{},"dependencies":{"typescript.api":"0.5.8"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.4.8":{"name":"appex","version":"0.4.8","keywords":["typescript","web api","reflection","compiler","schema"],"author":{"name":"sinclair"},"_id":"appex@0.4.8","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"c513ce201acf41b9ee1a87a6833305a262f6fc0d","tarball":"https://registry.npmjs.org/appex/-/appex-0.4.8.tgz","integrity":"sha512-rxHUSBS/XjATqdGC0JOzj4qcGV5DADuQM2l0l1Qgbser3veTUGE7boXwlJGxK9UJwsX0qqzPiblkiKCS2s1ZlQ==","signatures":[{"sig":"MEUCIQCQ6eqJ25TTyqpTfjw5COf96SCR4bFhgg3AE5IdEZN+/QIgLD6K3HR3EqiGuIAefOZXSbuV9ZtqN3GZzURuYutUvUw=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/artifacts/logo.jpg)\r\n\r\n### nodejs web api with [typescript](http://www.typescriptlang.org/)\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http://localhost:3000/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// http://localhost:3000/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about');\r\n}\r\n\r\n// http://localhost:3000/(.*)\r\nexport function wildcard (context, path) {\r\n    \r\n    context.response.send(404, path + \"not found\");\r\n}\r\n\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n## overview\r\n\r\nappex is a nodejs web api framework built on top of the TypeScript programming language. It enables\r\ndevelopers to create RESTful service endpoints by writing TypeScript functions, as well as providing\r\nreflection / type meta data derived from the languages type system.\r\n\r\n* [getting started](#getting_started)\r\n\t* [application](#application)\r\n\t* [options](#options)\r\n\t* [http server](#http_server)\r\n\t* [express middleware](#express_middleware)\r\n* [creating services with typescript](#creating_services)\r\n\t* [app context](#app_context)\r\n\t* [routing handlers](#routing_handlers)\r\n\t* [handler signatures](#handler_signatures)\r\n\t* [named handlers](#named_handlers)\r\n\t* [index handlers](#index_handlers)\r\n\t* [wildcard handlers](#wildcard_handlers)\r\n\t* [cascades](#cascades)\r\n\t* [http verbs](#http_verbs)\r\n\t* [middleware](#middleware)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [handling 404](#handling_404)\r\n\t* [serving static files](#serving_static_files)\r\n* [reflection](#reflection)\r\n\t* [reflect everything](#reflect_everything)\r\n\t* [reflect specific types](#reflect_specific_types)\r\n\t* [json schema](#json_schema)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [appex.d.ts declaration](#appex_declaration)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n* [license](#license)\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following section outlines configuring appex.\r\n\r\n<a name=\"application\" />\r\n### application\r\n\r\nsetting up. \r\n\r\n```javascript\r\nvar appex   = require('appex');\r\n\r\nvar app   = appex({ program : './program.ts', \r\n                    devmode : true,\r\n                    logging : true });\r\n\r\napp.listen(3000);\r\n```\r\n\r\n<a name=\"options\" />\r\n### options\r\n\r\nthe following lists the appex startup options.\r\n\r\n```javascript\r\nvar options = { \r\n\t// (required) location of source file.\r\n\tprogram    : './program.ts', \r\n\r\n\t// (optional) recompile on request. (default:false) \r\n\tdevmode    : true,          \r\n\r\n\t// (optional) log to stdout. (default:false) \r\n\tlogging    : true,\r\n\r\n\t// (optional) user defined objects added to the app context.\r\n\tcontext    : {}\r\n};\r\n\r\nvar app = appex( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### http server\r\n\r\nsetting up appex on a nodejs http server.\r\n\r\n```javascript\r\nvar http = require('http');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\nvar server = http.createServer( app );\r\n\r\nserver.listen(3000);\r\n```\r\n<a name=\"express_middleware\" />\r\n### express middleware\r\n\r\nappex is allows developers to augment existing express / connect applications by \r\nway of middleware. The following demonstrates setting up appex as express middleware.\r\n\r\n```javascript\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) ); \r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nBy doing this, appex will attempt to intercept incoming requests. if appex cannot find a matching route for \r\nthe request, it will automatically call the \"next\" function to pass the request on to the next middleware or\r\nexpress handler.\r\n\r\nin addition to this, appex may also function as traditional express middleware. the following example sets up a wildcard\r\nfunction (to match all requests), it prints a message to the console on each request and forwards the request on...\r\n\r\n```javascript\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tconsole.log('hello world!!');\r\n\r\n\tcontext.next(); // pass it on!\r\n}\r\n\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) );\r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nIts important to note that appex will also inheriate the characteristics of the request defined by\r\nother middleware in the stack, or configurations made to express prior. consider the following example \r\nin which the jade view engine is configured. appex will inheritate the response.render() method, passing it on the \r\ncontext.response as follows..\r\n\r\n```javascript\r\n\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\napp.configure(function(){\r\n\r\n  app.set('views', __dirname + '/views');\r\n  \r\n  // set up the jade engine.\r\n  app.set('view engine', 'jade'); \r\n  \r\n  // bind appex\r\n  app.use( appex({program:'./program.ts', devmode:true} ));  \r\n});\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/\r\nexport function index(context) {\r\n\t\r\n\t// jade renderer works!\r\n\tcontext.response.render('index', { title: 'Express' }); \r\n}\r\n```\r\n\r\n<a name=\"creating_services\" />\r\n## creating services with typescript\r\n\r\nThe following section describes how to write http accessible functions with appex.\r\n\r\n<a name=\"app_context\" />\r\n### app context\r\n\r\nAll appex functions are passed a application context object as their first argument. The app context object \r\nencapulates the http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the app context\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.cascade    - appex cascade.\r\n\r\n\t// context.next       - the next function (express middleware)\r\n\t\r\n\t// context.router     - the appex router\r\n\t\r\n\t// context.module     - the module being run (this module)\r\n\r\n\t// context.schema     - json schema api.\r\n\r\n\t// context.mime       - a http mime type utility.\r\n}\r\n```\r\n\r\nit is possible to extend the default objects passed on the context by adding them on the appex startup options. The \r\nfollowing will attach the async module to the context. \r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = appex({ program : './program.ts', \r\n\t\t\t\t  devmode : true, \r\n\t\t\t      context: {\r\n\t\t\t\t\t\tasync : require('async')\r\n\t\t\t\t  }});\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\r\n\t// context.async = passed on the context.\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n```\r\n<a name=\"routing_handlers\" />\r\n### routing handlers\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context) { /* handle route */ }\r\n}\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/(.*)\r\nexport function wildcard (context, path) { /* handle route */ }\r\n\r\n```\r\n\r\n<a name=\"handler_signatures\" />\r\n### handler signatures\r\n\r\nappex supports three function signatures for http routing (named, index and wildcard). Functions that\r\ndo not apply these signatures will not be routed.\r\n\r\n<a name=\"named_handlers\" />\r\n### named handlers\r\n\r\nNamed handlers resolve urls to their current module scope + the name of the function.\r\n\r\nNamed handlers require the following signature:\r\n\r\n* name        - 'anything'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n\r\n// http://[host]:[port]/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about page');\r\n}\r\n\r\n// http://[host]:[port]/users/login\r\nexport module users {\r\n\r\n\texport function login(context) {\r\n\t\t\r\n\t\tcontext.response.send('handle login');\t\r\n\t}\r\n}\r\n\r\n```\r\n\r\n<a name=\"index_handlers\" />\r\n### index handlers\r\n\r\nIndex handlers resolve urls to their current module scope.\r\n\r\nIndex handlers require the following signature:\r\n\r\n* name        - 'index'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) \r\n\t{\t\r\n\t\tcontext.response.send('blog index');\r\n\t}\r\n}\r\n```\r\n\r\n<a name=\"wildcard_handlers\" />\r\n### wildcard handlers\r\n\r\nWildcard handlers resolve their urls to their current module scope + url.\r\n\r\nappex wildcard handlers allow for wildcard routing at a given module scope. Wildcard handlers\r\nsupport 'typed' url argument mapping, as denoted by the arguments annotation.\r\n\r\nIn addition, wildcard handlers also support optional arguments which can be specified with TypeScript's '?' \r\non argument names.\r\n\r\nappex wildcard handlers require the following signature:\r\n\r\n* name        - 'wildcard'\r\n* argument[0] - app context\r\n* argument[n] - 1 or more arguments to be mapped from the url\r\n* returns     - void (optional)\r\n\r\n```javascript\r\ndeclare var console;\r\n\r\nexport module blogs {\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11   - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/11  - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/3rd - not matched - (see number annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01     - matched     - (see ? annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013        - not matched - (month is required)\r\n\t\r\n    export function wildcard(context, year:number, month:number, day?:number) {\r\n\r\n        context.response.json({ year: year, month: month, day: day})\r\n    }\r\n}\r\n\r\n// url : http://[host]:[port]/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// url : http://[host]:[port]/(.*) \r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, 'not found');\r\n}\r\n\r\n```\r\nnote: appex supports boolean, number, string and any annotations on wildcard arguments. if no annotation\r\nis specified, appex interprets the argument as a string. the type 'any' is also interpreted as string.\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"cascades\" />\r\n### cascades\r\n\r\nappex supports a cascading attribute scheme on modules and functions. With this, developers can apply\r\narbituary meta data for modules and functions that will propagate through scope. appex has two special\r\ncascade properties for middleware and http verb matching, which are described below, however consider\r\nthe following code which illustrates the concept.\r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ncascade({a: 10}); // global.\r\n\r\ncascade('foo', {b : 20})\r\nexport module foo {\r\n\r\n    cascade('foo.bar', {c : 30})\r\n    export module bar {\r\n            \r\n        cascade('foo.bar.index', {d : 40})\r\n        export function index(context) {\r\n        \r\n            //context.cascade\r\n            //{\r\n            //    \"a\": 10,\r\n            //    \"b\": 20,\r\n            //    \"c\": 30,\r\n\t\t\t//    \"d\": 40\r\n            //}\r\n\r\n            context.response.json( context.cascade );       \r\n        }\r\n    }\r\n}\r\n\r\n```\r\n\r\n<a name=\"http_verbs\" />\r\n### http verbs\r\n\r\nappex handles http verb matching with cascades. appex will recognise the \r\n'verbs' property applied to the cascade to match against http verbs.\r\n\r\n```javascript\r\ncascade('index', { verbs: ['get'] })\r\nexport function index (context) { \r\n        \r\n    // only allow HTTP GET requests\r\n    context.response.send('index')\r\n}\r\n\r\ncascade('index', { verbs: ['post', 'put'] })\r\nexport function submit (context) { \r\n    \r\n    // only allow HTTP POST and PUT requests\r\n    context.response.send('submit')\r\n}\r\n```\r\n\r\n\r\n<a name=\"middleware\" />\r\n### middleware\r\n\r\nappex supports middleware with cascades. appex middleware defined with cascades allows\r\ndevelopers to scope middleware on single functions, or entire module scopes. appex will \r\nrecognise the 'use' property applied to the cascade to invoke middleware.\r\n\r\nthe following demonstrates how one might use middleware to secure a site admin.\r\n\r\nnote: middleware 'must' call next or handle the request. \r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ndeclare var console;\r\n\r\nfunction authenticate(context) {\r\n\r\n    console.log('authenticate')\r\n\r\n\t// call next() if authenticated, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\nfunction authorize(context) {\r\n\r\n    console.log('authorize')\r\n\r\n\t// call next() if authorized, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\n// apply security middleware to admin scope.\r\ncascade('admin', {use: [authenticate, authorize]}) \r\nexport module admin {\r\n\r\n    export function index(context) {\r\n        \r\n        console.log(context.cascade); // view cascade\r\n\r\n        context.response.send('access granted!')\r\n    }\r\n}\r\n\r\n// index handler has no middleware applied.\r\nexport function index (context) { \r\n    \r\n    console.log(context.cascade); // view cascade\r\n\r\n    context.response.send('home')\r\n}\r\n```\r\n\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex will only route functions prefixed with the TypeScript 'export' declarer. This rule\r\nalso applied to modules. Developers can use this to infer notions of public and private \r\nat the http level.\r\n\r\nconsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.send('public_function');\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```javascript\r\n// http:[host]:[port]/\r\nexport function index (context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard (context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n<a name=\"serving_static_files\" />\r\n## serving static files\r\n\r\nUse wildcard functions with context.response.serve() to serve static content.\r\n\r\n```javascript\r\nexport module static {\r\n\t\r\n\t// http:[host]:[port]/static/(.*)\r\n\texport function wildcard(context, path) {\r\n\r\n\t\tcontext.response.serve('./static/', path);\r\n\t}\r\n}\r\n\r\n// http:[host]:[port]/\r\nexport function index (context) {\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n\r\n<a name=\"reflection\" />\r\n## reflection\r\n\r\nappex provides a reflection api derived from TypeScript's type system that developers can \r\nleverage to reflect type information declared throughout their appex modules. \r\n\r\nthe following section outlines how to use the reflection api.\r\n\r\n<a name=\"reflect_everything\" />\r\n### reflect everything\r\n\r\nthe appex reflection api is passed on the context.module.reflection property and is available to all\r\nappex handler methods. The following code will JSON serialize everything declared in your appex\r\nproject and write it to the http response. \r\n\r\n```javascript\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection );\r\n}\r\n```\r\n<a name=\"reflect_specific_types\" />\r\n### reflect specific types\r\n\r\nIn typical scenarios, developers will want to leverage reflection meta data to generate\r\nservice contacts and client side models. the reflection api lets you access meta data \r\nfor the following types declared in your project. \r\n\r\n* modules\r\n* imports\r\n* classes\r\n* interfaces\r\n* functions\r\n* variables\r\n\r\nto access specific type metadata, use the reflection.get([qualifier]) method, as demonstrated below.\r\n\r\n```javascript\r\nexport module models {\r\n    \r\n    export class Customer {\r\n\r\n        public firstname   : string;\r\n\r\n        public lastname    : string;\r\n\r\n        public age         : number;\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('models.Customer') );\r\n}\r\n```\r\nand methods..\r\n\r\n```javascript\r\nfunction some_method(a:string, b:number, c?:boolean) : void { }\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_method') );\r\n}\r\n```\r\n\r\n....and variables...\r\n\r\n```javascript\r\nvar some_variable:number = 10;\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_variable') );\r\n}\r\n```\r\n<a name=\"json_schema\" />\r\n### json schema\r\n\r\nappex supports reflecting back JSON schema meta data from class and interface type definitions. for example, the following\r\nwill output a json schema on the type 'models.Employee'.\r\n\r\n```javascript\r\n\r\nexport module models {\r\n\r\n\texport class Address {\r\n\r\n        /** street */\r\n\t\tpublic addressLine1: string;\r\n        /** suburb */\t\t\r\n        public addressLine2: string;\r\n\t}\r\n\t\r\n\texport class User {\r\n\r\n\t\t/** this users id */\r\n        public id : string;\r\n\t}\r\n\r\n    export class Customer extends User {\r\n        \r\n        /** the customers firstname */\r\n\t\tpublic firstname  : string;\r\n\t\t\r\n        /** the customers lastname */\r\n        public lastname   : string;\r\n    }\r\n\r\n\texport class Employee extends User {\r\n\r\n        /** the employees firstname */\r\n\t\tpublic firstname  : string;\r\n\t\t\r\n        /** the employees lastname */\r\n        public lastname   : string;\r\n\t\t\r\n        /** the employees address */\r\n        public address  : Address;\r\n\r\n        /** this employees customers */\r\n        public customers : Customer[];\r\n\t}\r\n}\r\n\r\nexport function index (context) {\r\n    \r\n    context.response.json( context.schema.get('models.Employee') );\r\n}\r\n\r\n```\r\n\r\nwhich generates the following json schema.\r\n\r\n```javascript\r\n{\r\n    \"id\": \"#models.Employee\",\r\n    \"type\": \"object\",\r\n    \"properties\": {\r\n        \"id\": {\r\n            \"id\": \"id\",\r\n            \"type\": \"string\",\r\n            \"description\": \"this users id\"\r\n        },\r\n        \"firstname\": {\r\n            \"id\": \"firstname\",\r\n            \"type\": \"string\",\r\n            \"description\": \"the employees firstname\"\r\n        },\r\n        \"lastname\": {\r\n            \"id\": \"lastname\",\r\n            \"type\": \"string\",\r\n            \"description\": \"the employees lastname\"\r\n        },\r\n        \"address\": {\r\n            \"id\": \"#models.Address\",\r\n            \"type\": \"object\",\r\n            \"properties\": {\r\n                \"addressLine1\": {\r\n                    \"id\": \"addressLine1\",\r\n                    \"type\": \"string\",\r\n                    \"description\": \"street\"\r\n                },\r\n                \"addressLine2\": {\r\n                    \"id\": \"addressLine2\",\r\n                    \"type\": \"string\",\r\n                    \"description\": \"suburb\"\r\n                }\r\n            }\r\n        },\r\n        \"customers\": {\r\n            \"id\": \"customers\",\r\n            \"type\": \"array\",\r\n            \"items\": {\r\n                \"type\": {\r\n                    \"id\": \"#models.Customer\",\r\n                    \"type\": \"object\",\r\n                    \"properties\": {\r\n                        \"id\": {\r\n                            \"id\": \"id\",\r\n                            \"type\": \"string\",\r\n                            \"description\": \"this users id\"\r\n                        },\r\n                        \"firstname\": {\r\n                            \"id\": \"firstname\",\r\n                            \"type\": \"string\",\r\n                            \"description\": \"the customers firstname\"\r\n                        },\r\n                        \"lastname\": {\r\n                            \"id\": \"lastname\",\r\n                            \"type\": \"string\",\r\n                            \"description\": \"the customers lastname\"\r\n                        }\r\n                    }\r\n                }\r\n            },\r\n            \"description\": \"this employees customers\"\r\n        }\r\n    }\r\n}\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\nThis section outlines development with appex.\r\n\r\n<a name=\"appex_declaration\" />\r\n### appex.d.ts declaration\r\n\r\nIf you develop on a TypeScript complicant editor (one that supports TS 0.9), appex comes bundled\r\nwith a declaration file you can reference in your project. If installing appex via npm, your\r\nreference should be as follows.\r\n\r\n```javascript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nexport function index (context:appex.web.IContext) { \r\n    \r\n    context.response.send('hello');\r\n}\r\n\r\nexport function wildcard(context:appex.web.IContext, path:string) {\r\n\r\n    context.response.serve('./', path);\r\n}\r\n```\r\n\r\nBy referencing this in your project, you get the benefits of code completion and static type checking\r\nagainst both appex, and the nodejs core.\r\n\r\n![](https://raw.github.com/sinclairzx81/appex/master/artifacts/code-completion.jpg)\r\n\r\nAdditional declaration files may be obtained from [here](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex ({ program : './index.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"users.ts\" />\r\n/// <reference path=\"pages.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { context.response.send('users.login') }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { context.response.send('users.logout') }\r\n}\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { context.response.send('home') }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { context.response.send('about') }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { context.response.send('contact') }\r\n\r\nexport function wildcard (context, path) { context.response.send(404, ' not found') }\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"license\" />\r\n## license\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) 2013 Haydn Paterson (sinclair) <haydn.developer@gmail.com>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in\r\nall copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\nTHE SOFTWARE.\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"https://raw.github.com/sinclairzx81/appex/master/license.txt","type":"The MIT License (MIT)"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"nodejs web api with typescript","directories":{},"dependencies":{"typescript.api":"0.5.9"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.4.9":{"name":"appex","version":"0.4.9","keywords":["typescript","web api","reflection","compiler","schema"],"author":{"name":"sinclair"},"_id":"appex@0.4.9","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"529dbba5fbb6ffff4b2651aeed04d9a3d94fb043","tarball":"https://registry.npmjs.org/appex/-/appex-0.4.9.tgz","integrity":"sha512-JCYYhiKJ5VgBinAyOS2NVxCtqtf1htqDZZ3FqCSPAV/KuOxjp5iE/PrbR4h6lCYF3z5UqdZ3FVBIxi3SxwDoZA==","signatures":[{"sig":"MEYCIQCCzBDcfvOMHElZ2oYIdSzlEOY4Tl/BMO+I/Whi44GBHgIhAIkuNy7O4ObO3UPUqyzXZ/2CmmURG6d87cFe2Vug+qmb","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/artifacts/logo.jpg)\r\n\r\n### nodejs web api with [typescript](http://www.typescriptlang.org/)\r\n\r\n## overview\r\n\r\nappex is a nodejs web framework built around the TypeScript programming language and\r\ncompiler. appex lets developers create and route http endpoints with TypeScript modules and \r\nfunctions, as well as providing nodejs developers similar reflection and type introspection \r\nservices found in platforms such as .net.\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http://localhost:3000/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// http://localhost:3000/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about');\r\n}\r\n\r\n// http://localhost:3000/(.*)\r\nexport function wildcard (context, path) {\r\n    \r\n    context.response.send(404, path + \" not found\");\r\n}\r\n\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n### contents\r\n\r\n* [getting started](#getting_started)\r\n\t* [create a application](#application)\r\n\t* [start up options](#options)\r\n\t* [running on an existing http server](#http_server)\r\n\t* [running as express middleware](#express_middleware)\r\n* [creating services with typescript](#creating_services)\r\n\t* [app context](#app_context)\r\n\t* [routing handlers](#routing_handlers)\r\n\t* [handler signatures](#handler_signatures)\r\n\t* [named handlers](#named_handlers)\r\n\t* [index handlers](#index_handlers)\r\n\t* [wildcard handlers](#wildcard_handlers)\r\n\t* [cascades](#cascades)\r\n\t* [http verbs](#http_verbs)\r\n\t* [middleware](#middleware)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [handling 404](#handling_404)\r\n\t* [serving static files](#serving_static_files)\r\n* [reflection](#reflection)\r\n\t* [reflect everything](#reflect_everything)\r\n\t* [reflect specific types](#reflect_specific_types)\r\n\t* [json schema](#json_schema)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [appex.d.ts declaration](#appex_declaration)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n* [license](#license)\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline creating appex applications and configuration.\r\n\r\n<a name=\"application\" />\r\n### create a application\r\n\r\nThe following code will create a standalone appex application and \r\nhttp server and listen on port 3000.\r\n\r\n```javascript\r\nvar appex   = require('appex');\r\n\r\nvar app   = appex({ program : './program.ts', \r\n                    devmode : true,\r\n                    logging : true });\r\n\r\napp.listen(3000);\r\n```\r\n\r\nnote: devmode and logging are optional. however, when developing \r\nwith appex, it is helpful to have these enabled.\r\n\r\n<a name=\"options\" />\r\n### start up options\r\n\r\nappex accepts the following start up options.\r\n\r\n```javascript\r\nvar options = {\r\n\r\n\t// (required) location of source file.\r\n\tprogram    : './program.ts', \r\n\r\n\t// (optional) recompile on request. (default:false) \r\n\tdevmode    : true,          \r\n\r\n\t// (optional) log to stdout. (default:false) \r\n\tlogging    : true,\r\n\r\n\t// (optional) user defined objects added to the app context.\r\n\tcontext    : {}\r\n};\r\n\r\nvar app = appex( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### running on an existing http server\r\n\r\nThe following demonstrates setting up appex on an existing nodejs http server. In \r\nthis example, appex will attempt to handle incoming requests, and if appex cannot\r\nroute the request, will fire the callback.\r\n\r\n```javascript\r\nvar http  = require('http');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\nvar server = http.createServer(function(req, res){\r\n\r\n    app(req, res, function() { // appex handler...\r\n\t\t\r\n\t\t// not handled.\r\n\r\n\t}); \r\n});\r\n\r\nserver.listen(3000);\r\n```\r\n\r\n\r\n<a name=\"express_middleware\" />\r\n### running as express middleware\r\n\r\nappex allows developers to augment existing express / connect applications by \r\nway of middleware. The following demonstrates setting up appex as express middleware.\r\n\r\n```javascript\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) ); \r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nLike in the \"running on an existing http server\" example above, appex will attempt to intercept incoming requests. \r\nif appex cannot find a matching route for the request, it will automatically call the \"next\" function to pass the request \r\non to the next middleware or express handler.\r\n\r\nin addition to this, appex may also act as traditional express middleware. In the example below, a appex wildcard\r\nfunction is created which will match \"all\" incoming requests, the wildcard function simply prints hello world to \r\nthe console and then calls context.next(), which passes the request on the express handler.\r\n\r\n```javascript\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tconsole.log('hello world!!');\r\n\r\n\tcontext.next(); // pass it on!\r\n}\r\n\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) );\r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nJust like traditional express middleware, appex will also inheriate the characteristics of the request.\r\n\r\nconsider the following example in which the jade view engine is configured for use. appex will inheritate the \r\nresponse.render() method, which is passed to the appex handler as context.response.render()\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\napp.configure(function(){\r\n\r\n  app.set('views', __dirname + '/views');\r\n  \r\n  // set up the jade engine.\r\n  app.set('view engine', 'jade'); \r\n  \r\n  // bind appex\r\n  app.use( appex({program:'./program.ts', devmode:true} ));  \r\n});\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/\r\nexport function index(context) {\r\n\t\r\n\t// jade renderer works!\r\n\tcontext.response.render('index', { title: 'Express' }); \r\n}\r\n```\r\n\r\n<a name=\"creating_services\" />\r\n## creating services with typescript\r\n\r\nThe following section describes how to write http accessible functions with appex.\r\n\r\n<a name=\"app_context\" />\r\n### app context\r\n\r\nAll appex functions are passed a application context object as their first argument. The app context object \r\nencapulates the http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the app context\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.cascade    - appex cascade.\r\n\r\n\t// context.next       - the next function (express middleware)\r\n\t\r\n\t// context.router     - the appex router\r\n\t\r\n\t// context.module     - the module being run (this module)\r\n\r\n\t// context.schema     - json schema api.\r\n\r\n\t// context.mime       - a http mime type utility.\r\n}\r\n```\r\n\r\nit is possible to extend the default objects passed on the context by adding them on the appex startup options. The \r\nfollowing will attach the async module to the context. \r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = appex({ program : './program.ts', \r\n\t\t\t\t  devmode : true, \r\n\t\t\t      context: {\r\n\t\t\t\t\t\tasync : require('async')\r\n\t\t\t\t  }});\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\r\n\t// context.async = passed on the context.\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n```\r\n<a name=\"routing_handlers\" />\r\n### routing handlers\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context) { /* handle route */ }\r\n}\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/(.*)\r\nexport function wildcard (context, path) { /* handle route */ }\r\n\r\n```\r\n\r\n<a name=\"handler_signatures\" />\r\n### handler signatures\r\n\r\nappex supports three function signatures for http routing (named, index and wildcard). Functions that\r\ndo not apply these signatures will not be routed.\r\n\r\n<a name=\"named_handlers\" />\r\n### named handlers\r\n\r\nNamed handlers resolve urls to their current module scope + the name of the function.\r\n\r\nNamed handlers require the following signature:\r\n\r\n* name        - 'anything'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n\r\n// http://[host]:[port]/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about page');\r\n}\r\n\r\n// http://[host]:[port]/users/login\r\nexport module users {\r\n\r\n\texport function login(context) {\r\n\t\t\r\n\t\tcontext.response.send('handle login');\t\r\n\t}\r\n}\r\n\r\n```\r\n\r\n<a name=\"index_handlers\" />\r\n### index handlers\r\n\r\nIndex handlers resolve urls to their current module scope.\r\n\r\nIndex handlers require the following signature:\r\n\r\n* name        - 'index'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) \r\n\t{\t\r\n\t\tcontext.response.send('blog index');\r\n\t}\r\n}\r\n```\r\n\r\n<a name=\"wildcard_handlers\" />\r\n### wildcard handlers\r\n\r\nWildcard handlers resolve their urls to their current module scope + url.\r\n\r\nappex wildcard handlers allow for wildcard routing at a given module scope. Wildcard handlers\r\nsupport 'typed' url argument mapping, as denoted by the arguments annotation.\r\n\r\nIn addition, wildcard handlers also support optional arguments which can be specified with TypeScript's '?' \r\non argument names.\r\n\r\nappex wildcard handlers require the following signature:\r\n\r\n* name        - 'wildcard'\r\n* argument[0] - app context\r\n* argument[n] - 1 or more arguments to be mapped from the url\r\n* returns     - void (optional)\r\n\r\n```javascript\r\ndeclare var console;\r\n\r\nexport module blogs {\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11   - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/11  - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/3rd - not matched - (see number annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01     - matched     - (see ? annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013        - not matched - (month is required)\r\n\t\r\n    export function wildcard(context, year:number, month:number, day?:number) {\r\n\r\n        context.response.json({ year: year, month: month, day: day})\r\n    }\r\n}\r\n\r\n// url : http://[host]:[port]/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// url : http://[host]:[port]/(.*) \r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, 'not found');\r\n}\r\n\r\n```\r\nnote: appex supports boolean, number, string and any annotations on wildcard arguments. if no annotation\r\nis specified, appex interprets the argument as a string. the type 'any' is also interpreted as string.\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"cascades\" />\r\n### cascades\r\n\r\nappex supports a cascading attribute scheme on modules and functions. With this, developers can apply\r\narbituary meta data for modules and functions that will propagate through scope. appex has two special\r\ncascade properties for middleware and http verb matching, which are described below, however consider\r\nthe following code which illustrates the concept.\r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ncascade({a: 10}); // global.\r\n\r\ncascade('foo', {b : 20})\r\nexport module foo {\r\n\r\n    cascade('foo.bar', {c : 30})\r\n    export module bar {\r\n            \r\n        cascade('foo.bar.index', {d : 40})\r\n        export function index(context) {\r\n        \r\n            //context.cascade\r\n            //{\r\n            //    \"a\": 10,\r\n            //    \"b\": 20,\r\n            //    \"c\": 30,\r\n\t\t\t//    \"d\": 40\r\n            //}\r\n\r\n            context.response.json( context.cascade );       \r\n        }\r\n    }\r\n}\r\n\r\n```\r\n\r\n<a name=\"http_verbs\" />\r\n### http verbs\r\n\r\nappex handles http verb matching with cascades. appex will recognise the \r\n'verbs' property applied to the cascade to match against http verbs.\r\n\r\n```javascript\r\ncascade('index', { verbs: ['get'] })\r\nexport function index (context) { \r\n        \r\n    // only allow HTTP GET requests\r\n    context.response.send('index')\r\n}\r\n\r\ncascade('index', { verbs: ['post', 'put'] })\r\nexport function submit (context) { \r\n    \r\n    // only allow HTTP POST and PUT requests\r\n    context.response.send('submit')\r\n}\r\n```\r\n\r\n\r\n<a name=\"middleware\" />\r\n### middleware\r\n\r\nappex supports middleware with cascades. appex middleware defined with cascades allows\r\ndevelopers to scope middleware on single functions, or entire module scopes. appex will \r\nrecognise the 'use' property applied to the cascade to invoke middleware.\r\n\r\nthe following demonstrates how one might use middleware to secure a site admin.\r\n\r\nnote: middleware 'must' call next or handle the request. \r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ndeclare var console;\r\n\r\nfunction authenticate(context) {\r\n\r\n    console.log('authenticate')\r\n\r\n\t// call next() if authenticated, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\nfunction authorize(context) {\r\n\r\n    console.log('authorize')\r\n\r\n\t// call next() if authorized, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\n// apply security middleware to admin scope.\r\ncascade('admin', {use: [authenticate, authorize]}) \r\nexport module admin {\r\n\r\n    export function index(context) {\r\n        \r\n        console.log(context.cascade); // view cascade\r\n\r\n        context.response.send('access granted!')\r\n    }\r\n}\r\n\r\n// index handler has no middleware applied.\r\nexport function index (context) { \r\n    \r\n    console.log(context.cascade); // view cascade\r\n\r\n    context.response.send('home')\r\n}\r\n```\r\n\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex will only route functions prefixed with the TypeScript 'export' declarer. This rule\r\nalso applied to modules. Developers can use this to infer notions of public and private \r\nat the http level.\r\n\r\nconsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.send('public_function');\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```javascript\r\n// http:[host]:[port]/\r\nexport function index (context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard (context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n<a name=\"serving_static_files\" />\r\n## serving static files\r\n\r\nUse wildcard functions with context.response.serve() to serve static content.\r\n\r\n```javascript\r\nexport module static {\r\n\t\r\n\t// http:[host]:[port]/static/(.*)\r\n\texport function wildcard(context, path) {\r\n\r\n\t\tcontext.response.serve('./static/', path);\r\n\t}\r\n}\r\n\r\n// http:[host]:[port]/\r\nexport function index (context) {\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n\r\n<a name=\"reflection\" />\r\n## reflection\r\n\r\nappex provides a reflection api derived from TypeScript's type system that developers can \r\nleverage to reflect type information declared throughout their appex modules. \r\n\r\nthe following section outlines how to use the reflection api.\r\n\r\n<a name=\"reflect_everything\" />\r\n### reflect everything\r\n\r\nthe appex reflection api is passed on the context.module.reflection property and is available to all\r\nappex handler methods. The following code will JSON serialize everything declared in your appex\r\nproject and write it to the http response. \r\n\r\n```javascript\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection );\r\n}\r\n```\r\n<a name=\"reflect_specific_types\" />\r\n### reflect specific types\r\n\r\nIn typical scenarios, developers will want to leverage reflection meta data to generate\r\nservice contacts and client side models. the reflection api lets you access meta data \r\nfor the following types declared in your project. \r\n\r\n* modules\r\n* imports\r\n* classes\r\n* interfaces\r\n* functions\r\n* variables\r\n\r\nto access specific type metadata, use the reflection.get([qualifier]) method, as demonstrated below.\r\n\r\n```javascript\r\nexport module model {\r\n    \r\n    export class Customer {\r\n\r\n        public firstname   : string;\r\n\r\n        public lastname    : string;\r\n\r\n        public age         : number;\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('model.Customer') );\r\n}\r\n```\r\nand methods..\r\n\r\n```javascript\r\nfunction some_method(a:string, b:number, c?:boolean) : void { }\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_method') );\r\n}\r\n```\r\n\r\n....and variables...\r\n\r\n```javascript\r\nvar some_variable:number = 10;\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_variable') );\r\n}\r\n```\r\n<a name=\"json_schema\" />\r\n### json schema\r\n\r\nappex supports reflecting back JSON schema from class and interface type definitions. for example, the following\r\nwill output a json schema on the type 'model.Customer'.\r\n\r\n```javascript\r\nexport module model {\r\n\r\n    /** a product */\r\n    export class Product {\r\n        \r\n        /** the product name */\r\n        public name        : string;\r\n\r\n        /** the product description */\r\n        public description : string;\r\n\r\n        /** the product cost */\r\n        public cost        : number;\r\n    } \r\n\r\n    /** a order */\r\n    export class Order {\r\n        \r\n        /** the product being ordered */\r\n        public products  : Product;\r\n    }\r\n\r\n    /** a customer */\r\n    export class Customer {\r\n\r\n        /** the customers firstname */\r\n        public firstname  : string;\r\n\r\n        /** the customers lastname */\r\n        public lastname   : string;\r\n\r\n        /** orders made by this customer */\r\n        public orders     : Order[];\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.IContext) {\r\n\r\n    var schema = context.schema.get('model.Customer');\r\n\r\n    context.response.json(schema);\r\n}\r\n```\r\n\r\nwhich generates the following json schema.\r\n\r\n```javascript\r\n{\r\n    \"id\": \"model.Customer\",\r\n    \"type\": \"object\",\r\n    \"description\": \"a customer\",\r\n    \"properties\": {\r\n        \"firstname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers firstname\",\r\n            \"required\": true\r\n        },\r\n        \"lastname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers lastname\",\r\n            \"required\": true\r\n        },\r\n        \"orders\": {\r\n            \"type\": \"array\",\r\n            \"items\": {\r\n                \"type\": {\r\n                    \"id\": \"model.Order\",\r\n                    \"type\": \"object\",\r\n                    \"description\": \"a order\",\r\n                    \"properties\": {\r\n                        \"products\": {\r\n                            \"id\": \"model.Product\",\r\n                            \"type\": \"object\",\r\n                            \"description\": \"a product\",\r\n                            \"properties\": {\r\n                                \"name\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product name\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"description\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product description\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"cost\": {\r\n                                    \"type\": \"number\",\r\n                                    \"description\": \"the product cost\",\r\n                                    \"required\": true\r\n                                }\r\n                            },\r\n                            \"required\": true\r\n                        }\r\n                    }\r\n                }\r\n            },\r\n            \"description\": \"orders made by this customer\",\r\n            \"required\": true\r\n        }\r\n    }\r\n}\r\n```\r\na quick note...\r\n\r\nwhen generating schema from classes:\r\n\r\n* only public class variables will be emitted.\r\n* all properties will be marked as \"required\".\r\n\r\nwhen generating schema from interfaces:\r\n\r\n* all properties will be emitted. \r\n* all properties will be marked as \"required\" unless modified with '?'.\r\n\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\nThis section outlines development with appex.\r\n\r\n<a name=\"appex_declaration\" />\r\n### appex.d.ts declaration\r\n\r\nIf you develop on a TypeScript complicant editor (one that supports TS 0.9), appex comes bundled\r\nwith a declaration file you can reference in your project. If installing appex via npm, your\r\nreference should be as follows.\r\n\r\n```javascript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nexport function index (context:appex.web.IContext) { \r\n    \r\n    context.response.send('hello');\r\n}\r\n\r\nexport function wildcard(context:appex.web.IContext, path:string) {\r\n\r\n    context.response.serve('./', path);\r\n}\r\n```\r\n\r\nBy referencing this in your project, you get the benefits of code completion and static type checking\r\nagainst both appex, and the nodejs core.\r\n\r\n![](https://raw.github.com/sinclairzx81/appex/master/artifacts/code-completion.jpg)\r\n\r\nAdditional declaration files may be obtained from [here](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex ({ program : './index.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"users.ts\" />\r\n/// <reference path=\"pages.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { context.response.send('users.login') }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { context.response.send('users.logout') }\r\n}\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { context.response.send('home') }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { context.response.send('about') }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { context.response.send('contact') }\r\n\r\nexport function wildcard (context, path) { context.response.send(404, ' not found') }\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"license\" />\r\n## license\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) 2013 Haydn Paterson (sinclair) <haydn.developer@gmail.com>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in\r\nall copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\nTHE SOFTWARE.\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"https://raw.github.com/sinclairzx81/appex/master/license.txt","type":"The MIT License (MIT)"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"nodejs web api with typescript","directories":{},"dependencies":{"typescript.api":"0.5.9"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.5.0":{"name":"appex","version":"0.5.0","keywords":["typescript","web api","reflection","compiler","schema"],"author":{"name":"sinclair"},"_id":"appex@0.5.0","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"64514bbbaee4fddc49f93087d1857609747397a0","tarball":"https://registry.npmjs.org/appex/-/appex-0.5.0.tgz","integrity":"sha512-CTCJTHc4QbzaJ799+D+OFGEeRb84f4QXP4HOiZlSgli4buB31reoetlc4GYvyH+gUd+kDWmzsY+nHdG6ofo1fQ==","signatures":[{"sig":"MEYCIQCMDpDvckDWE6h6I69FWbMu4F393nBaVn6NQyRnc8+TSgIhAN56hCRMs2zU9oXcFI4uTUqnBKPyEF+tsp/KJbFj8pnF","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/artifacts/logo.jpg)\r\n\r\n### nodejs web api with [typescript](http://www.typescriptlang.org/)\r\n\r\n## overview\r\n\r\nappex is a nodejs web framework built around the TypeScript programming language and\r\ncompiler. appex lets developers create and route http endpoints with TypeScript modules and \r\nfunctions, as well as providing nodejs developers similar reflection and type introspection \r\nservices found in platforms such as .net.\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http://localhost:3000/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// http://localhost:3000/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about');\r\n}\r\n\r\n// http://localhost:3000/(.*)\r\nexport function wildcard (context, path) {\r\n    \r\n    context.response.send(404, path + \" not found\");\r\n}\r\n\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n### contents\r\n\r\n* [getting started](#getting_started)\r\n\t* [create a application](#application)\r\n\t* [start up options](#options)\r\n\t* [running on an existing http server](#http_server)\r\n\t* [running as express middleware](#express_middleware)\r\n* [creating services with typescript](#creating_services)\r\n\t* [app context](#app_context)\r\n\t* [routing handlers](#routing_handlers)\r\n\t* [handler signatures](#handler_signatures)\r\n\t* [named handlers](#named_handlers)\r\n\t* [index handlers](#index_handlers)\r\n\t* [wildcard handlers](#wildcard_handlers)\r\n\t* [cascades](#cascades)\r\n\t* [http verbs](#http_verbs)\r\n\t* [middleware](#middleware)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [handling 404](#handling_404)\r\n\t* [serving static files](#serving_static_files)\r\n* [reflection](#reflection)\r\n\t* [reflect everything](#reflect_everything)\r\n\t* [reflect specific types](#reflect_specific_types)\r\n\t* [generating json schema](#generating_json_schema)\r\n\t* [validating json schema](#validating_json_schema)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [appex.d.ts declaration](#appex_declaration)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n* [license](#license)\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline creating appex applications and configuration.\r\n\r\n<a name=\"application\" />\r\n### create a application\r\n\r\nThe following code will create a standalone appex application and \r\nhttp server and listen on port 3000.\r\n\r\n```javascript\r\nvar appex   = require('appex');\r\n\r\nvar app   = appex({ program : './program.ts', \r\n                    devmode : true,\r\n                    logging : true });\r\n\r\napp.listen(3000);\r\n```\r\n\r\nnote: devmode and logging are optional. however, when developing \r\nwith appex, it is helpful to have these enabled.\r\n\r\n<a name=\"options\" />\r\n### start up options\r\n\r\nappex accepts the following start up options.\r\n\r\n```javascript\r\nvar options = {\r\n\r\n\t// (required) location of source file.\r\n\tprogram    : './program.ts', \r\n\r\n\t// (optional) recompile on request. (default:false) \r\n\tdevmode    : true,          \r\n\r\n\t// (optional) log to stdout. (default:false) \r\n\tlogging    : true,\r\n\r\n\t// (optional) user defined objects added to the app context.\r\n\tcontext    : {}\r\n};\r\n\r\nvar app = appex( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### running on an existing http server\r\n\r\nThe following demonstrates setting up appex on an existing nodejs http server. In \r\nthis example, appex will attempt to handle incoming requests, and if appex cannot\r\nroute the request, will fire the callback.\r\n\r\n```javascript\r\nvar http  = require('http');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\nvar server = http.createServer(function(req, res){\r\n\r\n    app(req, res, function() { // appex handler...\r\n\t\t\r\n\t\t// not handled.\r\n\r\n\t}); \r\n});\r\n\r\nserver.listen(3000);\r\n```\r\n\r\n\r\n<a name=\"express_middleware\" />\r\n### running as express middleware\r\n\r\nappex allows developers to augment existing express / connect applications by \r\nway of middleware. The following demonstrates setting up appex as express middleware.\r\n\r\n```javascript\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) ); \r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nLike in the \"running on an existing http server\" example above, appex will attempt to intercept incoming requests. \r\nif appex cannot find a matching route for the request, it will automatically call the \"next\" function to pass the request \r\non to the next middleware or express handler.\r\n\r\nin addition to this, appex may also act as traditional express middleware. In the example below, a appex wildcard\r\nfunction is created which will match \"all\" incoming requests, the wildcard function simply prints hello world to \r\nthe console and then calls context.next(), which passes the request on the express handler.\r\n\r\n```javascript\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tconsole.log('hello world!!');\r\n\r\n\tcontext.next(); // pass it on!\r\n}\r\n\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) );\r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nJust like traditional express middleware, appex will also inheriate the characteristics of the request.\r\n\r\nconsider the following example in which the jade view engine is configured for use. appex will inheritate the \r\nresponse.render() method, which is passed to the appex handler as context.response.render()\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\napp.configure(function(){\r\n\r\n  app.set('views', __dirname + '/views');\r\n  \r\n  // set up the jade engine.\r\n  app.set('view engine', 'jade'); \r\n  \r\n  // bind appex\r\n  app.use( appex({program:'./program.ts', devmode:true} ));  \r\n});\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/\r\nexport function index(context) {\r\n\t\r\n\t// jade renderer works!\r\n\tcontext.response.render('index', { title: 'Express' }); \r\n}\r\n```\r\n\r\n<a name=\"creating_services\" />\r\n## creating services with typescript\r\n\r\nThe following section describes how to write http accessible functions with appex.\r\n\r\n<a name=\"app_context\" />\r\n### app context\r\n\r\nAll appex functions are passed a application context object as their first argument. The app context object \r\nencapulates the http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the app context\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.cascade    - appex cascade.\r\n\r\n\t// context.next       - the next function (express middleware)\r\n\t\r\n\t// context.router     - the appex router\r\n\t\r\n\t// context.module     - the module being run (this module)\r\n\r\n\t// context.schema     - json schema api.\r\n\r\n\t// context.mime       - a http mime type utility.\r\n}\r\n```\r\n\r\nit is possible to extend the default objects passed on the context by adding them on the appex startup options. The \r\nfollowing will attach the async module to the context. \r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = appex({ program : './program.ts', \r\n\t\t\t\t  devmode : true, \r\n\t\t\t      context: {\r\n\t\t\t\t\t\tasync : require('async')\r\n\t\t\t\t  }});\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\r\n\t// context.async = passed on the context.\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n```\r\n<a name=\"routing_handlers\" />\r\n### routing handlers\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context) { /* handle route */ }\r\n}\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/(.*)\r\nexport function wildcard (context, path) { /* handle route */ }\r\n\r\n```\r\n\r\n<a name=\"handler_signatures\" />\r\n### handler signatures\r\n\r\nappex supports three function signatures for http routing (named, index and wildcard). Functions that\r\ndo not apply these signatures will not be routed.\r\n\r\n<a name=\"named_handlers\" />\r\n### named handlers\r\n\r\nNamed handlers resolve urls to their current module scope + the name of the function.\r\n\r\nNamed handlers require the following signature:\r\n\r\n* name        - 'anything'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n\r\n// http://[host]:[port]/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about page');\r\n}\r\n\r\n// http://[host]:[port]/users/login\r\nexport module users {\r\n\r\n\texport function login(context) {\r\n\t\t\r\n\t\tcontext.response.send('handle login');\t\r\n\t}\r\n}\r\n\r\n```\r\n\r\n<a name=\"index_handlers\" />\r\n### index handlers\r\n\r\nIndex handlers resolve urls to their current module scope.\r\n\r\nIndex handlers require the following signature:\r\n\r\n* name        - 'index'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) \r\n\t{\t\r\n\t\tcontext.response.send('blog index');\r\n\t}\r\n}\r\n```\r\n\r\n<a name=\"wildcard_handlers\" />\r\n### wildcard handlers\r\n\r\nWildcard handlers resolve their urls to their current module scope + url.\r\n\r\nappex wildcard handlers allow for wildcard routing at a given module scope. Wildcard handlers\r\nsupport 'typed' url argument mapping, as denoted by the arguments annotation.\r\n\r\nIn addition, wildcard handlers also support optional arguments which can be specified with TypeScript's '?' \r\non argument names.\r\n\r\nappex wildcard handlers require the following signature:\r\n\r\n* name        - 'wildcard'\r\n* argument[0] - app context\r\n* argument[n] - 1 or more arguments to be mapped from the url\r\n* returns     - void (optional)\r\n\r\n```javascript\r\ndeclare var console;\r\n\r\nexport module blogs {\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11   - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/11  - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/3rd - not matched - (see number annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01     - matched     - (see ? annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013        - not matched - (month is required)\r\n\t\r\n    export function wildcard(context, year:number, month:number, day?:number) {\r\n\r\n        context.response.json({ year: year, month: month, day: day})\r\n    }\r\n}\r\n\r\n// url : http://[host]:[port]/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// url : http://[host]:[port]/(.*) \r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, 'not found');\r\n}\r\n\r\n```\r\nnote: appex supports boolean, number, string and any annotations on wildcard arguments. if no annotation\r\nis specified, appex interprets the argument as a string. the type 'any' is also interpreted as string.\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"cascades\" />\r\n### cascades\r\n\r\nappex supports a cascading attribute scheme on modules and functions. With this, developers can apply\r\narbituary meta data for modules and functions that will propagate through scope. appex has two special\r\ncascade properties for middleware and http verb matching, which are described below, however consider\r\nthe following code which illustrates the concept.\r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ncascade({a: 10}); // global.\r\n\r\ncascade('foo', {b : 20})\r\nexport module foo {\r\n\r\n    cascade('foo.bar', {c : 30})\r\n    export module bar {\r\n            \r\n        cascade('foo.bar.index', {d : 40})\r\n        export function index(context) {\r\n        \r\n            //context.cascade\r\n            //{\r\n            //    \"a\": 10,\r\n            //    \"b\": 20,\r\n            //    \"c\": 30,\r\n\t\t\t//    \"d\": 40\r\n            //}\r\n\r\n            context.response.json( context.cascade );       \r\n        }\r\n    }\r\n}\r\n\r\n```\r\n\r\n<a name=\"http_verbs\" />\r\n### http verbs\r\n\r\nappex handles http verb matching with cascades. appex will recognise the \r\n'verbs' property applied to the cascade to match against http verbs.\r\n\r\n```javascript\r\ncascade('index', { verbs: ['get'] })\r\nexport function index (context) { \r\n        \r\n    // only allow HTTP GET requests\r\n    context.response.send('index')\r\n}\r\n\r\ncascade('index', { verbs: ['post', 'put'] })\r\nexport function submit (context) { \r\n    \r\n    // only allow HTTP POST and PUT requests\r\n    context.response.send('submit')\r\n}\r\n```\r\n\r\n\r\n<a name=\"middleware\" />\r\n### middleware\r\n\r\nappex supports middleware with cascades. appex middleware defined with cascades allows\r\ndevelopers to scope middleware on single functions, or entire module scopes. appex will \r\nrecognise the 'use' property applied to the cascade to invoke middleware.\r\n\r\nthe following demonstrates how one might use middleware to secure a site admin.\r\n\r\nnote: middleware 'must' call next or handle the request. \r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ndeclare var console;\r\n\r\nfunction authenticate(context) {\r\n\r\n    console.log('authenticate')\r\n\r\n\t// call next() if authenticated, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\nfunction authorize(context) {\r\n\r\n    console.log('authorize')\r\n\r\n\t// call next() if authorized, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\n// apply security middleware to admin scope.\r\ncascade('admin', {use: [authenticate, authorize]}) \r\nexport module admin {\r\n\r\n    export function index(context) {\r\n        \r\n        console.log(context.cascade); // view cascade\r\n\r\n        context.response.send('access granted!')\r\n    }\r\n}\r\n\r\n// index handler has no middleware applied.\r\nexport function index (context) { \r\n    \r\n    console.log(context.cascade); // view cascade\r\n\r\n    context.response.send('home')\r\n}\r\n```\r\n\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex will only route functions prefixed with the TypeScript 'export' declarer. This rule\r\nalso applied to modules. Developers can use this to infer notions of public and private \r\nat the http level.\r\n\r\nconsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.send('public_function');\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```javascript\r\n// http:[host]:[port]/\r\nexport function index (context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard (context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n<a name=\"serving_static_files\" />\r\n## serving static files\r\n\r\nUse wildcard functions with context.response.serve() to serve static content.\r\n\r\n```javascript\r\nexport module static {\r\n\t\r\n\t// http:[host]:[port]/static/(.*)\r\n\texport function wildcard(context, path) {\r\n\r\n\t\tcontext.response.serve('./static/', path);\r\n\t}\r\n}\r\n\r\n// http:[host]:[port]/\r\nexport function index (context) {\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n\r\n<a name=\"reflection\" />\r\n## reflection\r\n\r\nappex provides a reflection api derived from TypeScript's type system that developers can \r\nleverage to reflect type information declared throughout their appex modules. \r\n\r\nthe following section outlines how to use the reflection api.\r\n\r\n<a name=\"reflect_everything\" />\r\n### reflect everything\r\n\r\nthe appex reflection api is passed on the context.module.reflection property and is available to all\r\nappex handler methods. The following code will JSON serialize everything declared in your appex\r\nproject and write it to the http response. \r\n\r\n```javascript\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection );\r\n}\r\n```\r\n<a name=\"reflect_specific_types\" />\r\n### reflect specific types\r\n\r\nIn typical scenarios, developers will want to leverage reflection meta data to generate\r\nservice contacts and client side models. the reflection api lets you access meta data \r\nfor the following types declared in your project. \r\n\r\n* modules\r\n* imports\r\n* classes\r\n* interfaces\r\n* functions\r\n* variables\r\n\r\nto access specific type metadata, use the reflection.get([qualifier]) method, as demonstrated below.\r\n\r\n```javascript\r\nexport module model {\r\n    \r\n    export class Customer {\r\n\r\n        public firstname   : string;\r\n\r\n        public lastname    : string;\r\n\r\n        public age         : number;\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('model.Customer') );\r\n}\r\n```\r\nand methods..\r\n\r\n```javascript\r\nfunction some_method(a:string, b:number, c?:boolean) : void { }\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_method') );\r\n}\r\n```\r\n\r\n....and variables...\r\n\r\n```javascript\r\nvar some_variable:number = 10;\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_variable') );\r\n}\r\n```\r\n<a name=\"generating_json_schema\" />\r\n### generating json schema\r\n\r\nappex supports the generation of json schema from class and interface definitions.\r\n\r\n```javascript\r\nexport module model {\r\n\r\n    /** a product */\r\n    export class Product {\r\n        \r\n        /** the product name */\r\n        public name        : string;\r\n\r\n        /** the product description */\r\n        public description : string;\r\n\r\n        /** the product cost */\r\n        public cost        : number;\r\n    } \r\n\r\n    /** a order */\r\n    export class Order {\r\n        \r\n        /** the product being ordered */\r\n        public products  : Product;\r\n    }\r\n\r\n    /** a customer */\r\n    export class Customer {\r\n\r\n        /** the customers firstname */\r\n        public firstname  : string;\r\n\r\n        /** the customers lastname */\r\n        public lastname   : string;\r\n\r\n        /** orders made by this customer */\r\n        public orders     : Order[];\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.IContext) {\r\n\r\n    var schema = context.schema.generate('model.Customer');\r\n\r\n    context.response.json(schema);\r\n}\r\n```\r\n\r\nwhich generates the following json schema.\r\n\r\n```javascript\r\n{\r\n    \"id\": \"model.Customer\",\r\n    \"type\": \"object\",\r\n    \"description\": \"a customer\",\r\n    \"properties\": {\r\n        \"firstname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers firstname\",\r\n            \"required\": true\r\n        },\r\n        \"lastname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers lastname\",\r\n            \"required\": true\r\n        },\r\n        \"orders\": {\r\n            \"type\": \"array\",\r\n            \"items\": {\r\n                \"type\": {\r\n                    \"id\": \"model.Order\",\r\n                    \"type\": \"object\",\r\n                    \"description\": \"a order\",\r\n                    \"properties\": {\r\n                        \"products\": {\r\n                            \"id\": \"model.Product\",\r\n                            \"type\": \"object\",\r\n                            \"description\": \"a product\",\r\n                            \"properties\": {\r\n                                \"name\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product name\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"description\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product description\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"cost\": {\r\n                                    \"type\": \"number\",\r\n                                    \"description\": \"the product cost\",\r\n                                    \"required\": true\r\n                                }\r\n                            },\r\n                            \"required\": true\r\n                        }\r\n                    }\r\n                }\r\n            },\r\n            \"description\": \"orders made by this customer\",\r\n            \"required\": true\r\n        }\r\n    }\r\n}\r\n```\r\na quick note...\r\n\r\nwhen generating schema from classes:\r\n\r\n* only public class variables will be emitted.\r\n* all properties will be marked as \"required\".\r\n\r\nwhen generating schema from interfaces:\r\n\r\n* all properties will be emitted. \r\n* all properties will be marked as \"required\" unless modified with '?'.\r\n\r\n<a name=\"validating_json_schema\" />\r\n### validating json schema\r\n\r\nappex supports json schema validation from class and interface definitions. consider the following...\r\n\r\n```javascript\r\ninterface Customer {\r\n\r\n    firstname    : string;\r\n\r\n    lastname     : string;\r\n\r\n    age          : number;\r\n\r\n    emails       : string[];\r\n\r\n    option_a ?   : boolean; // optional\r\n\r\n    option_b ?   : boolean; // optional\r\n\r\n}\r\n\r\nexport function index(context) {\r\n\r\n    // a customer with invalid data.\r\n\r\n    var customer = {\r\n\r\n        firstname    : 'dave',\r\n\r\n        age          : '33',\r\n\r\n        emails       : [12345, 'dave@domain.com', true],\r\n\r\n        option_b     : 1,\r\n\r\n        option_c     : 1\r\n    }\r\n\r\n    // do validation.\r\n\r\n    var errors = context.schema.validate('Customer', customer);\r\n\r\n    if(errors) {\r\n\r\n        context.response.json(errors);\r\n    }\r\n}\r\n```\r\n\r\nwill output the following.\r\n\r\n```javascript\r\n[\r\n    {\r\n        \"message\": \"instance.lastname is required.\"\r\n    },\r\n    {\r\n        \"message\": \"instance.age is not a number\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[0] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[2] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_b is not a boolean\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_c unexpected property\"\r\n    }\r\n]\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\nThis section outlines development with appex.\r\n\r\n<a name=\"appex_declaration\" />\r\n### appex.d.ts declaration\r\n\r\nIf you develop on a TypeScript complicant editor (one that supports TS 0.9), appex comes bundled\r\nwith a declaration file you can reference in your project. If installing appex via npm, your\r\nreference should be as follows.\r\n\r\n```javascript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nexport function index (context:appex.web.IContext) { \r\n    \r\n    context.response.send('hello');\r\n}\r\n\r\nexport function wildcard(context:appex.web.IContext, path:string) {\r\n\r\n    context.response.serve('./', path);\r\n}\r\n```\r\n\r\nBy referencing this in your project, you get the benefits of code completion and static type checking\r\nagainst both appex, and the nodejs core.\r\n\r\n![](https://raw.github.com/sinclairzx81/appex/master/artifacts/code-completion.jpg)\r\n\r\nAdditional declaration files may be obtained from [here](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex ({ program : './index.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"users.ts\" />\r\n/// <reference path=\"pages.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { context.response.send('users.login') }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { context.response.send('users.logout') }\r\n}\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { context.response.send('home') }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { context.response.send('about') }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { context.response.send('contact') }\r\n\r\nexport function wildcard (context, path) { context.response.send(404, ' not found') }\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"license\" />\r\n## license\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) 2013 Haydn Paterson (sinclair) <haydn.developer@gmail.com>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in\r\nall copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\nTHE SOFTWARE.\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"https://raw.github.com/sinclairzx81/appex/master/license.txt","type":"The MIT License (MIT)"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"nodejs web api with typescript","directories":{},"dependencies":{"typescript.api":"0.5.9"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.5.1":{"name":"appex","version":"0.5.1","keywords":["typescript","web api","reflection","compiler","schema"],"author":{"name":"sinclair"},"_id":"appex@0.5.1","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"045a6d4f2e9ae65724fb2d2e28d8130faa856094","tarball":"https://registry.npmjs.org/appex/-/appex-0.5.1.tgz","integrity":"sha512-rCRVI4AZsiwxHG/Z/Q5J8ciLi51Xu1gLuVWvFKST+hEiXCsmKGdErk9c2M7SmDIPQQeG5G9zlNf7NfN5DVpZVQ==","signatures":[{"sig":"MEQCICIH84QJIHf5uG3CXY0bJ+VhOT5OLNEho+9AoDKqs1ECAiAAnZL0DvtSijPBizn1be7KbAKD3LzVRzegDPbc5XQ2uw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/artifacts/logo.jpg)\r\n\r\n### nodejs web api with [typescript](http://www.typescriptlang.org/)\r\n\r\n## overview\r\n\r\nappex is a nodejs web framework built around the TypeScript programming language and\r\ncompiler. appex lets developers create and route http endpoints with TypeScript modules and \r\nfunctions, as well as providing nodejs developers similar reflection and type introspection \r\nservices found in platforms such as .net.\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http://localhost:3000/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// http://localhost:3000/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about');\r\n}\r\n\r\n// http://localhost:3000/(.*)\r\nexport function wildcard (context, path) {\r\n    \r\n    context.response.send(404, path + \" not found\");\r\n}\r\n\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n### contents\r\n\r\n* [getting started](#getting_started)\r\n\t* [create a application](#application)\r\n\t* [start up options](#options)\r\n\t* [running on an existing http server](#http_server)\r\n\t* [running as express middleware](#express_middleware)\r\n* [creating services with typescript](#creating_services)\r\n\t* [app context](#app_context)\r\n\t* [routing handlers](#routing_handlers)\r\n\t* [handler signatures](#handler_signatures)\r\n\t* [named handlers](#named_handlers)\r\n\t* [index handlers](#index_handlers)\r\n\t* [wildcard handlers](#wildcard_handlers)\r\n\t* [cascades](#cascades)\r\n\t* [http verbs](#http_verbs)\r\n\t* [middleware](#middleware)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [handling 404](#handling_404)\r\n\t* [serving static files](#serving_static_files)\r\n* [reflection](#reflection)\r\n\t* [reflect everything](#reflect_everything)\r\n\t* [reflect specific types](#reflect_specific_types)\r\n\t* [generating json schema](#generating_json_schema)\r\n\t* [validating json schema](#validating_json_schema)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [appex.d.ts declaration](#appex_declaration)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n* [license](#license)\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline creating appex applications and configuration.\r\n\r\n<a name=\"application\" />\r\n### create a application\r\n\r\nThe following code will create a standalone appex application and \r\nhttp server and listen on port 3000.\r\n\r\n```javascript\r\nvar appex   = require('appex');\r\n\r\nvar app   = appex({ program : './program.ts', \r\n                    devmode : true,\r\n                    logging : true });\r\n\r\napp.listen(3000);\r\n```\r\n\r\nnote: devmode and logging are optional. however, when developing \r\nwith appex, it is helpful to have these enabled.\r\n\r\n<a name=\"options\" />\r\n### start up options\r\n\r\nappex accepts the following start up options.\r\n\r\n```javascript\r\nvar options = {\r\n\r\n\t// (required) location of source file.\r\n\tprogram    : './program.ts', \r\n\r\n\t// (optional) recompile on request. (default:false) \r\n\tdevmode    : true,          \r\n\r\n\t// (optional) log to stdout. (default:false) \r\n\tlogging    : true,\r\n\r\n\t// (optional) user defined objects added to the app context.\r\n\tcontext    : {}\r\n};\r\n\r\nvar app = appex( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### running on an existing http server\r\n\r\nThe following demonstrates setting up appex on an existing nodejs http server. In \r\nthis example, appex will attempt to handle incoming requests, and if appex cannot\r\nroute the request, will fire the callback.\r\n\r\n```javascript\r\nvar http  = require('http');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\nvar server = http.createServer(function(req, res){\r\n\r\n    app(req, res, function() { // appex handler...\r\n\t\t\r\n\t\t// not handled.\r\n\r\n\t}); \r\n});\r\n\r\nserver.listen(3000);\r\n```\r\n\r\n\r\n<a name=\"express_middleware\" />\r\n### running as express middleware\r\n\r\nappex allows developers to augment existing express / connect applications by \r\nway of middleware. The following demonstrates setting up appex as express middleware.\r\n\r\n```javascript\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) ); \r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nLike in the \"running on an existing http server\" example above, appex will attempt to intercept incoming requests. \r\nif appex cannot find a matching route for the request, it will automatically call the \"next\" function to pass the request \r\non to the next middleware or express handler.\r\n\r\nin addition to this, appex may also act as traditional express middleware. In the example below, a appex wildcard\r\nfunction is created which will match \"all\" incoming requests, the wildcard function simply prints hello world to \r\nthe console and then calls context.next(), which passes the request on the express handler.\r\n\r\n```javascript\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tconsole.log('hello world!!');\r\n\r\n\tcontext.next(); // pass it on!\r\n}\r\n\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) );\r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nJust like traditional express middleware, appex will also inheriate the characteristics of the request.\r\n\r\nconsider the following example in which the jade view engine is configured for use. appex will inheritate the \r\nresponse.render() method, which is passed to the appex handler as context.response.render()\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\napp.configure(function(){\r\n\r\n  app.set('views', __dirname + '/views');\r\n  \r\n  // set up the jade engine.\r\n  app.set('view engine', 'jade'); \r\n  \r\n  // bind appex\r\n  app.use( appex({program:'./program.ts', devmode:true} ));  \r\n});\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/\r\nexport function index(context) {\r\n\t\r\n\t// jade renderer works!\r\n\tcontext.response.render('index', { title: 'Express' }); \r\n}\r\n```\r\n\r\n<a name=\"creating_services\" />\r\n## creating services with typescript\r\n\r\nThe following section describes how to write http accessible functions with appex.\r\n\r\n<a name=\"app_context\" />\r\n### app context\r\n\r\nAll appex functions are passed a application context object as their first argument. The app context object \r\nencapulates the http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the app context\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.cascade    - appex cascade.\r\n\r\n\t// context.next       - the next function (express middleware)\r\n\t\r\n\t// context.router     - the appex router\r\n\t\r\n\t// context.module     - the module being run (this module)\r\n\r\n\t// context.schema     - json schema api.\r\n\r\n\t// context.mime       - a http mime type utility.\r\n}\r\n```\r\n\r\nit is possible to extend the default objects passed on the context by adding them on the appex startup options. The \r\nfollowing will attach the async module to the context. \r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = appex({ program : './program.ts', \r\n\t\t\t\t  devmode : true, \r\n\t\t\t      context: {\r\n\t\t\t\t\t\tasync : require('async')\r\n\t\t\t\t  }});\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\r\n\t// context.async = passed on the context.\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n```\r\n<a name=\"routing_handlers\" />\r\n### routing handlers\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context) { /* handle route */ }\r\n}\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/(.*)\r\nexport function wildcard (context, path) { /* handle route */ }\r\n\r\n```\r\n\r\n<a name=\"handler_signatures\" />\r\n### handler signatures\r\n\r\nappex supports three function signatures for http routing (named, index and wildcard). Functions that\r\ndo not apply these signatures will not be routed.\r\n\r\n<a name=\"named_handlers\" />\r\n### named handlers\r\n\r\nNamed handlers resolve urls to their current module scope + the name of the function.\r\n\r\nNamed handlers require the following signature:\r\n\r\n* name        - 'anything'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n\r\n// http://[host]:[port]/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about page');\r\n}\r\n\r\n// http://[host]:[port]/users/login\r\nexport module users {\r\n\r\n\texport function login(context) {\r\n\t\t\r\n\t\tcontext.response.send('handle login');\t\r\n\t}\r\n}\r\n\r\n```\r\n\r\n<a name=\"index_handlers\" />\r\n### index handlers\r\n\r\nIndex handlers resolve urls to their current module scope.\r\n\r\nIndex handlers require the following signature:\r\n\r\n* name        - 'index'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) \r\n\t{\t\r\n\t\tcontext.response.send('blog index');\r\n\t}\r\n}\r\n```\r\n\r\n<a name=\"wildcard_handlers\" />\r\n### wildcard handlers\r\n\r\nWildcard handlers resolve their urls to their current module scope + url.\r\n\r\nappex wildcard handlers allow for wildcard routing at a given module scope. Wildcard handlers\r\nsupport 'typed' url argument mapping, as denoted by the arguments annotation.\r\n\r\nIn addition, wildcard handlers also support optional arguments which can be specified with TypeScript's '?' \r\non argument names.\r\n\r\nappex wildcard handlers require the following signature:\r\n\r\n* name        - 'wildcard'\r\n* argument[0] - app context\r\n* argument[n] - 1 or more arguments to be mapped from the url\r\n* returns     - void (optional)\r\n\r\n```javascript\r\ndeclare var console;\r\n\r\nexport module blogs {\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11   - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/11  - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/3rd - not matched - (see number annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01     - matched     - (see ? annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013        - not matched - (month is required)\r\n\t\r\n    export function wildcard(context, year:number, month:number, day?:number) {\r\n\r\n        context.response.json({ year: year, month: month, day: day})\r\n    }\r\n}\r\n\r\n// url : http://[host]:[port]/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// url : http://[host]:[port]/(.*) \r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, 'not found');\r\n}\r\n\r\n```\r\nnote: appex supports boolean, number, string and any annotations on wildcard arguments. if no annotation\r\nis specified, appex interprets the argument as a string. the type 'any' is also interpreted as string.\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"cascades\" />\r\n### cascades\r\n\r\nappex supports a cascading attribute scheme on modules and functions. With this, developers can apply\r\narbituary meta data for modules and functions that will propagate through scope. appex has two special\r\ncascade properties for middleware and http verb matching, which are described below, however consider\r\nthe following code which illustrates the concept.\r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ncascade({a: 10}); // global.\r\n\r\ncascade('foo', {b : 20})\r\nexport module foo {\r\n\r\n    cascade('foo.bar', {c : 30})\r\n    export module bar {\r\n            \r\n        cascade('foo.bar.index', {d : 40})\r\n        export function index(context) {\r\n        \r\n            //context.cascade\r\n            //{\r\n            //    \"a\": 10,\r\n            //    \"b\": 20,\r\n            //    \"c\": 30,\r\n\t\t\t//    \"d\": 40\r\n            //}\r\n\r\n            context.response.json( context.cascade );       \r\n        }\r\n    }\r\n}\r\n\r\n```\r\n\r\n<a name=\"http_verbs\" />\r\n### http verbs\r\n\r\nappex handles http verb matching with cascades. appex will recognise the \r\n'verbs' property applied to the cascade to match against http verbs.\r\n\r\n```javascript\r\ncascade('index', { verbs: ['get'] })\r\nexport function index (context) { \r\n        \r\n    // only allow HTTP GET requests\r\n    context.response.send('index')\r\n}\r\n\r\ncascade('index', { verbs: ['post', 'put'] })\r\nexport function submit (context) { \r\n    \r\n    // only allow HTTP POST and PUT requests\r\n    context.response.send('submit')\r\n}\r\n```\r\n\r\n\r\n<a name=\"middleware\" />\r\n### middleware\r\n\r\nappex supports middleware with cascades. appex middleware defined with cascades allows\r\ndevelopers to scope middleware on single functions, or entire module scopes. appex will \r\nrecognise the 'use' property applied to the cascade to invoke middleware.\r\n\r\nthe following demonstrates how one might use middleware to secure a site admin.\r\n\r\nnote: middleware 'must' call next or handle the request. \r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ndeclare var console;\r\n\r\nfunction authenticate(context) {\r\n\r\n    console.log('authenticate')\r\n\r\n\t// call next() if authenticated, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\nfunction authorize(context) {\r\n\r\n    console.log('authorize')\r\n\r\n\t// call next() if authorized, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\n// apply security middleware to admin scope.\r\ncascade('admin', {use: [authenticate, authorize]}) \r\nexport module admin {\r\n\r\n    export function index(context) {\r\n        \r\n        console.log(context.cascade); // view cascade\r\n\r\n        context.response.send('access granted!')\r\n    }\r\n}\r\n\r\n// index handler has no middleware applied.\r\nexport function index (context) { \r\n    \r\n    console.log(context.cascade); // view cascade\r\n\r\n    context.response.send('home')\r\n}\r\n```\r\n\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex will only route functions prefixed with the TypeScript 'export' declarer. This rule\r\nalso applied to modules. Developers can use this to infer notions of public and private \r\nat the http level.\r\n\r\nconsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.send('public_function');\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```javascript\r\n// http:[host]:[port]/\r\nexport function index (context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard (context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n<a name=\"serving_static_files\" />\r\n## serving static files\r\n\r\nUse wildcard functions with context.response.serve() to serve static content.\r\n\r\n```javascript\r\nexport module static {\r\n\t\r\n\t// http:[host]:[port]/static/(.*)\r\n\texport function wildcard(context, path) {\r\n\r\n\t\tcontext.response.serve('./static/', path);\r\n\t}\r\n}\r\n\r\n// http:[host]:[port]/\r\nexport function index (context) {\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n\r\n<a name=\"reflection\" />\r\n## reflection\r\n\r\nappex provides a reflection api derived from TypeScript's type system that developers can \r\nleverage to reflect type information declared throughout their appex modules. \r\n\r\nthe following section outlines how to use the reflection api.\r\n\r\n<a name=\"reflect_everything\" />\r\n### reflect everything\r\n\r\nthe appex reflection api is passed on the context.module.reflection property and is available to all\r\nappex handler methods. The following code will JSON serialize everything declared in your appex\r\nproject and write it to the http response. \r\n\r\n```javascript\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection );\r\n}\r\n```\r\n<a name=\"reflect_specific_types\" />\r\n### reflect specific types\r\n\r\nIn typical scenarios, developers will want to leverage reflection meta data to generate\r\nservice contacts and client side models. the reflection api lets you access meta data \r\nfor the following types declared in your project. \r\n\r\n* modules\r\n* imports\r\n* classes\r\n* interfaces\r\n* functions\r\n* variables\r\n\r\nto access specific type metadata, use the reflection.get([qualifier]) method, as demonstrated below.\r\n\r\n```javascript\r\nexport module model {\r\n    \r\n    export class Customer {\r\n\r\n        public firstname   : string;\r\n\r\n        public lastname    : string;\r\n\r\n        public age         : number;\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('model.Customer') );\r\n}\r\n```\r\nand methods..\r\n\r\n```javascript\r\nfunction some_method(a:string, b:number, c?:boolean) : void { }\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_method') );\r\n}\r\n```\r\n\r\n....and variables...\r\n\r\n```javascript\r\nvar some_variable:number = 10;\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_variable') );\r\n}\r\n```\r\n<a name=\"generating_json_schema\" />\r\n### generating json schema\r\n\r\nappex supports the generation of json schema from class and interface definitions.\r\n\r\n```javascript\r\nexport module model {\r\n\r\n    /** a product */\r\n    export class Product {\r\n        \r\n        /** the product name */\r\n        public name        : string;\r\n\r\n        /** the product description */\r\n        public description : string;\r\n\r\n        /** the product cost */\r\n        public cost        : number;\r\n    } \r\n\r\n    /** a order */\r\n    export class Order {\r\n        \r\n        /** the product being ordered */\r\n        public products  : Product;\r\n    }\r\n\r\n    /** a customer */\r\n    export class Customer {\r\n\r\n        /** the customers firstname */\r\n        public firstname  : string;\r\n\r\n        /** the customers lastname */\r\n        public lastname   : string;\r\n\r\n        /** orders made by this customer */\r\n        public orders     : Order[];\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.IContext) {\r\n\r\n    var schema = context.schema.generate('model.Customer');\r\n\r\n    context.response.json(schema);\r\n}\r\n```\r\n\r\nwhich generates the following json schema.\r\n\r\n```javascript\r\n{\r\n    \"id\": \"model.Customer\",\r\n    \"type\": \"object\",\r\n    \"description\": \"a customer\",\r\n    \"properties\": {\r\n        \"firstname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers firstname\",\r\n            \"required\": true\r\n        },\r\n        \"lastname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers lastname\",\r\n            \"required\": true\r\n        },\r\n        \"orders\": {\r\n            \"type\": \"array\",\r\n            \"items\": {\r\n                \"type\": {\r\n                    \"id\": \"model.Order\",\r\n                    \"type\": \"object\",\r\n                    \"description\": \"a order\",\r\n                    \"properties\": {\r\n                        \"products\": {\r\n                            \"id\": \"model.Product\",\r\n                            \"type\": \"object\",\r\n                            \"description\": \"a product\",\r\n                            \"properties\": {\r\n                                \"name\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product name\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"description\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product description\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"cost\": {\r\n                                    \"type\": \"number\",\r\n                                    \"description\": \"the product cost\",\r\n                                    \"required\": true\r\n                                }\r\n                            },\r\n                            \"required\": true\r\n                        }\r\n                    }\r\n                }\r\n            },\r\n            \"description\": \"orders made by this customer\",\r\n            \"required\": true\r\n        }\r\n    }\r\n}\r\n```\r\na quick note...\r\n\r\nwhen generating schema from classes:\r\n\r\n* only public class variables will be emitted.\r\n* all properties will be marked as \"required\".\r\n\r\nwhen generating schema from interfaces:\r\n\r\n* all properties will be emitted. \r\n* all properties will be marked as \"required\" unless modified with '?'.\r\n\r\n<a name=\"validating_json_schema\" />\r\n### validating json schema\r\n\r\nappex supports json schema validation from class and interface definitions. consider the following...\r\n\r\n```javascript\r\ninterface Customer {\r\n\r\n    firstname    : string;\r\n\r\n    lastname     : string;\r\n\r\n    age          : number;\r\n\r\n    emails       : string[];\r\n\r\n    option_a ?   : boolean; // optional\r\n\r\n    option_b ?   : boolean; // optional\r\n\r\n}\r\n\r\nexport function index(context) {\r\n\r\n    // a customer with invalid data.\r\n\r\n    var customer = {\r\n\r\n        firstname    : 'dave',\r\n\r\n        age          : '33',\r\n\r\n        emails       : [12345, 'dave@domain.com', true],\r\n\r\n        option_b     : 1,\r\n\r\n        option_c     : 1\r\n    }\r\n\r\n    // do validation.\r\n\r\n    var errors = context.schema.validate('Customer', customer);\r\n\r\n    if(errors) {\r\n\r\n        context.response.json(errors);\r\n    }\r\n}\r\n```\r\n\r\nwill output the following.\r\n\r\n```javascript\r\n[\r\n    {\r\n        \"message\": \"instance.lastname is required.\"\r\n    },\r\n    {\r\n        \"message\": \"instance.age is not a number\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[0] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[2] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_b is not a boolean\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_c unexpected property\"\r\n    }\r\n]\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\nThis section outlines development with appex.\r\n\r\n<a name=\"appex_declaration\" />\r\n### appex.d.ts declaration\r\n\r\nIf you develop on a TypeScript complicant editor (one that supports TS 0.9), appex comes bundled\r\nwith a declaration file you can reference in your project. If installing appex via npm, your\r\nreference should be as follows.\r\n\r\n```javascript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nexport function index (context:appex.web.IContext) { \r\n    \r\n    context.response.send('hello');\r\n}\r\n\r\nexport function wildcard(context:appex.web.IContext, path:string) {\r\n\r\n    context.response.serve('./', path);\r\n}\r\n```\r\n\r\nBy referencing this in your project, you get the benefits of code completion and static type checking\r\nagainst both appex, and the nodejs core.\r\n\r\n![](https://raw.github.com/sinclairzx81/appex/master/artifacts/code-completion.jpg)\r\n\r\nAdditional declaration files may be obtained from [here](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex ({ program : './index.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"users.ts\" />\r\n/// <reference path=\"pages.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { context.response.send('users.login') }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { context.response.send('users.logout') }\r\n}\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { context.response.send('home') }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { context.response.send('about') }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { context.response.send('contact') }\r\n\r\nexport function wildcard (context, path) { context.response.send(404, ' not found') }\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"license\" />\r\n## license\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) 2013 Haydn Paterson (sinclair) <haydn.developer@gmail.com>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in\r\nall copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\nTHE SOFTWARE.\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"https://raw.github.com/sinclairzx81/appex/master/license.txt","type":"The MIT License (MIT)"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"nodejs web api with typescript","directories":{},"dependencies":{"typescript.api":"0.6.0"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.5.2":{"name":"appex","version":"0.5.2","keywords":["typescript","web api","reflection","compiler","schema"],"author":{"name":"sinclair"},"_id":"appex@0.5.2","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"73972fe68915373645827b161fa299adf14c1fc8","tarball":"https://registry.npmjs.org/appex/-/appex-0.5.2.tgz","integrity":"sha512-O+6IvDvT8maaB3yvPLUI1/twwaHgoJIzNHl3+kYnQHnnxID07SJ3DIlZ0NXlEniJSfrTUtJSqZFTY5PugDmjLg==","signatures":[{"sig":"MEUCIQDOLM7q/GVkDiHY11XcFiUS24hstKw1uN+BXFNNhziaWAIgMI+/6QubYCbn6mfWLASzN43RD3V4sL5NsTAb8EYKkYI=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/artifacts/logo.jpg)\r\n\r\n### nodejs web api with [typescript](http://www.typescriptlang.org/)\r\n\r\n## overview\r\n\r\nappex is a nodejs web application framework built around the TypeScript programming language and\r\ncompiler. appex lets developers create and route http endpoints with TypeScript modules and \r\nfunctions, as well as providing nodejs developers similar reflection and type introspection \r\nservices found in platforms such as .net.\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http://localhost:3000/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// http://localhost:3000/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about');\r\n}\r\n\r\n// http://localhost:3000/(.*)\r\nexport function wildcard (context, path) {\r\n    \r\n    context.response.send(404, path + \" not found\");\r\n}\r\n\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n### contents\r\n\r\n* [getting started](#getting_started)\r\n\t* [create a application](#application)\r\n\t* [start up options](#options)\r\n\t* [running on an existing http server](#http_server)\r\n\t* [running as express middleware](#express_middleware)\r\n* [creating services with typescript](#creating_services)\r\n\t* [app context](#app_context)\r\n\t* [routing handlers](#routing_handlers)\r\n\t* [handler signatures](#handler_signatures)\r\n\t* [named handlers](#named_handlers)\r\n\t* [index handlers](#index_handlers)\r\n\t* [wildcard handlers](#wildcard_handlers)\r\n\t* [cascades](#cascades)\r\n\t* [http verbs](#http_verbs)\r\n\t* [middleware](#middleware)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [handling 404](#handling_404)\r\n\t* [serving static files](#serving_static_files)\r\n* [templating](#templating)\r\n\t* [rendering templates](#rendering_templates)\r\n\t* [template context](#template_context)\r\n\t* [layouts](#template_layouts)\r\n\t* [partials](#template_partials)\r\n\t* [caching and devmode](#caching_and_devmode)\r\n* [json schema](#json_schema)\r\n\t* [generating schema](#generating_schema)\r\n\t* [validating json](#validating_json)\r\n* [reflection](#reflection)\r\n\t* [reflect everything](#reflect_everything)\r\n\t* [reflect specific types](#reflect_specific_types)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [appex.d.ts declaration](#appex_declaration)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n* [license](#license)\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline creating appex applications and configuration.\r\n\r\n<a name=\"application\" />\r\n### create a application\r\n\r\nThe following code will create a standalone appex application and \r\nhttp server and listen on port 3000.\r\n\r\n```javascript\r\nvar appex   = require('appex');\r\n\r\nvar app   = appex({ program : './program.ts', \r\n                    devmode : true,\r\n                    logging : true });\r\n\r\napp.listen(3000);\r\n```\r\n\r\nnote: devmode and logging are optional. however, when developing \r\nwith appex, it is helpful to have these enabled.\r\n\r\n<a name=\"options\" />\r\n### start up options\r\n\r\nappex accepts the following start up options.\r\n\r\n```javascript\r\nvar options = {\r\n\r\n\t// (required) location of source file.\r\n\tprogram    : './program.ts', \r\n\r\n\t// (optional) recompile on request. (default:false) \r\n\tdevmode    : true,          \r\n\r\n\t// (optional) log to stdout. (default:false) \r\n\tlogging    : true,\r\n\r\n\t// (optional) user defined objects added to the app context.\r\n\tcontext    : {}\r\n};\r\n\r\nvar app = appex( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### running on an existing http server\r\n\r\nThe following demonstrates setting up appex on an existing nodejs http server. In \r\nthis example, appex will attempt to handle incoming requests, and if appex cannot\r\nroute the request, will fire the callback.\r\n\r\n```javascript\r\nvar http  = require('http');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\nvar server = http.createServer(function(req, res){\r\n\r\n    app(req, res, function() { // appex handler...\r\n\t\t\r\n\t\t// not handled.\r\n\r\n\t}); \r\n});\r\n\r\nserver.listen(3000);\r\n```\r\n\r\n\r\n<a name=\"express_middleware\" />\r\n### running as express middleware\r\n\r\nappex allows developers to augment existing express / connect applications by \r\nway of middleware. The following demonstrates setting up appex as express middleware.\r\n\r\n```javascript\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) ); \r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nLike in the \"running on an existing http server\" example above, appex will attempt to intercept incoming requests. \r\nif appex cannot find a matching route for the request, it will automatically call the \"next\" function to pass the request \r\non to the next middleware or express handler.\r\n\r\nin addition to this, appex may also act as traditional express middleware. In the example below, a appex wildcard\r\nfunction is created which will match \"all\" incoming requests, the wildcard function simply prints hello world to \r\nthe console and then calls context.next(), which passes the request on the express handler.\r\n\r\n```javascript\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tconsole.log('hello world!!');\r\n\r\n\tcontext.next(); // pass it on!\r\n}\r\n\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) );\r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nJust like traditional express middleware, appex will also inheriate the characteristics of the request.\r\n\r\nconsider the following example in which the jade view engine is configured for use. appex will inheritate the \r\nresponse.render() method, which is passed to the appex handler as context.response.render()\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\napp.configure(function(){\r\n\r\n  app.set('views', __dirname + '/views');\r\n  \r\n  // set up the jade engine.\r\n  app.set('view engine', 'jade'); \r\n  \r\n  // bind appex\r\n  app.use( appex({program:'./program.ts', devmode:true} ));  \r\n});\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/\r\nexport function index(context) {\r\n\t\r\n\t// jade renderer works!\r\n\tcontext.response.render('index', { title: 'Express' }); \r\n}\r\n```\r\n\r\n<a name=\"creating_services\" />\r\n## creating services with typescript\r\n\r\nThe following section describes how to write http accessible functions with appex.\r\n\r\n<a name=\"app_context\" />\r\n### app context\r\n\r\nAll appex functions are passed a application context object as their first argument. The app context object \r\nencapulates the http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the app context\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.cascade    - appex cascade.\r\n\r\n\t// context.next       - the next function (express middleware)\r\n\t\r\n\t// context.router     - the appex router\r\n\r\n\t// context.template   - the appex template engine.\r\n\t\r\n\t// context.module     - the module being run (this module)\r\n\r\n\t// context.schema     - json schema api.\r\n\r\n\t// context.mime       - a http mime type utility.\r\n}\r\n```\r\n\r\nit is possible to extend the default objects passed on the context by adding them on the appex startup options. The \r\nfollowing will attach the async module to the context. \r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = appex({ program : './program.ts', \r\n\t\t\t\t  devmode : true, \r\n\t\t\t      context: {\r\n\t\t\t\t\t\tasync : require('async')\r\n\t\t\t\t  }});\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\r\n\t// context.async = passed on the context.\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n```\r\n<a name=\"routing_handlers\" />\r\n### routing handlers\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context) { /* handle route */ }\r\n}\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/(.*)\r\nexport function wildcard (context, path) { /* handle route */ }\r\n\r\n```\r\n\r\n<a name=\"handler_signatures\" />\r\n### handler signatures\r\n\r\nappex supports three function signatures for http routing (named, index and wildcard). Functions that\r\ndo not apply these signatures will not be routed.\r\n\r\n<a name=\"named_handlers\" />\r\n### named handlers\r\n\r\nNamed handlers resolve urls to their current module scope + the name of the function.\r\n\r\nNamed handlers require the following signature:\r\n\r\n* name        - 'anything'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n\r\n// http://[host]:[port]/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about page');\r\n}\r\n\r\n// http://[host]:[port]/users/login\r\nexport module users {\r\n\r\n\texport function login(context) {\r\n\t\t\r\n\t\tcontext.response.send('handle login');\t\r\n\t}\r\n}\r\n\r\n```\r\n\r\n<a name=\"index_handlers\" />\r\n### index handlers\r\n\r\nIndex handlers resolve urls to their current module scope.\r\n\r\nIndex handlers require the following signature:\r\n\r\n* name        - 'index'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) \r\n\t{\t\r\n\t\tcontext.response.send('blog index');\r\n\t}\r\n}\r\n```\r\n\r\n<a name=\"wildcard_handlers\" />\r\n### wildcard handlers\r\n\r\nWildcard handlers resolve their urls to their current module scope + url.\r\n\r\nappex wildcard handlers allow for wildcard routing at a given module scope. Wildcard handlers\r\nsupport 'typed' url argument mapping, as denoted by the arguments annotation.\r\n\r\nIn addition, wildcard handlers also support optional arguments which can be specified with TypeScript's '?' \r\non argument names.\r\n\r\nappex wildcard handlers require the following signature:\r\n\r\n* name        - 'wildcard'\r\n* argument[0] - app context\r\n* argument[n] - 1 or more arguments to be mapped from the url\r\n* returns     - void (optional)\r\n\r\n```javascript\r\ndeclare var console;\r\n\r\nexport module blogs {\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11   - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/11  - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/3rd - not matched - (see number annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01     - matched     - (see ? annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013        - not matched - (month is required)\r\n\t\r\n    export function wildcard(context, year:number, month:number, day?:number) {\r\n\r\n        context.response.json({ year: year, month: month, day: day})\r\n    }\r\n}\r\n\r\n// url : http://[host]:[port]/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// url : http://[host]:[port]/(.*) \r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, 'not found');\r\n}\r\n\r\n```\r\nnote: appex supports boolean, number, string and any annotations on wildcard arguments. if no annotation\r\nis specified, appex interprets the argument as a string. the type 'any' is also interpreted as string.\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"cascades\" />\r\n### cascades\r\n\r\nappex supports a cascading attribute scheme on modules and functions. With this, developers can apply\r\narbituary meta data for modules and functions that will propagate through scope. appex has two special\r\ncascade properties for middleware and http verb matching, which are described below, however consider\r\nthe following code which illustrates the concept.\r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ncascade({a: 10}); // global.\r\n\r\ncascade('foo', {b : 20})\r\nexport module foo {\r\n\r\n    cascade('foo.bar', {c : 30})\r\n    export module bar {\r\n            \r\n        cascade('foo.bar.index', {d : 40})\r\n        export function index(context) {\r\n        \r\n            //context.cascade\r\n            //{\r\n            //    \"a\": 10,\r\n            //    \"b\": 20,\r\n            //    \"c\": 30,\r\n\t\t\t//    \"d\": 40\r\n            //}\r\n\r\n            context.response.json( context.cascade );       \r\n        }\r\n    }\r\n}\r\n\r\n```\r\n\r\n<a name=\"http_verbs\" />\r\n### http verbs\r\n\r\nappex handles http verb matching with cascades. appex will recognise the \r\n'verbs' property applied to the cascade to match against http verbs.\r\n\r\n```javascript\r\ncascade('index', { verbs: ['get'] })\r\nexport function index (context) { \r\n        \r\n    // only allow HTTP GET requests\r\n    context.response.send('index')\r\n}\r\n\r\ncascade('index', { verbs: ['post', 'put'] })\r\nexport function submit (context) { \r\n    \r\n    // only allow HTTP POST and PUT requests\r\n    context.response.send('submit')\r\n}\r\n```\r\n\r\n\r\n<a name=\"middleware\" />\r\n### middleware\r\n\r\nappex supports middleware with cascades. appex middleware defined with cascades allows\r\ndevelopers to scope middleware on single functions, or entire module scopes. appex will \r\nrecognise the 'use' property applied to the cascade to invoke middleware.\r\n\r\nthe following demonstrates how one might use middleware to secure a site admin.\r\n\r\nnote: middleware 'must' call next or handle the request. \r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ndeclare var console;\r\n\r\nfunction authenticate(context) {\r\n\r\n    console.log('authenticate')\r\n\r\n\t// call next() if authenticated, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\nfunction authorize(context) {\r\n\r\n    console.log('authorize')\r\n\r\n\t// call next() if authorized, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\n// apply security middleware to admin scope.\r\ncascade('admin', {use: [authenticate, authorize]}) \r\nexport module admin {\r\n\r\n    export function index(context) {\r\n        \r\n        console.log(context.cascade); // view cascade\r\n\r\n        context.response.send('access granted!')\r\n    }\r\n}\r\n\r\n// index handler has no middleware applied.\r\nexport function index (context) { \r\n    \r\n    console.log(context.cascade); // view cascade\r\n\r\n    context.response.send('home')\r\n}\r\n```\r\n\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex will only route functions prefixed with the TypeScript 'export' declarer. This rule\r\nalso applied to modules. Developers can use this to infer notions of public and private \r\nat the http level.\r\n\r\nconsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.send('public_function');\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```javascript\r\n// http:[host]:[port]/\r\nexport function index (context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard (context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n<a name=\"serving_static_files\" />\r\n## serving static files\r\n\r\nUse wildcard functions with context.response.serve() to serve static content.\r\n\r\n```javascript\r\nexport module static {\r\n\t\r\n\t// http:[host]:[port]/static/(.*)\r\n\texport function wildcard(context, path) {\r\n\r\n\t\tcontext.response.serve('./static/', path);\r\n\t}\r\n}\r\n\r\n// http:[host]:[port]/\r\nexport function index (context) {\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n\r\n<a name=\"templating\" />\r\n## templating\r\n\r\nappex comes bundled with a built in template engine which is modelled on the Microsoft \r\nRazor templating engine. The following sections outline its use.\r\n\r\n<a name=\"rendering_templates\" />\r\n### rendering templates\r\n\r\nthe template engine is passed on the appex app context. The following demonstrates\r\npassing data to, and rendering a template with the engine.\r\n```javascript\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n@for(var n in context.users) {\r\n\r\n\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t@(context.users[n].name)\r\n\t}\r\n}\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\r\n    context.response.send(text);\r\n}\r\n\r\n```\r\nnote: appex templates supports two control statements, @if for conditions and @for for iteration.\r\n\r\nnote: rendering variables are achieved with the @(expression) syntax. i.e. @(\"hello world\") or \r\n@(my_var_here).\r\n\r\n\r\n<a name=\"template_context\" />\r\n### template context\r\n\r\nAll user data passed to a template for rendering is passed on the templates 'context'.\r\n\r\n<a name=\"layouts\" />\r\n### layouts\r\n\r\nappex templates support layouts by way of the @layout and @section statements.\r\n\r\nconsider the following where layout.txt defines the sections 'header' and 'content' and the view.txt overrides\r\nthese sections with its own content.\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// layout.txt\r\n//----------------------------------------------\r\n\r\n<html>\r\n\r\n\t<head>\r\n\t\t\r\n\t\t@section header\r\n\r\n\t</head>\r\n\r\n\t<body>\r\n\r\n\t\t@section content {\r\n\t\t\r\n\t\t\t<span>some default content</span>\r\n\t\t\t\r\n\t\t}\r\n\r\n\t</body>\r\n\t\r\n</html>\r\n\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n@layout 'layout.txt'\r\n\r\n@section header {\r\n\r\n\t<title>my page</title>\r\n}\r\n\r\n@section content {\r\n\r\n\t<p>overriding the layout.txt content section.</p>\r\n\r\n\t<ul>\r\n\t@for(var n in context.users) {\r\n\r\n\t\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t\t<li>@(context.users[n].name)</li>\r\n\t\t}\r\n\t}\r\n\t</ul>\r\n}\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\r\n    context.response.send(text);\r\n}\r\n```\r\n\r\nnote : it is optional to override content in the view.txt. \r\n\r\nnote : @sections without a body (like the header above) are treated as placeholders. \r\n\r\n<a name=\"partials\" />\r\n### partials\r\n\r\nappex templates also allow for partial views with the @render statment. consider the following \r\nwhich renders the nav.txt file into the layout.txt file.\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// nav.txt\r\n//----------------------------------------------\r\n<ul>\r\n\t<li>home</li>\r\n\t<li>about</li>\r\n\t<li>contact</li>\r\n</ul>\r\n\r\n//----------------------------------------------\r\n// layout.txt\r\n//----------------------------------------------\r\n\r\n<html>\r\n\t<head>\r\n\t\t\r\n\t\t@section header\r\n\r\n\t</head>\r\n\r\n\t<body>\r\n\t\t\r\n\t\t@render 'nav.txt'\r\n\r\n\t\t@section content {\r\n\t\t\r\n\t\t\t<span>some default content</span>\r\n\t\t\t\r\n\t\t}\r\n\r\n\t</body>\r\n\t\r\n</html>\r\n\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n@layout 'layout.txt'\r\n\r\n@section header {\r\n\r\n\t<title>my page</title>\r\n}\r\n\r\n@section content {\r\n\r\n\t<p>overriding the layout.txt content section.</p>\r\n\r\n\t<ul>\r\n\t@for(var n in context.users) {\r\n\r\n\t\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t\t<li>@(context.users[n].name)</li>\r\n\t\t}\r\n\t}\r\n\t</ul>\r\n}\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\r\n    context.response.send(text);\r\n}\r\n```\r\n\r\n<a name=\"caching_and_devmode\" />\r\n### caching and devmode\r\n\r\nappex template content is not cached (the implementor is expected to handle their own caching)\r\nhowever the generated template code is. \r\n\r\nappex templates do inheriate the behaviour of the appex 'devmode' option. setting\r\ndevmode to 'true' will cause template code to be reloaded from disk and code generated with each \r\nrequest. setting devmode to false will load content from disk on first request, and \r\ncache the generated template code in memory for the lifetime of the application.\r\n\r\n<a name=\"json_schema\" />\r\n## json schema\r\n\r\nappex provides functionality for generating json schemas from TypeScript classes\r\nand interfaces as well as tools for validating json data.\r\n\r\n<a name=\"generating_schema\" />\r\n### generating schema\r\n\r\nThe following demonstrates generating json schema from the following class\r\nhierarchy.\r\n\r\n```javascript\r\nexport module model {\r\n\r\n    /** a product */\r\n    export class Product {\r\n        \r\n        /** the product name */\r\n        public name        : string;\r\n\r\n        /** the product description */\r\n        public description : string;\r\n\r\n        /** the product cost */\r\n        public cost        : number;\r\n    } \r\n\r\n    /** a order */\r\n    export class Order {\r\n        \r\n        /** the product being ordered */\r\n        public products  : Product;\r\n    }\r\n\r\n    /** a customer */\r\n    export class Customer {\r\n\r\n        /** the customers firstname */\r\n        public firstname  : string;\r\n\r\n        /** the customers lastname */\r\n        public lastname   : string;\r\n\r\n        /** orders made by this customer */\r\n        public orders     : Order[];\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.IContext) {\r\n\t\r\n\t// pass the fully qualified name of the type.\r\n    var schema = context.schema.generate('model.Customer');\r\n\r\n    context.response.json(schema);\r\n}\r\n```\r\n\r\nwhich generates the following json schema.\r\n\r\n```javascript\r\n{\r\n    \"id\": \"model.Customer\",\r\n    \"type\": \"object\",\r\n    \"description\": \"a customer\",\r\n    \"properties\": {\r\n        \"firstname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers firstname\",\r\n            \"required\": true\r\n        },\r\n        \"lastname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers lastname\",\r\n            \"required\": true\r\n        },\r\n        \"orders\": {\r\n            \"type\": \"array\",\r\n            \"items\": {\r\n                \"type\": {\r\n                    \"id\": \"model.Order\",\r\n                    \"type\": \"object\",\r\n                    \"description\": \"a order\",\r\n                    \"properties\": {\r\n                        \"products\": {\r\n                            \"id\": \"model.Product\",\r\n                            \"type\": \"object\",\r\n                            \"description\": \"a product\",\r\n                            \"properties\": {\r\n                                \"name\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product name\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"description\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product description\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"cost\": {\r\n                                    \"type\": \"number\",\r\n                                    \"description\": \"the product cost\",\r\n                                    \"required\": true\r\n                                }\r\n                            },\r\n                            \"required\": true\r\n                        }\r\n                    }\r\n                }\r\n            },\r\n            \"description\": \"orders made by this customer\",\r\n            \"required\": true\r\n        }\r\n    }\r\n}\r\n```\r\na quick note...\r\n\r\nwhen generating schema from classes:\r\n\r\n* only public class variables will be emitted.\r\n* all properties will be marked as \"required\".\r\n\r\nwhen generating schema from interfaces:\r\n\r\n* all properties will be emitted. \r\n* all properties will be marked as \"required\" unless modified with '?'.\r\n\r\n<a name=\"validating_schema\" />\r\n### validating json\r\n\r\nappex supports json schema validation from class and interface definitions. consider the following...\r\n\r\n```javascript\r\ninterface Customer {\r\n\r\n    firstname    : string;\r\n\r\n    lastname     : string;\r\n\r\n    age          : number;\r\n\r\n    emails       : string[];\r\n\r\n    option_a ?   : boolean; // optional\r\n\r\n    option_b ?   : boolean; // optional\r\n\r\n}\r\n\r\nexport function index(context) {\r\n\r\n    // a customer with invalid data.\r\n\r\n    var customer = {\r\n\r\n        firstname    : 'dave',\r\n\r\n        age          : '33',\r\n\r\n        emails       : [12345, 'dave@domain.com', true],\r\n\r\n        option_b     : 1,\r\n\r\n        option_c     : 1\r\n    }\r\n\r\n    // do validation.\r\n\r\n    var errors = context.schema.validate('Customer', customer);\r\n\r\n    if(errors) {\r\n\r\n        context.response.json(errors);\r\n    }\r\n}\r\n```\r\n\r\nwill output the following.\r\n\r\n```javascript\r\n[\r\n    {\r\n        \"message\": \"instance.lastname is required.\"\r\n    },\r\n    {\r\n        \"message\": \"instance.age is not a number\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[0] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[2] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_b is not a boolean\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_c unexpected property\"\r\n    }\r\n]\r\n```\r\n\r\n<a name=\"reflection\" />\r\n## reflection\r\n\r\nappex provides a reflection api derived from TypeScript's type system that developers can \r\nleverage to reflect type information declared throughout their appex modules. \r\n\r\nthe following section outlines how to use the reflection api.\r\n\r\n<a name=\"reflect_everything\" />\r\n### reflect everything\r\n\r\nthe appex reflection api is passed on the context.module.reflection property and is available to all\r\nappex handler methods. The following code will JSON serialize everything declared in your appex\r\nproject and write it to the http response. \r\n\r\n```javascript\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection );\r\n}\r\n```\r\n\r\n<a name=\"reflect_specific_types\" />\r\n### reflect specific types\r\n\r\nIn typical scenarios, developers will want to leverage reflection meta data to generate\r\nservice contacts and client side models. the reflection api lets you access meta data \r\nfor the following types declared in your project. \r\n\r\n* modules\r\n* imports\r\n* classes\r\n* interfaces\r\n* functions\r\n* variables\r\n\r\nto access specific type metadata, use the reflection.get([qualifier]) method, as demonstrated below.\r\n\r\n```javascript\r\nexport module model {\r\n    \r\n    export class Customer {\r\n\r\n        public firstname   : string;\r\n\r\n        public lastname    : string;\r\n\r\n        public age         : number;\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('model.Customer') );\r\n}\r\n```\r\nand methods..\r\n\r\n```javascript\r\nfunction some_method(a:string, b:number, c?:boolean) : void { }\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_method') );\r\n}\r\n```\r\n\r\n....and variables...\r\n\r\n```javascript\r\nvar some_variable:number = 10;\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_variable') );\r\n}\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\nThis section outlines development with appex.\r\n\r\n<a name=\"appex_declaration\" />\r\n### appex.d.ts declaration\r\n\r\nIf you develop on a TypeScript complicant editor (one that supports TS 0.9), appex comes bundled\r\nwith a declaration file you can reference in your project. If installing appex via npm, your\r\nreference should be as follows.\r\n\r\n```javascript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nexport function index (context:appex.web.IContext) { \r\n    \r\n    context.response.send('hello');\r\n}\r\n\r\nexport function wildcard(context:appex.web.IContext, path:string) {\r\n\r\n    context.response.serve('./', path);\r\n}\r\n```\r\n\r\nBy referencing this in your project, you get the benefits of code completion and static type checking\r\nagainst both appex, and the nodejs core.\r\n\r\n![](https://raw.github.com/sinclairzx81/appex/master/artifacts/code-completion.jpg)\r\n\r\nAdditional declaration files may be obtained from [here](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex ({ program : './index.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"users.ts\" />\r\n/// <reference path=\"pages.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { context.response.send('users.login') }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { context.response.send('users.logout') }\r\n}\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { context.response.send('home') }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { context.response.send('about') }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { context.response.send('contact') }\r\n\r\nexport function wildcard (context, path) { context.response.send(404, ' not found') }\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"license\" />\r\n## license\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) 2013 Haydn Paterson (sinclair) <haydn.developer@gmail.com>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in\r\nall copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\nTHE SOFTWARE.\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"https://raw.github.com/sinclairzx81/appex/master/license.txt","type":"The MIT License (MIT)"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"nodejs web api with typescript","directories":{},"dependencies":{"typescript.api":"0.6.0"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.5.3":{"name":"appex","version":"0.5.3","keywords":["typescript","web api","reflection","compiler","schema"],"author":{"name":"sinclair"},"_id":"appex@0.5.3","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"62d73f1739eee0bea2e9dc8bbba37311d42e2d59","tarball":"https://registry.npmjs.org/appex/-/appex-0.5.3.tgz","integrity":"sha512-2Tiepc0NOLgKkA4jYhqkiMobG3hGUX9lWCup4i3ua0bCYEOdgfSC4DzDzN95QbewtQ8TXr8OxeEIRi4SbV+Big==","signatures":[{"sig":"MEUCICRoA+ZWQaOTgmUguflTPLdM8qSkesxXQEzm0FvgtYweAiEAlWaems1oIJ8lA9JWAHQBMyQ3mmfhF4RW9DclWP3NFpg=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/artifacts/logo.jpg)\r\n\r\n### nodejs web api with [typescript](http://www.typescriptlang.org/)\r\n\r\n## overview\r\n\r\nappex is a nodejs web application framework built around the TypeScript programming language and\r\ncompiler. appex lets developers create and route http endpoints with TypeScript modules and \r\nfunctions, as well as providing nodejs developers similar reflection and type introspection \r\nservices found in platforms such as .net.\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http://localhost:3000/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// http://localhost:3000/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about');\r\n}\r\n\r\n// http://localhost:3000/(.*)\r\nexport function wildcard (context, path) {\r\n    \r\n    context.response.send(404, path + \" not found\");\r\n}\r\n\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n### contents\r\n\r\n* [getting started](#getting_started)\r\n\t* [create a application](#application)\r\n\t* [start up options](#options)\r\n\t* [running on an existing http server](#http_server)\r\n\t* [running as express middleware](#express_middleware)\r\n* [creating services with typescript](#creating_services)\r\n\t* [app context](#app_context)\r\n\t* [routing handlers](#routing_handlers)\r\n\t* [handler signatures](#handler_signatures)\r\n\t* [named handlers](#named_handlers)\r\n\t* [index handlers](#index_handlers)\r\n\t* [wildcard handlers](#wildcard_handlers)\r\n\t* [cascades](#cascades)\r\n\t* [http verbs](#http_verbs)\r\n\t* [middleware](#middleware)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [handling 404](#handling_404)\r\n\t* [serving static files](#serving_static_files)\r\n* [templating](#templating)\r\n\t* [overview](#template_overview)\r\n\t* [context](#template_context)\t\r\n\t* [syntax](#template_syntax)\r\n\t* [layouts and sections](#template_layouts_and_sections)\r\n\t* [render](#template_render)\r\n\t* [caching and devmode](#caching_and_devmode)\r\n* [json schema](#json_schema)\r\n\t* [generating schema](#generating_schema)\r\n\t* [validating json](#validating_json)\r\n* [reflection](#reflection)\r\n\t* [reflect everything](#reflect_everything)\r\n\t* [reflect specific types](#reflect_specific_types)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [appex.d.ts declaration](#appex_declaration)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n* [license](#license)\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline creating appex applications and configuration.\r\n\r\n<a name=\"application\" />\r\n### create a application\r\n\r\nThe following code will create a standalone appex application and \r\nhttp server and listen on port 3000.\r\n\r\n```javascript\r\nvar appex   = require('appex');\r\n\r\nvar app   = appex({ program : './program.ts', \r\n                    devmode : true,\r\n                    logging : true });\r\n\r\napp.listen(3000);\r\n```\r\n\r\nnote: devmode and logging are optional. however, when developing \r\nwith appex, it is helpful to have these enabled.\r\n\r\n<a name=\"options\" />\r\n### start up options\r\n\r\nappex accepts the following start up options.\r\n\r\n```javascript\r\nvar options = {\r\n\r\n\t// (required) location of source file.\r\n\tprogram    : './program.ts', \r\n\r\n\t// (optional) recompile on request. (default:false) \r\n\tdevmode    : true,          \r\n\r\n\t// (optional) log to stdout. (default:false) \r\n\tlogging    : true,\r\n\r\n\t// (optional) user defined objects added to the app context.\r\n\tcontext    : {}\r\n};\r\n\r\nvar app = appex( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### running on an existing http server\r\n\r\nThe following demonstrates setting up appex on an existing nodejs http server. In \r\nthis example, appex will attempt to handle incoming requests, and if appex cannot\r\nroute the request, will fire the callback.\r\n\r\n```javascript\r\nvar http  = require('http');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\nvar server = http.createServer(function(req, res){\r\n\r\n    app(req, res, function() { // appex handler...\r\n\t\t\r\n\t\t// not handled.\r\n\r\n\t}); \r\n});\r\n\r\nserver.listen(3000);\r\n```\r\n\r\n\r\n<a name=\"express_middleware\" />\r\n### running as express middleware\r\n\r\nappex allows developers to augment existing express / connect applications by \r\nway of middleware. The following demonstrates setting up appex as express middleware.\r\n\r\n```javascript\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) ); \r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nLike in the \"running on an existing http server\" example above, appex will attempt to intercept incoming requests. \r\nif appex cannot find a matching route for the request, it will automatically call the \"next\" function to pass the request \r\non to the next middleware or express handler.\r\n\r\nin addition to this, appex may also act as traditional express middleware. In the example below, a appex wildcard\r\nfunction is created which will match \"all\" incoming requests, the wildcard function simply prints hello world to \r\nthe console and then calls context.next(), which passes the request on the express handler.\r\n\r\n```javascript\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tconsole.log('hello world!!');\r\n\r\n\tcontext.next(); // pass it on!\r\n}\r\n\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) );\r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nJust like traditional express middleware, appex will also inheriate the characteristics of the request.\r\n\r\nconsider the following example in which the jade view engine is configured for use. appex will inheritate the \r\nresponse.render() method, which is passed to the appex handler as context.response.render()\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\napp.configure(function(){\r\n\r\n  app.set('views', __dirname + '/views');\r\n  \r\n  // set up the jade engine.\r\n  app.set('view engine', 'jade'); \r\n  \r\n  // bind appex\r\n  app.use( appex({program:'./program.ts', devmode:true} ));  \r\n});\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/\r\nexport function index(context) {\r\n\t\r\n\t// jade renderer works!\r\n\tcontext.response.render('index', { title: 'Express' }); \r\n}\r\n```\r\n\r\n<a name=\"creating_services\" />\r\n## creating services with typescript\r\n\r\nThe following section describes how to write http accessible functions with appex.\r\n\r\n<a name=\"app_context\" />\r\n### app context\r\n\r\nAll appex functions are passed a application context object as their first argument. The app context object \r\nencapulates the http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the app context\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.cascade    - appex cascade.\r\n\r\n\t// context.next       - the next function (express middleware)\r\n\t\r\n\t// context.router     - the appex router\r\n\r\n\t// context.template   - the appex template engine.\r\n\t\r\n\t// context.module     - the module being run (this module)\r\n\r\n\t// context.schema     - json schema api.\r\n\r\n\t// context.mime       - a http mime type utility.\r\n}\r\n```\r\n\r\nit is possible to extend the default objects passed on the context by adding them on the appex startup options. The \r\nfollowing will attach the async module to the context. \r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = appex({ program : './program.ts', \r\n\t\t\t\t  devmode : true, \r\n\t\t\t      context: {\r\n\t\t\t\t\t\tasync : require('async')\r\n\t\t\t\t  }});\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\r\n\t// context.async = passed on the context.\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n```\r\n<a name=\"routing_handlers\" />\r\n### routing handlers\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context) { /* handle route */ }\r\n}\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/(.*)\r\nexport function wildcard (context, path) { /* handle route */ }\r\n\r\n```\r\n\r\n<a name=\"handler_signatures\" />\r\n### handler signatures\r\n\r\nappex supports three function signatures for http routing (named, index and wildcard). Functions that\r\ndo not apply these signatures will not be routed.\r\n\r\n<a name=\"named_handlers\" />\r\n### named handlers\r\n\r\nNamed handlers resolve urls to their current module scope + the name of the function.\r\n\r\nNamed handlers require the following signature:\r\n\r\n* name        - 'anything'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n\r\n// http://[host]:[port]/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about page');\r\n}\r\n\r\n// http://[host]:[port]/users/login\r\nexport module users {\r\n\r\n\texport function login(context) {\r\n\t\t\r\n\t\tcontext.response.send('handle login');\t\r\n\t}\r\n}\r\n\r\n```\r\n\r\n<a name=\"index_handlers\" />\r\n### index handlers\r\n\r\nIndex handlers resolve urls to their current module scope.\r\n\r\nIndex handlers require the following signature:\r\n\r\n* name        - 'index'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) \r\n\t{\t\r\n\t\tcontext.response.send('blog index');\r\n\t}\r\n}\r\n```\r\n\r\n<a name=\"wildcard_handlers\" />\r\n### wildcard handlers\r\n\r\nWildcard handlers resolve their urls to their current module scope + url.\r\n\r\nappex wildcard handlers allow for wildcard routing at a given module scope. Wildcard handlers\r\nsupport 'typed' url argument mapping, as denoted by the arguments annotation.\r\n\r\nIn addition, wildcard handlers also support optional arguments which can be specified with TypeScript's '?' \r\non argument names.\r\n\r\nappex wildcard handlers require the following signature:\r\n\r\n* name        - 'wildcard'\r\n* argument[0] - app context\r\n* argument[n] - 1 or more arguments to be mapped from the url\r\n* returns     - void (optional)\r\n\r\n```javascript\r\ndeclare var console;\r\n\r\nexport module blogs {\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11   - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/11  - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/3rd - not matched - (see number annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01     - matched     - (see ? annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013        - not matched - (month is required)\r\n\t\r\n    export function wildcard(context, year:number, month:number, day?:number) {\r\n\r\n        context.response.json({ year: year, month: month, day: day})\r\n    }\r\n}\r\n\r\n// url : http://[host]:[port]/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// url : http://[host]:[port]/(.*) \r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, 'not found');\r\n}\r\n\r\n```\r\nnote: appex supports boolean, number, string and any annotations on wildcard arguments. if no annotation\r\nis specified, appex interprets the argument as a string. the type 'any' is also interpreted as string.\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"cascades\" />\r\n### cascades\r\n\r\nappex supports a cascading attribute scheme on modules and functions. With this, developers can apply\r\narbituary meta data for modules and functions that will propagate through scope. appex has two special\r\ncascade properties for middleware and http verb matching, which are described below, however consider\r\nthe following code which illustrates the concept.\r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ncascade({a: 10}); // global.\r\n\r\ncascade('foo', {b : 20})\r\nexport module foo {\r\n\r\n    cascade('foo.bar', {c : 30})\r\n    export module bar {\r\n            \r\n        cascade('foo.bar.index', {d : 40})\r\n        export function index(context) {\r\n        \r\n            //context.cascade\r\n            //{\r\n            //    \"a\": 10,\r\n            //    \"b\": 20,\r\n            //    \"c\": 30,\r\n\t\t\t//    \"d\": 40\r\n            //}\r\n\r\n            context.response.json( context.cascade );       \r\n        }\r\n    }\r\n}\r\n\r\n```\r\n\r\n<a name=\"http_verbs\" />\r\n### http verbs\r\n\r\nappex handles http verb matching with cascades. appex will recognise the \r\n'verbs' property applied to the cascade to match against http verbs.\r\n\r\n```javascript\r\ncascade('index', { verbs: ['get'] })\r\nexport function index (context) { \r\n        \r\n    // only allow HTTP GET requests\r\n    context.response.send('index')\r\n}\r\n\r\ncascade('index', { verbs: ['post', 'put'] })\r\nexport function submit (context) { \r\n    \r\n    // only allow HTTP POST and PUT requests\r\n    context.response.send('submit')\r\n}\r\n```\r\n\r\n\r\n<a name=\"middleware\" />\r\n### middleware\r\n\r\nappex supports middleware with cascades. appex middleware defined with cascades allows\r\ndevelopers to scope middleware on single functions, or entire module scopes. appex will \r\nrecognise the 'use' property applied to the cascade to invoke middleware.\r\n\r\nthe following demonstrates how one might use middleware to secure a site admin.\r\n\r\nnote: middleware 'must' call next or handle the request. \r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ndeclare var console;\r\n\r\nfunction authenticate(context) {\r\n\r\n    console.log('authenticate')\r\n\r\n\t// call next() if authenticated, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\nfunction authorize(context) {\r\n\r\n    console.log('authorize')\r\n\r\n\t// call next() if authorized, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\n// apply security middleware to admin scope.\r\ncascade('admin', {use: [authenticate, authorize]}) \r\nexport module admin {\r\n\r\n    export function index(context) {\r\n        \r\n        console.log(context.cascade); // view cascade\r\n\r\n        context.response.send('access granted!')\r\n    }\r\n}\r\n\r\n// index handler has no middleware applied.\r\nexport function index (context) { \r\n    \r\n    console.log(context.cascade); // view cascade\r\n\r\n    context.response.send('home')\r\n}\r\n```\r\n\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex will only route functions prefixed with the TypeScript 'export' declarer. This rule\r\nalso applied to modules. Developers can use this to infer notions of public and private \r\nat the http level.\r\n\r\nconsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.send('public_function');\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```javascript\r\n// http:[host]:[port]/\r\nexport function index (context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard (context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n<a name=\"serving_static_files\" />\r\n## serving static files\r\n\r\nUse wildcard functions with context.response.serve() to serve static content.\r\n\r\n```javascript\r\nexport module static {\r\n\t\r\n\t// http:[host]:[port]/static/(.*)\r\n\texport function wildcard(context, path) {\r\n\r\n\t\tcontext.response.serve('./static/', path);\r\n\t}\r\n}\r\n\r\n// http:[host]:[port]/\r\nexport function index (context) {\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n\r\n<a name=\"templating\" />\r\n## templating\r\n\r\nappex comes bundled with a built in template engine which is modelled on the Microsoft \r\nRazor templating engine. The following sections outline its use.\r\n\r\n<a name=\"template_overview\" />\r\n### overview\r\n\r\nThe appex template engine is available to all handlers by default. it is accessible\r\non the context.template property. the following is an example of its use.\r\n\r\n```\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n<ul>\r\n@for(var n in context.users) {\r\n\r\n\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t<li>@(context.users[n].name)</li>\r\n\t}\r\n}\r\n</ul>\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\t\r\n\tcontext.response.headers['Content-Type'] = 'text/html';\r\n\r\n    context.response.send(text);\r\n}\r\n\r\n```\r\n\r\n<a name=\"template_context\" />\r\n### context\r\n\r\neach template is passed a data context. this context allows the caller to \r\nsend data to the template for rendering. the context parameter is optional.\r\nthe example below is sending the users array to the template context for \r\nrendering.\r\n\r\n```\r\nexport function index(context) {\r\n\t\r\n    var users  = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    context.response.send(context.template.render('./view.txt', { users: users }));\r\n}\r\n```\r\n\r\n<a name=\"template_syntax\" />\r\n### syntax\r\n\r\nappex templates support the following statements and syntax\r\n\r\n#### if statement\r\n\r\nif statments are supported.\r\n\r\n```\r\n@if(expression) {\r\n\tsome content\r\n}\r\n\r\n@if(a > 10) {\r\n\tsome content\r\n}\r\n\r\n@(user.loggedin) {\r\n\t<span>welcome</span>\r\n}\r\n```\r\n\r\n#### for statement\r\n\r\nthe following for loops are supported.\r\n\r\n```\r\n@for(var i = i; i < 100; i++) {\r\n\t@(i)\r\n}\r\n\r\n@for(var n in list) {\r\n\t@(list[n])\r\n}\r\n```\r\n\r\n#### expressions\r\n\r\nwill emit the value contained.\r\n\r\n```\r\n@('hello world')\r\n\r\n@(123)\r\n\r\n@(some_variable)\r\n```\r\n\r\n#### code blocks\r\n\r\ncode blocks can be useful for adding template side rendering logic.\r\n\r\n```\r\n@{\r\n\tvar message = 'hello'\r\n}\r\n\r\n@(message)\r\n```\r\n\r\n#### comments\r\n```\r\n@*\r\n\tthis comment will not be rendered!\r\n*@\r\n```\r\n\r\n<a name=\"template_layouts_and_sections\" />\r\n### layouts and sections\r\n\r\nappex templates support template inheritance.\r\n\r\nconsider the following where layout.txt defines the sections 'header' and 'content' and the view.txt overrides\r\nthese sections with its own content.\r\n\r\n```\r\n//----------------------------------------------\r\n// layout.txt\r\n//----------------------------------------------\r\n\r\n<html>\r\n\r\n\t<head>\r\n\t\t\r\n\t\t@section header\r\n\r\n\t</head>\r\n\r\n\t<body>\r\n\r\n\t\t@section content {\r\n\t\t\r\n\t\t\t<span>some default content</span>\r\n\t\t\t\r\n\t\t}\r\n\r\n\t</body>\r\n\t\r\n</html>\r\n\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n@layout 'layout.txt'\r\n\r\n@section header {\r\n\r\n\t<title>my page</title>\r\n}\r\n\r\n@section content {\r\n\r\n\t<p>overriding the layout.txt content section.</p>\r\n\r\n\t<ul>\r\n\t@for(var n in context.users) {\r\n\r\n\t\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t\t<li>@(context.users[n].name)</li>\r\n\t\t}\r\n\t}\r\n\t</ul>\r\n}\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\r\n    context.response.send(text);\r\n}\r\n```\r\n\r\nnote : when specifying a layout, the view will only render content within\r\nthe layouts section placeholders. \r\n\r\n<a name=\"render\" />\r\n### render\r\n\r\nappex templates also allow for partial views with the @render statment. consider the following \r\nwhich renders the nav.txt file into the layout.txt file.\r\n\r\n```\r\n//----------------------------------------------\r\n// nav.txt\r\n//----------------------------------------------\r\n<ul>\r\n\t<li>home</li>\r\n\t<li>about</li>\r\n\t<li>contact</li>\r\n</ul>\r\n\r\n//----------------------------------------------\r\n// layout.txt\r\n//----------------------------------------------\r\n\r\n<html>\r\n\t<head>\r\n\t\t\r\n\t\t@section header\r\n\r\n\t</head>\r\n\r\n\t<body>\r\n\t\t\r\n\t\t@render 'nav.txt'\r\n\r\n\t\t@section content {\r\n\t\t\r\n\t\t\t<span>some default content</span>\r\n\t\t\t\r\n\t\t}\r\n\r\n\t</body>\r\n\t\r\n</html>\r\n\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n@layout 'layout.txt'\r\n\r\n@section header {\r\n\r\n\t<title>my page</title>\r\n}\r\n\r\n@section content {\r\n\r\n\t<p>overriding the layout.txt content section.</p>\r\n\r\n\t<ul>\r\n\t@for(var n in context.users) {\r\n\r\n\t\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t\t<li>@(context.users[n].name)</li>\r\n\t\t}\r\n\t}\r\n\t</ul>\r\n}\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\r\n    context.response.send(text);\r\n}\r\n```\r\n\r\n<a name=\"caching_and_devmode\" />\r\n### caching and devmode\r\n\r\nappex template content is not cached (the implementor is expected to handle their own caching)\r\nhowever the generated template code is. \r\n\r\nappex templates do inheriate the behaviour of the appex 'devmode' option. setting\r\ndevmode to 'true' will cause template code to be reloaded from disk and code generated with each \r\nrequest. setting devmode to false will load content from disk on first request, and \r\ncache the generated template code in memory for the lifetime of the application.\r\n\r\nin addition to this, a implementation where the devmode is false can override the caching \r\nbehaviour with the following.\r\n\r\n```javascript\r\nexport function index(context) {\r\n\r\n\t// manually override the template devmode option.\r\n\tcontext.template.option.devmode = true; \r\n\r\n\tcontext.response.send(context.template.render('./view.txt'))\r\n}\r\n```\r\n\r\n<a name=\"json_schema\" />\r\n## json schema\r\n\r\nappex provides functionality for generating json schemas from TypeScript classes\r\nand interfaces as well as tools for validating json data.\r\n\r\n<a name=\"generating_schema\" />\r\n### generating schema\r\n\r\nThe following demonstrates generating json schema from the following class\r\nhierarchy.\r\n\r\n```javascript\r\nexport module model {\r\n\r\n    /** a product */\r\n    export class Product {\r\n        \r\n        /** the product name */\r\n        public name        : string;\r\n\r\n        /** the product description */\r\n        public description : string;\r\n\r\n        /** the product cost */\r\n        public cost        : number;\r\n    } \r\n\r\n    /** a order */\r\n    export class Order {\r\n        \r\n        /** the product being ordered */\r\n        public products  : Product;\r\n    }\r\n\r\n    /** a customer */\r\n    export class Customer {\r\n\r\n        /** the customers firstname */\r\n        public firstname  : string;\r\n\r\n        /** the customers lastname */\r\n        public lastname   : string;\r\n\r\n        /** orders made by this customer */\r\n        public orders     : Order[];\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.IContext) {\r\n\t\r\n\t// pass the fully qualified name of the type.\r\n    var schema = context.schema.generate('model.Customer');\r\n\r\n    context.response.json(schema);\r\n}\r\n```\r\n\r\nwhich generates the following json schema.\r\n\r\n```javascript\r\n{\r\n    \"id\": \"model.Customer\",\r\n    \"type\": \"object\",\r\n    \"description\": \"a customer\",\r\n    \"properties\": {\r\n        \"firstname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers firstname\",\r\n            \"required\": true\r\n        },\r\n        \"lastname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers lastname\",\r\n            \"required\": true\r\n        },\r\n        \"orders\": {\r\n            \"type\": \"array\",\r\n            \"items\": {\r\n                \"type\": {\r\n                    \"id\": \"model.Order\",\r\n                    \"type\": \"object\",\r\n                    \"description\": \"a order\",\r\n                    \"properties\": {\r\n                        \"products\": {\r\n                            \"id\": \"model.Product\",\r\n                            \"type\": \"object\",\r\n                            \"description\": \"a product\",\r\n                            \"properties\": {\r\n                                \"name\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product name\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"description\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product description\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"cost\": {\r\n                                    \"type\": \"number\",\r\n                                    \"description\": \"the product cost\",\r\n                                    \"required\": true\r\n                                }\r\n                            },\r\n                            \"required\": true\r\n                        }\r\n                    }\r\n                }\r\n            },\r\n            \"description\": \"orders made by this customer\",\r\n            \"required\": true\r\n        }\r\n    }\r\n}\r\n```\r\na quick note...\r\n\r\nwhen generating schema from classes:\r\n\r\n* only public class variables will be emitted.\r\n* all properties will be marked as \"required\".\r\n\r\nwhen generating schema from interfaces:\r\n\r\n* all properties will be emitted. \r\n* all properties will be marked as \"required\" unless modified with '?'.\r\n\r\n<a name=\"validating_schema\" />\r\n### validating json\r\n\r\nappex supports json schema validation from class and interface definitions. consider the following...\r\n\r\n```javascript\r\ninterface Customer {\r\n\r\n    firstname    : string;\r\n\r\n    lastname     : string;\r\n\r\n    age          : number;\r\n\r\n    emails       : string[];\r\n\r\n    option_a ?   : boolean; // optional\r\n\r\n    option_b ?   : boolean; // optional\r\n\r\n}\r\n\r\nexport function index(context) {\r\n\r\n    // a customer with invalid data.\r\n\r\n    var customer = {\r\n\r\n        firstname    : 'dave',\r\n\r\n        age          : '33',\r\n\r\n        emails       : [12345, 'dave@domain.com', true],\r\n\r\n        option_b     : 1,\r\n\r\n        option_c     : 1\r\n    }\r\n\r\n    // do validation.\r\n\r\n    var errors = context.schema.validate('Customer', customer);\r\n\r\n    if(errors) {\r\n\r\n        context.response.json(errors);\r\n    }\r\n}\r\n```\r\n\r\nwill output the following.\r\n\r\n```javascript\r\n[\r\n    {\r\n        \"message\": \"instance.lastname is required.\"\r\n    },\r\n    {\r\n        \"message\": \"instance.age is not a number\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[0] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[2] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_b is not a boolean\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_c unexpected property\"\r\n    }\r\n]\r\n```\r\n\r\n<a name=\"reflection\" />\r\n## reflection\r\n\r\nappex provides a reflection api derived from TypeScript's type system that developers can \r\nleverage to reflect type information declared throughout their appex modules. \r\n\r\nthe following section outlines how to use the reflection api.\r\n\r\n<a name=\"reflect_everything\" />\r\n### reflect everything\r\n\r\nthe appex reflection api is passed on the context.module.reflection property and is available to all\r\nappex handler methods. The following code will JSON serialize everything declared in your appex\r\nproject and write it to the http response. \r\n\r\n```javascript\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection );\r\n}\r\n```\r\n\r\n<a name=\"reflect_specific_types\" />\r\n### reflect specific types\r\n\r\nIn typical scenarios, developers will want to leverage reflection meta data to generate\r\nservice contacts and client side models. the reflection api lets you access meta data \r\nfor the following types declared in your project. \r\n\r\n* modules\r\n* imports\r\n* classes\r\n* interfaces\r\n* functions\r\n* variables\r\n\r\nto access specific type metadata, use the reflection.get([qualifier]) method, as demonstrated below.\r\n\r\n```javascript\r\nexport module model {\r\n    \r\n    export class Customer {\r\n\r\n        public firstname   : string;\r\n\r\n        public lastname    : string;\r\n\r\n        public age         : number;\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('model.Customer') );\r\n}\r\n```\r\nand methods..\r\n\r\n```javascript\r\nfunction some_method(a:string, b:number, c?:boolean) : void { }\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_method') );\r\n}\r\n```\r\n\r\n....and variables...\r\n\r\n```javascript\r\nvar some_variable:number = 10;\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_variable') );\r\n}\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\nThis section outlines development with appex.\r\n\r\n<a name=\"appex_declaration\" />\r\n### appex.d.ts declaration\r\n\r\nIf you develop on a TypeScript complicant editor (one that supports TS 0.9), appex comes bundled\r\nwith a declaration file you can reference in your project. If installing appex via npm, your\r\nreference should be as follows.\r\n\r\n```javascript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nexport function index (context:appex.web.IContext) { \r\n    \r\n    context.response.send('hello');\r\n}\r\n\r\nexport function wildcard(context:appex.web.IContext, path:string) {\r\n\r\n    context.response.serve('./', path);\r\n}\r\n```\r\n\r\nBy referencing this in your project, you get the benefits of code completion and static type checking\r\nagainst both appex, and the nodejs core.\r\n\r\n![](https://raw.github.com/sinclairzx81/appex/master/artifacts/code-completion.jpg)\r\n\r\nAdditional declaration files may be obtained from [here](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex ({ program : './index.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"users.ts\" />\r\n/// <reference path=\"pages.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { context.response.send('users.login') }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { context.response.send('users.logout') }\r\n}\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { context.response.send('home') }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { context.response.send('about') }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { context.response.send('contact') }\r\n\r\nexport function wildcard (context, path) { context.response.send(404, ' not found') }\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"license\" />\r\n## license\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) 2013 Haydn Paterson (sinclair) <haydn.developer@gmail.com>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in\r\nall copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\nTHE SOFTWARE.\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"https://raw.github.com/sinclairzx81/appex/master/license.txt","type":"The MIT License (MIT)"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"nodejs web api with typescript","directories":{},"dependencies":{"typescript.api":"0.6.0"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.5.4":{"name":"appex","version":"0.5.4","keywords":["typescript","web api","reflection","compiler","schema"],"author":{"name":"sinclair"},"_id":"appex@0.5.4","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"ff0e779333c610328aa49250e37db3c995d75259","tarball":"https://registry.npmjs.org/appex/-/appex-0.5.4.tgz","integrity":"sha512-ogJiU6w48mJldz1Q3I0oKB9Nlfe3jQFb+2qnuZ8U74lYu99muAmBiKKjZp23wiXKacUG55Ix/2Yzr0QXPOVb1w==","signatures":[{"sig":"MEQCIDqmetjSX8a2fpDrFCmrC71PLAFnOR5NooeqajvaEkpNAiAiWYpaqIRuyFc6Le6TVSrDU/QyNY1/OzzrkaCH+le/Og==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/artifacts/logo.jpg)\r\n\r\n### nodejs web api with [typescript](http://www.typescriptlang.org/)\r\n\r\n## overview\r\n\r\nappex is a nodejs web application framework built around the TypeScript programming language and\r\ncompiler. appex lets developers create and route http endpoints with TypeScript modules and \r\nfunctions, as well as providing nodejs developers similar reflection and type introspection \r\nservices found in platforms such as .net.\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http://localhost:3000/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// http://localhost:3000/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about');\r\n}\r\n\r\n// http://localhost:3000/(.*)\r\nexport function wildcard (context, path) {\r\n    \r\n    context.response.send(404, path + \" not found\");\r\n}\r\n\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n### contents\r\n\r\n* [getting started](#getting_started)\r\n\t* [create a application](#application)\r\n\t* [start up options](#options)\r\n\t* [running on an existing http server](#http_server)\r\n\t* [running as express middleware](#express_middleware)\r\n* [creating services with typescript](#creating_services)\r\n\t* [app context](#app_context)\r\n\t* [routing handlers](#routing_handlers)\r\n\t* [handler signatures](#handler_signatures)\r\n\t* [named handlers](#named_handlers)\r\n\t* [index handlers](#index_handlers)\r\n\t* [wildcard handlers](#wildcard_handlers)\r\n\t* [cascades](#cascades)\r\n\t* [http verbs](#http_verbs)\r\n\t* [middleware](#middleware)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [handling 404](#handling_404)\r\n\t* [serving static files](#serving_static_files)\r\n* [templating](#templating)\r\n\t* [overview](#template_overview)\r\n\t* [context](#template_context)\t\r\n\t* [syntax](#template_syntax)\r\n\t* [layouts and sections](#template_layouts_and_sections)\r\n\t* [render](#template_render)\r\n\t* [caching and devmode](#caching_and_devmode)\r\n* [json schema](#json_schema)\r\n\t* [generating schema](#generating_schema)\r\n\t* [validating json](#validating_json)\r\n* [reflection](#reflection)\r\n\t* [reflect everything](#reflect_everything)\r\n\t* [reflect specific types](#reflect_specific_types)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [appex.d.ts declaration](#appex_declaration)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n* [license](#license)\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline creating appex applications and configuration.\r\n\r\n<a name=\"application\" />\r\n### create a application\r\n\r\nThe following code will create a standalone appex application and \r\nhttp server and listen on port 3000.\r\n\r\n```javascript\r\nvar appex   = require('appex');\r\n\r\nvar app   = appex({ program : './program.ts', \r\n                    devmode : true,\r\n                    logging : true });\r\n\r\napp.listen(3000);\r\n```\r\n\r\nnote: devmode and logging are optional. however, when developing \r\nwith appex, it is helpful to have these enabled.\r\n\r\n<a name=\"options\" />\r\n### start up options\r\n\r\nappex accepts the following start up options.\r\n\r\n```javascript\r\nvar options = {\r\n\r\n\t// (required) location of source file.\r\n\tprogram    : './program.ts', \r\n\r\n\t// (optional) recompile on request. (default:false) \r\n\tdevmode    : true,          \r\n\r\n\t// (optional) log to stdout. (default:false) \r\n\tlogging    : true,\r\n\r\n\t// (optional) user defined objects added to the app context.\r\n\tcontext    : {}\r\n};\r\n\r\nvar app = appex( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### running on an existing http server\r\n\r\nThe following demonstrates setting up appex on an existing nodejs http server. In \r\nthis example, appex will attempt to handle incoming requests, and if appex cannot\r\nroute the request, will fire the callback.\r\n\r\n```javascript\r\nvar http  = require('http');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\nvar server = http.createServer(function(req, res){\r\n\r\n    app(req, res, function() { // appex handler...\r\n\t\t\r\n\t\t// not handled.\r\n\r\n\t}); \r\n});\r\n\r\nserver.listen(3000);\r\n```\r\n\r\n\r\n<a name=\"express_middleware\" />\r\n### running as express middleware\r\n\r\nappex allows developers to augment existing express / connect applications by \r\nway of middleware. The following demonstrates setting up appex as express middleware.\r\n\r\n```javascript\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) ); \r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nLike in the \"running on an existing http server\" example above, appex will attempt to intercept incoming requests. \r\nif appex cannot find a matching route for the request, it will automatically call the \"next\" function to pass the request \r\non to the next middleware or express handler.\r\n\r\nin addition to this, appex may also act as traditional express middleware. In the example below, a appex wildcard\r\nfunction is created which will match \"all\" incoming requests, the wildcard function simply prints hello world to \r\nthe console and then calls context.next(), which passes the request on the express handler.\r\n\r\n```javascript\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tconsole.log('hello world!!');\r\n\r\n\tcontext.next(); // pass it on!\r\n}\r\n\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) );\r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nJust like traditional express middleware, appex will also inheriate the characteristics of the request.\r\n\r\nconsider the following example in which the jade view engine is configured for use. appex will inheritate the \r\nresponse.render() method, which is passed to the appex handler as context.response.render()\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\napp.configure(function(){\r\n\r\n  app.set('views', __dirname + '/views');\r\n  \r\n  // set up the jade engine.\r\n  app.set('view engine', 'jade'); \r\n  \r\n  // bind appex\r\n  app.use( appex({program:'./program.ts', devmode:true} ));  \r\n});\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/\r\nexport function index(context) {\r\n\t\r\n\t// jade renderer works!\r\n\tcontext.response.render('index', { title: 'Express' }); \r\n}\r\n```\r\n\r\n<a name=\"creating_services\" />\r\n## creating services with typescript\r\n\r\nThe following section describes how to write http accessible functions with appex.\r\n\r\n<a name=\"app_context\" />\r\n### app context\r\n\r\nAll appex functions are passed a application context object as their first argument. The app context object \r\nencapulates the http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the app context\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.cascade    - appex cascade.\r\n\r\n\t// context.next       - the next function (express middleware)\r\n\t\r\n\t// context.router     - the appex router\r\n\r\n\t// context.template   - the appex template engine.\r\n\t\r\n\t// context.module     - the module being run (this module)\r\n\r\n\t// context.schema     - json schema api.\r\n\r\n\t// context.mime       - a http mime type utility.\r\n}\r\n```\r\n\r\nit is possible to extend the default objects passed on the context by adding them on the appex startup options. The \r\nfollowing will attach the async module to the context. \r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = appex({ program : './program.ts', \r\n\t\t\t\t  devmode : true, \r\n\t\t\t      context: {\r\n\t\t\t\t\t\tasync : require('async')\r\n\t\t\t\t  }});\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\r\n\t// context.async = passed on the context.\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n```\r\n<a name=\"routing_handlers\" />\r\n### routing handlers\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context) { /* handle route */ }\r\n}\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/(.*)\r\nexport function wildcard (context, path) { /* handle route */ }\r\n\r\n```\r\n\r\n<a name=\"handler_signatures\" />\r\n### handler signatures\r\n\r\nappex supports three function signatures for http routing (named, index and wildcard). Functions that\r\ndo not apply these signatures will not be routed.\r\n\r\n<a name=\"named_handlers\" />\r\n### named handlers\r\n\r\nNamed handlers resolve urls to their current module scope + the name of the function.\r\n\r\nNamed handlers require the following signature:\r\n\r\n* name        - 'anything'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n\r\n// http://[host]:[port]/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about page');\r\n}\r\n\r\n// http://[host]:[port]/users/login\r\nexport module users {\r\n\r\n\texport function login(context) {\r\n\t\t\r\n\t\tcontext.response.send('handle login');\t\r\n\t}\r\n}\r\n\r\n```\r\n\r\n<a name=\"index_handlers\" />\r\n### index handlers\r\n\r\nIndex handlers resolve urls to their current module scope.\r\n\r\nIndex handlers require the following signature:\r\n\r\n* name        - 'index'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) \r\n\t{\t\r\n\t\tcontext.response.send('blog index');\r\n\t}\r\n}\r\n```\r\n\r\n<a name=\"wildcard_handlers\" />\r\n### wildcard handlers\r\n\r\nWildcard handlers resolve their urls to their current module scope + url.\r\n\r\nappex wildcard handlers allow for wildcard routing at a given module scope. Wildcard handlers\r\nsupport 'typed' url argument mapping, as denoted by the arguments annotation.\r\n\r\nIn addition, wildcard handlers also support optional arguments which can be specified with TypeScript's '?' \r\non argument names.\r\n\r\nappex wildcard handlers require the following signature:\r\n\r\n* name        - 'wildcard'\r\n* argument[0] - app context\r\n* argument[n] - 1 or more arguments to be mapped from the url\r\n* returns     - void (optional)\r\n\r\n```javascript\r\ndeclare var console;\r\n\r\nexport module blogs {\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11   - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/11  - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/3rd - not matched - (see number annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01     - matched     - (see ? annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013        - not matched - (month is required)\r\n\t\r\n    export function wildcard(context, year:number, month:number, day?:number) {\r\n\r\n        context.response.json({ year: year, month: month, day: day})\r\n    }\r\n}\r\n\r\n// url : http://[host]:[port]/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// url : http://[host]:[port]/(.*) \r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, 'not found');\r\n}\r\n\r\n```\r\nnote: appex supports boolean, number, string and any annotations on wildcard arguments. if no annotation\r\nis specified, appex interprets the argument as a string. the type 'any' is also interpreted as string.\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"cascades\" />\r\n### cascades\r\n\r\nappex supports a cascading attribute scheme on modules and functions. With this, developers can apply\r\narbituary meta data for modules and functions that will propagate through scope. appex has two special\r\ncascade properties for middleware and http verb matching, which are described below, however consider\r\nthe following code which illustrates the concept.\r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ncascade({a: 10}); // global.\r\n\r\ncascade('foo', {b : 20})\r\nexport module foo {\r\n\r\n    cascade('foo.bar', {c : 30})\r\n    export module bar {\r\n            \r\n        cascade('foo.bar.index', {d : 40})\r\n        export function index(context) {\r\n        \r\n            //context.cascade\r\n            //{\r\n            //    \"a\": 10,\r\n            //    \"b\": 20,\r\n            //    \"c\": 30,\r\n\t\t\t//    \"d\": 40\r\n            //}\r\n\r\n            context.response.json( context.cascade );       \r\n        }\r\n    }\r\n}\r\n\r\n```\r\n\r\n<a name=\"http_verbs\" />\r\n### http verbs\r\n\r\nappex handles http verb matching with cascades. appex will recognise the \r\n'verbs' property applied to the cascade to match against http verbs.\r\n\r\n```javascript\r\ncascade('index', { verbs: ['get'] })\r\nexport function index (context) { \r\n        \r\n    // only allow HTTP GET requests\r\n    context.response.send('index')\r\n}\r\n\r\ncascade('index', { verbs: ['post', 'put'] })\r\nexport function submit (context) { \r\n    \r\n    // only allow HTTP POST and PUT requests\r\n    context.response.send('submit')\r\n}\r\n```\r\n\r\n\r\n<a name=\"middleware\" />\r\n### middleware\r\n\r\nappex supports middleware with cascades. appex middleware defined with cascades allows\r\ndevelopers to scope middleware on single functions, or entire module scopes. appex will \r\nrecognise the 'use' property applied to the cascade to invoke middleware.\r\n\r\nthe following demonstrates how one might use middleware to secure a site admin.\r\n\r\nnote: middleware 'must' call next or handle the request. \r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ndeclare var console;\r\n\r\nfunction authenticate(context) {\r\n\r\n    console.log('authenticate')\r\n\r\n\t// call next() if authenticated, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\nfunction authorize(context) {\r\n\r\n    console.log('authorize')\r\n\r\n\t// call next() if authorized, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\n// apply security middleware to admin scope.\r\ncascade('admin', {use: [authenticate, authorize]}) \r\nexport module admin {\r\n\r\n    export function index(context) {\r\n        \r\n        console.log(context.cascade); // view cascade\r\n\r\n        context.response.send('access granted!')\r\n    }\r\n}\r\n\r\n// index handler has no middleware applied.\r\nexport function index (context) { \r\n    \r\n    console.log(context.cascade); // view cascade\r\n\r\n    context.response.send('home')\r\n}\r\n```\r\n\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex will only route functions prefixed with the TypeScript 'export' declarer. This rule\r\nalso applied to modules. Developers can use this to infer notions of public and private \r\nat the http level.\r\n\r\nconsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.send('public_function');\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```javascript\r\n// http:[host]:[port]/\r\nexport function index (context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard (context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n<a name=\"serving_static_files\" />\r\n## serving static files\r\n\r\nUse wildcard functions with context.response.serve() to serve static content.\r\n\r\n```javascript\r\nexport module static {\r\n\t\r\n\t// http:[host]:[port]/static/(.*)\r\n\texport function wildcard(context, path) {\r\n\r\n\t\tcontext.response.serve('./static/', path);\r\n\t}\r\n}\r\n\r\n// http:[host]:[port]/\r\nexport function index (context) {\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n\r\n<a name=\"templating\" />\r\n## templating\r\n\r\nappex comes bundled with a built in template engine which is modelled on the Microsoft \r\nRazor templating engine. The following sections outline its use.\r\n\r\n<a name=\"template_overview\" />\r\n### overview\r\n\r\nThe appex template engine is available to all handlers by default. it is accessible\r\non the context.template property. the following is an example of its use.\r\n\r\n```\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n<ul>\r\n@for(var n in context.users) {\r\n\r\n\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t<li>@(context.users[n].name)</li>\r\n\t}\r\n}\r\n</ul>\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\t\r\n\tcontext.response.headers['Content-Type'] = 'text/html';\r\n\r\n    context.response.send(text);\r\n}\r\n\r\n```\r\n\r\n<a name=\"template_context\" />\r\n### context\r\n\r\neach template is passed a data context. this context allows the caller to \r\nsend data to the template for rendering. the context parameter is optional.\r\nthe example below is sending the users array to the template context for \r\nrendering.\r\n\r\n```\r\nexport function index(context) {\r\n\t\r\n    var users  = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    context.response.send(context.template.render('./view.txt', { users: users }));\r\n}\r\n```\r\n\r\n<a name=\"template_syntax\" />\r\n### syntax\r\n\r\nappex templates support the following statements and syntax\r\n\r\n#### if statement\r\n\r\nif statments are supported.\r\n\r\n```\r\n@if(expression) {\r\n\tsome content\r\n}\r\n\r\n@if(a > 10) {\r\n\tsome content\r\n}\r\n\r\n@(user.loggedin) {\r\n\t<span>welcome</span>\r\n}\r\n```\r\n\r\n#### for statement\r\n\r\nthe following for loops are supported.\r\n\r\n```\r\n@for(var i = i; i < 100; i++) {\r\n\t@(i)\r\n}\r\n\r\n@for(var n in list) {\r\n\t@(list[n])\r\n}\r\n```\r\n\r\n#### expressions\r\n\r\nwill emit the value contained.\r\n\r\n```\r\n@('hello world')\r\n\r\n@(123)\r\n\r\n@(some_variable)\r\n```\r\n\r\n#### code blocks\r\n\r\ncode blocks can be useful for adding template side rendering logic.\r\n\r\n```\r\n@{\r\n\tvar message = 'hello'\r\n}\r\n\r\n@(message)\r\n```\r\n\r\n#### comments\r\n```\r\n@*\r\n\tthis comment will not be rendered!\r\n*@\r\n```\r\n\r\n<a name=\"template_layouts_and_sections\" />\r\n### layouts and sections\r\n\r\nappex templates support template inheritance.\r\n\r\nconsider the following where layout.txt defines the sections 'header' and 'content' and the view.txt overrides\r\nthese sections with its own content.\r\n\r\n```\r\n//----------------------------------------------\r\n// layout.txt\r\n//----------------------------------------------\r\n\r\n<html>\r\n\r\n\t<head>\r\n\t\t\r\n\t\t@section header\r\n\r\n\t</head>\r\n\r\n\t<body>\r\n\r\n\t\t@section content {\r\n\t\t\r\n\t\t\t<span>some default content</span>\r\n\t\t\t\r\n\t\t}\r\n\r\n\t</body>\r\n\t\r\n</html>\r\n\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n@layout 'layout.txt'\r\n\r\n@section header {\r\n\r\n\t<title>my page</title>\r\n}\r\n\r\n@section content {\r\n\r\n\t<p>overriding the layout.txt content section.</p>\r\n\r\n\t<ul>\r\n\t@for(var n in context.users) {\r\n\r\n\t\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t\t<li>@(context.users[n].name)</li>\r\n\t\t}\r\n\t}\r\n\t</ul>\r\n}\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\r\n    context.response.send(text);\r\n}\r\n```\r\n\r\nnote : when specifying a layout, the view will only render content within\r\nthe layouts section placeholders. \r\n\r\n<a name=\"render\" />\r\n### render\r\n\r\nappex templates also allow for partial views with the @render statment. consider the following \r\nwhich renders the nav.txt file into the layout.txt file.\r\n\r\n```\r\n//----------------------------------------------\r\n// nav.txt\r\n//----------------------------------------------\r\n<ul>\r\n\t<li>home</li>\r\n\t<li>about</li>\r\n\t<li>contact</li>\r\n</ul>\r\n\r\n//----------------------------------------------\r\n// layout.txt\r\n//----------------------------------------------\r\n\r\n<html>\r\n\t<head>\r\n\t\t\r\n\t\t@section header\r\n\r\n\t</head>\r\n\r\n\t<body>\r\n\t\t\r\n\t\t@render 'nav.txt'\r\n\r\n\t\t@section content {\r\n\t\t\r\n\t\t\t<span>some default content</span>\r\n\t\t\t\r\n\t\t}\r\n\r\n\t</body>\r\n\t\r\n</html>\r\n\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n@layout 'layout.txt'\r\n\r\n@section header {\r\n\r\n\t<title>my page</title>\r\n}\r\n\r\n@section content {\r\n\r\n\t<p>overriding the layout.txt content section.</p>\r\n\r\n\t<ul>\r\n\t@for(var n in context.users) {\r\n\r\n\t\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t\t<li>@(context.users[n].name)</li>\r\n\t\t}\r\n\t}\r\n\t</ul>\r\n}\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\r\n    context.response.send(text);\r\n}\r\n```\r\n\r\n<a name=\"caching_and_devmode\" />\r\n### caching and devmode\r\n\r\nappex template content is not cached (the implementor is expected to handle their own caching)\r\nhowever the generated template code is. \r\n\r\nappex templates do inheriate the behaviour of the appex 'devmode' option. setting\r\ndevmode to 'true' will cause template code to be reloaded from disk and code generated with each \r\nrequest. setting devmode to false will load content from disk on first request, and \r\ncache the generated template code in memory for the lifetime of the application.\r\n\r\nin addition to this, a implementation where the devmode is false can override the caching \r\nbehaviour with the following.\r\n\r\n```javascript\r\nexport function index(context) {\r\n\r\n\t// manually override the template devmode option.\r\n\tcontext.template.option.devmode = true; \r\n\r\n\tcontext.response.send(context.template.render('./view.txt'))\r\n}\r\n```\r\n\r\n<a name=\"json_schema\" />\r\n## json schema\r\n\r\nappex provides functionality for generating json schemas from TypeScript classes\r\nand interfaces as well as tools for validating json data.\r\n\r\n<a name=\"generating_schema\" />\r\n### generating schema\r\n\r\nThe following demonstrates generating json schema from the following class\r\nhierarchy.\r\n\r\n```javascript\r\nexport module model {\r\n\r\n    /** a product */\r\n    export class Product {\r\n        \r\n        /** the product name */\r\n        public name        : string;\r\n\r\n        /** the product description */\r\n        public description : string;\r\n\r\n        /** the product cost */\r\n        public cost        : number;\r\n    } \r\n\r\n    /** a order */\r\n    export class Order {\r\n        \r\n        /** the product being ordered */\r\n        public products  : Product;\r\n    }\r\n\r\n    /** a customer */\r\n    export class Customer {\r\n\r\n        /** the customers firstname */\r\n        public firstname  : string;\r\n\r\n        /** the customers lastname */\r\n        public lastname   : string;\r\n\r\n        /** orders made by this customer */\r\n        public orders     : Order[];\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.IContext) {\r\n\t\r\n\t// pass the fully qualified name of the type.\r\n    var schema = context.schema.generate('model.Customer');\r\n\r\n    context.response.json(schema);\r\n}\r\n```\r\n\r\nwhich generates the following json schema.\r\n\r\n```javascript\r\n{\r\n    \"id\": \"model.Customer\",\r\n    \"type\": \"object\",\r\n    \"description\": \"a customer\",\r\n    \"properties\": {\r\n        \"firstname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers firstname\",\r\n            \"required\": true\r\n        },\r\n        \"lastname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers lastname\",\r\n            \"required\": true\r\n        },\r\n        \"orders\": {\r\n            \"type\": \"array\",\r\n            \"items\": {\r\n                \"type\": {\r\n                    \"id\": \"model.Order\",\r\n                    \"type\": \"object\",\r\n                    \"description\": \"a order\",\r\n                    \"properties\": {\r\n                        \"products\": {\r\n                            \"id\": \"model.Product\",\r\n                            \"type\": \"object\",\r\n                            \"description\": \"a product\",\r\n                            \"properties\": {\r\n                                \"name\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product name\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"description\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product description\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"cost\": {\r\n                                    \"type\": \"number\",\r\n                                    \"description\": \"the product cost\",\r\n                                    \"required\": true\r\n                                }\r\n                            },\r\n                            \"required\": true\r\n                        }\r\n                    }\r\n                }\r\n            },\r\n            \"description\": \"orders made by this customer\",\r\n            \"required\": true\r\n        }\r\n    }\r\n}\r\n```\r\na quick note...\r\n\r\nwhen generating schema from classes:\r\n\r\n* only public class variables will be emitted.\r\n* all properties will be marked as \"required\".\r\n\r\nwhen generating schema from interfaces:\r\n\r\n* all properties will be emitted. \r\n* all properties will be marked as \"required\" unless modified with '?'.\r\n\r\n<a name=\"validating_schema\" />\r\n### validating json\r\n\r\nappex supports json schema validation from class and interface definitions. consider the following...\r\n\r\n```javascript\r\ninterface Customer {\r\n\r\n    firstname    : string;\r\n\r\n    lastname     : string;\r\n\r\n    age          : number;\r\n\r\n    emails       : string[];\r\n\r\n    option_a ?   : boolean; // optional\r\n\r\n    option_b ?   : boolean; // optional\r\n\r\n}\r\n\r\nexport function index(context) {\r\n\r\n    // a customer with invalid data.\r\n\r\n    var customer = {\r\n\r\n        firstname    : 'dave',\r\n\r\n        age          : '33',\r\n\r\n        emails       : [12345, 'dave@domain.com', true],\r\n\r\n        option_b     : 1,\r\n\r\n        option_c     : 1\r\n    }\r\n\r\n    // do validation.\r\n\r\n    var errors = context.schema.validate('Customer', customer);\r\n\r\n    if(errors) {\r\n\r\n        context.response.json(errors);\r\n    }\r\n}\r\n```\r\n\r\nwill output the following.\r\n\r\n```javascript\r\n[\r\n    {\r\n        \"message\": \"instance.lastname is required.\"\r\n    },\r\n    {\r\n        \"message\": \"instance.age is not a number\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[0] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[2] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_b is not a boolean\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_c unexpected property\"\r\n    }\r\n]\r\n```\r\n\r\n<a name=\"reflection\" />\r\n## reflection\r\n\r\nappex provides a reflection api derived from TypeScript's type system that developers can \r\nleverage to reflect type information declared throughout their appex modules. \r\n\r\nthe following section outlines how to use the reflection api.\r\n\r\n<a name=\"reflect_everything\" />\r\n### reflect everything\r\n\r\nthe appex reflection api is passed on the context.module.reflection property and is available to all\r\nappex handler methods. The following code will JSON serialize everything declared in your appex\r\nproject and write it to the http response. \r\n\r\n```javascript\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection );\r\n}\r\n```\r\n\r\n<a name=\"reflect_specific_types\" />\r\n### reflect specific types\r\n\r\nIn typical scenarios, developers will want to leverage reflection meta data to generate\r\nservice contacts and client side models. the reflection api lets you access meta data \r\nfor the following types declared in your project. \r\n\r\n* modules\r\n* imports\r\n* classes\r\n* interfaces\r\n* functions\r\n* variables\r\n\r\nto access specific type metadata, use the reflection.get([qualifier]) method, as demonstrated below.\r\n\r\n```javascript\r\nexport module model {\r\n    \r\n    export class Customer {\r\n\r\n        public firstname   : string;\r\n\r\n        public lastname    : string;\r\n\r\n        public age         : number;\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('model.Customer') );\r\n}\r\n```\r\nand methods..\r\n\r\n```javascript\r\nfunction some_method(a:string, b:number, c?:boolean) : void { }\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_method') );\r\n}\r\n```\r\n\r\n....and variables...\r\n\r\n```javascript\r\nvar some_variable:number = 10;\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_variable') );\r\n}\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\nThis section outlines development with appex.\r\n\r\n<a name=\"appex_declaration\" />\r\n### appex.d.ts declaration\r\n\r\nIf you develop on a TypeScript complicant editor (one that supports TS 0.9), appex comes bundled\r\nwith a declaration file you can reference in your project. If installing appex via npm, your\r\nreference should be as follows.\r\n\r\n```javascript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nexport function index (context:appex.web.IContext) { \r\n    \r\n    context.response.send('hello');\r\n}\r\n\r\nexport function wildcard(context:appex.web.IContext, path:string) {\r\n\r\n    context.response.serve('./', path);\r\n}\r\n```\r\n\r\nBy referencing this in your project, you get the benefits of code completion and static type checking\r\nagainst both appex, and the nodejs core.\r\n\r\n![](https://raw.github.com/sinclairzx81/appex/master/artifacts/code-completion.jpg)\r\n\r\nAdditional declaration files may be obtained from [here](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex ({ program : './index.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"users.ts\" />\r\n/// <reference path=\"pages.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { context.response.send('users.login') }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { context.response.send('users.logout') }\r\n}\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { context.response.send('home') }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { context.response.send('about') }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { context.response.send('contact') }\r\n\r\nexport function wildcard (context, path) { context.response.send(404, ' not found') }\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"license\" />\r\n## license\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) 2013 Haydn Paterson (sinclair) <haydn.developer@gmail.com>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in\r\nall copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\nTHE SOFTWARE.\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"https://raw.github.com/sinclairzx81/appex/master/license.txt","type":"The MIT License (MIT)"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"nodejs web api with typescript","directories":{},"dependencies":{"typescript.api":"0.6.1"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.5.5":{"name":"appex","version":"0.5.5","keywords":["typescript","web api","reflection","compiler","schema"],"author":{"name":"sinclair"},"_id":"appex@0.5.5","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"04646ad9d378158f1e3d71e7bd66ed4d692ec60a","tarball":"https://registry.npmjs.org/appex/-/appex-0.5.5.tgz","integrity":"sha512-8bgynqn60V9bWg//1bFd9GSwpC5G4atESRxzYFqZbeQQ8ePb+h+p5t0XO2ZZ8AK5U0DFWRtBRWE8yS94wSS02g==","signatures":[{"sig":"MEUCICg9yEW3TyeX2C9GpWWu/gR0ZfPmZYEc4zkmZiKts011AiEA6Eapxd0/8sZxPQdvsdqB116mSDrSzv0xgfC4uDRQ4tk=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/artifacts/logo.jpg)\r\n\r\n### nodejs web api with [typescript](http://www.typescriptlang.org/)\r\n\r\n## overview\r\n\r\nappex is a nodejs web application framework built around the TypeScript programming language and\r\ncompiler. appex lets developers create and route http endpoints with TypeScript modules and \r\nfunctions, as well as providing nodejs developers similar reflection and type introspection \r\nservices found in platforms such as .net.\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http://localhost:3000/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// http://localhost:3000/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about');\r\n}\r\n\r\n// http://localhost:3000/(.*)\r\nexport function wildcard (context, path) {\r\n    \r\n    context.response.send(404, path + \" not found\");\r\n}\r\n\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n### contents\r\n\r\n* [getting started](#getting_started)\r\n\t* [create a application](#application)\r\n\t* [start up options](#options)\r\n\t* [running on an existing http server](#http_server)\r\n\t* [running as express middleware](#express_middleware)\r\n* [http handlers](#http_handlers)\r\n\t* [app context](#app_context)\r\n\t* [routing handlers](#routing_handlers)\r\n\t* [handler signatures](#handler_signatures)\r\n\t* [named handlers](#named_handlers)\r\n\t* [index handlers](#index_handlers)\r\n\t* [wildcard handlers](#wildcard_handlers)\r\n\t* [cascades](#cascades)\r\n\t* [http verbs](#http_verbs)\r\n\t* [middleware](#middleware)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [handling 404](#handling_404)\r\n\t* [serving static files](#serving_static_files)\r\n* [templating](#templating)\r\n\t* [overview](#template_overview)\r\n\t* [context](#template_context)\t\r\n\t* [syntax](#template_syntax)\r\n\t* [layouts and sections](#template_layouts_and_sections)\r\n\t* [render](#template_render)\r\n\t* [caching and devmode](#caching_and_devmode)\r\n* [sitemaps](#sitemaps)\r\n\t* [generating](#sitemap_generate)\r\n\t* [metadata](#sitemap_metadata)\r\n* [json schema](#json_schema)\r\n\t* [generating schema](#generating_schema)\r\n\t* [validating json](#validating_json)\r\n* [reflection](#reflection)\r\n\t* [reflect everything](#reflect_everything)\r\n\t* [reflect specific types](#reflect_specific_types)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [appex.d.ts declaration](#appex_declaration)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n* [license](#license)\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline creating appex applications and configuration.\r\n\r\n<a name=\"application\" />\r\n### create a application\r\n\r\nThe following code will create a standalone appex application and \r\nhttp server and listen on port 3000.\r\n\r\n```javascript\r\nvar appex   = require('appex');\r\n\r\nvar app   = appex({ program : './program.ts', \r\n                    devmode : true,\r\n                    logging : true });\r\n\r\napp.listen(3000);\r\n```\r\n\r\nnote: devmode and logging are optional. however, when developing \r\nwith appex, it is helpful to have these enabled.\r\n\r\n<a name=\"options\" />\r\n### start up options\r\n\r\nappex accepts the following start up options.\r\n\r\n```javascript\r\nvar options = {\r\n\r\n\t// (required) location of source file.\r\n\tprogram    : './program.ts', \r\n\r\n\t// (optional) recompile on request. (default:false) \r\n\tdevmode    : true,          \r\n\r\n\t// (optional) log to stdout. (default:false) \r\n\tlogging    : true,\r\n\r\n\t// (optional) user defined objects added to the app context.\r\n\tcontext    : {}\r\n};\r\n\r\nvar app = appex( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### running on an existing http server\r\n\r\nThe following demonstrates setting up appex on an existing nodejs http server. In \r\nthis example, appex will attempt to handle incoming requests, and if appex cannot\r\nroute the request, will fire the callback.\r\n\r\n```javascript\r\nvar http  = require('http');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\nvar server = http.createServer(function(req, res){\r\n\r\n    app(req, res, function() { // appex handler...\r\n\t\t\r\n\t\t// not handled.\r\n\r\n\t}); \r\n});\r\n\r\nserver.listen(3000);\r\n```\r\n\r\n\r\n<a name=\"express_middleware\" />\r\n### running as express middleware\r\n\r\nappex allows developers to augment existing express / connect applications by \r\nway of middleware. The following demonstrates setting up appex as express middleware.\r\n\r\n```javascript\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) ); \r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nLike in the \"running on an existing http server\" example above, appex will attempt to intercept incoming requests. \r\nif appex cannot find a matching route for the request, it will automatically call the \"next\" function to pass the request \r\non to the next middleware or express handler.\r\n\r\nin addition to this, appex may also act as traditional express middleware. In the example below, a appex wildcard\r\nfunction is created which will match \"all\" incoming requests, the wildcard function simply prints hello world to \r\nthe console and then calls context.next(), which passes the request on the express handler.\r\n\r\n```javascript\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tconsole.log('hello world!!');\r\n\r\n\tcontext.next(); // pass it on!\r\n}\r\n\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) );\r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nJust like traditional express middleware, appex will also inheriate the characteristics of the request.\r\n\r\nconsider the following example in which the jade view engine is configured for use. appex will inheritate the \r\nresponse.render() method, which is passed to the appex handler as context.response.render()\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\napp.configure(function(){\r\n\r\n  app.set('views', __dirname + '/views');\r\n  \r\n  // set up the jade engine.\r\n  app.set('view engine', 'jade'); \r\n  \r\n  // bind appex\r\n  app.use( appex({program:'./program.ts', devmode:true} ));  \r\n});\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/\r\nexport function index(context) {\r\n\t\r\n\t// jade renderer works!\r\n\tcontext.response.render('index', { title: 'Express' }); \r\n}\r\n```\r\n\r\n<a name=\"http_handlers\" />\r\n## http handlers\r\n\r\nThe following sections describe how to create http accessible handlers with appex.\r\n\r\n<a name=\"app_context\" />\r\n### app context\r\n\r\nAll appex functions are passed a application context object as their first argument. The app context object \r\nencapulates the http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the app context\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.cascade    - appex cascade.\r\n\r\n\t// context.next       - the next function (express middleware)\r\n\t\r\n\t// context.router     - the appex router\r\n\r\n\t// context.sitemap    - the appex sitemap api\r\n\r\n\t// context.template   - the appex template engine.\r\n\t\r\n\t// context.module     - the module being run (this module)\r\n\r\n\t// context.schema     - json schema api.\r\n\r\n\t// context.mime       - a http mime type utility.\r\n}\r\n```\r\n\r\nit is possible to extend the default objects passed on the context by adding them on the appex startup options. The \r\nfollowing will attach the async module to the context. \r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = appex({ program : './program.ts', \r\n\t\t\t\t  devmode : true, \r\n\t\t\t      context: {\r\n\t\t\t\t\t\tasync : require('async')\r\n\t\t\t\t  }});\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\r\n\t// context.async = passed on the context.\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n```\r\n<a name=\"routing_handlers\" />\r\n### routing handlers\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context) { /* handle route */ }\r\n}\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/(.*)\r\nexport function wildcard (context, path) { /* handle route */ }\r\n\r\n```\r\n\r\n<a name=\"handler_signatures\" />\r\n### handler signatures\r\n\r\nappex supports three function signatures for http routing (named, index and wildcard). Functions that\r\ndo not apply these signatures will not be routed.\r\n\r\n<a name=\"named_handlers\" />\r\n### named handlers\r\n\r\nNamed handlers resolve urls to their current module scope + the name of the function.\r\n\r\nNamed handlers require the following signature:\r\n\r\n* name        - 'anything'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n\r\n// http://[host]:[port]/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about page');\r\n}\r\n\r\n// http://[host]:[port]/users/login\r\nexport module users {\r\n\r\n\texport function login(context) {\r\n\t\t\r\n\t\tcontext.response.send('handle login');\t\r\n\t}\r\n}\r\n\r\n```\r\n\r\n<a name=\"index_handlers\" />\r\n### index handlers\r\n\r\nIndex handlers resolve urls to their current module scope.\r\n\r\nIndex handlers require the following signature:\r\n\r\n* name        - 'index'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) \r\n\t{\t\r\n\t\tcontext.response.send('blog index');\r\n\t}\r\n}\r\n```\r\n\r\n<a name=\"wildcard_handlers\" />\r\n### wildcard handlers\r\n\r\nWildcard handlers resolve their urls to their current module scope + url.\r\n\r\nappex wildcard handlers allow for wildcard routing at a given module scope. Wildcard handlers\r\nsupport 'typed' url argument mapping, as denoted by the arguments annotation.\r\n\r\nIn addition, wildcard handlers also support optional arguments which can be specified with TypeScript's '?' \r\non argument names.\r\n\r\nappex wildcard handlers require the following signature:\r\n\r\n* name        - 'wildcard'\r\n* argument[0] - app context\r\n* argument[n] - 1 or more arguments to be mapped from the url\r\n* returns     - void (optional)\r\n\r\n```javascript\r\ndeclare var console;\r\n\r\nexport module blogs {\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11   - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/11  - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/3rd - not matched - (see number annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01     - matched     - (see ? annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013        - not matched - (month is required)\r\n\t\r\n    export function wildcard(context, year:number, month:number, day?:number) {\r\n\r\n        context.response.json({ year: year, month: month, day: day})\r\n    }\r\n}\r\n\r\n// url : http://[host]:[port]/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// url : http://[host]:[port]/(.*) \r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, 'not found');\r\n}\r\n\r\n```\r\nnote: appex supports boolean, number, string and any annotations on wildcard arguments. if no annotation\r\nis specified, appex interprets the argument as a string. the type 'any' is also interpreted as string.\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"cascades\" />\r\n### cascades\r\n\r\nappex supports a cascading attribute scheme on modules and functions. With this, developers can apply\r\narbituary meta data for modules and functions that will propagate through scope. appex has two special\r\ncascade properties for middleware and http verb matching, which are described below, however consider\r\nthe following code which illustrates the concept.\r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ncascade({a: 10}); // global.\r\n\r\ncascade('foo', {b : 20})\r\nexport module foo {\r\n\r\n    cascade('foo.bar', {c : 30})\r\n    export module bar {\r\n            \r\n        cascade('foo.bar.index', {d : 40})\r\n        export function index(context) {\r\n        \r\n            //context.cascade\r\n            //{\r\n            //    \"a\": 10,\r\n            //    \"b\": 20,\r\n            //    \"c\": 30,\r\n\t\t\t//    \"d\": 40\r\n            //}\r\n\r\n            context.response.json( context.cascade );       \r\n        }\r\n    }\r\n}\r\n\r\n```\r\n\r\n<a name=\"http_verbs\" />\r\n### http verbs\r\n\r\nappex handles http verb matching with cascades. appex will recognise the \r\n'verbs' property applied to the cascade to match against http verbs.\r\n\r\n```javascript\r\ncascade('index', { verbs: ['get'] })\r\nexport function index (context) { \r\n        \r\n    // only allow HTTP GET requests\r\n    context.response.send('index')\r\n}\r\n\r\ncascade('index', { verbs: ['post', 'put'] })\r\nexport function submit (context) { \r\n    \r\n    // only allow HTTP POST and PUT requests\r\n    context.response.send('submit')\r\n}\r\n```\r\n\r\n\r\n<a name=\"middleware\" />\r\n### middleware\r\n\r\nappex supports middleware with cascades. appex middleware defined with cascades allows\r\ndevelopers to scope middleware on single functions, or entire module scopes. appex will \r\nrecognise the 'use' property applied to the cascade to invoke middleware.\r\n\r\nthe following demonstrates how one might use middleware to secure a site admin.\r\n\r\nnote: middleware 'must' call next or handle the request. \r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ndeclare var console;\r\n\r\nfunction authenticate(context) {\r\n\r\n    console.log('authenticate')\r\n\r\n\t// call next() if authenticated, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\nfunction authorize(context) {\r\n\r\n    console.log('authorize')\r\n\r\n\t// call next() if authorized, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\n// apply security middleware to admin scope.\r\ncascade('admin', {use: [authenticate, authorize]}) \r\nexport module admin {\r\n\r\n    export function index(context) {\r\n        \r\n        console.log(context.cascade); // view cascade\r\n\r\n        context.response.send('access granted!')\r\n    }\r\n}\r\n\r\n// index handler has no middleware applied.\r\nexport function index (context) { \r\n    \r\n    console.log(context.cascade); // view cascade\r\n\r\n    context.response.send('home')\r\n}\r\n```\r\n\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex will only route functions prefixed with the TypeScript 'export' declarer. This rule\r\nalso applied to modules. Developers can use this to infer notions of public and private \r\nat the http level.\r\n\r\nconsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.send('public_function');\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```javascript\r\n// http:[host]:[port]/\r\nexport function index (context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard (context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n<a name=\"serving_static_files\" />\r\n## serving static files\r\n\r\nUse wildcard functions with context.response.serve() to serve static content.\r\n\r\n```javascript\r\nexport module static {\r\n\t\r\n\t// http:[host]:[port]/static/(.*)\r\n\texport function wildcard(context, path) {\r\n\r\n\t\tcontext.response.serve('./static/', path);\r\n\t}\r\n}\r\n\r\n// http:[host]:[port]/\r\nexport function index (context) {\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n\r\n<a name=\"templating\" />\r\n## templating\r\n\r\nappex comes bundled with a built in template engine which is modelled on the Microsoft \r\nRazor templating engine. The following sections outline its use.\r\n\r\n<a name=\"template_overview\" />\r\n### overview\r\n\r\nThe appex template engine is available to all handlers by default. it is accessible\r\non the context.template property. the following is an example of its use.\r\n\r\n```\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n<ul>\r\n@for(var n in context.users) {\r\n\r\n\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t<li>@(context.users[n].name)</li>\r\n\t}\r\n}\r\n</ul>\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\t\r\n\tcontext.response.headers['Content-Type'] = 'text/html';\r\n\r\n    context.response.send(text);\r\n}\r\n\r\n```\r\n\r\n<a name=\"template_context\" />\r\n### context\r\n\r\neach template is passed a data context. this context allows the caller to \r\nsend data to the template for rendering. the context parameter is optional.\r\nthe example below is sending the users array to the template context for \r\nrendering.\r\n\r\n```\r\nexport function index(context) {\r\n\t\r\n    var users  = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    context.response.send(context.template.render('./view.txt', { users: users }));\r\n}\r\n```\r\n\r\n<a name=\"template_syntax\" />\r\n### syntax\r\n\r\nappex templates support the following statements and syntax\r\n\r\n#### if statement\r\n\r\nif statments are supported.\r\n\r\n```\r\n@if(expression) {\r\n\tsome content\r\n}\r\n\r\n@if(a > 10) {\r\n\tsome content\r\n}\r\n\r\n@(user.loggedin) {\r\n\t<span>welcome</span>\r\n}\r\n```\r\n\r\n#### for statement\r\n\r\nthe following for loops are supported.\r\n\r\n```\r\n@for(var i = i; i < 100; i++) {\r\n\t@(i)\r\n}\r\n\r\n@for(var n in list) {\r\n\t@(list[n])\r\n}\r\n```\r\n\r\n#### expressions\r\n\r\nwill emit the value contained.\r\n\r\n```\r\n@('hello world')\r\n\r\n@(123)\r\n\r\n@(some_variable)\r\n```\r\n\r\n#### code blocks\r\n\r\ncode blocks can be useful for adding template side rendering logic.\r\n\r\n```\r\n@{\r\n\tvar message = 'hello'\r\n}\r\n\r\n@(message)\r\n```\r\n\r\n#### comments\r\n```\r\n@*\r\n\tthis comment will not be rendered!\r\n*@\r\n```\r\n\r\n<a name=\"template_layouts_and_sections\" />\r\n### layouts and sections\r\n\r\nappex templates support template inheritance.\r\n\r\nconsider the following where layout.txt defines the sections 'header' and 'content' and the view.txt overrides\r\nthese sections with its own content.\r\n\r\n```\r\n//----------------------------------------------\r\n// layout.txt\r\n//----------------------------------------------\r\n\r\n<html>\r\n\r\n\t<head>\r\n\t\t\r\n\t\t@section header\r\n\r\n\t</head>\r\n\r\n\t<body>\r\n\r\n\t\t@section content {\r\n\t\t\r\n\t\t\t<span>some default content</span>\r\n\t\t\t\r\n\t\t}\r\n\r\n\t</body>\r\n\t\r\n</html>\r\n\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n@layout 'layout.txt'\r\n\r\n@section header {\r\n\r\n\t<title>my page</title>\r\n}\r\n\r\n@section content {\r\n\r\n\t<p>overriding the layout.txt content section.</p>\r\n\r\n\t<ul>\r\n\t@for(var n in context.users) {\r\n\r\n\t\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t\t<li>@(context.users[n].name)</li>\r\n\t\t}\r\n\t}\r\n\t</ul>\r\n}\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\r\n    context.response.send(text);\r\n}\r\n```\r\n\r\nnote : when specifying a layout, the view will only render content within\r\nthe layouts section placeholders. \r\n\r\n<a name=\"render\" />\r\n### render\r\n\r\nappex templates also allow for partial views with the @render statment. consider the following \r\nwhich renders the nav.txt file into the layout.txt file.\r\n\r\n```\r\n//----------------------------------------------\r\n// nav.txt\r\n//----------------------------------------------\r\n<ul>\r\n\t<li>home</li>\r\n\t<li>about</li>\r\n\t<li>contact</li>\r\n</ul>\r\n\r\n//----------------------------------------------\r\n// layout.txt\r\n//----------------------------------------------\r\n\r\n<html>\r\n\t<head>\r\n\t\t\r\n\t\t@section header\r\n\r\n\t</head>\r\n\r\n\t<body>\r\n\t\t\r\n\t\t@render 'nav.txt'\r\n\r\n\t\t@section content {\r\n\t\t\r\n\t\t\t<span>some default content</span>\r\n\t\t\t\r\n\t\t}\r\n\r\n\t</body>\r\n\t\r\n</html>\r\n\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n@layout 'layout.txt'\r\n\r\n@section header {\r\n\r\n\t<title>my page</title>\r\n}\r\n\r\n@section content {\r\n\r\n\t<p>overriding the layout.txt content section.</p>\r\n\r\n\t<ul>\r\n\t@for(var n in context.users) {\r\n\r\n\t\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t\t<li>@(context.users[n].name)</li>\r\n\t\t}\r\n\t}\r\n\t</ul>\r\n}\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\r\n    context.response.send(text);\r\n}\r\n```\r\n\r\n<a name=\"caching_and_devmode\" />\r\n### caching and devmode\r\n\r\nappex template content is not cached (the implementor is expected to handle their own caching)\r\nhowever the generated template code is. \r\n\r\nappex templates do inheriate the behaviour of the appex 'devmode' option. setting\r\ndevmode to 'true' will cause template code to be reloaded from disk and code generated with each \r\nrequest. setting devmode to false will load content from disk on first request, and \r\ncache the generated template code in memory for the lifetime of the application.\r\n\r\nin addition to this, a implementation where the devmode is false can override the caching \r\nbehaviour with the following.\r\n\r\n```javascript\r\nexport function index(context) {\r\n\r\n\t// manually override the template devmode option.\r\n\tcontext.template.option.devmode = true; \r\n\r\n\tcontext.response.send(context.template.render('./view.txt'))\r\n}\r\n```\r\n\r\n<a name=\"sitemaps\" />\r\n## sitemaps\r\n\r\nappex is able to derive sitemap metadata automatically from http endpoints created with\r\ntypescript modules and functions. This metadata is useful to generate sitemap.xml\r\nfiles, as well as creating site navigation links automatically.\r\n\r\n<a name=\"sitemap_generate\" />\r\n### generate sitemap\r\n\r\nappex sitemaps can be obtained from the context.sitemap property. \r\n\r\n```javascript\r\nexport function index(context) {\r\n\r\n\t// return all nodes in this site.\r\n\tcontext.response.json(context.sitemap)\r\n\r\n}\r\n```\r\n\r\nAdditionally, it may be helpful to isolate branches of the sitemap with the \r\ncontext.sitemap.get([qualifier]) function. as demonstrated below.\r\n\r\n```javascript\r\nexport module admin {\r\n\texport function index     (context) { }\r\n\texport function dashboard (context) { }\r\n\texport function content   (context) { }\r\n\texport module users {\r\n\t\texport function login(context) { }\r\n\t\texport function logout(context) { }\r\n\t}\r\n}\r\n\r\nexport function test(context) {\r\n\t\r\n\t// view all admin sitemap nodes\r\n\tcontext.response.json(context.sitemap.get('admin'))\r\n\r\n\t// view all admin.users sitemap nodes\r\n\t//context.response.json(context.sitemap.get('admin.users'))\r\n}\r\n```\r\n\r\n<a name=\"sitemap_metadata\" />\r\n### cascade metadata\r\n\r\neach node returned in the appex sitemap includes the cascade applied for that handler. With this\r\ndevelopers can apply their own metadata for a given handler. as demonstrated below.\r\n\r\n```javascript\r\ndeclare var cascade;\r\n\r\ncascade({website:'http://mysite.com/'}) // global\r\n\r\ncascade('index', {title:'home page'})\r\nexport function index(context) {\r\n\tcontext.response.send('index')\r\n}\r\n\r\ncascade('about', {title: 'about page'})\r\nexport function about(context) {\r\n\tcontext.response.send('about')\r\n}\r\n\r\ncascade('sitemap', {title: 'sitemap pages'})\r\nexport function sitemap(context) {\r\n\tcontext.response.json(context.sitemap)\r\n}\r\n```\r\n\r\nvisiting /sitemap will display the following..\r\n\r\n```javascript\r\n{\r\n    \"nodes\": [\r\n        {\r\n            \"name\": \"index\",\r\n            \"cascade\": {\r\n                \"website\": \"http://mysite.com/\",\r\n                \"title\": \"home page\"\r\n            },\r\n            \"urls\": [\r\n                \"/\"\r\n            ]\r\n        },\r\n        {\r\n            \"name\": \"about\",\r\n            \"cascade\": {\r\n                \"website\": \"http://mysite.com/\",\r\n                \"title\": \"about page\"\r\n            },\r\n            \"urls\": [\r\n                \"/about\"\r\n            ]\r\n        },\r\n        {\r\n            \"name\": \"sitemap\",\r\n            \"cascade\": {\r\n                \"website\": \"http://mysite.com/\",\r\n                \"title\": \"sitemap pages\"\r\n            },\r\n            \"urls\": [\r\n                \"/sitemap\"\r\n            ]\r\n        }\r\n    ]\r\n}\r\n```\r\n\r\n<a name=\"json_schema\" />\r\n## json schema\r\n\r\nappex provides functionality for generating json schemas from TypeScript classes\r\nand interfaces as well as tools for validating json data.\r\n\r\n<a name=\"generating_schema\" />\r\n### generating schema\r\n\r\nThe following demonstrates generating json schema from the following class\r\nhierarchy.\r\n\r\n```javascript\r\nexport module model {\r\n\r\n    /** a product */\r\n    export class Product {\r\n        \r\n        /** the product name */\r\n        public name        : string;\r\n\r\n        /** the product description */\r\n        public description : string;\r\n\r\n        /** the product cost */\r\n        public cost        : number;\r\n    } \r\n\r\n    /** a order */\r\n    export class Order {\r\n        \r\n        /** the product being ordered */\r\n        public products  : Product;\r\n    }\r\n\r\n    /** a customer */\r\n    export class Customer {\r\n\r\n        /** the customers firstname */\r\n        public firstname  : string;\r\n\r\n        /** the customers lastname */\r\n        public lastname   : string;\r\n\r\n        /** orders made by this customer */\r\n        public orders     : Order[];\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.IContext) {\r\n\t\r\n\t// pass the fully qualified name of the type.\r\n    var schema = context.schema.generate('model.Customer');\r\n\r\n    context.response.json(schema);\r\n}\r\n```\r\n\r\nwhich generates the following json schema.\r\n\r\n```javascript\r\n{\r\n    \"id\": \"model.Customer\",\r\n    \"type\": \"object\",\r\n    \"description\": \"a customer\",\r\n    \"properties\": {\r\n        \"firstname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers firstname\",\r\n            \"required\": true\r\n        },\r\n        \"lastname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers lastname\",\r\n            \"required\": true\r\n        },\r\n        \"orders\": {\r\n            \"type\": \"array\",\r\n            \"items\": {\r\n                \"type\": {\r\n                    \"id\": \"model.Order\",\r\n                    \"type\": \"object\",\r\n                    \"description\": \"a order\",\r\n                    \"properties\": {\r\n                        \"products\": {\r\n                            \"id\": \"model.Product\",\r\n                            \"type\": \"object\",\r\n                            \"description\": \"a product\",\r\n                            \"properties\": {\r\n                                \"name\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product name\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"description\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product description\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"cost\": {\r\n                                    \"type\": \"number\",\r\n                                    \"description\": \"the product cost\",\r\n                                    \"required\": true\r\n                                }\r\n                            },\r\n                            \"required\": true\r\n                        }\r\n                    }\r\n                }\r\n            },\r\n            \"description\": \"orders made by this customer\",\r\n            \"required\": true\r\n        }\r\n    }\r\n}\r\n```\r\na quick note...\r\n\r\nwhen generating schema from classes:\r\n\r\n* only public class variables will be emitted.\r\n* all properties will be marked as \"required\".\r\n\r\nwhen generating schema from interfaces:\r\n\r\n* all properties will be emitted. \r\n* all properties will be marked as \"required\" unless modified with '?'.\r\n\r\n<a name=\"validating_schema\" />\r\n### validating json\r\n\r\nappex supports json schema validation from class and interface definitions. consider the following...\r\n\r\n```javascript\r\ninterface Customer {\r\n\r\n    firstname    : string;\r\n\r\n    lastname     : string;\r\n\r\n    age          : number;\r\n\r\n    emails       : string[];\r\n\r\n    option_a ?   : boolean; // optional\r\n\r\n    option_b ?   : boolean; // optional\r\n\r\n}\r\n\r\nexport function index(context) {\r\n\r\n    // a customer with invalid data.\r\n\r\n    var customer = {\r\n\r\n        firstname    : 'dave',\r\n\r\n        age          : '33',\r\n\r\n        emails       : [12345, 'dave@domain.com', true],\r\n\r\n        option_b     : 1,\r\n\r\n        option_c     : 1\r\n    }\r\n\r\n    // do validation.\r\n\r\n    var errors = context.schema.validate('Customer', customer);\r\n\r\n    if(errors) {\r\n\r\n        context.response.json(errors);\r\n    }\r\n}\r\n```\r\n\r\nwill output the following.\r\n\r\n```javascript\r\n[\r\n    {\r\n        \"message\": \"instance.lastname is required.\"\r\n    },\r\n    {\r\n        \"message\": \"instance.age is not a number\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[0] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[2] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_b is not a boolean\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_c unexpected property\"\r\n    }\r\n]\r\n```\r\n\r\n<a name=\"reflection\" />\r\n## reflection\r\n\r\nappex provides a reflection api derived from TypeScript's type system that developers can \r\nleverage to reflect type information declared throughout their appex modules. \r\n\r\nthe following section outlines how to use the reflection api.\r\n\r\n<a name=\"reflect_everything\" />\r\n### reflect everything\r\n\r\nthe appex reflection api is passed on the context.module.reflection property and is available to all\r\nappex handler methods. The following code will JSON serialize everything declared in your appex\r\nproject and write it to the http response. \r\n\r\n```javascript\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection );\r\n}\r\n```\r\n\r\n<a name=\"reflect_specific_types\" />\r\n### reflect specific types\r\n\r\nIn typical scenarios, developers will want to leverage reflection meta data to generate\r\nservice contacts and client side models. the reflection api lets you access meta data \r\nfor the following types declared in your project. \r\n\r\n* modules\r\n* imports\r\n* classes\r\n* interfaces\r\n* functions\r\n* variables\r\n\r\nto access specific type metadata, use the reflection.get([qualifier]) method, as demonstrated below.\r\n\r\n```javascript\r\nexport module model {\r\n    \r\n    export class Customer {\r\n\r\n        public firstname   : string;\r\n\r\n        public lastname    : string;\r\n\r\n        public age         : number;\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('model.Customer') );\r\n}\r\n```\r\nand methods..\r\n\r\n```javascript\r\nfunction some_method(a:string, b:number, c?:boolean) : void { }\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_method') );\r\n}\r\n```\r\n\r\n....and variables...\r\n\r\n```javascript\r\nvar some_variable:number = 10;\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_variable') );\r\n}\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\nThis section outlines development with appex.\r\n\r\n<a name=\"appex_declaration\" />\r\n### appex.d.ts declaration\r\n\r\nIf you develop on a TypeScript complicant editor (one that supports TS 0.9), appex comes bundled\r\nwith a declaration file you can reference in your project. If installing appex via npm, your\r\nreference should be as follows.\r\n\r\n```javascript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nexport function index (context:appex.web.IContext) { \r\n    \r\n    context.response.send('hello');\r\n}\r\n\r\nexport function wildcard(context:appex.web.IContext, path:string) {\r\n\r\n    context.response.serve('./', path);\r\n}\r\n```\r\n\r\nBy referencing this in your project, you get the benefits of code completion and static type checking\r\nagainst both appex, and the nodejs core.\r\n\r\n![](https://raw.github.com/sinclairzx81/appex/master/artifacts/code-completion.jpg)\r\n\r\nAdditional declaration files may be obtained from [here](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex ({ program : './index.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"users.ts\" />\r\n/// <reference path=\"pages.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { context.response.send('users.login') }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { context.response.send('users.logout') }\r\n}\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { context.response.send('home') }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { context.response.send('about') }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { context.response.send('contact') }\r\n\r\nexport function wildcard (context, path) { context.response.send(404, ' not found') }\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"license\" />\r\n## license\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) 2013 Haydn Paterson (sinclair) <haydn.developer@gmail.com>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in\r\nall copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\nTHE SOFTWARE.\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"https://raw.github.com/sinclairzx81/appex/master/license.txt","type":"The MIT License (MIT)"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"nodejs web api with typescript","directories":{},"dependencies":{"typescript.api":"0.6.1"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.5.6":{"name":"appex","version":"0.5.6","keywords":["typescript","web api","reflection","compiler","schema","templates","sitemap"],"author":{"name":"sinclair"},"_id":"appex@0.5.6","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"eab1044967ead92ce35563ff4f95aa3f8e271da1","tarball":"https://registry.npmjs.org/appex/-/appex-0.5.6.tgz","integrity":"sha512-9Whu3rxN205LPFXxKDCtOmnfszxTlwpWI4++rjeIJ9cvw/UF00HQQCmkpYr+kp8vlApAB0Yyig8IU/9J7IXYgA==","signatures":[{"sig":"MEUCIBtElFORudI4sgNQvIYZLckrJh4YeynQ5FlsUUTYfQNKAiEAhn3lEa1Ir2evKg8h8Y5/t+lXryAAU5mag7XdMJpBqio=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/artifacts/logo.jpg)\r\n\r\n### develop nodejs web applications with [typescript](http://www.typescriptlang.org/)\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http://localhost:3000/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// http://localhost:3000/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about');\r\n}\r\n\r\n// http://localhost:3000/(.*)\r\nexport function wildcard (context, path) {\r\n    \r\n    context.response.send(404, path + \" not found\");\r\n}\r\n\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n### contents\r\n\r\n* [getting started](#getting_started)\r\n\t* [create a application](#application)\r\n\t* [start up options](#options)\r\n\t* [running on an existing http server](#http_server)\r\n\t* [running as express middleware](#express_middleware)\r\n* [http handlers](#http_handlers)\r\n\t* [app context](#app_context)\r\n\t* [routing handlers](#routing_handlers)\r\n\t* [handler signatures](#handler_signatures)\r\n\t* [named handlers](#named_handlers)\r\n\t* [index handlers](#index_handlers)\r\n\t* [wildcard handlers](#wildcard_handlers)\r\n\t* [cascades](#cascades)\r\n\t* [http verbs](#http_verbs)\r\n\t* [middleware](#middleware)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [handling 404](#handling_404)\r\n\t* [serving static files](#serving_static_files)\r\n* [templating](#templating)\r\n\t* [overview](#template_overview)\r\n\t* [context](#template_context)\t\r\n\t* [syntax](#template_syntax)\r\n\t* [layouts and sections](#template_layouts_and_sections)\r\n\t* [render](#template_render)\r\n\t* [caching and devmode](#caching_and_devmode)\r\n* [sitemaps](#sitemaps)\r\n\t* [generating](#sitemap_generate)\r\n\t* [metadata](#sitemap_metadata)\r\n* [json schema](#json_schema)\r\n\t* [generating schema](#generating_schema)\r\n\t* [validating json](#validating_json)\r\n* [reflection](#reflection)\r\n\t* [reflect everything](#reflect_everything)\r\n\t* [reflect specific types](#reflect_specific_types)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [appex.d.ts declaration](#appex_declaration)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n* [license](#license)\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline creating appex applications and configuration.\r\n\r\n<a name=\"application\" />\r\n### create a application\r\n\r\nThe following code will create a standalone appex application and \r\nhttp server and listen on port 3000.\r\n\r\n```javascript\r\nvar appex   = require('appex');\r\n\r\nvar app   = appex({ program : './program.ts', \r\n                    devmode : true,\r\n                    logging : true });\r\n\r\napp.listen(3000);\r\n```\r\n\r\nnote: devmode and logging are optional. however, when developing \r\nwith appex, it is helpful to have these enabled.\r\n\r\n<a name=\"options\" />\r\n### start up options\r\n\r\nappex accepts the following start up options.\r\n\r\n```javascript\r\nvar options = {\r\n\r\n\t// (required) location of source file.\r\n\tprogram    : './program.ts', \r\n\r\n\t// (optional) recompile on request. (default:false) \r\n\tdevmode    : true,          \r\n\r\n\t// (optional) log to stdout. (default:false) \r\n\tlogging    : true,\r\n\r\n\t// (optional) user defined objects added to the app context.\r\n\tcontext    : {}\r\n};\r\n\r\nvar app = appex( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### running on an existing http server\r\n\r\nThe following demonstrates setting up appex on an existing nodejs http server. In \r\nthis example, appex will attempt to handle incoming requests, and if appex cannot\r\nroute the request, will fire the callback.\r\n\r\n```javascript\r\nvar http  = require('http');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\nvar server = http.createServer(function(req, res){\r\n\r\n    app(req, res, function() { // appex handler...\r\n\t\t\r\n\t\t// not handled.\r\n\r\n\t}); \r\n});\r\n\r\nserver.listen(3000);\r\n```\r\n\r\n<a name=\"express_middleware\" />\r\n### running as express middleware\r\n\r\nappex allows developers to augment existing express / connect applications by \r\nway of middleware. The following demonstrates setting up appex as express middleware.\r\n\r\n```javascript\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) ); \r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nLike in the \"running on an existing http server\" example above, appex will attempt to intercept incoming requests. \r\nif appex cannot find a matching route for the request, it will automatically call the \"next\" function to pass the request \r\non to the next middleware or express handler.\r\n\r\nin addition to this, appex may also act as traditional express middleware. In the example below, a appex wildcard\r\nfunction is created which will match \"all\" incoming requests, the wildcard function simply prints hello world to \r\nthe console and then calls context.next(), which passes the request on the express handler.\r\n\r\n```javascript\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tconsole.log('hello world!!');\r\n\r\n\tcontext.next(); // pass it on!\r\n}\r\n\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) );\r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nJust like traditional express middleware, appex will also inheriate the characteristics of the request.\r\n\r\nconsider the following example in which the jade view engine is configured for use. appex will inheritate the \r\nresponse.render() method, which is passed to the appex handler as context.response.render()\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\napp.configure(function(){\r\n\r\n  app.set('views', __dirname + '/views');\r\n  \r\n  // set up the jade engine.\r\n  app.set('view engine', 'jade'); \r\n  \r\n  // bind appex\r\n  app.use( appex({program:'./program.ts', devmode:true} ));  \r\n});\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/\r\nexport function index(context) {\r\n\t\r\n\t// jade renderer works!\r\n\tcontext.response.render('index', { title: 'Express' }); \r\n}\r\n```\r\n\r\n<a name=\"http_handlers\" />\r\n## http handlers\r\n\r\nThe following sections describe how to create http accessible handlers with appex.\r\n\r\n<a name=\"app_context\" />\r\n### app context\r\n\r\nAll appex functions are passed a application context object as their first argument. The app context object \r\nencapulates the http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the app context\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.cascade    - appex cascade.\r\n\r\n\t// context.next       - the next function (express middleware)\r\n\t\r\n\t// context.router     - the appex router\r\n\r\n\t// context.sitemap    - the appex sitemap api\r\n\r\n\t// context.template   - the appex template engine.\r\n\t\r\n\t// context.module     - the module being run (this module)\r\n\r\n\t// context.schema     - json schema api.\r\n\r\n\t// context.mime       - a http mime type utility.\r\n}\r\n```\r\n\r\nit is possible to extend the default objects passed on the context by adding them on the appex startup options. The \r\nfollowing will attach the async module to the context. \r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = appex({ program : './program.ts', \r\n\t\t\t\t  devmode : true, \r\n\t\t\t      context: {\r\n\t\t\t\t\t\tasync : require('async')\r\n\t\t\t\t  }});\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\r\n\t// context.async = passed on the context.\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n```\r\n<a name=\"routing_handlers\" />\r\n### routing handlers\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context) { /* handle route */ }\r\n}\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/(.*)\r\nexport function wildcard (context, path) { /* handle route */ }\r\n\r\n```\r\n\r\n<a name=\"handler_signatures\" />\r\n### handler signatures\r\n\r\nappex supports three function signatures for http routing (named, index and wildcard). Functions that\r\ndo not apply these signatures will not be routed.\r\n\r\n<a name=\"named_handlers\" />\r\n### named handlers\r\n\r\nNamed handlers resolve urls to their current module scope + the name of the function.\r\n\r\nNamed handlers require the following signature:\r\n\r\n* name        - 'anything'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n\r\n// http://[host]:[port]/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about page');\r\n}\r\n\r\n// http://[host]:[port]/users/login\r\nexport module users {\r\n\r\n\texport function login(context) {\r\n\t\t\r\n\t\tcontext.response.send('handle login');\t\r\n\t}\r\n}\r\n\r\n```\r\n\r\n<a name=\"index_handlers\" />\r\n### index handlers\r\n\r\nIndex handlers resolve urls to their current module scope.\r\n\r\nIndex handlers require the following signature:\r\n\r\n* name        - 'index'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) \r\n\t{\t\r\n\t\tcontext.response.send('blog index');\r\n\t}\r\n}\r\n```\r\n\r\n<a name=\"wildcard_handlers\" />\r\n### wildcard handlers\r\n\r\nWildcard handlers resolve their urls to their current module scope + url.\r\n\r\nappex wildcard handlers allow for wildcard routing at a given module scope. Wildcard handlers\r\nsupport 'typed' url argument mapping, as denoted by the arguments annotation.\r\n\r\nIn addition, wildcard handlers also support optional arguments which can be specified with TypeScript's '?' \r\non argument names.\r\n\r\nappex wildcard handlers require the following signature:\r\n\r\n* name        - 'wildcard'\r\n* argument[0] - app context\r\n* argument[n] - 1 or more arguments to be mapped from the url\r\n* returns     - void (optional)\r\n\r\n```javascript\r\ndeclare var console;\r\n\r\nexport module blogs {\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11   - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/11  - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/3rd - not matched - (see number annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01     - matched     - (see ? annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013        - not matched - (month is required)\r\n\t\r\n    export function wildcard(context, year:number, month:number, day?:number) {\r\n\r\n        context.response.json({ year: year, month: month, day: day})\r\n    }\r\n}\r\n\r\n// url : http://[host]:[port]/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// url : http://[host]:[port]/(.*) \r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, 'not found');\r\n}\r\n\r\n```\r\nnote: appex supports boolean, number, string and any annotations on wildcard arguments. if no annotation\r\nis specified, appex interprets the argument as a string. the type 'any' is also interpreted as string.\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"cascades\" />\r\n### cascades\r\n\r\nappex supports a cascading attribute scheme on modules and functions. With this, developers can apply\r\narbituary meta data for modules and functions that will propagate through scope. appex has two special\r\ncascade properties for middleware and http verb matching, which are described below, however consider\r\nthe following code which illustrates the concept.\r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ncascade({a: 10}); // global.\r\n\r\ncascade('foo', {b : 20})\r\nexport module foo {\r\n\r\n    cascade('foo.bar', {c : 30})\r\n    export module bar {\r\n            \r\n        cascade('foo.bar.index', {d : 40})\r\n        export function index(context) {\r\n        \r\n            //context.cascade\r\n            //{\r\n            //    \"a\": 10,\r\n            //    \"b\": 20,\r\n            //    \"c\": 30,\r\n\t\t\t//    \"d\": 40\r\n            //}\r\n\r\n            context.response.json( context.cascade );       \r\n        }\r\n    }\r\n}\r\n\r\n```\r\n\r\n<a name=\"http_verbs\" />\r\n### http verbs\r\n\r\nappex handles http verb matching with cascades. appex will recognise the \r\n'verbs' property applied to the cascade to match against http verbs.\r\n\r\n```javascript\r\ncascade('index', { verbs: ['get'] })\r\nexport function index (context) { \r\n        \r\n    // only allow HTTP GET requests\r\n    context.response.send('index')\r\n}\r\n\r\ncascade('index', { verbs: ['post', 'put'] })\r\nexport function submit (context) { \r\n    \r\n    // only allow HTTP POST and PUT requests\r\n    context.response.send('submit')\r\n}\r\n```\r\n\r\n\r\n<a name=\"middleware\" />\r\n### middleware\r\n\r\nappex supports middleware with cascades. appex middleware defined with cascades allows\r\ndevelopers to scope middleware on single functions, or entire module scopes. appex will \r\nrecognise the 'use' property applied to the cascade to invoke middleware.\r\n\r\nthe following demonstrates how one might use middleware to secure a site admin.\r\n\r\nnote: middleware 'must' call next or handle the request. \r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ndeclare var console;\r\n\r\nfunction authenticate(context) {\r\n\r\n    console.log('authenticate')\r\n\r\n\t// call next() if authenticated, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\nfunction authorize(context) {\r\n\r\n    console.log('authorize')\r\n\r\n\t// call next() if authorized, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\n// apply security middleware to admin scope.\r\ncascade('admin', {use: [authenticate, authorize]}) \r\nexport module admin {\r\n\r\n    export function index(context) {\r\n        \r\n        console.log(context.cascade); // view cascade\r\n\r\n        context.response.send('access granted!')\r\n    }\r\n}\r\n\r\n// index handler has no middleware applied.\r\nexport function index (context) { \r\n    \r\n    console.log(context.cascade); // view cascade\r\n\r\n    context.response.send('home')\r\n}\r\n```\r\n\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex will only route functions prefixed with the TypeScript 'export' declarer. This rule\r\nalso applied to modules. Developers can use this to infer notions of public and private \r\nat the http level.\r\n\r\nconsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is \r\n// therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private \r\n\t// as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is \r\n\t// private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and \r\n// is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore \r\n// publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke \r\n\t// private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in \r\n\t// private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method \r\n\t// in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.send('public_function');\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```javascript\r\n// http:[host]:[port]/\r\nexport function index (context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard (context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n<a name=\"serving_static_files\" />\r\n## serving static files\r\n\r\nUse wildcard functions with context.response.serve() to serve static content.\r\n\r\n```javascript\r\nexport module static {\r\n\t\r\n\t// http:[host]:[port]/static/(.*)\r\n\texport function wildcard(context, path) {\r\n\r\n\t\tcontext.response.serve('./static/', path);\r\n\t}\r\n}\r\n\r\n// http:[host]:[port]/\r\nexport function index (context) {\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n\r\n<a name=\"templating\" />\r\n## templating\r\n\r\nappex comes bundled with a built in template engine which is modelled on the Microsoft \r\nRazor templating engine. The following sections outline its use.\r\n\r\n<a name=\"template_overview\" />\r\n### overview\r\n\r\nThe appex template engine is available to all handlers by default. it is accessible\r\non the context.template property. the following is an example of its use.\r\n\r\n```\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n<ul>\r\n@for(var n in context.users) {\r\n\r\n\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t<li>@(context.users[n].name)</li>\r\n\t}\r\n}\r\n</ul>\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\t\r\n\tcontext.response.headers['Content-Type'] = 'text/html';\r\n\r\n    context.response.send(text);\r\n}\r\n\r\n```\r\n\r\n<a name=\"template_context\" />\r\n### context\r\n\r\neach template is passed a data context. this context allows the caller to \r\nsend data to the template for rendering. the context parameter is optional.\r\nthe example below is sending the users array to the template context for \r\nrendering.\r\n\r\n```\r\nexport function index(context) {\r\n\t\r\n    var users  = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    context.response.send(context.template.render('./view.txt', { users: users }));\r\n}\r\n```\r\n\r\n<a name=\"template_syntax\" />\r\n### syntax\r\n\r\nappex templates support the following statements and syntax\r\n\r\n#### if statement\r\n\r\nif statments are supported.\r\n\r\n```\r\n@if(expression) {\r\n\tsome content\r\n}\r\n\r\n@if(a > 10) {\r\n\tsome content\r\n}\r\n\r\n@(user.loggedin) {\r\n\t<span>welcome</span>\r\n}\r\n```\r\n\r\n#### for statement\r\n\r\nthe following for loops are supported.\r\n\r\n```\r\n@for(var i = i; i < 100; i++) {\r\n\t@(i)\r\n}\r\n\r\n@for(var n in list) {\r\n\t@(list[n])\r\n}\r\n```\r\n\r\n#### expressions\r\n\r\nwill emit the value contained.\r\n\r\n```\r\n@('hello world')\r\n\r\n@(123)\r\n\r\n@(some_variable)\r\n```\r\n\r\n#### code blocks\r\n\r\ncode blocks can be useful for adding template side rendering logic.\r\n\r\n```\r\n@{\r\n\tvar message = 'hello'\r\n}\r\n\r\n@(message)\r\n```\r\n\r\n#### comments\r\n```\r\n@*\r\n\tthis comment will not be rendered!\r\n*@\r\n```\r\n\r\n<a name=\"template_layouts_and_sections\" />\r\n### layouts and sections\r\n\r\nappex templates support template inheritance.\r\n\r\nconsider the following where layout.txt defines the sections 'header' and 'content' and the view.txt overrides\r\nthese sections with its own content.\r\n\r\n```\r\n//----------------------------------------------\r\n// layout.txt\r\n//----------------------------------------------\r\n\r\n<html>\r\n\r\n\t<head>\r\n\t\t\r\n\t\t@section header\r\n\r\n\t</head>\r\n\r\n\t<body>\r\n\r\n\t\t@section content {\r\n\t\t\r\n\t\t\t<span>some default content</span>\r\n\t\t\t\r\n\t\t}\r\n\r\n\t</body>\r\n\t\r\n</html>\r\n\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n@layout 'layout.txt'\r\n\r\n@section header {\r\n\r\n\t<title>my page</title>\r\n}\r\n\r\n@section content {\r\n\r\n\t<p>overriding the layout.txt content section.</p>\r\n\r\n\t<ul>\r\n\t@for(var n in context.users) {\r\n\r\n\t\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t\t<li>@(context.users[n].name)</li>\r\n\t\t}\r\n\t}\r\n\t</ul>\r\n}\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\r\n    context.response.send(text);\r\n}\r\n```\r\n\r\nnote : when specifying a layout, the view will only render content within\r\nthe layouts section placeholders. \r\n\r\n<a name=\"render\" />\r\n### render\r\n\r\nappex templates also allow for partial views with the @render statment. consider the following \r\nwhich renders the nav.txt file into the layout.txt file.\r\n\r\n```\r\n//----------------------------------------------\r\n// nav.txt\r\n//----------------------------------------------\r\n<ul>\r\n\t<li>home</li>\r\n\t<li>about</li>\r\n\t<li>contact</li>\r\n</ul>\r\n\r\n//----------------------------------------------\r\n// layout.txt\r\n//----------------------------------------------\r\n\r\n<html>\r\n\t<head>\r\n\t\t\r\n\t\t@section header\r\n\r\n\t</head>\r\n\r\n\t<body>\r\n\t\t\r\n\t\t@render 'nav.txt'\r\n\r\n\t\t@section content {\r\n\t\t\r\n\t\t\t<span>some default content</span>\r\n\t\t\t\r\n\t\t}\r\n\r\n\t</body>\r\n\t\r\n</html>\r\n\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n@layout 'layout.txt'\r\n\r\n@section header {\r\n\r\n\t<title>my page</title>\r\n}\r\n\r\n@section content {\r\n\r\n\t<p>overriding the layout.txt content section.</p>\r\n\r\n\t<ul>\r\n\t@for(var n in context.users) {\r\n\r\n\t\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t\t<li>@(context.users[n].name)</li>\r\n\t\t}\r\n\t}\r\n\t</ul>\r\n}\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\r\n    context.response.send(text);\r\n}\r\n```\r\n\r\n<a name=\"caching_and_devmode\" />\r\n### caching and devmode\r\n\r\nappex template content is not cached (the implementor is expected to handle their own caching)\r\nhowever the generated template code is. \r\n\r\nappex templates do inheriate the behaviour of the appex 'devmode' option. setting\r\ndevmode to 'true' will cause template code to be reloaded from disk and code generated with each \r\nrequest. setting devmode to false will load content from disk on first request, and \r\ncache the generated template code in memory for the lifetime of the application.\r\n\r\nin addition to this, a implementation where the devmode is false can override the caching \r\nbehaviour with the following.\r\n\r\n```javascript\r\nexport function index(context) {\r\n\r\n\t// manually override the template devmode option.\r\n\tcontext.template.option.devmode = true; \r\n\r\n\tcontext.response.send(context.template.render('./view.txt'))\r\n}\r\n```\r\n\r\n<a name=\"sitemaps\" />\r\n## sitemaps\r\n\r\nappex is able to derive sitemap metadata automatically from http endpoints created with\r\ntypescript modules and functions. This metadata is useful to generate sitemap.xml\r\nfiles, as well as helping to create site navigation links when combined a template\r\nengine.\r\n\r\n<a name=\"sitemap_generate\" />\r\n### generate sitemap\r\n\r\nappex sitemaps can be obtained from the context.sitemap property. \r\n\r\n```javascript\r\nexport function index(context) {\r\n\r\n\t// return all nodes in this site.\r\n\tcontext.response.json(context.sitemap)\r\n\r\n}\r\n```\r\n\r\nAdditionally, it may be helpful to isolate branches of the sitemap with the \r\ncontext.sitemap.get([qualifier]) function. as demonstrated below.\r\n\r\n```javascript\r\nexport module admin {\r\n\r\n\texport function index     (context) { }\r\n\r\n\texport function dashboard (context) { }\r\n\r\n\texport function content   (context) { }\r\n\r\n\texport module users {\r\n\r\n\t\texport function login(context) { }\r\n\r\n\t\texport function logout(context) { }\r\n\t}\r\n}\r\n\r\nexport function test(context) {\r\n\t\r\n\t// view all admin sitemap nodes\r\n\tcontext.response.json(context.sitemap.get('admin'))\r\n\r\n\t// view all admin.users sitemap nodes\r\n\t//context.response.json(context.sitemap.get('admin.users'))\r\n}\r\n```\r\n\r\n<a name=\"sitemap_metadata\" />\r\n### cascade metadata\r\n\r\neach sitemap node contains the cascade applied to the handler for which the node applies. With this\r\ndevelopers can apply custom metadata for a given node. as demonstrated below.\r\n\r\n```javascript\r\ndeclare var cascade;\r\n\r\ncascade({website:'http://mysite.com/'}) // global\r\n\r\ncascade('index', {title:'home page'})\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('index')\r\n}\r\n\r\ncascade('about', {title: 'about page'})\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about')\r\n}\r\n\r\ncascade('sitemap', {title: 'sitemap page'})\r\nexport function sitemap(context) {\r\n\r\n\tcontext.response.json(context.sitemap)\r\n}\r\n```\r\n\r\nvisiting /sitemap will output the following.\r\n\r\n```javascript\r\n{\r\n    \"name\": \"sitemap\",\r\n    \"nodes\": [\r\n        {\r\n            \"name\": \"index\",\r\n            \"urls\": [\r\n                \"/\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"home page\"\r\n        },\r\n        {\r\n            \"name\": \"about\",\r\n            \"urls\": [\r\n                \"/about\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"about page\"\r\n        },\r\n        {\r\n            \"name\": \"sitemap\",\r\n            \"urls\": [\r\n                \"/sitemap\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"sitemap page\"\r\n        }\r\n    ]\r\n}\r\n```\r\n\r\n<a name=\"json_schema\" />\r\n## json schema\r\n\r\nappex provides functionality for generating json schemas from TypeScript classes\r\nand interfaces as well as tools for validating json data.\r\n\r\n<a name=\"generating_schema\" />\r\n### generating schema\r\n\r\nThe following demonstrates generating json schema from the following class\r\nhierarchy.\r\n\r\n```javascript\r\nexport module model {\r\n\r\n    /** a product */\r\n    export class Product {\r\n        \r\n        /** the product name */\r\n        public name        : string;\r\n\r\n        /** the product description */\r\n        public description : string;\r\n\r\n        /** the product cost */\r\n        public cost        : number;\r\n    } \r\n\r\n    /** a order */\r\n    export class Order {\r\n        \r\n        /** the product being ordered */\r\n        public products  : Product;\r\n    }\r\n\r\n    /** a customer */\r\n    export class Customer {\r\n\r\n        /** the customers firstname */\r\n        public firstname  : string;\r\n\r\n        /** the customers lastname */\r\n        public lastname   : string;\r\n\r\n        /** orders made by this customer */\r\n        public orders     : Order[];\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.IContext) {\r\n\t\r\n\t// pass the fully qualified name of the type.\r\n    var schema = context.schema.generate('model.Customer');\r\n\r\n    context.response.json(schema);\r\n}\r\n```\r\n\r\nwhich generates the following json schema.\r\n\r\n```javascript\r\n{\r\n    \"id\": \"model.Customer\",\r\n    \"type\": \"object\",\r\n    \"description\": \"a customer\",\r\n    \"properties\": {\r\n        \"firstname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers firstname\",\r\n            \"required\": true\r\n        },\r\n        \"lastname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers lastname\",\r\n            \"required\": true\r\n        },\r\n        \"orders\": {\r\n            \"type\": \"array\",\r\n            \"items\": {\r\n                \"type\": {\r\n                    \"id\": \"model.Order\",\r\n                    \"type\": \"object\",\r\n                    \"description\": \"a order\",\r\n                    \"properties\": {\r\n                        \"products\": {\r\n                            \"id\": \"model.Product\",\r\n                            \"type\": \"object\",\r\n                            \"description\": \"a product\",\r\n                            \"properties\": {\r\n                                \"name\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product name\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"description\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product description\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"cost\": {\r\n                                    \"type\": \"number\",\r\n                                    \"description\": \"the product cost\",\r\n                                    \"required\": true\r\n                                }\r\n                            },\r\n                            \"required\": true\r\n                        }\r\n                    }\r\n                }\r\n            },\r\n            \"description\": \"orders made by this customer\",\r\n            \"required\": true\r\n        }\r\n    }\r\n}\r\n```\r\na quick note...\r\n\r\nwhen generating schema from classes:\r\n\r\n* only public class variables will be emitted.\r\n* all properties will be marked as \"required\".\r\n\r\nwhen generating schema from interfaces:\r\n\r\n* all properties will be emitted. \r\n* all properties will be marked as \"required\" unless modified with '?'.\r\n\r\n<a name=\"validating_schema\" />\r\n### validating json\r\n\r\nappex supports json schema validation from class and interface definitions. consider the following...\r\n\r\n```javascript\r\ninterface Customer {\r\n\r\n    firstname    : string;\r\n\r\n    lastname     : string;\r\n\r\n    age          : number;\r\n\r\n    emails       : string[];\r\n\r\n    option_a ?   : boolean; // optional\r\n\r\n    option_b ?   : boolean; // optional\r\n\r\n}\r\n\r\nexport function index(context) {\r\n\r\n    // a customer with invalid data.\r\n\r\n    var customer = {\r\n\r\n        firstname    : 'dave',\r\n\r\n        age          : '33',\r\n\r\n        emails       : [12345, 'dave@domain.com', true],\r\n\r\n        option_b     : 1,\r\n\r\n        option_c     : 1\r\n    }\r\n\r\n    // do validation.\r\n\r\n    var errors = context.schema.validate('Customer', customer);\r\n\r\n    if(errors) {\r\n\r\n        context.response.json(errors);\r\n    }\r\n}\r\n```\r\n\r\nwill output the following.\r\n\r\n```javascript\r\n[\r\n    {\r\n        \"message\": \"instance.lastname is required.\"\r\n    },\r\n    {\r\n        \"message\": \"instance.age is not a number\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[0] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[2] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_b is not a boolean\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_c unexpected property\"\r\n    }\r\n]\r\n```\r\n\r\n<a name=\"reflection\" />\r\n## reflection\r\n\r\nappex provides a reflection api derived from TypeScript's type system that developers can \r\nleverage to reflect type information declared throughout their appex modules. \r\n\r\nthe following section outlines how to use the reflection api.\r\n\r\n<a name=\"reflect_everything\" />\r\n### reflect everything\r\n\r\nthe appex reflection api is passed on the context.module.reflection property and is available to all\r\nappex handler methods. The following code will JSON serialize everything declared in your appex\r\nproject and write it to the http response. \r\n\r\n```javascript\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection );\r\n}\r\n```\r\n\r\n<a name=\"reflect_specific_types\" />\r\n### reflect specific types\r\n\r\nIn typical scenarios, developers will want to leverage reflection meta data to generate\r\nservice contacts and client side models. the reflection api lets you access meta data \r\nfor the following types declared in your project. \r\n\r\n* modules\r\n* imports\r\n* classes\r\n* interfaces\r\n* functions\r\n* variables\r\n\r\nto access specific type metadata, use the reflection.get([qualifier]) method, as demonstrated below.\r\n\r\n```javascript\r\nexport module model {\r\n    \r\n    export class Customer {\r\n\r\n        public firstname   : string;\r\n\r\n        public lastname    : string;\r\n\r\n        public age         : number;\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('model.Customer') );\r\n}\r\n```\r\nand methods..\r\n\r\n```javascript\r\nfunction some_method(a:string, b:number, c?:boolean) : void { }\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_method') );\r\n}\r\n```\r\n\r\n....and variables...\r\n\r\n```javascript\r\nvar some_variable:number = 10;\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_variable') );\r\n}\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\nThis section outlines development with appex.\r\n\r\n<a name=\"appex_declaration\" />\r\n### appex.d.ts declaration\r\n\r\nIf you develop on a TypeScript complicant editor (one that supports TS 0.9), appex comes bundled\r\nwith a declaration file you can reference in your project. If installing appex via npm, your\r\nreference should be as follows.\r\n\r\n```javascript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nexport function index (context:appex.web.IContext) { \r\n    \r\n    context.response.send('hello');\r\n}\r\n\r\nexport function wildcard(context:appex.web.IContext, path:string) {\r\n\r\n    context.response.serve('./', path);\r\n}\r\n```\r\n\r\nBy referencing this in your project, you get the benefits of code completion and static type checking\r\nagainst both appex, and the nodejs core.\r\n\r\n![](https://raw.github.com/sinclairzx81/appex/master/artifacts/code-completion.jpg)\r\n\r\nAdditional declaration files may be obtained from [here](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex ({ program : './index.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"users.ts\" />\r\n/// <reference path=\"pages.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { context.response.send('users.login') }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { context.response.send('users.logout') }\r\n}\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { context.response.send('home') }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { context.response.send('about') }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { context.response.send('contact') }\r\n\r\nexport function wildcard (context, path) { context.response.send(404, ' not found') }\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"license\" />\r\n## license\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) 2013 Haydn Paterson (sinclair) <haydn.developer@gmail.com>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in\r\nall copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\nTHE SOFTWARE.\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"https://raw.github.com/sinclairzx81/appex/master/license.txt","type":"The MIT License (MIT)"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"develop nodejs web applications with typescript","directories":{},"dependencies":{"typescript.api":"0.6.1"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.5.7":{"name":"appex","version":"0.5.7","keywords":["typescript","web api","reflection","compiler","schema","templates","sitemap"],"author":{"name":"sinclair"},"_id":"appex@0.5.7","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"2ed0a7a353088b6302f52dd50bcbe17694dd3914","tarball":"https://registry.npmjs.org/appex/-/appex-0.5.7.tgz","integrity":"sha512-EWsYG1mi8t92dkX4rCNZ7qFF36JSRm9wjrkZWKK2p52ga5eOzz0y43953PQPPfOPam0eg5WBaOBOQr971rrTvQ==","signatures":[{"sig":"MEYCIQC4w3eupGHVg4XYaS3fglfxEysMM6F2ZRekP7/wLJriAgIhAPpTCJCEWKjSye2t/tHJqkh3vpTiI+Twzfdu1YUyXKXW","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/artifacts/logo.jpg)\r\n\r\n### develop nodejs web applications with [typescript](http://www.typescriptlang.org/)\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http://localhost:3000/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// http://localhost:3000/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about');\r\n}\r\n\r\n// http://localhost:3000/(.*)\r\nexport function wildcard (context, path) {\r\n    \r\n    context.response.send(404, path + \" not found\");\r\n}\r\n\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n### contents\r\n\r\n* [getting started](#getting_started)\r\n\t* [create a application](#application)\r\n\t* [start up options](#options)\r\n\t* [running on an existing http server](#http_server)\r\n\t* [running as express middleware](#express_middleware)\r\n* [http handlers](#http_handlers)\r\n\t* [app context](#app_context)\r\n\t* [routing handlers](#routing_handlers)\r\n\t* [handler signatures](#handler_signatures)\r\n\t* [named handlers](#named_handlers)\r\n\t* [index handlers](#index_handlers)\r\n\t* [wildcard handlers](#wildcard_handlers)\r\n\t* [cascades](#cascades)\r\n\t* [http verbs](#http_verbs)\r\n\t* [middleware](#middleware)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [handling 404](#handling_404)\r\n\t* [serving static files](#serving_static_files)\r\n* [templating](#templating)\r\n\t* [overview](#template_overview)\r\n\t* [context](#template_context)\t\r\n\t* [syntax](#template_syntax)\r\n\t* [layouts and sections](#template_layouts_and_sections)\r\n\t* [render](#template_render)\r\n\t* [caching and devmode](#caching_and_devmode)\r\n* [sitemaps](#sitemaps)\r\n\t* [generating](#sitemap_generate)\r\n\t* [metadata](#sitemap_metadata)\r\n* [json schema](#json_schema)\r\n\t* [generating schema](#generating_schema)\r\n\t* [validating json](#validating_json)\r\n\t* [web service descriptions](#web_service_descriptions)\r\n* [reflection](#reflection)\r\n\t* [reflect everything](#reflect_everything)\r\n\t* [reflect specific types](#reflect_specific_types)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [appex.d.ts declaration](#appex_declaration)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n* [license](#license)\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline creating appex applications and configuration.\r\n\r\n<a name=\"application\" />\r\n### create a application\r\n\r\nThe following code will create a standalone appex application and \r\nhttp server and listen on port 3000.\r\n\r\n```javascript\r\nvar appex   = require('appex');\r\n\r\nvar app   = appex({ program : './program.ts', \r\n                    devmode : true,\r\n                    logging : true });\r\n\r\napp.listen(3000);\r\n```\r\n\r\nnote: devmode and logging are optional. however, when developing \r\nwith appex, it is helpful to have these enabled.\r\n\r\n<a name=\"options\" />\r\n### start up options\r\n\r\nappex accepts the following start up options.\r\n\r\n```javascript\r\nvar options = {\r\n\r\n\t// (required) location of source file.\r\n\tprogram    : './program.ts', \r\n\r\n\t// (optional) recompile on request. (default:false) \r\n\tdevmode    : true,          \r\n\r\n\t// (optional) log to stdout. (default:false) \r\n\tlogging    : true,\r\n\r\n\t// (optional) user defined objects added to the app context.\r\n\tcontext    : {}\r\n};\r\n\r\nvar app = appex( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### running on an existing http server\r\n\r\nThe following demonstrates setting up appex on an existing nodejs http server. In \r\nthis example, appex will attempt to handle incoming requests, and if appex cannot\r\nroute the request, will fire the callback.\r\n\r\n```javascript\r\nvar http  = require('http');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\nvar server = http.createServer(function(req, res){\r\n\r\n    app(req, res, function() { // appex handler...\r\n\t\t\r\n\t\t// not handled.\r\n\r\n\t}); \r\n});\r\n\r\nserver.listen(3000);\r\n```\r\n\r\n<a name=\"express_middleware\" />\r\n### running as express middleware\r\n\r\nappex allows developers to augment existing express / connect applications by \r\nway of middleware. The following demonstrates setting up appex as express middleware.\r\n\r\n```javascript\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) ); \r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nLike in the \"running on an existing http server\" example above, appex will attempt to intercept incoming requests. \r\nif appex cannot find a matching route for the request, it will automatically call the \"next\" function to pass the request \r\non to the next middleware or express handler.\r\n\r\nin addition to this, appex may also act as traditional express middleware. In the example below, a appex wildcard\r\nfunction is created which will match \"all\" incoming requests, the wildcard function simply prints hello world to \r\nthe console and then calls context.next(), which passes the request on the express handler.\r\n\r\n```javascript\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tconsole.log('hello world!!');\r\n\r\n\tcontext.next(); // pass it on!\r\n}\r\n\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) );\r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nJust like traditional express middleware, appex will also inheriate the characteristics of the request.\r\n\r\nconsider the following example in which the jade view engine is configured for use. appex will inheritate the \r\nresponse.render() method, which is passed to the appex handler as context.response.render()\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\napp.configure(function(){\r\n\r\n  app.set('views', __dirname + '/views');\r\n  \r\n  // set up the jade engine.\r\n  app.set('view engine', 'jade'); \r\n  \r\n  // bind appex\r\n  app.use( appex({program:'./program.ts', devmode:true} ));  \r\n});\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/\r\nexport function index(context) {\r\n\t\r\n\t// jade renderer works!\r\n\tcontext.response.render('index', { title: 'Express' }); \r\n}\r\n```\r\n\r\n<a name=\"http_handlers\" />\r\n## http handlers\r\n\r\nThe following sections describe how to create http accessible handlers with appex.\r\n\r\n<a name=\"app_context\" />\r\n### app context\r\n\r\nAll appex functions are passed a application context object as their first argument. The app context object \r\nencapulates the http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the app context\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.cascade    - appex cascade.\r\n\r\n\t// context.next       - the next function (express middleware)\r\n\t\r\n\t// context.router     - the appex router\r\n\r\n\t// context.sitemap    - the appex sitemap api\r\n\r\n\t// context.template   - the appex template engine.\r\n\t\r\n\t// context.module     - the module being run (this module)\r\n\r\n\t// context.schema     - json schema api.\r\n\r\n\t// context.mime       - a http mime type utility.\r\n}\r\n```\r\n\r\nit is possible to extend the default objects passed on the context by adding them on the appex startup options. The \r\nfollowing will attach the async module to the context. \r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = appex({ program : './program.ts', \r\n\t\t\t\t  devmode : true, \r\n\t\t\t      context: {\r\n\t\t\t\t\t\tasync : require('async')\r\n\t\t\t\t  }});\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\r\n\t// context.async = passed on the context.\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n```\r\n<a name=\"routing_handlers\" />\r\n### routing handlers\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context) { /* handle route */ }\r\n}\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/(.*)\r\nexport function wildcard (context, path) { /* handle route */ }\r\n\r\n```\r\n\r\n<a name=\"handler_signatures\" />\r\n### handler signatures\r\n\r\nappex supports three function signatures for http routing (named, index and wildcard). Functions that\r\ndo not apply these signatures will not be routed.\r\n\r\n<a name=\"named_handlers\" />\r\n### named handlers\r\n\r\nNamed handlers resolve urls to their current module scope + the name of the function.\r\n\r\nNamed handlers require the following signature:\r\n\r\n* name        - 'anything'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n\r\n// http://[host]:[port]/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about page');\r\n}\r\n\r\n// http://[host]:[port]/users/login\r\nexport module users {\r\n\r\n\texport function login(context) {\r\n\t\t\r\n\t\tcontext.response.send('handle login');\t\r\n\t}\r\n}\r\n\r\n```\r\n\r\n<a name=\"index_handlers\" />\r\n### index handlers\r\n\r\nIndex handlers resolve urls to their current module scope.\r\n\r\nIndex handlers require the following signature:\r\n\r\n* name        - 'index'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) \r\n\t{\t\r\n\t\tcontext.response.send('blog index');\r\n\t}\r\n}\r\n```\r\n\r\n<a name=\"wildcard_handlers\" />\r\n### wildcard handlers\r\n\r\nWildcard handlers resolve their urls to their current module scope + url.\r\n\r\nappex wildcard handlers allow for wildcard routing at a given module scope. Wildcard handlers\r\nsupport 'typed' url argument mapping, as denoted by the arguments annotation.\r\n\r\nIn addition, wildcard handlers also support optional arguments which can be specified with TypeScript's '?' \r\non argument names.\r\n\r\nappex wildcard handlers require the following signature:\r\n\r\n* name        - 'wildcard'\r\n* argument[0] - app context\r\n* argument[n] - 1 or more arguments to be mapped from the url\r\n* returns     - void (optional)\r\n\r\n```javascript\r\ndeclare var console;\r\n\r\nexport module blogs {\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11   - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/11  - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/3rd - not matched - (see number annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01     - matched     - (see ? annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013        - not matched - (month is required)\r\n\t\r\n    export function wildcard(context, year:number, month:number, day?:number) {\r\n\r\n        context.response.json({ year: year, month: month, day: day})\r\n    }\r\n}\r\n\r\n// url : http://[host]:[port]/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// url : http://[host]:[port]/(.*) \r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, 'not found');\r\n}\r\n\r\n```\r\nnote: appex supports boolean, number, string and any annotations on wildcard arguments. if no annotation\r\nis specified, appex interprets the argument as a string. the type 'any' is also interpreted as string.\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"cascades\" />\r\n### cascades\r\n\r\nappex supports a cascading attribute scheme on modules and functions. With this, developers can apply\r\narbituary meta data for modules and functions that will propagate through scope. appex has two special\r\ncascade properties for middleware and http verb matching, which are described below, however consider\r\nthe following code which illustrates the concept.\r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ncascade({a: 10}); // global.\r\n\r\ncascade('foo', {b : 20})\r\nexport module foo {\r\n\r\n    cascade('foo.bar', {c : 30})\r\n    export module bar {\r\n            \r\n        cascade('foo.bar.index', {d : 40})\r\n        export function index(context) {\r\n        \r\n            //context.cascade\r\n            //{\r\n            //    \"a\": 10,\r\n            //    \"b\": 20,\r\n            //    \"c\": 30,\r\n\t\t\t//    \"d\": 40\r\n            //}\r\n\r\n            context.response.json( context.cascade );       \r\n        }\r\n    }\r\n}\r\n\r\n```\r\n\r\n<a name=\"http_verbs\" />\r\n### http verbs\r\n\r\nappex handles http verb matching with cascades. appex will recognise the \r\n'verbs' property applied to the cascade to match against http verbs.\r\n\r\n```javascript\r\ncascade('index', { verbs: ['get'] })\r\nexport function index (context) { \r\n        \r\n    // only allow HTTP GET requests\r\n    context.response.send('index')\r\n}\r\n\r\ncascade('index', { verbs: ['post', 'put'] })\r\nexport function submit (context) { \r\n    \r\n    // only allow HTTP POST and PUT requests\r\n    context.response.send('submit')\r\n}\r\n```\r\n\r\n\r\n<a name=\"middleware\" />\r\n### middleware\r\n\r\nappex supports middleware with cascades. appex middleware defined with cascades allows\r\ndevelopers to scope middleware on single functions, or entire module scopes. appex will \r\nrecognise the 'use' property applied to the cascade to invoke middleware.\r\n\r\nthe following demonstrates how one might use middleware to secure a site admin.\r\n\r\nnote: middleware 'must' call next or handle the request. \r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ndeclare var console;\r\n\r\nfunction authenticate(context) {\r\n\r\n    console.log('authenticate')\r\n\r\n\t// call next() if authenticated, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\nfunction authorize(context) {\r\n\r\n    console.log('authorize')\r\n\r\n\t// call next() if authorized, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\n// apply security middleware to admin scope.\r\ncascade('admin', {use: [authenticate, authorize]}) \r\nexport module admin {\r\n\r\n    export function index(context) {\r\n        \r\n        console.log(context.cascade); // view cascade\r\n\r\n        context.response.send('access granted!')\r\n    }\r\n}\r\n\r\n// index handler has no middleware applied.\r\nexport function index (context) { \r\n    \r\n    console.log(context.cascade); // view cascade\r\n\r\n    context.response.send('home')\r\n}\r\n```\r\n\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex will only route functions prefixed with the TypeScript 'export' declarer. This rule\r\nalso applied to modules. Developers can use this to infer notions of public and private \r\nat the http level.\r\n\r\nconsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is \r\n// therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private \r\n\t// as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is \r\n\t// private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and \r\n// is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore \r\n// publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke \r\n\t// private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in \r\n\t// private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method \r\n\t// in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.send('public_function');\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```javascript\r\n// http:[host]:[port]/\r\nexport function index (context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard (context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n<a name=\"serving_static_files\" />\r\n## serving static files\r\n\r\nUse wildcard functions with context.response.serve() to serve static content.\r\n\r\n```javascript\r\nexport module static {\r\n\t\r\n\t// http:[host]:[port]/static/(.*)\r\n\texport function wildcard(context, path) {\r\n\r\n\t\tcontext.response.serve('./static/', path);\r\n\t}\r\n}\r\n\r\n// http:[host]:[port]/\r\nexport function index (context) {\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n\r\n<a name=\"templating\" />\r\n## templating\r\n\r\nappex comes bundled with a built in template engine which is modelled on the Microsoft \r\nRazor templating engine. The following sections outline its use.\r\n\r\n<a name=\"template_overview\" />\r\n### overview\r\n\r\nThe appex template engine is available to all handlers by default. it is accessible\r\non the context.template property. the following is an example of its use.\r\n\r\n```\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n<ul>\r\n@for(var n in context.users) {\r\n\r\n\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t<li>@(context.users[n].name)</li>\r\n\t}\r\n}\r\n</ul>\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\t\r\n\tcontext.response.headers['Content-Type'] = 'text/html';\r\n\r\n    context.response.send(text);\r\n}\r\n\r\n```\r\n\r\n<a name=\"template_context\" />\r\n### context\r\n\r\neach template is passed a data context. this context allows the caller to \r\nsend data to the template for rendering. the context parameter is optional.\r\nthe example below is sending the users array to the template context for \r\nrendering.\r\n\r\n```\r\nexport function index(context) {\r\n\t\r\n    var users  = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    context.response.send(context.template.render('./view.txt', { users: users }));\r\n}\r\n```\r\n\r\n<a name=\"template_syntax\" />\r\n### syntax\r\n\r\nappex templates support the following statements and syntax\r\n\r\n#### if statement\r\n\r\nif statments are supported.\r\n\r\n```\r\n@if(expression) {\r\n\tsome content\r\n}\r\n\r\n@if(a > 10) {\r\n\tsome content\r\n}\r\n\r\n@(user.loggedin) {\r\n\t<span>welcome</span>\r\n}\r\n```\r\n\r\n#### for statement\r\n\r\nthe following for loops are supported.\r\n\r\n```\r\n@for(var i = i; i < 100; i++) {\r\n\t@(i)\r\n}\r\n\r\n@for(var n in list) {\r\n\t@(list[n])\r\n}\r\n```\r\n\r\n#### expressions\r\n\r\nwill emit the value contained.\r\n\r\n```\r\n@('hello world')\r\n\r\n@(123)\r\n\r\n@(some_variable)\r\n```\r\n\r\n#### code blocks\r\n\r\ncode blocks can be useful for adding template side rendering logic.\r\n\r\n```\r\n@{\r\n\tvar message = 'hello'\r\n}\r\n\r\n@(message)\r\n```\r\n\r\n#### comments\r\n```\r\n@*\r\n\tthis comment will not be rendered!\r\n*@\r\n```\r\n\r\n<a name=\"template_layouts_and_sections\" />\r\n### layouts and sections\r\n\r\nappex templates support template inheritance.\r\n\r\nconsider the following where layout.txt defines the sections 'header' and 'content' and the view.txt overrides\r\nthese sections with its own content.\r\n\r\n```\r\n//----------------------------------------------\r\n// layout.txt\r\n//----------------------------------------------\r\n\r\n<html>\r\n\r\n\t<head>\r\n\t\t\r\n\t\t@section header\r\n\r\n\t</head>\r\n\r\n\t<body>\r\n\r\n\t\t@section content {\r\n\t\t\r\n\t\t\t<span>some default content</span>\r\n\t\t\t\r\n\t\t}\r\n\r\n\t</body>\r\n\t\r\n</html>\r\n\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n@layout 'layout.txt'\r\n\r\n@section header {\r\n\r\n\t<title>my page</title>\r\n}\r\n\r\n@section content {\r\n\r\n\t<p>overriding the layout.txt content section.</p>\r\n\r\n\t<ul>\r\n\t@for(var n in context.users) {\r\n\r\n\t\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t\t<li>@(context.users[n].name)</li>\r\n\t\t}\r\n\t}\r\n\t</ul>\r\n}\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\r\n    context.response.send(text);\r\n}\r\n```\r\n\r\nnote : when specifying a layout, the view will only render content within\r\nthe layouts section placeholders. \r\n\r\n<a name=\"render\" />\r\n### render\r\n\r\nappex templates also allow for partial views with the @render statment. consider the following \r\nwhich renders the nav.txt file into the layout.txt file.\r\n\r\n```\r\n//----------------------------------------------\r\n// nav.txt\r\n//----------------------------------------------\r\n<ul>\r\n\t<li>home</li>\r\n\t<li>about</li>\r\n\t<li>contact</li>\r\n</ul>\r\n\r\n//----------------------------------------------\r\n// layout.txt\r\n//----------------------------------------------\r\n\r\n<html>\r\n\t<head>\r\n\t\t\r\n\t\t@section header\r\n\r\n\t</head>\r\n\r\n\t<body>\r\n\t\t\r\n\t\t@render 'nav.txt'\r\n\r\n\t\t@section content {\r\n\t\t\r\n\t\t\t<span>some default content</span>\r\n\t\t\t\r\n\t\t}\r\n\r\n\t</body>\r\n\t\r\n</html>\r\n\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n@layout 'layout.txt'\r\n\r\n@section header {\r\n\r\n\t<title>my page</title>\r\n}\r\n\r\n@section content {\r\n\r\n\t<p>overriding the layout.txt content section.</p>\r\n\r\n\t<ul>\r\n\t@for(var n in context.users) {\r\n\r\n\t\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t\t<li>@(context.users[n].name)</li>\r\n\t\t}\r\n\t}\r\n\t</ul>\r\n}\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\r\n    context.response.send(text);\r\n}\r\n```\r\n\r\n<a name=\"caching_and_devmode\" />\r\n### caching and devmode\r\n\r\nappex template content is not cached (the implementor is expected to handle their own caching)\r\nhowever the generated template code is. \r\n\r\nappex templates do inheriate the behaviour of the appex 'devmode' option. setting\r\ndevmode to 'true' will cause template code to be reloaded from disk and code generated with each \r\nrequest. setting devmode to false will load content from disk on first request, and \r\ncache the generated template code in memory for the lifetime of the application.\r\n\r\nin addition to this, a implementation where the devmode is false can override the caching \r\nbehaviour with the following.\r\n\r\n```javascript\r\nexport function index(context) {\r\n\r\n\t// manually override the template devmode option.\r\n\tcontext.template.option.devmode = true; \r\n\r\n\tcontext.response.send(context.template.render('./view.txt'))\r\n}\r\n```\r\n\r\n<a name=\"sitemaps\" />\r\n## sitemaps\r\n\r\nappex is able to derive sitemap metadata automatically from http endpoints created with\r\ntypescript modules and functions. This metadata is useful to generate sitemap.xml\r\nfiles, as well as helping to create site navigation links when combined a template\r\nengine.\r\n\r\n<a name=\"sitemap_generate\" />\r\n### generate sitemap\r\n\r\nappex sitemaps can be obtained from the context.sitemap property. \r\n\r\n```javascript\r\nexport function index(context) {\r\n\r\n\t// return all nodes in this site.\r\n\tcontext.response.json(context.sitemap)\r\n\r\n}\r\n```\r\n\r\nAdditionally, it may be helpful to isolate branches of the sitemap with the \r\ncontext.sitemap.get([qualifier]) function. as demonstrated below.\r\n\r\n```javascript\r\nexport module admin {\r\n\r\n\texport function index     (context) { }\r\n\r\n\texport function dashboard (context) { }\r\n\r\n\texport function content   (context) { }\r\n\r\n\texport module users {\r\n\r\n\t\texport function login(context) { }\r\n\r\n\t\texport function logout(context) { }\r\n\t}\r\n}\r\n\r\nexport function test(context) {\r\n\t\r\n\t// view all admin sitemap nodes\r\n\tcontext.response.json(context.sitemap.get('admin'))\r\n\r\n\t// view all admin.users sitemap nodes\r\n\t//context.response.json(context.sitemap.get('admin.users'))\r\n}\r\n```\r\n\r\n<a name=\"sitemap_metadata\" />\r\n### cascade metadata\r\n\r\neach sitemap node contains the cascade applied to the handler for which the node applies. With this\r\ndevelopers can apply custom metadata for a given node. as demonstrated below.\r\n\r\n```javascript\r\ndeclare var cascade;\r\n\r\ncascade({website:'http://mysite.com/'}) // global\r\n\r\ncascade('index', {title:'home page'})\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('index')\r\n}\r\n\r\ncascade('about', {title: 'about page'})\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about')\r\n}\r\n\r\ncascade('sitemap', {title: 'sitemap page'})\r\nexport function sitemap(context) {\r\n\r\n\tcontext.response.json(context.sitemap)\r\n}\r\n```\r\n\r\nvisiting /sitemap will output the following.\r\n\r\n```javascript\r\n{\r\n    \"name\": \"sitemap\",\r\n    \"nodes\": [\r\n        {\r\n            \"name\": \"index\",\r\n            \"urls\": [\r\n                \"/\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"home page\"\r\n        },\r\n        {\r\n            \"name\": \"about\",\r\n            \"urls\": [\r\n                \"/about\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"about page\"\r\n        },\r\n        {\r\n            \"name\": \"sitemap\",\r\n            \"urls\": [\r\n                \"/sitemap\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"sitemap page\"\r\n        }\r\n    ]\r\n}\r\n```\r\n\r\n<a name=\"json_schema\" />\r\n## json schema\r\n\r\nappex provides functionality for generating json schemas from TypeScript classes\r\nand interfaces as well as tools for validating json data.\r\n\r\n<a name=\"generating_schema\" />\r\n### generating schema\r\n\r\nThe following demonstrates generating json schema from the following class\r\nhierarchy.\r\n\r\n```javascript\r\nexport module model {\r\n\r\n    /** a product */\r\n    export class Product {\r\n        \r\n        /** the product name */\r\n        public name        : string;\r\n\r\n        /** the product description */\r\n        public description : string;\r\n\r\n        /** the product cost */\r\n        public cost        : number;\r\n    } \r\n\r\n    /** a order */\r\n    export class Order {\r\n        \r\n        /** the product being ordered */\r\n        public products  : Product;\r\n    }\r\n\r\n    /** a customer */\r\n    export class Customer {\r\n\r\n        /** the customers firstname */\r\n        public firstname  : string;\r\n\r\n        /** the customers lastname */\r\n        public lastname   : string;\r\n\r\n        /** orders made by this customer */\r\n        public orders     : Order[];\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.IContext) {\r\n\t\r\n\t// pass the fully qualified name of the type.\r\n    var schema = context.schema.generate('model.Customer');\r\n\r\n    context.response.json(schema);\r\n}\r\n```\r\n\r\nwhich generates the following json schema.\r\n\r\n```javascript\r\n{\r\n    \"id\": \"model.Customer\",\r\n    \"type\": \"object\",\r\n    \"description\": \"a customer\",\r\n    \"properties\": {\r\n        \"firstname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers firstname\",\r\n            \"required\": true\r\n        },\r\n        \"lastname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers lastname\",\r\n            \"required\": true\r\n        },\r\n        \"orders\": {\r\n            \"type\": \"array\",\r\n            \"items\": {\r\n                \"type\": {\r\n                    \"id\": \"model.Order\",\r\n                    \"type\": \"object\",\r\n                    \"description\": \"a order\",\r\n                    \"properties\": {\r\n                        \"products\": {\r\n                            \"id\": \"model.Product\",\r\n                            \"type\": \"object\",\r\n                            \"description\": \"a product\",\r\n                            \"properties\": {\r\n                                \"name\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product name\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"description\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product description\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"cost\": {\r\n                                    \"type\": \"number\",\r\n                                    \"description\": \"the product cost\",\r\n                                    \"required\": true\r\n                                }\r\n                            },\r\n                            \"required\": true\r\n                        }\r\n                    }\r\n                }\r\n            },\r\n            \"description\": \"orders made by this customer\",\r\n            \"required\": true\r\n        }\r\n    }\r\n}\r\n```\r\na quick note...\r\n\r\nwhen generating schema from classes:\r\n\r\n* only public class variables will be emitted.\r\n* all properties will be marked as \"required\".\r\n\r\nwhen generating schema from interfaces:\r\n\r\n* all properties will be emitted. \r\n* all properties will be marked as \"required\" unless modified with '?'.\r\n\r\n<a name=\"validating_schema\" />\r\n### validating json\r\n\r\nappex supports json schema validation from class and interface definitions. consider the following...\r\n\r\n```javascript\r\ninterface Customer {\r\n\r\n    firstname    : string;\r\n\r\n    lastname     : string;\r\n\r\n    age          : number;\r\n\r\n    emails       : string[];\r\n\r\n    option_a ?   : boolean; // optional\r\n\r\n    option_b ?   : boolean; // optional\r\n\r\n}\r\n\r\nexport function index(context) {\r\n\r\n    // a customer with invalid data.\r\n\r\n    var customer = {\r\n\r\n        firstname    : 'dave',\r\n\r\n        age          : '33',\r\n\r\n        emails       : [12345, 'dave@domain.com', true],\r\n\r\n        option_b     : 1,\r\n\r\n        option_c     : 1\r\n    }\r\n\r\n    // do validation.\r\n\r\n    var errors = context.schema.validate('Customer', customer);\r\n\r\n    if(errors) {\r\n\r\n        context.response.json(errors);\r\n    }\r\n}\r\n```\r\n\r\nwill output the following.\r\n\r\n```javascript\r\n[\r\n    {\r\n        \"message\": \"instance.lastname is required.\"\r\n    },\r\n    {\r\n        \"message\": \"instance.age is not a number\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[0] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[2] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_b is not a boolean\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_c unexpected property\"\r\n    }\r\n]\r\n```\r\n\r\n<a name=\"web_service_descriptions\">\r\n### web service descriptions\r\n\r\nFor those using appex for web services, developers can leverage appex json schema generation\r\nto generate endpoint metadata (think wsdl). Consider the following which leverages both appex \r\nschema generation and cascades to produce a metadata endpoint consumers of your\r\napi can use to see what data the endpoint http://example.com/customer/create accepts \r\nand returns.\r\n\r\n```javascript\r\nclass Request {\r\n\r\n    /** the customers firstname */\r\n    firstname : string;\r\n\r\n    /** the customers lastname */\r\n    lastname  : string;\r\n\r\n\t/** the customers lastname */\r\n}\r\n\r\nclass Response {\r\n\r\n    /** true on success  */\r\n    success:boolean;\r\n    \r\n    /** an array of validation errors  */\r\n    errors : string[];\r\n}\r\n\r\ncascade('metadata', {input  : 'Request', output : 'Response'})\r\nexport function metadata(context:appex.web.IContext) {\r\n\r\n    var metadata = {\r\n        \r\n\t\tendpoint : 'http://example.com/customer/create',\r\n\r\n        input    : context.schema.generate(context.cascade.input),\r\n\r\n        output   : context.schema.generate(context.cascade.output)\r\n    }\r\n\r\n    context.response.json(metadata)\r\n}\r\n```\r\n\r\nwhich outputs the following.\r\n\r\n```javascript\r\n{\r\n    \"endpoint\": \"http://example.com/customer/create\",\r\n    \"input\": {\r\n        \"id\": \"Request\",\r\n        \"type\": \"object\",\r\n        \"properties\": {\r\n            \"firstname\": {\r\n                \"type\": \"string\",\r\n                \"description\": \"the customers firstname\",\r\n                \"required\": true\r\n            },\r\n            \"lastname\": {\r\n                \"type\": \"string\",\r\n                \"description\": \"the customers lastname\",\r\n                \"required\": true\r\n            }\r\n        }\r\n    },\r\n    \"output\": {\r\n        \"id\": \"Response\",\r\n        \"type\": \"object\",\r\n        \"properties\": {\r\n            \"success\": {\r\n                \"type\": \"boolean\",\r\n                \"description\": \"true on success\",\r\n                \"required\": true\r\n            },\r\n            \"errors\": {\r\n                \"type\": \"array\",\r\n                \"description\": \"an array of validation errors\",\r\n                \"items\": {\r\n                    \"type\": \"string\"\r\n                },\r\n                \"required\": true\r\n            }\r\n        }\r\n    }\r\n}\r\n```\r\ntip: use the appex sitemap metadata to produce a metadata endpoint for all service methods \r\nin your application.\r\n\r\n\r\n<a name=\"reflection\" />\r\n## reflection\r\n\r\nappex provides a reflection api derived from TypeScript's type system that developers can \r\nleverage to reflect type information declared throughout their appex modules. \r\n\r\nthe following section outlines how to use the reflection api.\r\n\r\n<a name=\"reflect_everything\" />\r\n### reflect everything\r\n\r\nthe appex reflection api is passed on the context.module.reflection property and is available to all\r\nappex handler methods. The following code will JSON serialize everything declared in your appex\r\nproject and write it to the http response. \r\n\r\n```javascript\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection );\r\n}\r\n```\r\n\r\n<a name=\"reflect_specific_types\" />\r\n### reflect specific types\r\n\r\nIn typical scenarios, developers will want to leverage reflection meta data to generate\r\nservice contacts and client side models. the reflection api lets you access meta data \r\nfor the following types declared in your project. \r\n\r\n* modules\r\n* imports\r\n* classes\r\n* interfaces\r\n* functions\r\n* variables\r\n\r\nto access specific type metadata, use the reflection.get([qualifier]) method, as demonstrated below.\r\n\r\n```javascript\r\nexport module model {\r\n    \r\n    export class Customer {\r\n\r\n        public firstname   : string;\r\n\r\n        public lastname    : string;\r\n\r\n        public age         : number;\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('model.Customer') );\r\n}\r\n```\r\nand methods..\r\n\r\n```javascript\r\nfunction some_method(a:string, b:number, c?:boolean) : void { }\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_method') );\r\n}\r\n```\r\n\r\n....and variables...\r\n\r\n```javascript\r\nvar some_variable:number = 10;\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_variable') );\r\n}\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\nThis section outlines development with appex.\r\n\r\n<a name=\"appex_declaration\" />\r\n### appex.d.ts declaration\r\n\r\nIf you develop on a TypeScript complicant editor (one that supports TS 0.9), appex comes bundled\r\nwith a declaration file you can reference in your project. If installing appex via npm, your\r\nreference should be as follows.\r\n\r\n```javascript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nexport function index (context:appex.web.IContext) { \r\n    \r\n    context.response.send('hello');\r\n}\r\n\r\nexport function wildcard(context:appex.web.IContext, path:string) {\r\n\r\n    context.response.serve('./', path);\r\n}\r\n```\r\n\r\nBy referencing this in your project, you get the benefits of code completion and static type checking\r\nagainst both appex, and the nodejs core.\r\n\r\n![](https://raw.github.com/sinclairzx81/appex/master/artifacts/code-completion.jpg)\r\n\r\nAdditional declaration files may be obtained from [here](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex ({ program : './index.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"users.ts\" />\r\n/// <reference path=\"pages.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { context.response.send('users.login') }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { context.response.send('users.logout') }\r\n}\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { context.response.send('home') }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { context.response.send('about') }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { context.response.send('contact') }\r\n\r\nexport function wildcard (context, path) { context.response.send(404, ' not found') }\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"license\" />\r\n## license\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) 2013 Haydn Paterson (sinclair) <haydn.developer@gmail.com>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in\r\nall copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\nTHE SOFTWARE.\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"https://raw.github.com/sinclairzx81/appex/master/license.txt","type":"The MIT License (MIT)"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"develop nodejs web applications with typescript","directories":{},"dependencies":{"typescript.api":"0.6.1"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.6.0":{"name":"appex","version":"0.6.0","keywords":["typescript","web api","reflection","compiler","schema","templates","sitemap"],"author":{"name":"sinclair"},"_id":"appex@0.6.0","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"606c87483d5f20872489b8eef778e181f40c1f98","tarball":"https://registry.npmjs.org/appex/-/appex-0.6.0.tgz","integrity":"sha512-OXhiwyvR4DjjKWZC0Q4MmM6ntTvBkVTMqcCjbMjzVkgpVHXQR6S9EH4AVeegsZhiyT0kvcPqiZZbD4M005uQaQ==","signatures":[{"sig":"MEYCIQD10VFckTgtYkMBDaYMwk+0/kewW6aLmmewavpTerOP1QIhAL6Mgjwt2Y1PgL3ORB7ieDNEBkThtMzcJQeZIbMM6uWQ","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/artifacts/logo.jpg)\r\n\r\n### develop nodejs web applications with [typescript](http://www.typescriptlang.org/)\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http://localhost:3000/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// http://localhost:3000/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about');\r\n}\r\n\r\n// http://localhost:3000/(.*)\r\nexport function wildcard (context, path) {\r\n    \r\n    context.response.send(404, path + \" not found\");\r\n}\r\n\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n### contents\r\n\r\n* [getting started](#getting_started)\r\n\t* [create a application](#application)\r\n\t* [start up options](#options)\r\n\t* [running on an existing http server](#http_server)\r\n\t* [running as express middleware](#express_middleware)\r\n* [http handlers](#http_handlers)\r\n\t* [app context](#app_context)\r\n\t* [routing handlers](#routing_handlers)\r\n\t* [handler signatures](#handler_signatures)\r\n\t* [named handlers](#named_handlers)\r\n\t* [index handlers](#index_handlers)\r\n\t* [wildcard handlers](#wildcard_handlers)\r\n\t* [cascades](#cascades)\r\n\t* [http verbs](#http_verbs)\r\n\t* [middleware](#middleware)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [handling 404](#handling_404)\r\n\t* [serving static files](#serving_static_files)\r\n* [templating](#templating)\r\n\t* [overview](#template_overview)\r\n\t* [context](#template_context)\t\r\n\t* [syntax](#template_syntax)\r\n\t* [layouts and sections](#template_layouts_and_sections)\r\n\t* [render](#template_render)\r\n\t* [caching and devmode](#caching_and_devmode)\r\n* [sitemaps](#sitemaps)\r\n\t* [generating](#sitemap_generate)\r\n\t* [metadata](#sitemap_metadata)\r\n* [json schema](#json_schema)\r\n\t* [generating schema](#generating_schema)\r\n\t* [validating json](#validating_json)\r\n\t* [web service descriptions](#web_service_descriptions)\r\n* [reflection](#reflection)\r\n\t* [reflect everything](#reflect_everything)\r\n\t* [reflect specific types](#reflect_specific_types)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [appex.d.ts declaration](#appex_declaration)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n* [license](#license)\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline creating appex applications and configuration.\r\n\r\n<a name=\"application\" />\r\n### create a application\r\n\r\nThe following code will create a standalone appex application and \r\nhttp server and listen on port 3000.\r\n\r\n```javascript\r\nvar appex   = require('appex');\r\n\r\nvar app   = appex({ program : './program.ts', \r\n                    devmode : true,\r\n                    logging : true });\r\n\r\napp.listen(3000);\r\n```\r\n\r\nnote: devmode and logging are optional. however, when developing \r\nwith appex, it is helpful to have these enabled.\r\n\r\n<a name=\"options\" />\r\n### start up options\r\n\r\nappex accepts the following start up options.\r\n\r\n```javascript\r\nvar options = {\r\n\r\n\t// (required) location of source file.\r\n\tprogram    : './program.ts', \r\n\r\n\t// (optional) recompile on request. (default:false) \r\n\tdevmode    : true,          \r\n\r\n\t// (optional) log to stdout. (default:false) \r\n\tlogging    : true,\r\n\r\n\t// (optional) user defined objects added to the app context.\r\n\tcontext    : {}\r\n};\r\n\r\nvar app = appex( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### running on an existing http server\r\n\r\nThe following demonstrates setting up appex on an existing nodejs http server. In \r\nthis example, appex will attempt to handle incoming requests, and if appex cannot\r\nroute the request, will fire the callback.\r\n\r\n```javascript\r\nvar http  = require('http');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\nvar server = http.createServer(function(req, res){\r\n\r\n    app(req, res, function() { // appex handler...\r\n\t\t\r\n\t\t// not handled.\r\n\r\n\t}); \r\n});\r\n\r\nserver.listen(3000);\r\n```\r\n\r\n<a name=\"express_middleware\" />\r\n### running as express middleware\r\n\r\nappex allows developers to augment existing express / connect applications by \r\nway of middleware. The following demonstrates setting up appex as express middleware.\r\n\r\n```javascript\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) ); \r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nLike in the \"running on an existing http server\" example above, appex will attempt to intercept incoming requests. \r\nif appex cannot find a matching route for the request, it will automatically call the \"next\" function to pass the request \r\non to the next middleware or express handler.\r\n\r\nin addition to this, appex may also act as traditional express middleware. In the example below, a appex wildcard\r\nfunction is created which will match \"all\" incoming requests, the wildcard function simply prints hello world to \r\nthe console and then calls context.next(), which passes the request on the express handler.\r\n\r\n```javascript\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tconsole.log('hello world!!');\r\n\r\n\tcontext.next(); // pass it on!\r\n}\r\n\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) );\r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nJust like traditional express middleware, appex will also inheriate the characteristics of the request.\r\n\r\nconsider the following example in which the jade view engine is configured for use. appex will inheritate the \r\nresponse.render() method, which is passed to the appex handler as context.response.render()\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\napp.configure(function(){\r\n\r\n  app.set('views', __dirname + '/views');\r\n  \r\n  // set up the jade engine.\r\n  app.set('view engine', 'jade'); \r\n  \r\n  // bind appex\r\n  app.use( appex({program:'./program.ts', devmode:true} ));  \r\n});\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/\r\nexport function index(context) {\r\n\t\r\n\t// jade renderer works!\r\n\tcontext.response.render('index', { title: 'Express' }); \r\n}\r\n```\r\n\r\n<a name=\"http_handlers\" />\r\n## http handlers\r\n\r\nThe following sections describe how to create http accessible handlers with appex.\r\n\r\n<a name=\"app_context\" />\r\n### app context\r\n\r\nAll appex functions are passed a application context object as their first argument. The app context object \r\nencapulates the http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the app context\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.cascade    - appex cascade.\r\n\r\n\t// context.next       - the next function (express middleware)\r\n\t\r\n\t// context.router     - the appex router\r\n\r\n\t// context.sitemap    - the appex sitemap api\r\n\r\n\t// context.template   - the appex template engine.\r\n\t\r\n\t// context.module     - the module being run (this module)\r\n\r\n\t// context.schema     - json schema api.\r\n\r\n\t// context.mime       - a http mime type utility.\r\n}\r\n```\r\n\r\nit is possible to extend the default objects passed on the context by adding them on the appex startup options. The \r\nfollowing will attach the async module to the context. \r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = appex({ program : './program.ts', \r\n\t\t\t\t  devmode : true, \r\n\t\t\t      context: {\r\n\t\t\t\t\t\tasync : require('async')\r\n\t\t\t\t  }});\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\r\n\t// context.async = passed on the context.\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n```\r\n<a name=\"routing_handlers\" />\r\n### routing handlers\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context) { /* handle route */ }\r\n}\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/(.*)\r\nexport function wildcard (context, path) { /* handle route */ }\r\n\r\n```\r\n\r\n<a name=\"handler_signatures\" />\r\n### handler signatures\r\n\r\nappex supports three function signatures for http routing (named, index and wildcard). Functions that\r\ndo not apply these signatures will not be routed.\r\n\r\n<a name=\"named_handlers\" />\r\n### named handlers\r\n\r\nNamed handlers resolve urls to their current module scope + the name of the function.\r\n\r\nNamed handlers require the following signature:\r\n\r\n* name        - 'anything'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n\r\n// http://[host]:[port]/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about page');\r\n}\r\n\r\n// http://[host]:[port]/users/login\r\nexport module users {\r\n\r\n\texport function login(context) {\r\n\t\t\r\n\t\tcontext.response.send('handle login');\t\r\n\t}\r\n}\r\n\r\n```\r\n\r\n<a name=\"index_handlers\" />\r\n### index handlers\r\n\r\nIndex handlers resolve urls to their current module scope.\r\n\r\nIndex handlers require the following signature:\r\n\r\n* name        - 'index'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) \r\n\t{\t\r\n\t\tcontext.response.send('blog index');\r\n\t}\r\n}\r\n```\r\n\r\n<a name=\"wildcard_handlers\" />\r\n### wildcard handlers\r\n\r\nWildcard handlers resolve their urls to their current module scope + url.\r\n\r\nappex wildcard handlers allow for wildcard routing at a given module scope. Wildcard handlers\r\nsupport 'typed' url argument mapping, as denoted by the arguments annotation.\r\n\r\nIn addition, wildcard handlers also support optional arguments which can be specified with TypeScript's '?' \r\non argument names.\r\n\r\nappex wildcard handlers require the following signature:\r\n\r\n* name        - 'wildcard'\r\n* argument[0] - app context\r\n* argument[n] - 1 or more arguments to be mapped from the url\r\n* returns     - void (optional)\r\n\r\n```javascript\r\ndeclare var console;\r\n\r\nexport module blogs {\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11   - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/11  - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/3rd - not matched - (see number annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01     - matched     - (see ? annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013        - not matched - (month is required)\r\n\t\r\n    export function wildcard(context, year:number, month:number, day?:number) {\r\n\r\n        context.response.json({ year: year, month: month, day: day})\r\n    }\r\n}\r\n\r\n// url : http://[host]:[port]/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// url : http://[host]:[port]/(.*) \r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, 'not found');\r\n}\r\n\r\n```\r\nnote: appex supports boolean, number, string and any annotations on wildcard arguments. if no annotation\r\nis specified, appex interprets the argument as a string. the type 'any' is also interpreted as string.\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"cascades\" />\r\n### cascades\r\n\r\nappex supports a cascading attribute scheme on modules and functions. With this, developers can apply\r\narbituary meta data for modules and functions that will propagate through scope. appex has two special\r\ncascade properties for middleware and http verb matching, which are described below, however consider\r\nthe following code which illustrates the concept.\r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ncascade({a: 10}); // global.\r\n\r\ncascade('foo', {b : 20})\r\nexport module foo {\r\n\r\n    cascade('foo.bar', {c : 30})\r\n    export module bar {\r\n            \r\n        cascade('foo.bar.index', {d : 40})\r\n        export function index(context) {\r\n        \r\n            //context.cascade\r\n            //{\r\n            //    \"a\": 10,\r\n            //    \"b\": 20,\r\n            //    \"c\": 30,\r\n\t\t\t//    \"d\": 40\r\n            //}\r\n\r\n            context.response.json( context.cascade );       \r\n        }\r\n    }\r\n}\r\n\r\n```\r\n\r\n<a name=\"http_verbs\" />\r\n### http verbs\r\n\r\nappex handles http verb matching with cascades. appex will recognise the \r\n'verbs' property applied to the cascade to match against http verbs.\r\n\r\n```javascript\r\ncascade('index', { verbs: ['get'] })\r\nexport function index (context) { \r\n        \r\n    // only allow HTTP GET requests\r\n    context.response.send('index')\r\n}\r\n\r\ncascade('index', { verbs: ['post', 'put'] })\r\nexport function submit (context) { \r\n    \r\n    // only allow HTTP POST and PUT requests\r\n    context.response.send('submit')\r\n}\r\n```\r\n\r\n\r\n<a name=\"middleware\" />\r\n### middleware\r\n\r\nappex supports middleware with cascades. appex middleware defined with cascades allows\r\ndevelopers to scope middleware on single functions, or entire module scopes. appex will \r\nrecognise the 'use' property applied to the cascade to invoke middleware.\r\n\r\nthe following demonstrates how one might use middleware to secure a site admin.\r\n\r\nnote: middleware 'must' call next or handle the request. \r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ndeclare var console;\r\n\r\nfunction authenticate(context) {\r\n\r\n    console.log('authenticate')\r\n\r\n\t// call next() if authenticated, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\nfunction authorize(context) {\r\n\r\n    console.log('authorize')\r\n\r\n\t// call next() if authorized, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\n// apply security middleware to admin scope.\r\ncascade('admin', {use: [authenticate, authorize]}) \r\nexport module admin {\r\n\r\n    export function index(context) {\r\n        \r\n        console.log(context.cascade); // view cascade\r\n\r\n        context.response.send('access granted!')\r\n    }\r\n}\r\n\r\n// index handler has no middleware applied.\r\nexport function index (context) { \r\n    \r\n    console.log(context.cascade); // view cascade\r\n\r\n    context.response.send('home')\r\n}\r\n```\r\n\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex will only route functions prefixed with the TypeScript 'export' declarer. This rule\r\nalso applied to modules. Developers can use this to infer notions of public and private \r\nat the http level.\r\n\r\nconsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is \r\n// therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private \r\n\t// as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is \r\n\t// private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and \r\n// is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore \r\n// publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke \r\n\t// private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in \r\n\t// private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method \r\n\t// in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.send('public_function');\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```javascript\r\n// http:[host]:[port]/\r\nexport function index (context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard (context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n<a name=\"serving_static_files\" />\r\n## serving static files\r\n\r\nUse wildcard functions with context.response.serve() to serve static content.\r\n\r\n```javascript\r\nexport module static {\r\n\t\r\n\t// http:[host]:[port]/static/(.*)\r\n\texport function wildcard(context, path) {\r\n\r\n\t\tcontext.response.serve('./static/', path);\r\n\t}\r\n}\r\n\r\n// http:[host]:[port]/\r\nexport function index (context) {\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n\r\n<a name=\"templating\" />\r\n## templating\r\n\r\nappex comes bundled with a built in template engine which is modelled on the Microsoft \r\nRazor templating engine. The following sections outline its use.\r\n\r\n<a name=\"template_overview\" />\r\n### overview\r\n\r\nThe appex template engine is available to all handlers by default. it is accessible\r\non the context.template property. the following is an example of its use.\r\n\r\n```\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n<ul>\r\n@for(var n in context.users) {\r\n\r\n\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t<li>@(context.users[n].name)</li>\r\n\t}\r\n}\r\n</ul>\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\t\r\n\tcontext.response.headers['Content-Type'] = 'text/html';\r\n\r\n    context.response.send(text);\r\n}\r\n\r\n```\r\n\r\n<a name=\"template_context\" />\r\n### context\r\n\r\neach template is passed a data context. this context allows the caller to \r\nsend data to the template for rendering. the context parameter is optional.\r\nthe example below is sending the users array to the template context for \r\nrendering.\r\n\r\n```\r\nexport function index(context) {\r\n\t\r\n    var users  = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    context.response.send(context.template.render('./view.txt', { users: users }));\r\n}\r\n```\r\n\r\n<a name=\"template_syntax\" />\r\n### syntax\r\n\r\nappex templates support the following statements and syntax\r\n\r\n#### if statement\r\n\r\nif statments are supported.\r\n\r\n```\r\n@if(expression) {\r\n\tsome content\r\n}\r\n\r\n@if(a > 10) {\r\n\tsome content\r\n}\r\n\r\n@(user.loggedin) {\r\n\t<span>welcome</span>\r\n}\r\n```\r\n\r\n#### for statement\r\n\r\nthe following for loops are supported.\r\n\r\n```\r\n@for(var i = i; i < 100; i++) {\r\n\t@(i)\r\n}\r\n\r\n@for(var n in list) {\r\n\t@(list[n])\r\n}\r\n```\r\n\r\n#### expressions\r\n\r\nwill emit the value contained.\r\n\r\n```\r\n@('hello world')\r\n\r\n@(123)\r\n\r\n@(some_variable)\r\n```\r\n\r\n#### code blocks\r\n\r\ncode blocks can be useful for adding template side rendering logic.\r\n\r\n```\r\n@{\r\n\tvar message = 'hello'\r\n}\r\n\r\n@(message)\r\n```\r\n\r\n#### comments\r\n```\r\n@*\r\n\tthis comment will not be rendered!\r\n*@\r\n```\r\n\r\n<a name=\"template_layouts_and_sections\" />\r\n### layouts and sections\r\n\r\nappex templates support template inheritance.\r\n\r\nconsider the following where layout.txt defines the sections 'header' and 'content' and the view.txt overrides\r\nthese sections with its own content.\r\n\r\n```\r\n//----------------------------------------------\r\n// layout.txt\r\n//----------------------------------------------\r\n\r\n<html>\r\n\r\n\t<head>\r\n\t\t\r\n\t\t@section header\r\n\r\n\t</head>\r\n\r\n\t<body>\r\n\r\n\t\t@section content {\r\n\t\t\r\n\t\t\t<span>some default content</span>\r\n\t\t\t\r\n\t\t}\r\n\r\n\t</body>\r\n\t\r\n</html>\r\n\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n@layout 'layout.txt'\r\n\r\n@section header {\r\n\r\n\t<title>my page</title>\r\n}\r\n\r\n@section content {\r\n\r\n\t<p>overriding the layout.txt content section.</p>\r\n\r\n\t<ul>\r\n\t@for(var n in context.users) {\r\n\r\n\t\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t\t<li>@(context.users[n].name)</li>\r\n\t\t}\r\n\t}\r\n\t</ul>\r\n}\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\r\n    context.response.send(text);\r\n}\r\n```\r\n\r\nnote : when specifying a layout, the view will only render content within\r\nthe layouts section placeholders. \r\n\r\n<a name=\"render\" />\r\n### render\r\n\r\nappex templates also allow for partial views with the @render statment. consider the following \r\nwhich renders the nav.txt file into the layout.txt file.\r\n\r\n```\r\n//----------------------------------------------\r\n// nav.txt\r\n//----------------------------------------------\r\n<ul>\r\n\t<li>home</li>\r\n\t<li>about</li>\r\n\t<li>contact</li>\r\n</ul>\r\n\r\n//----------------------------------------------\r\n// layout.txt\r\n//----------------------------------------------\r\n\r\n<html>\r\n\t<head>\r\n\t\t\r\n\t\t@section header\r\n\r\n\t</head>\r\n\r\n\t<body>\r\n\t\t\r\n\t\t@render 'nav.txt'\r\n\r\n\t\t@section content {\r\n\t\t\r\n\t\t\t<span>some default content</span>\r\n\t\t\t\r\n\t\t}\r\n\r\n\t</body>\r\n\t\r\n</html>\r\n\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n@layout 'layout.txt'\r\n\r\n@section header {\r\n\r\n\t<title>my page</title>\r\n}\r\n\r\n@section content {\r\n\r\n\t<p>overriding the layout.txt content section.</p>\r\n\r\n\t<ul>\r\n\t@for(var n in context.users) {\r\n\r\n\t\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t\t<li>@(context.users[n].name)</li>\r\n\t\t}\r\n\t}\r\n\t</ul>\r\n}\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\r\n    context.response.send(text);\r\n}\r\n```\r\n\r\n<a name=\"caching_and_devmode\" />\r\n### caching and devmode\r\n\r\nappex template content is not cached (the implementor is expected to handle their own caching)\r\nhowever the generated template code is. \r\n\r\nappex templates do inheriate the behaviour of the appex 'devmode' option. setting\r\ndevmode to 'true' will cause template code to be reloaded from disk and code generated with each \r\nrequest. setting devmode to false will load content from disk on first request, and \r\ncache the generated template code in memory for the lifetime of the application.\r\n\r\nin addition to this, a implementation where the devmode is false can override the caching \r\nbehaviour with the following.\r\n\r\n```javascript\r\nexport function index(context) {\r\n\r\n\t// manually override the template devmode option.\r\n\tcontext.template.option.devmode = true; \r\n\r\n\tcontext.response.send(context.template.render('./view.txt'))\r\n}\r\n```\r\n\r\n<a name=\"sitemaps\" />\r\n## sitemaps\r\n\r\nappex is able to derive sitemap metadata automatically from http endpoints created with\r\ntypescript modules and functions. This metadata is useful to generate sitemap.xml\r\nfiles, as well as helping to create site navigation links when combined a template\r\nengine.\r\n\r\n<a name=\"sitemap_generate\" />\r\n### generate sitemap\r\n\r\nappex sitemaps can be obtained from the context.sitemap property. \r\n\r\n```javascript\r\nexport function index(context) {\r\n\r\n\t// return all nodes in this site.\r\n\tcontext.response.json(context.sitemap)\r\n\r\n}\r\n```\r\n\r\nAdditionally, it may be helpful to isolate branches of the sitemap with the \r\ncontext.sitemap.get([qualifier]) function. as demonstrated below.\r\n\r\n```javascript\r\nexport module admin {\r\n\r\n\texport function index     (context) { }\r\n\r\n\texport function dashboard (context) { }\r\n\r\n\texport function content   (context) { }\r\n\r\n\texport module users {\r\n\r\n\t\texport function login(context) { }\r\n\r\n\t\texport function logout(context) { }\r\n\t}\r\n}\r\n\r\nexport function test(context) {\r\n\t\r\n\t// view all admin sitemap nodes\r\n\tcontext.response.json(context.sitemap.get('admin'))\r\n\r\n\t// view all admin.users sitemap nodes\r\n\t//context.response.json(context.sitemap.get('admin.users'))\r\n}\r\n```\r\n\r\n<a name=\"sitemap_metadata\" />\r\n### cascade metadata\r\n\r\neach sitemap node contains the cascade applied to the handler for which the node applies. With this\r\ndevelopers can apply custom metadata for a given node. as demonstrated below.\r\n\r\n```javascript\r\ndeclare var cascade;\r\n\r\ncascade({website:'http://mysite.com/'}) // global\r\n\r\ncascade('index', {title:'home page'})\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('index')\r\n}\r\n\r\ncascade('about', {title: 'about page'})\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about')\r\n}\r\n\r\ncascade('sitemap', {title: 'sitemap page'})\r\nexport function sitemap(context) {\r\n\r\n\tcontext.response.json(context.sitemap)\r\n}\r\n```\r\n\r\nvisiting /sitemap will output the following.\r\n\r\n```javascript\r\n{\r\n    \"name\": \"sitemap\",\r\n    \"nodes\": [\r\n        {\r\n            \"name\": \"index\",\r\n            \"urls\": [\r\n                \"/\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"home page\"\r\n        },\r\n        {\r\n            \"name\": \"about\",\r\n            \"urls\": [\r\n                \"/about\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"about page\"\r\n        },\r\n        {\r\n            \"name\": \"sitemap\",\r\n            \"urls\": [\r\n                \"/sitemap\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"sitemap page\"\r\n        }\r\n    ]\r\n}\r\n```\r\n\r\n<a name=\"json_schema\" />\r\n## json schema\r\n\r\nappex provides functionality for generating json schemas from TypeScript classes\r\nand interfaces as well as tools for validating json data.\r\n\r\n<a name=\"generating_schema\" />\r\n### generating schema\r\n\r\nThe following demonstrates generating json schema from the following class\r\nhierarchy.\r\n\r\n```javascript\r\nexport module model {\r\n\r\n    /** a product */\r\n    export class Product {\r\n        \r\n        /** the product name */\r\n        public name        : string;\r\n\r\n        /** the product description */\r\n        public description : string;\r\n\r\n        /** the product cost */\r\n        public cost        : number;\r\n    } \r\n\r\n    /** a order */\r\n    export class Order {\r\n        \r\n        /** the product being ordered */\r\n        public products  : Product;\r\n    }\r\n\r\n    /** a customer */\r\n    export class Customer {\r\n\r\n        /** the customers firstname */\r\n        public firstname  : string;\r\n\r\n        /** the customers lastname */\r\n        public lastname   : string;\r\n\r\n        /** orders made by this customer */\r\n        public orders     : Order[];\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.IContext) {\r\n\t\r\n\t// pass the fully qualified name of the type.\r\n    var schema = context.schema.generate('model.Customer');\r\n\r\n    context.response.json(schema);\r\n}\r\n```\r\n\r\nwhich generates the following json schema.\r\n\r\n```javascript\r\n{\r\n    \"id\": \"model.Customer\",\r\n    \"type\": \"object\",\r\n    \"description\": \"a customer\",\r\n    \"properties\": {\r\n        \"firstname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers firstname\",\r\n            \"required\": true\r\n        },\r\n        \"lastname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers lastname\",\r\n            \"required\": true\r\n        },\r\n        \"orders\": {\r\n            \"type\": \"array\",\r\n            \"items\": {\r\n                \"type\": {\r\n                    \"id\": \"model.Order\",\r\n                    \"type\": \"object\",\r\n                    \"description\": \"a order\",\r\n                    \"properties\": {\r\n                        \"products\": {\r\n                            \"id\": \"model.Product\",\r\n                            \"type\": \"object\",\r\n                            \"description\": \"a product\",\r\n                            \"properties\": {\r\n                                \"name\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product name\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"description\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product description\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"cost\": {\r\n                                    \"type\": \"number\",\r\n                                    \"description\": \"the product cost\",\r\n                                    \"required\": true\r\n                                }\r\n                            },\r\n                            \"required\": true\r\n                        }\r\n                    }\r\n                }\r\n            },\r\n            \"description\": \"orders made by this customer\",\r\n            \"required\": true\r\n        }\r\n    }\r\n}\r\n```\r\na quick note...\r\n\r\nwhen generating schema from classes:\r\n\r\n* only public class variables will be emitted.\r\n* all properties will be marked as \"required\".\r\n\r\nwhen generating schema from interfaces:\r\n\r\n* all properties will be emitted. \r\n* all properties will be marked as \"required\" unless modified with '?'.\r\n\r\n<a name=\"validating_schema\" />\r\n### validating json\r\n\r\nappex supports json schema validation from class and interface definitions. consider the following...\r\n\r\n```javascript\r\ninterface Customer {\r\n\r\n    firstname    : string;\r\n\r\n    lastname     : string;\r\n\r\n    age          : number;\r\n\r\n    emails       : string[];\r\n\r\n    option_a ?   : boolean; // optional\r\n\r\n    option_b ?   : boolean; // optional\r\n\r\n}\r\n\r\nexport function index(context) {\r\n\r\n    // a customer with invalid data.\r\n\r\n    var customer = {\r\n\r\n        firstname    : 'dave',\r\n\r\n        age          : '33',\r\n\r\n        emails       : [12345, 'dave@domain.com', true],\r\n\r\n        option_b     : 1,\r\n\r\n        option_c     : 1\r\n    }\r\n\r\n    // do validation.\r\n\r\n    var errors = context.schema.validate('Customer', customer);\r\n\r\n    if(errors) {\r\n\r\n        context.response.json(errors);\r\n    }\r\n}\r\n```\r\n\r\nwill output the following.\r\n\r\n```javascript\r\n[\r\n    {\r\n        \"message\": \"instance.lastname is required.\"\r\n    },\r\n    {\r\n        \"message\": \"instance.age is not a number\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[0] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[2] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_b is not a boolean\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_c unexpected property\"\r\n    }\r\n]\r\n```\r\n\r\n<a name=\"web_service_descriptions\">\r\n### web service descriptions\r\n\r\nFor those using appex for web services, developers can leverage appex json schema generation\r\nto generate endpoint metadata (think wsdl). Consider the following which leverages both appex \r\nschema generation and cascades to produce a metadata endpoint consumers of your\r\napi can use to see what data the endpoint http://example.com/customer/create accepts \r\nand returns.\r\n\r\n```javascript\r\nclass Request {\r\n\r\n    /** the customers firstname */\r\n    firstname : string;\r\n\r\n    /** the customers lastname */\r\n    lastname  : string;\r\n\r\n\t/** the customers lastname */\r\n}\r\n\r\nclass Response {\r\n\r\n    /** true on success  */\r\n    success:boolean;\r\n    \r\n    /** an array of validation errors  */\r\n    errors : string[];\r\n}\r\n\r\ncascade('metadata', {input  : 'Request', output : 'Response'})\r\nexport function metadata(context:appex.web.IContext) {\r\n\r\n    var metadata = {\r\n        \r\n\t\tendpoint : 'http://example.com/customer/create',\r\n\r\n        input    : context.schema.generate(context.cascade.input),\r\n\r\n        output   : context.schema.generate(context.cascade.output)\r\n    }\r\n\r\n    context.response.json(metadata)\r\n}\r\n```\r\n\r\nwhich outputs the following.\r\n\r\n```javascript\r\n{\r\n    \"endpoint\": \"http://example.com/customer/create\",\r\n    \"input\": {\r\n        \"id\": \"Request\",\r\n        \"type\": \"object\",\r\n        \"properties\": {\r\n            \"firstname\": {\r\n                \"type\": \"string\",\r\n                \"description\": \"the customers firstname\",\r\n                \"required\": true\r\n            },\r\n            \"lastname\": {\r\n                \"type\": \"string\",\r\n                \"description\": \"the customers lastname\",\r\n                \"required\": true\r\n            }\r\n        }\r\n    },\r\n    \"output\": {\r\n        \"id\": \"Response\",\r\n        \"type\": \"object\",\r\n        \"properties\": {\r\n            \"success\": {\r\n                \"type\": \"boolean\",\r\n                \"description\": \"true on success\",\r\n                \"required\": true\r\n            },\r\n            \"errors\": {\r\n                \"type\": \"array\",\r\n                \"description\": \"an array of validation errors\",\r\n                \"items\": {\r\n                    \"type\": \"string\"\r\n                },\r\n                \"required\": true\r\n            }\r\n        }\r\n    }\r\n}\r\n```\r\ntip: use the appex sitemap metadata to produce a metadata endpoint for all service methods \r\nin your application.\r\n\r\n\r\n<a name=\"reflection\" />\r\n## reflection\r\n\r\nappex provides a reflection api derived from TypeScript's type system that developers can \r\nleverage to reflect type information declared throughout their appex modules. \r\n\r\nthe following section outlines how to use the reflection api.\r\n\r\n<a name=\"reflect_everything\" />\r\n### reflect everything\r\n\r\nthe appex reflection api is passed on the context.module.reflection property and is available to all\r\nappex handler methods. The following code will JSON serialize everything declared in your appex\r\nproject and write it to the http response. \r\n\r\n```javascript\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection );\r\n}\r\n```\r\n\r\n<a name=\"reflect_specific_types\" />\r\n### reflect specific types\r\n\r\nIn typical scenarios, developers will want to leverage reflection meta data to generate\r\nservice contacts and client side models. the reflection api lets you access meta data \r\nfor the following types declared in your project. \r\n\r\n* modules\r\n* imports\r\n* classes\r\n* interfaces\r\n* functions\r\n* variables\r\n\r\nto access specific type metadata, use the reflection.get([qualifier]) method, as demonstrated below.\r\n\r\n```javascript\r\nexport module model {\r\n    \r\n    export class Customer {\r\n\r\n        public firstname   : string;\r\n\r\n        public lastname    : string;\r\n\r\n        public age         : number;\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('model.Customer') );\r\n}\r\n```\r\nand methods..\r\n\r\n```javascript\r\nfunction some_method(a:string, b:number, c?:boolean) : void { }\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_method') );\r\n}\r\n```\r\n\r\n....and variables...\r\n\r\n```javascript\r\nvar some_variable:number = 10;\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_variable') );\r\n}\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\nThis section outlines development with appex.\r\n\r\n<a name=\"appex_declaration\" />\r\n### appex.d.ts declaration\r\n\r\nIf you develop on a TypeScript complicant editor (one that supports TS 0.9), appex comes bundled\r\nwith a declaration file you can reference in your project. If installing appex via npm, your\r\nreference should be as follows.\r\n\r\n```javascript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nexport function index (context:appex.web.IContext) { \r\n    \r\n    context.response.send('hello');\r\n}\r\n\r\nexport function wildcard(context:appex.web.IContext, path:string) {\r\n\r\n    context.response.serve('./', path);\r\n}\r\n```\r\n\r\nBy referencing this in your project, you get the benefits of code completion and static type checking\r\nagainst both appex, and the nodejs core.\r\n\r\n![](https://raw.github.com/sinclairzx81/appex/master/artifacts/code-completion.jpg)\r\n\r\nAdditional declaration files may be obtained from [here](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex ({ program : './index.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"users.ts\" />\r\n/// <reference path=\"pages.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { context.response.send('users.login') }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { context.response.send('users.logout') }\r\n}\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { context.response.send('home') }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { context.response.send('about') }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { context.response.send('contact') }\r\n\r\nexport function wildcard (context, path) { context.response.send(404, ' not found') }\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"license\" />\r\n## license\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) 2013 Haydn Paterson (sinclair) <haydn.developer@gmail.com>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in\r\nall copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\nTHE SOFTWARE.\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"https://raw.github.com/sinclairzx81/appex/master/license.txt","type":"The MIT License (MIT)"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"develop nodejs web applications with typescript","directories":{},"dependencies":{"typescript.api":"0.7.0"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.6.1":{"name":"appex","version":"0.6.1","keywords":["typescript","web api","reflection","compiler","schema","templates","sitemap"],"author":{"name":"sinclair"},"_id":"appex@0.6.1","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"70ba5c7f167d7c7e4d1678fa70442252f513154b","tarball":"https://registry.npmjs.org/appex/-/appex-0.6.1.tgz","integrity":"sha512-BEtYh55hYCabYK8n+cLUqIuS4Pbhm1riWFGSMGsHw6r8PmD+paT88anuVcyNoMunOPBd6HCVOy+PLoLg/JZy6A==","signatures":[{"sig":"MEQCIDTKEgs2Ta92ewpI7Gv1uFyVoVrJZ06xVKbfGzLZjhVVAiAOrcRIVJO+gfr/WsxzEBZd198GE5BVuZqkKJXUmgTU+Q==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/artifacts/logo.jpg)\r\n\r\n### develop nodejs web applications with [typescript](http://www.typescriptlang.org/)\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http://localhost:3000/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// http://localhost:3000/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about');\r\n}\r\n\r\n// http://localhost:3000/(.*)\r\nexport function wildcard (context, path) {\r\n    \r\n    context.response.send(404, path + \" not found\");\r\n}\r\n\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n### contents\r\n\r\n* [getting started](#getting_started)\r\n\t* [create a application](#application)\r\n\t* [start up options](#options)\r\n\t* [running on an existing http server](#http_server)\r\n\t* [running as express middleware](#express_middleware)\r\n* [http handlers](#http_handlers)\r\n\t* [app context](#app_context)\r\n\t* [routing handlers](#routing_handlers)\r\n\t* [handler signatures](#handler_signatures)\r\n\t* [named handlers](#named_handlers)\r\n\t* [index handlers](#index_handlers)\r\n\t* [wildcard handlers](#wildcard_handlers)\r\n\t* [cascades](#cascades)\r\n\t* [http verbs](#http_verbs)\r\n\t* [middleware](#middleware)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [handling 404](#handling_404)\r\n\t* [serving static files](#serving_static_files)\r\n* [templating](#templating)\r\n\t* [overview](#template_overview)\r\n\t* [context](#template_context)\t\r\n\t* [syntax](#template_syntax)\r\n\t* [layouts and sections](#template_layouts_and_sections)\r\n\t* [render](#template_render)\r\n\t* [caching and devmode](#caching_and_devmode)\r\n* [sitemaps](#sitemaps)\r\n\t* [generating](#sitemap_generate)\r\n\t* [metadata](#sitemap_metadata)\r\n* [json schema](#json_schema)\r\n\t* [generating schema](#generating_schema)\r\n\t* [validating json](#validating_json)\r\n\t* [web service descriptions](#web_service_descriptions)\r\n* [reflection](#reflection)\r\n\t* [reflect everything](#reflect_everything)\r\n\t* [reflect specific types](#reflect_specific_types)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [appex.d.ts declaration](#appex_declaration)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n* [license](#license)\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline creating appex applications and configuration.\r\n\r\n<a name=\"application\" />\r\n### create a application\r\n\r\nThe following code will create a standalone appex application and \r\nhttp server and listen on port 3000.\r\n\r\n```javascript\r\nvar appex   = require('appex');\r\n\r\nvar app   = appex({ program : './program.ts', \r\n                    devmode : true,\r\n                    logging : true });\r\n\r\napp.listen(3000);\r\n```\r\n\r\nnote: devmode and logging are optional. however, when developing \r\nwith appex, it is helpful to have these enabled.\r\n\r\n<a name=\"options\" />\r\n### start up options\r\n\r\nappex accepts the following start up options.\r\n\r\n```javascript\r\nvar options = {\r\n\r\n\t// (required) location of source file.\r\n\tprogram    : './program.ts', \r\n\r\n\t// (optional) recompile on request. (default:false) \r\n\tdevmode    : true,          \r\n\r\n\t// (optional) log to stdout. (default:false) \r\n\tlogging    : true,\r\n\r\n\t// (optional) user defined objects added to the app context.\r\n\tcontext    : {}\r\n};\r\n\r\nvar app = appex( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### running on an existing http server\r\n\r\nThe following demonstrates setting up appex on an existing nodejs http server. In \r\nthis example, appex will attempt to handle incoming requests, and if appex cannot\r\nroute the request, will fire the callback.\r\n\r\n```javascript\r\nvar http  = require('http');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\nvar server = http.createServer(function(req, res){\r\n\r\n    app(req, res, function() { // appex handler...\r\n\t\t\r\n\t\t// not handled.\r\n\r\n\t}); \r\n});\r\n\r\nserver.listen(3000);\r\n```\r\n\r\n<a name=\"express_middleware\" />\r\n### running as express middleware\r\n\r\nappex allows developers to augment existing express / connect applications by \r\nway of middleware. The following demonstrates setting up appex as express middleware.\r\n\r\n```javascript\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) ); \r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nLike in the \"running on an existing http server\" example above, appex will attempt to intercept incoming requests. \r\nif appex cannot find a matching route for the request, it will automatically call the \"next\" function to pass the request \r\non to the next middleware or express handler.\r\n\r\nin addition to this, appex may also act as traditional express middleware. In the example below, a appex wildcard\r\nfunction is created which will match \"all\" incoming requests, the wildcard function simply prints hello world to \r\nthe console and then calls context.next(), which passes the request on the express handler.\r\n\r\n```javascript\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tconsole.log('hello world!!');\r\n\r\n\tcontext.next(); // pass it on!\r\n}\r\n\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) );\r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nJust like traditional express middleware, appex will also inheriate the characteristics of the request.\r\n\r\nconsider the following example in which the jade view engine is configured for use. appex will inheritate the \r\nresponse.render() method, which is passed to the appex handler as context.response.render()\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\napp.configure(function(){\r\n\r\n  app.set('views', __dirname + '/views');\r\n  \r\n  // set up the jade engine.\r\n  app.set('view engine', 'jade'); \r\n  \r\n  // bind appex\r\n  app.use( appex({program:'./program.ts', devmode:true} ));  \r\n});\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/\r\nexport function index(context) {\r\n\t\r\n\t// jade renderer works!\r\n\tcontext.response.render('index', { title: 'Express' }); \r\n}\r\n```\r\n\r\n<a name=\"http_handlers\" />\r\n## http handlers\r\n\r\nThe following sections describe how to create http accessible handlers with appex.\r\n\r\n<a name=\"app_context\" />\r\n### app context\r\n\r\nAll appex functions are passed a application context object as their first argument. The app context object \r\nencapulates the http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the app context\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.cascade    - appex cascade.\r\n\r\n\t// context.next       - the next function (express middleware)\r\n\t\r\n\t// context.router     - the appex router\r\n\r\n\t// context.sitemap    - the appex sitemap api\r\n\r\n\t// context.template   - the appex template engine.\r\n\t\r\n\t// context.module     - the module being run (this module)\r\n\r\n\t// context.schema     - json schema api.\r\n\r\n\t// context.mime       - a http mime type utility.\r\n}\r\n```\r\n\r\nit is possible to extend the default objects passed on the context by adding them on the appex startup options. The \r\nfollowing will attach the async module to the context. \r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = appex({ program : './program.ts', \r\n\t\t\t\t  devmode : true, \r\n\t\t\t      context: {\r\n\t\t\t\t\t\tasync : require('async')\r\n\t\t\t\t  }});\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\r\n\t// context.async = passed on the context.\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n```\r\n<a name=\"routing_handlers\" />\r\n### routing handlers\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context) { /* handle route */ }\r\n}\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/(.*)\r\nexport function wildcard (context, path) { /* handle route */ }\r\n\r\n```\r\n\r\n<a name=\"handler_signatures\" />\r\n### handler signatures\r\n\r\nappex supports three function signatures for http routing (named, index and wildcard). Functions that\r\ndo not apply these signatures will not be routed.\r\n\r\n<a name=\"named_handlers\" />\r\n### named handlers\r\n\r\nNamed handlers resolve urls to their current module scope + the name of the function.\r\n\r\nNamed handlers require the following signature:\r\n\r\n* name        - 'anything'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n\r\n// http://[host]:[port]/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about page');\r\n}\r\n\r\n// http://[host]:[port]/users/login\r\nexport module users {\r\n\r\n\texport function login(context) {\r\n\t\t\r\n\t\tcontext.response.send('handle login');\t\r\n\t}\r\n}\r\n\r\n```\r\n\r\n<a name=\"index_handlers\" />\r\n### index handlers\r\n\r\nIndex handlers resolve urls to their current module scope.\r\n\r\nIndex handlers require the following signature:\r\n\r\n* name        - 'index'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) \r\n\t{\t\r\n\t\tcontext.response.send('blog index');\r\n\t}\r\n}\r\n```\r\n\r\n<a name=\"wildcard_handlers\" />\r\n### wildcard handlers\r\n\r\nWildcard handlers resolve their urls to their current module scope + url.\r\n\r\nappex wildcard handlers allow for wildcard routing at a given module scope. Wildcard handlers\r\nsupport 'typed' url argument mapping, as denoted by the arguments annotation.\r\n\r\nIn addition, wildcard handlers also support optional arguments which can be specified with TypeScript's '?' \r\non argument names.\r\n\r\nappex wildcard handlers require the following signature:\r\n\r\n* name        - 'wildcard'\r\n* argument[0] - app context\r\n* argument[n] - 1 or more arguments to be mapped from the url\r\n* returns     - void (optional)\r\n\r\n```javascript\r\ndeclare var console;\r\n\r\nexport module blogs {\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11   - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/11  - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/3rd - not matched - (see number annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01     - matched     - (see ? annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013        - not matched - (month is required)\r\n\t\r\n    export function wildcard(context, year:number, month:number, day?:number) {\r\n\r\n        context.response.json({ year: year, month: month, day: day})\r\n    }\r\n}\r\n\r\n// url : http://[host]:[port]/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// url : http://[host]:[port]/(.*) \r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, 'not found');\r\n}\r\n\r\n```\r\nnote: appex supports boolean, number, string and any annotations on wildcard arguments. if no annotation\r\nis specified, appex interprets the argument as a string. the type 'any' is also interpreted as string.\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"cascades\" />\r\n### cascades\r\n\r\nappex supports a cascading attribute scheme on modules and functions. With this, developers can apply\r\narbituary meta data for modules and functions that will propagate through scope. appex has two special\r\ncascade properties for middleware and http verb matching, which are described below, however consider\r\nthe following code which illustrates the concept.\r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ncascade({a: 10}); // global.\r\n\r\ncascade('foo', {b : 20})\r\nexport module foo {\r\n\r\n    cascade('foo.bar', {c : 30})\r\n    export module bar {\r\n            \r\n        cascade('foo.bar.index', {d : 40})\r\n        export function index(context) {\r\n        \r\n            //context.cascade\r\n            //{\r\n            //    \"a\": 10,\r\n            //    \"b\": 20,\r\n            //    \"c\": 30,\r\n\t\t\t//    \"d\": 40\r\n            //}\r\n\r\n            context.response.json( context.cascade );       \r\n        }\r\n    }\r\n}\r\n\r\n```\r\n\r\n<a name=\"http_verbs\" />\r\n### http verbs\r\n\r\nappex handles http verb matching with cascades. appex will recognise the \r\n'verbs' property applied to the cascade to match against http verbs.\r\n\r\n```javascript\r\ncascade('index', { verbs: ['get'] })\r\nexport function index (context) { \r\n        \r\n    // only allow HTTP GET requests\r\n    context.response.send('index')\r\n}\r\n\r\ncascade('index', { verbs: ['post', 'put'] })\r\nexport function submit (context) { \r\n    \r\n    // only allow HTTP POST and PUT requests\r\n    context.response.send('submit')\r\n}\r\n```\r\n\r\n\r\n<a name=\"middleware\" />\r\n### middleware\r\n\r\nappex supports middleware with cascades. appex middleware defined with cascades allows\r\ndevelopers to scope middleware on single functions, or entire module scopes. appex will \r\nrecognise the 'use' property applied to the cascade to invoke middleware.\r\n\r\nthe following demonstrates how one might use middleware to secure a site admin.\r\n\r\nnote: middleware 'must' call next or handle the request. \r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ndeclare var console;\r\n\r\nfunction authenticate(context) {\r\n\r\n    console.log('authenticate')\r\n\r\n\t// call next() if authenticated, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\nfunction authorize(context) {\r\n\r\n    console.log('authorize')\r\n\r\n\t// call next() if authorized, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\n// apply security middleware to admin scope.\r\ncascade('admin', {use: [authenticate, authorize]}) \r\nexport module admin {\r\n\r\n    export function index(context) {\r\n        \r\n        console.log(context.cascade); // view cascade\r\n\r\n        context.response.send('access granted!')\r\n    }\r\n}\r\n\r\n// index handler has no middleware applied.\r\nexport function index (context) { \r\n    \r\n    console.log(context.cascade); // view cascade\r\n\r\n    context.response.send('home')\r\n}\r\n```\r\n\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex will only route functions prefixed with the TypeScript 'export' declarer. This rule\r\nalso applied to modules. Developers can use this to infer notions of public and private \r\nat the http level.\r\n\r\nconsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is \r\n// therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private \r\n\t// as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is \r\n\t// private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and \r\n// is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore \r\n// publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke \r\n\t// private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in \r\n\t// private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method \r\n\t// in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.send('public_function');\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```javascript\r\n// http:[host]:[port]/\r\nexport function index (context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard (context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n<a name=\"serving_static_files\" />\r\n## serving static files\r\n\r\nUse wildcard functions with context.response.serve() to serve static content.\r\n\r\n```javascript\r\nexport module static {\r\n\t\r\n\t// http:[host]:[port]/static/(.*)\r\n\texport function wildcard(context, path) {\r\n\r\n\t\tcontext.response.serve('./static/', path);\r\n\t}\r\n}\r\n\r\n// http:[host]:[port]/\r\nexport function index (context) {\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n\r\n<a name=\"templating\" />\r\n## templating\r\n\r\nappex comes bundled with a built in template engine which is modelled on the Microsoft \r\nRazor templating engine. The following sections outline its use.\r\n\r\n<a name=\"template_overview\" />\r\n### overview\r\n\r\nThe appex template engine is available to all handlers by default. it is accessible\r\non the context.template property. the following is an example of its use.\r\n\r\n```\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n<ul>\r\n@for(var n in context.users) {\r\n\r\n\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t<li>@(context.users[n].name)</li>\r\n\t}\r\n}\r\n</ul>\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\t\r\n\tcontext.response.headers['Content-Type'] = 'text/html';\r\n\r\n    context.response.send(text);\r\n}\r\n\r\n```\r\n\r\n<a name=\"template_context\" />\r\n### context\r\n\r\neach template is passed a data context. this context allows the caller to \r\nsend data to the template for rendering. the context parameter is optional.\r\nthe example below is sending the users array to the template context for \r\nrendering.\r\n\r\n```\r\nexport function index(context) {\r\n\t\r\n    var users  = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    context.response.send(context.template.render('./view.txt', { users: users }));\r\n}\r\n```\r\n\r\n<a name=\"template_syntax\" />\r\n### syntax\r\n\r\nappex templates support the following statements and syntax\r\n\r\n#### if statement\r\n\r\nif statments are supported.\r\n\r\n```\r\n@if(expression) {\r\n\tsome content\r\n}\r\n\r\n@if(a > 10) {\r\n\tsome content\r\n}\r\n\r\n@(user.loggedin) {\r\n\t<span>welcome</span>\r\n}\r\n```\r\n\r\n#### for statement\r\n\r\nthe following for loops are supported.\r\n\r\n```\r\n@for(var i = i; i < 100; i++) {\r\n\t@(i)\r\n}\r\n\r\n@for(var n in list) {\r\n\t@(list[n])\r\n}\r\n```\r\n\r\n#### expressions\r\n\r\nwill emit the value contained.\r\n\r\n```\r\n@('hello world')\r\n\r\n@(123)\r\n\r\n@(some_variable)\r\n```\r\n\r\n#### code blocks\r\n\r\ncode blocks can be useful for adding template side rendering logic.\r\n\r\n```\r\n@{\r\n\tvar message = 'hello'\r\n}\r\n\r\n@(message)\r\n```\r\n\r\n#### comments\r\n```\r\n@*\r\n\tthis comment will not be rendered!\r\n*@\r\n```\r\n\r\n<a name=\"template_layouts_and_sections\" />\r\n### layouts and sections\r\n\r\nappex templates support template inheritance.\r\n\r\nconsider the following where layout.txt defines the sections 'header' and 'content' and the view.txt overrides\r\nthese sections with its own content.\r\n\r\n```\r\n//----------------------------------------------\r\n// layout.txt\r\n//----------------------------------------------\r\n\r\n<html>\r\n\r\n\t<head>\r\n\t\t\r\n\t\t@section header\r\n\r\n\t</head>\r\n\r\n\t<body>\r\n\r\n\t\t@section content {\r\n\t\t\r\n\t\t\t<span>some default content</span>\r\n\t\t\t\r\n\t\t}\r\n\r\n\t</body>\r\n\t\r\n</html>\r\n\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n@layout 'layout.txt'\r\n\r\n@section header {\r\n\r\n\t<title>my page</title>\r\n}\r\n\r\n@section content {\r\n\r\n\t<p>overriding the layout.txt content section.</p>\r\n\r\n\t<ul>\r\n\t@for(var n in context.users) {\r\n\r\n\t\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t\t<li>@(context.users[n].name)</li>\r\n\t\t}\r\n\t}\r\n\t</ul>\r\n}\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\r\n    context.response.send(text);\r\n}\r\n```\r\n\r\nnote : when specifying a layout, the view will only render content within\r\nthe layouts section placeholders. \r\n\r\n<a name=\"render\" />\r\n### render\r\n\r\nappex templates also allow for partial views with the @render statment. consider the following \r\nwhich renders the nav.txt file into the layout.txt file.\r\n\r\n```\r\n//----------------------------------------------\r\n// nav.txt\r\n//----------------------------------------------\r\n<ul>\r\n\t<li>home</li>\r\n\t<li>about</li>\r\n\t<li>contact</li>\r\n</ul>\r\n\r\n//----------------------------------------------\r\n// layout.txt\r\n//----------------------------------------------\r\n\r\n<html>\r\n\t<head>\r\n\t\t\r\n\t\t@section header\r\n\r\n\t</head>\r\n\r\n\t<body>\r\n\t\t\r\n\t\t@render 'nav.txt'\r\n\r\n\t\t@section content {\r\n\t\t\r\n\t\t\t<span>some default content</span>\r\n\t\t\t\r\n\t\t}\r\n\r\n\t</body>\r\n\t\r\n</html>\r\n\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n@layout 'layout.txt'\r\n\r\n@section header {\r\n\r\n\t<title>my page</title>\r\n}\r\n\r\n@section content {\r\n\r\n\t<p>overriding the layout.txt content section.</p>\r\n\r\n\t<ul>\r\n\t@for(var n in context.users) {\r\n\r\n\t\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t\t<li>@(context.users[n].name)</li>\r\n\t\t}\r\n\t}\r\n\t</ul>\r\n}\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\r\n    context.response.send(text);\r\n}\r\n```\r\n\r\n<a name=\"caching_and_devmode\" />\r\n### caching and devmode\r\n\r\nappex template content is not cached (the implementor is expected to handle their own caching)\r\nhowever the generated template code is. \r\n\r\nappex templates do inheriate the behaviour of the appex 'devmode' option. setting\r\ndevmode to 'true' will cause template code to be reloaded from disk and code generated with each \r\nrequest. setting devmode to false will load content from disk on first request, and \r\ncache the generated template code in memory for the lifetime of the application.\r\n\r\nin addition to this, a implementation where the devmode is false can override the caching \r\nbehaviour with the following.\r\n\r\n```javascript\r\nexport function index(context) {\r\n\r\n\t// manually override the template devmode option.\r\n\tcontext.template.option.devmode = true; \r\n\r\n\tcontext.response.send(context.template.render('./view.txt'))\r\n}\r\n```\r\n\r\n<a name=\"sitemaps\" />\r\n## sitemaps\r\n\r\nappex is able to derive sitemap metadata automatically from http endpoints created with\r\ntypescript modules and functions. This metadata is useful to generate sitemap.xml\r\nfiles, as well as helping to create site navigation links when combined a template\r\nengine.\r\n\r\n<a name=\"sitemap_generate\" />\r\n### generate sitemap\r\n\r\nappex sitemaps can be obtained from the context.sitemap property. \r\n\r\n```javascript\r\nexport function index(context) {\r\n\r\n\t// return all nodes in this site.\r\n\tcontext.response.json(context.sitemap)\r\n\r\n}\r\n```\r\n\r\nAdditionally, it may be helpful to isolate branches of the sitemap with the \r\ncontext.sitemap.get([qualifier]) function. as demonstrated below.\r\n\r\n```javascript\r\nexport module admin {\r\n\r\n\texport function index     (context) { }\r\n\r\n\texport function dashboard (context) { }\r\n\r\n\texport function content   (context) { }\r\n\r\n\texport module users {\r\n\r\n\t\texport function login(context) { }\r\n\r\n\t\texport function logout(context) { }\r\n\t}\r\n}\r\n\r\nexport function test(context) {\r\n\t\r\n\t// view all admin sitemap nodes\r\n\tcontext.response.json(context.sitemap.get('admin'))\r\n\r\n\t// view all admin.users sitemap nodes\r\n\t//context.response.json(context.sitemap.get('admin.users'))\r\n}\r\n```\r\n\r\n<a name=\"sitemap_metadata\" />\r\n### cascade metadata\r\n\r\neach sitemap node contains the cascade applied to the handler for which the node applies. With this\r\ndevelopers can apply custom metadata for a given node. as demonstrated below.\r\n\r\n```javascript\r\ndeclare var cascade;\r\n\r\ncascade({website:'http://mysite.com/'}) // global\r\n\r\ncascade('index', {title:'home page'})\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('index')\r\n}\r\n\r\ncascade('about', {title: 'about page'})\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about')\r\n}\r\n\r\ncascade('sitemap', {title: 'sitemap page'})\r\nexport function sitemap(context) {\r\n\r\n\tcontext.response.json(context.sitemap)\r\n}\r\n```\r\n\r\nvisiting /sitemap will output the following.\r\n\r\n```javascript\r\n{\r\n    \"name\": \"sitemap\",\r\n    \"nodes\": [\r\n        {\r\n            \"name\": \"index\",\r\n            \"urls\": [\r\n                \"/\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"home page\"\r\n        },\r\n        {\r\n            \"name\": \"about\",\r\n            \"urls\": [\r\n                \"/about\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"about page\"\r\n        },\r\n        {\r\n            \"name\": \"sitemap\",\r\n            \"urls\": [\r\n                \"/sitemap\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"sitemap page\"\r\n        }\r\n    ]\r\n}\r\n```\r\n\r\n<a name=\"json_schema\" />\r\n## json schema\r\n\r\nappex provides functionality for generating json schemas from TypeScript classes\r\nand interfaces as well as tools for validating json data.\r\n\r\n<a name=\"generating_schema\" />\r\n### generating schema\r\n\r\nThe following demonstrates generating json schema from the following class\r\nhierarchy.\r\n\r\n```javascript\r\nexport module model {\r\n\r\n    /** a product */\r\n    export class Product {\r\n        \r\n        /** the product name */\r\n        public name        : string;\r\n\r\n        /** the product description */\r\n        public description : string;\r\n\r\n        /** the product cost */\r\n        public cost        : number;\r\n    } \r\n\r\n    /** a order */\r\n    export class Order {\r\n        \r\n        /** the product being ordered */\r\n        public products  : Product;\r\n    }\r\n\r\n    /** a customer */\r\n    export class Customer {\r\n\r\n        /** the customers firstname */\r\n        public firstname  : string;\r\n\r\n        /** the customers lastname */\r\n        public lastname   : string;\r\n\r\n        /** orders made by this customer */\r\n        public orders     : Order[];\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.IContext) {\r\n\t\r\n\t// pass the fully qualified name of the type.\r\n    var schema = context.schema.generate('model.Customer');\r\n\r\n    context.response.json(schema);\r\n}\r\n```\r\n\r\nwhich generates the following json schema.\r\n\r\n```javascript\r\n{\r\n    \"id\": \"model.Customer\",\r\n    \"type\": \"object\",\r\n    \"description\": \"a customer\",\r\n    \"properties\": {\r\n        \"firstname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers firstname\",\r\n            \"required\": true\r\n        },\r\n        \"lastname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers lastname\",\r\n            \"required\": true\r\n        },\r\n        \"orders\": {\r\n            \"type\": \"array\",\r\n            \"items\": {\r\n                \"type\": {\r\n                    \"id\": \"model.Order\",\r\n                    \"type\": \"object\",\r\n                    \"description\": \"a order\",\r\n                    \"properties\": {\r\n                        \"products\": {\r\n                            \"id\": \"model.Product\",\r\n                            \"type\": \"object\",\r\n                            \"description\": \"a product\",\r\n                            \"properties\": {\r\n                                \"name\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product name\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"description\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product description\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"cost\": {\r\n                                    \"type\": \"number\",\r\n                                    \"description\": \"the product cost\",\r\n                                    \"required\": true\r\n                                }\r\n                            },\r\n                            \"required\": true\r\n                        }\r\n                    }\r\n                }\r\n            },\r\n            \"description\": \"orders made by this customer\",\r\n            \"required\": true\r\n        }\r\n    }\r\n}\r\n```\r\na quick note...\r\n\r\nwhen generating schema from classes:\r\n\r\n* only public class variables will be emitted.\r\n* all properties will be marked as \"required\".\r\n\r\nwhen generating schema from interfaces:\r\n\r\n* all properties will be emitted. \r\n* all properties will be marked as \"required\" unless modified with '?'.\r\n\r\n<a name=\"validating_schema\" />\r\n### validating json\r\n\r\nappex supports json schema validation from class and interface definitions. consider the following...\r\n\r\n```javascript\r\ninterface Customer {\r\n\r\n    firstname    : string;\r\n\r\n    lastname     : string;\r\n\r\n    age          : number;\r\n\r\n    emails       : string[];\r\n\r\n    option_a ?   : boolean; // optional\r\n\r\n    option_b ?   : boolean; // optional\r\n\r\n}\r\n\r\nexport function index(context) {\r\n\r\n    // a customer with invalid data.\r\n\r\n    var customer = {\r\n\r\n        firstname    : 'dave',\r\n\r\n        age          : '33',\r\n\r\n        emails       : [12345, 'dave@domain.com', true],\r\n\r\n        option_b     : 1,\r\n\r\n        option_c     : 1\r\n    }\r\n\r\n    // do validation.\r\n\r\n    var errors = context.schema.validate('Customer', customer);\r\n\r\n    if(errors) {\r\n\r\n        context.response.json(errors);\r\n    }\r\n}\r\n```\r\n\r\nwill output the following.\r\n\r\n```javascript\r\n[\r\n    {\r\n        \"message\": \"instance.lastname is required.\"\r\n    },\r\n    {\r\n        \"message\": \"instance.age is not a number\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[0] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[2] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_b is not a boolean\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_c unexpected property\"\r\n    }\r\n]\r\n```\r\n\r\n<a name=\"web_service_descriptions\">\r\n### web service descriptions\r\n\r\nFor those using appex for web services, developers can leverage appex json schema generation\r\nto generate endpoint metadata (think wsdl). Consider the following which leverages both appex \r\nschema generation and cascades to produce a metadata endpoint consumers of your\r\napi can use to see what data the endpoint http://example.com/customer/create accepts \r\nand returns.\r\n\r\n```javascript\r\nclass Request {\r\n\r\n    /** the customers firstname */\r\n    firstname : string;\r\n\r\n    /** the customers lastname */\r\n    lastname  : string;\r\n\r\n\t/** the customers lastname */\r\n}\r\n\r\nclass Response {\r\n\r\n    /** true on success  */\r\n    success:boolean;\r\n    \r\n    /** an array of validation errors  */\r\n    errors : string[];\r\n}\r\n\r\ncascade('metadata', {input  : 'Request', output : 'Response'})\r\nexport function metadata(context:appex.web.IContext) {\r\n\r\n    var metadata = {\r\n        \r\n\t\tendpoint : 'http://example.com/customer/create',\r\n\r\n        input    : context.schema.generate(context.cascade.input),\r\n\r\n        output   : context.schema.generate(context.cascade.output)\r\n    }\r\n\r\n    context.response.json(metadata)\r\n}\r\n```\r\n\r\nwhich outputs the following.\r\n\r\n```javascript\r\n{\r\n    \"endpoint\": \"http://example.com/customer/create\",\r\n    \"input\": {\r\n        \"id\": \"Request\",\r\n        \"type\": \"object\",\r\n        \"properties\": {\r\n            \"firstname\": {\r\n                \"type\": \"string\",\r\n                \"description\": \"the customers firstname\",\r\n                \"required\": true\r\n            },\r\n            \"lastname\": {\r\n                \"type\": \"string\",\r\n                \"description\": \"the customers lastname\",\r\n                \"required\": true\r\n            }\r\n        }\r\n    },\r\n    \"output\": {\r\n        \"id\": \"Response\",\r\n        \"type\": \"object\",\r\n        \"properties\": {\r\n            \"success\": {\r\n                \"type\": \"boolean\",\r\n                \"description\": \"true on success\",\r\n                \"required\": true\r\n            },\r\n            \"errors\": {\r\n                \"type\": \"array\",\r\n                \"description\": \"an array of validation errors\",\r\n                \"items\": {\r\n                    \"type\": \"string\"\r\n                },\r\n                \"required\": true\r\n            }\r\n        }\r\n    }\r\n}\r\n```\r\ntip: use the appex sitemap metadata to produce a metadata endpoint for all service methods \r\nin your application.\r\n\r\n\r\n<a name=\"reflection\" />\r\n## reflection\r\n\r\nappex provides a reflection api derived from TypeScript's type system that developers can \r\nleverage to reflect type information declared throughout their appex modules. \r\n\r\nthe following section outlines how to use the reflection api.\r\n\r\n<a name=\"reflect_everything\" />\r\n### reflect everything\r\n\r\nthe appex reflection api is passed on the context.module.reflection property and is available to all\r\nappex handler methods. The following code will JSON serialize everything declared in your appex\r\nproject and write it to the http response. \r\n\r\n```javascript\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection );\r\n}\r\n```\r\n\r\n<a name=\"reflect_specific_types\" />\r\n### reflect specific types\r\n\r\nIn typical scenarios, developers will want to leverage reflection meta data to generate\r\nservice contacts and client side models. the reflection api lets you access meta data \r\nfor the following types declared in your project. \r\n\r\n* modules\r\n* imports\r\n* classes\r\n* interfaces\r\n* functions\r\n* variables\r\n\r\nto access specific type metadata, use the reflection.get([qualifier]) method, as demonstrated below.\r\n\r\n```javascript\r\nexport module model {\r\n    \r\n    export class Customer {\r\n\r\n        public firstname   : string;\r\n\r\n        public lastname    : string;\r\n\r\n        public age         : number;\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('model.Customer') );\r\n}\r\n```\r\nand methods..\r\n\r\n```javascript\r\nfunction some_method(a:string, b:number, c?:boolean) : void { }\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_method') );\r\n}\r\n```\r\n\r\n....and variables...\r\n\r\n```javascript\r\nvar some_variable:number = 10;\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_variable') );\r\n}\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\nThis section outlines development with appex.\r\n\r\n<a name=\"appex_declaration\" />\r\n### appex.d.ts declaration\r\n\r\nIf you develop on a TypeScript complicant editor (one that supports TS 0.9), appex comes bundled\r\nwith a declaration file you can reference in your project. If installing appex via npm, your\r\nreference should be as follows.\r\n\r\n```javascript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nexport function index (context:appex.web.IContext) { \r\n    \r\n    context.response.send('hello');\r\n}\r\n\r\nexport function wildcard(context:appex.web.IContext, path:string) {\r\n\r\n    context.response.serve('./', path);\r\n}\r\n```\r\n\r\nBy referencing this in your project, you get the benefits of code completion and static type checking\r\nagainst both appex, and the nodejs core.\r\n\r\n![](https://raw.github.com/sinclairzx81/appex/master/artifacts/code-completion.jpg)\r\n\r\nAdditional declaration files may be obtained from [here](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex ({ program : './index.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"users.ts\" />\r\n/// <reference path=\"pages.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { context.response.send('users.login') }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { context.response.send('users.logout') }\r\n}\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { context.response.send('home') }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { context.response.send('about') }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { context.response.send('contact') }\r\n\r\nexport function wildcard (context, path) { context.response.send(404, ' not found') }\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"license\" />\r\n## license\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) 2013 Haydn Paterson (sinclair) <haydn.developer@gmail.com>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in\r\nall copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\nTHE SOFTWARE.\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"https://raw.github.com/sinclairzx81/appex/master/license.txt","type":"The MIT License (MIT)"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"develop nodejs web applications with typescript","directories":{},"dependencies":{"typescript.api":"0.7.0"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.6.2":{"name":"appex","version":"0.6.2","keywords":["typescript","web api","reflection","compiler","schema","templates","sitemap"],"author":{"name":"sinclair"},"_id":"appex@0.6.2","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"48e6a46ecedb216d1076c3d1d1003196871e9079","tarball":"https://registry.npmjs.org/appex/-/appex-0.6.2.tgz","integrity":"sha512-GbM0qPQEZ30QO8dDnHYK4IsJIxem7ufdHYAGEMsD8iqMBvpR/jUdWINuGTOBkFOfwBTFsQBAX7gU6raeRqpCLA==","signatures":[{"sig":"MEQCIFxEdELTShZa7zMzrhhekjIvd888EDvfM/AYAyc4H0DRAiBZtI2gAS+hxAvIY8KwhxZeSn2VI2aJ93+Xm8M2Mqksmg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/artifacts/logo.jpg)\r\n\r\n### develop nodejs web applications with [typescript](http://www.typescriptlang.org/)\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\n// http://localhost:3000/\r\nexport function index(context:appex.web.IContext) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// http://localhost:3000/about\r\nexport function about(context:appex.web.IContext) {\r\n\r\n\tcontext.response.send('about');\r\n}\r\n\r\n// http://localhost:3000/(.*)\r\nexport function wildcard (context:appex.web.IContext, path:string) {\r\n    \r\n    context.response.send(404, path + \" not found\");\r\n}\r\n\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n### contents\r\n\r\n* [getting started](#getting_started)\r\n\t* [create a application](#application)\r\n\t* [start up options](#options)\r\n\t* [running on an existing http server](#http_server)\r\n\t* [running as express middleware](#express_middleware)\r\n* [http handlers](#http_handlers)\r\n\t* [app context](#app_context)\r\n\t* [request methods](#request_methods)\r\n\t* [response methods](#response_methods)\r\n\t* [routing handlers](#routing_handlers)\r\n\t* [handler signatures](#handler_signatures)\r\n\t* [named handlers](#named_handlers)\r\n\t* [index handlers](#index_handlers)\r\n\t* [wildcard handlers](#wildcard_handlers)\r\n\t* [cascades](#cascades)\r\n\t* [http verbs](#http_verbs)\r\n\t* [middleware](#middleware)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [handling 404](#handling_404)\r\n\t* [serving static files](#serving_static_files)\r\n* [templating](#templating)\r\n\t* [overview](#template_overview)\r\n\t* [context](#template_context)\t\r\n\t* [syntax](#template_syntax)\r\n\t* [layouts and sections](#template_layouts_and_sections)\r\n\t* [render](#template_render)\r\n\t* [caching and devmode](#caching_and_devmode)\r\n* [sitemaps](#sitemaps)\r\n\t* [generating](#sitemap_generate)\r\n\t* [metadata](#sitemap_metadata)\r\n* [json schema](#json_schema)\r\n\t* [generating schema](#generating_schema)\r\n\t* [validating json](#validating_json)\r\n\t* [web service descriptions](#web_service_descriptions)\r\n* [reflection](#reflection)\r\n\t* [reflect everything](#reflect_everything)\r\n\t* [reflect specific types](#reflect_specific_types)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [appex.d.ts declaration](#appex_declaration)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n* [license](#license)\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline creating appex applications and configuration.\r\n\r\n<a name=\"application\" />\r\n### create a application\r\n\r\nThe following code will create a standalone appex application and \r\nhttp server and listen on port 3000.\r\n\r\n```javascript\r\nvar appex   = require('appex');\r\n\r\nvar app   = appex({ program : './program.ts', \r\n                    devmode : true,\r\n                    logging : true });\r\n\r\napp.listen(3000);\r\n```\r\n\r\nnote: devmode and logging are optional. however, when developing \r\nwith appex, it is helpful to have these enabled.\r\n\r\n<a name=\"options\" />\r\n### start up options\r\n\r\nappex accepts the following start up options.\r\n\r\n```javascript\r\nvar options = {\r\n\r\n\t// (required) location of source file.\r\n\tprogram    : './program.ts', \r\n\r\n\t// (optional) recompile on request. (default:false) \r\n\tdevmode    : true,          \r\n\r\n\t// (optional) log to stdout. (default:false) \r\n\tlogging    : true,\r\n\r\n\t// (optional) user defined objects added to the app context.\r\n\tcontext    : {}\r\n};\r\n\r\nvar app = appex( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### running on an existing http server\r\n\r\nThe following demonstrates setting up appex on an existing nodejs http server. In \r\nthis example, appex will attempt to handle incoming requests, and if appex cannot\r\nroute the request, will fire the callback.\r\n\r\n```javascript\r\nvar http  = require('http');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\nvar server = http.createServer(function(req, res){\r\n\r\n    app(req, res, function() { // appex handler...\r\n\t\t\r\n\t\t// not handled.\r\n\r\n\t}); \r\n});\r\n\r\nserver.listen(3000);\r\n```\r\n\r\n<a name=\"express_middleware\" />\r\n### running as express middleware\r\n\r\nappex allows developers to augment existing express / connect applications by \r\nway of middleware. The following demonstrates setting up appex as express middleware.\r\n\r\n```javascript\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) ); \r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nLike in the \"running on an existing http server\" example above, appex will attempt to intercept incoming requests. \r\nif appex cannot find a matching route for the request, it will automatically call the \"next\" function to pass the request \r\non to the next middleware or express handler.\r\n\r\nin addition to this, appex may also act as traditional express middleware. In the example below, a appex wildcard\r\nfunction is created which will match \"all\" incoming requests, the wildcard function simply prints hello world to \r\nthe console and then calls context.next(), which passes the request on the express handler.\r\n\r\n```javascript\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tconsole.log('hello world!!');\r\n\r\n\tcontext.next(); // pass it on!\r\n}\r\n\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) );\r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nJust like traditional express middleware, appex will also inheriate the characteristics of the request.\r\n\r\nconsider the following example in which the jade view engine is configured for use. appex will inheritate the \r\nresponse.render() method, which is passed to the appex handler as context.response.render()\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\napp.configure(function(){\r\n\r\n  app.set('views', __dirname + '/views');\r\n  \r\n  // set up the jade engine.\r\n  app.set('view engine', 'jade'); \r\n  \r\n  // bind appex\r\n  app.use( appex({program:'./program.ts', devmode:true} ));  \r\n});\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/\r\nexport function index(context) {\r\n\t\r\n\t// jade renderer works!\r\n\tcontext.response.render('index', { title: 'Express' }); \r\n}\r\n```\r\n\r\n<a name=\"http_handlers\" />\r\n## http handlers\r\n\r\nThe following sections describe how to create http accessible handlers with appex.\r\n\r\n<a name=\"app_context\" />\r\n### app context\r\n\r\nAll appex functions are passed a application context object as their first argument. The app context object \r\nencapulates the http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the app context\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.cascade    - appex cascade.\r\n\r\n\t// context.next       - the next function (express middleware)\r\n\t\r\n\t// context.router     - the appex router\r\n\r\n\t// context.sitemap    - the appex sitemap api\r\n\r\n\t// context.template   - the appex template engine.\r\n\t\r\n\t// context.module     - the module being run (this module)\r\n\r\n\t// context.schema     - json schema api.\r\n\r\n\t// context.mime       - a http mime type utility.\r\n}\r\n```\r\n\r\nit is possible to extend the default objects passed on the context by adding them on the appex startup options. The \r\nfollowing will attach the async module to the context. \r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = appex({ program : './program.ts', \r\n\t\t\t\t  devmode : true, \r\n\t\t\t      context: {\r\n\t\t\t\t\t\tasync : require('async')\r\n\t\t\t\t  }});\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\r\n\t// context.async = passed on the context.\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n```\r\n<a name=\"request_methods\" />\r\n### request methods\r\n\r\nappex provides some utility methods for reading http request data. \r\n\r\nnote: if appex detects that express or connect middleware has already been applied\r\nto the request object, appex will use those instead.\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// receive request as a string\r\n//----------------------------------------------\r\nexport function submit(context) {\r\n\r\n\tcontext.request.body.recv((str) => {\r\n\r\n\t\t// do something with str\r\n\t})\r\n}\r\n```\r\n```javascript\r\n//----------------------------------------------\r\n// receive a form post\r\n//----------------------------------------------\r\nexport function submit(context) {\r\n\r\n\tcontext.request.body.post((obj) => {\r\n\r\n\t\t// do something with obj\r\n\t})\r\n}\r\n```\r\n```javascript\r\n//----------------------------------------------\r\n// receive a json post\r\n//----------------------------------------------\r\nexport function submit(context) {\r\n\r\n\tcontext.request.body.json((obj) => {\r\n\t\t\r\n\t\t// do something with obj\r\n\t})\r\n}\r\n```\r\n<a name=\"response_methods\" />\r\n### response methods\r\n\r\nappex provides some utility methods for writing http responses.\r\n\r\nnote: if appex detects that express or connect middleware has already been applied\r\nto for any of the following response methods, appex will use those instead.\r\n\r\n```js\r\n//----------------------------------------------\r\n// the nodejs response has been extended with the following\r\n// signatures.\r\n//----------------------------------------------\r\nexport interface IResponse extends http.ServerResponse {\r\n\r\n\tsend (data     : string): void;\r\n\r\n\tsend (data     : NodeBuffer): void;\r\n\r\n\tsend (status   : number, data : string): void;\r\n\r\n\tserve (filepath: string): void;\r\n\r\n\tserve (root : string, filepath: string): void;\r\n\r\n\tserve (root : string, filepath: string, mime:string): void;\r\n\r\n\tjson (obj      : any): void;\r\n\r\n\tjson (status   : number, obj : any): void;\r\n\r\n\tjsonp (obj     : any): void;\r\n\r\n\tjsonp (status  : number, obj : any): void;\r\n\r\n\tjsonp (status  : number, obj : any, callback: string): void;\r\n}\r\n```\r\n\r\n<a name=\"routing_handlers\" />\r\n### routing handlers\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context) { /* handle route */ }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context) { /* handle route */ }\r\n}\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context) { /* handle route */ }\r\n\r\n// url: http://[host]:[port]/(.*)\r\nexport function wildcard (context, path) { /* handle route */ }\r\n\r\n```\r\n\r\n<a name=\"handler_signatures\" />\r\n### handler signatures\r\n\r\nappex supports three function signatures for http routing (named, index and wildcard). Functions that\r\ndo not apply these signatures will not be routed.\r\n\r\n<a name=\"named_handlers\" />\r\n### named handlers\r\n\r\nNamed handlers resolve urls to their current module scope + the name of the function.\r\n\r\nNamed handlers require the following signature:\r\n\r\n* name        - 'anything'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n\r\n// http://[host]:[port]/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about page');\r\n}\r\n\r\n// http://[host]:[port]/users/login\r\nexport module users {\r\n\r\n\texport function login(context) {\r\n\t\t\r\n\t\tcontext.response.send('handle login');\t\r\n\t}\r\n}\r\n\r\n```\r\n\r\n<a name=\"index_handlers\" />\r\n### index handlers\r\n\r\nIndex handlers resolve urls to their current module scope.\r\n\r\nIndex handlers require the following signature:\r\n\r\n* name        - 'index'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) \r\n\t{\t\r\n\t\tcontext.response.send('blog index');\r\n\t}\r\n}\r\n```\r\n\r\n<a name=\"wildcard_handlers\" />\r\n### wildcard handlers\r\n\r\nWildcard handlers resolve their urls to their current module scope + url.\r\n\r\nappex wildcard handlers allow for wildcard routing at a given module scope. Wildcard handlers\r\nsupport 'typed' url argument mapping, as denoted by the arguments annotation.\r\n\r\nIn addition, wildcard handlers also support optional arguments which can be specified with TypeScript's '?' \r\non argument names.\r\n\r\nappex wildcard handlers require the following signature:\r\n\r\n* name        - 'wildcard'\r\n* argument[0] - app context\r\n* argument[n] - 1 or more arguments to be mapped from the url\r\n* returns     - void (optional)\r\n\r\n```javascript\r\ndeclare var console;\r\n\r\nexport module blogs {\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11   - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/11  - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/3rd - not matched - (see number annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01     - matched     - (see ? annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013        - not matched - (month is required)\r\n\t\r\n    export function wildcard(context, year:number, month:number, day?:number) {\r\n\r\n        context.response.json({ year: year, month: month, day: day})\r\n    }\r\n}\r\n\r\n// url : http://[host]:[port]/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// url : http://[host]:[port]/(.*) \r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, 'not found');\r\n}\r\n\r\n```\r\nnote: appex supports boolean, number, string and any annotations on wildcard arguments. if no annotation\r\nis specified, appex interprets the argument as a string. the type 'any' is also interpreted as string.\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"cascades\" />\r\n### cascades\r\n\r\nappex supports a cascading attribute scheme on modules and functions. With this, developers can apply\r\narbituary meta data for modules and functions that will propagate through scope. appex has two special\r\ncascade properties for middleware and http verb matching, which are described below, however consider\r\nthe following code which illustrates the concept.\r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ncascade({a: 10}); // global.\r\n\r\ncascade('foo', {b : 20})\r\nexport module foo {\r\n\r\n    cascade('foo.bar', {c : 30})\r\n    export module bar {\r\n            \r\n        cascade('foo.bar.index', {d : 40})\r\n        export function index(context) {\r\n        \r\n            //context.cascade\r\n            //{\r\n            //    \"a\": 10,\r\n            //    \"b\": 20,\r\n            //    \"c\": 30,\r\n\t\t\t//    \"d\": 40\r\n            //}\r\n\r\n            context.response.json( context.cascade );       \r\n        }\r\n    }\r\n}\r\n\r\n```\r\n\r\n<a name=\"http_verbs\" />\r\n### http verbs\r\n\r\nappex handles http verb matching with cascades. appex will recognise the \r\n'verbs' property applied to the cascade to match against http verbs.\r\n\r\n```javascript\r\ncascade('index', { verbs: ['get'] })\r\nexport function index (context) { \r\n        \r\n    // only allow HTTP GET requests\r\n    context.response.send('index')\r\n}\r\n\r\ncascade('index', { verbs: ['post', 'put'] })\r\nexport function submit (context) { \r\n    \r\n    // only allow HTTP POST and PUT requests\r\n    context.response.send('submit')\r\n}\r\n```\r\n\r\n\r\n<a name=\"middleware\" />\r\n### middleware\r\n\r\nappex supports middleware with cascades. appex middleware defined with cascades allows\r\ndevelopers to scope middleware on single functions, or entire module scopes. appex will \r\nrecognise the 'use' property applied to the cascade to invoke middleware.\r\n\r\nthe following demonstrates how one might use middleware to secure a site admin.\r\n\r\nnote: middleware 'must' call next or handle the request. \r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ndeclare var console;\r\n\r\nfunction authenticate(context) {\r\n\r\n    console.log('authenticate')\r\n\r\n\t// call next() if authenticated, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\nfunction authorize(context) {\r\n\r\n    console.log('authorize')\r\n\r\n\t// call next() if authorized, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\n// apply security middleware to admin scope.\r\ncascade('admin', {use: [authenticate, authorize]}) \r\nexport module admin {\r\n\r\n    export function index(context) {\r\n        \r\n        console.log(context.cascade); // view cascade\r\n\r\n        context.response.send('access granted!')\r\n    }\r\n}\r\n\r\n// index handler has no middleware applied.\r\nexport function index (context) { \r\n    \r\n    console.log(context.cascade); // view cascade\r\n\r\n    context.response.send('home')\r\n}\r\n```\r\n\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex will only route functions prefixed with the TypeScript 'export' declarer. This rule\r\nalso applied to modules. Developers can use this to infer notions of public and private \r\nat the http level.\r\n\r\nconsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is \r\n// therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private \r\n\t// as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is \r\n\t// private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and \r\n// is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore \r\n// publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke \r\n\t// private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in \r\n\t// private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method \r\n\t// in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.send('public_function');\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```javascript\r\n// http:[host]:[port]/\r\nexport function index (context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard (context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n<a name=\"serving_static_files\" />\r\n## serving static files\r\n\r\nUse wildcard functions with context.response.serve() to serve static content.\r\n\r\n```javascript\r\nexport module static {\r\n\t\r\n\t// http:[host]:[port]/static/(.*)\r\n\texport function wildcard(context, path) {\r\n\r\n\t\tcontext.response.serve('./static/', path);\r\n\t}\r\n}\r\n\r\n// http:[host]:[port]/\r\nexport function index (context) {\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n\r\n<a name=\"templating\" />\r\n## templating\r\n\r\nappex comes bundled with a built in template engine which is modelled on the Microsoft \r\nRazor templating engine. The following sections outline its use.\r\n\r\n<a name=\"template_overview\" />\r\n### overview\r\n\r\nThe appex template engine is available to all handlers by default. it is accessible\r\non the context.template property. the following is an example of its use.\r\n\r\n```\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n<ul>\r\n@for(var n in context.users) {\r\n\r\n\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t<li>@(context.users[n].name)</li>\r\n\t}\r\n}\r\n</ul>\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\t\r\n\tcontext.response.headers['Content-Type'] = 'text/html';\r\n\r\n    context.response.send(text);\r\n}\r\n\r\n```\r\n\r\n<a name=\"template_context\" />\r\n### context\r\n\r\neach template is passed a data context. this context allows the caller to \r\nsend data to the template for rendering. the context parameter is optional.\r\nthe example below is sending the users array to the template context for \r\nrendering.\r\n\r\n```\r\nexport function index(context) {\r\n\t\r\n    var users  = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    context.response.send(context.template.render('./view.txt', { users: users }));\r\n}\r\n```\r\n\r\n<a name=\"template_syntax\" />\r\n### syntax\r\n\r\nappex templates support the following statements and syntax\r\n\r\n#### if statement\r\n\r\nif statments are supported.\r\n\r\n```\r\n@if(expression) {\r\n\tsome content\r\n}\r\n\r\n@if(a > 10) {\r\n\tsome content\r\n}\r\n\r\n@(user.loggedin) {\r\n\t<span>welcome</span>\r\n}\r\n```\r\n\r\n#### for statement\r\n\r\nthe following for loops are supported.\r\n\r\n```\r\n@for(var i = i; i < 100; i++) {\r\n\t@(i)\r\n}\r\n\r\n@for(var n in list) {\r\n\t@(list[n])\r\n}\r\n```\r\n\r\n#### expressions\r\n\r\nwill emit the value contained.\r\n\r\n```\r\n@('hello world')\r\n\r\n@(123)\r\n\r\n@(some_variable)\r\n```\r\n\r\n#### code blocks\r\n\r\ncode blocks can be useful for adding template side rendering logic.\r\n\r\n```\r\n@{\r\n\tvar message = 'hello'\r\n}\r\n\r\n@(message)\r\n```\r\n\r\n#### comments\r\n```\r\n@*\r\n\tthis comment will not be rendered!\r\n*@\r\n```\r\n\r\n<a name=\"template_layouts_and_sections\" />\r\n### layouts and sections\r\n\r\nappex templates support template inheritance.\r\n\r\nconsider the following where layout.txt defines the sections 'header' and 'content' and the view.txt overrides\r\nthese sections with its own content.\r\n\r\n```\r\n//----------------------------------------------\r\n// layout.txt\r\n//----------------------------------------------\r\n\r\n<html>\r\n\r\n\t<head>\r\n\t\t\r\n\t\t@section header\r\n\r\n\t</head>\r\n\r\n\t<body>\r\n\r\n\t\t@section content {\r\n\t\t\r\n\t\t\t<span>some default content</span>\r\n\t\t\t\r\n\t\t}\r\n\r\n\t</body>\r\n\t\r\n</html>\r\n\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n@layout 'layout.txt'\r\n\r\n@section header {\r\n\r\n\t<title>my page</title>\r\n}\r\n\r\n@section content {\r\n\r\n\t<p>overriding the layout.txt content section.</p>\r\n\r\n\t<ul>\r\n\t@for(var n in context.users) {\r\n\r\n\t\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t\t<li>@(context.users[n].name)</li>\r\n\t\t}\r\n\t}\r\n\t</ul>\r\n}\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\r\n    context.response.send(text);\r\n}\r\n```\r\n\r\nnote : when specifying a layout, the view will only render content within\r\nthe layouts section placeholders. \r\n\r\n<a name=\"render\" />\r\n### render\r\n\r\nappex templates also allow for partial views with the @render statment. consider the following \r\nwhich renders the nav.txt file into the layout.txt file.\r\n\r\n```\r\n//----------------------------------------------\r\n// nav.txt\r\n//----------------------------------------------\r\n<ul>\r\n\t<li>home</li>\r\n\t<li>about</li>\r\n\t<li>contact</li>\r\n</ul>\r\n\r\n//----------------------------------------------\r\n// layout.txt\r\n//----------------------------------------------\r\n\r\n<html>\r\n\t<head>\r\n\t\t\r\n\t\t@section header\r\n\r\n\t</head>\r\n\r\n\t<body>\r\n\t\t\r\n\t\t@render 'nav.txt'\r\n\r\n\t\t@section content {\r\n\t\t\r\n\t\t\t<span>some default content</span>\r\n\t\t\t\r\n\t\t}\r\n\r\n\t</body>\r\n\t\r\n</html>\r\n\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n@layout 'layout.txt'\r\n\r\n@section header {\r\n\r\n\t<title>my page</title>\r\n}\r\n\r\n@section content {\r\n\r\n\t<p>overriding the layout.txt content section.</p>\r\n\r\n\t<ul>\r\n\t@for(var n in context.users) {\r\n\r\n\t\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t\t<li>@(context.users[n].name)</li>\r\n\t\t}\r\n\t}\r\n\t</ul>\r\n}\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\r\n    context.response.send(text);\r\n}\r\n```\r\n\r\n<a name=\"caching_and_devmode\" />\r\n### caching and devmode\r\n\r\nappex template content is not cached (the implementor is expected to handle their own caching)\r\nhowever the generated template code is. \r\n\r\nappex templates do inheriate the behaviour of the appex 'devmode' option. setting\r\ndevmode to 'true' will cause template code to be reloaded from disk and code generated with each \r\nrequest. setting devmode to false will load content from disk on first request, and \r\ncache the generated template code in memory for the lifetime of the application.\r\n\r\nin addition to this, a implementation where the devmode is false can override the caching \r\nbehaviour with the following.\r\n\r\n```javascript\r\nexport function index(context) {\r\n\r\n\t// manually override the template devmode option.\r\n\tcontext.template.option.devmode = true; \r\n\r\n\tcontext.response.send(context.template.render('./view.txt'))\r\n}\r\n```\r\n\r\n<a name=\"sitemaps\" />\r\n## sitemaps\r\n\r\nappex is able to derive sitemap metadata automatically from http endpoints created with\r\ntypescript modules and functions. This metadata is useful to generate sitemap.xml\r\nfiles, as well as helping to create site navigation links when combined a template\r\nengine.\r\n\r\n<a name=\"sitemap_generate\" />\r\n### generate sitemap\r\n\r\nappex sitemaps can be obtained from the context.sitemap property. \r\n\r\n```javascript\r\nexport function index(context) {\r\n\r\n\t// return all nodes in this site.\r\n\tcontext.response.json(context.sitemap)\r\n\r\n}\r\n```\r\n\r\nAdditionally, it may be helpful to isolate branches of the sitemap with the \r\ncontext.sitemap.get([qualifier]) function. as demonstrated below.\r\n\r\n```javascript\r\nexport module admin {\r\n\r\n\texport function index     (context) { }\r\n\r\n\texport function dashboard (context) { }\r\n\r\n\texport function content   (context) { }\r\n\r\n\texport module users {\r\n\r\n\t\texport function login(context) { }\r\n\r\n\t\texport function logout(context) { }\r\n\t}\r\n}\r\n\r\nexport function test(context) {\r\n\t\r\n\t// view all admin sitemap nodes\r\n\tcontext.response.json(context.sitemap.get('admin'))\r\n\r\n\t// view all admin.users sitemap nodes\r\n\t//context.response.json(context.sitemap.get('admin.users'))\r\n}\r\n```\r\n\r\n<a name=\"sitemap_metadata\" />\r\n### cascade metadata\r\n\r\neach sitemap node contains the cascade applied to the handler for which the node applies. With this\r\ndevelopers can apply custom metadata for a given node. as demonstrated below.\r\n\r\n```javascript\r\ndeclare var cascade;\r\n\r\ncascade({website:'http://mysite.com/'}) // global\r\n\r\ncascade('index', {title:'home page'})\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('index')\r\n}\r\n\r\ncascade('about', {title: 'about page'})\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about')\r\n}\r\n\r\ncascade('sitemap', {title: 'sitemap page'})\r\nexport function sitemap(context) {\r\n\r\n\tcontext.response.json(context.sitemap)\r\n}\r\n```\r\n\r\nvisiting /sitemap will output the following.\r\n\r\n```javascript\r\n{\r\n    \"name\": \"sitemap\",\r\n    \"nodes\": [\r\n        {\r\n            \"name\": \"index\",\r\n            \"urls\": [\r\n                \"/\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"home page\"\r\n        },\r\n        {\r\n            \"name\": \"about\",\r\n            \"urls\": [\r\n                \"/about\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"about page\"\r\n        },\r\n        {\r\n            \"name\": \"sitemap\",\r\n            \"urls\": [\r\n                \"/sitemap\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"sitemap page\"\r\n        }\r\n    ]\r\n}\r\n```\r\n\r\n<a name=\"json_schema\" />\r\n## json schema\r\n\r\nappex provides functionality for generating json schemas from TypeScript classes\r\nand interfaces as well as tools for validating json data.\r\n\r\n<a name=\"generating_schema\" />\r\n### generating schema\r\n\r\nThe following demonstrates generating json schema from the following class\r\nhierarchy.\r\n\r\n```javascript\r\nexport module model {\r\n\r\n    /** a product */\r\n    export class Product {\r\n        \r\n        /** the product name */\r\n        public name        : string;\r\n\r\n        /** the product description */\r\n        public description : string;\r\n\r\n        /** the product cost */\r\n        public cost        : number;\r\n    } \r\n\r\n    /** a order */\r\n    export class Order {\r\n        \r\n        /** the product being ordered */\r\n        public products  : Product;\r\n    }\r\n\r\n    /** a customer */\r\n    export class Customer {\r\n\r\n        /** the customers firstname */\r\n        public firstname  : string;\r\n\r\n        /** the customers lastname */\r\n        public lastname   : string;\r\n\r\n        /** orders made by this customer */\r\n        public orders     : Order[];\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.IContext) {\r\n\t\r\n\t// pass the fully qualified name of the type.\r\n    var schema = context.schema.generate('model.Customer');\r\n\r\n    context.response.json(schema);\r\n}\r\n```\r\n\r\nwhich generates the following json schema.\r\n\r\n```javascript\r\n{\r\n    \"id\": \"model.Customer\",\r\n    \"type\": \"object\",\r\n    \"description\": \"a customer\",\r\n    \"properties\": {\r\n        \"firstname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers firstname\",\r\n            \"required\": true\r\n        },\r\n        \"lastname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers lastname\",\r\n            \"required\": true\r\n        },\r\n        \"orders\": {\r\n            \"type\": \"array\",\r\n            \"items\": {\r\n                \"type\": {\r\n                    \"id\": \"model.Order\",\r\n                    \"type\": \"object\",\r\n                    \"description\": \"a order\",\r\n                    \"properties\": {\r\n                        \"products\": {\r\n                            \"id\": \"model.Product\",\r\n                            \"type\": \"object\",\r\n                            \"description\": \"a product\",\r\n                            \"properties\": {\r\n                                \"name\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product name\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"description\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product description\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"cost\": {\r\n                                    \"type\": \"number\",\r\n                                    \"description\": \"the product cost\",\r\n                                    \"required\": true\r\n                                }\r\n                            },\r\n                            \"required\": true\r\n                        }\r\n                    }\r\n                }\r\n            },\r\n            \"description\": \"orders made by this customer\",\r\n            \"required\": true\r\n        }\r\n    }\r\n}\r\n```\r\na quick note...\r\n\r\nwhen generating schema from classes:\r\n\r\n* only public class variables will be emitted.\r\n* all properties will be marked as \"required\".\r\n\r\nwhen generating schema from interfaces:\r\n\r\n* all properties will be emitted. \r\n* all properties will be marked as \"required\" unless modified with '?'.\r\n\r\n<a name=\"validating_schema\" />\r\n### validating json\r\n\r\nappex supports json schema validation from class and interface definitions. consider the following...\r\n\r\n```javascript\r\ninterface Customer {\r\n\r\n    firstname    : string;\r\n\r\n    lastname     : string;\r\n\r\n    age          : number;\r\n\r\n    emails       : string[];\r\n\r\n    option_a ?   : boolean; // optional\r\n\r\n    option_b ?   : boolean; // optional\r\n\r\n}\r\n\r\nexport function index(context) {\r\n\r\n    // a customer with invalid data.\r\n\r\n    var customer = {\r\n\r\n        firstname    : 'dave',\r\n\r\n        age          : '33',\r\n\r\n        emails       : [12345, 'dave@domain.com', true],\r\n\r\n        option_b     : 1,\r\n\r\n        option_c     : 1\r\n    }\r\n\r\n    // do validation.\r\n\r\n    var errors = context.schema.validate('Customer', customer);\r\n\r\n    if(errors) {\r\n\r\n        context.response.json(errors);\r\n    }\r\n}\r\n```\r\n\r\nwill output the following.\r\n\r\n```javascript\r\n[\r\n    {\r\n        \"message\": \"instance.lastname is required.\"\r\n    },\r\n    {\r\n        \"message\": \"instance.age is not a number\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[0] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[2] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_b is not a boolean\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_c unexpected property\"\r\n    }\r\n]\r\n```\r\n\r\n<a name=\"web_service_descriptions\">\r\n### web service descriptions\r\n\r\nFor those using appex for web services, developers can leverage appex json schema generation\r\nto generate endpoint metadata (think wsdl). Consider the following which leverages both appex \r\nschema generation and cascades to produce a metadata endpoint consumers of your\r\napi can use to see what data the endpoint http://example.com/customer/create accepts \r\nand returns.\r\n\r\n```javascript\r\nclass Request {\r\n\r\n    /** the customers firstname */\r\n    firstname : string;\r\n\r\n    /** the customers lastname */\r\n    lastname  : string;\r\n\r\n\t/** the customers lastname */\r\n}\r\n\r\nclass Response {\r\n\r\n    /** true on success  */\r\n    success:boolean;\r\n    \r\n    /** an array of validation errors  */\r\n    errors : string[];\r\n}\r\n\r\ncascade('metadata', {input  : 'Request', output : 'Response'})\r\nexport function metadata(context:appex.web.IContext) {\r\n\r\n    var metadata = {\r\n        \r\n\t\tendpoint : 'http://example.com/customer/create',\r\n\r\n        input    : context.schema.generate(context.cascade.input),\r\n\r\n        output   : context.schema.generate(context.cascade.output)\r\n    }\r\n\r\n    context.response.json(metadata)\r\n}\r\n```\r\n\r\nwhich outputs the following.\r\n\r\n```javascript\r\n{\r\n    \"endpoint\": \"http://example.com/customer/create\",\r\n    \"input\": {\r\n        \"id\": \"Request\",\r\n        \"type\": \"object\",\r\n        \"properties\": {\r\n            \"firstname\": {\r\n                \"type\": \"string\",\r\n                \"description\": \"the customers firstname\",\r\n                \"required\": true\r\n            },\r\n            \"lastname\": {\r\n                \"type\": \"string\",\r\n                \"description\": \"the customers lastname\",\r\n                \"required\": true\r\n            }\r\n        }\r\n    },\r\n    \"output\": {\r\n        \"id\": \"Response\",\r\n        \"type\": \"object\",\r\n        \"properties\": {\r\n            \"success\": {\r\n                \"type\": \"boolean\",\r\n                \"description\": \"true on success\",\r\n                \"required\": true\r\n            },\r\n            \"errors\": {\r\n                \"type\": \"array\",\r\n                \"description\": \"an array of validation errors\",\r\n                \"items\": {\r\n                    \"type\": \"string\"\r\n                },\r\n                \"required\": true\r\n            }\r\n        }\r\n    }\r\n}\r\n```\r\ntip: use the appex sitemap metadata to produce a metadata endpoint for all service methods \r\nin your application.\r\n\r\n\r\n<a name=\"reflection\" />\r\n## reflection\r\n\r\nappex provides a reflection api derived from TypeScript's type system that developers can \r\nleverage to reflect type information declared throughout their appex modules. \r\n\r\nthe following section outlines how to use the reflection api.\r\n\r\n<a name=\"reflect_everything\" />\r\n### reflect everything\r\n\r\nthe appex reflection api is passed on the context.module.reflection property and is available to all\r\nappex handler methods. The following code will JSON serialize everything declared in your appex\r\nproject and write it to the http response. \r\n\r\n```javascript\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection );\r\n}\r\n```\r\n\r\n<a name=\"reflect_specific_types\" />\r\n### reflect specific types\r\n\r\nIn typical scenarios, developers will want to leverage reflection meta data to generate\r\nservice contacts and client side models. the reflection api lets you access meta data \r\nfor the following types declared in your project. \r\n\r\n* modules\r\n* imports\r\n* classes\r\n* interfaces\r\n* functions\r\n* variables\r\n\r\nto access specific type metadata, use the reflection.get([qualifier]) method, as demonstrated below.\r\n\r\n```javascript\r\nexport module model {\r\n    \r\n    export class Customer {\r\n\r\n        public firstname   : string;\r\n\r\n        public lastname    : string;\r\n\r\n        public age         : number;\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('model.Customer') );\r\n}\r\n```\r\nand methods..\r\n\r\n```javascript\r\nfunction some_method(a:string, b:number, c?:boolean) : void { }\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_method') );\r\n}\r\n```\r\n\r\n....and variables...\r\n\r\n```javascript\r\nvar some_variable:number = 10;\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_variable') );\r\n}\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\nThis section outlines development with appex.\r\n\r\n<a name=\"appex_declaration\" />\r\n### appex.d.ts declaration\r\n\r\nIf you develop on a TypeScript complicant editor (one that supports TS 0.9), appex comes bundled\r\nwith a declaration file you can reference in your project. If installing appex via npm, your\r\nreference should be as follows.\r\n\r\n```javascript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nexport function index (context:appex.web.IContext) { \r\n    \r\n    context.response.send('hello');\r\n}\r\n\r\nexport function wildcard(context:appex.web.IContext, path:string) {\r\n\r\n    context.response.serve('./', path);\r\n}\r\n```\r\n\r\nBy referencing this in your project, you get the benefits of code completion and static type checking\r\nagainst both appex, and the nodejs core.\r\n\r\n![](https://raw.github.com/sinclairzx81/appex/master/artifacts/code-completion.jpg)\r\n\r\nAdditional declaration files may be obtained from [here](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex ({ program : './index.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"users.ts\" />\r\n/// <reference path=\"pages.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { context.response.send('users.login') }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { context.response.send('users.logout') }\r\n}\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { context.response.send('home') }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { context.response.send('about') }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { context.response.send('contact') }\r\n\r\nexport function wildcard (context, path) { context.response.send(404, ' not found') }\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"license\" />\r\n## license\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) 2013 Haydn Paterson (sinclair) <haydn.developer@gmail.com>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in\r\nall copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\nTHE SOFTWARE.\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"https://raw.github.com/sinclairzx81/appex/master/license.txt","type":"The MIT License (MIT)"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"develop nodejs web applications with typescript","directories":{},"dependencies":{"typescript.api":"0.7.1"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.6.3":{"name":"appex","version":"0.6.3","keywords":["typescript","web api","reflection","compiler","schema","templates","sitemap"],"author":{"name":"sinclair"},"_id":"appex@0.6.3","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"28425083db0cf391bc4267a0ad8b3ef5f8862b8c","tarball":"https://registry.npmjs.org/appex/-/appex-0.6.3.tgz","integrity":"sha512-6dozjDfj/e7nuQw9fhtbCzqOumOLfokUpxyYb0o/eAmOK8bOvfdc2yIaVf8UmtmZhpSuNPcxxbWaJ06lxjEd0A==","signatures":[{"sig":"MEYCIQC86wUGsnrMCSTEjqS8KLXalnjjzhmkRGZVMXUdoxk7bgIhAPZzFMpoqyNPK3dCdpTTvpKisagHr++szwBOuZkzS4HM","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/artifacts/logo.jpg)\r\n\r\n### develop nodejs web applications with [typescript](http://www.typescriptlang.org/)\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\n// http://localhost:3000/\r\nexport function index(context:appex.web.IContext) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// http://localhost:3000/about\r\nexport function about(context:appex.web.IContext) {\r\n\r\n\tcontext.response.send('about');\r\n}\r\n\r\n// http://localhost:3000/(.*)\r\nexport function wildcard (context:appex.web.IContext, path:string) {\r\n    \r\n    context.response.send(404, path + \" not found\");\r\n}\r\n\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n### contents\r\n\r\n* [getting started](#getting_started)\r\n\t* [create a application](#application)\r\n\t* [start up options](#options)\r\n\t* [running on an existing http server](#http_server)\r\n\t* [running as express middleware](#express_middleware)\r\n* [http handlers](#http_handlers)\r\n\t* [context](#context)\r\n\t* [request](#request)\r\n\t* [response](#response)\r\n\t* [routing](#routing)\r\n\t* [signatures](#signatures)\r\n\t* [named handlers](#named_handlers)\r\n\t* [index handlers](#index_handlers)\r\n\t* [wildcard handlers](#wildcard_handlers)\r\n\t* [cascades](#cascades)\r\n\t* [http verbs](#http_verbs)\r\n\t* [middleware](#middleware)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [handling 404](#handling_404)\r\n\t* [serving static files](#serving_static_files)\r\n* [templating](#templating)\r\n\t* [overview](#template_overview)\r\n\t* [context](#template_context)\t\r\n\t* [syntax](#template_syntax)\r\n\t* [layouts and sections](#template_layouts_and_sections)\r\n\t* [render](#template_render)\r\n\t* [caching and devmode](#caching_and_devmode)\r\n* [sitemaps](#sitemaps)\r\n\t* [generating](#sitemap_generate)\r\n\t* [metadata](#sitemap_metadata)\r\n* [json schema](#json_schema)\r\n\t* [generating schema](#generating_schema)\r\n\t* [validating json](#validating_json)\r\n\t* [web service descriptions](#web_service_descriptions)\r\n* [reflection](#reflection)\r\n\t* [reflect everything](#reflect_everything)\r\n\t* [reflect specific types](#reflect_specific_types)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [appex.d.ts declaration](#appex_declaration)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n* [license](#license)\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline creating appex applications and configuration.\r\n\r\n<a name=\"application\" />\r\n### create a application\r\n\r\nThe following code will create a standalone appex application and \r\nhttp server and listen on port 3000.\r\n\r\n```javascript\r\nvar appex   = require('appex');\r\n\r\nvar app   = appex({ program : './program.ts', \r\n                    devmode : true,\r\n                    logging : true });\r\n\r\napp.listen(3000);\r\n```\r\n\r\nnote: devmode and logging are optional. however, when developing \r\nwith appex, it is helpful to have these enabled.\r\n\r\n<a name=\"options\" />\r\n### start up options\r\n\r\nappex accepts the following start up options.\r\n\r\n```javascript\r\nvar options = {\r\n\r\n\t// (required) location of source file.\r\n\tprogram    : './program.ts', \r\n\r\n\t// (optional) recompile on request. (default:false) \r\n\tdevmode    : true,          \r\n\r\n\t// (optional) log to stdout. (default:false) \r\n\tlogging    : true,\r\n\r\n\t// (optional) user defined objects added to the app context.\r\n\tcontext    : {}\r\n};\r\n\r\nvar app = appex( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### running on an existing http server\r\n\r\nThe following demonstrates setting up appex on an existing nodejs http server. In \r\nthis example, appex will attempt to handle incoming requests, and if appex cannot\r\nroute the request, will fire the callback.\r\n\r\n```javascript\r\nvar http  = require('http');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\nvar server = http.createServer(function(req, res){\r\n\r\n    app(req, res, function() { // appex handler...\r\n\t\t\r\n\t\t// not handled.\r\n\r\n\t}); \r\n});\r\n\r\nserver.listen(3000);\r\n```\r\n\r\n<a name=\"express_middleware\" />\r\n### running as express middleware\r\n\r\nappex allows developers to augment existing express / connect applications by \r\nway of middleware. The following demonstrates setting up appex as express middleware.\r\n\r\n```javascript\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) ); \r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nLike in the \"running on an existing http server\" example above, appex will attempt to intercept incoming requests. \r\nif appex cannot find a matching route for the request, it will automatically call the \"next\" function to pass the request \r\non to the next middleware or express handler.\r\n\r\nin addition to this, appex may also act as traditional express middleware. In the example below, a appex wildcard\r\nfunction is created which will match \"all\" incoming requests, the wildcard function simply prints hello world to \r\nthe console and then calls context.next(), which passes the request on the express handler.\r\n\r\n```javascript\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tconsole.log('hello world!!');\r\n\r\n\tcontext.next(); // pass it on!\r\n}\r\n\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) );\r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nJust like traditional express middleware, appex will also inheriate the characteristics of the request.\r\n\r\nconsider the following example in which the jade view engine is configured for use. appex will inheritate the \r\nresponse.render() method, which is passed to the appex handler as context.response.render()\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\napp.configure(function(){\r\n\r\n  app.set('views', __dirname + '/views');\r\n  \r\n  // set up the jade engine.\r\n  app.set('view engine', 'jade'); \r\n  \r\n  // bind appex\r\n  app.use( appex({program:'./program.ts', devmode:true} ));  \r\n});\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/\r\nexport function index(context) {\r\n\t\r\n\t// jade renderer works!\r\n\tcontext.response.render('index', { title: 'Express' }); \r\n}\r\n```\r\n\r\n<a name=\"http_handlers\" />\r\n## http handlers\r\n\r\nThe following sections describe how to create http accessible handlers with appex.\r\n\r\n<a name=\"context\" />\r\n### context\r\n\r\nAll appex functions are passed a application context object as their first argument. The app context object \r\nencapulates the http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the app context\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.cascade    - appex cascade.\r\n\r\n\t// context.next       - the next function (express middleware)\r\n\t\r\n\t// context.router     - the appex router\r\n\r\n\t// context.sitemap    - the appex sitemap api\r\n\r\n\t// context.template   - the appex template engine.\r\n\t\r\n\t// context.module     - the module being run (this module)\r\n\r\n\t// context.schema     - json schema api.\r\n\r\n\t// context.mime       - a http mime type utility.\r\n}\r\n```\r\n\r\nit is possible to extend the default objects passed on the context by adding them on the appex startup options. The \r\nfollowing will attach the async module to the context. \r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = appex({ program : './program.ts', \r\n\t\t\t\t  devmode : true, \r\n\t\t\t      context: {\r\n\t\t\t\t\t\tasync : require('async')\r\n\t\t\t\t  }});\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\r\n\t// context.async = passed on the context.\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n```\r\n<a name=\"request\" />\r\n### request\r\n\r\nThe appex request is a nodejs http request issued by the underlying node http server. \r\nappex extends the request with convenience methods for reading http request data. These\r\nare outlined below.\r\n\r\nreading a posted string. \r\n```javascript\r\n//----------------------------------------------\r\n// receive request as a string\r\n//----------------------------------------------\r\nexport function submit(context) {\r\n\r\n\tcontext.request.body.recv((str) => {\r\n\r\n\t\t// do something with str\r\n\t})\r\n}\r\n```\r\nreading posted form data as json object.\r\n```javascript\r\n//----------------------------------------------\r\n// receive a form post\r\n//----------------------------------------------\r\nexport function submit(context) {\r\n\r\n\tcontext.request.body.form((obj) => {\r\n\r\n\t\t// do something with obj\r\n\t})\r\n}\r\n```\r\nreading posted json data as a json object.\r\n```javascript\r\n//----------------------------------------------\r\n// receive a json post\r\n//----------------------------------------------\r\nexport function submit(context) {\r\n\r\n\tcontext.request.body.json((obj) => {\r\n\t\t\r\n\t\t// do something with obj\r\n\t})\r\n}\r\n```\r\n\r\nnote: if appex detects that express or connect middleware has already been applied\r\nto the request object, appex will use those instead.\r\n\r\n<a name=\"response\" />\r\n### response\r\n\r\nThe appex response is a nodejs http response issued by the underlying node http server. \r\nappex provides some utility methods for writing http responses. These are outlined below.\r\n\r\n```js\r\n//----------------------------------------------\r\n// the nodejs response has been extended with the following\r\n// signatures.\r\n//----------------------------------------------\r\nexport interface IResponse extends http.ServerResponse {\r\n\r\n\tsend (data     : string): void;\r\n\r\n\tsend (data     : NodeBuffer): void;\r\n\r\n\tsend (status   : number, data : string): void;\r\n\r\n\tserve (filepath: string): void;\r\n\r\n\tserve (root : string, filepath: string): void;\r\n\r\n\tserve (root : string, filepath: string, mime:string): void;\r\n\r\n\tjson (obj      : any): void;\r\n\r\n\tjson (status   : number, obj : any): void;\r\n\r\n\tjsonp (obj     : any): void;\r\n\r\n\tjsonp (status  : number, obj : any): void;\r\n\r\n\tjsonp (status  : number, obj : any, callback: string): void;\r\n}\r\n```\r\n\r\nnote: if appex detects that express or connect middleware has already been applied\r\nto for any of the following response methods, appex will use those instead.\r\n\r\n<a name=\"routing\" />\r\n### routing\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context) {\r\n\r\n\t\tcontext.response.send('services.customers.insert')\r\n    }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context) { \r\n\t\t\r\n\t\tcontext.response.send('services.customers.update')\r\n    }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context) { \r\n\r\n\t\tcontext.response.send('services.customers.delete')\r\n\t}\r\n}\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context) { \r\n\r\n\tcontext.response.send('home page')\r\n}\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context) { \r\n\r\n\tcontext.response.send('about page')\r\n}\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context) { \r\n\r\n\tcontext.response.send('contact page')\r\n}\r\n\r\n// url: http://[host]:[port]/(.*)\r\nexport function wildcard (context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found')\r\n}\r\n\r\n```\r\n\r\n<a name=\"signatures\" />\r\n### signatures\r\n\r\nappex supports three function signatures for http routing (named, index and wildcard). Functions that\r\ndo not apply these signatures will not be routed.\r\n\r\n<a name=\"named_handlers\" />\r\n### named handlers\r\n\r\nNamed handlers resolve urls to their current module scope + the name of the function.\r\n\r\nNamed handlers require the following signature:\r\n\r\n* name        - 'anything'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n\r\n// http://[host]:[port]/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about page');\r\n}\r\n\r\n// http://[host]:[port]/users/login\r\nexport module users {\r\n\r\n\texport function login(context) {\r\n\t\t\r\n\t\tcontext.response.send('handle login');\t\r\n\t}\r\n}\r\n\r\n```\r\n\r\n<a name=\"index_handlers\" />\r\n### index handlers\r\n\r\nIndex handlers resolve urls to their current module scope.\r\n\r\nIndex handlers require the following signature:\r\n\r\n* name        - 'index'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) \r\n\t{\t\r\n\t\tcontext.response.send('blog index');\r\n\t}\r\n}\r\n```\r\n\r\n<a name=\"wildcard_handlers\" />\r\n### wildcard handlers\r\n\r\nWildcard handlers resolve their urls to their current module scope + url.\r\n\r\nappex wildcard handlers allow for wildcard routing at a given module scope. Wildcard handlers\r\nsupport 'typed' url argument mapping, as denoted by the arguments annotation.\r\n\r\nIn addition, wildcard handlers also support optional arguments which can be specified with TypeScript's '?' \r\non argument names.\r\n\r\nappex wildcard handlers require the following signature:\r\n\r\n* name        - 'wildcard'\r\n* argument[0] - app context\r\n* argument[n] - 1 or more arguments to be mapped from the url\r\n* returns     - void (optional)\r\n\r\n```javascript\r\ndeclare var console;\r\n\r\nexport module blogs {\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11   - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/11  - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/3rd - not matched - (see number annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01     - matched     - (see ? annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013        - not matched - (month is required)\r\n\t\r\n    export function wildcard(context, year:number, month:number, day?:number) {\r\n\r\n        context.response.json({ year: year, month: month, day: day})\r\n    }\r\n}\r\n\r\n// url : http://[host]:[port]/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// url : http://[host]:[port]/(.*) \r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, 'not found');\r\n}\r\n\r\n```\r\nnote: appex supports boolean, number, string and any annotations on wildcard arguments. if no annotation\r\nis specified, appex interprets the argument as a string. the type 'any' is also interpreted as string.\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"cascades\" />\r\n### cascades\r\n\r\nappex supports a cascading attribute scheme on modules and functions. With this, developers can apply\r\narbituary meta data for modules and functions that will propagate through scope. appex has two special\r\ncascade properties for middleware and http verb matching, which are described below, however consider\r\nthe following code which illustrates the concept.\r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ncascade({a: 10}); // global.\r\n\r\ncascade('foo', {b : 20})\r\nexport module foo {\r\n\r\n    cascade('foo.bar', {c : 30})\r\n    export module bar {\r\n            \r\n        cascade('foo.bar.index', {d : 40})\r\n        export function index(context) {\r\n        \r\n            //context.cascade\r\n            //{\r\n            //    \"a\": 10,\r\n            //    \"b\": 20,\r\n            //    \"c\": 30,\r\n\t\t\t//    \"d\": 40\r\n            //}\r\n\r\n            context.response.json( context.cascade );       \r\n        }\r\n    }\r\n}\r\n\r\n```\r\n\r\n<a name=\"http_verbs\" />\r\n### http verbs\r\n\r\nappex handles http verb matching with cascades. appex will recognise the \r\n'verbs' property applied to the cascade to match against http verbs.\r\n\r\n```javascript\r\ncascade('index', { verbs: ['get'] })\r\nexport function index (context) { \r\n        \r\n    // only allow HTTP GET requests\r\n    context.response.send('index')\r\n}\r\n\r\ncascade('index', { verbs: ['post', 'put'] })\r\nexport function submit (context) { \r\n    \r\n    // only allow HTTP POST and PUT requests\r\n    context.response.send('submit')\r\n}\r\n```\r\n\r\n\r\n<a name=\"middleware\" />\r\n### middleware\r\n\r\nappex supports middleware with cascades. appex middleware defined with cascades allows\r\ndevelopers to scope middleware on single functions, or entire module scopes. appex will \r\nrecognise the 'use' property applied to the cascade to invoke middleware.\r\n\r\nthe following demonstrates how one might use middleware to secure a site admin.\r\n\r\nnote: middleware 'must' call next or handle the request. \r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ndeclare var console;\r\n\r\nfunction authenticate(context) {\r\n\r\n    console.log('authenticate')\r\n\r\n\t// call next() if authenticated, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\nfunction authorize(context) {\r\n\r\n    console.log('authorize')\r\n\r\n\t// call next() if authorized, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\n// apply security middleware to admin scope.\r\ncascade('admin', {use: [authenticate, authorize]}) \r\nexport module admin {\r\n\r\n    export function index(context) {\r\n        \r\n        console.log(context.cascade); // view cascade\r\n\r\n        context.response.send('access granted!')\r\n    }\r\n}\r\n\r\n// index handler has no middleware applied.\r\nexport function index (context) { \r\n    \r\n    console.log(context.cascade); // view cascade\r\n\r\n    context.response.send('home')\r\n}\r\n```\r\n\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex will only route functions prefixed with the TypeScript 'export' declarer. This rule\r\nalso applied to modules. Developers can use this to infer notions of public and private \r\nat the http level.\r\n\r\nconsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is \r\n// therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private \r\n\t// as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is \r\n\t// private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and \r\n// is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore \r\n// publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke \r\n\t// private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in \r\n\t// private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method \r\n\t// in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.send('public_function');\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```javascript\r\n// http:[host]:[port]/\r\nexport function index (context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard (context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n<a name=\"serving_static_files\" />\r\n## serving static files\r\n\r\nUse wildcard functions with context.response.serve() to serve static content.\r\n\r\n```javascript\r\nexport module static {\r\n\t\r\n\t// http:[host]:[port]/static/(.*)\r\n\texport function wildcard(context, path) {\r\n\r\n\t\tcontext.response.serve('./static/', path);\r\n\t}\r\n}\r\n\r\n// http:[host]:[port]/\r\nexport function index (context) {\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n\r\n<a name=\"templating\" />\r\n## templating\r\n\r\nappex comes bundled with a built in template engine which is modelled on the Microsoft \r\nRazor templating engine. The following sections outline its use.\r\n\r\n<a name=\"template_overview\" />\r\n### overview\r\n\r\nThe appex template engine is available to all handlers by default. it is accessible\r\non the context.template property. the following is an example of its use.\r\n\r\n```\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n<ul>\r\n@for(var n in context.users) {\r\n\r\n\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t<li>@(context.users[n].name)</li>\r\n\t}\r\n}\r\n</ul>\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\t\r\n\tcontext.response.headers['Content-Type'] = 'text/html';\r\n\r\n    context.response.send(text);\r\n}\r\n\r\n```\r\n\r\n<a name=\"template_context\" />\r\n### context\r\n\r\neach template is passed a data context. this context allows the caller to \r\nsend data to the template for rendering. the context parameter is optional.\r\nthe example below is sending the users array to the template context for \r\nrendering.\r\n\r\n```\r\nexport function index(context) {\r\n\t\r\n    var users  = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    context.response.send(context.template.render('./view.txt', { users: users }));\r\n}\r\n```\r\n\r\n<a name=\"template_syntax\" />\r\n### syntax\r\n\r\nappex templates support the following statements and syntax\r\n\r\n#### if statement\r\n\r\nif statments are supported.\r\n\r\n```\r\n@if(expression) {\r\n\tsome content\r\n}\r\n\r\n@if(a > 10) {\r\n\tsome content\r\n}\r\n\r\n@(user.loggedin) {\r\n\t<span>welcome</span>\r\n}\r\n```\r\n\r\n#### for statement\r\n\r\nthe following for loops are supported.\r\n\r\n```\r\n@for(var i = i; i < 100; i++) {\r\n\t@(i)\r\n}\r\n\r\n@for(var n in list) {\r\n\t@(list[n])\r\n}\r\n```\r\n\r\n#### expressions\r\n\r\nwill emit the value contained.\r\n\r\n```\r\n@('hello world')\r\n\r\n@(123)\r\n\r\n@(some_variable)\r\n```\r\n\r\n#### code blocks\r\n\r\ncode blocks can be useful for adding template side rendering logic.\r\n\r\n```\r\n@{\r\n\tvar message = 'hello'\r\n}\r\n\r\n@(message)\r\n```\r\n\r\n#### comments\r\n```\r\n@*\r\n\tthis comment will not be rendered!\r\n*@\r\n```\r\n\r\n<a name=\"template_layouts_and_sections\" />\r\n### layouts and sections\r\n\r\nappex templates support template inheritance.\r\n\r\nconsider the following where layout.txt defines the sections 'header' and 'content' and the view.txt overrides\r\nthese sections with its own content.\r\n\r\n```\r\n//----------------------------------------------\r\n// layout.txt\r\n//----------------------------------------------\r\n\r\n<html>\r\n\r\n\t<head>\r\n\t\t\r\n\t\t@section header\r\n\r\n\t</head>\r\n\r\n\t<body>\r\n\r\n\t\t@section content {\r\n\t\t\r\n\t\t\t<span>some default content</span>\r\n\t\t\t\r\n\t\t}\r\n\r\n\t</body>\r\n\t\r\n</html>\r\n\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n@layout 'layout.txt'\r\n\r\n@section header {\r\n\r\n\t<title>my page</title>\r\n}\r\n\r\n@section content {\r\n\r\n\t<p>overriding the layout.txt content section.</p>\r\n\r\n\t<ul>\r\n\t@for(var n in context.users) {\r\n\r\n\t\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t\t<li>@(context.users[n].name)</li>\r\n\t\t}\r\n\t}\r\n\t</ul>\r\n}\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\r\n    context.response.send(text);\r\n}\r\n```\r\n\r\nnote : when specifying a layout, the view will only render content within\r\nthe layouts section placeholders. \r\n\r\n<a name=\"render\" />\r\n### render\r\n\r\nappex templates also allow for partial views with the @render statment. consider the following \r\nwhich renders the nav.txt file into the layout.txt file.\r\n\r\n```\r\n//----------------------------------------------\r\n// nav.txt\r\n//----------------------------------------------\r\n<ul>\r\n\t<li>home</li>\r\n\t<li>about</li>\r\n\t<li>contact</li>\r\n</ul>\r\n\r\n//----------------------------------------------\r\n// layout.txt\r\n//----------------------------------------------\r\n\r\n<html>\r\n\t<head>\r\n\t\t\r\n\t\t@section header\r\n\r\n\t</head>\r\n\r\n\t<body>\r\n\t\t\r\n\t\t@render 'nav.txt'\r\n\r\n\t\t@section content {\r\n\t\t\r\n\t\t\t<span>some default content</span>\r\n\t\t\t\r\n\t\t}\r\n\r\n\t</body>\r\n\t\r\n</html>\r\n\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n@layout 'layout.txt'\r\n\r\n@section header {\r\n\r\n\t<title>my page</title>\r\n}\r\n\r\n@section content {\r\n\r\n\t<p>overriding the layout.txt content section.</p>\r\n\r\n\t<ul>\r\n\t@for(var n in context.users) {\r\n\r\n\t\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t\t<li>@(context.users[n].name)</li>\r\n\t\t}\r\n\t}\r\n\t</ul>\r\n}\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\r\n    context.response.send(text);\r\n}\r\n```\r\n\r\n<a name=\"caching_and_devmode\" />\r\n### caching and devmode\r\n\r\nappex template content is not cached (the implementor is expected to handle their own caching)\r\nhowever the generated template code is. \r\n\r\nappex templates do inheriate the behaviour of the appex 'devmode' option. setting\r\ndevmode to 'true' will cause template code to be reloaded from disk and code generated with each \r\nrequest. setting devmode to false will load content from disk on first request, and \r\ncache the generated template code in memory for the lifetime of the application.\r\n\r\nin addition to this, a implementation where the devmode is false can override the caching \r\nbehaviour with the following.\r\n\r\n```javascript\r\nexport function index(context) {\r\n\r\n\t// manually override the template devmode option.\r\n\tcontext.template.option.devmode = true; \r\n\r\n\tcontext.response.send(context.template.render('./view.txt'))\r\n}\r\n```\r\n\r\n<a name=\"sitemaps\" />\r\n## sitemaps\r\n\r\nappex is able to derive sitemap metadata automatically from http endpoints created with\r\ntypescript modules and functions. This metadata is useful to generate sitemap.xml\r\nfiles, as well as helping to create site navigation links when combined a template\r\nengine.\r\n\r\n<a name=\"sitemap_generate\" />\r\n### generate sitemap\r\n\r\nappex sitemaps can be obtained from the context.sitemap property. \r\n\r\n```javascript\r\nexport function index(context) {\r\n\r\n\t// return all nodes in this site.\r\n\tcontext.response.json(context.sitemap)\r\n\r\n}\r\n```\r\n\r\nAdditionally, it may be helpful to isolate branches of the sitemap with the \r\ncontext.sitemap.get([qualifier]) function. as demonstrated below.\r\n\r\n```javascript\r\nexport module admin {\r\n\r\n\texport function index     (context) { }\r\n\r\n\texport function dashboard (context) { }\r\n\r\n\texport function content   (context) { }\r\n\r\n\texport module users {\r\n\r\n\t\texport function login(context) { }\r\n\r\n\t\texport function logout(context) { }\r\n\t}\r\n}\r\n\r\nexport function test(context) {\r\n\t\r\n\t// view all admin sitemap nodes\r\n\tcontext.response.json(context.sitemap.get('admin'))\r\n\r\n\t// view all admin.users sitemap nodes\r\n\t//context.response.json(context.sitemap.get('admin.users'))\r\n}\r\n```\r\n\r\n<a name=\"sitemap_metadata\" />\r\n### cascade metadata\r\n\r\neach sitemap node contains the cascade applied to the handler for which the node applies. With this\r\ndevelopers can apply custom metadata for a given node. as demonstrated below.\r\n\r\n```javascript\r\ndeclare var cascade;\r\n\r\ncascade({website:'http://mysite.com/'}) // global\r\n\r\ncascade('index', {title:'home page'})\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('index')\r\n}\r\n\r\ncascade('about', {title: 'about page'})\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about')\r\n}\r\n\r\ncascade('sitemap', {title: 'sitemap page'})\r\nexport function sitemap(context) {\r\n\r\n\tcontext.response.json(context.sitemap)\r\n}\r\n```\r\n\r\nvisiting /sitemap will output the following.\r\n\r\n```javascript\r\n{\r\n    \"name\": \"sitemap\",\r\n    \"nodes\": [\r\n        {\r\n            \"name\": \"index\",\r\n            \"urls\": [\r\n                \"/\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"home page\"\r\n        },\r\n        {\r\n            \"name\": \"about\",\r\n            \"urls\": [\r\n                \"/about\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"about page\"\r\n        },\r\n        {\r\n            \"name\": \"sitemap\",\r\n            \"urls\": [\r\n                \"/sitemap\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"sitemap page\"\r\n        }\r\n    ]\r\n}\r\n```\r\n\r\n<a name=\"json_schema\" />\r\n## json schema\r\n\r\nappex provides functionality for generating json schemas from TypeScript classes\r\nand interfaces as well as tools for validating json data.\r\n\r\n<a name=\"generating_schema\" />\r\n### generating schema\r\n\r\nThe following demonstrates generating json schema from the following class\r\nhierarchy.\r\n\r\n```javascript\r\nexport module model {\r\n\r\n    /** a product */\r\n    export class Product {\r\n        \r\n        /** the product name */\r\n        public name        : string;\r\n\r\n        /** the product description */\r\n        public description : string;\r\n\r\n        /** the product cost */\r\n        public cost        : number;\r\n    } \r\n\r\n    /** a order */\r\n    export class Order {\r\n        \r\n        /** the product being ordered */\r\n        public products  : Product;\r\n    }\r\n\r\n    /** a customer */\r\n    export class Customer {\r\n\r\n        /** the customers firstname */\r\n        public firstname  : string;\r\n\r\n        /** the customers lastname */\r\n        public lastname   : string;\r\n\r\n        /** orders made by this customer */\r\n        public orders     : Order[];\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.IContext) {\r\n\t\r\n\t// pass the fully qualified name of the type.\r\n    var schema = context.schema.generate('model.Customer');\r\n\r\n    context.response.json(schema);\r\n}\r\n```\r\n\r\nwhich generates the following json schema.\r\n\r\n```javascript\r\n{\r\n    \"id\": \"model.Customer\",\r\n    \"type\": \"object\",\r\n    \"description\": \"a customer\",\r\n    \"properties\": {\r\n        \"firstname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers firstname\",\r\n            \"required\": true\r\n        },\r\n        \"lastname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers lastname\",\r\n            \"required\": true\r\n        },\r\n        \"orders\": {\r\n            \"type\": \"array\",\r\n            \"items\": {\r\n                \"type\": {\r\n                    \"id\": \"model.Order\",\r\n                    \"type\": \"object\",\r\n                    \"description\": \"a order\",\r\n                    \"properties\": {\r\n                        \"products\": {\r\n                            \"id\": \"model.Product\",\r\n                            \"type\": \"object\",\r\n                            \"description\": \"a product\",\r\n                            \"properties\": {\r\n                                \"name\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product name\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"description\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product description\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"cost\": {\r\n                                    \"type\": \"number\",\r\n                                    \"description\": \"the product cost\",\r\n                                    \"required\": true\r\n                                }\r\n                            },\r\n                            \"required\": true\r\n                        }\r\n                    }\r\n                }\r\n            },\r\n            \"description\": \"orders made by this customer\",\r\n            \"required\": true\r\n        }\r\n    }\r\n}\r\n```\r\na quick note...\r\n\r\nwhen generating schema from classes:\r\n\r\n* only public class variables will be emitted.\r\n* all properties will be marked as \"required\".\r\n\r\nwhen generating schema from interfaces:\r\n\r\n* all properties will be emitted. \r\n* all properties will be marked as \"required\" unless modified with '?'.\r\n\r\n<a name=\"validating_json\" />\r\n### validating json\r\n\r\nappex supports json schema validation from class and interface definitions. consider the following...\r\n\r\n```javascript\r\ninterface Customer {\r\n\r\n    firstname    : string;\r\n\r\n    lastname     : string;\r\n\r\n    age          : number;\r\n\r\n    emails       : string[];\r\n\r\n    option_a ?   : boolean; // optional\r\n\r\n    option_b ?   : boolean; // optional\r\n\r\n}\r\n\r\nexport function index(context) {\r\n\r\n    // a customer with invalid data.\r\n\r\n    var customer = {\r\n\r\n        firstname    : 'dave',\r\n\r\n        age          : '33',\r\n\r\n        emails       : [12345, 'dave@domain.com', true],\r\n\r\n        option_b     : 1,\r\n\r\n        option_c     : 1\r\n    }\r\n\r\n    // do validation.\r\n\r\n    var errors = context.schema.validate('Customer', customer);\r\n\r\n    if(errors) {\r\n\r\n        context.response.json(errors);\r\n    }\r\n}\r\n```\r\n\r\nwill output the following.\r\n\r\n```javascript\r\n[\r\n    {\r\n        \"message\": \"instance.lastname is required.\"\r\n    },\r\n    {\r\n        \"message\": \"instance.age is not a number\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[0] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[2] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_b is not a boolean\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_c unexpected property\"\r\n    }\r\n]\r\n```\r\n\r\n<a name=\"web_service_descriptions\">\r\n### web service descriptions\r\n\r\nFor those using appex for web services, developers can leverage appex json schema generation\r\nto generate endpoint metadata (think wsdl). Consider the following which leverages both appex \r\nschema generation and cascades to produce a metadata endpoint consumers of your\r\napi can use to see what data the endpoint http://example.com/customer/create accepts \r\nand returns.\r\n\r\n```javascript\r\nclass Request {\r\n\r\n    /** the customers firstname */\r\n    firstname : string;\r\n\r\n    /** the customers lastname */\r\n    lastname  : string;\r\n\r\n\t/** the customers lastname */\r\n}\r\n\r\nclass Response {\r\n\r\n    /** true on success  */\r\n    success:boolean;\r\n    \r\n    /** an array of validation errors  */\r\n    errors : string[];\r\n}\r\n\r\ncascade('metadata', {input  : 'Request', output : 'Response'})\r\nexport function metadata(context:appex.web.IContext) {\r\n\r\n    var metadata = {\r\n        \r\n\t\tendpoint : 'http://example.com/customer/create',\r\n\r\n        input    : context.schema.generate(context.cascade.input),\r\n\r\n        output   : context.schema.generate(context.cascade.output)\r\n    }\r\n\r\n    context.response.json(metadata)\r\n}\r\n```\r\n\r\nwhich outputs the following.\r\n\r\n```javascript\r\n{\r\n    \"endpoint\": \"http://example.com/customer/create\",\r\n    \"input\": {\r\n        \"id\": \"Request\",\r\n        \"type\": \"object\",\r\n        \"properties\": {\r\n            \"firstname\": {\r\n                \"type\": \"string\",\r\n                \"description\": \"the customers firstname\",\r\n                \"required\": true\r\n            },\r\n            \"lastname\": {\r\n                \"type\": \"string\",\r\n                \"description\": \"the customers lastname\",\r\n                \"required\": true\r\n            }\r\n        }\r\n    },\r\n    \"output\": {\r\n        \"id\": \"Response\",\r\n        \"type\": \"object\",\r\n        \"properties\": {\r\n            \"success\": {\r\n                \"type\": \"boolean\",\r\n                \"description\": \"true on success\",\r\n                \"required\": true\r\n            },\r\n            \"errors\": {\r\n                \"type\": \"array\",\r\n                \"description\": \"an array of validation errors\",\r\n                \"items\": {\r\n                    \"type\": \"string\"\r\n                },\r\n                \"required\": true\r\n            }\r\n        }\r\n    }\r\n}\r\n```\r\ntip: use the appex sitemap metadata to produce a metadata endpoint for all service methods \r\nin your application.\r\n\r\n\r\n<a name=\"reflection\" />\r\n## reflection\r\n\r\nappex provides a reflection api derived from TypeScript's type system that developers can \r\nleverage to reflect type information declared throughout their appex modules. \r\n\r\nthe following section outlines how to use the reflection api.\r\n\r\n<a name=\"reflect_everything\" />\r\n### reflect everything\r\n\r\nthe appex reflection api is passed on the context.module.reflection property and is available to all\r\nappex handler methods. The following code will JSON serialize everything declared in your appex\r\nproject and write it to the http response. \r\n\r\n```javascript\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection );\r\n}\r\n```\r\n\r\n<a name=\"reflect_specific_types\" />\r\n### reflect specific types\r\n\r\nIn typical scenarios, developers will want to leverage reflection meta data to generate\r\nservice contacts and client side models. the reflection api lets you access meta data \r\nfor the following types declared in your project. \r\n\r\n* modules\r\n* imports\r\n* classes\r\n* interfaces\r\n* functions\r\n* variables\r\n\r\nto access specific type metadata, use the reflection.get([qualifier]) method, as demonstrated below.\r\n\r\n```javascript\r\nexport module model {\r\n    \r\n    export class Customer {\r\n\r\n        public firstname   : string;\r\n\r\n        public lastname    : string;\r\n\r\n        public age         : number;\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('model.Customer') );\r\n}\r\n```\r\nand methods..\r\n\r\n```javascript\r\nfunction some_method(a:string, b:number, c?:boolean) : void { }\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_method') );\r\n}\r\n```\r\n\r\n....and variables...\r\n\r\n```javascript\r\nvar some_variable:number = 10;\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_variable') );\r\n}\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\nThis section outlines development with appex.\r\n\r\n<a name=\"appex_declaration\" />\r\n### appex.d.ts declaration\r\n\r\nIf you develop on a TypeScript complicant editor (one that supports TS 0.9), appex comes bundled\r\nwith a declaration file you can reference in your project. If installing appex via npm, your\r\nreference should be as follows.\r\n\r\n```javascript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nexport function index (context:appex.web.IContext) { \r\n    \r\n    context.response.send('hello');\r\n}\r\n\r\nexport function wildcard(context:appex.web.IContext, path:string) {\r\n\r\n    context.response.serve('./', path);\r\n}\r\n```\r\n\r\nBy referencing this in your project, you get the benefits of code completion and static type checking\r\nagainst both appex, and the nodejs core.\r\n\r\n![](https://raw.github.com/sinclairzx81/appex/master/artifacts/code-completion.jpg)\r\n\r\nAdditional declaration files may be obtained from [here](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex ({ program : './index.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"users.ts\" />\r\n/// <reference path=\"pages.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { context.response.send('users.login') }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { context.response.send('users.logout') }\r\n}\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { context.response.send('home') }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { context.response.send('about') }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { context.response.send('contact') }\r\n\r\nexport function wildcard (context, path) { context.response.send(404, ' not found') }\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"license\" />\r\n## license\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) 2013 Haydn Paterson (sinclair) <haydn.developer@gmail.com>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in\r\nall copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\nTHE SOFTWARE.\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"https://raw.github.com/sinclairzx81/appex/master/license.txt","type":"The MIT License (MIT)"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"develop nodejs web applications with typescript","directories":{},"dependencies":{"typescript.api":"0.7.2"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.6.4":{"name":"appex","version":"0.6.4","keywords":["typescript","web api","reflection","compiler","schema","templates","sitemap"],"author":{"name":"sinclair"},"_id":"appex@0.6.4","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"1d494a99720abdc0d91d06cfb9fb8d034fc41e14","tarball":"https://registry.npmjs.org/appex/-/appex-0.6.4.tgz","integrity":"sha512-JcrGx5L8wQGLsZK7KlvHa2gzsdq+vG7l1GTZ3IQUN6Frbxd2LBaPJYRh8qoec1ycDkmYT2qG5Ac6UkXgC68GBA==","signatures":[{"sig":"MEUCIQDgxSLL63accHmqw6NtI2BzkdR3d+4gTxyPx9O+jQnybwIgMbVjSiZY1W5wqaMfuDe/4PeuqHLDQi+5R4HCwz3PHpE=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/artifacts/logo.jpg)\r\n\r\n### develop nodejs web applications with [typescript](http://www.typescriptlang.org/)\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\n// http://localhost:3000/\r\nexport function index(context:appex.web.IContext) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// http://localhost:3000/about\r\nexport function about(context:appex.web.IContext) {\r\n\r\n\tcontext.response.send('about');\r\n}\r\n\r\n// http://localhost:3000/(.*)\r\nexport function wildcard (context:appex.web.IContext, path:string) {\r\n    \r\n    context.response.send(404, path + \" not found\");\r\n}\r\n\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n### contents\r\n\r\n* [getting started](#getting_started)\r\n\t* [create a application](#application)\r\n\t* [start up options](#options)\r\n\t* [running on an existing http server](#http_server)\r\n\t* [running as express middleware](#express_middleware)\r\n* [http handlers](#http_handlers)\r\n\t* [context](#context)\r\n\t* [request](#request)\r\n\t* [response](#response)\r\n\t* [routing](#routing)\r\n\t* [signatures](#signatures)\r\n\t* [named handlers](#named_handlers)\r\n\t* [index handlers](#index_handlers)\r\n\t* [wildcard handlers](#wildcard_handlers)\r\n\t* [cascades](#cascades)\r\n\t* [http verbs](#http_verbs)\r\n\t* [middleware](#middleware)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [handling 404](#handling_404)\r\n\t* [serving static files](#serving_static_files)\r\n* [templating](#templating)\r\n\t* [overview](#template_overview)\r\n\t* [context](#template_context)\t\r\n\t* [syntax](#template_syntax)\r\n\t* [layouts and sections](#template_layouts_and_sections)\r\n\t* [render](#template_render)\r\n\t* [caching and devmode](#caching_and_devmode)\r\n* [sitemaps](#sitemaps)\r\n\t* [generating](#sitemap_generate)\r\n\t* [metadata](#sitemap_metadata)\r\n* [json schema](#json_schema)\r\n\t* [generating schema](#generating_schema)\r\n\t* [validating json](#validating_json)\r\n\t* [web service descriptions](#web_service_descriptions)\r\n* [reflection](#reflection)\r\n\t* [reflect everything](#reflect_everything)\r\n\t* [reflect specific types](#reflect_specific_types)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [appex.d.ts declaration](#appex_declaration)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n* [license](#license)\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline creating appex applications and configuration.\r\n\r\n<a name=\"application\" />\r\n### create a application\r\n\r\nThe following code will create a standalone appex application and \r\nhttp server and listen on port 3000.\r\n\r\n```javascript\r\nvar appex   = require('appex');\r\n\r\nvar app   = appex({ program : './program.ts', \r\n                    devmode : true,\r\n                    logging : true });\r\n\r\napp.listen(3000);\r\n```\r\n\r\nnote: devmode and logging are optional. however, when developing \r\nwith appex, it is helpful to have these enabled.\r\n\r\n<a name=\"options\" />\r\n### start up options\r\n\r\nappex accepts the following start up options.\r\n\r\n```javascript\r\nvar options = {\r\n\r\n\t// (required) location of source file.\r\n\tprogram    : './program.ts', \r\n\r\n\t// (optional) recompile on request. (default:false) \r\n\tdevmode    : true,          \r\n\r\n\t// (optional) log to stdout. (default:false) \r\n\tlogging    : true,\r\n\r\n\t// (optional) user defined objects added to the app context.\r\n\tcontext    : {}\r\n};\r\n\r\nvar app = appex( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### running on an existing http server\r\n\r\nThe following demonstrates setting up appex on an existing nodejs http server. In \r\nthis example, appex will attempt to handle incoming requests, and if appex cannot\r\nroute the request, will fire the callback.\r\n\r\n```javascript\r\nvar http  = require('http');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\nvar server = http.createServer(function(req, res){\r\n\r\n    app(req, res, function() { // appex handler...\r\n\t\t\r\n\t\t// not handled.\r\n\r\n\t}); \r\n});\r\n\r\nserver.listen(3000);\r\n```\r\n\r\n<a name=\"express_middleware\" />\r\n### running as express middleware\r\n\r\nappex allows developers to augment existing express / connect applications by \r\nway of middleware. The following demonstrates setting up appex as express middleware.\r\n\r\n```javascript\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) ); \r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nLike in the \"running on an existing http server\" example above, appex will attempt to intercept incoming requests. \r\nif appex cannot find a matching route for the request, it will automatically call the \"next\" function to pass the request \r\non to the next middleware or express handler.\r\n\r\nin addition to this, appex may also act as traditional express middleware. In the example below, a appex wildcard\r\nfunction is created which will match \"all\" incoming requests, the wildcard function simply prints hello world to \r\nthe console and then calls context.next(), which passes the request on the express handler.\r\n\r\n```javascript\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tconsole.log('hello world!!');\r\n\r\n\tcontext.next(); // pass it on!\r\n}\r\n\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) );\r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nJust like traditional express middleware, appex will also inheriate the characteristics of the request.\r\n\r\nconsider the following example in which the jade view engine is configured for use. appex will inheritate the \r\nresponse.render() method, which is passed to the appex handler as context.response.render()\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\napp.configure(function(){\r\n\r\n  app.set('views', __dirname + '/views');\r\n  \r\n  // set up the jade engine.\r\n  app.set('view engine', 'jade'); \r\n  \r\n  // bind appex\r\n  app.use( appex({program:'./program.ts', devmode:true} ));  \r\n});\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/\r\nexport function index(context) {\r\n\t\r\n\t// jade renderer works!\r\n\tcontext.response.render('index', { title: 'Express' }); \r\n}\r\n```\r\n\r\n<a name=\"http_handlers\" />\r\n## http handlers\r\n\r\nThe following sections describe how to create http accessible handlers with appex.\r\n\r\n<a name=\"context\" />\r\n### context\r\n\r\nAll appex functions are passed a application context object as their first argument. The app context object \r\nencapulates the http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the app context\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.cascade    - appex cascade.\r\n\r\n\t// context.next       - the next function (express middleware)\r\n\t\r\n\t// context.router     - the appex router\r\n\r\n\t// context.sitemap    - the appex sitemap api\r\n\r\n\t// context.template   - the appex template engine.\r\n\t\r\n\t// context.module     - the module being run (this module)\r\n\r\n\t// context.schema     - json schema api.\r\n\r\n\t// context.mime       - a http mime type utility.\r\n}\r\n```\r\n\r\nit is possible to extend the default objects passed on the context by adding them on the appex startup options. The \r\nfollowing will attach the async module to the context. \r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = appex({ program : './program.ts', \r\n\t\t\t\t  devmode : true, \r\n\t\t\t      context: {\r\n\t\t\t\t\t\tasync : require('async')\r\n\t\t\t\t  }});\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\r\n\t// context.async = passed on the context.\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n```\r\n<a name=\"request\" />\r\n### request\r\n\r\nThe appex request is a nodejs http request issued by the underlying node http server. \r\nappex extends the request with convenience methods for reading http request data. These\r\nare outlined below.\r\n\r\nreading a posted string. \r\n```javascript\r\n//----------------------------------------------\r\n// receive request as a string\r\n//----------------------------------------------\r\nexport function submit(context) {\r\n\r\n\tcontext.request.body.recv((str) => {\r\n\r\n\t\t// do something with str\r\n\t})\r\n}\r\n```\r\nreading posted form data as json object.\r\n```javascript\r\n//----------------------------------------------\r\n// receive a form post\r\n//----------------------------------------------\r\nexport function submit(context) {\r\n\r\n\tcontext.request.body.form((obj) => {\r\n\r\n\t\t// do something with obj\r\n\t})\r\n}\r\n```\r\nreading posted json data as a json object.\r\n```javascript\r\n//----------------------------------------------\r\n// receive a json post\r\n//----------------------------------------------\r\nexport function submit(context) {\r\n\r\n\tcontext.request.body.json((obj) => {\r\n\t\t\r\n\t\t// do something with obj\r\n\t})\r\n}\r\n```\r\n\r\nnote: if appex detects that express or connect middleware has already been applied\r\nto the request object, appex will use those instead.\r\n\r\n<a name=\"response\" />\r\n### response\r\n\r\nThe appex response is a nodejs http response issued by the underlying node http server. \r\nappex provides some utility methods for writing http responses. These are outlined below.\r\n\r\n```js\r\n//----------------------------------------------\r\n// the nodejs response has been extended with the following\r\n// signatures.\r\n//----------------------------------------------\r\nexport interface IResponse extends http.ServerResponse {\r\n\t\r\n\tsend (data     : string): void;\r\n\r\n\tsend (data     : NodeBuffer): void;\r\n\r\n\tsend (status   : number, data : string): void;\r\n\r\n\tserve (filepath: string): void;\r\n\r\n\tserve (root : string, filepath: string): void;\r\n\r\n\tserve (root : string, filepath: string, mime:string): void;\r\n\r\n\tjson (obj      : any): void;\r\n\r\n\tjson (status   : number, obj : any): void;\r\n\r\n\tjsonp (obj     : any): void;\r\n\r\n\tjsonp (status  : number, obj : any): void;\r\n\r\n\tjsonp (status  : number, obj : any, callback: string): void;\r\n}\r\n```\r\n\r\nnote: if appex detects that express or connect middleware has already been applied\r\nto for any of the following response methods, appex will use those instead.\r\n\r\n<a name=\"routing\" />\r\n### routing\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context) {\r\n\r\n\t\tcontext.response.send('services.customers.insert')\r\n    }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context) { \r\n\t\t\r\n\t\tcontext.response.send('services.customers.update')\r\n    }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context) { \r\n\r\n\t\tcontext.response.send('services.customers.delete')\r\n\t}\r\n}\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context) { \r\n\r\n\tcontext.response.send('home page')\r\n}\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context) { \r\n\r\n\tcontext.response.send('about page')\r\n}\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context) { \r\n\r\n\tcontext.response.send('contact page')\r\n}\r\n\r\n// url: http://[host]:[port]/(.*)\r\nexport function wildcard (context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found')\r\n}\r\n\r\n```\r\n\r\n<a name=\"signatures\" />\r\n### signatures\r\n\r\nappex supports three function signatures for http routing (named, index and wildcard). Functions that\r\ndo not apply these signatures will not be routed.\r\n\r\n<a name=\"named_handlers\" />\r\n### named handlers\r\n\r\nNamed handlers resolve urls to their current module scope + the name of the function.\r\n\r\nNamed handlers require the following signature:\r\n\r\n* name        - 'anything'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n\r\n// http://[host]:[port]/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about page');\r\n}\r\n\r\n// http://[host]:[port]/users/login\r\nexport module users {\r\n\r\n\texport function login(context) {\r\n\t\t\r\n\t\tcontext.response.send('handle login');\t\r\n\t}\r\n}\r\n\r\n```\r\n\r\n<a name=\"index_handlers\" />\r\n### index handlers\r\n\r\nIndex handlers resolve urls to their current module scope.\r\n\r\nIndex handlers require the following signature:\r\n\r\n* name        - 'index'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) \r\n\t{\t\r\n\t\tcontext.response.send('blog index');\r\n\t}\r\n}\r\n```\r\n\r\n<a name=\"wildcard_handlers\" />\r\n### wildcard handlers\r\n\r\nWildcard handlers resolve their urls to their current module scope + url.\r\n\r\nappex wildcard handlers allow for wildcard routing at a given module scope. Wildcard handlers\r\nsupport 'typed' url argument mapping, as denoted by the arguments annotation.\r\n\r\nIn addition, wildcard handlers also support optional arguments which can be specified with TypeScript's '?' \r\non argument names.\r\n\r\nappex wildcard handlers require the following signature:\r\n\r\n* name        - 'wildcard'\r\n* argument[0] - app context\r\n* argument[n] - 1 or more arguments to be mapped from the url\r\n* returns     - void (optional)\r\n\r\n```javascript\r\ndeclare var console;\r\n\r\nexport module blogs {\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11   - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/11  - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/3rd - not matched - (see number annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01     - matched     - (see ? annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013        - not matched - (month is required)\r\n\t\r\n    export function wildcard(context, year:number, month:number, day?:number) {\r\n\r\n        context.response.json({ year: year, month: month, day: day})\r\n    }\r\n}\r\n\r\n// url : http://[host]:[port]/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// url : http://[host]:[port]/(.*) \r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, 'not found');\r\n}\r\n\r\n```\r\nnote: appex supports boolean, number, string and any annotations on wildcard arguments. if no annotation\r\nis specified, appex interprets the argument as a string. the type 'any' is also interpreted as string.\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"cascades\" />\r\n### cascades\r\n\r\nappex supports a cascading attribute scheme on modules and functions. With this, developers can apply\r\narbituary meta data for modules and functions that will propagate through scope. appex has two special\r\ncascade properties for middleware and http verb matching, which are described below, however consider\r\nthe following code which illustrates the concept.\r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ncascade({a: 10}); // global.\r\n\r\ncascade('foo', {b : 20})\r\nexport module foo {\r\n\r\n    cascade('foo.bar', {c : 30})\r\n    export module bar {\r\n            \r\n        cascade('foo.bar.index', {d : 40})\r\n        export function index(context) {\r\n        \r\n            //context.cascade\r\n            //{\r\n            //    \"a\": 10,\r\n            //    \"b\": 20,\r\n            //    \"c\": 30,\r\n\t\t\t//    \"d\": 40\r\n            //}\r\n\r\n            context.response.json( context.cascade );       \r\n        }\r\n    }\r\n}\r\n\r\n```\r\n\r\n<a name=\"http_verbs\" />\r\n### http verbs\r\n\r\nappex handles http verb matching with cascades. appex will recognise the \r\n'verbs' property applied to the cascade to match against http verbs.\r\n\r\n```javascript\r\ncascade('index', { verbs: ['get'] })\r\nexport function index (context) { \r\n        \r\n    // only allow HTTP GET requests\r\n    context.response.send('index')\r\n}\r\n\r\ncascade('index', { verbs: ['post', 'put'] })\r\nexport function submit (context) { \r\n    \r\n    // only allow HTTP POST and PUT requests\r\n    context.response.send('submit')\r\n}\r\n```\r\n\r\n\r\n<a name=\"middleware\" />\r\n### middleware\r\n\r\nappex supports middleware with cascades. appex middleware defined with cascades allows\r\ndevelopers to scope middleware on single functions, or entire module scopes. appex will \r\nrecognise the 'use' property applied to the cascade to invoke middleware.\r\n\r\nthe following demonstrates how one might use middleware to secure a site admin.\r\n\r\nnote: middleware 'must' call next or handle the request. \r\n\r\n```javascript\r\ndeclare function cascade (qualifier:string, obj:any);\r\n\r\ndeclare var console;\r\n\r\nfunction authenticate(context) {\r\n\r\n    console.log('authenticate')\r\n\r\n\t// call next() if authenticated, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\nfunction authorize(context) {\r\n\r\n    console.log('authorize')\r\n\r\n\t// call next() if authorized, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\n// apply security middleware to admin scope.\r\ncascade('admin', {use: [authenticate, authorize]}) \r\nexport module admin {\r\n\r\n    export function index(context) {\r\n        \r\n        console.log(context.cascade); // view cascade\r\n\r\n        context.response.send('access granted!')\r\n    }\r\n}\r\n\r\n// index handler has no middleware applied.\r\nexport function index (context) { \r\n    \r\n    console.log(context.cascade); // view cascade\r\n\r\n    context.response.send('home')\r\n}\r\n```\r\n\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex will only route functions prefixed with the TypeScript 'export' declarer. This rule\r\nalso applied to modules. Developers can use this to infer notions of public and private \r\nat the http level.\r\n\r\nconsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is \r\n// therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private \r\n\t// as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is \r\n\t// private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and \r\n// is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore \r\n// publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke \r\n\t// private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in \r\n\t// private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method \r\n\t// in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.send('public_function');\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```javascript\r\n// http:[host]:[port]/\r\nexport function index (context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard (context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n<a name=\"serving_static_files\" />\r\n## serving static files\r\n\r\nUse wildcard functions with context.response.serve() to serve static content.\r\n\r\n```javascript\r\nexport module static {\r\n\t\r\n\t// http:[host]:[port]/static/(.*)\r\n\texport function wildcard(context, path) {\r\n\r\n\t\tcontext.response.serve('./static/', path);\r\n\t}\r\n}\r\n\r\n// http:[host]:[port]/\r\nexport function index (context) {\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n\r\n<a name=\"templating\" />\r\n## templating\r\n\r\nappex comes bundled with a built in template engine which is modelled on the Microsoft \r\nRazor templating engine. The following sections outline its use.\r\n\r\n<a name=\"template_overview\" />\r\n### overview\r\n\r\nThe appex template engine is available to all handlers by default. it is accessible\r\non the context.template property. the following is an example of its use.\r\n\r\n```\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n<ul>\r\n@for(var n in context.users) {\r\n\r\n\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t<li>@(context.users[n].name)</li>\r\n\t}\r\n}\r\n</ul>\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\t\r\n\tcontext.response.headers['Content-Type'] = 'text/html';\r\n\r\n    context.response.send(text);\r\n}\r\n\r\n```\r\n\r\n<a name=\"template_context\" />\r\n### context\r\n\r\neach template is passed a data context. this context allows the caller to \r\nsend data to the template for rendering. the context parameter is optional.\r\nthe example below is sending the users array to the template context for \r\nrendering.\r\n\r\n```\r\nexport function index(context) {\r\n\t\r\n    var users  = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    context.response.send(context.template.render('./view.txt', { users: users }));\r\n}\r\n```\r\n\r\n<a name=\"template_syntax\" />\r\n### syntax\r\n\r\nappex templates support the following statements and syntax\r\n\r\n#### if statement\r\n\r\nif statments are supported.\r\n\r\n```\r\n@if(expression) {\r\n\tsome content\r\n}\r\n\r\n@if(a > 10) {\r\n\tsome content\r\n}\r\n\r\n@(user.loggedin) {\r\n\t<span>welcome</span>\r\n}\r\n```\r\n\r\n#### for statement\r\n\r\nthe following for loops are supported.\r\n\r\n```\r\n@for(var i = i; i < 100; i++) {\r\n\t@(i)\r\n}\r\n\r\n@for(var n in list) {\r\n\t@(list[n])\r\n}\r\n```\r\n\r\n#### expressions\r\n\r\nwill emit the value contained.\r\n\r\n```\r\n@('hello world')\r\n\r\n@(123)\r\n\r\n@(some_variable)\r\n```\r\n\r\n#### code blocks\r\n\r\ncode blocks can be useful for adding template side rendering logic.\r\n\r\n```\r\n@{\r\n\tvar message = 'hello'\r\n}\r\n\r\n@(message)\r\n```\r\n\r\n#### comments\r\n```\r\n@*\r\n\tthis comment will not be rendered!\r\n*@\r\n```\r\n\r\n<a name=\"template_layouts_and_sections\" />\r\n### layouts and sections\r\n\r\nappex templates support template inheritance.\r\n\r\nconsider the following where layout.txt defines the sections 'header' and 'content' and the view.txt overrides\r\nthese sections with its own content.\r\n\r\n```\r\n//----------------------------------------------\r\n// layout.txt\r\n//----------------------------------------------\r\n\r\n<html>\r\n\r\n\t<head>\r\n\t\t\r\n\t\t@section header\r\n\r\n\t</head>\r\n\r\n\t<body>\r\n\r\n\t\t@section content {\r\n\t\t\r\n\t\t\t<span>some default content</span>\r\n\t\t\t\r\n\t\t}\r\n\r\n\t</body>\r\n\t\r\n</html>\r\n\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n@layout 'layout.txt'\r\n\r\n@section header {\r\n\r\n\t<title>my page</title>\r\n}\r\n\r\n@section content {\r\n\r\n\t<p>overriding the layout.txt content section.</p>\r\n\r\n\t<ul>\r\n\t@for(var n in context.users) {\r\n\r\n\t\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t\t<li>@(context.users[n].name)</li>\r\n\t\t}\r\n\t}\r\n\t</ul>\r\n}\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\r\n    context.response.send(text);\r\n}\r\n```\r\n\r\nnote : when specifying a layout, the view will only render content within\r\nthe layouts section placeholders. \r\n\r\n<a name=\"render\" />\r\n### render\r\n\r\nappex templates also allow for partial views with the @render statment. consider the following \r\nwhich renders the nav.txt file into the layout.txt file.\r\n\r\n```\r\n//----------------------------------------------\r\n// nav.txt\r\n//----------------------------------------------\r\n<ul>\r\n\t<li>home</li>\r\n\t<li>about</li>\r\n\t<li>contact</li>\r\n</ul>\r\n\r\n//----------------------------------------------\r\n// layout.txt\r\n//----------------------------------------------\r\n\r\n<html>\r\n\t<head>\r\n\t\t\r\n\t\t@section header\r\n\r\n\t</head>\r\n\r\n\t<body>\r\n\t\t\r\n\t\t@render 'nav.txt'\r\n\r\n\t\t@section content {\r\n\t\t\r\n\t\t\t<span>some default content</span>\r\n\t\t\t\r\n\t\t}\r\n\r\n\t</body>\r\n\t\r\n</html>\r\n\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n@layout 'layout.txt'\r\n\r\n@section header {\r\n\r\n\t<title>my page</title>\r\n}\r\n\r\n@section content {\r\n\r\n\t<p>overriding the layout.txt content section.</p>\r\n\r\n\t<ul>\r\n\t@for(var n in context.users) {\r\n\r\n\t\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t\t<li>@(context.users[n].name)</li>\r\n\t\t}\r\n\t}\r\n\t</ul>\r\n}\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\r\n    context.response.send(text);\r\n}\r\n```\r\n\r\n<a name=\"caching_and_devmode\" />\r\n### caching and devmode\r\n\r\nappex template content is not cached (the implementor is expected to handle their own caching)\r\nhowever the generated template code is. \r\n\r\nappex templates do inheriate the behaviour of the appex 'devmode' option. setting\r\ndevmode to 'true' will cause template code to be reloaded from disk and code generated with each \r\nrequest. setting devmode to false will load content from disk on first request, and \r\ncache the generated template code in memory for the lifetime of the application.\r\n\r\nin addition to this, a implementation where the devmode is false can override the caching \r\nbehaviour with the following.\r\n\r\n```javascript\r\nexport function index(context) {\r\n\r\n\t// manually override the template devmode option.\r\n\tcontext.template.option.devmode = true; \r\n\r\n\tcontext.response.send(context.template.render('./view.txt'))\r\n}\r\n```\r\n\r\n<a name=\"sitemaps\" />\r\n## sitemaps\r\n\r\nappex is able to derive sitemap metadata automatically from http endpoints created with\r\ntypescript modules and functions. This metadata is useful to generate sitemap.xml\r\nfiles, as well as helping to create site navigation links when combined a template\r\nengine.\r\n\r\n<a name=\"sitemap_generate\" />\r\n### generate sitemap\r\n\r\nappex sitemaps can be obtained from the context.sitemap property. \r\n\r\n```javascript\r\nexport function index(context) {\r\n\r\n\t// return all nodes in this site.\r\n\tcontext.response.json(context.sitemap)\r\n\r\n}\r\n```\r\n\r\nAdditionally, it may be helpful to isolate branches of the sitemap with the \r\ncontext.sitemap.get([qualifier]) function. as demonstrated below.\r\n\r\n```javascript\r\nexport module admin {\r\n\r\n\texport function index     (context) { }\r\n\r\n\texport function dashboard (context) { }\r\n\r\n\texport function content   (context) { }\r\n\r\n\texport module users {\r\n\r\n\t\texport function login(context) { }\r\n\r\n\t\texport function logout(context) { }\r\n\t}\r\n}\r\n\r\nexport function test(context) {\r\n\t\r\n\t// view all admin sitemap nodes\r\n\tcontext.response.json(context.sitemap.get('admin'))\r\n\r\n\t// view all admin.users sitemap nodes\r\n\t//context.response.json(context.sitemap.get('admin.users'))\r\n}\r\n```\r\n\r\n<a name=\"sitemap_metadata\" />\r\n### cascade metadata\r\n\r\neach sitemap node contains the cascade applied to the handler for which the node applies. With this\r\ndevelopers can apply custom metadata for a given node. as demonstrated below.\r\n\r\n```javascript\r\ndeclare var cascade;\r\n\r\ncascade({website:'http://mysite.com/'}) // global\r\n\r\ncascade('index', {title:'home page'})\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('index')\r\n}\r\n\r\ncascade('about', {title: 'about page'})\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about')\r\n}\r\n\r\ncascade('sitemap', {title: 'sitemap page'})\r\nexport function sitemap(context) {\r\n\r\n\tcontext.response.json(context.sitemap)\r\n}\r\n```\r\n\r\nvisiting /sitemap will output the following.\r\n\r\n```javascript\r\n{\r\n    \"name\": \"sitemap\",\r\n    \"nodes\": [\r\n        {\r\n            \"name\": \"index\",\r\n            \"urls\": [\r\n                \"/\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"home page\"\r\n        },\r\n        {\r\n            \"name\": \"about\",\r\n            \"urls\": [\r\n                \"/about\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"about page\"\r\n        },\r\n        {\r\n            \"name\": \"sitemap\",\r\n            \"urls\": [\r\n                \"/sitemap\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"sitemap page\"\r\n        }\r\n    ]\r\n}\r\n```\r\n\r\n<a name=\"json_schema\" />\r\n## json schema\r\n\r\nappex provides functionality for generating json schemas from TypeScript classes\r\nand interfaces as well as tools for validating json data.\r\n\r\n<a name=\"generating_schema\" />\r\n### generating schema\r\n\r\nThe following demonstrates generating json schema from the following class\r\nhierarchy.\r\n\r\n```javascript\r\nexport module model {\r\n\r\n    /** a product */\r\n    export class Product {\r\n        \r\n        /** the product name */\r\n        public name        : string;\r\n\r\n        /** the product description */\r\n        public description : string;\r\n\r\n        /** the product cost */\r\n        public cost        : number;\r\n    } \r\n\r\n    /** a order */\r\n    export class Order {\r\n        \r\n        /** the product being ordered */\r\n        public products  : Product;\r\n    }\r\n\r\n    /** a customer */\r\n    export class Customer {\r\n\r\n        /** the customers firstname */\r\n        public firstname  : string;\r\n\r\n        /** the customers lastname */\r\n        public lastname   : string;\r\n\r\n        /** orders made by this customer */\r\n        public orders     : Order[];\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.IContext) {\r\n\t\r\n\t// pass the fully qualified name of the type.\r\n    var schema = context.schema.generate('model.Customer');\r\n\r\n    context.response.json(schema);\r\n}\r\n```\r\n\r\nwhich generates the following json schema.\r\n\r\n```javascript\r\n{\r\n    \"id\": \"model.Customer\",\r\n    \"type\": \"object\",\r\n    \"description\": \"a customer\",\r\n    \"properties\": {\r\n        \"firstname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers firstname\",\r\n            \"required\": true\r\n        },\r\n        \"lastname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers lastname\",\r\n            \"required\": true\r\n        },\r\n        \"orders\": {\r\n            \"type\": \"array\",\r\n            \"items\": {\r\n                \"type\": {\r\n                    \"id\": \"model.Order\",\r\n                    \"type\": \"object\",\r\n                    \"description\": \"a order\",\r\n                    \"properties\": {\r\n                        \"products\": {\r\n                            \"id\": \"model.Product\",\r\n                            \"type\": \"object\",\r\n                            \"description\": \"a product\",\r\n                            \"properties\": {\r\n                                \"name\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product name\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"description\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product description\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"cost\": {\r\n                                    \"type\": \"number\",\r\n                                    \"description\": \"the product cost\",\r\n                                    \"required\": true\r\n                                }\r\n                            },\r\n                            \"required\": true\r\n                        }\r\n                    }\r\n                }\r\n            },\r\n            \"description\": \"orders made by this customer\",\r\n            \"required\": true\r\n        }\r\n    }\r\n}\r\n```\r\na quick note...\r\n\r\nwhen generating schema from classes:\r\n\r\n* only public class variables will be emitted.\r\n* all properties will be marked as \"required\".\r\n\r\nwhen generating schema from interfaces:\r\n\r\n* all properties will be emitted. \r\n* all properties will be marked as \"required\" unless modified with '?'.\r\n\r\n<a name=\"validating_json\" />\r\n### validating json\r\n\r\nappex supports json schema validation from class and interface definitions. consider the following...\r\n\r\n```javascript\r\ninterface Customer {\r\n\r\n    firstname    : string;\r\n\r\n    lastname     : string;\r\n\r\n    age          : number;\r\n\r\n    emails       : string[];\r\n\r\n    option_a ?   : boolean; // optional\r\n\r\n    option_b ?   : boolean; // optional\r\n\r\n}\r\n\r\nexport function index(context) {\r\n\r\n    // a customer with invalid data.\r\n\r\n    var customer = {\r\n\r\n        firstname    : 'dave',\r\n\r\n        age          : '33',\r\n\r\n        emails       : [12345, 'dave@domain.com', true],\r\n\r\n        option_b     : 1,\r\n\r\n        option_c     : 1\r\n    }\r\n\r\n    // do validation.\r\n\r\n    var errors = context.schema.validate('Customer', customer);\r\n\r\n    if(errors) {\r\n\r\n        context.response.json(errors);\r\n    }\r\n}\r\n```\r\n\r\nwill output the following.\r\n\r\n```javascript\r\n[\r\n    {\r\n        \"message\": \"instance.lastname is required.\"\r\n    },\r\n    {\r\n        \"message\": \"instance.age is not a number\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[0] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[2] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_b is not a boolean\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_c unexpected property\"\r\n    }\r\n]\r\n```\r\n\r\n<a name=\"web_service_descriptions\">\r\n### web service descriptions\r\n\r\nFor those using appex for web services, developers can leverage appex json schema generation\r\nto generate endpoint metadata (think wsdl). Consider the following which leverages both appex \r\nschema generation and cascades to produce a metadata endpoint consumers of your\r\napi can use to see what data the endpoint http://example.com/customer/create accepts \r\nand returns.\r\n\r\n```javascript\r\nclass Request {\r\n\r\n    /** the customers firstname */\r\n    firstname : string;\r\n\r\n    /** the customers lastname */\r\n    lastname  : string;\r\n\r\n\t/** the customers lastname */\r\n}\r\n\r\nclass Response {\r\n\r\n    /** true on success  */\r\n    success:boolean;\r\n    \r\n    /** an array of validation errors  */\r\n    errors : string[];\r\n}\r\n\r\ncascade('metadata', {input  : 'Request', output : 'Response'})\r\nexport function metadata(context:appex.web.IContext) {\r\n\r\n    var metadata = {\r\n        \r\n\t\tendpoint : 'http://example.com/customer/create',\r\n\r\n        input    : context.schema.generate(context.cascade.input),\r\n\r\n        output   : context.schema.generate(context.cascade.output)\r\n    }\r\n\r\n    context.response.json(metadata)\r\n}\r\n```\r\n\r\nwhich outputs the following.\r\n\r\n```javascript\r\n{\r\n    \"endpoint\": \"http://example.com/customer/create\",\r\n    \"input\": {\r\n        \"id\": \"Request\",\r\n        \"type\": \"object\",\r\n        \"properties\": {\r\n            \"firstname\": {\r\n                \"type\": \"string\",\r\n                \"description\": \"the customers firstname\",\r\n                \"required\": true\r\n            },\r\n            \"lastname\": {\r\n                \"type\": \"string\",\r\n                \"description\": \"the customers lastname\",\r\n                \"required\": true\r\n            }\r\n        }\r\n    },\r\n    \"output\": {\r\n        \"id\": \"Response\",\r\n        \"type\": \"object\",\r\n        \"properties\": {\r\n            \"success\": {\r\n                \"type\": \"boolean\",\r\n                \"description\": \"true on success\",\r\n                \"required\": true\r\n            },\r\n            \"errors\": {\r\n                \"type\": \"array\",\r\n                \"description\": \"an array of validation errors\",\r\n                \"items\": {\r\n                    \"type\": \"string\"\r\n                },\r\n                \"required\": true\r\n            }\r\n        }\r\n    }\r\n}\r\n```\r\ntip: use the appex sitemap metadata to produce a metadata endpoint for all service methods \r\nin your application.\r\n\r\n\r\n<a name=\"reflection\" />\r\n## reflection\r\n\r\nappex provides a reflection api derived from TypeScript's type system that developers can \r\nleverage to reflect type information declared throughout their appex modules. \r\n\r\nthe following section outlines how to use the reflection api.\r\n\r\n<a name=\"reflect_everything\" />\r\n### reflect everything\r\n\r\nthe appex reflection api is passed on the context.module.reflection property and is available to all\r\nappex handler methods. The following code will JSON serialize everything declared in your appex\r\nproject and write it to the http response. \r\n\r\n```javascript\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection );\r\n}\r\n```\r\n\r\n<a name=\"reflect_specific_types\" />\r\n### reflect specific types\r\n\r\nIn typical scenarios, developers will want to leverage reflection meta data to generate\r\nservice contacts and client side models. the reflection api lets you access meta data \r\nfor the following types declared in your project. \r\n\r\n* modules\r\n* imports\r\n* classes\r\n* interfaces\r\n* functions\r\n* variables\r\n\r\nto access specific type metadata, use the reflection.get([qualifier]) method, as demonstrated below.\r\n\r\n```javascript\r\nexport module model {\r\n    \r\n    export class Customer {\r\n\r\n        public firstname   : string;\r\n\r\n        public lastname    : string;\r\n\r\n        public age         : number;\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('model.Customer') );\r\n}\r\n```\r\nand methods..\r\n\r\n```javascript\r\nfunction some_method(a:string, b:number, c?:boolean) : void { }\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_method') );\r\n}\r\n```\r\n\r\n....and variables...\r\n\r\n```javascript\r\nvar some_variable:number = 10;\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_variable') );\r\n}\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\nThis section outlines development with appex.\r\n\r\n<a name=\"appex_declaration\" />\r\n### appex.d.ts declaration\r\n\r\nIf you develop on a TypeScript complicant editor (one that supports TS 0.9), appex comes bundled\r\nwith a declaration file you can reference in your project. If installing appex via npm, your\r\nreference should be as follows.\r\n\r\n```javascript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nexport function index (context:appex.web.IContext) { \r\n    \r\n    context.response.send('hello');\r\n}\r\n\r\nexport function wildcard(context:appex.web.IContext, path:string) {\r\n\r\n    context.response.serve('./', path);\r\n}\r\n```\r\n\r\nBy referencing this in your project, you get the benefits of code completion and static type checking\r\nagainst both appex, and the nodejs core.\r\n\r\n![](https://raw.github.com/sinclairzx81/appex/master/artifacts/code-completion.jpg)\r\n\r\nAdditional declaration files may be obtained from [here](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex ({ program : './index.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"users.ts\" />\r\n/// <reference path=\"pages.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { context.response.send('users.login') }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { context.response.send('users.logout') }\r\n}\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { context.response.send('home') }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { context.response.send('about') }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { context.response.send('contact') }\r\n\r\nexport function wildcard (context, path) { context.response.send(404, ' not found') }\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"license\" />\r\n## license\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) 2013 Haydn Paterson (sinclair) <haydn.developer@gmail.com>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in\r\nall copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\nTHE SOFTWARE.\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"https://raw.github.com/sinclairzx81/appex/master/license.txt","type":"The MIT License (MIT)"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"develop nodejs web applications with typescript","directories":{},"dependencies":{"typescript.api":"0.7.3"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.6.5":{"name":"appex","version":"0.6.5","keywords":["typescript","web api","reflection","compiler","schema","templates","sitemap"],"author":{"name":"sinclair"},"_id":"appex@0.6.5","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"fa9d6c52f64ff07d48b3f5fda0fb0f2b1dc28b65","tarball":"https://registry.npmjs.org/appex/-/appex-0.6.5.tgz","integrity":"sha512-kVd2ms0ML1iCfMdHdK7CAoGM5yBTKc1hnMpHnp0q5zDkZOezwn6qfhHEvg+T417va6NYS1LUizXWpw/NgfkM1g==","signatures":[{"sig":"MEUCIQDgtIrt+XvP6/GZZOvPA6gjfsujkT9hIF5fZyzD4bFJJgIgactkkd7MWyaac0s2sl7jw4huwgvwZtr5dEaENwAKcns=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/artifacts/logo.jpg)\r\n\r\n### develop nodejs web applications with [typescript](http://www.typescriptlang.org/)\r\n\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nexport function index(context:appex.web.IContext) {\r\n\t\r\n\tcontext.response.send('home page');\r\n}\r\n\r\nexport function about(context:appex.web.IContext) {\r\n\t\r\n\tcontext.response.send('about page');\r\n}\r\n\r\nexport function wildcard (context:appex.web.IContext, path:string) {\r\n    \r\n    context.response.send(404, path + \" not found\");\r\n}\r\n\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n### contents\r\n\r\n* [getting started](#getting_started)\r\n\t* [create a application](#application)\r\n\t* [start up options](#options)\r\n\t* [running on an existing http server](#http_server)\r\n\t* [running as express middleware](#express_middleware)\r\n* [http handlers](#http_handlers)\r\n\t* [context](#context)\r\n\t* [request](#request)\r\n\t* [response](#response)\r\n\t* [routing](#routing)\r\n\t* [signatures](#signatures)\r\n\t* [named handlers](#named_handlers)\r\n\t* [index handlers](#index_handlers)\r\n\t* [wildcard handlers](#wildcard_handlers)\r\n\t* [attributes](#attributes)\r\n\t* [verbs](#verbs)\r\n\t* [url rewrite](#url_rewrite)\r\n\t* [middleware](#middleware)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [handling 404](#handling_404)\r\n\t* [serving static files](#serving_static_files)\r\n* [templating](#templating)\r\n\t* [overview](#template_overview)\r\n\t* [context](#template_context)\t\r\n\t* [syntax](#template_syntax)\r\n\t* [layouts and sections](#template_layouts_and_sections)\r\n\t* [render](#template_render)\r\n\t* [caching and devmode](#caching_and_devmode)\r\n* [sitemaps](#sitemaps)\r\n\t* [generating](#sitemap_generate)\r\n\t* [metadata](#sitemap_metadata)\r\n* [json schema](#json_schema)\r\n\t* [generating schema](#generating_schema)\r\n\t* [validating json](#validating_json)\r\n\t* [web service descriptions](#web_service_descriptions)\r\n* [reflection](#reflection)\r\n\t* [reflect everything](#reflect_everything)\r\n\t* [reflect specific types](#reflect_specific_types)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [appex.d.ts declaration](#appex_declaration)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n* [license](#license)\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline creating appex applications and configuration.\r\n\r\n<a name=\"application\" />\r\n### create a application\r\n\r\nThe following code will create a standalone appex application and \r\nhttp server and listen on port 3000.\r\n\r\n```javascript\r\nvar appex   = require('appex');\r\n\r\nvar app   = appex({ program : './program.ts', \r\n                    devmode : true,\r\n                    logging : true });\r\n\r\napp.listen(3000);\r\n```\r\n\r\nnote: devmode and logging are optional. however, when developing \r\nwith appex, it is helpful to have these enabled.\r\n\r\n<a name=\"options\" />\r\n### start up options\r\n\r\nappex accepts the following start up options.\r\n\r\n```javascript\r\nvar options = {\r\n\r\n\t// (required) location of source file.\r\n\tprogram    : './program.ts', \r\n\r\n\t// (optional) recompile on request. (default:false) \r\n\tdevmode    : true,          \r\n\r\n\t// (optional) log to stdout. (default:false) \r\n\tlogging    : true,\r\n\r\n\t// (optional) user defined objects added to the app context.\r\n\tcontext    : {}\r\n};\r\n\r\nvar app = appex( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### running on an existing http server\r\n\r\nThe following demonstrates setting up appex on an existing nodejs http server. In \r\nthis example, appex will attempt to handle incoming requests, and if appex cannot\r\nroute the request, will fire the callback.\r\n\r\n```javascript\r\nvar http  = require('http');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\nvar server = http.createServer(function(req, res){\r\n\r\n    app(req, res, function() { // appex handler...\r\n\t\t\r\n\t\t// not handled.\r\n\r\n\t}); \r\n});\r\n\r\nserver.listen(3000);\r\n```\r\n\r\n<a name=\"express_middleware\" />\r\n### running as express middleware\r\n\r\nappex allows developers to augment existing express / connect applications by \r\nway of middleware. The following demonstrates setting up appex as express middleware.\r\n\r\n```javascript\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) ); \r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nLike in the \"running on an existing http server\" example above, appex will attempt to intercept incoming requests. \r\nif appex cannot find a matching route for the request, it will automatically call the \"next\" function to pass the request \r\non to the next middleware or express handler.\r\n\r\nin addition to this, appex may also act as traditional express middleware. In the example below, a appex wildcard\r\nfunction is created which will match \"all\" incoming requests, the wildcard function simply prints hello world to \r\nthe console and then calls context.next(), which passes the request on the express handler.\r\n\r\n```javascript\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tconsole.log('hello world!!');\r\n\r\n\tcontext.next(); // pass it on!\r\n}\r\n\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) );\r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nJust like traditional express middleware, appex will also inheriate the characteristics of the request.\r\n\r\nconsider the following example in which the jade view engine is configured for use. appex will inheritate the \r\nresponse.render() method, which is passed to the appex handler as context.response.render()\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\napp.configure(function(){\r\n\r\n  app.set('views', __dirname + '/views');\r\n  \r\n  // set up the jade engine.\r\n  app.set('view engine', 'jade'); \r\n  \r\n  // bind appex\r\n  app.use( appex({program:'./program.ts', devmode:true} ));  \r\n});\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/\r\nexport function index(context) {\r\n\t\r\n\t// jade renderer works!\r\n\tcontext.response.render('index', { title: 'Express' }); \r\n}\r\n```\r\n\r\n<a name=\"http_handlers\" />\r\n## http handlers\r\n\r\nThe following sections describe how to create http accessible handlers with appex.\r\n\r\n<a name=\"context\" />\r\n### context\r\n\r\nAll appex functions are passed a application context object as their first argument. The app context object \r\nencapulates the http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the app context\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.attribute    - appex attribute.\r\n\r\n\t// context.next       - the next function (express middleware)\r\n\t\r\n\t// context.router     - the appex router\r\n\r\n\t// context.sitemap    - the appex sitemap api\r\n\r\n\t// context.template   - the appex template engine.\r\n\t\r\n\t// context.module     - the module being run (this module)\r\n\r\n\t// context.schema     - json schema api.\r\n\r\n\t// context.mime       - a http mime type utility.\r\n}\r\n```\r\n\r\nit is possible to extend the default objects passed on the context by adding them on the appex startup options. The \r\nfollowing will attach the async module to the context. \r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = appex({ program : './program.ts', \r\n\t\t\t\t  devmode : true, \r\n\t\t\t      context: {\r\n\t\t\t\t\t\tasync : require('async')\r\n\t\t\t\t  }});\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\r\n\t// context.async = passed on the context.\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n```\r\n<a name=\"request\" />\r\n### request\r\n\r\nThe appex request is a nodejs http request issued by the underlying node http server. \r\nappex extends the request with convenience methods for reading http request data. These\r\nare outlined below.\r\n\r\nreading a posted string. \r\n```javascript\r\n//----------------------------------------------\r\n// receive request as a string\r\n//----------------------------------------------\r\nexport function submit(context) {\r\n\r\n\tcontext.request.body.recv((str) => {\r\n\r\n\t\t// do something with str\r\n\t})\r\n}\r\n```\r\nreading posted form data as json object.\r\n```javascript\r\n//----------------------------------------------\r\n// receive a form post\r\n//----------------------------------------------\r\nexport function submit(context) {\r\n\r\n\tcontext.request.body.form((obj) => {\r\n\r\n\t\t// do something with obj\r\n\t})\r\n}\r\n```\r\nreading posted json data as a json object.\r\n```javascript\r\n//----------------------------------------------\r\n// receive a json post\r\n//----------------------------------------------\r\nexport function submit(context) {\r\n\r\n\tcontext.request.body.json((obj) => {\r\n\t\t\r\n\t\t// do something with obj\r\n\t})\r\n}\r\n```\r\n\r\nnote: if appex detects that express or connect middleware has already been applied\r\nto the request object, appex will use those instead.\r\n\r\n<a name=\"response\" />\r\n### response\r\n\r\nThe appex response is a nodejs http response issued by the underlying node http server. \r\nappex provides some utility methods for writing http responses. These are outlined below.\r\n\r\n```js\r\n//----------------------------------------------\r\n// the nodejs response has been extended with the following\r\n// signatures.\r\n//----------------------------------------------\r\nexport interface IResponse extends http.ServerResponse {\r\n\t\r\n\tsend (data     : string): void;\r\n\r\n\tsend (data     : NodeBuffer): void;\r\n\r\n\tsend (status   : number, data : string): void;\r\n\r\n\tserve (filepath: string): void;\r\n\r\n\tserve (root : string, filepath: string): void;\r\n\r\n\tserve (root : string, filepath: string, mime:string): void;\r\n\r\n\tjson (obj      : any): void;\r\n\r\n\tjson (status   : number, obj : any): void;\r\n\r\n\tjsonp (obj     : any): void;\r\n\r\n\tjsonp (status  : number, obj : any): void;\r\n\r\n\tjsonp (status  : number, obj : any, callback: string): void;\r\n}\r\n```\r\n\r\nnote: if appex detects that express or connect middleware has already been applied\r\nto for any of the following response methods, appex will use those instead.\r\n\r\n<a name=\"routing\" />\r\n### routing\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context) {\r\n\r\n\t\tcontext.response.send('services.customers.insert')\r\n    }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context) { \r\n\t\t\r\n\t\tcontext.response.send('services.customers.update')\r\n    }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context) { \r\n\r\n\t\tcontext.response.send('services.customers.delete')\r\n\t}\r\n}\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context) { \r\n\r\n\tcontext.response.send('home page')\r\n}\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context) { \r\n\r\n\tcontext.response.send('about page')\r\n}\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context) { \r\n\r\n\tcontext.response.send('contact page')\r\n}\r\n\r\n// url: http://[host]:[port]/(.*)\r\nexport function wildcard (context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found')\r\n}\r\n\r\n```\r\n\r\n<a name=\"signatures\" />\r\n### signatures\r\n\r\nappex supports three function signatures for http routing (named, index and wildcard). Functions that\r\ndo not apply these signatures will not be routed.\r\n\r\n<a name=\"named_handlers\" />\r\n### named handlers\r\n\r\nNamed handlers resolve urls to their current module scope + the name of the function.\r\n\r\nNamed handlers require the following signature:\r\n\r\n* name        - 'anything'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n\r\n// http://[host]:[port]/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about page');\r\n}\r\n\r\n// http://[host]:[port]/users/login\r\nexport module users {\r\n\r\n\texport function login(context) {\r\n\t\t\r\n\t\tcontext.response.send('handle login');\t\r\n\t}\r\n}\r\n\r\n```\r\n\r\n<a name=\"index_handlers\" />\r\n### index handlers\r\n\r\nIndex handlers resolve urls to their current module scope.\r\n\r\nIndex handlers require the following signature:\r\n\r\n* name        - 'index'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) \r\n\t{\t\r\n\t\tcontext.response.send('blog index');\r\n\t}\r\n}\r\n```\r\n\r\n<a name=\"wildcard_handlers\" />\r\n### wildcard handlers\r\n\r\nWildcard handlers resolve their urls to their current module scope + url.\r\n\r\nappex wildcard handlers allow for wildcard routing at a given module scope. Wildcard handlers\r\nsupport 'typed' url argument mapping, as denoted by the arguments annotation.\r\n\r\nIn addition, wildcard handlers also support optional arguments which can be specified with TypeScript's '?' \r\non argument names.\r\n\r\nappex wildcard handlers require the following signature:\r\n\r\n* name        - 'wildcard'\r\n* argument[0] - app context\r\n* argument[n] - 1 or more arguments to be mapped from the url\r\n* returns     - void (optional)\r\n\r\n```javascript\r\ndeclare var console;\r\n\r\nexport module blogs {\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11   - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/11  - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/3rd - not matched - (see number annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01     - matched     - (see ? annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013        - not matched - (month is required)\r\n\t\r\n    export function wildcard(context, year:number, month:number, day?:number) {\r\n\r\n        context.response.json({ year: year, month: month, day: day})\r\n    }\r\n}\r\n\r\n// url : http://[host]:[port]/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// url : http://[host]:[port]/(.*) \r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, 'not found');\r\n}\r\n\r\n```\r\nnote: appex supports boolean, number, string and any annotations on wildcard arguments. if no annotation\r\nis specified, appex interprets the argument as a string. the type 'any' is also interpreted as string.\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"attributes\" />\r\n### attributes\r\n\r\nappex supports a attribute scheme which developers can use to decorate modules and functions with \r\ndeclaritive metadata. appex attributes can set by calling the attribute('qualifier', data)\r\nfunction which is passed to the appex module on the global scope.\r\n\r\nunlike traditional attributes (in languages like C sharp) appex attributes have a cascading behaviour\r\nwhich allows developers to apply metadata at a lexical scope, and have it cascade through to descendant scopes.\r\n\r\nThe following outlines this behavour.\r\n\r\n```javascript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nattribute({a: 10}); // global.\r\n\r\nattribute('foo', {b : 20})\r\nexport module foo {\r\n\r\n    attribute('foo.bar', {c : 30})\r\n    export module bar {\r\n            \r\n        attribute('foo.bar.index', {d : 40})\r\n        export function index(context) {\r\n        \r\n            //context.attribute\r\n            //{\r\n            //    \"a\": 10,\r\n            //    \"b\": 20,\r\n            //    \"c\": 30,\r\n\t\t\t//    \"d\": 40\r\n            //}\r\n\r\n            context.response.json( context.attribute );       \r\n        }\r\n    }\r\n}\r\n\r\n```\r\n\r\nin addition, appex recognizes three types of attributes. developers can use these to override the default \r\nbahavour of the appex router and apply url rewriting (urls), verb matching (verbs) and middleware (use),\r\nas demonstrated below.\r\n\r\n```javascript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nfunction logger(context) {\r\n\tconsole.log('logging')\r\n\tcontext.next()\r\n}\r\n\r\n// invoke 'logger' middleware.\r\nattribute('index', {use   : [logger]})   \r\n\r\n// override the default route.\r\nattribute('index', {urls  : ['/', '/home']})  \r\n\r\n// only accept GET requests.\r\nattribute('index', {verbs : ['GET']})    \r\n\r\nexport function index(context:appex.web.IContext) {\r\n\t\r\n\tcontext.response.send('home page')\r\n}\r\n```\r\n\r\n<a name=\"verbs\" />\r\n### verbs\r\n\r\nappex handles http verb matching with attributes. appex will recognise the \r\n'verbs' property applied to the attribute to match against http verbs.\r\n\r\n```javascript\r\nattribute('index', { verbs: ['GET'] })\r\nexport function index (context) { \r\n        \r\n    // only allow HTTP GET requests\r\n    context.response.send('index')\r\n}\r\n\r\nattribute('submit', { verbs: ['POST', 'PUT'] })\r\nexport function submit (context) { \r\n    \r\n    // only allow HTTP POST and PUT requests\r\n    context.response.send('submit')\r\n}\r\n```\r\n\r\n<a name=\"url_rewrite\" />\r\n### url rewrite\r\n\r\ndevelopers can rewrite the default route given to exported functions with the 'urls' property applied\r\nto the attribute. \r\n\r\n```javascript\r\nattribute('index', { urls: ['/', '/home', 'home.html'] })\r\nexport function index (context) { \r\n    \r\n    context.response.send('index')\r\n}\r\n```\r\nnote: url rewriting is only available on index and named routes.\r\n\r\nnote: rewriting with regular expressions is currently not supported.\r\n\r\n<a name=\"middleware\" />\r\n### middleware\r\n\r\nappex supports middleware with attributes. appex middleware defined with attributes allows\r\ndevelopers to scope middleware on single functions, or entire module scopes. appex will \r\nrecognise the 'use' property applied to the attribute to invoke middleware.\r\n\r\nthe following demonstrates how one might use middleware to secure a site admin.\r\n\r\nnote: middleware 'must' call next or handle the request. \r\n\r\n```javascript\r\ndeclare function attribute (qualifier:string, obj:any);\r\n\r\ndeclare var console;\r\n\r\nfunction authenticate(context) {\r\n\r\n    console.log('authenticate')\r\n\r\n\t// call next() if authenticated, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\nfunction authorize(context) {\r\n\r\n    console.log('authorize')\r\n\r\n\t// call next() if authorized, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\n// apply security middleware to admin scope.\r\nattribute('admin', {use: [authenticate, authorize]}) \r\nexport module admin {\r\n\r\n    export function index(context) {\r\n        \r\n        console.log(context.attribute); // view attribute\r\n\r\n        context.response.send('access granted!')\r\n    }\r\n}\r\n\r\n// index handler has no middleware applied.\r\nexport function index (context) { \r\n    \r\n    console.log(context.attribute); // view attribute\r\n\r\n    context.response.send('home')\r\n}\r\n```\r\n\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex will only route functions prefixed with the TypeScript 'export' declarer. This rule\r\nalso applied to modules. Developers can use this to infer notions of public and private \r\nat the http level.\r\n\r\nconsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is \r\n// therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private \r\n\t// as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is \r\n\t// private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and \r\n// is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore \r\n// publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke \r\n\t// private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in \r\n\t// private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method \r\n\t// in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.send('public_function');\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```javascript\r\n// http:[host]:[port]/\r\nexport function index (context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard (context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n<a name=\"serving_static_files\" />\r\n## serving static files\r\n\r\nUse wildcard functions with context.response.serve() to serve static content.\r\n\r\n```javascript\r\nexport module static {\r\n\t\r\n\t// http:[host]:[port]/static/(.*)\r\n\texport function wildcard(context, path) {\r\n\r\n\t\tcontext.response.serve('./static/', path);\r\n\t}\r\n}\r\n\r\n// http:[host]:[port]/\r\nexport function index (context) {\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n\r\n<a name=\"templating\" />\r\n## templating\r\n\r\nappex comes bundled with a built in template engine which is modelled on the Microsoft \r\nRazor templating engine. The following sections outline its use.\r\n\r\n<a name=\"template_overview\" />\r\n### overview\r\n\r\nThe appex template engine is available to all handlers by default. it is accessible\r\non the context.template property. the following is an example of its use.\r\n\r\n```\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n<ul>\r\n@for(var n in context.users) {\r\n\r\n\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t<li>@(context.users[n].name)</li>\r\n\t}\r\n}\r\n</ul>\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\t\r\n\tcontext.response.headers['Content-Type'] = 'text/html';\r\n\r\n    context.response.send(text);\r\n}\r\n\r\n```\r\n\r\n<a name=\"template_context\" />\r\n### context\r\n\r\neach template is passed a data context. this context allows the caller to \r\nsend data to the template for rendering. the context parameter is optional.\r\nthe example below is sending the users array to the template context for \r\nrendering.\r\n\r\n```\r\nexport function index(context) {\r\n\t\r\n    var users  = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    context.response.send(context.template.render('./view.txt', { users: users }));\r\n}\r\n```\r\n\r\n<a name=\"template_syntax\" />\r\n### syntax\r\n\r\nappex templates support the following statements and syntax\r\n\r\n#### if statement\r\n\r\nif statments are supported.\r\n\r\n```\r\n@if(expression) {\r\n\tsome content\r\n}\r\n\r\n@if(a > 10) {\r\n\tsome content\r\n}\r\n\r\n@(user.loggedin) {\r\n\t<span>welcome</span>\r\n}\r\n```\r\n\r\n#### for statement\r\n\r\nthe following for loops are supported.\r\n\r\n```\r\n@for(var i = i; i < 100; i++) {\r\n\t@(i)\r\n}\r\n\r\n@for(var n in list) {\r\n\t@(list[n])\r\n}\r\n```\r\n\r\n#### expressions\r\n\r\nwill emit the value contained.\r\n\r\n```\r\n@('hello world')\r\n\r\n@(123)\r\n\r\n@(some_variable)\r\n```\r\n\r\n#### code blocks\r\n\r\ncode blocks can be useful for adding template side rendering logic.\r\n\r\n```\r\n@{\r\n\tvar message = 'hello'\r\n}\r\n\r\n@(message)\r\n```\r\n\r\n#### comments\r\n```\r\n@*\r\n\tthis comment will not be rendered!\r\n*@\r\n```\r\n\r\n<a name=\"template_layouts_and_sections\" />\r\n### layouts and sections\r\n\r\nappex templates support template inheritance.\r\n\r\nconsider the following where layout.txt defines the sections 'header' and 'content' and the view.txt overrides\r\nthese sections with its own content.\r\n\r\n```\r\n//----------------------------------------------\r\n// layout.txt\r\n//----------------------------------------------\r\n\r\n<html>\r\n\r\n\t<head>\r\n\t\t\r\n\t\t@section header\r\n\r\n\t</head>\r\n\r\n\t<body>\r\n\r\n\t\t@section content {\r\n\t\t\r\n\t\t\t<span>some default content</span>\r\n\t\t\t\r\n\t\t}\r\n\r\n\t</body>\r\n\t\r\n</html>\r\n\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n@layout 'layout.txt'\r\n\r\n@section header {\r\n\r\n\t<title>my page</title>\r\n}\r\n\r\n@section content {\r\n\r\n\t<p>overriding the layout.txt content section.</p>\r\n\r\n\t<ul>\r\n\t@for(var n in context.users) {\r\n\r\n\t\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t\t<li>@(context.users[n].name)</li>\r\n\t\t}\r\n\t}\r\n\t</ul>\r\n}\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\r\n    context.response.send(text);\r\n}\r\n```\r\n\r\nnote : when specifying a layout, the view will only render content within\r\nthe layouts section placeholders. \r\n\r\n<a name=\"render\" />\r\n### render\r\n\r\nappex templates also allow for partial views with the @render statment. consider the following \r\nwhich renders the nav.txt file into the layout.txt file.\r\n\r\n```\r\n//----------------------------------------------\r\n// nav.txt\r\n//----------------------------------------------\r\n<ul>\r\n\t<li>home</li>\r\n\t<li>about</li>\r\n\t<li>contact</li>\r\n</ul>\r\n\r\n//----------------------------------------------\r\n// layout.txt\r\n//----------------------------------------------\r\n\r\n<html>\r\n\t<head>\r\n\t\t\r\n\t\t@section header\r\n\r\n\t</head>\r\n\r\n\t<body>\r\n\t\t\r\n\t\t@render 'nav.txt'\r\n\r\n\t\t@section content {\r\n\t\t\r\n\t\t\t<span>some default content</span>\r\n\t\t\t\r\n\t\t}\r\n\r\n\t</body>\r\n\t\r\n</html>\r\n\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n@layout 'layout.txt'\r\n\r\n@section header {\r\n\r\n\t<title>my page</title>\r\n}\r\n\r\n@section content {\r\n\r\n\t<p>overriding the layout.txt content section.</p>\r\n\r\n\t<ul>\r\n\t@for(var n in context.users) {\r\n\r\n\t\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t\t<li>@(context.users[n].name)</li>\r\n\t\t}\r\n\t}\r\n\t</ul>\r\n}\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\r\n    context.response.send(text);\r\n}\r\n```\r\n\r\n<a name=\"caching_and_devmode\" />\r\n### caching and devmode\r\n\r\nappex template content is not cached (the implementor is expected to handle their own caching)\r\nhowever the generated template code is. \r\n\r\nappex templates do inheriate the behaviour of the appex 'devmode' option. setting\r\ndevmode to 'true' will cause template code to be reloaded from disk and code generated with each \r\nrequest. setting devmode to false will load content from disk on first request, and \r\ncache the generated template code in memory for the lifetime of the application.\r\n\r\nin addition to this, a implementation where the devmode is false can override the caching \r\nbehaviour with the following.\r\n\r\n```javascript\r\nexport function index(context) {\r\n\r\n\t// manually override the template devmode option.\r\n\tcontext.template.option.devmode = true; \r\n\r\n\tcontext.response.send(context.template.render('./view.txt'))\r\n}\r\n```\r\n\r\n<a name=\"sitemaps\" />\r\n## sitemaps\r\n\r\nappex is able to derive sitemap metadata automatically from http endpoints created with\r\ntypescript modules and functions. This metadata is useful to generate sitemap.xml\r\nfiles, as well as helping to create site navigation links when combined a template\r\nengine.\r\n\r\n<a name=\"sitemap_generate\" />\r\n### generate sitemap\r\n\r\nappex sitemaps can be obtained from the context.sitemap property. \r\n\r\n```javascript\r\nexport function index(context) {\r\n\r\n\t// return all nodes in this site.\r\n\tcontext.response.json(context.sitemap)\r\n\r\n}\r\n```\r\n\r\nAdditionally, it may be helpful to isolate branches of the sitemap with the \r\ncontext.sitemap.get([qualifier]) function. as demonstrated below.\r\n\r\n```javascript\r\nexport module admin {\r\n\r\n\texport function index     (context) { }\r\n\r\n\texport function dashboard (context) { }\r\n\r\n\texport function content   (context) { }\r\n\r\n\texport module users {\r\n\r\n\t\texport function login(context) { }\r\n\r\n\t\texport function logout(context) { }\r\n\t}\r\n}\r\n\r\nexport function test(context) {\r\n\t\r\n\t// view all admin sitemap nodes\r\n\tcontext.response.json(context.sitemap.get('admin'))\r\n\r\n\t// view all admin.users sitemap nodes\r\n\t//context.response.json(context.sitemap.get('admin.users'))\r\n}\r\n```\r\n\r\n<a name=\"sitemap_metadata\" />\r\n### attribute metadata\r\n\r\neach sitemap node contains the attribute applied to the handler for which the node applies. With this\r\ndevelopers can apply custom metadata for a given node. as demonstrated below.\r\n\r\n```javascript\r\ndeclare var attribute;\r\n\r\nattribute({website:'http://mysite.com/'}) // global\r\n\r\nattribute('index', {title:'home page'})\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('index')\r\n}\r\n\r\nattribute('about', {title: 'about page'})\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about')\r\n}\r\n\r\nattribute('sitemap', {title: 'sitemap page'})\r\nexport function sitemap(context) {\r\n\r\n\tcontext.response.json(context.sitemap)\r\n}\r\n```\r\n\r\nvisiting /sitemap will output the following.\r\n\r\n```javascript\r\n{\r\n    \"name\": \"sitemap\",\r\n    \"nodes\": [\r\n        {\r\n            \"name\": \"index\",\r\n            \"urls\": [\r\n                \"/\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"home page\"\r\n        },\r\n        {\r\n            \"name\": \"about\",\r\n            \"urls\": [\r\n                \"/about\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"about page\"\r\n        },\r\n        {\r\n            \"name\": \"sitemap\",\r\n            \"urls\": [\r\n                \"/sitemap\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"sitemap page\"\r\n        }\r\n    ]\r\n}\r\n```\r\n\r\n<a name=\"json_schema\" />\r\n## json schema\r\n\r\nappex provides functionality for generating json schemas from TypeScript classes\r\nand interfaces as well as tools for validating json data.\r\n\r\n<a name=\"generating_schema\" />\r\n### generating schema\r\n\r\nThe following demonstrates generating json schema from the following class\r\nhierarchy.\r\n\r\n```javascript\r\nexport module model {\r\n\r\n    /** a product */\r\n    export class Product {\r\n        \r\n        /** the product name */\r\n        public name        : string;\r\n\r\n        /** the product description */\r\n        public description : string;\r\n\r\n        /** the product cost */\r\n        public cost        : number;\r\n    } \r\n\r\n    /** a order */\r\n    export class Order {\r\n        \r\n        /** the product being ordered */\r\n        public products  : Product;\r\n    }\r\n\r\n    /** a customer */\r\n    export class Customer {\r\n\r\n        /** the customers firstname */\r\n        public firstname  : string;\r\n\r\n        /** the customers lastname */\r\n        public lastname   : string;\r\n\r\n        /** orders made by this customer */\r\n        public orders     : Order[];\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.IContext) {\r\n\t\r\n\t// pass the fully qualified name of the type.\r\n    var schema = context.schema.generate('model.Customer');\r\n\r\n    context.response.json(schema);\r\n}\r\n```\r\n\r\nwhich generates the following json schema.\r\n\r\n```javascript\r\n{\r\n    \"id\": \"model.Customer\",\r\n    \"type\": \"object\",\r\n    \"description\": \"a customer\",\r\n    \"properties\": {\r\n        \"firstname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers firstname\",\r\n            \"required\": true\r\n        },\r\n        \"lastname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers lastname\",\r\n            \"required\": true\r\n        },\r\n        \"orders\": {\r\n            \"type\": \"array\",\r\n            \"items\": {\r\n                \"type\": {\r\n                    \"id\": \"model.Order\",\r\n                    \"type\": \"object\",\r\n                    \"description\": \"a order\",\r\n                    \"properties\": {\r\n                        \"products\": {\r\n                            \"id\": \"model.Product\",\r\n                            \"type\": \"object\",\r\n                            \"description\": \"a product\",\r\n                            \"properties\": {\r\n                                \"name\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product name\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"description\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product description\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"cost\": {\r\n                                    \"type\": \"number\",\r\n                                    \"description\": \"the product cost\",\r\n                                    \"required\": true\r\n                                }\r\n                            },\r\n                            \"required\": true\r\n                        }\r\n                    }\r\n                }\r\n            },\r\n            \"description\": \"orders made by this customer\",\r\n            \"required\": true\r\n        }\r\n    }\r\n}\r\n```\r\na quick note...\r\n\r\nwhen generating schema from classes:\r\n\r\n* only public class variables will be emitted.\r\n* all properties will be marked as \"required\".\r\n\r\nwhen generating schema from interfaces:\r\n\r\n* all properties will be emitted. \r\n* all properties will be marked as \"required\" unless modified with '?'.\r\n\r\n<a name=\"validating_json\" />\r\n### validating json\r\n\r\nappex supports json schema validation from class and interface definitions. consider the following...\r\n\r\n```javascript\r\ninterface Customer {\r\n\r\n    firstname    : string;\r\n\r\n    lastname     : string;\r\n\r\n    age          : number;\r\n\r\n    emails       : string[];\r\n\r\n    option_a ?   : boolean; // optional\r\n\r\n    option_b ?   : boolean; // optional\r\n\r\n}\r\n\r\nexport function index(context) {\r\n\r\n    // a customer with invalid data.\r\n\r\n    var customer = {\r\n\r\n        firstname    : 'dave',\r\n\r\n        age          : '33',\r\n\r\n        emails       : [12345, 'dave@domain.com', true],\r\n\r\n        option_b     : 1,\r\n\r\n        option_c     : 1\r\n    }\r\n\r\n    // do validation.\r\n\r\n    var errors = context.schema.validate('Customer', customer);\r\n\r\n    if(errors) {\r\n\r\n        context.response.json(errors);\r\n    }\r\n}\r\n```\r\n\r\nwill output the following.\r\n\r\n```javascript\r\n[\r\n    {\r\n        \"message\": \"instance.lastname is required.\"\r\n    },\r\n    {\r\n        \"message\": \"instance.age is not a number\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[0] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[2] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_b is not a boolean\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_c unexpected property\"\r\n    }\r\n]\r\n```\r\n\r\n<a name=\"web_service_descriptions\">\r\n### web service descriptions\r\n\r\nFor those using appex for web services, developers can leverage appex json schema generation\r\nto generate endpoint metadata (think wsdl). Consider the following which leverages both appex \r\nschema generation and attributes to produce a metadata endpoint consumers of your\r\napi can use to see what data the endpoint http://example.com/customer/create accepts \r\nand returns.\r\n\r\n```javascript\r\nclass Request {\r\n\r\n    /** the customers firstname */\r\n    firstname : string;\r\n\r\n    /** the customers lastname */\r\n    lastname  : string;\r\n\r\n\t/** the customers lastname */\r\n}\r\n\r\nclass Response {\r\n\r\n    /** true on success  */\r\n    success:boolean;\r\n    \r\n    /** an array of validation errors  */\r\n    errors : string[];\r\n}\r\n\r\nattribute('metadata', {input  : 'Request', output : 'Response'})\r\nexport function metadata(context:appex.web.IContext) {\r\n\r\n    var metadata = {\r\n        \r\n\t\tendpoint : 'http://example.com/customer/create',\r\n\r\n        input    : context.schema.generate(context.attribute.input),\r\n\r\n        output   : context.schema.generate(context.attribute.output)\r\n    }\r\n\r\n    context.response.json(metadata)\r\n}\r\n```\r\n\r\nwhich outputs the following.\r\n\r\n```javascript\r\n{\r\n    \"endpoint\": \"http://example.com/customer/create\",\r\n    \"input\": {\r\n        \"id\": \"Request\",\r\n        \"type\": \"object\",\r\n        \"properties\": {\r\n            \"firstname\": {\r\n                \"type\": \"string\",\r\n                \"description\": \"the customers firstname\",\r\n                \"required\": true\r\n            },\r\n            \"lastname\": {\r\n                \"type\": \"string\",\r\n                \"description\": \"the customers lastname\",\r\n                \"required\": true\r\n            }\r\n        }\r\n    },\r\n    \"output\": {\r\n        \"id\": \"Response\",\r\n        \"type\": \"object\",\r\n        \"properties\": {\r\n            \"success\": {\r\n                \"type\": \"boolean\",\r\n                \"description\": \"true on success\",\r\n                \"required\": true\r\n            },\r\n            \"errors\": {\r\n                \"type\": \"array\",\r\n                \"description\": \"an array of validation errors\",\r\n                \"items\": {\r\n                    \"type\": \"string\"\r\n                },\r\n                \"required\": true\r\n            }\r\n        }\r\n    }\r\n}\r\n```\r\ntip: use the appex sitemap metadata to produce a metadata endpoint for all service methods \r\nin your application.\r\n\r\n\r\n<a name=\"reflection\" />\r\n## reflection\r\n\r\nappex provides a reflection api derived from TypeScript's type system that developers can \r\nleverage to reflect type information declared throughout their appex modules. \r\n\r\nthe following section outlines how to use the reflection api.\r\n\r\n<a name=\"reflect_everything\" />\r\n### reflect everything\r\n\r\nthe appex reflection api is passed on the context.module.reflection property and is available to all\r\nappex handler methods. The following code will JSON serialize everything declared in your appex\r\nproject and write it to the http response. \r\n\r\n```javascript\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection );\r\n}\r\n```\r\n\r\n<a name=\"reflect_specific_types\" />\r\n### reflect specific types\r\n\r\nIn typical scenarios, developers will want to leverage reflection meta data to generate\r\nservice contacts and client side models. the reflection api lets you access meta data \r\nfor the following types declared in your project. \r\n\r\n* modules\r\n* imports\r\n* classes\r\n* interfaces\r\n* functions\r\n* variables\r\n\r\nto access specific type metadata, use the reflection.get([qualifier]) method, as demonstrated below.\r\n\r\n```javascript\r\nexport module model {\r\n    \r\n    export class Customer {\r\n\r\n        public firstname   : string;\r\n\r\n        public lastname    : string;\r\n\r\n        public age         : number;\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('model.Customer') );\r\n}\r\n```\r\nand methods..\r\n\r\n```javascript\r\nfunction some_method(a:string, b:number, c?:boolean) : void { }\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_method') );\r\n}\r\n```\r\n\r\n....and variables...\r\n\r\n```javascript\r\nvar some_variable:number = 10;\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_variable') );\r\n}\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\nThis section outlines development with appex.\r\n\r\n<a name=\"appex_declaration\" />\r\n### appex.d.ts declaration\r\n\r\nIf you develop on a TypeScript complicant editor (one that supports TS 0.9), appex comes bundled\r\nwith a declaration file you can reference in your project. If installing appex via npm, your\r\nreference should be as follows.\r\n\r\n```javascript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nexport function index (context:appex.web.IContext) { \r\n    \r\n    context.response.send('hello');\r\n}\r\n\r\nexport function wildcard(context:appex.web.IContext, path:string) {\r\n\r\n    context.response.serve('./', path);\r\n}\r\n```\r\n\r\nBy referencing this in your project, you get the benefits of code completion and static type checking\r\nagainst both appex, and the nodejs core.\r\n\r\n![](https://raw.github.com/sinclairzx81/appex/master/artifacts/code-completion.jpg)\r\n\r\nAdditional declaration files may be obtained from [here](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex ({ program : './index.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"users.ts\" />\r\n/// <reference path=\"pages.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { context.response.send('users.login') }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { context.response.send('users.logout') }\r\n}\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { context.response.send('home') }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { context.response.send('about') }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { context.response.send('contact') }\r\n\r\nexport function wildcard (context, path) { context.response.send(404, ' not found') }\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"license\" />\r\n## license\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) 2013 Haydn Paterson (sinclair) <haydn.developer@gmail.com>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in\r\nall copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\nTHE SOFTWARE.\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"https://raw.github.com/sinclairzx81/appex/master/license.txt","type":"The MIT License (MIT)"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"develop nodejs web applications with typescript","directories":{},"dependencies":{"typescript.api":"0.7.5"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.6.6":{"name":"appex","version":"0.6.6","keywords":["typescript","web api","reflection","compiler","schema","templates","sitemap"],"author":{"name":"sinclair"},"_id":"appex@0.6.6","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"4214a541044a906486704740de612a9838e5efc7","tarball":"https://registry.npmjs.org/appex/-/appex-0.6.6.tgz","integrity":"sha512-R+5PwLRcaVe1zoMl4fj2h74+WjcfjlrA+Qx3Ba9YZM27PZy29WwVvgDm9Alb+WeLQMz+hU0CEED0oCTzmGGjBA==","signatures":[{"sig":"MEUCIDOBw8dSDSLHy/4TcRuQhQpUicqWDrvRYX310KtbT8H4AiEAidlM6u+L2I1XgJ1qplL152lYrw0mZJEQ7G14Qn99zcU=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/artifacts/logo.jpg)\r\n\r\n### develop nodejs web applications with [typescript](http://www.typescriptlang.org/)\r\n\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nexport function index(context:appex.web.IContext) {\r\n\t\r\n\tcontext.response.send('home page');\r\n}\r\n\r\nexport function about(context:appex.web.IContext) {\r\n\t\r\n\tcontext.response.send('about page');\r\n}\r\n\r\nexport function wildcard (context:appex.web.IContext, path:string) {\r\n    \r\n    context.response.send(404, path + \" not found\");\r\n}\r\n\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n### contents\r\n\r\n* [getting started](#getting_started)\r\n\t* [create a application](#application)\r\n\t* [start up options](#options)\r\n\t* [running on an existing http server](#http_server)\r\n\t* [running as express middleware](#express_middleware)\r\n* [http handlers](#http_handlers)\r\n\t* [context](#context)\r\n\t* [request](#request)\r\n\t* [response](#response)\r\n\t* [routing](#routing)\r\n\t* [signatures](#signatures)\r\n\t* [named handlers](#named_handlers)\r\n\t* [index handlers](#index_handlers)\r\n\t* [wildcard handlers](#wildcard_handlers)\r\n\t* [attributes](#attributes)\r\n\t* [verbs](#verbs)\r\n\t* [url rewrite](#url_rewrite)\r\n\t* [middleware](#middleware)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [handling 404](#handling_404)\r\n\t* [serving static files](#serving_static_files)\r\n* [templating](#templating)\r\n\t* [overview](#template_overview)\r\n\t* [context](#template_context)\t\r\n\t* [syntax](#template_syntax)\r\n\t* [layouts and sections](#template_layouts_and_sections)\r\n\t* [render](#template_render)\r\n\t* [caching and devmode](#caching_and_devmode)\r\n* [sitemaps](#sitemaps)\r\n\t* [generating](#sitemap_generate)\r\n\t* [metadata](#sitemap_metadata)\r\n* [json schema](#json_schema)\r\n\t* [generating schema](#generating_schema)\r\n\t* [validating json](#validating_json)\r\n\t* [web service descriptions](#web_service_descriptions)\r\n* [reflection](#reflection)\r\n\t* [reflect everything](#reflect_everything)\r\n\t* [reflect specific types](#reflect_specific_types)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [appex.d.ts declaration](#appex_declaration)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n* [license](#license)\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline creating appex applications and configuration.\r\n\r\n<a name=\"application\" />\r\n### create a application\r\n\r\nThe following code will create a standalone appex application and \r\nhttp server and listen on port 3000.\r\n\r\n```javascript\r\nvar appex   = require('appex');\r\n\r\nvar app   = appex({ program : './program.ts', \r\n                    devmode : true,\r\n                    logging : true });\r\n\r\napp.listen(3000);\r\n```\r\n\r\nnote: devmode and logging are optional. however, when developing \r\nwith appex, it is helpful to have these enabled.\r\n\r\n<a name=\"options\" />\r\n### start up options\r\n\r\nappex accepts the following start up options.\r\n\r\n```javascript\r\nvar options = {\r\n\r\n\t// (required) location of source file.\r\n\tprogram    : './program.ts', \r\n\r\n\t// (optional) recompile on request. (default:false) \r\n\tdevmode    : true,          \r\n\r\n\t// (optional) log to stdout. (default:false) \r\n\tlogging    : true,\r\n\r\n\t// (optional) user defined objects added to the app context.\r\n\tcontext    : {}\r\n};\r\n\r\nvar app = appex( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### running on an existing http server\r\n\r\nThe following demonstrates setting up appex on an existing nodejs http server. In \r\nthis example, appex will attempt to handle incoming requests, and if appex cannot\r\nroute the request, will fire the callback.\r\n\r\n```javascript\r\nvar http  = require('http');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\nvar server = http.createServer(function(req, res){\r\n\r\n    app(req, res, function() { // appex handler...\r\n\t\t\r\n\t\t// not handled.\r\n\r\n\t}); \r\n});\r\n\r\nserver.listen(3000);\r\n```\r\n\r\n<a name=\"express_middleware\" />\r\n### running as express middleware\r\n\r\nappex allows developers to augment existing express / connect applications by \r\nway of middleware. The following demonstrates setting up appex as express middleware.\r\n\r\n```javascript\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) ); \r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nLike in the \"running on an existing http server\" example above, appex will attempt to intercept incoming requests. \r\nif appex cannot find a matching route for the request, it will automatically call the \"next\" function to pass the request \r\non to the next middleware or express handler.\r\n\r\nin addition to this, appex may also act as traditional express middleware. In the example below, a appex wildcard\r\nfunction is created which will match \"all\" incoming requests, the wildcard function simply prints hello world to \r\nthe console and then calls context.next(), which passes the request on the express handler.\r\n\r\n```javascript\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tconsole.log('hello world!!');\r\n\r\n\tcontext.next(); // pass it on!\r\n}\r\n\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) );\r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nJust like traditional express middleware, appex will also inheriate the characteristics of the request.\r\n\r\nconsider the following example in which the jade view engine is configured for use. appex will inheritate the \r\nresponse.render() method, which is passed to the appex handler as context.response.render()\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\napp.configure(function(){\r\n\r\n  app.set('views', __dirname + '/views');\r\n  \r\n  // set up the jade engine.\r\n  app.set('view engine', 'jade'); \r\n  \r\n  // bind appex\r\n  app.use( appex({program:'./program.ts', devmode:true} ));  \r\n});\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/\r\nexport function index(context) {\r\n\t\r\n\t// jade renderer works!\r\n\tcontext.response.render('index', { title: 'Express' }); \r\n}\r\n```\r\n\r\n<a name=\"http_handlers\" />\r\n## http handlers\r\n\r\nThe following sections describe how to create http accessible handlers with appex.\r\n\r\n<a name=\"context\" />\r\n### context\r\n\r\nAll appex functions are passed a application context object as their first argument. The app context object \r\nencapulates the http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the app context\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.attribute    - appex attribute.\r\n\r\n\t// context.next       - the next function (express middleware)\r\n\t\r\n\t// context.router     - the appex router\r\n\r\n\t// context.sitemap    - the appex sitemap api\r\n\r\n\t// context.template   - the appex template engine.\r\n\t\r\n\t// context.module     - the module being run (this module)\r\n\r\n\t// context.schema     - json schema api.\r\n\r\n\t// context.mime       - a http mime type utility.\r\n}\r\n```\r\n\r\nit is possible to extend the default objects passed on the context by adding them on the appex startup options. The \r\nfollowing will attach the async module to the context. \r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = appex({ program : './program.ts', \r\n\t\t\t\t  devmode : true, \r\n\t\t\t      context: {\r\n\t\t\t\t\t\tasync : require('async')\r\n\t\t\t\t  }});\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\r\n\t// context.async = passed on the context.\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n```\r\n<a name=\"request\" />\r\n### request\r\n\r\nThe appex request is a nodejs http request issued by the underlying node http server. \r\nappex extends the request with convenience methods for reading http request data. These\r\nare outlined below.\r\n\r\nreading a posted string. \r\n```javascript\r\n//----------------------------------------------\r\n// receive request as a string\r\n//----------------------------------------------\r\nexport function submit(context) {\r\n\r\n\tcontext.request.body.recv((str) => {\r\n\r\n\t\t// do something with str\r\n\t})\r\n}\r\n```\r\nreading posted form data as json object.\r\n```javascript\r\n//----------------------------------------------\r\n// receive a form post\r\n//----------------------------------------------\r\nexport function submit(context) {\r\n\r\n\tcontext.request.body.form((obj) => {\r\n\r\n\t\t// do something with obj\r\n\t})\r\n}\r\n```\r\nreading posted json data as a json object.\r\n```javascript\r\n//----------------------------------------------\r\n// receive a json post\r\n//----------------------------------------------\r\nexport function submit(context) {\r\n\r\n\tcontext.request.body.json((obj) => {\r\n\t\t\r\n\t\t// do something with obj\r\n\t})\r\n}\r\n```\r\n\r\nnote: if appex detects that express or connect middleware has already been applied\r\nto the request object, appex will use those instead.\r\n\r\n<a name=\"response\" />\r\n### response\r\n\r\nThe appex response is a nodejs http response issued by the underlying node http server. \r\nappex provides some utility methods for writing http responses. These are outlined below.\r\n\r\n```js\r\n//----------------------------------------------\r\n// the nodejs response has been extended with the following\r\n// signatures.\r\n//----------------------------------------------\r\nexport interface IResponse extends http.ServerResponse {\r\n\t\r\n\tsend (data     : string): void;\r\n\r\n\tsend (data     : NodeBuffer): void;\r\n\r\n\tsend (status   : number, data : string): void;\r\n\r\n\tserve (filepath: string): void;\r\n\r\n\tserve (root : string, filepath: string): void;\r\n\r\n\tserve (root : string, filepath: string, mime:string): void;\r\n\r\n\tjson (obj      : any): void;\r\n\r\n\tjson (status   : number, obj : any): void;\r\n\r\n\tjsonp (obj     : any): void;\r\n\r\n\tjsonp (status  : number, obj : any): void;\r\n\r\n\tjsonp (status  : number, obj : any, callback: string): void;\r\n}\r\n```\r\n\r\nnote: if appex detects that express or connect middleware has already been applied\r\nto for any of the following response methods, appex will use those instead.\r\n\r\n<a name=\"routing\" />\r\n### routing\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context) {\r\n\r\n\t\tcontext.response.send('services.customers.insert')\r\n    }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context) { \r\n\t\t\r\n\t\tcontext.response.send('services.customers.update')\r\n    }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context) { \r\n\r\n\t\tcontext.response.send('services.customers.delete')\r\n\t}\r\n}\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context) { \r\n\r\n\tcontext.response.send('home page')\r\n}\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context) { \r\n\r\n\tcontext.response.send('about page')\r\n}\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context) { \r\n\r\n\tcontext.response.send('contact page')\r\n}\r\n\r\n// url: http://[host]:[port]/(.*)\r\nexport function wildcard (context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found')\r\n}\r\n\r\n```\r\n\r\n<a name=\"signatures\" />\r\n### signatures\r\n\r\nappex supports three function signatures for http routing (named, index and wildcard). Functions that\r\ndo not apply these signatures will not be routed.\r\n\r\n<a name=\"named_handlers\" />\r\n### named handlers\r\n\r\nNamed handlers resolve urls to their current module scope + the name of the function.\r\n\r\nNamed handlers require the following signature:\r\n\r\n* name        - 'anything'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n\r\n// http://[host]:[port]/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about page');\r\n}\r\n\r\n// http://[host]:[port]/users/login\r\nexport module users {\r\n\r\n\texport function login(context) {\r\n\t\t\r\n\t\tcontext.response.send('handle login');\t\r\n\t}\r\n}\r\n\r\n```\r\n\r\n<a name=\"index_handlers\" />\r\n### index handlers\r\n\r\nIndex handlers resolve urls to their current module scope.\r\n\r\nIndex handlers require the following signature:\r\n\r\n* name        - 'index'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) \r\n\t{\t\r\n\t\tcontext.response.send('blog index');\r\n\t}\r\n}\r\n```\r\n\r\n<a name=\"wildcard_handlers\" />\r\n### wildcard handlers\r\n\r\nWildcard handlers resolve their urls to their current module scope + url.\r\n\r\nappex wildcard handlers allow for wildcard routing at a given module scope. Wildcard handlers\r\nsupport 'typed' url argument mapping, as denoted by the arguments annotation.\r\n\r\nIn addition, wildcard handlers also support optional arguments which can be specified with TypeScript's '?' \r\non argument names.\r\n\r\nappex wildcard handlers require the following signature:\r\n\r\n* name        - 'wildcard'\r\n* argument[0] - app context\r\n* argument[n] - 1 or more arguments to be mapped from the url\r\n* returns     - void (optional)\r\n\r\n```javascript\r\ndeclare var console;\r\n\r\nexport module blogs {\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11   - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/11  - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/3rd - not matched - (see number annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01     - matched     - (see ? annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013        - not matched - (month is required)\r\n\t\r\n    export function wildcard(context, year:number, month:number, day?:number) {\r\n\r\n        context.response.json({ year: year, month: month, day: day})\r\n    }\r\n}\r\n\r\n// url : http://[host]:[port]/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// url : http://[host]:[port]/(.*) \r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, 'not found');\r\n}\r\n\r\n```\r\nnote: appex supports boolean, number, string and any annotations on wildcard arguments. if no annotation\r\nis specified, appex interprets the argument as a string. the type 'any' is also interpreted as string.\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"attributes\" />\r\n### attributes\r\n\r\nappex supports a attribute scheme which developers can use to decorate modules and functions with \r\ndeclaritive metadata. appex attributes can set by calling the attribute('qualifier', data)\r\nfunction which is passed to the appex module on the global scope.\r\n\r\nunlike traditional attributes (in languages like C sharp) appex attributes have a cascading behaviour\r\nwhich allows developers to apply metadata at a lexical scope, and have it cascade through to descendant scopes.\r\n\r\nThe following outlines this behavour.\r\n\r\n```javascript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nattribute({a: 10}); // global.\r\n\r\nattribute('foo', {b : 20})\r\nexport module foo {\r\n\r\n    attribute('foo.bar', {c : 30})\r\n    export module bar {\r\n            \r\n        attribute('foo.bar.index', {d : 40})\r\n        export function index(context) {\r\n        \r\n            //context.attribute\r\n            //{\r\n            //    \"a\": 10,\r\n            //    \"b\": 20,\r\n            //    \"c\": 30,\r\n\t\t\t//    \"d\": 40\r\n            //}\r\n\r\n            context.response.json( context.attribute );       \r\n        }\r\n    }\r\n}\r\n\r\n```\r\n\r\nin addition, appex recognizes three types of attributes. developers can use these to override the default \r\nbahavour of the appex router and apply url rewriting (urls), verb matching (verbs) and middleware (use),\r\nas demonstrated below.\r\n\r\n```javascript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nfunction logger(context) {\r\n\tconsole.log('logging')\r\n\tcontext.next()\r\n}\r\n\r\n// invoke 'logger' middleware.\r\nattribute('index', {use   : [logger]})   \r\n\r\n// override the default route.\r\nattribute('index', {urls  : ['/', '/home']})  \r\n\r\n// only accept GET requests.\r\nattribute('index', {verbs : ['GET']})    \r\n\r\nexport function index(context:appex.web.IContext) {\r\n\t\r\n\tcontext.response.send('home page')\r\n}\r\n```\r\n\r\n<a name=\"verbs\" />\r\n### verbs\r\n\r\nappex handles http verb matching with attributes. appex will recognise the \r\n'verbs' property applied to the attribute to match against http verbs.\r\n\r\n```javascript\r\nattribute('index', { verbs: ['GET'] })\r\nexport function index (context) { \r\n        \r\n    // only allow HTTP GET requests\r\n    context.response.send('index')\r\n}\r\n\r\nattribute('submit', { verbs: ['POST', 'PUT'] })\r\nexport function submit (context) { \r\n    \r\n    // only allow HTTP POST and PUT requests\r\n    context.response.send('submit')\r\n}\r\n```\r\n\r\n<a name=\"url_rewrite\" />\r\n### url rewrite\r\n\r\ndevelopers can rewrite the default route given to exported functions with the 'urls' property applied\r\nto the attribute. \r\n\r\n```javascript\r\nattribute('index', { urls: ['/', '/home', 'home.html'] })\r\nexport function index (context) { \r\n    \r\n    context.response.send('index')\r\n}\r\n```\r\nnote: url rewriting is only available on index and named routes.\r\n\r\nnote: rewriting with regular expressions is currently not supported.\r\n\r\n<a name=\"middleware\" />\r\n### middleware\r\n\r\nappex supports middleware with attributes. appex middleware defined with attributes allows\r\ndevelopers to scope middleware on single functions, or entire module scopes. appex will \r\nrecognise the 'use' property applied to the attribute to invoke middleware.\r\n\r\nthe following demonstrates how one might use middleware to secure a site admin.\r\n\r\nnote: middleware 'must' call next or handle the request. \r\n\r\n```javascript\r\ndeclare function attribute (qualifier:string, obj:any);\r\n\r\ndeclare var console;\r\n\r\nfunction authenticate(context) {\r\n\r\n    console.log('authenticate')\r\n\r\n\t// call next() if authenticated, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\nfunction authorize(context) {\r\n\r\n    console.log('authorize')\r\n\r\n\t// call next() if authorized, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\n// apply security middleware to admin scope.\r\nattribute('admin', {use: [authenticate, authorize]}) \r\nexport module admin {\r\n\r\n    export function index(context) {\r\n        \r\n        console.log(context.attribute); // view attribute\r\n\r\n        context.response.send('access granted!')\r\n    }\r\n}\r\n\r\n// index handler has no middleware applied.\r\nexport function index (context) { \r\n    \r\n    console.log(context.attribute); // view attribute\r\n\r\n    context.response.send('home')\r\n}\r\n```\r\n\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex will only route functions prefixed with the TypeScript 'export' declarer. This rule\r\nalso applied to modules. Developers can use this to infer notions of public and private \r\nat the http level.\r\n\r\nconsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is \r\n// therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private \r\n\t// as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is \r\n\t// private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and \r\n// is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore \r\n// publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke \r\n\t// private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in \r\n\t// private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method \r\n\t// in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.send('public_function');\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```javascript\r\n// http:[host]:[port]/\r\nexport function index (context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard (context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n<a name=\"serving_static_files\" />\r\n## serving static files\r\n\r\nUse wildcard functions with context.response.serve() to serve static content.\r\n\r\n```javascript\r\nexport module static {\r\n\t\r\n\t// http:[host]:[port]/static/(.*)\r\n\texport function wildcard(context, path) {\r\n\r\n\t\tcontext.response.serve('./static/', path);\r\n\t}\r\n}\r\n\r\n// http:[host]:[port]/\r\nexport function index (context) {\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n\r\n<a name=\"templating\" />\r\n## templating\r\n\r\nappex comes bundled with a built in template engine which is modelled on the Microsoft \r\nRazor templating engine. The following sections outline its use.\r\n\r\n<a name=\"template_overview\" />\r\n### overview\r\n\r\nThe appex template engine is available to all handlers by default. it is accessible\r\non the context.template property. the following is an example of its use.\r\n\r\n```\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n<ul>\r\n@for(var n in context.users) {\r\n\r\n\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t<li>@(context.users[n].name)</li>\r\n\t}\r\n}\r\n</ul>\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\t\r\n\tcontext.response.headers['Content-Type'] = 'text/html';\r\n\r\n    context.response.send(text);\r\n}\r\n\r\n```\r\n\r\n<a name=\"template_context\" />\r\n### context\r\n\r\neach template is passed a data context. this context allows the caller to \r\nsend data to the template for rendering. the context parameter is optional.\r\nthe example below is sending the users array to the template context for \r\nrendering.\r\n\r\n```\r\nexport function index(context) {\r\n\t\r\n    var users  = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    context.response.send(context.template.render('./view.txt', { users: users }));\r\n}\r\n```\r\n\r\n<a name=\"template_syntax\" />\r\n### syntax\r\n\r\nappex templates support the following statements and syntax\r\n\r\n#### if statement\r\n\r\nif statments are supported.\r\n\r\n```\r\n@if(expression) {\r\n\tsome content\r\n}\r\n\r\n@if(a > 10) {\r\n\tsome content\r\n}\r\n\r\n@(user.loggedin) {\r\n\t<span>welcome</span>\r\n}\r\n```\r\n\r\n#### for statement\r\n\r\nthe following for loops are supported.\r\n\r\n```\r\n@for(var i = i; i < 100; i++) {\r\n\t@(i)\r\n}\r\n\r\n@for(var n in list) {\r\n\t@(list[n])\r\n}\r\n```\r\n\r\n#### expressions\r\n\r\nwill emit the value contained.\r\n\r\n```\r\n@('hello world')\r\n\r\n@(123)\r\n\r\n@(some_variable)\r\n```\r\n\r\n#### code blocks\r\n\r\ncode blocks can be useful for adding template side rendering logic.\r\n\r\n```\r\n@{\r\n\tvar message = 'hello'\r\n}\r\n\r\n@(message)\r\n```\r\n\r\n#### comments\r\n```\r\n@*\r\n\tthis comment will not be rendered!\r\n*@\r\n```\r\n\r\n<a name=\"template_layouts_and_sections\" />\r\n### layouts and sections\r\n\r\nappex templates support template inheritance.\r\n\r\nconsider the following where layout.txt defines the sections 'header' and 'content' and the view.txt overrides\r\nthese sections with its own content.\r\n\r\n```\r\n//----------------------------------------------\r\n// layout.txt\r\n//----------------------------------------------\r\n\r\n<html>\r\n\r\n\t<head>\r\n\t\t\r\n\t\t@section header\r\n\r\n\t</head>\r\n\r\n\t<body>\r\n\r\n\t\t@section content {\r\n\t\t\r\n\t\t\t<span>some default content</span>\r\n\t\t\t\r\n\t\t}\r\n\r\n\t</body>\r\n\t\r\n</html>\r\n\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n@layout 'layout.txt'\r\n\r\n@section header {\r\n\r\n\t<title>my page</title>\r\n}\r\n\r\n@section content {\r\n\r\n\t<p>overriding the layout.txt content section.</p>\r\n\r\n\t<ul>\r\n\t@for(var n in context.users) {\r\n\r\n\t\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t\t<li>@(context.users[n].name)</li>\r\n\t\t}\r\n\t}\r\n\t</ul>\r\n}\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\r\n    context.response.send(text);\r\n}\r\n```\r\n\r\nnote : when specifying a layout, the view will only render content within\r\nthe layouts section placeholders. \r\n\r\n<a name=\"render\" />\r\n### render\r\n\r\nappex templates also allow for partial views with the @render statment. consider the following \r\nwhich renders the nav.txt file into the layout.txt file.\r\n\r\n```\r\n//----------------------------------------------\r\n// nav.txt\r\n//----------------------------------------------\r\n<ul>\r\n\t<li>home</li>\r\n\t<li>about</li>\r\n\t<li>contact</li>\r\n</ul>\r\n\r\n//----------------------------------------------\r\n// layout.txt\r\n//----------------------------------------------\r\n\r\n<html>\r\n\t<head>\r\n\t\t\r\n\t\t@section header\r\n\r\n\t</head>\r\n\r\n\t<body>\r\n\t\t\r\n\t\t@render 'nav.txt'\r\n\r\n\t\t@section content {\r\n\t\t\r\n\t\t\t<span>some default content</span>\r\n\t\t\t\r\n\t\t}\r\n\r\n\t</body>\r\n\t\r\n</html>\r\n\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n@layout 'layout.txt'\r\n\r\n@section header {\r\n\r\n\t<title>my page</title>\r\n}\r\n\r\n@section content {\r\n\r\n\t<p>overriding the layout.txt content section.</p>\r\n\r\n\t<ul>\r\n\t@for(var n in context.users) {\r\n\r\n\t\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t\t<li>@(context.users[n].name)</li>\r\n\t\t}\r\n\t}\r\n\t</ul>\r\n}\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\r\n    context.response.send(text);\r\n}\r\n```\r\n\r\n<a name=\"caching_and_devmode\" />\r\n### caching and devmode\r\n\r\nappex template content is not cached (the implementor is expected to handle their own caching)\r\nhowever the generated template code is. \r\n\r\nappex templates do inheriate the behaviour of the appex 'devmode' option. setting\r\ndevmode to 'true' will cause template code to be reloaded from disk and code generated with each \r\nrequest. setting devmode to false will load content from disk on first request, and \r\ncache the generated template code in memory for the lifetime of the application.\r\n\r\nin addition to this, a implementation where the devmode is false can override the caching \r\nbehaviour with the following.\r\n\r\n```javascript\r\nexport function index(context) {\r\n\r\n\t// manually override the template devmode option.\r\n\tcontext.template.option.devmode = true; \r\n\r\n\tcontext.response.send(context.template.render('./view.txt'))\r\n}\r\n```\r\n\r\n<a name=\"sitemaps\" />\r\n## sitemaps\r\n\r\nappex is able to derive sitemap metadata automatically from http endpoints created with\r\ntypescript modules and functions. This metadata is useful to generate sitemap.xml\r\nfiles, as well as helping to create site navigation links when combined a template\r\nengine.\r\n\r\n<a name=\"sitemap_generate\" />\r\n### generate sitemap\r\n\r\nappex sitemaps can be obtained from the context.sitemap property. \r\n\r\n```javascript\r\nexport function index(context) {\r\n\r\n\t// return all nodes in this site.\r\n\tcontext.response.json(context.sitemap)\r\n\r\n}\r\n```\r\n\r\nAdditionally, it may be helpful to isolate branches of the sitemap with the \r\ncontext.sitemap.get([qualifier]) function. as demonstrated below.\r\n\r\n```javascript\r\nexport module admin {\r\n\r\n\texport function index     (context) { }\r\n\r\n\texport function dashboard (context) { }\r\n\r\n\texport function content   (context) { }\r\n\r\n\texport module users {\r\n\r\n\t\texport function login(context) { }\r\n\r\n\t\texport function logout(context) { }\r\n\t}\r\n}\r\n\r\nexport function test(context) {\r\n\t\r\n\t// view all admin sitemap nodes\r\n\tcontext.response.json(context.sitemap.get('admin'))\r\n\r\n\t// view all admin.users sitemap nodes\r\n\t//context.response.json(context.sitemap.get('admin.users'))\r\n}\r\n```\r\n\r\n<a name=\"sitemap_metadata\" />\r\n### attribute metadata\r\n\r\neach sitemap node contains the attribute applied to the handler for which the node applies. With this\r\ndevelopers can apply custom metadata for a given node. as demonstrated below.\r\n\r\n```javascript\r\ndeclare var attribute;\r\n\r\nattribute({website:'http://mysite.com/'}) // global\r\n\r\nattribute('index', {title:'home page'})\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('index')\r\n}\r\n\r\nattribute('about', {title: 'about page'})\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about')\r\n}\r\n\r\nattribute('sitemap', {title: 'sitemap page'})\r\nexport function sitemap(context) {\r\n\r\n\tcontext.response.json(context.sitemap)\r\n}\r\n```\r\n\r\nvisiting /sitemap will output the following.\r\n\r\n```javascript\r\n{\r\n    \"name\": \"sitemap\",\r\n    \"nodes\": [\r\n        {\r\n            \"name\": \"index\",\r\n            \"urls\": [\r\n                \"/\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"home page\"\r\n        },\r\n        {\r\n            \"name\": \"about\",\r\n            \"urls\": [\r\n                \"/about\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"about page\"\r\n        },\r\n        {\r\n            \"name\": \"sitemap\",\r\n            \"urls\": [\r\n                \"/sitemap\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"sitemap page\"\r\n        }\r\n    ]\r\n}\r\n```\r\n\r\n<a name=\"json_schema\" />\r\n## json schema\r\n\r\nappex provides functionality for generating json schemas from TypeScript classes\r\nand interfaces as well as tools for validating json data.\r\n\r\n<a name=\"generating_schema\" />\r\n### generating schema\r\n\r\nThe following demonstrates generating json schema from the following class\r\nhierarchy.\r\n\r\n```javascript\r\nexport module model {\r\n\r\n    /** a product */\r\n    export class Product {\r\n        \r\n        /** the product name */\r\n        public name        : string;\r\n\r\n        /** the product description */\r\n        public description : string;\r\n\r\n        /** the product cost */\r\n        public cost        : number;\r\n    } \r\n\r\n    /** a order */\r\n    export class Order {\r\n        \r\n        /** the product being ordered */\r\n        public products  : Product;\r\n    }\r\n\r\n    /** a customer */\r\n    export class Customer {\r\n\r\n        /** the customers firstname */\r\n        public firstname  : string;\r\n\r\n        /** the customers lastname */\r\n        public lastname   : string;\r\n\r\n        /** orders made by this customer */\r\n        public orders     : Order[];\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.IContext) {\r\n\t\r\n\t// pass the fully qualified name of the type.\r\n    var schema = context.schema.generate('model.Customer');\r\n\r\n    context.response.json(schema);\r\n}\r\n```\r\n\r\nwhich generates the following json schema.\r\n\r\n```javascript\r\n{\r\n    \"id\": \"model.Customer\",\r\n    \"type\": \"object\",\r\n    \"description\": \"a customer\",\r\n    \"properties\": {\r\n        \"firstname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers firstname\",\r\n            \"required\": true\r\n        },\r\n        \"lastname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers lastname\",\r\n            \"required\": true\r\n        },\r\n        \"orders\": {\r\n            \"type\": \"array\",\r\n            \"items\": {\r\n                \"type\": {\r\n                    \"id\": \"model.Order\",\r\n                    \"type\": \"object\",\r\n                    \"description\": \"a order\",\r\n                    \"properties\": {\r\n                        \"products\": {\r\n                            \"id\": \"model.Product\",\r\n                            \"type\": \"object\",\r\n                            \"description\": \"a product\",\r\n                            \"properties\": {\r\n                                \"name\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product name\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"description\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product description\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"cost\": {\r\n                                    \"type\": \"number\",\r\n                                    \"description\": \"the product cost\",\r\n                                    \"required\": true\r\n                                }\r\n                            },\r\n                            \"required\": true\r\n                        }\r\n                    }\r\n                }\r\n            },\r\n            \"description\": \"orders made by this customer\",\r\n            \"required\": true\r\n        }\r\n    }\r\n}\r\n```\r\na quick note...\r\n\r\nwhen generating schema from classes:\r\n\r\n* only public class variables will be emitted.\r\n* all properties will be marked as \"required\".\r\n\r\nwhen generating schema from interfaces:\r\n\r\n* all properties will be emitted. \r\n* all properties will be marked as \"required\" unless modified with '?'.\r\n\r\n<a name=\"validating_json\" />\r\n### validating json\r\n\r\nappex supports json schema validation from class and interface definitions. consider the following...\r\n\r\n```javascript\r\ninterface Customer {\r\n\r\n    firstname    : string;\r\n\r\n    lastname     : string;\r\n\r\n    age          : number;\r\n\r\n    emails       : string[];\r\n\r\n    option_a ?   : boolean; // optional\r\n\r\n    option_b ?   : boolean; // optional\r\n\r\n}\r\n\r\nexport function index(context) {\r\n\r\n    // a customer with invalid data.\r\n\r\n    var customer = {\r\n\r\n        firstname    : 'dave',\r\n\r\n        age          : '33',\r\n\r\n        emails       : [12345, 'dave@domain.com', true],\r\n\r\n        option_b     : 1,\r\n\r\n        option_c     : 1\r\n    }\r\n\r\n    // do validation.\r\n\r\n    var errors = context.schema.validate('Customer', customer);\r\n\r\n    if(errors) {\r\n\r\n        context.response.json(errors);\r\n    }\r\n}\r\n```\r\n\r\nwill output the following.\r\n\r\n```javascript\r\n[\r\n    {\r\n        \"message\": \"instance.lastname is required.\"\r\n    },\r\n    {\r\n        \"message\": \"instance.age is not a number\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[0] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[2] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_b is not a boolean\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_c unexpected property\"\r\n    }\r\n]\r\n```\r\n\r\n<a name=\"web_service_descriptions\">\r\n### web service descriptions\r\n\r\nFor those using appex for web services, developers can leverage appex json schema generation\r\nto generate endpoint metadata (think wsdl). Consider the following which leverages both appex \r\nschema generation and attributes to produce a metadata endpoint consumers of your\r\napi can use to see what data the endpoint http://example.com/customer/create accepts \r\nand returns.\r\n\r\n```javascript\r\nclass Request {\r\n\r\n    /** the customers firstname */\r\n    firstname : string;\r\n\r\n    /** the customers lastname */\r\n    lastname  : string;\r\n\r\n\t/** the customers lastname */\r\n}\r\n\r\nclass Response {\r\n\r\n    /** true on success  */\r\n    success:boolean;\r\n    \r\n    /** an array of validation errors  */\r\n    errors : string[];\r\n}\r\n\r\nattribute('metadata', {input  : 'Request', output : 'Response'})\r\nexport function metadata(context:appex.web.IContext) {\r\n\r\n    var metadata = {\r\n        \r\n\t\tendpoint : 'http://example.com/customer/create',\r\n\r\n        input    : context.schema.generate(context.attribute.input),\r\n\r\n        output   : context.schema.generate(context.attribute.output)\r\n    }\r\n\r\n    context.response.json(metadata)\r\n}\r\n```\r\n\r\nwhich outputs the following.\r\n\r\n```javascript\r\n{\r\n    \"endpoint\": \"http://example.com/customer/create\",\r\n    \"input\": {\r\n        \"id\": \"Request\",\r\n        \"type\": \"object\",\r\n        \"properties\": {\r\n            \"firstname\": {\r\n                \"type\": \"string\",\r\n                \"description\": \"the customers firstname\",\r\n                \"required\": true\r\n            },\r\n            \"lastname\": {\r\n                \"type\": \"string\",\r\n                \"description\": \"the customers lastname\",\r\n                \"required\": true\r\n            }\r\n        }\r\n    },\r\n    \"output\": {\r\n        \"id\": \"Response\",\r\n        \"type\": \"object\",\r\n        \"properties\": {\r\n            \"success\": {\r\n                \"type\": \"boolean\",\r\n                \"description\": \"true on success\",\r\n                \"required\": true\r\n            },\r\n            \"errors\": {\r\n                \"type\": \"array\",\r\n                \"description\": \"an array of validation errors\",\r\n                \"items\": {\r\n                    \"type\": \"string\"\r\n                },\r\n                \"required\": true\r\n            }\r\n        }\r\n    }\r\n}\r\n```\r\ntip: use the appex sitemap metadata to produce a metadata endpoint for all service methods \r\nin your application.\r\n\r\n\r\n<a name=\"reflection\" />\r\n## reflection\r\n\r\nappex provides a reflection api derived from TypeScript's type system that developers can \r\nleverage to reflect type information declared throughout their appex modules. \r\n\r\nthe following section outlines how to use the reflection api.\r\n\r\n<a name=\"reflect_everything\" />\r\n### reflect everything\r\n\r\nthe appex reflection api is passed on the context.module.reflection property and is available to all\r\nappex handler methods. The following code will JSON serialize everything declared in your appex\r\nproject and write it to the http response. \r\n\r\n```javascript\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection );\r\n}\r\n```\r\n\r\n<a name=\"reflect_specific_types\" />\r\n### reflect specific types\r\n\r\nIn typical scenarios, developers will want to leverage reflection meta data to generate\r\nservice contacts and client side models. the reflection api lets you access meta data \r\nfor the following types declared in your project. \r\n\r\n* modules\r\n* imports\r\n* classes\r\n* interfaces\r\n* functions\r\n* variables\r\n\r\nto access specific type metadata, use the reflection.get([qualifier]) method, as demonstrated below.\r\n\r\n```javascript\r\nexport module model {\r\n    \r\n    export class Customer {\r\n\r\n        public firstname   : string;\r\n\r\n        public lastname    : string;\r\n\r\n        public age         : number;\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('model.Customer') );\r\n}\r\n```\r\nand methods..\r\n\r\n```javascript\r\nfunction some_method(a:string, b:number, c?:boolean) : void { }\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_method') );\r\n}\r\n```\r\n\r\n....and variables...\r\n\r\n```javascript\r\nvar some_variable:number = 10;\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_variable') );\r\n}\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\nThis section outlines development with appex.\r\n\r\n<a name=\"appex_declaration\" />\r\n### appex.d.ts declaration\r\n\r\nIf you develop on a TypeScript complicant editor (one that supports TS 0.9), appex comes bundled\r\nwith a declaration file you can reference in your project. If installing appex via npm, your\r\nreference should be as follows.\r\n\r\n```javascript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nexport function index (context:appex.web.IContext) { \r\n    \r\n    context.response.send('hello');\r\n}\r\n\r\nexport function wildcard(context:appex.web.IContext, path:string) {\r\n\r\n    context.response.serve('./', path);\r\n}\r\n```\r\n\r\nBy referencing this in your project, you get the benefits of code completion and static type checking\r\nagainst both appex, and the nodejs core.\r\n\r\n![](https://raw.github.com/sinclairzx81/appex/master/artifacts/code-completion.jpg)\r\n\r\nAdditional declaration files may be obtained from [here](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex ({ program : './index.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"users.ts\" />\r\n/// <reference path=\"pages.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { context.response.send('users.login') }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { context.response.send('users.logout') }\r\n}\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { context.response.send('home') }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { context.response.send('about') }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { context.response.send('contact') }\r\n\r\nexport function wildcard (context, path) { context.response.send(404, ' not found') }\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"license\" />\r\n## license\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) 2013 Haydn Paterson (sinclair) <haydn.developer@gmail.com>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in\r\nall copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\nTHE SOFTWARE.\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"https://raw.github.com/sinclairzx81/appex/master/license.txt","type":"The MIT License (MIT)"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.2.21","description":"develop nodejs web applications with typescript","directories":{},"dependencies":{"typescript.api":"0.7.6"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.6.7":{"name":"appex","version":"0.6.7","keywords":["typescript","web api","reflection","compiler","schema","templates","sitemap"],"author":{"name":"sinclair"},"_id":"appex@0.6.7","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"2cf4f1586835edda48181ec6864fdcba283b33c5","tarball":"https://registry.npmjs.org/appex/-/appex-0.6.7.tgz","integrity":"sha512-uL+fPiK1LHL1HpeVQSAa+AakxCPDErULJwJB0flPD/y3kAvnuF7+sLOXjS0dg78Zee/1NNM4X4XQI/eEvp9b9A==","signatures":[{"sig":"MEUCIQCZ31s5STz4Fa50WSNw5e+Z5/TWun3C8+pUbjUM+PgDkQIgVI4zYiGUHs6JzByomR+ZxIKeah+HBORP0UwcZ1LmkaM=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/artifacts/logo.jpg)\r\n\r\n### develop nodejs web applications with [typescript](http://www.typescriptlang.org/)\r\n\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nexport function index(context:appex.web.IContext) {\r\n\t\r\n\tcontext.response.send('home page');\r\n}\r\n\r\nexport function about(context:appex.web.IContext) {\r\n\t\r\n\tcontext.response.send('about page');\r\n}\r\n\r\nexport function wildcard (context:appex.web.IContext, path:string) {\r\n    \r\n    context.response.send(404, path + \" not found\");\r\n}\r\n\r\n```\r\n### install\r\n\r\n```javascript\r\nnpm install appex\r\n```\r\n### contents\r\n\r\n* [getting started](#getting_started)\r\n\t* [create a application](#application)\r\n\t* [start up options](#options)\r\n\t* [running on an existing http server](#http_server)\r\n\t* [running as express middleware](#express_middleware)\r\n* [http handlers](#http_handlers)\r\n\t* [context](#context)\r\n\t* [request](#request)\r\n\t* [response](#response)\r\n\t* [routing](#routing)\r\n\t* [signatures](#signatures)\r\n\t* [named handlers](#named_handlers)\r\n\t* [index handlers](#index_handlers)\r\n\t* [wildcard handlers](#wildcard_handlers)\r\n\t* [attributes](#attributes)\r\n\t* [verbs](#verbs)\r\n\t* [url rewrite](#url_rewrite)\r\n\t* [middleware](#middleware)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [handling 404](#handling_404)\r\n\t* [serving static files](#serving_static_files)\r\n* [templating](#templating)\r\n\t* [overview](#template_overview)\r\n\t* [context](#template_context)\t\r\n\t* [syntax](#template_syntax)\r\n\t* [layouts and sections](#template_layouts_and_sections)\r\n\t* [render](#template_render)\r\n\t* [caching and devmode](#caching_and_devmode)\r\n* [sitemaps](#sitemaps)\r\n\t* [generating](#sitemap_generate)\r\n\t* [metadata](#sitemap_metadata)\r\n* [json schema](#json_schema)\r\n\t* [generating schema](#generating_schema)\r\n\t* [validating json](#validating_json)\r\n\t* [web service descriptions](#web_service_descriptions)\r\n* [reflection](#reflection)\r\n\t* [reflect everything](#reflect_everything)\r\n\t* [reflect specific types](#reflect_specific_types)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [appex.d.ts declaration](#appex_declaration)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n* [license](#license)\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline creating appex applications and configuration.\r\n\r\n<a name=\"application\" />\r\n### create a application\r\n\r\nThe following code will create a standalone appex application and \r\nhttp server and listen on port 3000.\r\n\r\n```javascript\r\nvar appex   = require('appex');\r\n\r\nvar app   = appex({ program : './program.ts', \r\n                    devmode : true,\r\n                    logging : true });\r\n\r\napp.listen(3000);\r\n```\r\n\r\nnote: devmode and logging are optional. however, when developing \r\nwith appex, it is helpful to have these enabled.\r\n\r\n<a name=\"options\" />\r\n### start up options\r\n\r\nappex accepts the following start up options.\r\n\r\n```javascript\r\nvar options = {\r\n\r\n\t// (required) location of source file.\r\n\tprogram    : './program.ts', \r\n\r\n\t// (optional) recompile on request. (default:false) \r\n\tdevmode    : true,          \r\n\r\n\t// (optional) log to stdout. (default:false) \r\n\tlogging    : true,\r\n\r\n\t// (optional) user defined objects added to the app context.\r\n\tcontext    : {}\r\n};\r\n\r\nvar app = appex( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### running on an existing http server\r\n\r\nThe following demonstrates setting up appex on an existing nodejs http server. In \r\nthis example, appex will attempt to handle incoming requests, and if appex cannot\r\nroute the request, will fire the callback.\r\n\r\n```javascript\r\nvar http  = require('http');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\nvar server = http.createServer(function(req, res){\r\n\r\n    app(req, res, function() { // appex handler...\r\n\t\t\r\n\t\t// not handled.\r\n\r\n\t}); \r\n});\r\n\r\nserver.listen(3000);\r\n```\r\n\r\n<a name=\"express_middleware\" />\r\n### running as express middleware\r\n\r\nappex allows developers to augment existing express / connect applications by \r\nway of middleware. The following demonstrates setting up appex as express middleware.\r\n\r\n```javascript\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) ); \r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nLike in the \"running on an existing http server\" example above, appex will attempt to intercept incoming requests. \r\nif appex cannot find a matching route for the request, it will automatically call the \"next\" function to pass the request \r\non to the next middleware or express handler.\r\n\r\nin addition to this, appex may also act as traditional express middleware. In the example below, a appex wildcard\r\nfunction is created which will match \"all\" incoming requests, the wildcard function simply prints hello world to \r\nthe console and then calls context.next(), which passes the request on the express handler.\r\n\r\n```javascript\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tconsole.log('hello world!!');\r\n\r\n\tcontext.next(); // pass it on!\r\n}\r\n\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) );\r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nJust like traditional express middleware, appex will also inheriate the characteristics of the request.\r\n\r\nconsider the following example in which the jade view engine is configured for use. appex will inheritate the \r\nresponse.render() method, which is passed to the appex handler as context.response.render()\r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\napp.configure(function(){\r\n\r\n  app.set('views', __dirname + '/views');\r\n  \r\n  // set up the jade engine.\r\n  app.set('view engine', 'jade'); \r\n  \r\n  // bind appex\r\n  app.use( appex({program:'./program.ts', devmode:true} ));  \r\n});\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/\r\nexport function index(context) {\r\n\t\r\n\t// jade renderer works!\r\n\tcontext.response.render('index', { title: 'Express' }); \r\n}\r\n```\r\n\r\n<a name=\"http_handlers\" />\r\n## http handlers\r\n\r\nThe following sections describe how to create http accessible handlers with appex.\r\n\r\n<a name=\"context\" />\r\n### context\r\n\r\nAll appex functions are passed a application context object as their first argument. The app context object \r\nencapulates the http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```javascript\r\n// the app context\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.attribute    - appex attribute.\r\n\r\n\t// context.next       - the next function (express middleware)\r\n\t\r\n\t// context.router     - the appex router\r\n\r\n\t// context.sitemap    - the appex sitemap api\r\n\r\n\t// context.template   - the appex template engine.\r\n\t\r\n\t// context.module     - the module being run (this module)\r\n\r\n\t// context.schema     - json schema api.\r\n\r\n\t// context.mime       - a http mime type utility.\r\n}\r\n```\r\n\r\nit is possible to extend the default objects passed on the context by adding them on the appex startup options. The \r\nfollowing will attach the async module to the context. \r\n\r\n```javascript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = appex({ program : './program.ts', \r\n\t\t\t\t  devmode : true, \r\n\t\t\t      context: {\r\n\t\t\t\t\t\tasync : require('async')\r\n\t\t\t\t  }});\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\r\n\t// context.async = passed on the context.\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n```\r\n<a name=\"request\" />\r\n### request\r\n\r\nThe appex request is a nodejs http request issued by the underlying node http server. \r\nappex extends the request with convenience methods for reading http request data. These\r\nare outlined below.\r\n\r\nreading a posted string. \r\n```javascript\r\n//----------------------------------------------\r\n// receive request as a string\r\n//----------------------------------------------\r\nexport function submit(context) {\r\n\r\n\tcontext.request.body.recv((str) => {\r\n\r\n\t\t// do something with str\r\n\t})\r\n}\r\n```\r\nreading posted form data as json object.\r\n```javascript\r\n//----------------------------------------------\r\n// receive a form post\r\n//----------------------------------------------\r\nexport function submit(context) {\r\n\r\n\tcontext.request.body.form((obj) => {\r\n\r\n\t\t// do something with obj\r\n\t})\r\n}\r\n```\r\nreading posted json data as a json object.\r\n```javascript\r\n//----------------------------------------------\r\n// receive a json post\r\n//----------------------------------------------\r\nexport function submit(context) {\r\n\r\n\tcontext.request.body.json((obj) => {\r\n\t\t\r\n\t\t// do something with obj\r\n\t})\r\n}\r\n```\r\n\r\nnote: if appex detects that express or connect middleware has already been applied\r\nto the request object, appex will use those instead.\r\n\r\n<a name=\"response\" />\r\n### response\r\n\r\nThe appex response is a nodejs http response issued by the underlying node http server. \r\nappex provides some utility methods for writing http responses. These are outlined below.\r\n\r\n```js\r\n//----------------------------------------------\r\n// the nodejs response has been extended with the following\r\n// signatures.\r\n//----------------------------------------------\r\nexport interface IResponse extends http.ServerResponse {\r\n\t\r\n\tsend (data     : string): void;\r\n\r\n\tsend (data     : NodeBuffer): void;\r\n\r\n\tsend (status   : number, data : string): void;\r\n\r\n\tserve (filepath: string): void;\r\n\r\n\tserve (root : string, filepath: string): void;\r\n\r\n\tserve (root : string, filepath: string, mime:string): void;\r\n\r\n\tjson (obj      : any): void;\r\n\r\n\tjson (status   : number, obj : any): void;\r\n\r\n\tjsonp (obj     : any): void;\r\n\r\n\tjsonp (status  : number, obj : any): void;\r\n\r\n\tjsonp (status  : number, obj : any, callback: string): void;\r\n}\r\n```\r\n\r\nnote: if appex detects that express or connect middleware has already been applied\r\nto for any of the following response methods, appex will use those instead.\r\n\r\n<a name=\"routing\" />\r\n### routing\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```javascript\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context) {\r\n\r\n\t\tcontext.response.send('services.customers.insert')\r\n    }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context) { \r\n\t\t\r\n\t\tcontext.response.send('services.customers.update')\r\n    }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context) { \r\n\r\n\t\tcontext.response.send('services.customers.delete')\r\n\t}\r\n}\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context) { \r\n\r\n\tcontext.response.send('home page')\r\n}\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context) { \r\n\r\n\tcontext.response.send('about page')\r\n}\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context) { \r\n\r\n\tcontext.response.send('contact page')\r\n}\r\n\r\n// url: http://[host]:[port]/(.*)\r\nexport function wildcard (context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found')\r\n}\r\n\r\n```\r\n\r\n<a name=\"signatures\" />\r\n### signatures\r\n\r\nappex supports three function signatures for http routing (named, index and wildcard). Functions that\r\ndo not apply these signatures will not be routed.\r\n\r\n<a name=\"named_handlers\" />\r\n### named handlers\r\n\r\nNamed handlers resolve urls to their current module scope + the name of the function.\r\n\r\nNamed handlers require the following signature:\r\n\r\n* name        - 'anything'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n\r\n// http://[host]:[port]/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about page');\r\n}\r\n\r\n// http://[host]:[port]/users/login\r\nexport module users {\r\n\r\n\texport function login(context) {\r\n\t\t\r\n\t\tcontext.response.send('handle login');\t\r\n\t}\r\n}\r\n\r\n```\r\n\r\n<a name=\"index_handlers\" />\r\n### index handlers\r\n\r\nIndex handlers resolve urls to their current module scope.\r\n\r\nIndex handlers require the following signature:\r\n\r\n* name        - 'index'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```javascript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) \r\n\t{\t\r\n\t\tcontext.response.send('blog index');\r\n\t}\r\n}\r\n```\r\n\r\n<a name=\"wildcard_handlers\" />\r\n### wildcard handlers\r\n\r\nWildcard handlers resolve their urls to their current module scope + url.\r\n\r\nappex wildcard handlers allow for wildcard routing at a given module scope. Wildcard handlers\r\nsupport 'typed' url argument mapping, as denoted by the arguments annotation.\r\n\r\nIn addition, wildcard handlers also support optional arguments which can be specified with TypeScript's '?' \r\non argument names.\r\n\r\nappex wildcard handlers require the following signature:\r\n\r\n* name        - 'wildcard'\r\n* argument[0] - app context\r\n* argument[n] - 1 or more arguments to be mapped from the url\r\n* returns     - void (optional)\r\n\r\n```javascript\r\ndeclare var console;\r\n\r\nexport module blogs {\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11   - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/11  - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/3rd - not matched - (see number annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01     - matched     - (see ? annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013        - not matched - (month is required)\r\n\t\r\n    export function wildcard(context, year:number, month:number, day?:number) {\r\n\r\n        context.response.json({ year: year, month: month, day: day})\r\n    }\r\n}\r\n\r\n// url : http://[host]:[port]/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// url : http://[host]:[port]/(.*) \r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, 'not found');\r\n}\r\n\r\n```\r\nnote: appex supports boolean, number, string and any annotations on wildcard arguments. if no annotation\r\nis specified, appex interprets the argument as a string. the type 'any' is also interpreted as string.\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"attributes\" />\r\n### attributes\r\n\r\nappex supports a attribute scheme which developers can use to decorate modules and functions with \r\ndeclaritive metadata. appex attributes can set by calling the attribute('qualifier', data)\r\nfunction which is passed to the appex module on the global scope.\r\n\r\nunlike traditional attributes (in languages like C sharp) appex attributes have a cascading behaviour\r\nwhich allows developers to apply metadata at a lexical scope, and have it cascade through to descendant scopes.\r\n\r\nThe following outlines this behavour.\r\n\r\n```javascript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nattribute({a: 10}); // global.\r\n\r\nattribute('foo', {b : 20})\r\nexport module foo {\r\n\r\n    attribute('foo.bar', {c : 30})\r\n    export module bar {\r\n            \r\n        attribute('foo.bar.index', {d : 40})\r\n        export function index(context) {\r\n        \r\n            //context.attribute\r\n            //{\r\n            //    \"a\": 10,\r\n            //    \"b\": 20,\r\n            //    \"c\": 30,\r\n\t\t\t//    \"d\": 40\r\n            //}\r\n\r\n            context.response.json( context.attribute );       \r\n        }\r\n    }\r\n}\r\n\r\n```\r\n\r\nin addition, appex recognizes three types of attributes. developers can use these to override the default \r\nbahavour of the appex router and apply url rewriting (urls), verb matching (verbs) and middleware (use),\r\nas demonstrated below.\r\n\r\n```javascript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nfunction logger(context) {\r\n\tconsole.log('logging')\r\n\tcontext.next()\r\n}\r\n\r\n// invoke 'logger' middleware.\r\nattribute('index', {use   : [logger]})   \r\n\r\n// override the default route.\r\nattribute('index', {urls  : ['/', '/home']})  \r\n\r\n// only accept GET requests.\r\nattribute('index', {verbs : ['GET']})    \r\n\r\nexport function index(context:appex.web.IContext) {\r\n\t\r\n\tcontext.response.send('home page')\r\n}\r\n```\r\n\r\n<a name=\"verbs\" />\r\n### verbs\r\n\r\nappex handles http verb matching with attributes. appex will recognise the \r\n'verbs' property applied to the attribute to match against http verbs.\r\n\r\n```javascript\r\nattribute('index', { verbs: ['GET'] })\r\nexport function index (context) { \r\n        \r\n    // only allow HTTP GET requests\r\n    context.response.send('index')\r\n}\r\n\r\nattribute('submit', { verbs: ['POST', 'PUT'] })\r\nexport function submit (context) { \r\n    \r\n    // only allow HTTP POST and PUT requests\r\n    context.response.send('submit')\r\n}\r\n```\r\n\r\n<a name=\"url_rewrite\" />\r\n### url rewrite\r\n\r\ndevelopers can rewrite the default route given to exported functions with the 'urls' property applied\r\nto the attribute. \r\n\r\n```javascript\r\nattribute('index', { urls: ['/', '/home', 'home.html'] })\r\nexport function index (context) { \r\n    \r\n    context.response.send('index')\r\n}\r\n```\r\nnote: url rewriting is only available on index and named routes.\r\n\r\nnote: rewriting with regular expressions is currently not supported.\r\n\r\n<a name=\"middleware\" />\r\n### middleware\r\n\r\nappex supports middleware with attributes. appex middleware defined with attributes allows\r\ndevelopers to scope middleware on single functions, or entire module scopes. appex will \r\nrecognise the 'use' property applied to the attribute to invoke middleware.\r\n\r\nthe following demonstrates how one might use middleware to secure a site admin.\r\n\r\nnote: middleware 'must' call next or handle the request. \r\n\r\n```javascript\r\ndeclare function attribute (qualifier:string, obj:any);\r\n\r\ndeclare var console;\r\n\r\nfunction authenticate(context) {\r\n\r\n    console.log('authenticate')\r\n\r\n\t// call next() if authenticated, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\nfunction authorize(context) {\r\n\r\n    console.log('authorize')\r\n\r\n\t// call next() if authorized, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\n// apply security middleware to admin scope.\r\nattribute('admin', {use: [authenticate, authorize]}) \r\nexport module admin {\r\n\r\n    export function index(context) {\r\n        \r\n        console.log(context.attribute); // view attribute\r\n\r\n        context.response.send('access granted!')\r\n    }\r\n}\r\n\r\n// index handler has no middleware applied.\r\nexport function index (context) { \r\n    \r\n    console.log(context.attribute); // view attribute\r\n\r\n    context.response.send('home')\r\n}\r\n```\r\n\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex will only route functions prefixed with the TypeScript 'export' declarer. This rule\r\nalso applied to modules. Developers can use this to infer notions of public and private \r\nat the http level.\r\n\r\nconsider the following example:\r\n\r\n```javascript\r\n\r\n// module is not exported, and is \r\n// therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private \r\n\t// as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is \r\n\t// private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and \r\n// is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore \r\n// publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke \r\n\t// private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in \r\n\t// private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method \r\n\t// in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.send('public_function');\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```javascript\r\n// http:[host]:[port]/\r\nexport function index (context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard (context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n<a name=\"serving_static_files\" />\r\n## serving static files\r\n\r\nUse wildcard functions with context.response.serve() to serve static content.\r\n\r\n```javascript\r\nexport module static {\r\n\t\r\n\t// http:[host]:[port]/static/(.*)\r\n\texport function wildcard(context, path) {\r\n\r\n\t\tcontext.response.serve('./static/', path);\r\n\t}\r\n}\r\n\r\n// http:[host]:[port]/\r\nexport function index (context) {\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n\r\n<a name=\"templating\" />\r\n## templating\r\n\r\nappex comes bundled with a built in template engine which is modelled on the Microsoft \r\nRazor templating engine. The following sections outline its use.\r\n\r\n<a name=\"template_overview\" />\r\n### overview\r\n\r\nThe appex template engine is available to all handlers by default. it is accessible\r\non the context.template property. the following is an example of its use.\r\n\r\n```\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n<ul>\r\n@for(var n in context.users) {\r\n\r\n\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t<li>@(context.users[n].name)</li>\r\n\t}\r\n}\r\n</ul>\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\t\r\n\tcontext.response.headers['Content-Type'] = 'text/html';\r\n\r\n    context.response.send(text);\r\n}\r\n\r\n```\r\n\r\n<a name=\"template_context\" />\r\n### context\r\n\r\neach template is passed a data context. this context allows the caller to \r\nsend data to the template for rendering. the context parameter is optional.\r\nthe example below is sending the users array to the template context for \r\nrendering.\r\n\r\n```\r\nexport function index(context) {\r\n\t\r\n    var users  = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    context.response.send(context.template.render('./view.txt', { users: users }));\r\n}\r\n```\r\n\r\n<a name=\"template_syntax\" />\r\n### syntax\r\n\r\nappex templates support the following statements and syntax\r\n\r\n#### if statement\r\n\r\nif statments are supported.\r\n\r\n```\r\n@if(expression) {\r\n\tsome content\r\n}\r\n\r\n@if(a > 10) {\r\n\tsome content\r\n}\r\n\r\n@(user.loggedin) {\r\n\t<span>welcome</span>\r\n}\r\n```\r\n\r\n#### for statement\r\n\r\nthe following for loops are supported.\r\n\r\n```\r\n@for(var i = i; i < 100; i++) {\r\n\t@(i)\r\n}\r\n\r\n@for(var n in list) {\r\n\t@(list[n])\r\n}\r\n```\r\n\r\n#### expressions\r\n\r\nwill emit the value contained.\r\n\r\n```\r\n@('hello world')\r\n\r\n@(123)\r\n\r\n@(some_variable)\r\n```\r\n\r\n#### code blocks\r\n\r\ncode blocks can be useful for adding template side rendering logic.\r\n\r\n```\r\n@{\r\n\tvar message = 'hello'\r\n}\r\n\r\n@(message)\r\n```\r\n\r\n#### comments\r\n```\r\n@*\r\n\tthis comment will not be rendered!\r\n*@\r\n```\r\n\r\n<a name=\"template_layouts_and_sections\" />\r\n### layouts and sections\r\n\r\nappex templates support template inheritance.\r\n\r\nconsider the following where layout.txt defines the sections 'header' and 'content' and the view.txt overrides\r\nthese sections with its own content.\r\n\r\n```\r\n//----------------------------------------------\r\n// layout.txt\r\n//----------------------------------------------\r\n\r\n<html>\r\n\r\n\t<head>\r\n\t\t\r\n\t\t@section header\r\n\r\n\t</head>\r\n\r\n\t<body>\r\n\r\n\t\t@section content {\r\n\t\t\r\n\t\t\t<span>some default content</span>\r\n\t\t\t\r\n\t\t}\r\n\r\n\t</body>\r\n\t\r\n</html>\r\n\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n@layout 'layout.txt'\r\n\r\n@section header {\r\n\r\n\t<title>my page</title>\r\n}\r\n\r\n@section content {\r\n\r\n\t<p>overriding the layout.txt content section.</p>\r\n\r\n\t<ul>\r\n\t@for(var n in context.users) {\r\n\r\n\t\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t\t<li>@(context.users[n].name)</li>\r\n\t\t}\r\n\t}\r\n\t</ul>\r\n}\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\r\n    context.response.send(text);\r\n}\r\n```\r\n\r\nnote : when specifying a layout, the view will only render content within\r\nthe layouts section placeholders. \r\n\r\n<a name=\"render\" />\r\n### render\r\n\r\nappex templates also allow for partial views with the @render statment. consider the following \r\nwhich renders the nav.txt file into the layout.txt file.\r\n\r\n```\r\n//----------------------------------------------\r\n// nav.txt\r\n//----------------------------------------------\r\n<ul>\r\n\t<li>home</li>\r\n\t<li>about</li>\r\n\t<li>contact</li>\r\n</ul>\r\n\r\n//----------------------------------------------\r\n// layout.txt\r\n//----------------------------------------------\r\n\r\n<html>\r\n\t<head>\r\n\t\t\r\n\t\t@section header\r\n\r\n\t</head>\r\n\r\n\t<body>\r\n\t\t\r\n\t\t@render 'nav.txt'\r\n\r\n\t\t@section content {\r\n\t\t\r\n\t\t\t<span>some default content</span>\r\n\t\t\t\r\n\t\t}\r\n\r\n\t</body>\r\n\t\r\n</html>\r\n\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n@layout 'layout.txt'\r\n\r\n@section header {\r\n\r\n\t<title>my page</title>\r\n}\r\n\r\n@section content {\r\n\r\n\t<p>overriding the layout.txt content section.</p>\r\n\r\n\t<ul>\r\n\t@for(var n in context.users) {\r\n\r\n\t\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t\t<li>@(context.users[n].name)</li>\r\n\t\t}\r\n\t}\r\n\t</ul>\r\n}\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\r\n    context.response.send(text);\r\n}\r\n```\r\n\r\n<a name=\"caching_and_devmode\" />\r\n### caching and devmode\r\n\r\nappex template content is not cached (the implementor is expected to handle their own caching)\r\nhowever the generated template code is. \r\n\r\nappex templates do inheriate the behaviour of the appex 'devmode' option. setting\r\ndevmode to 'true' will cause template code to be reloaded from disk and code generated with each \r\nrequest. setting devmode to false will load content from disk on first request, and \r\ncache the generated template code in memory for the lifetime of the application.\r\n\r\nin addition to this, a implementation where the devmode is false can override the caching \r\nbehaviour with the following.\r\n\r\n```javascript\r\nexport function index(context) {\r\n\r\n\t// manually override the template devmode option.\r\n\tcontext.template.option.devmode = true; \r\n\r\n\tcontext.response.send(context.template.render('./view.txt'))\r\n}\r\n```\r\n\r\n<a name=\"sitemaps\" />\r\n## sitemaps\r\n\r\nappex is able to derive sitemap metadata automatically from http endpoints created with\r\ntypescript modules and functions. This metadata is useful to generate sitemap.xml\r\nfiles, as well as helping to create site navigation links when combined a template\r\nengine.\r\n\r\n<a name=\"sitemap_generate\" />\r\n### generate sitemap\r\n\r\nappex sitemaps can be obtained from the context.sitemap property. \r\n\r\n```javascript\r\nexport function index(context) {\r\n\r\n\t// return all nodes in this site.\r\n\tcontext.response.json(context.sitemap)\r\n\r\n}\r\n```\r\n\r\nAdditionally, it may be helpful to isolate branches of the sitemap with the \r\ncontext.sitemap.get([qualifier]) function. as demonstrated below.\r\n\r\n```javascript\r\nexport module admin {\r\n\r\n\texport function index     (context) { }\r\n\r\n\texport function dashboard (context) { }\r\n\r\n\texport function content   (context) { }\r\n\r\n\texport module users {\r\n\r\n\t\texport function login(context) { }\r\n\r\n\t\texport function logout(context) { }\r\n\t}\r\n}\r\n\r\nexport function test(context) {\r\n\t\r\n\t// view all admin sitemap nodes\r\n\tcontext.response.json(context.sitemap.get('admin'))\r\n\r\n\t// view all admin.users sitemap nodes\r\n\t//context.response.json(context.sitemap.get('admin.users'))\r\n}\r\n```\r\n\r\n<a name=\"sitemap_metadata\" />\r\n### attribute metadata\r\n\r\neach sitemap node contains the attribute applied to the handler for which the node applies. With this\r\ndevelopers can apply custom metadata for a given node. as demonstrated below.\r\n\r\n```javascript\r\ndeclare var attribute;\r\n\r\nattribute({website:'http://mysite.com/'}) // global\r\n\r\nattribute('index', {title:'home page'})\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('index')\r\n}\r\n\r\nattribute('about', {title: 'about page'})\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about')\r\n}\r\n\r\nattribute('sitemap', {title: 'sitemap page'})\r\nexport function sitemap(context) {\r\n\r\n\tcontext.response.json(context.sitemap)\r\n}\r\n```\r\n\r\nvisiting /sitemap will output the following.\r\n\r\n```javascript\r\n{\r\n    \"name\": \"sitemap\",\r\n    \"nodes\": [\r\n        {\r\n            \"name\": \"index\",\r\n            \"urls\": [\r\n                \"/\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"home page\"\r\n        },\r\n        {\r\n            \"name\": \"about\",\r\n            \"urls\": [\r\n                \"/about\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"about page\"\r\n        },\r\n        {\r\n            \"name\": \"sitemap\",\r\n            \"urls\": [\r\n                \"/sitemap\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"sitemap page\"\r\n        }\r\n    ]\r\n}\r\n```\r\n\r\n<a name=\"json_schema\" />\r\n## json schema\r\n\r\nappex provides functionality for generating json schemas from TypeScript classes\r\nand interfaces as well as tools for validating json data.\r\n\r\n<a name=\"generating_schema\" />\r\n### generating schema\r\n\r\nThe following demonstrates generating json schema from the following class\r\nhierarchy.\r\n\r\n```javascript\r\nexport module model {\r\n\r\n    /** a product */\r\n    export class Product {\r\n        \r\n        /** the product name */\r\n        public name        : string;\r\n\r\n        /** the product description */\r\n        public description : string;\r\n\r\n        /** the product cost */\r\n        public cost        : number;\r\n    } \r\n\r\n    /** a order */\r\n    export class Order {\r\n        \r\n        /** the product being ordered */\r\n        public products  : Product;\r\n    }\r\n\r\n    /** a customer */\r\n    export class Customer {\r\n\r\n        /** the customers firstname */\r\n        public firstname  : string;\r\n\r\n        /** the customers lastname */\r\n        public lastname   : string;\r\n\r\n        /** orders made by this customer */\r\n        public orders     : Order[];\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.IContext) {\r\n\t\r\n\t// pass the fully qualified name of the type.\r\n    var schema = context.schema.generate('model.Customer');\r\n\r\n    context.response.json(schema);\r\n}\r\n```\r\n\r\nwhich generates the following json schema.\r\n\r\n```javascript\r\n{\r\n    \"id\": \"model.Customer\",\r\n    \"type\": \"object\",\r\n    \"description\": \"a customer\",\r\n    \"properties\": {\r\n        \"firstname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers firstname\",\r\n            \"required\": true\r\n        },\r\n        \"lastname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers lastname\",\r\n            \"required\": true\r\n        },\r\n        \"orders\": {\r\n            \"type\": \"array\",\r\n            \"items\": {\r\n                \"type\": {\r\n                    \"id\": \"model.Order\",\r\n                    \"type\": \"object\",\r\n                    \"description\": \"a order\",\r\n                    \"properties\": {\r\n                        \"products\": {\r\n                            \"id\": \"model.Product\",\r\n                            \"type\": \"object\",\r\n                            \"description\": \"a product\",\r\n                            \"properties\": {\r\n                                \"name\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product name\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"description\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product description\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"cost\": {\r\n                                    \"type\": \"number\",\r\n                                    \"description\": \"the product cost\",\r\n                                    \"required\": true\r\n                                }\r\n                            },\r\n                            \"required\": true\r\n                        }\r\n                    }\r\n                }\r\n            },\r\n            \"description\": \"orders made by this customer\",\r\n            \"required\": true\r\n        }\r\n    }\r\n}\r\n```\r\na quick note...\r\n\r\nwhen generating schema from classes:\r\n\r\n* only public class variables will be emitted.\r\n* all properties will be marked as \"required\".\r\n\r\nwhen generating schema from interfaces:\r\n\r\n* all properties will be emitted. \r\n* all properties will be marked as \"required\" unless modified with '?'.\r\n\r\n<a name=\"validating_json\" />\r\n### validating json\r\n\r\nappex supports json schema validation from class and interface definitions. consider the following...\r\n\r\n```javascript\r\ninterface Customer {\r\n\r\n    firstname    : string;\r\n\r\n    lastname     : string;\r\n\r\n    age          : number;\r\n\r\n    emails       : string[];\r\n\r\n    option_a ?   : boolean; // optional\r\n\r\n    option_b ?   : boolean; // optional\r\n\r\n}\r\n\r\nexport function index(context) {\r\n\r\n    // a customer with invalid data.\r\n\r\n    var customer = {\r\n\r\n        firstname    : 'dave',\r\n\r\n        age          : '33',\r\n\r\n        emails       : [12345, 'dave@domain.com', true],\r\n\r\n        option_b     : 1,\r\n\r\n        option_c     : 1\r\n    }\r\n\r\n    // do validation.\r\n\r\n    var errors = context.schema.validate('Customer', customer);\r\n\r\n    if(errors) {\r\n\r\n        context.response.json(errors);\r\n    }\r\n}\r\n```\r\n\r\nwill output the following.\r\n\r\n```javascript\r\n[\r\n    {\r\n        \"message\": \"instance.lastname is required.\"\r\n    },\r\n    {\r\n        \"message\": \"instance.age is not a number\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[0] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[2] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_b is not a boolean\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_c unexpected property\"\r\n    }\r\n]\r\n```\r\n\r\n<a name=\"web_service_descriptions\">\r\n### web service descriptions\r\n\r\nFor those using appex for web services, developers can leverage appex json schema generation\r\nto generate endpoint metadata (think wsdl). Consider the following which leverages both appex \r\nschema generation and attributes to produce a metadata endpoint consumers of your\r\napi can use to see what data the endpoint http://example.com/customer/create accepts \r\nand returns.\r\n\r\n```javascript\r\nclass Request {\r\n\r\n    /** the customers firstname */\r\n    firstname : string;\r\n\r\n    /** the customers lastname */\r\n    lastname  : string;\r\n\r\n\t/** the customers lastname */\r\n}\r\n\r\nclass Response {\r\n\r\n    /** true on success  */\r\n    success:boolean;\r\n    \r\n    /** an array of validation errors  */\r\n    errors : string[];\r\n}\r\n\r\nattribute('metadata', {input  : 'Request', output : 'Response'})\r\nexport function metadata(context:appex.web.IContext) {\r\n\r\n    var metadata = {\r\n        \r\n\t\tendpoint : 'http://example.com/customer/create',\r\n\r\n        input    : context.schema.generate(context.attribute.input),\r\n\r\n        output   : context.schema.generate(context.attribute.output)\r\n    }\r\n\r\n    context.response.json(metadata)\r\n}\r\n```\r\n\r\nwhich outputs the following.\r\n\r\n```javascript\r\n{\r\n    \"endpoint\": \"http://example.com/customer/create\",\r\n    \"input\": {\r\n        \"id\": \"Request\",\r\n        \"type\": \"object\",\r\n        \"properties\": {\r\n            \"firstname\": {\r\n                \"type\": \"string\",\r\n                \"description\": \"the customers firstname\",\r\n                \"required\": true\r\n            },\r\n            \"lastname\": {\r\n                \"type\": \"string\",\r\n                \"description\": \"the customers lastname\",\r\n                \"required\": true\r\n            }\r\n        }\r\n    },\r\n    \"output\": {\r\n        \"id\": \"Response\",\r\n        \"type\": \"object\",\r\n        \"properties\": {\r\n            \"success\": {\r\n                \"type\": \"boolean\",\r\n                \"description\": \"true on success\",\r\n                \"required\": true\r\n            },\r\n            \"errors\": {\r\n                \"type\": \"array\",\r\n                \"description\": \"an array of validation errors\",\r\n                \"items\": {\r\n                    \"type\": \"string\"\r\n                },\r\n                \"required\": true\r\n            }\r\n        }\r\n    }\r\n}\r\n```\r\ntip: use the appex sitemap metadata to produce a metadata endpoint for all service methods \r\nin your application.\r\n\r\n\r\n<a name=\"reflection\" />\r\n## reflection\r\n\r\nappex provides a reflection api derived from TypeScript's type system that developers can \r\nleverage to reflect type information declared throughout their appex modules. \r\n\r\nthe following section outlines how to use the reflection api.\r\n\r\n<a name=\"reflect_everything\" />\r\n### reflect everything\r\n\r\nthe appex reflection api is passed on the context.module.reflection property and is available to all\r\nappex handler methods. The following code will JSON serialize everything declared in your appex\r\nproject and write it to the http response. \r\n\r\n```javascript\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection );\r\n}\r\n```\r\n\r\n<a name=\"reflect_specific_types\" />\r\n### reflect specific types\r\n\r\nIn typical scenarios, developers will want to leverage reflection meta data to generate\r\nservice contacts and client side models. the reflection api lets you access meta data \r\nfor the following types declared in your project. \r\n\r\n* modules\r\n* imports\r\n* classes\r\n* interfaces\r\n* functions\r\n* variables\r\n\r\nto access specific type metadata, use the reflection.get([qualifier]) method, as demonstrated below.\r\n\r\n```javascript\r\nexport module model {\r\n    \r\n    export class Customer {\r\n\r\n        public firstname   : string;\r\n\r\n        public lastname    : string;\r\n\r\n        public age         : number;\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('model.Customer') );\r\n}\r\n```\r\nand methods..\r\n\r\n```javascript\r\nfunction some_method(a:string, b:number, c?:boolean) : void { }\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_method') );\r\n}\r\n```\r\n\r\n....and variables...\r\n\r\n```javascript\r\nvar some_variable:number = 10;\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_variable') );\r\n}\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\nThis section outlines development with appex.\r\n\r\n<a name=\"appex_declaration\" />\r\n### appex.d.ts declaration\r\n\r\nIf you develop on a TypeScript complicant editor (one that supports TS 0.9), appex comes bundled\r\nwith a declaration file you can reference in your project. If installing appex via npm, your\r\nreference should be as follows.\r\n\r\n```javascript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nexport function index (context:appex.web.IContext) { \r\n    \r\n    context.response.send('hello');\r\n}\r\n\r\nexport function wildcard(context:appex.web.IContext, path:string) {\r\n\r\n    context.response.serve('./', path);\r\n}\r\n```\r\n\r\nBy referencing this in your project, you get the benefits of code completion and static type checking\r\nagainst both appex, and the nodejs core.\r\n\r\n![](https://raw.github.com/sinclairzx81/appex/master/artifacts/code-completion.jpg)\r\n\r\nAdditional declaration files may be obtained from [here](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```javascript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex ({ program : './index.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"users.ts\" />\r\n/// <reference path=\"pages.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { context.response.send('users.login') }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { context.response.send('users.logout') }\r\n}\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { context.response.send('home') }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { context.response.send('about') }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { context.response.send('contact') }\r\n\r\nexport function wildcard (context, path) { context.response.send(404, ' not found') }\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"license\" />\r\n## license\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) 2013 Haydn Paterson (sinclair) <haydn.developer@gmail.com>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in\r\nall copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\nTHE SOFTWARE.\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"https://raw.github.com/sinclairzx81/appex/master/license.txt","type":"The MIT License (MIT)"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.3.8","description":"develop nodejs web applications with typescript","directories":{},"dependencies":{"typescript.api":"0.7.7"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.6.8":{"name":"appex","version":"0.6.8","keywords":["typescript","web api","reflection","compiler","schema","templates","sitemap"],"author":{"name":"sinclair"},"_id":"appex@0.6.8","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"46d1128839c449ec4f0b22d8016d015715f28a93","tarball":"https://registry.npmjs.org/appex/-/appex-0.6.8.tgz","integrity":"sha512-cVG13Xtg2JEGIt7RimNYAr+Pq5+Ko6rPzn9CqUoGDYIgCuaY9qbYQVoQnPl4tMg2tVIXJzVfSvjzEagYsTHHoA==","signatures":[{"sig":"MEQCIB6W/HMl3PIAtRnPF/rlGaEa4tcgqkdjB5FKhSuHkouVAiB4MwJ1MYx+rnLk5fHOlPEubCA1cuKI7vjplw1YT96FBg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/artifacts/logo.jpg)\r\n\r\n### develop nodejs web applications with [typescript](http://www.typescriptlang.org/)\r\n\r\n\r\n```typescript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nexport function index(context:appex.web.IContext) {\r\n\t\r\n\tcontext.response.send('home page');\r\n}\r\n\r\nexport function about(context:appex.web.IContext) {\r\n\t\r\n\tcontext.response.send('about page');\r\n}\r\n\r\nexport function wildcard (context:appex.web.IContext, path:string) {\r\n    \r\n    context.response.send(404, path + \" not found\");\r\n}\r\n\r\n```\r\n### install\r\n\r\n```\r\nnpm install appex\r\n```\r\n### contents\r\n\r\n* [getting started](#getting_started)\r\n\t* [create a application](#application)\r\n\t* [start up options](#options)\r\n\t* [running on an existing http server](#http_server)\r\n\t* [running as express middleware](#express_middleware)\r\n* [http handlers](#http_handlers)\r\n\t* [context](#context)\r\n\t* [request](#request)\r\n\t* [response](#response)\r\n\t* [routing](#routing)\r\n\t* [signatures](#signatures)\r\n\t* [named handlers](#named_handlers)\r\n\t* [index handlers](#index_handlers)\r\n\t* [wildcard handlers](#wildcard_handlers)\r\n\t* [attributes](#attributes)\r\n\t* [verbs](#verbs)\r\n\t* [url rewrite](#url_rewrite)\r\n\t* [middleware](#middleware)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [handling 404](#handling_404)\r\n\t* [serving static files](#serving_static_files)\r\n* [templating](#templating)\r\n\t* [overview](#template_overview)\r\n\t* [context](#template_context)\t\r\n\t* [syntax](#template_syntax)\r\n\t* [layouts and sections](#template_layouts_and_sections)\r\n\t* [render](#template_render)\r\n\t* [caching and devmode](#caching_and_devmode)\r\n* [sitemaps](#sitemaps)\r\n\t* [generating](#sitemap_generate)\r\n\t* [metadata](#sitemap_metadata)\r\n* [json schema](#json_schema)\r\n\t* [generating schema](#generating_schema)\r\n\t* [validating json](#validating_json)\r\n\t* [web service descriptions](#web_service_descriptions)\r\n* [reflection](#reflection)\r\n\t* [reflect everything](#reflect_everything)\r\n\t* [reflect specific types](#reflect_specific_types)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [appex.d.ts declaration](#appex_declaration)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n* [license](#license)\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline creating appex applications and configuration.\r\n\r\n<a name=\"application\" />\r\n### create a application\r\n\r\nThe following code will create a standalone appex application and \r\nhttp server and listen on port 3000.\r\n\r\n```typescript\r\nvar appex   = require('appex');\r\n\r\nvar app   = appex({ program : './program.ts', \r\n                    devmode : true,\r\n                    logging : true });\r\n\r\napp.listen(3000);\r\n```\r\n\r\nnote: devmode and logging are optional. however, when developing \r\nwith appex, it is helpful to have these enabled.\r\n\r\n<a name=\"options\" />\r\n### start up options\r\n\r\nappex accepts the following start up options.\r\n\r\n```typescript\r\nvar options = {\r\n\r\n\t// (required) location of source file.\r\n\tprogram    : './program.ts', \r\n\r\n\t// (optional) recompile on request. (default:false) \r\n\tdevmode    : true,          \r\n\r\n\t// (optional) log to stdout. (default:false) \r\n\tlogging    : true,\r\n\r\n\t// (optional) user defined objects added to the app context.\r\n\tcontext    : {}\r\n};\r\n\r\nvar app = appex( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### running on an existing http server\r\n\r\nThe following demonstrates setting up appex on an existing nodejs http server. In \r\nthis example, appex will attempt to handle incoming requests, and if appex cannot\r\nroute the request, will fire the callback.\r\n\r\n```typescript\r\nvar http  = require('http');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\nvar server = http.createServer(function(req, res){\r\n\r\n    app(req, res, function() { // appex handler...\r\n\t\t\r\n\t\t// not handled.\r\n\r\n\t}); \r\n});\r\n\r\nserver.listen(3000);\r\n```\r\n\r\n<a name=\"express_middleware\" />\r\n### running as express middleware\r\n\r\nappex allows developers to augment existing express / connect applications by \r\nway of middleware. The following demonstrates setting up appex as express middleware.\r\n\r\n```typescript\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) ); \r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nLike in the \"running on an existing http server\" example above, appex will attempt to intercept incoming requests. \r\nif appex cannot find a matching route for the request, it will automatically call the \"next\" function to pass the request \r\non to the next middleware or express handler.\r\n\r\nin addition to this, appex may also act as traditional express middleware. In the example below, a appex wildcard\r\nfunction is created which will match \"all\" incoming requests, the wildcard function simply prints hello world to \r\nthe console and then calls context.next(), which passes the request on the express handler.\r\n\r\n```typescript\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tconsole.log('hello world!!');\r\n\r\n\tcontext.next(); // pass it on!\r\n}\r\n\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) );\r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nJust like traditional express middleware, appex will also inheriate the characteristics of the request.\r\n\r\nconsider the following example in which the jade view engine is configured for use. appex will inheritate the \r\nresponse.render() method, which is passed to the appex handler as context.response.render()\r\n\r\n```typescript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\napp.configure(function(){\r\n\r\n  app.set('views', __dirname + '/views');\r\n  \r\n  // set up the jade engine.\r\n  app.set('view engine', 'jade'); \r\n  \r\n  // bind appex\r\n  app.use( appex({program:'./program.ts', devmode:true} ));  \r\n});\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/\r\nexport function index(context) {\r\n\t\r\n\t// jade renderer works!\r\n\tcontext.response.render('index', { title: 'Express' }); \r\n}\r\n```\r\n\r\n<a name=\"http_handlers\" />\r\n## http handlers\r\n\r\nThe following sections describe how to create http accessible handlers with appex.\r\n\r\n<a name=\"context\" />\r\n### context\r\n\r\nAll appex functions are passed a application context object as their first argument. The app context object \r\nencapulates the http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```typescript\r\n// the app context\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.attribute    - appex attribute.\r\n\r\n\t// context.next       - the next function (express middleware)\r\n\t\r\n\t// context.router     - the appex router\r\n\r\n\t// context.sitemap    - the appex sitemap api\r\n\r\n\t// context.template   - the appex template engine.\r\n\t\r\n\t// context.module     - the module being run (this module)\r\n\r\n\t// context.schema     - json schema api.\r\n\r\n\t// context.mime       - a http mime type utility.\r\n}\r\n```\r\n\r\nit is possible to extend the default objects passed on the context by adding them on the appex startup options. The \r\nfollowing will attach the async module to the context. \r\n\r\n```typescript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = appex({ program : './program.ts', \r\n\t\t\t\t  devmode : true, \r\n\t\t\t      context: {\r\n\t\t\t\t\t\tasync : require('async')\r\n\t\t\t\t  }});\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\r\n\t// context.async = passed on the context.\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n```\r\n<a name=\"request\" />\r\n### request\r\n\r\nThe appex request is a nodejs http request issued by the underlying node http server. \r\nappex extends the request with convenience methods for reading http request data. These\r\nare outlined below.\r\n\r\nreading a posted string. \r\n```typescript\r\n//----------------------------------------------\r\n// receive request as a string\r\n//----------------------------------------------\r\nexport function submit(context) {\r\n\r\n\tcontext.request.body.recv((str) => {\r\n\r\n\t\t// do something with str\r\n\t})\r\n}\r\n```\r\nreading posted form data as json object.\r\n```typescript\r\n//----------------------------------------------\r\n// receive a form post\r\n//----------------------------------------------\r\nexport function submit(context) {\r\n\r\n\tcontext.request.body.form((obj) => {\r\n\r\n\t\t// do something with obj\r\n\t})\r\n}\r\n```\r\nreading posted json data as a json object.\r\n```typescript\r\n//----------------------------------------------\r\n// receive a json post\r\n//----------------------------------------------\r\nexport function submit(context) {\r\n\r\n\tcontext.request.body.json((obj) => {\r\n\t\t\r\n\t\t// do something with obj\r\n\t})\r\n}\r\n```\r\n\r\nnote: if appex detects that express or connect middleware has already been applied\r\nto the request object, appex will use those instead.\r\n\r\n<a name=\"response\" />\r\n### response\r\n\r\nThe appex response is a nodejs http response issued by the underlying node http server. \r\nappex provides some utility methods for writing http responses. These are outlined below.\r\n\r\n```js\r\n//----------------------------------------------\r\n// the nodejs response has been extended with the following\r\n// signatures.\r\n//----------------------------------------------\r\nexport interface IResponse extends http.ServerResponse {\r\n\t\r\n\tsend (data     : string): void;\r\n\r\n\tsend (data     : NodeBuffer): void;\r\n\r\n\tsend (status   : number, data : string): void;\r\n\r\n\tserve (filepath: string): void;\r\n\r\n\tserve (root : string, filepath: string): void;\r\n\r\n\tserve (root : string, filepath: string, mime:string): void;\r\n\r\n\tjson (obj      : any): void;\r\n\r\n\tjson (status   : number, obj : any): void;\r\n\r\n\tjsonp (obj     : any): void;\r\n\r\n\tjsonp (status  : number, obj : any): void;\r\n\r\n\tjsonp (status  : number, obj : any, callback: string): void;\r\n}\r\n```\r\n\r\nnote: if appex detects that express or connect middleware has already been applied\r\nto for any of the following response methods, appex will use those instead.\r\n\r\n<a name=\"routing\" />\r\n### routing\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```typescript\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context) {\r\n\r\n\t\tcontext.response.send('services.customers.insert')\r\n    }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context) { \r\n\t\t\r\n\t\tcontext.response.send('services.customers.update')\r\n    }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context) { \r\n\r\n\t\tcontext.response.send('services.customers.delete')\r\n\t}\r\n}\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context) { \r\n\r\n\tcontext.response.send('home page')\r\n}\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context) { \r\n\r\n\tcontext.response.send('about page')\r\n}\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context) { \r\n\r\n\tcontext.response.send('contact page')\r\n}\r\n\r\n// url: http://[host]:[port]/(.*)\r\nexport function wildcard (context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found')\r\n}\r\n\r\n```\r\n\r\n<a name=\"signatures\" />\r\n### signatures\r\n\r\nappex supports three function signatures for http routing (named, index and wildcard). Functions that\r\ndo not apply these signatures will not be routed.\r\n\r\n<a name=\"named_handlers\" />\r\n### named handlers\r\n\r\nNamed handlers resolve urls to their current module scope + the name of the function.\r\n\r\nNamed handlers require the following signature:\r\n\r\n* name        - 'anything'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```typescript\r\n\r\n// http://[host]:[port]/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about page');\r\n}\r\n\r\n// http://[host]:[port]/users/login\r\nexport module users {\r\n\r\n\texport function login(context) {\r\n\t\t\r\n\t\tcontext.response.send('handle login');\t\r\n\t}\r\n}\r\n\r\n```\r\n\r\n<a name=\"index_handlers\" />\r\n### index handlers\r\n\r\nIndex handlers resolve urls to their current module scope.\r\n\r\nIndex handlers require the following signature:\r\n\r\n* name        - 'index'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```typescript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) \r\n\t{\t\r\n\t\tcontext.response.send('blog index');\r\n\t}\r\n}\r\n```\r\n\r\n<a name=\"wildcard_handlers\" />\r\n### wildcard handlers\r\n\r\nWildcard handlers resolve their urls to their current module scope + url.\r\n\r\nappex wildcard handlers allow for wildcard routing at a given module scope. Wildcard handlers\r\nsupport 'typed' url argument mapping, as denoted by the arguments annotation.\r\n\r\nIn addition, wildcard handlers also support optional arguments which can be specified with TypeScript's '?' \r\non argument names.\r\n\r\nappex wildcard handlers require the following signature:\r\n\r\n* name        - 'wildcard'\r\n* argument[0] - app context\r\n* argument[n] - 1 or more arguments to be mapped from the url\r\n* returns     - void (optional)\r\n\r\n```typescript\r\ndeclare var console;\r\n\r\nexport module blogs {\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11   - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/11  - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/3rd - not matched - (see number annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01     - matched     - (see ? annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013        - not matched - (month is required)\r\n\t\r\n    export function wildcard(context, year:number, month:number, day?:number) {\r\n\r\n        context.response.json({ year: year, month: month, day: day})\r\n    }\r\n}\r\n\r\n// url : http://[host]:[port]/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// url : http://[host]:[port]/(.*) \r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, 'not found');\r\n}\r\n\r\n```\r\nnote: appex supports boolean, number, string and any annotations on wildcard arguments. if no annotation\r\nis specified, appex interprets the argument as a string. the type 'any' is also interpreted as string.\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"attributes\" />\r\n### attributes\r\n\r\nappex supports a attribute scheme which developers can use to decorate modules and functions with \r\ndeclaritive metadata. appex attributes can set by calling the attribute('qualifier', data)\r\nfunction which is passed to the appex module on the global scope.\r\n\r\nunlike traditional attributes (in languages like C sharp) appex attributes have a cascading behaviour\r\nwhich allows developers to apply metadata at a lexical scope, and have it cascade through to descendant scopes.\r\n\r\nThe following outlines this behavour.\r\n\r\n```typescript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nattribute({a: 10}); // global.\r\n\r\nattribute('foo', {b : 20})\r\nexport module foo {\r\n\r\n    attribute('foo.bar', {c : 30})\r\n    export module bar {\r\n            \r\n        attribute('foo.bar.index', {d : 40})\r\n        export function index(context) {\r\n        \r\n            //context.attribute\r\n            //{\r\n            //    \"a\": 10,\r\n            //    \"b\": 20,\r\n            //    \"c\": 30,\r\n\t\t\t//    \"d\": 40\r\n            //}\r\n\r\n            context.response.json( context.attribute );       \r\n        }\r\n    }\r\n}\r\n\r\n```\r\n\r\nin addition, appex recognizes three types of attributes. developers can use these to override the default \r\nbahavour of the appex router and apply url rewriting (urls), verb matching (verbs) and middleware (use),\r\nas demonstrated below.\r\n\r\n```typescript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nfunction logger(context) {\r\n\tconsole.log('logging')\r\n\tcontext.next()\r\n}\r\n\r\n// invoke 'logger' middleware.\r\nattribute('index', {use   : [logger]})   \r\n\r\n// override the default route.\r\nattribute('index', {urls  : ['/', '/home']})  \r\n\r\n// only accept GET requests.\r\nattribute('index', {verbs : ['GET']})    \r\n\r\nexport function index(context:appex.web.IContext) {\r\n\t\r\n\tcontext.response.send('home page')\r\n}\r\n```\r\n\r\n<a name=\"verbs\" />\r\n### verbs\r\n\r\nappex handles http verb matching with attributes. appex will recognise the \r\n'verbs' property applied to the attribute to match against http verbs.\r\n\r\n```typescript\r\nattribute('index', { verbs: ['GET'] })\r\nexport function index (context) { \r\n        \r\n    // only allow HTTP GET requests\r\n    context.response.send('index')\r\n}\r\n\r\nattribute('submit', { verbs: ['POST', 'PUT'] })\r\nexport function submit (context) { \r\n    \r\n    // only allow HTTP POST and PUT requests\r\n    context.response.send('submit')\r\n}\r\n```\r\n\r\n<a name=\"url_rewrite\" />\r\n### url rewrite\r\n\r\ndevelopers can rewrite the default route given to exported functions with the 'urls' property applied\r\nto the attribute. \r\n\r\n```typescript\r\nattribute('index', { urls: ['/', '/home', 'home.html'] })\r\nexport function index (context) { \r\n    \r\n    context.response.send('index')\r\n}\r\n```\r\nnote: url rewriting is only available on index and named routes.\r\n\r\nnote: rewriting with regular expressions is currently not supported.\r\n\r\n<a name=\"middleware\" />\r\n### middleware\r\n\r\nappex supports middleware with attributes. appex middleware defined with attributes allows\r\ndevelopers to scope middleware on single functions, or entire module scopes. appex will \r\nrecognise the 'use' property applied to the attribute to invoke middleware.\r\n\r\nthe following demonstrates how one might use middleware to secure a site admin.\r\n\r\nnote: middleware 'must' call next or handle the request. \r\n\r\n```typescript\r\ndeclare function attribute (qualifier:string, obj:any);\r\n\r\ndeclare var console;\r\n\r\nfunction authenticate(context) {\r\n\r\n    console.log('authenticate')\r\n\r\n\t// call next() if authenticated, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\nfunction authorize(context) {\r\n\r\n    console.log('authorize')\r\n\r\n\t// call next() if authorized, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\n// apply security middleware to admin scope.\r\nattribute('admin', {use: [authenticate, authorize]}) \r\nexport module admin {\r\n\r\n    export function index(context) {\r\n        \r\n        console.log(context.attribute); // view attribute\r\n\r\n        context.response.send('access granted!')\r\n    }\r\n}\r\n\r\n// index handler has no middleware applied.\r\nexport function index (context) { \r\n    \r\n    console.log(context.attribute); // view attribute\r\n\r\n    context.response.send('home')\r\n}\r\n```\r\n\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex will only route functions prefixed with the TypeScript 'export' declarer. This rule\r\nalso applied to modules. Developers can use this to infer notions of public and private \r\nat the http level.\r\n\r\nconsider the following example:\r\n\r\n```typescript\r\n\r\n// module is not exported, and is \r\n// therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private \r\n\t// as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is \r\n\t// private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and \r\n// is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore \r\n// publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke \r\n\t// private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in \r\n\t// private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method \r\n\t// in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.send('public_function');\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```typescript\r\n// http:[host]:[port]/\r\nexport function index (context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard (context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n<a name=\"serving_static_files\" />\r\n## serving static files\r\n\r\nUse wildcard functions with context.response.serve() to serve static content.\r\n\r\n```typescript\r\nexport module static {\r\n\t\r\n\t// http:[host]:[port]/static/(.*)\r\n\texport function wildcard(context, path) {\r\n\r\n\t\tcontext.response.serve('./static/', path);\r\n\t}\r\n}\r\n\r\n// http:[host]:[port]/\r\nexport function index (context) {\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n\r\n<a name=\"templating\" />\r\n## templating\r\n\r\nappex comes bundled with a built in template engine which is modelled on the Microsoft \r\nRazor templating engine. The following sections outline its use.\r\n\r\n<a name=\"template_overview\" />\r\n### overview\r\n\r\nThe appex template engine is available to all handlers by default. it is accessible\r\non the context.template property. the following is an example of its use.\r\n\r\n```\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n<ul>\r\n@for(var n in context.users) {\r\n\r\n\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t<li>@(context.users[n].name)</li>\r\n\t}\r\n}\r\n</ul>\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\t\r\n\tcontext.response.headers['Content-Type'] = 'text/html';\r\n\r\n    context.response.send(text);\r\n}\r\n\r\n```\r\n\r\n<a name=\"template_context\" />\r\n### context\r\n\r\neach template is passed a data context. this context allows the caller to \r\nsend data to the template for rendering. the context parameter is optional.\r\nthe example below is sending the users array to the template context for \r\nrendering.\r\n\r\n```\r\nexport function index(context) {\r\n\t\r\n    var users  = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    context.response.send(context.template.render('./view.txt', { users: users }));\r\n}\r\n```\r\n\r\n<a name=\"template_syntax\" />\r\n### syntax\r\n\r\nappex templates support the following statements and syntax\r\n\r\n#### if statement\r\n\r\nif statments are supported.\r\n\r\n```\r\n@if(expression) {\r\n\tsome content\r\n}\r\n\r\n@if(a > 10) {\r\n\tsome content\r\n}\r\n\r\n@(user.loggedin) {\r\n\t<span>welcome</span>\r\n}\r\n```\r\n\r\n#### for statement\r\n\r\nthe following for loops are supported.\r\n\r\n```\r\n@for(var i = i; i < 100; i++) {\r\n\t@(i)\r\n}\r\n\r\n@for(var n in list) {\r\n\t@(list[n])\r\n}\r\n```\r\n\r\n#### expressions\r\n\r\nwill emit the value contained.\r\n\r\n```\r\n@('hello world')\r\n\r\n@(123)\r\n\r\n@(some_variable)\r\n```\r\n\r\n#### code blocks\r\n\r\ncode blocks can be useful for adding template side rendering logic.\r\n\r\n```\r\n@{\r\n\tvar message = 'hello'\r\n}\r\n\r\n@(message)\r\n```\r\n\r\n#### comments\r\n```\r\n@*\r\n\tthis comment will not be rendered!\r\n*@\r\n```\r\n\r\n<a name=\"template_layouts_and_sections\" />\r\n### layouts and sections\r\n\r\nappex templates support template inheritance.\r\n\r\nconsider the following where layout.txt defines the sections 'header' and 'content' and the view.txt overrides\r\nthese sections with its own content.\r\n\r\n```\r\n//----------------------------------------------\r\n// layout.txt\r\n//----------------------------------------------\r\n\r\n<html>\r\n\r\n\t<head>\r\n\t\t\r\n\t\t@section header\r\n\r\n\t</head>\r\n\r\n\t<body>\r\n\r\n\t\t@section content {\r\n\t\t\r\n\t\t\t<span>some default content</span>\r\n\t\t\t\r\n\t\t}\r\n\r\n\t</body>\r\n\t\r\n</html>\r\n\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n@layout 'layout.txt'\r\n\r\n@section header {\r\n\r\n\t<title>my page</title>\r\n}\r\n\r\n@section content {\r\n\r\n\t<p>overriding the layout.txt content section.</p>\r\n\r\n\t<ul>\r\n\t@for(var n in context.users) {\r\n\r\n\t\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t\t<li>@(context.users[n].name)</li>\r\n\t\t}\r\n\t}\r\n\t</ul>\r\n}\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\r\n    context.response.send(text);\r\n}\r\n```\r\n\r\nnote : when specifying a layout, the view will only render content within\r\nthe layouts section placeholders. \r\n\r\n<a name=\"render\" />\r\n### render\r\n\r\nappex templates also allow for partial views with the @render statment. consider the following \r\nwhich renders the nav.txt file into the layout.txt file.\r\n\r\n```\r\n//----------------------------------------------\r\n// nav.txt\r\n//----------------------------------------------\r\n<ul>\r\n\t<li>home</li>\r\n\t<li>about</li>\r\n\t<li>contact</li>\r\n</ul>\r\n\r\n//----------------------------------------------\r\n// layout.txt\r\n//----------------------------------------------\r\n\r\n<html>\r\n\t<head>\r\n\t\t\r\n\t\t@section header\r\n\r\n\t</head>\r\n\r\n\t<body>\r\n\t\t\r\n\t\t@render 'nav.txt'\r\n\r\n\t\t@section content {\r\n\t\t\r\n\t\t\t<span>some default content</span>\r\n\t\t\t\r\n\t\t}\r\n\r\n\t</body>\r\n\t\r\n</html>\r\n\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n@layout 'layout.txt'\r\n\r\n@section header {\r\n\r\n\t<title>my page</title>\r\n}\r\n\r\n@section content {\r\n\r\n\t<p>overriding the layout.txt content section.</p>\r\n\r\n\t<ul>\r\n\t@for(var n in context.users) {\r\n\r\n\t\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t\t<li>@(context.users[n].name)</li>\r\n\t\t}\r\n\t}\r\n\t</ul>\r\n}\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\r\n    context.response.send(text);\r\n}\r\n```\r\n\r\n<a name=\"caching_and_devmode\" />\r\n### caching and devmode\r\n\r\nappex template content is not cached (the implementor is expected to handle their own caching)\r\nhowever the generated template code is. \r\n\r\nappex templates do inheriate the behaviour of the appex 'devmode' option. setting\r\ndevmode to 'true' will cause template code to be reloaded from disk and code generated with each \r\nrequest. setting devmode to false will load content from disk on first request, and \r\ncache the generated template code in memory for the lifetime of the application.\r\n\r\nin addition to this, a implementation where the devmode is false can override the caching \r\nbehaviour with the following.\r\n\r\n```typescript\r\nexport function index(context) {\r\n\r\n\t// manually override the template devmode option.\r\n\tcontext.template.option.devmode = true; \r\n\r\n\tcontext.response.send(context.template.render('./view.txt'))\r\n}\r\n```\r\n\r\n<a name=\"sitemaps\" />\r\n## sitemaps\r\n\r\nappex is able to derive sitemap metadata automatically from http endpoints created with\r\ntypescript modules and functions. This metadata is useful to generate sitemap.xml\r\nfiles, as well as helping to create site navigation links when combined a template\r\nengine.\r\n\r\n<a name=\"sitemap_generate\" />\r\n### generate sitemap\r\n\r\nappex sitemaps can be obtained from the context.sitemap property. \r\n\r\n```typescript\r\nexport function index(context) {\r\n\r\n\t// return all nodes in this site.\r\n\tcontext.response.json(context.sitemap)\r\n\r\n}\r\n```\r\n\r\nAdditionally, it may be helpful to isolate branches of the sitemap with the \r\ncontext.sitemap.get([qualifier]) function. as demonstrated below.\r\n\r\n```typescript\r\nexport module admin {\r\n\r\n\texport function index     (context) { }\r\n\r\n\texport function dashboard (context) { }\r\n\r\n\texport function content   (context) { }\r\n\r\n\texport module users {\r\n\r\n\t\texport function login(context) { }\r\n\r\n\t\texport function logout(context) { }\r\n\t}\r\n}\r\n\r\nexport function test(context) {\r\n\t\r\n\t// view all admin sitemap nodes\r\n\tcontext.response.json(context.sitemap.get('admin'))\r\n\r\n\t// view all admin.users sitemap nodes\r\n\t//context.response.json(context.sitemap.get('admin.users'))\r\n}\r\n```\r\n\r\n<a name=\"sitemap_metadata\" />\r\n### attribute metadata\r\n\r\neach sitemap node contains the attribute applied to the handler for which the node applies. With this\r\ndevelopers can apply custom metadata for a given node. as demonstrated below.\r\n\r\n```typescript\r\ndeclare var attribute;\r\n\r\nattribute({website:'http://mysite.com/'}) // global\r\n\r\nattribute('index', {title:'home page'})\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('index')\r\n}\r\n\r\nattribute('about', {title: 'about page'})\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about')\r\n}\r\n\r\nattribute('sitemap', {title: 'sitemap page'})\r\nexport function sitemap(context) {\r\n\r\n\tcontext.response.json(context.sitemap)\r\n}\r\n```\r\n\r\nvisiting /sitemap will output the following.\r\n\r\n```typescript\r\n{\r\n    \"name\": \"sitemap\",\r\n    \"nodes\": [\r\n        {\r\n            \"name\": \"index\",\r\n            \"urls\": [\r\n                \"/\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"home page\"\r\n        },\r\n        {\r\n            \"name\": \"about\",\r\n            \"urls\": [\r\n                \"/about\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"about page\"\r\n        },\r\n        {\r\n            \"name\": \"sitemap\",\r\n            \"urls\": [\r\n                \"/sitemap\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"sitemap page\"\r\n        }\r\n    ]\r\n}\r\n```\r\n\r\n<a name=\"json_schema\" />\r\n## json schema\r\n\r\nappex provides functionality for generating json schemas from TypeScript classes\r\nand interfaces as well as tools for validating json data.\r\n\r\n<a name=\"generating_schema\" />\r\n### generating schema\r\n\r\nThe following demonstrates generating json schema from the following class\r\nhierarchy.\r\n\r\n```typescript\r\nexport module model {\r\n\r\n    /** a product */\r\n    export class Product {\r\n        \r\n        /** the product name */\r\n        public name        : string;\r\n\r\n        /** the product description */\r\n        public description : string;\r\n\r\n        /** the product cost */\r\n        public cost        : number;\r\n    } \r\n\r\n    /** a order */\r\n    export class Order {\r\n        \r\n        /** the product being ordered */\r\n        public products  : Product;\r\n    }\r\n\r\n    /** a customer */\r\n    export class Customer {\r\n\r\n        /** the customers firstname */\r\n        public firstname  : string;\r\n\r\n        /** the customers lastname */\r\n        public lastname   : string;\r\n\r\n        /** orders made by this customer */\r\n        public orders     : Order[];\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.IContext) {\r\n\t\r\n\t// pass the fully qualified name of the type.\r\n    var schema = context.schema.get('model.Customer');\r\n\r\n    context.response.json(schema);\r\n}\r\n```\r\n\r\nwhich generates the following json schema.\r\n\r\n```typescript\r\n{\r\n    \"id\": \"model.Customer\",\r\n    \"type\": \"object\",\r\n    \"description\": \"a customer\",\r\n    \"properties\": {\r\n        \"firstname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers firstname\",\r\n            \"required\": true\r\n        },\r\n        \"lastname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers lastname\",\r\n            \"required\": true\r\n        },\r\n        \"orders\": {\r\n            \"type\": \"array\",\r\n            \"items\": {\r\n                \"type\": {\r\n                    \"id\": \"model.Order\",\r\n                    \"type\": \"object\",\r\n                    \"description\": \"a order\",\r\n                    \"properties\": {\r\n                        \"products\": {\r\n                            \"id\": \"model.Product\",\r\n                            \"type\": \"object\",\r\n                            \"description\": \"a product\",\r\n                            \"properties\": {\r\n                                \"name\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product name\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"description\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product description\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"cost\": {\r\n                                    \"type\": \"number\",\r\n                                    \"description\": \"the product cost\",\r\n                                    \"required\": true\r\n                                }\r\n                            },\r\n                            \"required\": true\r\n                        }\r\n                    }\r\n                }\r\n            },\r\n            \"description\": \"orders made by this customer\",\r\n            \"required\": true\r\n        }\r\n    }\r\n}\r\n```\r\na quick note...\r\n\r\nwhen generating schema from classes:\r\n\r\n* only public class variables will be emitted.\r\n* all properties will be marked as \"required\".\r\n\r\nwhen generating schema from interfaces:\r\n\r\n* all properties will be emitted. \r\n* all properties will be marked as \"required\" unless modified with '?'.\r\n\r\n<a name=\"validating_json\" />\r\n### validating json\r\n\r\nappex supports json schema validation from class and interface definitions. consider the following...\r\n\r\n```typescript\r\ninterface Customer {\r\n\r\n    firstname    : string;\r\n\r\n    lastname     : string;\r\n\r\n    age          : number;\r\n\r\n    emails       : string[];\r\n\r\n    option_a ?   : boolean; // optional\r\n\r\n    option_b ?   : boolean; // optional\r\n\r\n}\r\n\r\nexport function index(context) {\r\n\r\n    // a customer with invalid data.\r\n\r\n    var customer = {\r\n\r\n        firstname    : 'dave',\r\n\r\n        age          : '33',\r\n\r\n        emails       : [12345, 'dave@domain.com', true],\r\n\r\n        option_b     : 1,\r\n\r\n        option_c     : 1\r\n    }\r\n\r\n    // do validation.\r\n\r\n    var errors = context.schema.validate('Customer', customer);\r\n\r\n    if(errors) {\r\n\r\n        context.response.json(errors);\r\n    }\r\n}\r\n```\r\n\r\nwill output the following.\r\n\r\n```typescript\r\n[\r\n    {\r\n        \"message\": \"instance.lastname is required.\"\r\n    },\r\n    {\r\n        \"message\": \"instance.age is not a number\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[0] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[2] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_b is not a boolean\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_c unexpected property\"\r\n    }\r\n]\r\n```\r\n\r\n<a name=\"web_service_descriptions\">\r\n### web service descriptions\r\n\r\nFor those using appex for web services, developers can leverage appex json schema generation\r\nto generate endpoint metadata (think wsdl). Consider the following which leverages both appex \r\nschema generation and attributes to produce a metadata endpoint consumers of your\r\napi can use to see what data the endpoint http://example.com/customer/create accepts \r\nand returns.\r\n\r\n```typescript\r\nclass Request {\r\n\r\n    /** the customers firstname */\r\n    firstname : string;\r\n\r\n    /** the customers lastname */\r\n    lastname  : string;\r\n\r\n\t/** the customers lastname */\r\n}\r\n\r\nclass Response {\r\n\r\n    /** true on success  */\r\n    success:boolean;\r\n    \r\n    /** an array of validation errors  */\r\n    errors : string[];\r\n}\r\n\r\nattribute('metadata', {input  : 'Request', output : 'Response'})\r\nexport function metadata(context:appex.web.IContext) {\r\n\r\n    var metadata = {\r\n        \r\n\t\tendpoint : 'http://example.com/customer/create',\r\n\r\n        input    : context.schema.get(context.attribute.input),\r\n\r\n        output   : context.schema.get(context.attribute.output)\r\n    }\r\n\r\n    context.response.json(metadata)\r\n}\r\n```\r\n\r\nwhich outputs the following.\r\n\r\n```typescript\r\n{\r\n    \"endpoint\": \"http://example.com/customer/create\",\r\n    \"input\": {\r\n        \"id\": \"Request\",\r\n        \"type\": \"object\",\r\n        \"properties\": {\r\n            \"firstname\": {\r\n                \"type\": \"string\",\r\n                \"description\": \"the customers firstname\",\r\n                \"required\": true\r\n            },\r\n            \"lastname\": {\r\n                \"type\": \"string\",\r\n                \"description\": \"the customers lastname\",\r\n                \"required\": true\r\n            }\r\n        }\r\n    },\r\n    \"output\": {\r\n        \"id\": \"Response\",\r\n        \"type\": \"object\",\r\n        \"properties\": {\r\n            \"success\": {\r\n                \"type\": \"boolean\",\r\n                \"description\": \"true on success\",\r\n                \"required\": true\r\n            },\r\n            \"errors\": {\r\n                \"type\": \"array\",\r\n                \"description\": \"an array of validation errors\",\r\n                \"items\": {\r\n                    \"type\": \"string\"\r\n                },\r\n                \"required\": true\r\n            }\r\n        }\r\n    }\r\n}\r\n```\r\ntip: use the appex sitemap metadata to produce a metadata endpoint for all service methods \r\nin your application.\r\n\r\n\r\n<a name=\"reflection\" />\r\n## reflection\r\n\r\nappex provides a reflection api derived from TypeScript's type system that developers can \r\nleverage to reflect type information declared throughout their appex modules. \r\n\r\nthe following section outlines how to use the reflection api.\r\n\r\n<a name=\"reflect_everything\" />\r\n### reflect everything\r\n\r\nthe appex reflection api is passed on the context.module.reflection property and is available to all\r\nappex handler methods. The following code will JSON serialize everything declared in your appex\r\nproject and write it to the http response. \r\n\r\n```typescript\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection );\r\n}\r\n```\r\n\r\n<a name=\"reflect_specific_types\" />\r\n### reflect specific types\r\n\r\nIn typical scenarios, developers will want to leverage reflection meta data to generate\r\nservice contacts and client side models. the reflection api lets you access meta data \r\nfor the following types declared in your project. \r\n\r\n* modules\r\n* imports\r\n* classes\r\n* interfaces\r\n* functions\r\n* variables\r\n\r\nto access specific type metadata, use the reflection.get([qualifier]) method, as demonstrated below.\r\n\r\n```typescript\r\nexport module model {\r\n    \r\n    export class Customer {\r\n\r\n        public firstname   : string;\r\n\r\n        public lastname    : string;\r\n\r\n        public age         : number;\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('model.Customer') );\r\n}\r\n```\r\nand methods..\r\n\r\n```typescript\r\nfunction some_method(a:string, b:number, c?:boolean) : void { }\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_method') );\r\n}\r\n```\r\n\r\n....and variables...\r\n\r\n```typescript\r\nvar some_variable:number = 10;\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_variable') );\r\n}\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\nThis section outlines development with appex.\r\n\r\n<a name=\"appex_declaration\" />\r\n### appex.d.ts declaration\r\n\r\nIf you develop on a TypeScript complicant editor (one that supports TS 0.9), appex comes bundled\r\nwith a declaration file you can reference in your project. If installing appex via npm, your\r\nreference should be as follows.\r\n\r\n```typescript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nexport function index (context:appex.web.IContext) { \r\n    \r\n    context.response.send('hello');\r\n}\r\n\r\nexport function wildcard(context:appex.web.IContext, path:string) {\r\n\r\n    context.response.serve('./', path);\r\n}\r\n```\r\n\r\nBy referencing this in your project, you get the benefits of code completion and static type checking\r\nagainst both appex, and the nodejs core.\r\n\r\n![](https://raw.github.com/sinclairzx81/appex/master/artifacts/code-completion.jpg)\r\n\r\nAdditional declaration files may be obtained from [here](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```typescript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex ({ program : './index.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"users.ts\" />\r\n/// <reference path=\"pages.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { context.response.send('users.login') }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { context.response.send('users.logout') }\r\n}\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { context.response.send('home') }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { context.response.send('about') }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { context.response.send('contact') }\r\n\r\nexport function wildcard (context, path) { context.response.send(404, ' not found') }\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"license\" />\r\n## license\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) 2013 Haydn Paterson (sinclair) <haydn.developer@gmail.com>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in\r\nall copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\nTHE SOFTWARE.\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"https://raw.github.com/sinclairzx81/appex/master/license.txt","type":"The MIT License (MIT)"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.3.8","description":"develop nodejs web applications with typescript","directories":{},"dependencies":{"typescript.api":"0.7.7"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"},"0.6.9":{"name":"appex","version":"0.6.9","keywords":["typescript","web api","reflection","compiler","schema","templates","sitemap"],"author":{"name":"sinclair"},"_id":"appex@0.6.9","maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"dist":{"shasum":"ddae4f93ba1aaf6433dfd77dfbb3515fee81268c","tarball":"https://registry.npmjs.org/appex/-/appex-0.6.9.tgz","integrity":"sha512-2d5olkyezK8cF5R0LzhX1t2DmdTJWH5PxAYDJy3QHcUuCJW8Andh3eiRJVIZDuRrLt3o1f5FmQGkHW7T9/CC1w==","signatures":[{"sig":"MEUCIQCCz+Zu8KKqupn2XIe/GOz4iLNj09TZvgT2J2cABzNcWgIgfFqE1fHDrB3VvTWVmRji/uCKm0C0s1nNbTwCpTb4Bl8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","readme":"![](https://raw.github.com/sinclairzx81/appex/master/artifacts/logo.jpg)\r\n\r\n### develop nodejs web applications with [typescript](http://www.typescriptlang.org/)\r\n\r\n\r\n```typescript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nexport function index(context:appex.web.IContext) {\r\n\t\r\n\tcontext.response.send('home page');\r\n}\r\n\r\nexport function about(context:appex.web.IContext) {\r\n\t\r\n\tcontext.response.send('about page');\r\n}\r\n\r\nexport function wildcard (context:appex.web.IContext, path:string) {\r\n    \r\n    context.response.send(404, path + \" not found\");\r\n}\r\n\r\n```\r\n### install\r\n\r\n```\r\nnpm install appex\r\n```\r\n### contents\r\n\r\n* [getting started](#getting_started)\r\n\t* [create a application](#application)\r\n\t* [start up options](#options)\r\n\t* [running on an existing http server](#http_server)\r\n\t* [running as express middleware](#express_middleware)\r\n* [http handlers](#http_handlers)\r\n\t* [context](#context)\r\n\t* [request](#request)\r\n\t* [response](#response)\r\n\t* [routing](#routing)\r\n\t* [signatures](#signatures)\r\n\t* [named handlers](#named_handlers)\r\n\t* [index handlers](#index_handlers)\r\n\t* [wildcard handlers](#wildcard_handlers)\r\n\t* [attributes](#attributes)\r\n\t* [verbs](#verbs)\r\n\t* [url rewrite](#url_rewrite)\r\n\t* [middleware](#middleware)\r\n\t* [exporting functions](#exporting_functions)\r\n\t* [handling 404](#handling_404)\r\n\t* [serving static files](#serving_static_files)\r\n* [templating](#templating)\r\n\t* [overview](#template_overview)\r\n\t* [context](#template_context)\t\r\n\t* [syntax](#template_syntax)\r\n\t* [layouts and sections](#template_layouts_and_sections)\r\n\t* [render](#template_render)\r\n\t* [caching and devmode](#caching_and_devmode)\r\n* [sitemaps](#sitemaps)\r\n\t* [generating](#sitemap_generate)\r\n\t* [metadata](#sitemap_metadata)\r\n* [json schema](#json_schema)\r\n\t* [generating schema](#generating_schema)\r\n\t* [validating json](#validating_json)\r\n\t* [web service descriptions](#web_service_descriptions)\r\n* [reflection](#reflection)\r\n\t* [reflect everything](#reflect_everything)\r\n\t* [reflect specific types](#reflect_specific_types)\r\n* [developing with appex](#developing_with_appex)\r\n\t* [appex.d.ts declaration](#appex_declaration)\r\n\t* [structuring projects](#structuring_projects)\r\n* [additional resources](#resources)\r\n* [license](#license)\r\n\r\n<a name=\"getting_started\" />\r\n## getting started\r\n\r\nThe following sections outline creating appex applications and configuration.\r\n\r\n<a name=\"application\" />\r\n### create a application\r\n\r\nThe following code will create a standalone appex application and \r\nhttp server and listen on port 3000.\r\n\r\n```typescript\r\nvar appex   = require('appex');\r\n\r\nvar app   = appex({ program : './program.ts', \r\n                    devmode : true,\r\n                    logging : true });\r\n\r\napp.listen(3000);\r\n```\r\n\r\nnote: devmode and logging are optional. however, when developing \r\nwith appex, it is helpful to have these enabled.\r\n\r\n<a name=\"options\" />\r\n### start up options\r\n\r\nappex accepts the following start up options.\r\n\r\n```typescript\r\nvar options = {\r\n\r\n\t// (required) location of source file.\r\n\tprogram    : './program.ts', \r\n\r\n\t// (optional) recompile on request. (default:false) \r\n\tdevmode    : true,          \r\n\r\n\t// (optional) log to stdout. (default:false) \r\n\tlogging    : true,\r\n\r\n\t// (optional) user defined objects added to the app context.\r\n\tcontext    : {}\r\n};\r\n\r\nvar app = appex( options );\r\n```\r\n\r\n<a name=\"http_server\" />\r\n### running on an existing http server\r\n\r\nThe following demonstrates setting up appex on an existing nodejs http server. In \r\nthis example, appex will attempt to handle incoming requests, and if appex cannot\r\nroute the request, will fire the callback.\r\n\r\n```typescript\r\nvar http  = require('http');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex({ program : './program.ts' });\r\n\r\nvar server = http.createServer(function(req, res){\r\n\r\n    app(req, res, function() { // appex handler...\r\n\t\t\r\n\t\t// not handled.\r\n\r\n\t}); \r\n});\r\n\r\nserver.listen(3000);\r\n```\r\n\r\n<a name=\"express_middleware\" />\r\n### running as express middleware\r\n\r\nappex allows developers to augment existing express / connect applications by \r\nway of middleware. The following demonstrates setting up appex as express middleware.\r\n\r\n```typescript\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) ); \r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nLike in the \"running on an existing http server\" example above, appex will attempt to intercept incoming requests. \r\nif appex cannot find a matching route for the request, it will automatically call the \"next\" function to pass the request \r\non to the next middleware or express handler.\r\n\r\nin addition to this, appex may also act as traditional express middleware. In the example below, a appex wildcard\r\nfunction is created which will match \"all\" incoming requests, the wildcard function simply prints hello world to \r\nthe console and then calls context.next(), which passes the request on the express handler.\r\n\r\n```typescript\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tconsole.log('hello world!!');\r\n\r\n\tcontext.next(); // pass it on!\r\n}\r\n\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar express = require('express');\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = express();\r\n\r\napp.use( appex({ program : './program.ts' }) );\r\n\r\napp.get('/', function(req, res) {\r\n\r\n  res.send('Hello World');\r\n  \r\n});\r\n\r\napp.listen(3000);\r\n```\r\n\r\nJust like traditional express middleware, appex will also inheriate the characteristics of the request.\r\n\r\nconsider the following example in which the jade view engine is configured for use. appex will inheritate the \r\nresponse.render() method, which is passed to the appex handler as context.response.render()\r\n\r\n```typescript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\napp.configure(function(){\r\n\r\n  app.set('views', __dirname + '/views');\r\n  \r\n  // set up the jade engine.\r\n  app.set('view engine', 'jade'); \r\n  \r\n  // bind appex\r\n  app.use( appex({program:'./program.ts', devmode:true} ));  \r\n});\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\n// http:[host]:[port]/\r\nexport function index(context) {\r\n\t\r\n\t// jade renderer works!\r\n\tcontext.response.render('index', { title: 'Express' }); \r\n}\r\n```\r\n\r\n<a name=\"http_handlers\" />\r\n## http handlers\r\n\r\nThe following sections describe how to create http accessible handlers with appex.\r\n\r\n<a name=\"context\" />\r\n### context\r\n\r\nAll appex functions are passed a application context object as their first argument. The app context object \r\nencapulates the http request and response objects issued by the underlying http server, as well as\r\nadditional objects specific to appex. These are listed below:\r\n\r\n```typescript\r\n// the app context\r\nexport function method(context) {\r\n\t\r\n\t// context.request    - the http request object.\r\n\r\n\t// context.response   - the http response object.\r\n\r\n\t// context.attribute    - appex attribute.\r\n\r\n\t// context.next       - the next function (express middleware)\r\n\t\r\n\t// context.router     - the appex router\r\n\r\n\t// context.sitemap    - the appex sitemap api\r\n\r\n\t// context.template   - the appex template engine.\r\n\t\r\n\t// context.module     - the module being run (this module)\r\n\r\n\t// context.schema     - json schema api.\r\n\r\n\t// context.mime       - a http mime type utility.\r\n}\r\n```\r\n\r\nit is possible to extend the default objects passed on the context by adding them on the appex startup options. The \r\nfollowing will attach the async module to the context. \r\n\r\n```typescript\r\n//----------------------------------------------\r\n// app.js\r\n//----------------------------------------------\r\n\r\nvar appex   = require('appex');\r\n\r\nvar app = appex({ program : './program.ts', \r\n\t\t\t\t  devmode : true, \r\n\t\t\t      context: {\r\n\t\t\t\t\t\tasync : require('async')\r\n\t\t\t\t  }});\r\n\r\napp.listen(3000);\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\r\n\t// context.async = passed on the context.\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n```\r\n<a name=\"request\" />\r\n### request\r\n\r\nThe appex request is a nodejs http request issued by the underlying node http server. \r\nappex extends the request with convenience methods for reading http request data. These\r\nare outlined below.\r\n\r\nreading a posted string. \r\n```typescript\r\n//----------------------------------------------\r\n// receive request as a string\r\n//----------------------------------------------\r\nexport function submit(context) {\r\n\r\n\tcontext.request.body.recv((str) => {\r\n\r\n\t\t// do something with str\r\n\t})\r\n}\r\n```\r\nreading posted form data as json object.\r\n```typescript\r\n//----------------------------------------------\r\n// receive a form post\r\n//----------------------------------------------\r\nexport function submit(context) {\r\n\r\n\tcontext.request.body.form((obj) => {\r\n\r\n\t\t// do something with obj\r\n\t})\r\n}\r\n```\r\nreading posted json data as a json object.\r\n```typescript\r\n//----------------------------------------------\r\n// receive a json post\r\n//----------------------------------------------\r\nexport function submit(context) {\r\n\r\n\tcontext.request.body.json((obj) => {\r\n\t\t\r\n\t\t// do something with obj\r\n\t})\r\n}\r\n```\r\n\r\nnote: if appex detects that express or connect middleware has already been applied\r\nto the request object, appex will use those instead.\r\n\r\n<a name=\"response\" />\r\n### response\r\n\r\nThe appex response is a nodejs http response issued by the underlying node http server. \r\nappex provides some utility methods for writing http responses. These are outlined below.\r\n\r\n```js\r\n//----------------------------------------------\r\n// the nodejs response has been extended with the following\r\n// signatures.\r\n//----------------------------------------------\r\nexport interface IResponse extends http.ServerResponse {\r\n\t\r\n\tsend (data     : string): void;\r\n\r\n\tsend (data     : NodeBuffer): void;\r\n\r\n\tsend (status   : number, data : string): void;\r\n\r\n\tserve (filepath: string): void;\r\n\r\n\tserve (root : string, filepath: string): void;\r\n\r\n\tserve (root : string, filepath: string, mime:string): void;\r\n\r\n\tjson (obj      : any): void;\r\n\r\n\tjson (status   : number, obj : any): void;\r\n\r\n\tjsonp (obj     : any): void;\r\n\r\n\tjsonp (status  : number, obj : any): void;\r\n\r\n\tjsonp (status  : number, obj : any, callback: string): void;\r\n}\r\n```\r\n\r\nnote: if appex detects that express or connect middleware has already been applied\r\nto for any of the following response methods, appex will use those instead.\r\n\r\n<a name=\"routing\" />\r\n### routing\r\n\r\nappex creates routes based on module scope and function name. consider the following:\r\n\r\n```typescript\r\nexport module services.customers {\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/insert\r\n\texport function insert(context) {\r\n\r\n\t\tcontext.response.send('services.customers.insert')\r\n    }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/update\r\n\texport function update(context) { \r\n\t\t\r\n\t\tcontext.response.send('services.customers.update')\r\n    }\r\n\t\r\n\t// url: http://[host]:[port]/services/customers/delete\r\n\texport function delete(context) { \r\n\r\n\t\tcontext.response.send('services.customers.delete')\r\n\t}\r\n}\r\n\r\n// url: http://[host]:[port]/\r\nexport function index   (context) { \r\n\r\n\tcontext.response.send('home page')\r\n}\r\n\r\n// url: http://[host]:[port]/about\r\nexport function about   (context) { \r\n\r\n\tcontext.response.send('about page')\r\n}\r\n\r\n// url: http://[host]:[port]/contact\r\nexport function contact (context) { \r\n\r\n\tcontext.response.send('contact page')\r\n}\r\n\r\n// url: http://[host]:[port]/(.*)\r\nexport function wildcard (context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found')\r\n}\r\n\r\n```\r\n\r\n<a name=\"signatures\" />\r\n### signatures\r\n\r\nappex supports three function signatures for http routing (named, index and wildcard). Functions that\r\ndo not apply these signatures will not be routed.\r\n\r\n<a name=\"named_handlers\" />\r\n### named handlers\r\n\r\nNamed handlers resolve urls to their current module scope + the name of the function.\r\n\r\nNamed handlers require the following signature:\r\n\r\n* name        - 'anything'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```typescript\r\n\r\n// http://[host]:[port]/about\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about page');\r\n}\r\n\r\n// http://[host]:[port]/users/login\r\nexport module users {\r\n\r\n\texport function login(context) {\r\n\t\t\r\n\t\tcontext.response.send('handle login');\t\r\n\t}\r\n}\r\n\r\n```\r\n\r\n<a name=\"index_handlers\" />\r\n### index handlers\r\n\r\nIndex handlers resolve urls to their current module scope.\r\n\r\nIndex handlers require the following signature:\r\n\r\n* name        - 'index'\r\n* argument[0] - app context\r\n* returns     - void (optional)\r\n\r\n```typescript\r\n// url: http://[host]:[port]/\r\nexport function index(context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\nexport module blogs {\r\n\t\r\n\t// url: http://[host]:[port]/blogs\r\n\texport function index  (context) \r\n\t{\t\r\n\t\tcontext.response.send('blog index');\r\n\t}\r\n}\r\n```\r\n\r\n<a name=\"wildcard_handlers\" />\r\n### wildcard handlers\r\n\r\nWildcard handlers resolve their urls to their current module scope + url.\r\n\r\nappex wildcard handlers allow for wildcard routing at a given module scope. Wildcard handlers\r\nsupport 'typed' url argument mapping, as denoted by the arguments annotation.\r\n\r\nIn addition, wildcard handlers also support optional arguments which can be specified with TypeScript's '?' \r\non argument names.\r\n\r\nappex wildcard handlers require the following signature:\r\n\r\n* name        - 'wildcard'\r\n* argument[0] - app context\r\n* argument[n] - 1 or more arguments to be mapped from the url\r\n* returns     - void (optional)\r\n\r\n```typescript\r\ndeclare var console;\r\n\r\nexport module blogs {\r\n\t\r\n\t// url : http://[host]:[port]/blogs/2013/1/11   - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/11  - matched\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01/3rd - not matched - (see number annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013/01     - matched     - (see ? annotation)\r\n\r\n\t// url : http://[host]:[port]/blogs/2013        - not matched - (month is required)\r\n\t\r\n    export function wildcard(context, year:number, month:number, day?:number) {\r\n\r\n        context.response.json({ year: year, month: month, day: day})\r\n    }\r\n}\r\n\r\n// url : http://[host]:[port]/\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('home');\r\n}\r\n\r\n// url : http://[host]:[port]/(.*) \r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, 'not found');\r\n}\r\n\r\n```\r\nnote: appex supports boolean, number, string and any annotations on wildcard arguments. if no annotation\r\nis specified, appex interprets the argument as a string. the type 'any' is also interpreted as string.\r\n\r\nnote: wildcard functions should be declared last in any module scope. this ensures other routes\r\nwill be matched first.\r\n\r\n<a name=\"attributes\" />\r\n### attributes\r\n\r\nappex supports a attribute scheme which developers can use to decorate modules and functions with \r\ndeclaritive metadata. appex attributes can set by calling the attribute('qualifier', data)\r\nfunction which is passed to the appex module on the global scope.\r\n\r\nunlike traditional attributes (in languages like C sharp) appex attributes have a cascading behaviour\r\nwhich allows developers to apply metadata at a lexical scope, and have it cascade through to descendant scopes.\r\n\r\nThe following outlines this behavour.\r\n\r\n```typescript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nattribute({a: 10}); // global.\r\n\r\nattribute('foo', {b : 20})\r\nexport module foo {\r\n\r\n    attribute('foo.bar', {c : 30})\r\n    export module bar {\r\n            \r\n        attribute('foo.bar.index', {d : 40})\r\n        export function index(context) {\r\n        \r\n            //context.attribute\r\n            //{\r\n            //    \"a\": 10,\r\n            //    \"b\": 20,\r\n            //    \"c\": 30,\r\n\t\t\t//    \"d\": 40\r\n            //}\r\n\r\n            context.response.json( context.attribute );       \r\n        }\r\n    }\r\n}\r\n\r\n```\r\n\r\nin addition, appex recognizes three types of attributes. developers can use these to override the default \r\nbahavour of the appex router and apply url rewriting (urls), verb matching (verbs) and middleware (use),\r\nas demonstrated below.\r\n\r\n```typescript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nfunction logger(context) {\r\n\tconsole.log('logging')\r\n\tcontext.next()\r\n}\r\n\r\n// invoke 'logger' middleware.\r\nattribute('index', {use   : [logger]})   \r\n\r\n// override the default route.\r\nattribute('index', {urls  : ['/', '/home']})  \r\n\r\n// only accept GET requests.\r\nattribute('index', {verbs : ['GET']})    \r\n\r\nexport function index(context:appex.web.IContext) {\r\n\t\r\n\tcontext.response.send('home page')\r\n}\r\n```\r\n\r\n<a name=\"verbs\" />\r\n### verbs\r\n\r\nappex handles http verb matching with attributes. appex will recognise the \r\n'verbs' property applied to the attribute to match against http verbs.\r\n\r\n```typescript\r\nattribute('index', { verbs: ['GET'] })\r\nexport function index (context) { \r\n        \r\n    // only allow HTTP GET requests\r\n    context.response.send('index')\r\n}\r\n\r\nattribute('submit', { verbs: ['POST', 'PUT'] })\r\nexport function submit (context) { \r\n    \r\n    // only allow HTTP POST and PUT requests\r\n    context.response.send('submit')\r\n}\r\n```\r\n\r\n<a name=\"url_rewrite\" />\r\n### url rewrite\r\n\r\ndevelopers can rewrite the default route given to exported functions with the 'urls' property applied\r\nto the attribute. \r\n\r\n```typescript\r\nattribute('index', { urls: ['/', '/home', 'home.html'] })\r\nexport function index (context) { \r\n    \r\n    context.response.send('index')\r\n}\r\n```\r\nnote: url rewriting is only available on index and named routes.\r\n\r\nnote: rewriting with regular expressions is currently not supported.\r\n\r\n<a name=\"middleware\" />\r\n### middleware\r\n\r\nappex supports middleware with attributes. appex middleware defined with attributes allows\r\ndevelopers to scope middleware on single functions, or entire module scopes. appex will \r\nrecognise the 'use' property applied to the attribute to invoke middleware.\r\n\r\nthe following demonstrates how one might use middleware to secure a site admin.\r\n\r\nnote: middleware 'must' call next or handle the request. \r\n\r\n```typescript\r\ndeclare function attribute (qualifier:string, obj:any);\r\n\r\ndeclare var console;\r\n\r\nfunction authenticate(context) {\r\n\r\n    console.log('authenticate')\r\n\r\n\t// call next() if authenticated, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\nfunction authorize(context) {\r\n\r\n    console.log('authorize')\r\n\r\n\t// call next() if authorized, otherwise, handle the response.\r\n    context.next(); \r\n}\r\n\r\n// apply security middleware to admin scope.\r\nattribute('admin', {use: [authenticate, authorize]}) \r\nexport module admin {\r\n\r\n    export function index(context) {\r\n        \r\n        console.log(context.attribute); // view attribute\r\n\r\n        context.response.send('access granted!')\r\n    }\r\n}\r\n\r\n// index handler has no middleware applied.\r\nexport function index (context) { \r\n    \r\n    console.log(context.attribute); // view attribute\r\n\r\n    context.response.send('home')\r\n}\r\n```\r\n\r\n\r\n<a name=\"exporting_functions\" />\r\n### exporting functions\r\n\r\nappex will only route functions prefixed with the TypeScript 'export' declarer. This rule\r\nalso applied to modules. Developers can use this to infer notions of public and private \r\nat the http level.\r\n\r\nconsider the following example:\r\n\r\n```typescript\r\n\r\n// module is not exported, and is \r\n// therefore private.\r\nmodule private_module {\r\n\t\r\n\t// function is exported, yet private \r\n\t// as a http endpoint due to the \r\n\t// parent module being private.\r\n\texport function public_method () { }\r\n\t\r\n\t// function is not exported, and is \r\n\t// private to this module.\r\n\tfunction private_method() { }\r\n}\r\n\r\n// function is not exported, and \r\n// is therefore private.\r\nfunction private_function() { }\r\n\r\n// function is exported, and therefore \r\n// publically accessible.\r\nexport function public_function   (context) { \r\n\t\r\n\t// this function can invoke \r\n\t// private functions.\r\n\tprivate_function(); // ok\r\n\t\r\n\t// calling exported method in \r\n\t// private module\r\n\tprivate_module.public_method(); // ok\r\n\r\n\t// calling non exported method \r\n\t// in private module\r\n\t// private_module.private_method(); // bad\r\n\r\n\tcontext.response.send('public_function');\r\n}\r\n```\r\n\r\n<a name='handling_404' />\r\n### handling 404\r\n\r\nUse wildcard functions to catch unhandled routes.\r\n\r\n```typescript\r\n// http:[host]:[port]/\r\nexport function index (context) { \r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard (context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n<a name=\"serving_static_files\" />\r\n## serving static files\r\n\r\nUse wildcard functions with context.response.serve() to serve static content.\r\n\r\n```typescript\r\nexport module static {\r\n\t\r\n\t// http:[host]:[port]/static/(.*)\r\n\texport function wildcard(context, path) {\r\n\r\n\t\tcontext.response.serve('./static/', path);\r\n\t}\r\n}\r\n\r\n// http:[host]:[port]/\r\nexport function index (context) {\r\n\r\n\tcontext.response.send('home page');\r\n}\r\n\r\n// http:[host]:[port]/(.*)\r\nexport function wildcard(context, path) {\r\n\r\n\tcontext.response.send(404, path + ' not found');\r\n}\r\n```\r\n\r\n<a name=\"templating\" />\r\n## templating\r\n\r\nappex comes bundled with a built in template engine which is modelled on the Microsoft \r\nRazor templating engine. The following sections outline its use.\r\n\r\n<a name=\"template_overview\" />\r\n### overview\r\n\r\nThe appex template engine is available to all handlers by default. it is accessible\r\non the context.template property. the following is an example of its use.\r\n\r\n```\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n<ul>\r\n@for(var n in context.users) {\r\n\r\n\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t<li>@(context.users[n].name)</li>\r\n\t}\r\n}\r\n</ul>\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\t\r\n\tcontext.response.headers['Content-Type'] = 'text/html';\r\n\r\n    context.response.send(text);\r\n}\r\n\r\n```\r\n\r\n<a name=\"template_context\" />\r\n### context\r\n\r\neach template is passed a data context. this context allows the caller to \r\nsend data to the template for rendering. the context parameter is optional.\r\nthe example below is sending the users array to the template context for \r\nrendering.\r\n\r\n```\r\nexport function index(context) {\r\n\t\r\n    var users  = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    context.response.send(context.template.render('./view.txt', { users: users }));\r\n}\r\n```\r\n\r\n<a name=\"template_syntax\" />\r\n### syntax\r\n\r\nappex templates support the following statements and syntax\r\n\r\n#### if statement\r\n\r\nif statments are supported.\r\n\r\n```\r\n@if(expression) {\r\n\tsome content\r\n}\r\n\r\n@if(a > 10) {\r\n\tsome content\r\n}\r\n\r\n@(user.loggedin) {\r\n\t<span>welcome</span>\r\n}\r\n```\r\n\r\n#### for statement\r\n\r\nthe following for loops are supported.\r\n\r\n```\r\n@for(var i = i; i < 100; i++) {\r\n\t@(i)\r\n}\r\n\r\n@for(var n in list) {\r\n\t@(list[n])\r\n}\r\n```\r\n\r\n#### expressions\r\n\r\nwill emit the value contained.\r\n\r\n```\r\n@('hello world')\r\n\r\n@(123)\r\n\r\n@(some_variable)\r\n```\r\n\r\n#### code blocks\r\n\r\ncode blocks can be useful for adding template side rendering logic.\r\n\r\n```\r\n@{\r\n\tvar message = 'hello'\r\n}\r\n\r\n@(message)\r\n```\r\n\r\n#### comments\r\n```\r\n@*\r\n\tthis comment will not be rendered!\r\n*@\r\n```\r\n\r\n<a name=\"template_layouts_and_sections\" />\r\n### layouts and sections\r\n\r\nappex templates support template inheritance.\r\n\r\nconsider the following where layout.txt defines the sections 'header' and 'content' and the view.txt overrides\r\nthese sections with its own content.\r\n\r\n```\r\n//----------------------------------------------\r\n// layout.txt\r\n//----------------------------------------------\r\n\r\n<html>\r\n\r\n\t<head>\r\n\t\t\r\n\t\t@section header\r\n\r\n\t</head>\r\n\r\n\t<body>\r\n\r\n\t\t@section content {\r\n\t\t\r\n\t\t\t<span>some default content</span>\r\n\t\t\t\r\n\t\t}\r\n\r\n\t</body>\r\n\t\r\n</html>\r\n\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n@layout 'layout.txt'\r\n\r\n@section header {\r\n\r\n\t<title>my page</title>\r\n}\r\n\r\n@section content {\r\n\r\n\t<p>overriding the layout.txt content section.</p>\r\n\r\n\t<ul>\r\n\t@for(var n in context.users) {\r\n\r\n\t\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t\t<li>@(context.users[n].name)</li>\r\n\t\t}\r\n\t}\r\n\t</ul>\r\n}\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\r\n    context.response.send(text);\r\n}\r\n```\r\n\r\nnote : when specifying a layout, the view will only render content within\r\nthe layouts section placeholders. \r\n\r\n<a name=\"render\" />\r\n### render\r\n\r\nappex templates also allow for partial views with the @render statment. consider the following \r\nwhich renders the nav.txt file into the layout.txt file.\r\n\r\n```\r\n//----------------------------------------------\r\n// nav.txt\r\n//----------------------------------------------\r\n<ul>\r\n\t<li>home</li>\r\n\t<li>about</li>\r\n\t<li>contact</li>\r\n</ul>\r\n\r\n//----------------------------------------------\r\n// layout.txt\r\n//----------------------------------------------\r\n\r\n<html>\r\n\t<head>\r\n\t\t\r\n\t\t@section header\r\n\r\n\t</head>\r\n\r\n\t<body>\r\n\t\t\r\n\t\t@render 'nav.txt'\r\n\r\n\t\t@section content {\r\n\t\t\r\n\t\t\t<span>some default content</span>\r\n\t\t\t\r\n\t\t}\r\n\r\n\t</body>\r\n\t\r\n</html>\r\n\r\n//----------------------------------------------\r\n// view.txt\r\n//----------------------------------------------\r\n\r\n@layout 'layout.txt'\r\n\r\n@section header {\r\n\r\n\t<title>my page</title>\r\n}\r\n\r\n@section content {\r\n\r\n\t<p>overriding the layout.txt content section.</p>\r\n\r\n\t<ul>\r\n\t@for(var n in context.users) {\r\n\r\n\t\t@if(context.users[n].online) {\r\n\t\t\t\r\n\t\t\t<li>@(context.users[n].name)</li>\r\n\t\t}\r\n\t}\r\n\t</ul>\r\n}\r\n\r\n//----------------------------------------------\r\n// program.ts\r\n//----------------------------------------------\r\n\r\nexport function index(context) {\r\n\t\r\n    var users = [{name:'dave' , online : true}, \r\n                 {name:'smith', online : true}, \r\n                 {name:'jones', online : false}, \r\n                 {name:'alice', online : true}];\r\n\r\n    var text = context.template.render('./view.txt', { users: users });\r\n\r\n    context.response.send(text);\r\n}\r\n```\r\n\r\n<a name=\"caching_and_devmode\" />\r\n### caching and devmode\r\n\r\nappex template content is not cached (the implementor is expected to handle their own caching)\r\nhowever the generated template code is. \r\n\r\nappex templates do inheriate the behaviour of the appex 'devmode' option. setting\r\ndevmode to 'true' will cause template code to be reloaded from disk and code generated with each \r\nrequest. setting devmode to false will load content from disk on first request, and \r\ncache the generated template code in memory for the lifetime of the application.\r\n\r\nin addition to this, a implementation where the devmode is false can override the caching \r\nbehaviour with the following.\r\n\r\n```typescript\r\nexport function index(context) {\r\n\r\n\t// manually override the template devmode option.\r\n\tcontext.template.option.devmode = true; \r\n\r\n\tcontext.response.send(context.template.render('./view.txt'))\r\n}\r\n```\r\n\r\n<a name=\"sitemaps\" />\r\n## sitemaps\r\n\r\nappex is able to derive sitemap metadata automatically from http endpoints created with\r\ntypescript modules and functions. This metadata is useful to generate sitemap.xml\r\nfiles, as well as helping to create site navigation links when combined a template\r\nengine.\r\n\r\n<a name=\"sitemap_generate\" />\r\n### generate sitemap\r\n\r\nappex sitemaps can be obtained from the context.sitemap property. \r\n\r\n```typescript\r\nexport function index(context) {\r\n\r\n\t// return all nodes in this site.\r\n\tcontext.response.json(context.sitemap)\r\n\r\n}\r\n```\r\n\r\nAdditionally, it may be helpful to isolate branches of the sitemap with the \r\ncontext.sitemap.get([qualifier]) function. as demonstrated below.\r\n\r\n```typescript\r\nexport module admin {\r\n\r\n\texport function index     (context) { }\r\n\r\n\texport function dashboard (context) { }\r\n\r\n\texport function content   (context) { }\r\n\r\n\texport module users {\r\n\r\n\t\texport function login(context) { }\r\n\r\n\t\texport function logout(context) { }\r\n\t}\r\n}\r\n\r\nexport function test(context) {\r\n\t\r\n\t// view all admin sitemap nodes\r\n\tcontext.response.json(context.sitemap.get('admin'))\r\n\r\n\t// view all admin.users sitemap nodes\r\n\t//context.response.json(context.sitemap.get('admin.users'))\r\n}\r\n```\r\n\r\n<a name=\"sitemap_metadata\" />\r\n### attribute metadata\r\n\r\neach sitemap node contains the attribute applied to the handler for which the node applies. With this\r\ndevelopers can apply custom metadata for a given node. as demonstrated below.\r\n\r\n```typescript\r\ndeclare var attribute;\r\n\r\nattribute({website:'http://mysite.com/'}) // global\r\n\r\nattribute('index', {title:'home page'})\r\nexport function index(context) {\r\n\r\n\tcontext.response.send('index')\r\n}\r\n\r\nattribute('about', {title: 'about page'})\r\nexport function about(context) {\r\n\r\n\tcontext.response.send('about')\r\n}\r\n\r\nattribute('sitemap', {title: 'sitemap page'})\r\nexport function sitemap(context) {\r\n\r\n\tcontext.response.json(context.sitemap)\r\n}\r\n```\r\n\r\nvisiting /sitemap will output the following.\r\n\r\n```typescript\r\n{\r\n    \"name\": \"sitemap\",\r\n    \"nodes\": [\r\n        {\r\n            \"name\": \"index\",\r\n            \"urls\": [\r\n                \"/\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"home page\"\r\n        },\r\n        {\r\n            \"name\": \"about\",\r\n            \"urls\": [\r\n                \"/about\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"about page\"\r\n        },\r\n        {\r\n            \"name\": \"sitemap\",\r\n            \"urls\": [\r\n                \"/sitemap\"\r\n            ],\r\n            \"website\": \"http://mysite.com/\",\r\n            \"title\": \"sitemap page\"\r\n        }\r\n    ]\r\n}\r\n```\r\n\r\n<a name=\"json_schema\" />\r\n## json schema\r\n\r\nappex provides functionality for generating json schemas from TypeScript classes\r\nand interfaces as well as tools for validating json data.\r\n\r\n<a name=\"generating_schema\" />\r\n### generating schema\r\n\r\nThe following demonstrates generating json schema from the following class\r\nhierarchy.\r\n\r\n```typescript\r\nexport module model {\r\n\r\n    /** a product */\r\n    export class Product {\r\n        \r\n        /** the product name */\r\n        public name        : string;\r\n\r\n        /** the product description */\r\n        public description : string;\r\n\r\n        /** the product cost */\r\n        public cost        : number;\r\n    } \r\n\r\n    /** a order */\r\n    export class Order {\r\n        \r\n        /** the product being ordered */\r\n        public products  : Product;\r\n    }\r\n\r\n    /** a customer */\r\n    export class Customer {\r\n\r\n        /** the customers firstname */\r\n        public firstname  : string;\r\n\r\n        /** the customers lastname */\r\n        public lastname   : string;\r\n\r\n        /** orders made by this customer */\r\n        public orders     : Order[];\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.IContext) {\r\n\t\r\n\t// pass the fully qualified name of the type.\r\n    var schema = context.schema.get('model.Customer');\r\n\r\n    context.response.json(schema);\r\n}\r\n```\r\n\r\nwhich generates the following json schema.\r\n\r\n```typescript\r\n{\r\n    \"id\": \"model.Customer\",\r\n    \"type\": \"object\",\r\n    \"description\": \"a customer\",\r\n    \"properties\": {\r\n        \"firstname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers firstname\",\r\n            \"required\": true\r\n        },\r\n        \"lastname\": {\r\n            \"type\": \"string\",\r\n            \"description\": \"the customers lastname\",\r\n            \"required\": true\r\n        },\r\n        \"orders\": {\r\n            \"type\": \"array\",\r\n            \"items\": {\r\n                \"type\": {\r\n                    \"id\": \"model.Order\",\r\n                    \"type\": \"object\",\r\n                    \"description\": \"a order\",\r\n                    \"properties\": {\r\n                        \"products\": {\r\n                            \"id\": \"model.Product\",\r\n                            \"type\": \"object\",\r\n                            \"description\": \"a product\",\r\n                            \"properties\": {\r\n                                \"name\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product name\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"description\": {\r\n                                    \"type\": \"string\",\r\n                                    \"description\": \"the product description\",\r\n                                    \"required\": true\r\n                                },\r\n                                \"cost\": {\r\n                                    \"type\": \"number\",\r\n                                    \"description\": \"the product cost\",\r\n                                    \"required\": true\r\n                                }\r\n                            },\r\n                            \"required\": true\r\n                        }\r\n                    }\r\n                }\r\n            },\r\n            \"description\": \"orders made by this customer\",\r\n            \"required\": true\r\n        }\r\n    }\r\n}\r\n```\r\na quick note...\r\n\r\nwhen generating schema from classes:\r\n\r\n* only public class variables will be emitted.\r\n* all properties will be marked as \"required\".\r\n\r\nwhen generating schema from interfaces:\r\n\r\n* all properties will be emitted. \r\n* all properties will be marked as \"required\" unless modified with '?'.\r\n\r\n<a name=\"validating_json\" />\r\n### validating json\r\n\r\nappex supports json schema validation from class and interface definitions. consider the following...\r\n\r\n```typescript\r\ninterface Customer {\r\n\r\n    firstname    : string;\r\n\r\n    lastname     : string;\r\n\r\n    age          : number;\r\n\r\n    emails       : string[];\r\n\r\n    option_a ?   : boolean; // optional\r\n\r\n    option_b ?   : boolean; // optional\r\n\r\n}\r\n\r\nexport function index(context) {\r\n\r\n    // a customer with invalid data.\r\n\r\n    var customer = {\r\n\r\n        firstname    : 'dave',\r\n\r\n        age          : '33',\r\n\r\n        emails       : [12345, 'dave@domain.com', true],\r\n\r\n        option_b     : 1,\r\n\r\n        option_c     : 1\r\n    }\r\n\r\n    // do validation.\r\n\r\n    var errors = context.schema.validate('Customer', customer);\r\n\r\n    if(errors) {\r\n\r\n        context.response.json(errors);\r\n    }\r\n}\r\n```\r\n\r\nwill output the following.\r\n\r\n```typescript\r\n[\r\n    {\r\n        \"message\": \"instance.lastname is required.\"\r\n    },\r\n    {\r\n        \"message\": \"instance.age is not a number\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[0] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.emails[2] is not a string\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_b is not a boolean\"\r\n    },\r\n    {\r\n        \"message\": \"instance.option_c unexpected property\"\r\n    }\r\n]\r\n```\r\n\r\n<a name=\"web_service_descriptions\">\r\n### web service descriptions\r\n\r\nFor those using appex for web services, developers can leverage appex json schema generation\r\nto generate endpoint metadata (think wsdl). Consider the following which leverages both appex \r\nschema generation and attributes to produce a metadata endpoint consumers of your\r\napi can use to see what data the endpoint http://example.com/customer/create accepts \r\nand returns.\r\n\r\n```typescript\r\nclass Request {\r\n\r\n    /** the customers firstname */\r\n    firstname : string;\r\n\r\n    /** the customers lastname */\r\n    lastname  : string;\r\n\r\n\t/** the customers lastname */\r\n}\r\n\r\nclass Response {\r\n\r\n    /** true on success  */\r\n    success:boolean;\r\n    \r\n    /** an array of validation errors  */\r\n    errors : string[];\r\n}\r\n\r\nattribute('metadata', {input  : 'Request', output : 'Response'})\r\nexport function metadata(context:appex.web.IContext) {\r\n\r\n    var metadata = {\r\n        \r\n\t\tendpoint : 'http://example.com/customer/create',\r\n\r\n        input    : context.schema.get(context.attribute.input),\r\n\r\n        output   : context.schema.get(context.attribute.output)\r\n    }\r\n\r\n    context.response.json(metadata)\r\n}\r\n```\r\n\r\nwhich outputs the following.\r\n\r\n```typescript\r\n{\r\n    \"endpoint\": \"http://example.com/customer/create\",\r\n    \"input\": {\r\n        \"id\": \"Request\",\r\n        \"type\": \"object\",\r\n        \"properties\": {\r\n            \"firstname\": {\r\n                \"type\": \"string\",\r\n                \"description\": \"the customers firstname\",\r\n                \"required\": true\r\n            },\r\n            \"lastname\": {\r\n                \"type\": \"string\",\r\n                \"description\": \"the customers lastname\",\r\n                \"required\": true\r\n            }\r\n        }\r\n    },\r\n    \"output\": {\r\n        \"id\": \"Response\",\r\n        \"type\": \"object\",\r\n        \"properties\": {\r\n            \"success\": {\r\n                \"type\": \"boolean\",\r\n                \"description\": \"true on success\",\r\n                \"required\": true\r\n            },\r\n            \"errors\": {\r\n                \"type\": \"array\",\r\n                \"description\": \"an array of validation errors\",\r\n                \"items\": {\r\n                    \"type\": \"string\"\r\n                },\r\n                \"required\": true\r\n            }\r\n        }\r\n    }\r\n}\r\n```\r\ntip: use the appex sitemap metadata to produce a metadata endpoint for all service methods \r\nin your application.\r\n\r\n\r\n<a name=\"reflection\" />\r\n## reflection\r\n\r\nappex provides a reflection api derived from TypeScript's type system that developers can \r\nleverage to reflect type information declared throughout their appex modules. \r\n\r\nthe following section outlines how to use the reflection api.\r\n\r\n<a name=\"reflect_everything\" />\r\n### reflect everything\r\n\r\nthe appex reflection api is passed on the context.module.reflection property and is available to all\r\nappex handler methods. The following code will JSON serialize everything declared in your appex\r\nproject and write it to the http response. \r\n\r\n```typescript\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection );\r\n}\r\n```\r\n\r\n<a name=\"reflect_specific_types\" />\r\n### reflect specific types\r\n\r\nIn typical scenarios, developers will want to leverage reflection meta data to generate\r\nservice contacts and client side models. the reflection api lets you access meta data \r\nfor the following types declared in your project. \r\n\r\n* modules\r\n* imports\r\n* classes\r\n* interfaces\r\n* functions\r\n* variables\r\n\r\nto access specific type metadata, use the reflection.get([qualifier]) method, as demonstrated below.\r\n\r\n```typescript\r\nexport module model {\r\n    \r\n    export class Customer {\r\n\r\n        public firstname   : string;\r\n\r\n        public lastname    : string;\r\n\r\n        public age         : number;\r\n    }\r\n}\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('model.Customer') );\r\n}\r\n```\r\nand methods..\r\n\r\n```typescript\r\nfunction some_method(a:string, b:number, c?:boolean) : void { }\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_method') );\r\n}\r\n```\r\n\r\n....and variables...\r\n\r\n```typescript\r\nvar some_variable:number = 10;\r\n\r\nexport function index (context:appex.web.Context) {\r\n    \r\n    context.response.json( context.module.reflection.get('some_variable') );\r\n}\r\n```\r\n\r\n<a name=\"developing_with_appex\" />\r\n## developing with appex\r\n\r\nThis section outlines development with appex.\r\n\r\n<a name=\"appex_declaration\" />\r\n### appex.d.ts declaration\r\n\r\nIf you develop on a TypeScript complicant editor (one that supports TS 0.9), appex comes bundled\r\nwith a declaration file you can reference in your project. If installing appex via npm, your\r\nreference should be as follows.\r\n\r\n```typescript\r\n/// <reference path=\"node_modules/appex/appex.d.ts\" />\r\n\r\nexport function index (context:appex.web.IContext) { \r\n    \r\n    context.response.send('hello');\r\n}\r\n\r\nexport function wildcard(context:appex.web.IContext, path:string) {\r\n\r\n    context.response.serve('./', path);\r\n}\r\n```\r\n\r\nBy referencing this in your project, you get the benefits of code completion and static type checking\r\nagainst both appex, and the nodejs core.\r\n\r\n![](https://raw.github.com/sinclairzx81/appex/master/artifacts/code-completion.jpg)\r\n\r\nAdditional declaration files may be obtained from [here](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"structuring_projects\" />\r\n### structuring projects\r\n\r\nappex includes TypeScript's ability to reference source files with the 'reference' element. appex \r\nwill traverse each source files references and include it as part of the compilation.\r\n\r\nDevelopers can use this functionality to logically split source files into reusable components of\r\nfunctionality, as demonstrated below. \r\n\r\n```typescript\r\n//---------------------------------------------------\t\r\n// file: app.js\r\n//---------------------------------------------------\r\n\r\nvar appex = require('appex');\r\n\r\nvar app = appex ({ program : './index.ts' });\r\n\r\napp.listen(3000);\r\n\r\n//---------------------------------------------------\t\r\n// file: index.ts\r\n//---------------------------------------------------\r\n\r\n/// <reference path=\"users.ts\" />\r\n/// <reference path=\"pages.ts\" />\r\n\r\n//---------------------------------------------------\t\r\n// file: users.ts\r\n//---------------------------------------------------\r\n\r\nexport module users {\r\n\t\r\n\t// http://[host]:[port]/users/login\r\n\texport function login  (context) { context.response.send('users.login') }\r\n\t\r\n\t// http://[host]:[port]/users/logout\r\n\texport function logout (context) { context.response.send('users.logout') }\r\n}\r\n\r\n//---------------------------------------------------\t\r\n// file: pages.ts\r\n//---------------------------------------------------\r\n\r\n// http://[host]:[port]/\r\nexport function index   (context) { context.response.send('home') }\r\n\r\n// http://[host]:[port]/about\r\nexport function about   (context) { context.response.send('about') }\r\n\r\n// http://[host]:[port]/contact\r\nexport function contact (context) { context.response.send('contact') }\r\n\r\nexport function wildcard (context, path) { context.response.send(404, ' not found') }\r\n\r\n```\r\n\r\n<a name=\"resources\" />\r\n## additional resources\r\n\r\n* [typescript homepage](http://www.typescriptlang.org/)\r\n* [typescript language specification](http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf)\r\n* [typescript declarations repository](https://github.com/borisyankov/DefinitelyTyped)\r\n\r\n<a name=\"license\" />\r\n## license\r\n\r\nThe MIT License (MIT)\r\n\r\nCopyright (c) 2013 Haydn Paterson (sinclair) <haydn.developer@gmail.com>\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy\r\nof this software and associated documentation files (the \"Software\"), to deal\r\nin the Software without restriction, including without limitation the rights\r\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software, and to permit persons to whom the Software is\r\nfurnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in\r\nall copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\nTHE SOFTWARE.\r\n","scripts":{},"_npmUser":{"name":"sinclair","email":"haydn.developer@gmail.com"},"licenses":[{"url":"https://raw.github.com/sinclairzx81/appex/master/license.txt","type":"The MIT License (MIT)"}],"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"_npmVersion":"1.3.8","description":"develop nodejs web applications with typescript","directories":{},"dependencies":{"typescript.api":"0.7.7"},"readmeFilename":"readme.md","devDependencies":{},"deprecated":"Deprecated"}},"time":{"created":"2013-07-03T12:55:26.239Z","modified":"2026-04-15T10:54:42.546Z","0.0.1":"2013-07-03T12:55:31.329Z","0.0.2":"2013-07-04T01:22:24.567Z","0.0.3":"2013-07-04T04:49:18.307Z","0.1.1":"2013-07-05T07:33:09.957Z","0.1.2":"2013-07-05T08:04:39.519Z","0.2.0":"2013-07-05T11:40:00.724Z","0.2.1":"2013-07-05T12:24:31.824Z","0.2.2":"2013-07-05T13:06:52.043Z","0.2.3":"2013-07-05T13:50:53.594Z","0.2.4":"2013-07-05T15:05:24.367Z","0.2.5":"2013-07-06T14:28:40.666Z","0.2.6":"2013-07-06T17:37:03.061Z","0.2.7":"2013-07-06T17:59:37.796Z","0.2.8":"2013-07-06T19:57:22.766Z","0.2.9":"2013-07-06T22:01:57.386Z","0.3.0":"2013-07-07T00:34:54.715Z","0.3.1":"2013-07-07T05:00:36.528Z","0.3.2":"2013-07-08T06:05:29.140Z","0.3.3":"2013-07-08T08:16:09.879Z","0.3.4":"2013-07-09T12:09:14.943Z","0.3.5":"2013-07-10T00:16:25.873Z","0.3.6":"2013-07-10T02:03:09.215Z","0.3.7":"2013-07-10T03:21:32.265Z","0.3.8":"2013-07-10T10:27:47.507Z","0.3.9":"2013-07-10T14:11:02.003Z","0.4.0":"2013-07-11T02:06:14.217Z","0.4.1":"2013-07-12T10:30:13.767Z","0.4.2":"2013-07-12T15:44:42.370Z","0.4.3":"2013-07-14T06:51:16.990Z","0.4.4":"2013-07-14T13:30:09.316Z","0.4.5":"2013-07-15T06:24:51.929Z","0.4.6":"2013-07-15T15:28:48.034Z","0.4.7":"2013-07-16T06:27:57.356Z","0.4.8":"2013-07-16T13:58:48.623Z","0.4.9":"2013-07-17T14:07:14.286Z","0.5.0":"2013-07-20T15:14:48.732Z","0.5.1":"2013-07-21T16:29:43.679Z","0.5.2":"2013-07-26T13:56:44.270Z","0.5.3":"2013-07-26T16:01:53.216Z","0.5.4":"2013-07-27T11:27:34.571Z","0.5.5":"2013-07-29T04:19:53.487Z","0.5.6":"2013-07-31T10:55:24.271Z","0.5.7":"2013-08-05T03:06:37.059Z","0.6.0":"2013-08-13T09:57:59.322Z","0.6.1":"2013-08-14T13:18:38.926Z","0.6.2":"2013-08-18T18:16:18.941Z","0.6.3":"2013-08-21T12:50:09.750Z","0.6.4":"2013-08-23T17:12:03.532Z","0.6.5":"2013-08-29T22:27:40.081Z","0.6.6":"2013-08-30T11:09:15.108Z","0.6.7":"2013-10-02T04:32:45.651Z","0.6.8":"2013-11-04T13:54:17.035Z","0.6.9":"2013-11-23T23:58:51.371Z"},"author":{"name":"sinclair"},"repository":{"url":"https://github.com/sinclairzx81/appex","type":"git"},"description":"develop nodejs web applications with typescript","keywords":["typescript","web api","reflection","compiler","schema","templates","sitemap"],"bugs":{"url":"https://github.com/sinclairzx81/appex/issues"},"maintainers":[{"name":"sinclair","email":"haydn.developer@gmail.com"}],"readme":"# appex\r\n\r\nwork in progress.\r\n"}