jsforce2 1.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +74 -0
  3. package/bin/jsforce +3 -0
  4. package/bower.json +30 -0
  5. package/build/jsforce-api-analytics.js +393 -0
  6. package/build/jsforce-api-analytics.min.js +2 -0
  7. package/build/jsforce-api-analytics.min.js.map +1 -0
  8. package/build/jsforce-api-apex.js +183 -0
  9. package/build/jsforce-api-apex.min.js +2 -0
  10. package/build/jsforce-api-apex.min.js.map +1 -0
  11. package/build/jsforce-api-bulk.js +1054 -0
  12. package/build/jsforce-api-bulk.min.js +2 -0
  13. package/build/jsforce-api-bulk.min.js.map +1 -0
  14. package/build/jsforce-api-chatter.js +320 -0
  15. package/build/jsforce-api-chatter.min.js +2 -0
  16. package/build/jsforce-api-chatter.min.js.map +1 -0
  17. package/build/jsforce-api-metadata.js +3020 -0
  18. package/build/jsforce-api-metadata.min.js +2 -0
  19. package/build/jsforce-api-metadata.min.js.map +1 -0
  20. package/build/jsforce-api-soap.js +403 -0
  21. package/build/jsforce-api-soap.min.js +2 -0
  22. package/build/jsforce-api-soap.min.js.map +1 -0
  23. package/build/jsforce-api-streaming.js +3479 -0
  24. package/build/jsforce-api-streaming.min.js +2 -0
  25. package/build/jsforce-api-streaming.min.js.map +1 -0
  26. package/build/jsforce-api-tooling.js +319 -0
  27. package/build/jsforce-api-tooling.min.js +2 -0
  28. package/build/jsforce-api-tooling.min.js.map +1 -0
  29. package/build/jsforce-core.js +25250 -0
  30. package/build/jsforce-core.min.js +2 -0
  31. package/build/jsforce-core.min.js.map +1 -0
  32. package/build/jsforce.js +31637 -0
  33. package/build/jsforce.min.js +2 -0
  34. package/build/jsforce.min.js.map +1 -0
  35. package/core.js +1 -0
  36. package/index.js +1 -0
  37. package/lib/VERSION.js +2 -0
  38. package/lib/_required.js +29 -0
  39. package/lib/api/analytics.js +387 -0
  40. package/lib/api/apex.js +177 -0
  41. package/lib/api/bulk.js +862 -0
  42. package/lib/api/chatter.js +314 -0
  43. package/lib/api/index.js +8 -0
  44. package/lib/api/metadata.js +848 -0
  45. package/lib/api/soap.js +397 -0
  46. package/lib/api/streaming-extension.js +136 -0
  47. package/lib/api/streaming.js +270 -0
  48. package/lib/api/tooling.js +313 -0
  49. package/lib/browser/canvas.js +90 -0
  50. package/lib/browser/client.js +241 -0
  51. package/lib/browser/core.js +5 -0
  52. package/lib/browser/jsforce.js +6 -0
  53. package/lib/browser/jsonp.js +52 -0
  54. package/lib/browser/request.js +70 -0
  55. package/lib/cache.js +252 -0
  56. package/lib/cli/cli.js +431 -0
  57. package/lib/cli/repl.js +337 -0
  58. package/lib/connection.js +1881 -0
  59. package/lib/core.js +16 -0
  60. package/lib/csv.js +50 -0
  61. package/lib/date.js +163 -0
  62. package/lib/http-api.js +300 -0
  63. package/lib/jsforce.js +10 -0
  64. package/lib/logger.js +52 -0
  65. package/lib/oauth2.js +206 -0
  66. package/lib/process.js +275 -0
  67. package/lib/promise.js +164 -0
  68. package/lib/query.js +881 -0
  69. package/lib/quick-action.js +90 -0
  70. package/lib/record-stream.js +305 -0
  71. package/lib/record.js +107 -0
  72. package/lib/registry/file-registry.js +48 -0
  73. package/lib/registry/index.js +3 -0
  74. package/lib/registry/registry.js +111 -0
  75. package/lib/require.js +14 -0
  76. package/lib/soap.js +207 -0
  77. package/lib/sobject.js +558 -0
  78. package/lib/soql-builder.js +236 -0
  79. package/lib/transport.js +233 -0
  80. package/package.json +110 -0
@@ -0,0 +1,241 @@
1
+ /**
2
+ * @file Browser client connection management class
3
+ * @author Shinichi Tomita <shinichi.tomita@gmail.com>
4
+ */
5
+
6
+ 'use strict';
7
+
8
+ var events = require('events'),
9
+ inherits = require('inherits'),
10
+ qs = require('querystring'),
11
+ _ = require('lodash/core'),
12
+ Connection = require('../connection'),
13
+ OAuth2 = require('../oauth2');
14
+
15
+ /**
16
+ * @private
17
+ */
18
+ function popupWin(url, w, h) {
19
+ var left = (screen.width/2)-(w/2);
20
+ var top = (screen.height/2)-(h/2);
21
+ return window.open(url, null, 'location=yes,toolbar=no,status=no,menubar=no,width='+w+',height='+h+',top='+top+',left='+left);
22
+ }
23
+
24
+ function handleCallbackResponse() {
25
+ var res = checkCallbackResponse();
26
+ var state = localStorage.getItem('jsforce_state');
27
+ if (res && state && res.body.state === state) {
28
+ localStorage.removeItem('jsforce_state');
29
+ var states = state.split('.');
30
+ var prefix = states[0], promptType = states[1];
31
+ var cli = new Client(prefix);
32
+ if (res.success) {
33
+ cli._storeTokens(res.body);
34
+ location.hash = '';
35
+ } else {
36
+ cli._storeError(res.body);
37
+ }
38
+ if (promptType === 'popup') { window.close(); }
39
+ return true;
40
+ }
41
+ }
42
+
43
+ /**
44
+ * @private
45
+ */
46
+ function checkCallbackResponse() {
47
+ var params;
48
+ if (window.location.hash) {
49
+ params = qs.parse(window.location.hash.substring(1));
50
+ if (params.access_token) {
51
+ return { success: true, body: params };
52
+ }
53
+ } else if (window.location.search) {
54
+ params = qs.parse(window.location.search.substring(1));
55
+ if (params.error) {
56
+ return { success: false, body: params };
57
+ }
58
+ }
59
+ }
60
+
61
+ /** @private **/
62
+ var clientIdx = 0;
63
+
64
+
65
+ /**
66
+ * @class
67
+ * @todo add document
68
+ */
69
+ var Client = function(prefix) {
70
+ this._prefix = prefix || 'jsforce' + clientIdx++;
71
+ this.connection = null;
72
+ };
73
+
74
+ inherits(Client, events.EventEmitter);
75
+
76
+ /**
77
+ *
78
+ */
79
+ Client.prototype.init = function(config) {
80
+ if (handleCallbackResponse()) { return; }
81
+ this.config = config;
82
+ this.connection = new Connection(config);
83
+ var tokens = this._getTokens();
84
+ if (tokens) {
85
+ this.connection.initialize(tokens);
86
+ var self = this;
87
+ setTimeout(function() {
88
+ self.emit('connect', self.connection);
89
+ }, 10);
90
+ }
91
+ };
92
+
93
+ /**
94
+ *
95
+ */
96
+ Client.prototype.login = function(options, callback) {
97
+ if (_.isFunction(options)) {
98
+ callback = options;
99
+ options = {};
100
+ }
101
+ options = options || {};
102
+ callback = callback || function(){ };
103
+ _.extend(options, this.config);
104
+ var self = this;
105
+ this._prompt(options, callback);
106
+ };
107
+
108
+
109
+ Client.prototype._prompt = function(options, callback) {
110
+ var self = this;
111
+ var oauth2 = new OAuth2(options);
112
+ var rand = Math.random().toString(36).substring(2);
113
+ var state = [ this._prefix, "popup", rand ].join('.');
114
+ localStorage.setItem("jsforce_state", state);
115
+ var authzUrl = oauth2.getAuthorizationUrl({
116
+ response_type: 'token',
117
+ scope : options.scope,
118
+ state: state
119
+ });
120
+ var size = options.size || {};
121
+ var pw = popupWin(authzUrl, size.width || 912, size.height || 513);
122
+ if (!pw) {
123
+ state = [ this._prefix, "redirect", rand ].join('.');
124
+ localStorage.setItem("jsforce_state", state);
125
+ authzUrl = oauth2.getAuthorizationUrl({
126
+ response_type: 'token',
127
+ scope : options.scope,
128
+ state: state
129
+ });
130
+ location.href = authzUrl;
131
+ return;
132
+ }
133
+ self._removeTokens();
134
+ var pid = setInterval(function() {
135
+ try {
136
+ if (!pw || pw.closed) {
137
+ clearInterval(pid);
138
+ var tokens = self._getTokens();
139
+ if (tokens) {
140
+ self.connection.initialize(tokens);
141
+ self.emit('connect', self.connection);
142
+ callback(null, { status: 'connect' });
143
+ } else {
144
+ var err = self._getError();
145
+ if (err) {
146
+ callback(new Error(err.error + ": " + err.error_description));
147
+ } else {
148
+ callback(null, { status: 'cancel' });
149
+ }
150
+ }
151
+ }
152
+ } catch(e) {}
153
+ }, 1000);
154
+ };
155
+
156
+ /**
157
+ *
158
+ */
159
+ Client.prototype.isLoggedIn = function() {
160
+ return !!(this.connection && this.connection.accessToken);
161
+ };
162
+
163
+ /**
164
+ *
165
+ */
166
+ Client.prototype.logout = function() {
167
+ this.connection.logout();
168
+ this._removeTokens();
169
+ this.emit('disconnect');
170
+ };
171
+
172
+ /**
173
+ * @private
174
+ */
175
+ Client.prototype._getTokens = function() {
176
+ var regexp = new RegExp("(^|;\\s*)"+this._prefix+"_loggedin=true(;|$)");
177
+ if (document.cookie.match(regexp)) {
178
+ var issuedAt = Number(localStorage.getItem(this._prefix+'_issued_at'));
179
+ if (Date.now() < issuedAt + 2 * 60 * 60 * 1000) { // 2 hours
180
+ var userInfo;
181
+ var idUrl = localStorage.getItem(this._prefix + '_id');
182
+ if (idUrl) {
183
+ var ids = idUrl.split('/');
184
+ userInfo = { id: ids.pop(), organizationId: ids.pop(), url: idUrl };
185
+ }
186
+ return {
187
+ accessToken: localStorage.getItem(this._prefix + '_access_token'),
188
+ instanceUrl: localStorage.getItem(this._prefix + '_instance_url'),
189
+ userInfo: userInfo
190
+ };
191
+ }
192
+ }
193
+ return null;
194
+ };
195
+
196
+ /**
197
+ * @private
198
+ */
199
+ Client.prototype._storeTokens = function(params) {
200
+ localStorage.setItem(this._prefix + '_access_token', params.access_token);
201
+ localStorage.setItem(this._prefix + '_instance_url', params.instance_url);
202
+ localStorage.setItem(this._prefix + '_issued_at', params.issued_at);
203
+ localStorage.setItem(this._prefix + '_id', params.id);
204
+ document.cookie = this._prefix + '_loggedin=true;';
205
+ };
206
+
207
+ /**
208
+ * @private
209
+ */
210
+ Client.prototype._removeTokens = function() {
211
+ localStorage.removeItem(this._prefix + '_access_token');
212
+ localStorage.removeItem(this._prefix + '_instance_url');
213
+ localStorage.removeItem(this._prefix + '_issued_at');
214
+ localStorage.removeItem(this._prefix + '_id');
215
+ document.cookie = this._prefix + '_loggedin=';
216
+ };
217
+
218
+ /**
219
+ * @private
220
+ */
221
+ Client.prototype._getError = function() {
222
+ try {
223
+ var err = JSON.parse(localStorage.getItem(this._prefix + '_error'));
224
+ localStorage.removeItem(this._prefix + '_error');
225
+ return err;
226
+ } catch(e) {}
227
+ };
228
+
229
+ /**
230
+ * @private
231
+ */
232
+ Client.prototype._storeError = function(err) {
233
+ localStorage.setItem(this._prefix + '_error', JSON.stringify(err));
234
+ };
235
+
236
+ /**
237
+ *
238
+ */
239
+ module.exports = new Client();
240
+
241
+ module.exports.Client = Client;
@@ -0,0 +1,5 @@
1
+ 'use strict';
2
+
3
+ var jsforce = require('../core');
4
+ jsforce.browser = require('./client');
5
+ module.exports = jsforce;
@@ -0,0 +1,6 @@
1
+ 'use strict';
2
+
3
+ var jsforce = require('../core');
4
+ jsforce.browser = require('./client');
5
+ require('../api');
6
+ module.exports = jsforce;
@@ -0,0 +1,52 @@
1
+ /*global window, document */
2
+ 'use strict';
3
+
4
+ var _index = 0;
5
+
6
+ module.exports = {
7
+
8
+ supported: typeof window !== 'undefined' && typeof document !== 'undefined',
9
+
10
+ createRequest: function(jsonpParam, timeout) {
11
+ jsonpParam = jsonpParam || 'callback';
12
+ timeout = timeout || 10000;
13
+
14
+ return function(params, callback) {
15
+ if (params.method.toUpperCase() !== 'GET') {
16
+ return callback(new Error('JSONP only supports GET request.'));
17
+ }
18
+ var cbFuncName = '_jsforce_jsonpCallback_' + (++_index);
19
+ var callbacks = window;
20
+ var url = params.url;
21
+ url += url.indexOf('?')>0 ? '&' : '?';
22
+ url += jsonpParam + '=' + cbFuncName;
23
+
24
+ var script = document.createElement('script');
25
+ script.type = 'text/javascript';
26
+ script.src = url;
27
+ document.documentElement.appendChild(script);
28
+
29
+ var pid = setTimeout(function() {
30
+ cleanup();
31
+ callback(new Error("JSONP call time out."));
32
+ }, timeout);
33
+
34
+ callbacks[cbFuncName] = function(res) {
35
+ cleanup();
36
+ callback(null, {
37
+ statusCode: 200,
38
+ headers: { "content-type": "application/json" },
39
+ body: JSON.stringify(res)
40
+ });
41
+ };
42
+
43
+ var cleanup = function() {
44
+ clearTimeout(pid);
45
+ document.documentElement.removeChild(script);
46
+ delete callbacks[cbFuncName];
47
+ };
48
+ };
49
+
50
+ }
51
+
52
+ };
@@ -0,0 +1,70 @@
1
+ 'use strict';
2
+
3
+ var Duplex = require('readable-stream').Duplex;
4
+ var _ = require('lodash/core');
5
+
6
+ module.exports = function(params, callback) {
7
+ var xhr = new XMLHttpRequest();
8
+ xhr.open(params.method, params.url);
9
+ if (params.headers) {
10
+ for (var header in params.headers) {
11
+ xhr.setRequestHeader(header, params.headers[header]);
12
+ }
13
+ }
14
+ xhr.setRequestHeader("Accept", "*/*");
15
+ var response;
16
+ var str = new Duplex();
17
+ str._read = function(size) {
18
+ if (response) {
19
+ str.push(response.body);
20
+ }
21
+ };
22
+ var bufs = [];
23
+ var sent = false;
24
+ str._write = function(chunk, encoding, callback) {
25
+ bufs.push(chunk.toString(encoding === "buffer" ? "binary" : encoding));
26
+ callback();
27
+ };
28
+ str.on('finish', function() {
29
+ if (!sent) {
30
+ xhr.send(bufs.join(''));
31
+ sent = true;
32
+ }
33
+ });
34
+ if (params.body || params.body === "" || !/^(put|post|patch)$/i.test(params.method)) {
35
+ xhr.send(params.body);
36
+ sent = true;
37
+ }
38
+ xhr.onreadystatechange = function() {
39
+ if (xhr.readyState === 4) {
40
+ var headerNames = getResponseHeaderNames(xhr);
41
+ var headers = {};
42
+ _.forEach(headerNames, function(headerName) {
43
+ if (headerName) {
44
+ headers[headerName] = xhr.getResponseHeader(headerName);
45
+ }
46
+ });
47
+ response = {
48
+ statusCode: xhr.status,
49
+ headers: headers,
50
+ body: xhr.response
51
+ };
52
+ if (!response.statusCode) {
53
+ response.statusCode = 400;
54
+ response.body = "Access Declined";
55
+ }
56
+ if (callback) {
57
+ callback(null, response, response.body);
58
+ }
59
+ str.end();
60
+ }
61
+ };
62
+ return str;
63
+ };
64
+
65
+ function getResponseHeaderNames(xhr) {
66
+ var headerLines = (xhr.getAllResponseHeaders() || "").split(/[\r\n]+/);
67
+ return _.map(headerLines, function(headerLine) {
68
+ return headerLine.split(/\s*:/)[0].toLowerCase();
69
+ });
70
+ }
package/lib/cache.js ADDED
@@ -0,0 +1,252 @@
1
+ /**
2
+ * @file Manages asynchronous method response cache
3
+ * @author Shinichi Tomita <shinichi.tomita@gmail.com>
4
+ */
5
+
6
+ 'use strict';
7
+
8
+ var events = require('events'),
9
+ inherits = require('inherits'),
10
+ _ = require('lodash/core');
11
+
12
+ /**
13
+ * Class for managing cache entry
14
+ *
15
+ * @private
16
+ * @class
17
+ * @constructor
18
+ * @template T
19
+ */
20
+ var CacheEntry = function() {
21
+ this.fetching = false;
22
+ };
23
+
24
+ inherits(CacheEntry, events.EventEmitter);
25
+
26
+ /**
27
+ * Get value in the cache entry
28
+ *
29
+ * @param {Callback.<T>} [callback] - Callback function callbacked the cache entry updated
30
+ * @returns {T|undefined}
31
+ */
32
+ CacheEntry.prototype.get = function(callback) {
33
+ if (!callback) {
34
+ return this._value;
35
+ } else {
36
+ this.once('value', callback);
37
+ if (!_.isUndefined(this._value)) {
38
+ this.emit('value', this._value);
39
+ }
40
+ }
41
+ };
42
+
43
+ /**
44
+ * Set value in the cache entry
45
+ *
46
+ * @param {T} [value] - A value for caching
47
+ */
48
+ CacheEntry.prototype.set = function(value) {
49
+ this._value = value;
50
+ this.emit('value', this._value);
51
+ };
52
+
53
+ /**
54
+ * Clear cached value
55
+ */
56
+ CacheEntry.prototype.clear = function() {
57
+ this.fetching = false;
58
+ delete this._value;
59
+ };
60
+
61
+
62
+ /**
63
+ * Caching manager for async methods
64
+ *
65
+ * @class
66
+ * @constructor
67
+ */
68
+ var Cache = function() {
69
+ this._entries = {};
70
+ };
71
+
72
+ /**
73
+ * retrive cache entry, or create if not exists.
74
+ *
75
+ * @param {String} [key] - Key of cache entry
76
+ * @returns {CacheEntry}
77
+ */
78
+ Cache.prototype.get = function(key) {
79
+ if (key && this._entries[key]) {
80
+ return this._entries[key];
81
+ } else {
82
+ var entry = new CacheEntry();
83
+ this._entries[key] = entry;
84
+ return entry;
85
+ }
86
+ };
87
+
88
+ /**
89
+ * clear cache entries prefix matching given key
90
+ * @param {String} [key] - Key prefix of cache entry to clear
91
+ */
92
+ Cache.prototype.clear = function(key) {
93
+ for (var k in this._entries) {
94
+ if (!key || k.indexOf(key) === 0) {
95
+ this._entries[k].clear();
96
+ }
97
+ }
98
+ };
99
+
100
+ /**
101
+ * create and return cache key from namespace and serialized arguments.
102
+ * @private
103
+ */
104
+ function createCacheKey(namespace, args) {
105
+ args = Array.prototype.slice.apply(args);
106
+ return namespace + '(' + _.map(args, function(a){ return JSON.stringify(a); }).join(',') + ')';
107
+ }
108
+
109
+ /**
110
+ * Enable caching for async call fn to intercept the response and store it to cache.
111
+ * The original async calll fn is always invoked.
112
+ *
113
+ * @protected
114
+ * @param {Function} fn - Function to covert cacheable
115
+ * @param {Object} [scope] - Scope of function call
116
+ * @param {Object} [options] - Options
117
+ * @return {Function} - Cached version of function
118
+ */
119
+ Cache.prototype.makeResponseCacheable = function(fn, scope, options) {
120
+ var cache = this;
121
+ options = options || {};
122
+ return function() {
123
+ var args = Array.prototype.slice.apply(arguments);
124
+ var callback = args.pop();
125
+ if (!_.isFunction(callback)) {
126
+ args.push(callback);
127
+ callback = null;
128
+ }
129
+ var keys = _.isString(options.key) ? options.key :
130
+ _.isFunction(options.key) ? options.key.apply(scope, args) :
131
+ createCacheKey(options.namespace, args);
132
+ if (!Array.isArray(keys)) { keys = [ keys ]; }
133
+ var entries = [];
134
+ keys.forEach(function (key) {
135
+ var entry = cache.get(key);
136
+ entry.fetching = true;
137
+ entries.push(entry);
138
+ })
139
+ if (callback) {
140
+ args.push(function(err, result) {
141
+ if (Array.isArray(result) && result.length == entries.length) {
142
+ entries.forEach(function (entry, index) {
143
+ entry.set({ error: err, result: result[index] });
144
+ })
145
+ } else {
146
+ entries.forEach(function (entry) {
147
+ entry.set({ error: err, result: result });
148
+ });
149
+ }
150
+ callback(err, result);
151
+ });
152
+ }
153
+ var ret, error;
154
+ try {
155
+ ret = fn.apply(scope || this, args);
156
+ } catch(e) {
157
+ error = e;
158
+ }
159
+ if (ret && _.isFunction(ret.then)) { // if the returned value is promise
160
+ if (!callback) {
161
+ return ret.then(function(result) {
162
+ if (Array.isArray(result) && result.length == entries.length) {
163
+ entries.forEach(function (entry, index) {
164
+ entry.set({ error: undefined, result: result[index] });
165
+ })
166
+ } else {
167
+ entries.forEach(function (entry) {
168
+ entry.set({ error: undefined, result: result });
169
+ });
170
+ }
171
+ return result;
172
+ }, function(err) {
173
+ if (Array.isArray(err) && err.length == entries.length) {
174
+ entries.forEach(function (entry, index) {
175
+ entry.set({ error: err[index], result: undefined });
176
+ })
177
+ } else {
178
+ entries.forEach(function (entry) {
179
+ entry.set({ error: err, result: undefined });
180
+ });
181
+ }
182
+ throw err;
183
+ });
184
+ } else {
185
+ return ret;
186
+ }
187
+ } else {
188
+ if (Array.isArray(ret) && ret.length == entries.length) {
189
+ entries.forEach(function (entry, index) {
190
+ entry.set({ error: error, result: ret[index] });
191
+ })
192
+ } else {
193
+ entries.forEach(function (entry) {
194
+ entry.set({ error: error, result: ret });
195
+ });
196
+ }
197
+ if (error) { throw error; }
198
+ return ret;
199
+ }
200
+ };
201
+ };
202
+
203
+ /**
204
+ * Enable caching for async call fn to lookup the response cache first, then invoke original if no cached value.
205
+ *
206
+ * @protected
207
+ * @param {Function} fn - Function to covert cacheable
208
+ * @param {Object} [scope] - Scope of function call
209
+ * @param {Object} [options] - Options
210
+ * @return {Function} - Cached version of function
211
+ */
212
+ Cache.prototype.makeCacheable = function(fn, scope, options) {
213
+ var cache = this;
214
+ options = options || {};
215
+ var $fn = function() {
216
+ var args = Array.prototype.slice.apply(arguments);
217
+ var callback = args.pop();
218
+ if (!_.isFunction(callback)) {
219
+ args.push(callback);
220
+ }
221
+ var key = _.isString(options.key) ? options.key :
222
+ _.isFunction(options.key) ? options.key.apply(scope, args) :
223
+ createCacheKey(options.namespace, args);
224
+ var entry = cache.get(key);
225
+ if (!_.isFunction(callback)) { // if callback is not given in last arg, return cached result (immediate).
226
+ var value = entry.get();
227
+ if (!value) { throw new Error('Function call result is not cached yet.'); }
228
+ if (value.error) { throw value.error; }
229
+ return value.result;
230
+ }
231
+ entry.get(function(value) {
232
+ callback(value.error, value.result);
233
+ });
234
+ if (!entry.fetching) { // only when no other client is calling function
235
+ entry.fetching = true;
236
+ args.push(function(err, result) {
237
+ entry.set({ error: err, result: result });
238
+ });
239
+ fn.apply(scope || this, args);
240
+ }
241
+ };
242
+ $fn.clear = function() {
243
+ var key = _.isString(options.key) ? options.key :
244
+ _.isFunction(options.key) ? options.key.apply(scope, arguments) :
245
+ createCacheKey(options.namespace, arguments);
246
+ cache.clear(key);
247
+ };
248
+ return $fn;
249
+ };
250
+
251
+
252
+ module.exports = Cache;