Documentation

Configuration

Project configuration options can be added to the kanso.json file in your project directory.

Example config

{
    "name": "myblog",
    "load": "lib/app",
    "modules": "lib",
    "templates": "templates",
    "attachments": "static"
}

App format

The format of the loaded module (usually lib/app.js, depending on the "load" setting in kanso.json) follows the format of a CouchDB design doc. Any exported property of this module will be added to the design doc generated for your app.

Kanso will occasionally extend the default design doc API by adding some additional properties which have a special meaning.

Init

The 'init' property is expected to be a function, and will be called on the initial page load, once the document is ready and the commonjs environment is available.

This property is optional and can be safely omitted. If you want to progressively enhance a fallback page returned by CouchDB on the first hit, or initialize some application state, this is the place to do it.

exports.init = function () {
    alert('initializing app');
};

Types

The 'types' property is used by the admin app to find types to show in the applications types list. It is also assumed to be the location of any custom types by the skeleton app's validation function.

It's a good idea to export your type definitions on this property to make them easy to re-use and compatible with the admin app.

exports.types = {
    example: new Type('example', {
        fields: {
            title: fields.string(),
            message: fields.string()
        }
    })
};

SessionChange

The 'sessionChange' property is expected to be a function and is called whenever a change to the user's session is detected (usually after calling login or logout from the session module).

A sessionChange event will also occur on the initial site load, as soon as the user's session details are available. This happens after the init method has fired and before the client-side rendering of the list, show or update function for that page.

Modules

Documentation for the builtin CommonJS modules distributed as part of Kanso. All modules in this section can be used in your own code by doing: require('kanso/<name>').

Cookies

Functions related to the reading and manipulation of cookies.

cookies.readBrowserCookies()

Read cookies currently stored in the browser, returning an object keyed by cookie name.

Returns: Object

cookies.readBrowserCookie(name)

Reads browser cookies and returned the value of the named cookie.

Parameters:
name String
Returns: String

cookies.cookieString(req, opt)

Creates a string for storing a cookie on the browser.

Parameters:
req Request Object
opt Object
Returns: String

cookies.setBrowserCookie(req, opt)

Sets a cookie on the browser, for use client-side only.

Parameters:
req Request Object
opt Object

cookies.setResponseCookie(req, res, opt)

Creates a Set-Cookie header on a response object.

Parameters:
req Request Object
res Response Object
opt Object

Core

The core module contains functions used by kanso to facilitate the running of your app. You shouldn't need to use any of the functions here directly unless you're messing with the internals of Kanso.

core.init()

Called by kanso.js once the design doc has been loaded. You should not need to call this directly.

core.rewriteGroups(pattern, url)

Extracts groups from a url, eg:

'/some/path' with pattern '/some/:name' -> {name: 'path'}
Parameters:
pattern String
url String
Returns: Object

core.rewriteSplat(pattern, url)

Extracts a splat value from a rewrite pattern and matching URL.

Parameters:
pattern String
url String
Returns: String

core.matchURL(method, url)

Attempts to match rewrite from patterns to a URL, returning the matching rewrite object if successful.

Parameters:
method String
url String
Returns: Object

core.replaceGroups(val, groups, splat)

Replace group names and splats in a string with the value of that group or splat, eg:

"/:name" with groups {name: 'test'} -> "/test"
Parameters:
val String
groups Object
splat String
Returns: String

core.createRequest(method, url, data, match, callback)

Creates a new request object from a url and matching rewrite object. Query parameters are automatically populated from rewrite pattern.

Parameters:
method String
url String
data Object
match Object
callback Function
Returns via callback: Request Object

core.runShowBrowser(req, name, docid, callback)

Fetches the relevant document and calls the named show function.

Parameters:
req Object
name String
docid String
callback Function

core.runUpdateBrowser(req, name, docid, callback)

Fetches the relevant document and calls the named update function.

Parameters:
req Object
name String
docid String
callback Function

core.createHead(data)

Creates a fake head object from view results for passing to a list function being run client-side.

Parameters:
data Object
Returns: Object

core.runListBrowser(req, name, view, callback)

Fetches the relevant view and calls the named list function with the results.

Parameters:
req Object
name String
view String
callback Function

core.handle(method, url, data)

Creates a request object for the url and runs appropriate show, list or update functions.

Parameters:
method String
url String
data Object

core.setURL(method, url, data, hash)

Add a history entry for the given url, prefixed with the baseURL for the app.

Parameters:
method String
url String
data Object (Optional)
hash String (Optional)

core.getURL()

Gets the current app-level URL (without baseURL prefix).

Returns: String

core.sameOrigin(a, b)

Tests is two urls are of the same origin. Accepts parsed url objects or strings as arguments.

Returns: Boolean

core.appPath(p)

Converts a full url to an app-level url (without baseURL prefix). example: {baseURL}/some/path -> /some/path

Parameters:
p String
Returns: String

core.isAppURL(url)

Used to decide whether to handle a link or not. Should detect app vs. external urls.

Parameters:
url String
Returns: Boolean

DB

Contains functions for querying and storing data in CouchDB.

db.request(options, callback)

Make a request, with some default settings and proper callback handling. Used behind-the-scenes by most other DB module functions.

Parameters:
options Object
callback Function

db.getDoc(id, q, callback)

Fetches a document from the database the app is running on. Results are passed to the callback, with the first argument of the callback reserved for any exceptions that occurred (node.js style).

Parameters:
id String
q Object
callback Function

db.saveDoc(doc, callback)

Saves a document to the database the app is running on. Results are passed to the callback, with the first argument of the callback reserved for any exceptions that occurred (node.js style).

Parameters:
doc Object
callback Function

db.removeDoc(doc, callback)

Deletes a document from the database the app is running on. Results are passed to the callback, with the first argument of the callback reserved for any exceptions that occurred (node.js style).

Parameters:
doc Object
callback Function

db.getView(view, q, callback)

Fetches a view from the database the app is running on. Results are passed to the callback, with the first argument of the callback reserved for any exceptions that occurred (node.js style).

Parameters:
view String
q Object
callback Function

db.all(q, callback)

Get all documents (including design docs).

Parameters:
q Object (Optional
callback Function

db.stringifyQuery(query)

Properly encodes query parameters to CouchDB views etc. Handle complex keys and other non-string parameters by passing through JSON.stringify. Returns a shallow-copied clone of the original query after complex values have been stringified.

Parameters:
query Object
Returns: Object

db.newUUID(cacheNum, callback)

Returns a new UUID generated by CouchDB. Its possible to cache multiple UUIDs for later use, to avoid making too many requests.

Parameters:
cacheNum Number (Optional) Default: 1
callback Function

Fields

The building blocks of Types and Forms, Fields help to validate and authorize changes to docuemnt values.

forms.Field(options)

Field objects are used when constructing content types and forms.

Constructor
Parameters:
options Object see below for available properties
Options:
omit_empty Boolean Whether to omit the field from a document when the field is empty
permissions Object A permissions check function or an object containing separate functions to run on create, edit and update operations.
validators Array An array of validation functions (default: [])
required Boolean Whether the field is required (default: true)
Returns: Field Object

Field.parse(raw)

Parses a raw value returning the correct JavaScript type for this field. This will usually be overridden by other field types.

Parameters:
raw

Field.isEmpty(value, raw)

Test values to see if field is considered empty.

This function accepts the raw value even though by default it only checks the parsed value, so that other field types overridding this method have the raw data available.

Parameters:
value The parsed value for the field
raw The raw value for the field
Returns: Boolean

Field.validate(doc, value, raw)

Run the field's validation functions against a value. Returns an array of validation errors, or an empty array if valid.

Parameters:
doc Object
value
raw
Returns: Array

Field.authorize(newDoc, oldDoc, newVal, oldVal, userCtx)

Check relevant field permissions to see if user is authorised to make changes. Returns an array of permissions errors, or an empty array if the changes are permissible.

Parameters:
newDoc Object
oldDoc Object
newVal
oldVal
userCtx Object
Returns: Array

fields.Embedded(options)

Embedded objects represent a Type embedded within another Type or set of Fields. Its not a true field, but like the Field constructor it acts as a marker when walking through the sub-objects that make up a schema.

Exposes the same methods as Field objects.

Constructor
Parameters:
options Object See below for available properties
Options:
type Type Object Required, the Type definition to embed
omit_empty Boolean Whether to omit the field from a document when the field is empty
permissions Object A permissions check function or an object containing separate functions to run on create, edit and update operations.
validators Array An array of validation functions (default: [])
required Boolean Whether the field is required (default: true)
Returns: Embedded Object

fields.EmbeddedList(options)

EmbeddedList objects represent multiple instances of a Type embedded within another Type or set of Fields. Its not a true field, but like the Field constructor it acts as a marker when walking through the sub-objects that make up a schema.

Exposes the same methods as Field objects.

Constructor
Parameters:
options Object See below for available properties
Options:
type Type Object Required, the Type definition to embed
omit_empty Boolean Whether to omit the field from a document when the field is empty
permissions Object A permissions check function or an object containing separate functions to run on create, edit and update operations.
validators Array An array of validation functions (default: [])
required Boolean Whether the field is required (default: true)
Returns: EmbeddedList Object

EmbeddedList.missingIDs(list)

Detects embedded documents with missing _id properties and returns an array of Error objects for each occurence. Returns an empty array if all documents have a populated _id property.

Parameters:
list Array
Returns: Array

EmbeddedList.duplicateIDs(list)

Detects embedded documents with duplicate _id properties and returns an array of Error objects for each occurence. Returns an empty array if all documents have a unique _id property.

Parameters:
list Array
Returns: Array

fields.string(options)

Creates a new string Field

Parameters:
options Object See the Field constructor for available options
Returns: Field Object

fields.number(options)

Creates a new number Field

Parameters:
options Object See the Field constructor for available options
Returns: Field Object

fields.boolean(options)

Creates a new boolean Field

Parameters:
options Object See the Field constructor for available options
Returns: Field Object

fields.url(options)

Creates a new URL Field

Parameters:
options Object See the Field constructor for available options
Returns: Field Object

fields.email(options)

Creates a new email Field

Parameters:
options Object See the Field constructor for available options
Returns: Field Object

fields.creator(options)

Creates a new creator Field

Parameters:
options Object See the Field constructor for available options
Returns: Field Object

fields.timestamp(options)

Creates a new timestamp Field

Parameters:
options Object See the Field constructor for available options
Returns: Field Object

fields.choice(options)

Creates a new choice Field

Required option: values - an array of possible choices, each an array with the first item as the value and the second as its label.

Parameters:
options Object See the Field constructor for available options
Returns: Field Object

fields.numberChoice(options)

Creates a new numberChoice Field

Required option: values - an array of possible choices, each an array with the first item as the value and the second as its label.

Parameters:
options Object See the Field constructor for available options
Returns: Field Object

fields.embed(options)

Creates a new Embedded Field

Required option: type - the Type definition to embed

Parameters:
options Object See the Field constructor for available options
Returns: Embedded Object

fields.embedList(options)

Creates a new EmbeddedList Field

Required option: type - the Type definition to embed

Parameters:
options Object See the Field constructor for available options
Returns: EmbeddedList Object

Flashmessages

Flash messages help you store state between requests, such as reporting a successful or failed operation after a redirect.

The flash message implementation in this module handles both fallback couchdb mode, using cookies to persist state between requests, as well as supporting client-side operation, correctly handling new messages even inside the callbacks of async functions.

Flash messages only persist for the next request or the next template render! That means 2 redirects without explicitly currying the flash messages will cause the messages to be lost.

flashmessages.readRequestCookie(req)

Reads the flash messages cookie from a request object, returning an array of incoming messages.

Parameters:
req Object
Returns: Array

flashmessages.readBrowserCookie()

Reads the flash messages cookie from the browser, returning an array of incoming messages.

Returns: Array

flashmessages.updateRequest(req)

Adds a flash_messages property to a request containing all incoming messages.

Parameters:
req Object
Returns: Request Object

flashmessages.getMessages(req)

Get's all current flash messages, stopping them from being outgoing on the next request so they're not repeated.

Parameters:
req Object
Returns: Array

flashmessage.getOutgoingMessages(req)

Filters all available messages on a request object, returning only those flagged as outgoing (sending in the response to be made available to the next request).

Parameters:
req Object
Returns: Array

flashmessage.updateResponse(req, res)

Updates a response object after a list, show or update function has returned, setting the flash messages cookie to include the outgoing messages.

Parameters:
req Object
res Object
Returns: Response Object

flashmessages.createMessage(req, msg)

Creates a new flash message object, associating it with the given request.

Parameters:
req Object
msg String
Returns: Object

flashmessages.setBrowserCookie(req, messages)

Stores a list of messages in the flash messages cookie. This function is for client-side use.

Parameters:
req Object
messages Array

flashmessages.addMessage(req, msg)

Adds a new flash message for the current request. If the list, show or update function has not returned, it's added to the response Set-Cookie header, otherwise (if its the result of a client-side async operation) it's added directly to the browsers cookies.

Parameters:
req Object
msg String

Permissions

Used on both Fields and Types to check a given user is authorized to make a change to a document.

permissions.matchUsername()

Field's new value should match current user's name

Returns: Function

permissions.hasRole(role)

Checks if the user has a specific role

Parameters:
role String
Returns: Function

permissions.fieldUneditable()

The value of this field should never change after the document has been created.

Returns: Function

permissions.usernameMatchesField(path)

User's name should match the *old* value of the given field. A field can be specified using a string or an array of strings (like a path), eg:

usernameMatchesField('creator')
usernameMatchesField(['meta','creator'])
 
{
    creator: 'name',
    meta: {creator: 'name2'}
}
Parameters:
path
Returns: Function

permissions.loggedIn()

Checks that user's context has a username

Returns: Function

permissions.all(perms)

Runs an array of permissions functions and checks that all of them pass, returning all failures.

Parameters:
perms Array
Returns: Function

permissions.any(perms)

Tests to see if any one permission function passes, returning on the first success. If all permissions fail, then all errors are returned.

Parameters:
perms Array
Returns: Function

permissions.inherit(type)

Treat new and old values like new documents of a given type, and attempt to authorize the value against the type's permissions. Useful when handling permissions for an embedded type.

Can be combined with permissions.any or permissions.all to extend the permissions for an embedded type field. For example, the following might allow both the owner of the parent document and the owner of the comment itself to remove it.

comment: fields.embed({
    type: types.comment,
    permissions: {
        remove: permissions.any([
            permissions.usernameMatchesField('creator'),
            permissions.inherit(types.comment)
        ])
    }
});
Parameters:
type Type Object
Returns: Function

Session

Functions related to the management of user sessions and account information.

session.fakeRequest(userCtx, callback)

Creates a fake request to /_session to pass to sessionChange, useful when using functions such as templates.render

Parameters:
userCtx Object
callback Function

session.sessionChange(userCtx, callback)

Calls sessionChange if exported from the currently loaded app.

Parameters:
userCtx Object
callback Function

session.logout(callback)

Logs out the current user.

Parameters:
callback Function

session.login(username, password, callback)

Attempt to login using the username and password provided.

Parameters:
username String
password String
callback Function

session.info(callback)

Returns the current user's session information.

Parameters:
callback Function

session.userDb(callback)

Returns the authentication database for the current user's session.

Parameters:
callback Function

session.signup(username, password, callback)

Creates a new user document with given username and password.

Parameters:
username String
password String
callback Function

Templates

Kanso uses Dust templates for rendering pages. To learn more about the syntax, see the Dust site.

Since Dust stores compiled templates on the module itself, the templates module does some interesting things to work around the lack of a module cache in CouchDB. Because of this, compiled templates are automatically added to this module from your templates folder each time your app is pushed to CouchDB. You can see a list of the loaded template names on the 'loaded' property of this module.

templates.render(name, req, context)

Synchronously render dust template and return result, automatically adding baseURL to the template's context. The request object is required so we can determine the value of baseURL.

Parameters:
name String
req Request Object
context Object
Returns: String

Types

Document types can be used to ease the validation of updates and check permissions when creating, editing or deleting documents.

types.Type(name, options)

Creates a new Type object

constructor
Parameters:
options Object see below for available properties
Options:
fields Object Field objects to use as the Type's schema
permissions Object a permissions check function or an object containing separate functions to run on add, remove and update operations
Returns: Type Object

Type.validate(doc, rawDoc)

Run field validators against document and check for missing required fields or extra fields when the Types's allow_extra_fields property is set to false.

Parameters:
doc Object
rawDoc Object
Returns: Array

Type.authorize(nDoc, oDoc, user)

Run field permissions checks against userCtx and document.

Parameters:
nDoc Object new document
oDoc Object old document
userCtx Object user context object
Returns: Array

Type.authField(f, nDoc, oDoc, nVal, oVal, user, path)

Authorize a specific field, returning all permissions errors as an array with each error's field property prefixed by the current path.

Parameters:
f Field field object
nDoc Object new document
oDoc Object old document
nVal new field value
oVal old field value
user Object user context object
path Array current path
Returns: Array

Type.authFieldSet(f, nDoc, oDoc, nVal, oVal, user, path)

Authorizes an object containing fields or other sub-objects, iterating over each property and recursing through sub-objects to find all Fields.

Returns an array of permissions errors, each with a field property set to the path of the field which caused the error.

Parameters:
f Field field object
nDoc Object new document
oDoc Object old document
nVal new field value
oVal old field value
user Object user context object
path Array current path
Returns: Array

Type.create(userCtx, callback)

Create's a new object for this Type. Pre-filling any default values and providing a new _id value. This is a convenient funciton to use when creating a type to embed within another.

Parameters:
userCtx Object
callback Function

types.validate_doc_update(types, newDoc, oldDoc, userCtx)

Calls validation and permissions functions relevant to a document update. This should be called from your app's exported validate_doc_update function if you wish to use kanso Types in you project.

Throws on error.

Parameters:
types Object
newDoc Object
oldDoc Object
userCtx Object

Utils

General utility functions used by Kanso. Some functions were moved here from other modules (such as core), to avoid a circular dependency bug in CouchDB.

Utils properties

The utils module exports some useful properties you may want to use inside your own functions:

isBrowser Boolean whether or not the current code is running in the browser (not in CouchDB)
initial_hit Boolean set to true when the page is first loaded from CouchDB
userCtx Object stores cached user context information (username etc)
session Object stores cached extended user session info

utils.getBaseURL(req)

Returns the path to prefix to any URLs. When running behind a virtual host, there is nothing to prefix URLs with. When accessing the app directly, URLs need to be prefixed with /db/_design/appname/_rewrite.

The request object argument is only required when run server-side.

Parameters:
req Object
Returns: String

utils.getPropertyPath(obj, path)

Traverses an object and its sub-objects using an array of property names. Returns the value of the matched path, or undefined if the property does not exist.

getPropertyPath({a: {b: 'foo'}}, ['a','b']) -> 'foo'
Parameters:
obj Object
path Array

utils.setPropertyPath(obj, path, val)

Traverses an object and its sub-objects using an array of property names. Sets the value of the matched property.

setPropertyPath({}, ['a','b'], 'foo') -> {a: {b: 'foo'}}
Parameters:
obj Object
path Array
val

utils.constructorName(obj)

Returns the name of the constructor function for an object. This is used as a workaround for CouchDB's lack of a module cache, where instanceof checks can break if a module is re-eval'd.

Parameters:
obj Object
Returns: String

utils.getErrors(fn, args)

Call function with arguments, catch any errors and add to an array, returning the modified array.

Parameters:
arr Array
fn Function
args Array
Returns: Array

Validators

Validation functions used to validate Field contents.

validators.min(min)

Tests that the field's value is greater than 'min'.

Parameters:
min Number
Returns: Function

validators.max(max)

Tests that the field's value is less than 'max'

Parameters:
max Number
Returns: Function

validators.range(min, max)

Tests that the field's value is greater than 'min' AND less than 'max'

Parameters:
min Number
max Number
Returns: Function

validators.minlength(val)

Tests that the field's value length is greater than 'val'

Parameters:
val Number
Returns: Function

validators.maxlength(val)

Tests that the field's value length is less than 'val'

Parameters:
val Number
Returns: Function

validators.rangelength(min, max)

Tests that the field's value length is greater than 'min' AND less than 'max'

Parameters:
min Number
max Number
Returns: Function

validators.regexp(re, message)

Tests field's value against a regular expression

Parameters:
re RegExp can be a string or a RegExp object
message String (Optional) a custom error message to throw
Returns: Function

validators.email()

Tests that field's value is a valid email address using a regular expression.

Returns: Function

validators.url()

Tests that field's value is a valid URL using a regular expression.

Returns: Function

validators.missingIDs()

Detects embedded documents with missing _id properties and returns an array of Error objects for each occurence. Returns an empty array if all documents have a populated _id property.

Used by the EmbeddedList field type.

Returns: Function

Widgets

Widgets define the way a Field object is displayed when rendered as part of a Form. Changing a Field's widget will be reflected in the admin app.

widgets.Widget(type, options)

Widget constructor, creates a new Widget object.

constructor
Parameters:
type String
options Object
Options:
classes Array classes to add to the HTML element
id String id to use for the HTML element
Returns: Widget Object

Widget.toHTML(name, value, raw)

Converts a widget to HTML using the provided name and parsed and raw values

Parameters:
name String
value
raw
Returns: String

widgets.text(options)

Creates a new text input widget.

Parameters:
options Object
Returns: Widget Object

widgets.password(options)

Creates a new password input widget.

Parameters:
options Object
Returns: Widget Object

widgets.hidden(options)

Creates a new hidden input widget.

Parameters:
options Object
Returns: Widget Object

widgets.textarea(options)

Creates a new textarea input widget.

Parameters:
options Object
Returns: Widget Object

widgets.checkbox(options)

Creates a new checkboxinput widget.

Parameters:
options Object
Returns: Widget Object

widgets.select(options)

Creates a new select input widget.

Parameters:
options Object
Returns: Widget Object

Commands

Typing 'kanso' with no arguments will present you with a list of available commands. More information can be found by typing 'kanso help' optionally followed by the name of the command you need help with.

Push

Upload a project to a CouchDB instance.

kanso push [OPTIONS] DB [PATH]

  Parameters:
    DB     The CouchDB instance to upload the app to
    PATH   The project path to load the app from

  Options:
    --minify               Compress CommonJS modules using UglifyJS
    --minify-attachments   Compress .js attachments
    --baseURL PATH         Force the baseURL to a specific value.
                           (allows vhosts on CouchDB < v1.1.x)
  

Pushdata

Push a file or directory of JSON files to DB.

kanso pushdata [OPTIONS] DB PATH

  Parameters:
    DB     The CouchDB instance to upload the documents to
    PATH   A file or directory containing JSON documents to upload

  Options:
    -f, --force      Ignore document conflict errors and upload anyway
  

Pushadmin

Upload the kanso admin app to a CouchDB instance.

kanso pushadmin [OPTIONS] DB

Parameters:
  DB     The CouchDB instance to upload the app to

Options:
  --minify               Compress CommonJS modules using UglifyJS
  --minify-attachments   Compress .js attachments
  --baseURL PATH         Force the baseURL to a specific value.
                         (allows vhosts on CouchDB < v1.1.x)

Create

Create a new project skeleton.

kanso create PATH

  Parameters:
    PATH     Path to create a new project skeleton at, project name
             defaults to last directory in this path
  

Help

Show help specific to a command.

kanso help [COMMAND]

  Parameters:
    COMMAND      The kanso command to show help on
  

Show

Load a project and output resulting JSON

kanso show [PATH]

  Parameters:
    PATH     Path to project directory to show (defaults to ".")
  

UUIDs

Returns UUIDs generated by a CouchDB instance.

kanso uuids [OPTIONS] [URL]

  Parameters:
    URL         The CouchDB instance to generate UUIDs from
                (defaults to http://localhost:5984)

  Options:
    -n [NUM], --number [NUM]    The number of UUIDs to generate (default: 1)