1 /**
  2  * @fileOverview Channel Resource class definition
  3  */
  4 var Resource = require('./resource')
  5   , Message = require('./message')
  6   , Subscription = require('./subscription')
  7   ;
  8 
  9 /**
 10  * Represents a channel in the spire api.
 11  *
 12  * @class Channel Resource
 13  *
 14  * @constructor
 15  * @extends Resource
 16  * @param {object} spire Spire object
 17  * @param {object} data  Channel data from the spire api
 18  */
 19 function Channel(spire, data) {
 20   /**
 21    * Reference to spire object.
 22    */
 23   this.spire = spire;
 24 
 25   /**
 26    * Actual data from the spire.io api.
 27    */
 28   this.data = data;
 29 
 30   this.resourceName = 'channel';
 31 }
 32 
 33 Channel.prototype = new Resource();
 34 
 35 module.exports = Channel;
 36 
 37 /**
 38  * Returns the channel name.
 39  *
 40  * @returns {string} Channel name
 41  */
 42 Channel.prototype.name = function () {
 43   return this.data.name;
 44 };
 45 
 46 /**
 47  * Publishes a message to the channel.
 48  *
 49  * The messages can be a string, or any json'able object.
 50  *
 51  * @example
 52  * spire.channel('myChannel', function (err, channel) {
 53  *   channel.publish('hello world', function (err, message) {
 54  *     if (!err) {
 55  *       // Message has been published.
 56  *     }
 57  *   });
 58  * });
 59  *
 60  * @param {string|object} message Message to publish
 61  * @param {function (err, message)} cb Callback
 62  */
 63 Channel.prototype.publish = function (message, cb) {
 64   cb = cb || function (err) { if (err) { throw err; } };
 65   var spire = this.spire;
 66   this.request('publish', { content: message }, function (err, messageData) {
 67     if (err) return cb(err);
 68     cb(null, new Message(spire, messageData));
 69   });
 70 };
 71 
 72 /**
 73  * Gets a subscription to a channel, creating it if necessary.
 74  *
 75  * @example
 76  * spire.channel('myChannel', function (err, channel) {
 77  *   channel.subscription('mySubscription', function (err, subscription) {
 78  *     if (!err) {
 79  *       // `subscription` is the new subscription.
 80  *     }
 81  *   });
 82  * });
 83  *
 84  * @param {string} subName Subscription name
 85  * @param {function (err, subscription)} cb Callback
 86  */
 87 Channel.prototype.subscription = function (subName, cb) {
 88   if (!cb) {
 89     cb = subName;
 90     subName = null;
 91   }
 92   var spire = this.spire;
 93   this.request('create_subscription', subName, function (err, subData) {
 94     if (err) return cb(err);
 95     cb(null, new Subscription(spire, subData));
 96   });
 97 };
 98 
 99 /**
100  * Gets all named subscriptions to a channel, using cached data if available.
101  *
102  * @example
103  * channel.subscriptions(function (err, subscriptions) {
104 *   if (!err) {
105 *     // `subscriptions` is a hash of subscriptions
106 *   }
107  * });
108  *
109  * @param {function (err, subscriptions)} cb Callback
110  */
111 Channel.prototype.subscriptions = function (cb) {
112   if (this._subscriptions) {
113     return cb(null, this._subscriptions);
114   }
115   this.subscriptions$(cb);
116 };
117 
118 /**
119  * Gets all named subscriptions to a channel, ignoring any cached data.
120  *
121  * @example
122  * channel.subscriptions(function (err, subscriptions) {
123 *   if (!err) {
124 *     // `subscriptions` is a hash of subscriptions
125 *   }
126  * });
127  *
128  * @param {function (err, subscriptions)} cb Callback
129  */
130 Channel.prototype.subscriptions = function (cb) {
131   var channel = this;
132   this.request('subscriptions', function (err, subscriptions) {
133     if (err) return cb(err);
134     channel._subscriptions = subscriptions;
135     cb(null, subscriptions);
136   });
137 };
138 
139 /**
140  * Requests
141  *
142  * These define API calls and have no side effects.  They can be run by calling
143  *     this.request(<request name>);
144  */
145 
146 /**
147  * @name publish
148  * @ignore
149  * Publishes a message to the channel.
150  */
151 Resource.defineRequest(Channel.prototype, 'publish', function (message) {
152   return {
153     method: 'post',
154     url: this.url(),
155     headers: {
156       'Authorization': this.authorization('publish'),
157       'Accept': this.mediaType('message'),
158       'Content-Type': this.mediaType('message')
159     },
160     content: message
161   };
162 });
163 
164 /**
165  * @name subscriptions
166  * @ignore
167  * Gets all subscriptions for a channel.
168  */
169 Resource.defineRequest(Channel.prototype, 'subscriptions', function (message) {
170   var collection = this.data.resources.subscriptions;
171   return {
172     method: 'get',
173     url: collection.url,
174     headers: {
175       'Authorization': this.authorization('get_subscriptions', collection),
176       'Accept': this.mediaType('subscriptions'),
177     }
178   };
179 });
180 
181 /**
182  * @name create_subscription
183  * @ignore
184  * Create a subscription for the channel.
185  */
186 Resource.defineRequest(Channel.prototype, 'create_subscription', function (name) {
187   var collection = this.data.resources.subscriptions;
188   return {
189     method: 'post',
190     url: collection.url,
191     headers: {
192       'Authorization': this.authorization('create', collection),
193       'Accept': this.mediaType('subscription'),
194       'Content-Type': this.mediaType('subscription')
195     },
196     content: {name: name}
197   };
198 });
199