Code Monkey home page Code Monkey logo

flatiron's Introduction

Framework components for node.js and the browser

Example HTTP Server:

var flatiron = require('flatiron'),
    app = flatiron.app;

app.use(flatiron.plugins.http);

app.router.get('/', function () {
  this.res.writeHead(200, { 'Content-Type': 'text/plain' });
  this.res.end('Hello world!\n');
});

app.start(8080);

Example HTTPS Server:

var flatiron = require('flatiron'),
    app = flatiron.app;

app.use(flatiron.plugins.http, {
  https: {
    cert: 'path/to/cert.pem',
    key: 'path/to/key.pem',
    ca: 'path/to/ca.pem'
  }
});

app.router.get('/', function () {
  this.res.writeHead(200, { 'Content-Type': 'text/plain' });
  this.res.end('Hello world!\n');
});

app.start(8080);

Example CLI Application:

// example.js

var flatiron = require('flatiron'),
    app = flatiron.app;

app.use(flatiron.plugins.cli, {
  dir: __dirname,
  usage: [
    'This is a basic flatiron cli application example!',
    '',
    'hello - say hello to somebody.'
  ]
});

app.cmd('hello', function () {
  app.prompt.get('name', function (err, result) {
    app.log.info('hello '+result.name+'!');
  })
})

app.start();

Run It:

% node example.js hello
prompt: name: world
info:   hello world!

Installation

Installing NPM (Node Package Manager)

  curl http://npmjs.org/install.sh | sh

Installing Flatiron

  [sudo] npm install flatiron

Installing Union (Required for flatiron.plugins.http)

  npm install union

Usage:

Start With flatiron.app:

flatiron.app is a broadway injection container. To be brief, what it does is allow plugins to modify the app object directly:

var flatiron = require('flatiron'),
    app = flatiron.app;

var hello = {
  attach: function (options) {
    this.hello = options.message || 'Why hello!';
  }
};

app.use(hello, {
  message: "Hi! How are you?"
});

// Will print, "Hi! How are you?"
console.log(app.hello);

Virtually all additional functionality in flatiron comes from broadway plugins, such as flatiron.plugins.http and flatiron.plugins.cli.

app.config

flatiron.app comes with a config plugin pre-loaded, which adds configuration management courtesy nconf. app.config has the same api as the nconf object.

The literal store is configured by default. If you want to use different stores you can easily attach them to the app.config instance.

// add the `env` store to the config
app.config.use('env');

// add the `file` store the the config
app.config.use('file', { file: 'path/to/config.json' });

// or using an alternate syntax
app.config.env().file({ file: 'path/to/config.json' });

// and removing stores
app.config.remove('literal');

app.log

flatiron.app will also load a log plugin during the init phase, which attaches a winston container to app.log. This logger is configured by combining the app.options.log property with the configuration retrieved from app.config.get('log').

Create An HTTP Server with flatiron.plugins.http(options):

This plugin adds http serving functionality to your flatiron app by attaching the following properties and methods:

Define Routes with app.router:

This is a director router configured to route http requests after the middlewares in app.http.before are applied. Example routes include:

// GET /
app.router.get('/', function () {
  this.res.writeHead(200, { 'Content-Type': 'text/plain' });
  this.res.end('Hello world!\n');
});

// POST to /
app.router.post('/', function () {
  this.res.writeHead(200, { 'Content-Type': 'text/plain' });
  this.res.write('Hey, you posted some cool data!\n');
  this.res.end(util.inspect(this.req.body, true, 2, true) + '\n');
});

// Parameterized routes
app.router.get('/sandwich/:type', function (type) {
  if (~['bacon', 'burger'].indexOf(type)) {
    this.res.writeHead(200, { 'Content-Type': 'text/plain' });
    this.res.end('Serving ' + type + ' sandwich!\n');
  }
  else {
    this.res.writeHead(404, { 'Content-Type': 'text/plain' });
    this.res.end('No such sandwich, sorry!\n');
  }
});

app.router can also route against regular expressions and more! To learn more about director's advanced functionality, visit director's project page.

Access The Server with app.server:

This is a union middleware kernel.

Modify the Server Options with app.http:

This object contains options that are passed to the union server, including app.http.before, app.http.after and app.http.headers.

These properties may be set by passing them through as options:

app.use(flatiron.plugins.http, {
  before: [],
  after: []
});

You can read more about these options on the union project page.

Start The Server with app.start(port, <host>, <callback(err)>)

This method will both call app.init (which will call any asynchronous initialization steps on loaded plugins) and start the http server with the given arguments. For example, the following will start your flatiron http server on port 8080:

app.start(8080);

Create a CLI Application with flatiron.plugins.cli(options)

This plugin turns your app into a cli application framework. For example, [jitsu] (https://github.com/nodejitsu/jitsu) uses flatiron and the cli plugin.

Valid options include:

{
  "argvOptions": {}, // A configuration hash passed to the cli argv parser.
  "usage": [ "foo", "bar" ], // A message to show for cli usage. Joins arrays with `\n`.
  "dir": require('path').join(__dirname, 'lib', 'commands'), // A directory with commands to lazy-load
  "notFoundUsage": false // Disable help messages when command not found
}

Add lazy-loaded CLI commands with options.dir and app.commands:

Flatiron CLI will automatically lazy-load modules defining commands in the directory specified by options.dir. For example:

// example2.js
var path = require('path'),
    flatiron = require('./lib/flatiron'),
    app = flatiron.app;

app.use(flatiron.plugins.cli, {
  dir: path.join(__dirname, 'cmds')
});

app.start();
// cmd/highfive.js
var highfive = module.exports = function highfive (person, cb) {
  this.log.info('High five to ' + person + '!');
  cb(null);
};

In the command, you expose a function of arguments and a callback. this is set to app, and the routing is taken care of automatically.

Here it is in action:

% node example2.js highfive Flatiron 
info:   High five to Flatiron!

You can also define these commands by adding them directly to app.commands yourself:

// example2b.js
var flatiron = require('./lib/flatiron'),
    app = flatiron.app;

var path = require('path'),
    flatiron = require('./lib/flatiron'),
    app = flatiron.app;

app.use(flatiron.plugins.cli);

app.commands.highfive = function (person, cb) {
  this.log.info('High five to ' + person + '!');
  cb(null);
};

app.start();
% node example2b.js highfive Flatiron 
info:   High five to Flatiron!

Callback will always be the last argument provided to a function assigned to command

app.commands.highfive = function (person, cb) {
  this.log.info('High five to ' + person + '!');
  console.log(arguments);
}
% node example2b.js highfive Flatiron lol haha
info:    High five to Flatiron!
{
  '0': 'Flatiron',
  '1': 'lol',
  '2': 'haha',
  '3': [Function]
}

Define Ad-Hoc Commands With app.cmd(path, handler):

This adds the cli routing path path to the app's CLI router, using the director route handler handler, aliasing app.router.on. cmd routes are defined the same way as http routes, except that it uses (a space) for a delimiter instead of /.

For example:

// example.js
var flatiron = require('./lib/flatiron'),
    app = flatiron.app;

app.use(flatiron.plugins.cli, {
  usage: [
    'usage: node test.js hello <person>',
    '',
    '  This will print "hello <person>"'
  ]
});

app.cmd('hello :person', function (person) {
  app.log.info('hello ' + person + '!');
});

app.start()

When you run this program correctly, it will say hello:

% node example.js hello person
info:   hello person!

If not, you get a friendly usage message:

% node test.js hello
help:   usage: node test.js hello <person>
help:
help:     This will print "hello <person>"

Check CLI Arguments with app.argv:

Once your app is started, app.argv will contain the optimist-parsed argv options hash, ready to go!

Here's an example:

// example3.js
var flatiron = require('./lib/flatiron'),
    app = flatiron.app;

app.use(flatiron.plugins.cli);

app.start();

app.log.info(JSON.stringify(app.argv));

This prints:

% node example3.js
info:    {"_":[], "$0": "node ./example3.js"}

Awesome!

Add a Default Help Command with options.usage:

When attaching the CLI plugin, just specify options.usage to get a friendly default message for when there aren't any matching routes:

// example4.js
var flatiron = require('./lib/flatiron'),
    app = flatiron.app;

app.use(flatiron.plugins.cli, {
  usage: [
    'Welcome to my app!',
    'Your command didn\'t do anything.',
    'This is expected.'
  ]
});

app.start();
% node example4.js 
help:   Welcome to my app!
help:   Your command didn't do anything.
help:   This is expected.

Start The Application with app.start(callback):

As seen in these examples, starting your app is as easy as app.start! this method takes a callback, which is called when an app.command completes. Here's a complete example demonstrating this behavior and how it integrates with options.usage:

// example5.js
var path = require('path'),
    flatiron = require('./lib/flatiron'),
    app = flatiron.app;

app.use(flatiron.plugins.cli, {
  usage: [
    '`node example5.js error`: Throws an error.',
    '`node example5.js friendly`: Does not throw an error.'
  ]
});

app.commands.error = function (cb) {
  cb(new Error('I\'m an error!'));
};

app.commands.friendly = function (cb) {
  cb(null);
}

app.start(function (err) {
  if (err) {
    app.log.error(err.message || 'You didn\'t call any commands!');
    app.log.warn('NOT OK.');
    return process.exit(1);
  }
  app.log.info('OK.');
});

Here's how our app behaves:

% node example5.js friendly
info:   OK.

% node example5.js error
error:  I'm an error!
warn:   NOT OK.

% node example5.js
help:   `node example2b.js error`: Throws an error.
help:   `node example2b.js friendly`: Does not throw an error.
error:  You didn't call any commands!
warn:   NOT OK.

Read More About Flatiron!

Articles

Sub-Projects

Tests

Tests are written in vows:

  $ npm test

License: MIT

flatiron's People

Contributors

3rd-eden avatar avianflu avatar bmeck avatar coderarity avatar dscape avatar edef1c avatar indexzero avatar jcrugzz avatar jfhbrook avatar julianduque avatar marak avatar martinodf avatar mikl avatar mmalecki avatar nhunzaker avatar odbol avatar pgilad avatar pksunkara avatar raynos avatar southern avatar ssevertson avatar tricknotes avatar trodrigues avatar yawnt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

flatiron's Issues

Flatiron TODO example

The core parts of Flatiron (broadway, union, etc.) have enough documentation that you can infer generally how flatiron works, but flatiron itself has no documentation. In particular, the functionality of the baked-in plugins needs documenting.

Error after serving request: Cannot call method 'writeHead' of undefined

Really simple code from the README:

var flatiron = require('flatiron'),
    app = flatiron.app;

app.use(flatiron.plugins.http);

app.router.get('/', function () {
  this.res.writeHead(200, { 'Content-Type': 'text/plain' });
  this.res.end('Hello world!\n');
});

app.start(8080);

Install dependencies:

npm install flatiron
npm install union

Crash after serving a request:

curl localhost:8080/favicon.ico 
TypeError: Cannot call method 'writeHead' of undefined

How to do additional command-line options?

I have been working on a project using Flatiron for command line utilities, and I haven't been able to figure out how to add command-line options.

This my app entrypoint, and the commands are here.

I have my ./bin/ardon migrate, I’d like to add a --reset option to it. Does Flatiron support this, or will I have to roll my own using optimist or something similar?

Simple middleware seems to block requests

app.use(flatiron.plugins.http
  , { before: 
      [ function(req) { 
          console.log(
            {"method": req.method, "url": req.url, "date": Date.now()}); 
        }
      ]
    }
);

This simple canonical logger example breaks flatiron. The way I see it this is always a bug:

  • Either it actually is a bug that needs to be fixed
  • Or the fact that I didn't find a canonical example of a logger (or any simple middleware for that matter) is a bug

flatiron.app == undefined?

This seems really odd to me, and almost caused me to give up on Flatiron before I figured out what was going on (though I still don't get why it's going on)..

Here is the simplest app.js that demonstrates what I'm talking about:

var flatiron = require( 'flatiron' ), app = flatiron.app;
console.log( "app =", app );

When you run this, you get:

app = undefined

Although it indicates that it's undefined, it actually is there and is usable, but this caused me to spend hours trying to debug the wrong things, since it looked like flatiron.app wasn't working. I'm not sure if this is a flatiron issue, or something with the way that util.inherits works, but if there is a way to make this not happen that would make debugging a lot less painful (especially for someone new to Flatiron like I am)..

For anyone else who runs into this problem, try this instead:

var flatiron = require('flatiron'),inspect = require('inspect');
var app = flatiron.app;
console.log( inspect( app ) );

Have flatiron's cli plugin intercept -v and --version flags

It's a common pattern in our cli apps to do something like:

josh@onix:~$ jitsu -v
v0.7.3

It'd be pretty sweet if the cli plugin did this automatically. The downside I can see is that we're enforcing the opinion that -v means "version" and not "verbose".

Possibility to define a default route with Flatiron

I have not been able to find a better way to make a default route than this:

app.router.get(/((\w|.)*)/, function () {
  return nice404page();
}

And by default, Flatiron’s 404 page just has the word “undefined” on it. Not really a compelling user experience ;)

spdy plugin

would be great to be able to create a spdy flatiron app

Can't install..

Hey guys, after a long list of installed deps, I get here. Thoughts?

npm http 200 https://registry.npmjs.org/winston

npm ERR! Error: No compatible version found: read@'>=1.0.0- <1.1.0-'
npm ERR! Valid install targets:
npm ERR! ["0.0.1","0.0.2","0.0.3","0.1.0","0.1.1"]
npm ERR! at installTargetsError (/usr/local/lib/node_modules/npm/lib/cache.js:486:10)
npm ERR! at next_ (/usr/local/lib/node_modules/npm/lib/cache.js:436:17)
npm ERR! at next (/usr/local/lib/node_modules/npm/lib/cache.js:413:44)
npm ERR! at /usr/local/lib/node_modules/npm/lib/cache.js:406:5
npm ERR! at saved (/usr/local/lib/node_modules/npm/lib/utils/npm-registry-client/get.js:151:7)
npm ERR! at Object.oncomplete (/usr/local/lib/node_modules/npm/node_modules/graceful-fs/graceful-fs.js:230:7)

TypeError: Cannot read property 'before' of undefined in static.js

I get a TypeError when I do this:

// Instantiate a Flatiron HTTP server.
var apiserver = flatiron.createApp({});

// Configure HTTP services with ecstatic for serving static files.
apiserver.use(flatiron.plugins.http, {
  before: [
    // Enable CORS via middleware.
    require('../middleware/cors'),
  ],
  // These headers are set globally.
  headers: {
    'X-Powered-By': 'Flatiron',
  },
  // Configure HTTPS if certs are specified.
  https: app.config.get('server:https'),
});

app.use(flatiron.plugins.static, {
  root: path.join(__dirname, '..', '..', 'public'),
});

Here's the full traceback:

/home/mikl/Work/Node.js/kartotekov/node_modules/flatiron/lib/flatiron/plugins/static.js:67
    app.http.before = app.http.before.concat(st(options));
                              ^
TypeError: Cannot read property 'before' of undefined
    at exports.attach.app.static (/home/mikl/Work/Node.js/kartotekov/node_modules/flatiron/lib/flatiron/plugins/static.js:67:31)
    at exports.attach (/home/mikl/Work/Node.js/kartotekov/node_modules/flatiron/lib/flatiron/plugins/static.js:80:15)
    at App.use (/home/mikl/Work/Node.js/kartotekov/node_modules/flatiron/node_modules/broadway/lib/broadway/app.js:169:31)
    at module.exports (/home/mikl/Work/Node.js/kartotekov/lib/commands/apiserver.js:36:7)
    at executeCommand (/home/mikl/Work/Node.js/kartotekov/node_modules/flatiron/lib/flatiron/plugins/cli.js:297:19)
    at Object.exports.commands.app.router.notfound (/home/mikl/Work/Node.js/kartotekov/node_modules/flatiron/lib/flatiron/plugins/cli.js:357:5)
    at Router.dispatch (/home/mikl/Work/Node.js/kartotekov/node_modules/flatiron/node_modules/director/lib/director/cli.js:50:21)
    at exports.attach.app.start (/home/mikl/Work/Node.js/kartotekov/node_modules/flatiron/lib/flatiron/plugins/cli.js:87:18)
    at onComplete (/home/mikl/Work/Node.js/kartotekov/node_modules/flatiron/node_modules/broadway/lib/broadway/app.js:86:5)
    at Object.exports.ensure (/home/mikl/Work/Node.js/kartotekov/node_modules/flatiron/node_modules/broadway/lib/broadway/features/index.js:10:10)

Document HTTPS usage

Is there a need for an https plugin or can we specify this when creating an http app?

Cannot find module './daemon.v0.10.0'

forever crashes on node 0.10
module.js:340
throw err;
^
Error: Cannot find module './daemon.v0.10.0'
at Function.Module._resolveFilename (module.js:338:15)
at Function.Module._load (module.js:280:25)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at Object. (/usr/local/lib/node_modules/forever/node_modules/daemon/lib/daemon.js:12:11)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:364:17)

npm uninstall forever -g && npm install forever -g
... loads of npm...
/usr/bin/forever -> /usr/lib/node_modules/forever/bin/forever
/usr/bin/foreverd -> /usr/lib/node_modules/forever/bin/foreverd
[email protected] /usr/lib/node_modules/forever
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected] ([email protected])
├── [email protected] ([email protected], [email protected])
├── [email protected] ([email protected], [email protected])
├── [email protected] ([email protected], [email protected])
├── [email protected] ([email protected], [email protected], [email protected], [email protected], [email protected], [email protected])
├── [email protected] ([email protected], [email protected], [email protected], [email protected], [email protected], [email protected])
├── [email protected] ([email protected], [email protected], [email protected])
└── [email protected] ([email protected], [email protected], [email protected], [email protected])

$node -v
v0.10.0
$npm -v
1.2.14

I've read on a previous issue that daemon isn't required anymore?

I dont get the 'documentation'

Servus,
I am really intrested in using flatiron, because it seems to be more flexible and independant usable than e.g. express.

But I do not find any usefull documentation for the single modules, only that short descriptions, e.g. on flatiron.org.

Is there any deeper documentation, that I just didnt have seen so far?

How - e.g. - would I implement a sipmple static webserver with flatiron, you know that "ten-liner" that every express-docu shows ... ;)

Conflicting dependencies

Tried installing Flatiron (npm 1.3.2 Windows 7 & Ubuntu 12), errors complain about conflicting version dependencies in flatiron:

npm ERR! peerinvalid The package flatiron does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer [email protected] wants flatiron@~0.1.9
npm ERR! peerinvalid Peer [email protected] wants flatiron@~0.3.0
npm ERR! System Windows_NT 6.1.7601
npm ERR! command "C:\Program Files\nodejs\node.exe" "C:\Program Files\nodejs\node_modules\npm\bin\npm-cli.js" "install" "-g" "flatiron-cli-config"
npm ERR! cwd C:\development\code\webOSProjects\CrossPlatform\PhoneGap_3.0
npm ERR! node -v v0.10.13
npm ERR! npm -v 1.3.2
npm ERR! code EPEERINVALID

Example of config with additional log transports?

I have a config.json as such for testing:

{
  "log": {
    "couchdb": {
      "host": "localhost",
      "db" : "winston_logs"
    }
  }
}

When the app boots and the broadway log plugin kicks in, its winston module doesn't have access to the Couchdb transport from winston-couchdb. What is the proper way to configure logging?

OAuth support

I really want to use this framework, and I applaud nodejitsu for your contributions. Everything is pretty much what I am looking for, with one exception. I cannot for the life of me figure out how to add user authentication using OAuth or similar. Passport does this beautifully within Express.js framework, but the closest thing I have seen out there is a hacked up version of Passport for Flatiron (https://gist.github.com/2132062). I would prefer to use a community supported solution, but after a day of searching, I have come up with nothing...

Question... Is there anything out there that I can use for oauth authentication for flatiron?

Thanks in advance for your response,

Travis.

Exception running create and help commands

Running the latest version of flatiron (0.1.4), the create command throws the following exception in node 0.6.2

"TypeError: Cannot call method 'concat' of undefined",
" at Object. (/usr/local/lib/node_modules/flatiron/lib/flatiron/plugins/cli.js:197:46)",
" at apply (/usr/local/lib/node_modules/flatiron/node_modules/director/lib/director/router.js:356:19)",
" at _every (/usr/local/lib/node_modules/flatiron/node_modules/director/lib/director/router.js:28:9)",
" at [object Object].invoke (/usr/local/lib/node_modules/flatiron/node_modules/director/lib/director/router.js

Running help command throws:

"TypeError: Object [object Object] has no method 'help'",
" at /usr/local/lib/node_modules/flatiron/lib/flatiron/plugins/cli.js:110:15",
" at Array.forEach (native)",
" at showUsage (/usr/local/lib/node_modules/flatiron/lib/flatiron/plugins/cli.js:109:12)",
" at loadCommand (/usr/local/lib/node_modules/flatiron/lib/flatiron/plugins/cli.js:143:18)",
" at Object. (/usr/local/lib/node_modules/flatiron/lib/flatiron/plugins/cli.js:194:18)",
" at apply (/usr/local/lib/node_modules/flatiron/node_modules/director/lib/director/router.js:356:19)",
" at _every (/usr/local/lib/node_modules/flatiron/node_modules/director/lib/director/router.js:28:9)",

req.body validity in route methods in director (in POST requests) ...

req.body is currently interpreted for mimetypes such as application/x-www-form-urlencoded.
lib/director/http/index.js: Router.prototype.parse function:

 req.body = req.body && req.body.length
    ? parser(req.body)   // get it processed through mimetype parser.
    : {};

But in the process, if there is no mimetype associated, it is set to null, and the original body data is lost. Can we retain it (as string object)?

plugin.static makes route '/' static

Here is the code for the app

/* requires */
var fs       = require('fs'),
    path     = require('path'),
    flatiron = require('flatiron'),
    app      = flatiron.app;

/* config */
app.config.file({ file: path.join(__dirname, 'config', 'config.json') });
app.use(flatiron.plugins.http);
app.use(flatiron.plugins.static, {root: __dirname});

/* routing table */
var routes = {
    '/': {
        get: home,
        '/test': {
            get: test
        }
    }
}

app.router.mount(routes, '/');

/* routing function */
function home(){
    var index_template = fs.readFileSync(path.join(__dirname, 'app/templates', 'home.html'), 'utf-8');
    this.res.writeHead(200, {'Content-Type': 'text/html'});
    this.res.html(index_template);
}

function test(){
    var index_template = fs.readFileSync(path.join(__dirname, 'app/templates', 'test.html'), 'utf-8');
    this.res.writeHead(200, {'Content-Type': 'text/html'});
    this.res.html(index_template);
}

app.start(3000);

When I make changes to home.html, they don't get served until I comment out the static plugin usage. Changes to test.html get served right away. Otherwise no problems.

Environments?

Is there an easy way to figure out what environment you're running flatiron in, besides using process.env.NODE_ENV?

Using both flatiron.plugins.http and flatiron.plugins.cli within the same app?

I often find myself wanting to have both a CLI and a HTTP interface for an app. One of my CLI commands might be runserver, which then starts a HTTP server inside the CLI app. I have done so by creating a new flatiron appication inside the app, but I'm wondering if this is the right way to do it.

I can't imagine I'm the only one with this need – what does everyone else do?

package dependencies

pm ERR! peerinvalid The package flatiron does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer [email protected] wants flatiron@~0.1.9
npm ERR! peerinvalid Peer [email protected] wants flatiron@~0.3.0

npm ERR! System Darwin 12.2.0

app.prompt.get fails inside asynchronous callbacks on Windows

I have a weird problem that it only happens on windows. I don't know if this is the right place or if I should report it on flatiron/prompt.

Thing is that if I add a simple command like this:

var thing = module.exports,
    app = require("../../app");

thing.run = function(){
    process.nextTick(function(){
        app.prompt.get(["test"], function(e,r){
            console.log("error: " , e, " result: ", r);
        });
    });
};

to an auto generated application (with: flatiron create example cli)

when i execute the application like "simple thing run", I see the prompt message but it seems that it doesn't wait to the user data an inmediately fails with:

[Error: read Unknown system errno 6]
  code: 'Unknown system errno 6',
  errno: 'Unknown system errno 6',
  syscall: 'read' }  

The stack trace is:

prompt: test: error:  Error: read Unknown system errno 6
    at errnoException (net.js:670:11)
    at TTY.onread (net.js:395:21)

Again this only happens on windows.

Do you have any workarround to this? since I guess you do a lot of I/O in jitsu for instance.

Thank you very much, I really like flatiron

Order of flatiron plugin usage makes different behavior

If I go

app.use(flatiron.plugins.http, {
  // HTTP options
});
app.use(flatiron.plugins.cli, {
  // CLI options
});

then down here access some stuff in app.argv, and then later try to mount and access a route (say, '/') with director, I can't access the route, and it produces an Error: Not found on access, as if the route wasn't mounted.

If I swap the order of my app.use statements, it seems to work. Maybe plugins.cli overwrites something that plugins.http needs to set up the routes?

Let me know if any addtl. details needed.

Possible to merge route table into app.router?

So the documentation for using Director in Flatiron is not clear at all. The docs provide examples of a route table but no way to use a route table once you're using flatiron.app and the flatiron.plugins.http.

What I'm trying to achieve is using app.router with a route table like the below as I'm very intrigued by the possibility of using multiple response handlers for a single request.

var routes = {
'/authors': {
on: showAuthor,
'/books': { on: [showCover, showDescription] },
'/bios': { on: [showPicture, showBiography] }
}
};

Adhoc syntax support for this would also be great.
app.router.get('/user/:id', [function(){ /* show photo /}, function(){ / get contacat details */}]);

It's clear how to do this if you're setting up router from scratch but because there is already an instance ready to go on app.router, it's not clear how to merge a route table in.

api-easy version (0.1.0) not found

Hi,

First, I want to say this project(s) looks beautiful.

The generated package.json has the api-easy version => 0.1.0. This is not found by the npm install. I changed it to 0.3.2 and the install worked. Here is the command line error output:

$ npm install
npm ERR! Error: version not found: 0.1.0 : api-easy/0.1.0
npm ERR! at Request._callback (/usr/local/lib/node_modules/npm/lib/utils/npm-registry-client/request.js:180:12)
npm ERR! at Request.callback (/usr/local/lib/node_modules/npm/node_modules/request/main.js:99:22)
npm ERR! at Request. (/usr/local/lib/node_modules/npm/node_modules/request/main.js:361:18)
npm ERR! at Request.emit (events.js:67:17)
npm ERR! at IncomingMessage. (/usr/local/lib/node_modules/npm/node_modules/request/main.js:327:16)
npm ERR! at IncomingMessage.emit (events.js:88:20)
npm ERR! at HTTPParser.onMessageComplete (http.js:137:23)
npm ERR! at CleartextStream.ondata (http.js:1125:24)
npm ERR! at CleartextStream._push (tls.js:363:27)
npm ERR! at SecurePair.cycle (tls.js:679:20)
npm ERR! Report this entire log at:
npm ERR! http://github.com/isaacs/npm/issues
npm ERR! or email it to:
npm ERR! [email protected]
npm ERR!
npm ERR! System Darwin 11.3.0
npm ERR! command "node" "/usr/local/bin/npm" "install"
npm ERR! cwd /Users/rkoberg/Documents/workspace/flatiron-test
npm ERR! node -v v0.6.3
npm ERR! npm -v 1.0.106
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR! /Users/rkoberg/Documents/workspace/flatiron-test/npm-debug.log
npm not ok

Winston is required but not in dependencies

Winston is required in plugin/cli.js, but is not in the dependencies list.

Please fix this, I am to lazy to fork and make a pull request.

I found this erro by running the code:

var flatiron = require('flatiron'),
    app = flatiron.app;

    app.use(flatiron.plugins.cli, {
        dir: __dirname
    });

    app.cmd('app start', function () {
        app.prompt.get('name', function (err, name) {
            console.dir(arguments);
        });
    });

    app.init(function () {
        app.start();
    });

Performance Issues in CLI Apps

I was intending to use flatiron in a new CLI project.

However, initial testing suggests serious performance problems. Running the example CLI apps in the README takes about 2 seconds each, and simply require() the flatiron package takes about a second.

Is this normal? This maybe acceptable in a web app, where server processes are long-running. But for a command line app, let the user wait 2 seconds to see help text is insane.

Node version is 0.10.13.

http plugin should allow support for multiple servers

If an application wants to support both http and https you have to pipe a raw node https server into app.server. This is less than ideal. We should also think about having multiple servers on different ports ala Haibu, but this is less important.

cli plugin ignores command load errors

The current behavior is to ignore all errors. However, if the error has to do with malformed javascript instead of module discovery, then the user should get an error.

flatiron cli breaks without command in node 0.10.0

$ jitsu
info:    Welcome to Nodejitsu julianduque
info:    jitsu v0.12.3, node v0.10.0
info:    It worked if it ends with Nodejitsu ok
info:    Executing command
info:    Welcome to Nodejitsu julianduque
info:    jitsu v0.12.3, node v0.10.0
info:    It worked if it ends with Nodejitsu ok
info:    Executing command

TypeError: Arguments to path.join must be strings
    at path.js:360:15
    at Array.filter (native)
    at Object.exports.join (path.js:358:36)
    at loadCommand (/Users/julianduque/Development/nodejitsu/jitsu/node_modules/flatiron/lib/flatiron/plugins/cli.js:211:45)
    at executeCommand (/Users/julianduque/Development/nodejitsu/jitsu/node_modules/flatiron/lib/flatiron/plugins/cli.js:278:26)
    at Object.app.router.notfound (/Users/julianduque/Development/nodejitsu/jitsu/node_modules/flatiron/lib/flatiron/plugins/cli.js:357:5)
    at Router.dispatch (/Users/julianduque/Development/nodejitsu/jitsu/node_modules/flatiron/node_modules/director/lib/director/cli.js:50:21)
    at execCommand (/Users/julianduque/Development/nodejitsu/jitsu/lib/jitsu.js:234:18)
    at jitsu.exec (/Users/julianduque/Development/nodejitsu/jitsu/lib/jitsu.js:247:54)
    at /Users/julianduque/Development/nodejitsu/jitsu/lib/jitsu.js:190:20

Argument to app.command overwrites callback value

README doc on flatiron/flatiron states:

app.commands.highfive = function (person, cb) {
this.log.info('High five to ' + person + '!');
cb(null);

which is cool except when user does:

app highfive arg1 arg2 haha

arg1 is assigned to person, arg2 is assigned to callback cb and haha of course is only reachable in argv._.

This throws an error at cb(null) since strings can't null.

Also there is scant documentation on using callbacks and errors in Flatiron CLI apps.

Throw exception upon app.start on privileged ports

I was trying to run this code as a regular user using port 80.

try {
  app.start(
    app.config.get("server:port"),
    app.config.get("server:host"),
    function () {
      winston.info("Running app in "+app.config.get("NODE_ENV").toUpperCase()+" environment");
      winston.info("At: "+app.config.get("server:host")+":"+app.config.get("server:port"));
    }
  );
} catch (e) {
  winston.error(e);
}

This block won't catch the exception. Why is that? Is this a nodejs issue or can it be solved from within flatiron? I see how the err doesn't get thrown if there's a callback defined in the flatiron/plugins/http.js file. I'd be glad to submit a PR if you could give me any pointers.

Thanks for your time and this awesome framework.

Better error when the scaffold doesn't exist

Currently, if you try to use flatiron create with a scaffold that doesn't exist, it crashes and gives you ugly error output. For example, try flatiron create test blog, which will produce a huge error output. Instead, it should say something like 'Scaffold does not exist', and give the user a list of available scaffolds. Perhaps a separate command should be made that lists out the available scaffolds, and in the error for creating a scaffold that doesn't exist, tell the user to run this command.

tl;dr - have a way to list scaffolds and show a proper error message when the user tries to create a scaffold that doesn't exist

http plugin requiring error

After a fresh install of flatiron and flatiron create todo && cd todo

pksunkara@CodeMachine [todo] #49  →  node app.js 
flatiron.plugins.http requires the `union` module from npm
install using `npm install union`.

Can be solved by making flatiron dependent on union.

Documentation Style / API?

As mentioned in issue #5, the documentation for Flatiron itself is bit lacking, though the main components seem to have decent documentation coming along.

I was thinking about, say, starting with whatever piece I was trying to learn and adding markdown comments for Docco à la Backbone -- it looks like maybe this is already sort of the convention, but I wanted to check before moving forward.

In general, is there a strategy for documentation / what are the main resource / how to help/ etc.? :)

Should 'union' be included as a dependency in the package.json?

I tried to run some sample code that only had 2 require statements at the top for flatiron and ecstatic. When I ran it, however, I got a stack trace and this message:

flatiron.plugins.http requires the `union` module from npm
install using `npm install union`.

Did we leave union out on purpose or is it an oversight?

Front page example fails on windows

var flatiron = require('flatiron'),
    app = flatiron.app;

app.use(flatiron.plugins.cli, {
  dir: __dirname,
  usage: [
    'This is a basic flatiron cli application example!',
    '',
    'hello - say hello to somebody.'
  ]
});

app.cmd('hello', function () {
  app.prompt.get('name', function (err, result) {
    app.log.info('hello '+result.name+'!');
  })
})

app.start();

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.