0.0.17 • Published 11 years ago
barbakoa v0.0.17
barbakoa
Fullstack framework based on Koa
See axelhzf/barbakoa-base-app for usage example.
Installation
npm install barbakoa --save
barbakoa initCreate an application
var barbakoa = require("barbakoa");
var app = new barbakoa();
app.start();Router
Barbakoa uses koa-router internally. The router is exposed via barbakoa.router.
var router = barbakoa.router;
router.get("/", function* () {
    this.body = "Hello world";
}ORM
Barbakoa uses Sequelize for persistence.
Models defined in the folder app/server/models/ are auto initialized.
Define a model
var db = require("barbakoa").db;
module.exports = db.define("User", {
  name: db.types.STRING,
  password: db.types.STRING
});db.types.STRING                      // VARCHAR(255)
db.types.STRING(1234)                // VARCHAR(1234)
db.types.STRING.BINARY               // VARCHAR BINARY
db.types.TEXT                        // TEXT
 
db.types.INTEGER                     // INTEGER
db.types.BIGINT                      // BIGINT
db.types.BIGINT(11)                  // BIGINT(11)
db.types.FLOAT                       // FLOAT
db.types.FLOAT(11)                   // FLOAT(11)
db.types.FLOAT(11, 12)               // FLOAT(11,12)
 
db.types.DECIMAL                     // DECIMAL
db.types.DECIMAL(10, 2)              // DECIMAL(10,2)
 
db.types.DATE                        // DATETIME for mysql / sqlite, TIMESTAMP WITH TIME ZONE for postgres
db.types.BOOLEAN                     // TINYINT(1)
 
db.types.ENUM('value 1', 'value 2')  // An ENUM with allowed values 'value 1' and 'value 2'
db.types.ARRAY(Sequelize.TEXT)       // Defines an array. PostgreSQL only.
 
db.types.BLOB                        // BLOB (bytea for PostgreSQL)
db.types.BLOB('tiny')                // TINYBLOB (bytea for PostgreSQL. Other options are medium and long)
db.types.UUID    Custom types:
db.types.URL    //db.types.STRING(2000)Model usage
var User = require("./models/User");
var router = require("barbakoa").router;
router.get("/api/users", function* () {
  var users = yield User.findAll();
  this.body = {users: users};
});Model class methods
http://sequelize.readthedocs.org/en/latest/docs/models/
project = Project.build({
  title: 'my awesome project',
  description: 'woot woot. this will make me a rich man'
})
task = Task.create({ title: 'foo', description: 'bar', deadline: new Date() })
User.create({ username: 'barfooz', isAdmin: true }, [ 'username' ]) //filter properties
// search for one element
Project.find(123)
Project.find({ where: {title: 'aProject'} })
Project.find({
  where: {title: 'aProject'},
  attributes: ['id', ['name', 'title']]
})
User
  .findOrCreate({where: {username: 'sdepold'}, defaults: {job: 'Technical Lead JavaScript'}})
  .spread(function(user, created) {})
  
  
Project.findAndCountAll({where: { title: { $like: 'foo%'}}, offset: 10, limit: 2 })
  
Project.findAll()
Project.findAll({ where: ["id > ?", 25] })
  
Project.findAll({
  where: {
    id: {
      $gt: 6,                // id > 6
      $gte: 6,               // id >= 6
      $lt: 10,               // id < 10
      $lte: 10,              // id
      $ne: 20,               // id != 20
      $not: 3,               // id NOT 3
      $between: [6, 10],     // BETWEEN 6 AND 10
      $notBetween: [11, 15], // NOT BETWEEN 11 AND 15
      $in: [1, 2],           // IN [1, 2]
      $like: '%hat',         // LIKE '%hat'
      $notLike: '%hat'       // NOT LIKE '%hat'
      $iLike: '%hat'         // ILIKE '%hat' (case insensitive)
      $notILike: '%hat'      // NOT ILIKE '%hat'
      $overlap: [1, 2]       // && [1, 2] (PG array overlap operator)
      $contains: [1, 2]      // @> [1, 2] (PG array contains operator)
      $contained: [1, 2]     // <@ [1, 2] (PG array contained by operator)
    }
  }
})  
  
Project.find({
  where: { name: 'a project', $or: [{ id: [1,2,3] }, { id: { $gt: 10 } }]}
})
Project.findAll({ offset: 10, limit: 2 })
Project.findAll({order: 'title DESC'})
Project.findAll({group: 'name'})
Project.count({ where: ["id > ?", 25] })
Project.max('age')
Project.min('age')
Project.sum('age')
//eager loading
Task.findAll({ include: [ User ] })
User.findAll({ include: [{ model: Tool, as: 'Instruments' }] })
//bulk methods
User.bulkCreate([
  { username: 'barfooz', isAdmin: true },
  { username: 'foo', isAdmin: true }
])
User.bulkCreate([
  { username: 'foo' },
  { username: 'bar', admin: true}
], { fields: ['username'] })
Task.update(
  { status: 'inactive' }, 
  { where: { subject: 'programming' }}
)
Task.destroy({ where: {subject: 'programming'}})
Task.destroy({}, {truncate: true})Model instance methods
http://sequelize.readthedocs.org/en/latest/docs/instances/
project.save()
task.updateAttributes({title: 'a very different title now'})
task.destroy()
person.reload()
user.increment('my-integer-field')
user.increment('my-integer-field', 2)
user.decrement('my-integer-field')Migrations
Write your migrations in migrations folder
module.exports = {
  up: function* (migration, types) {
    yield migration.addIndex(
        'Votes', 
        ['UserId', 'SelfieId', "daysFromStart"], 
        {
            indexName: 'SuperDuperIndex',
            indicesType: 'UNIQUE' 
        }
    );
  },
  down: function () {
  }
};Migration methods
http://sequelize.readthedocs.org/en/latest/docs/migrations/
- createTable(tableName, attributes, options)
- dropTable(tableName)
- dropAllTables()
- renameTable(before, after)
- showAllTables()
- describeTable(tableName)
- addColumn(tableName, attributeName, dataTypeOrOptions)
- removeColumn(tableName, attributeName)
- changeColumn(tableName, attributeName, dataTypeOrOptions)
- renameColumn(tableName, attrNameBefore, attrNameAfter)
- addIndex(tableName, attributes, options)
- removeIndex(tableName, indexNameOrAttributes)
Request parsing and validation
var router = require("barbakoa").router;
var Joi = require("joi")
var idSchema = Joi.object().keys({
  id: Joi.number().integer().min(0).required()
});
router.get("/api/users/:id", function* () {
  var params = yield this.validateParams(idSchema);
  this.body = yield User.find(params.id)
});Methods:
- ctx.validateParams(schema): validates ctx.params
- ctx.validateQuery(schema): validates ctx.query
- ctx.validateBody(schema): validates ctx.body
Configuration¡
Barbakoa uses node-config
Events
barbakoa.on("post-start", function* () {
});Events:
- pre-start
- post-start
Gulp
Barbakoa comes with several gulp tasks defined.
Define your gulpfile like this to import these tasks
var gulp = require("gulp");
require("barbakoa/gulptasks")(gulp);Tasks:
- less: less + autoprefixer
- jade: client side templating
- es6: es6to5 transformation
- clean
- build
- default: clean + build
CLI
- barbakoa dev: Run app in dev mode. Gulp watch and nodemon for server restart
- barbakoa test: Run client and server test
- barbakoa test-client
- barbakoa test-server