diff --git a/node.js/examples/create-a-database.js b/node.js/examples/create-a-database.js new file mode 100644 index 0000000..ae43e65 --- /dev/null +++ b/node.js/examples/create-a-database.js @@ -0,0 +1,18 @@ +var nj = require('../lib/client'), + fs = require('fs'); + +var client = nj.createClient({ + username: 'marak', + password: 'foofoo', + addonsUri: 'https://addons.nodejitsu.com', + remoteUri: 'https://api.nodejitsu.com' +}); + + +client.databases.create('new-database-55558', 'couch', function(err, result){ + if (err) { + console.log(err); + return; + } + console.log(result) +}); diff --git a/node.js/examples/get-a-database.js b/node.js/examples/get-a-database.js new file mode 100644 index 0000000..498d7e8 --- /dev/null +++ b/node.js/examples/get-a-database.js @@ -0,0 +1,18 @@ +var nj = require('../lib/client'), + fs = require('fs'); + +var client = nj.createClient({ + username: 'marak', + password: 'foofoo', + addonsUri: 'http://addons.nodejitsu.com', + remoteUri: 'http://api.nodejitsu.com' +}); + + +client.databases.get('new-database-55558', function(err, result){ + if (err) { + console.log(err); + return; + } + console.log(result) +}); diff --git a/node.js/lib/client/addons/index.js b/node.js/lib/client/addons/index.js new file mode 100644 index 0000000..b7999dd --- /dev/null +++ b/node.js/lib/client/addons/index.js @@ -0,0 +1,23 @@ +/* + * + * + */ + +var util = require('util'), + Client = require('../client').Client, + fs = require("fs"), + dr = require('director-reflector'), + defaultUser = require('../helpers').defaultUser; + +var Addons = exports.Addons = function (options) { + this.router = JSON.parse(fs.readFileSync(__dirname + '/router.json').toString()); + this.client = dr.createClient(this.router); + Client.call(this, options); +}; + +// Inherit from Client base object +util.inherits(Addons, Client); + +Addons.prototype.list = function (username, callback) { + callback(); +}; diff --git a/node.js/lib/client/addons/router.json b/node.js/lib/client/addons/router.json new file mode 100644 index 0000000..d4502fb --- /dev/null +++ b/node.js/lib/client/addons/router.json @@ -0,0 +1,103 @@ +{ + "routes": { + "get": [ + {}, + {} + ], + "users": { + "([._a-zA-Z0-9-]+)": { + "databases": { + "new": { + "post": {} + }, + "([._a-zA-Z0-9-]+)": { + "update": { + "post": {} + }, + "destroy": { + "post": {} + }, + "post": {}, + "get": {}, + "delete": {}, + "put": {} + }, + "get": {}, + "post": {} + }, + "dropboxes": { + "new": { + "post": {} + }, + "([._a-zA-Z0-9-]+)": { + "update": { + "post": {} + }, + "destroy": { + "post": {} + }, + "post": {}, + "get": {}, + "delete": {}, + "put": {} + }, + "get": {}, + "post": {} + }, + "update": { + "post": {} + }, + "destroy": { + "post": {} + }, + "post": {}, + "get": {}, + "delete": {}, + "put": {} + }, + "new": { + "post": {} + }, + "get": {}, + "post": {} + }, + "apps": { + "([._a-zA-Z0-9-]+)": { + "logs": { + "new": { + "post": {} + }, + "([._a-zA-Z0-9-]+)": { + "update": { + "post": {} + }, + "destroy": { + "post": {} + }, + "post": {}, + "get": {}, + "delete": {}, + "put": {} + }, + "get": {}, + "post": {} + }, + "update": { + "post": {} + }, + "destroy": { + "post": {} + }, + "post": {}, + "get": {}, + "delete": {}, + "put": {} + }, + "new": { + "post": {} + }, + "get": {}, + "post": {} + } + } +} \ No newline at end of file diff --git a/node.js/lib/client/apps.js b/node.js/lib/client/apps.js index bb95f59..051495d 100644 --- a/node.js/lib/client/apps.js +++ b/node.js/lib/client/apps.js @@ -43,7 +43,7 @@ Apps.prototype.list = function (username, callback) { // ### function create (app, callback) // #### @app {Object} Package.json manifest for the application. // #### @callback {function} Continuation to pass control to when complete -// Creates an application with the specified package.json manifest in `app`. +// Creates an application with the specified package.json manifest in `app`. // Apps.prototype.create = function (app, callback) { var appName = defaultUser.call(this, app.name); @@ -88,7 +88,7 @@ Apps.prototype.update = function (appName, attrs, callback) { // ### function destroy (appName, callback) // #### @appName {string} Name of the application to destroy // #### @callback {function} Continuation to pass control to when complete -// Destroys the application with `name` for the authenticated user. +// Destroys the application with `name` for the authenticated user. // Apps.prototype.destroy = function (appName, callback) { var appName = defaultUser.call(this, appName), @@ -103,7 +103,7 @@ Apps.prototype.destroy = function (appName, callback) { // ### function start (appName, callback) // #### @appName {string} Name of the application to start // #### @callback {function} Continuation to pass control to when complete -// Starts the application with `name` for the authenticated user. +// Starts the application with `name` for the authenticated user. // Apps.prototype.start = function (appName, callback) { var appName = defaultUser.call(this, appName), @@ -118,7 +118,7 @@ Apps.prototype.start = function (appName, callback) { // ### function restart (appName, callback) // #### @appName {string} Name of the application to start // #### @callback {function} Continuation to pass control to when complete -// Starts the application with `name` for the authenticated user. +// Starts the application with `name` for the authenticated user. // Apps.prototype.restart = function (appName, callback) { var appName = defaultUser.call(this, appName), @@ -133,7 +133,7 @@ Apps.prototype.restart = function (appName, callback) { // ### function stop (appName, callback) // #### @appName {string} Name of the application to stop. // #### @callback {function} Continuation to pass control to when complete -// Stops the application with `name` for the authenticated user. +// Stops the application with `name` for the authenticated user. // Apps.prototype.stop = function (appName, callback) { var appName = defaultUser.call(this, appName), @@ -148,7 +148,7 @@ Apps.prototype.stop = function (appName, callback) { // ### function available (app, callback) // #### @app {Object} Application to check availability against. // #### @callback {function} Continuation to respond to when complete. -// Checks the availability of the `app.name` / `app.subdomain` combo +// Checks the availability of the `app.name` / `app.subdomain` combo // in the current Nodejitsu environment. // Apps.prototype.available = function (app, callback) { diff --git a/node.js/lib/client/client.js b/node.js/lib/client/client.js index 27ec698..0b92033 100644 --- a/node.js/lib/client/client.js +++ b/node.js/lib/client/client.js @@ -7,6 +7,7 @@ var fs = require('fs'), request = require('request'), + dr = require('director-reflector'), util = require('util'), EventEmitter = require('events').EventEmitter, Client = require('./client').Client; @@ -18,15 +19,30 @@ var fs = require('fs'), // for communicating with Nodejitsu's API // var Client = exports.Client = function (options) { - this.options = options; - this._request = request; - if (typeof this.options.get !== 'function') { - this.options.get = function (key) { + var self = this; + + self.options = options; + self._request = request; + + if (typeof self.options.get !== 'function') { + self.options.get = function (key) { return this[key]; } } + // + // Create an additional client for the addons server + // + self.addons = {} + self.addons.router = JSON.parse(fs.readFileSync(__dirname + '/addons/router.json').toString()); + self.addons.client = dr.createClient(self.addons.router, { + uri: self.options.get('addonsUri'), + username: self.options.get('username'), + password: self.options.get('password'), + proxy: self.options.get('proxy') + }); + }; util.inherits(Client, EventEmitter); @@ -38,9 +54,9 @@ util.inherits(Client, EventEmitter); // #### @body {Object} **optional** JSON Request Body // #### @callback {function} Continuation to call if errors occur. // #### @success {function} Continuation to call upon successful transactions -// Makes a request to `this.remoteUri + uri` using `method` and any +// Makes a request to `this.remoteUri + uri` using `method` and any // `body` (JSON-only) if supplied. Short circuits to `callback` if the response -// code from Nodejitsu matches `failCodes`. +// code from Nodejitsu matches `failCodes`. // Client.prototype.request = function (method, uri /* variable arguments */) { var options, args = Array.prototype.slice.call(arguments), @@ -58,14 +74,14 @@ Client.prototype.request = function (method, uri /* variable arguments */) { 'Content-Type': 'application/json' } }; - + if (body) { options.body = JSON.stringify(body); - } + } else if (method !== 'GET') { options.body = '{}'; } - + if (proxy) { options.proxy = proxy; } @@ -111,13 +127,13 @@ Client.prototype.request = function (method, uri /* variable arguments */) { }; // -// ### function upload (uri, contentType, file, callback, success) +// ### function upload (uri, contentType, file, callback, success) // #### @uri {Array} Locator for the Remote Resource // #### @contentType {string} Content-Type header to use for the upload. -// #### @file {string} Path of the local file to upload. +// #### @file {string} Path of the local file to upload. // #### @success {function} Continuation to call upon successful transactions // #### @callback {function} Continuation to call if errors occur. -// Makes a `POST` request to `this.remoteUri + uri` with the data in `file` +// Makes a `POST` request to `this.remoteUri + uri` with the data in `file` // as the request body. Short circuits to `callback` if the response // code from Nodejitsu matches `failCodes`. // diff --git a/node.js/lib/client/databases.js b/node.js/lib/client/databases.js index a6f12ec..0ae4390 100644 --- a/node.js/lib/client/databases.js +++ b/node.js/lib/client/databases.js @@ -15,77 +15,88 @@ var util = require('util'), // with Nodejitsu's Databases API // var Databases = exports.Databases = function (options) { - Client = require('./client').Client;Client.call(this, options); + Client = require('./client').Client; + Client.call(this, options); }; // Inherit from Client base object util.inherits(Databases, Client); // -// ### function create (databaseType, databaseName, callback) +// ### function create (username, databaseType, databaseName, callback) +// #### @username {string} Username // #### @databaseType {string} Type of database to create, valid values: redis, couch, mongo // #### @databaseName {string} Name of the database to create // #### @callback {function} Continuation to pass control to when complete // Provisions a database for the user // -Databases.prototype.create = function (databaseType, databaseName, callback) { - this.request( - 'POST', - ['databases', this.options.get('username'), databaseName], - { type: databaseType }, - callback, - function (res, result) { - callback(null, result.database, res); - } - ); +Databases.prototype.create = function (username, databaseType, databaseName, callback) { + if (arguments.length == 3) { + callback = databaseName; + databaseName = databaseType; + databaseType = username; + username = this.options.get('username'); + } + + this.addons.client.users.databases.create(username, { + type: databaseType, + name: databaseName + }, function(err, res, body){ + callback(err, body); + }); }; // -// ### function get (databaseName, callback) +// ### function get (username, databaseName, callback) +// #### @username {String} Username // #### @databaseName {string} Name of the database to get // #### @callback {function} Continuation to pass control to when complete // Gets the metadata for the specified database // -Databases.prototype.get = function (databaseName, callback) { - this.request( - 'GET', - ['databases', this.options.get('username'), databaseName], - callback, - function (res, result) { - callback(null, result.database); - } - ); +Databases.prototype.get = function (username, databaseName, callback) { + if (arguments.length == 2) { + callback = databaseName; + databaseName = username; + username = this.options.get('username'); + } + + this.addons.client.users.databases.get(username, databaseName, function(err, res, body){ + callback(err, body); + }); }; // -// ### function list (callback) +// ### function list (username, callback) +// #### @username {String} Username // #### @callback {function} Continuation to pass control to when complete // Gets the list of databases assigned to the user // -Databases.prototype.list = function (callback) { - this.request( - 'GET', - ['databases', this.options.get('username')], - callback, - function (res, result) { - callback(null, result.databases); - } - ); +Databases.prototype.list = function (username, callback) { + if (arguments.length == 1) { + callback = username; + username = this.options.get('username'); + } + + this.addons.client.users.databases(username, function(err, res, body){ + callback(err, body); + }); }; // -// ### function destroy (databaseName, callback) +// ### function destroy (username, databaseName, callback) +// #### @username {String} Username // #### @databaseName {string} Name of the database to delete // #### @callback {function} Continuation to pass control to when complete // Deprovisions specified database // -Databases.prototype.destroy = function (databaseName, callback) { - this.request( - 'DELETE', - ['databases', this.options.get('username'), databaseName], - callback, - function (res, result) { - callback(null, result); - } - ); -} +Databases.prototype.destroy = function (username, databaseName, callback) { + if (arguments.length == 2) { + callback = databaseName; + databaseName = username; + username = this.options.get('username'); + } + + this.addons.client.users.databases.destroy(username, databaseName, function(err, res, body){ + callback(err, body); + }); +}; diff --git a/node.js/lib/client/keys.js b/node.js/lib/client/keys.js index 1a0153d..eff678f 100644 --- a/node.js/lib/client/keys.js +++ b/node.js/lib/client/keys.js @@ -4,11 +4,11 @@ * (C) 2010, Nodejitsu Inc. * */ - + var util = require('util'), Client = require('./client').Client, defaultUser = require('./helpers').defaultUser; - + // // ### function Keys (options) // #### @options {Object} Options for this instance @@ -38,7 +38,7 @@ Keys.prototype.list = function (username, callback) { }; // -// ### function create (key, callback) +// ### function create (key, callback) // #### @key {Object} Properties for the new key. // #### @callback {function} Continuation to pass control to when complete // Creates a new key with the properties specified by `key`. @@ -55,7 +55,7 @@ Keys.prototype.create = function (id, key, callback) { // -// ### function destroy (key, callback) +// ### function destroy (key, callback) // #### @key {Object} Properties for the new key. // #### @callback {function} Continuation to pass control to when complete // Creates a new key with the properties specified by `key`. diff --git a/node.js/lib/client/snapshots.js b/node.js/lib/client/snapshots.js index ca69a9a..c70993e 100644 --- a/node.js/lib/client/snapshots.js +++ b/node.js/lib/client/snapshots.js @@ -82,7 +82,7 @@ Snapshots.prototype.fetch = function (appName, snapshotName, callback) { // #### @appName {string} Name of the application to destroy a snapshot for. // #### @snapshotName {string} Name of the snapshot to destroy. // #### @callback {function} Continuation to pass control to when complete -// Destroys a snapshot for the application with `app.name = name` and +// Destroys a snapshot for the application with `app.name = name` and // `snapshot.id === snapshotName`. // Snapshots.prototype.destroy = function (appName, snapshotName, callback) { @@ -90,7 +90,7 @@ Snapshots.prototype.destroy = function (appName, snapshotName, callback) { argv = ['apps'] .concat(appName.split('/')) .concat(['snapshots', snapshotName]); - + this.request('DELETE', argv, callback, function (res, body) { callback(null, body || res.statusCode); }); @@ -101,7 +101,7 @@ Snapshots.prototype.destroy = function (appName, snapshotName, callback) { // #### @appName {string} Name of the application to activate a snapshot for. // #### @snapshotName {string} Name of the snapshot to activate. // #### @callback {function} Continuation to pass control to when complete -// Activates a snapshot for the application with `app.name = name` and +// Activates a snapshot for the application with `app.name = name` and // `snapshot.id === snapshotName`. // Snapshots.prototype.activate = function (appName, snapshotName, callback) { @@ -109,7 +109,7 @@ Snapshots.prototype.activate = function (appName, snapshotName, callback) { argv = ['apps'] .concat(appName.split('/')) .concat(['snapshots', snapshotName, 'activate']); - + this.request('POST', argv, callback, function (res, body) { callback(null, body || res.statusCode); }); diff --git a/node.js/lib/client/users.js b/node.js/lib/client/users.js index 65c3842..e8d1d89 100644 --- a/node.js/lib/client/users.js +++ b/node.js/lib/client/users.js @@ -4,11 +4,11 @@ * (C) 2010, Nodejitsu Inc. * */ - + var util = require('util'), Client = require('./client').Client, defaultUser = require('./helpers').defaultUser; - + // // ### function Users (options) // #### @options {Object} Options for this instance @@ -34,7 +34,7 @@ Users.prototype.auth = function (callback) { }; // -// ### function create (user, callback) +// ### function create (user, callback) // #### @user {Object} Properties for the new user. // #### @callback {function} Continuation to pass control to when complete // Creates a new user with the properties specified by `user`. @@ -46,7 +46,7 @@ Users.prototype.create = function (user, callback) { }; // -// ### function available (username, callback) +// ### function available (username, callback) // #### @username {string} Username to check availability for. // #### @callback {function} Continuation to pass control to when complete // Checks the availability of the specified `username`. @@ -82,7 +82,7 @@ Users.prototype.confirm = function (user, callback) { }; // -// ### function forgot (username, callback) +// ### function forgot (username, callback) // #### @username {Object} username requesting password reset. // #### @params {Object} Object containing shake and new password, if applicable. // #### @callback {function} Continuation to pass control to when complete diff --git a/node.js/test/commands/databases-test.js b/node.js/test/commands/databases-test.js index 7f68c43..6199fde 100644 --- a/node.js/test/commands/databases-test.js +++ b/node.js/test/commands/databases-test.js @@ -6,28 +6,28 @@ var vows = require('vows'), vows.describe('databases').addBatch(makeApiCall( 'databases create couch chair', function setup () { - nock('http://api.mockjitsu.com') + nock('http://addons.mockjitsu.com') .post('/databases/tester/chair', { type: 'couch'}) .reply(200, {}, { 'x-powered-by': 'Nodejitsu' }) } )).addBatch(makeApiCall( 'databases get chair', function setup () { - nock('http://api.mockjitsu.com') + nock('http://addons.mockjitsu.com') .get('/databases/tester/chair') .reply(200, {}, { 'x-powered-by': 'Nodejitsu' }) } )).addBatch(makeApiCall( 'databases list', function setup () { - nock('http://api.mockjitsu.com') + nock('http://addons.mockjitsu.com') .get('/databases/tester') .reply(200, {}, { 'x-powered-by': 'Nodejitsu' }) } )).addBatch(makeApiCall( 'databases destroy chair', function setup () { - nock('http://api.mockjitsu.com') + nock('http://addons.mockjitsu.com') .delete('/databases/tester/chair', {}) .reply(200, {}, { 'x-powered-by': 'Nodejitsu' }) } diff --git a/node.js/test/macros.js b/node.js/test/macros.js index 9f53afa..d7b2f0a 100644 --- a/node.js/test/macros.js +++ b/node.js/test/macros.js @@ -2,6 +2,7 @@ var createClient = require('../lib/client').createClient, client = createClient({ username: 'tester', password: 'password', + addonsUri: 'https://addons.mockjitsu.com', remoteUri: 'http://api.mockjitsu.com' }), assert = require('assert');