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.
- package/LICENSE +22 -0
- package/README.md +74 -0
- package/bin/jsforce +3 -0
- package/bower.json +30 -0
- package/build/jsforce-api-analytics.js +393 -0
- package/build/jsforce-api-analytics.min.js +2 -0
- package/build/jsforce-api-analytics.min.js.map +1 -0
- package/build/jsforce-api-apex.js +183 -0
- package/build/jsforce-api-apex.min.js +2 -0
- package/build/jsforce-api-apex.min.js.map +1 -0
- package/build/jsforce-api-bulk.js +1054 -0
- package/build/jsforce-api-bulk.min.js +2 -0
- package/build/jsforce-api-bulk.min.js.map +1 -0
- package/build/jsforce-api-chatter.js +320 -0
- package/build/jsforce-api-chatter.min.js +2 -0
- package/build/jsforce-api-chatter.min.js.map +1 -0
- package/build/jsforce-api-metadata.js +3020 -0
- package/build/jsforce-api-metadata.min.js +2 -0
- package/build/jsforce-api-metadata.min.js.map +1 -0
- package/build/jsforce-api-soap.js +403 -0
- package/build/jsforce-api-soap.min.js +2 -0
- package/build/jsforce-api-soap.min.js.map +1 -0
- package/build/jsforce-api-streaming.js +3479 -0
- package/build/jsforce-api-streaming.min.js +2 -0
- package/build/jsforce-api-streaming.min.js.map +1 -0
- package/build/jsforce-api-tooling.js +319 -0
- package/build/jsforce-api-tooling.min.js +2 -0
- package/build/jsforce-api-tooling.min.js.map +1 -0
- package/build/jsforce-core.js +25250 -0
- package/build/jsforce-core.min.js +2 -0
- package/build/jsforce-core.min.js.map +1 -0
- package/build/jsforce.js +31637 -0
- package/build/jsforce.min.js +2 -0
- package/build/jsforce.min.js.map +1 -0
- package/core.js +1 -0
- package/index.js +1 -0
- package/lib/VERSION.js +2 -0
- package/lib/_required.js +29 -0
- package/lib/api/analytics.js +387 -0
- package/lib/api/apex.js +177 -0
- package/lib/api/bulk.js +862 -0
- package/lib/api/chatter.js +314 -0
- package/lib/api/index.js +8 -0
- package/lib/api/metadata.js +848 -0
- package/lib/api/soap.js +397 -0
- package/lib/api/streaming-extension.js +136 -0
- package/lib/api/streaming.js +270 -0
- package/lib/api/tooling.js +313 -0
- package/lib/browser/canvas.js +90 -0
- package/lib/browser/client.js +241 -0
- package/lib/browser/core.js +5 -0
- package/lib/browser/jsforce.js +6 -0
- package/lib/browser/jsonp.js +52 -0
- package/lib/browser/request.js +70 -0
- package/lib/cache.js +252 -0
- package/lib/cli/cli.js +431 -0
- package/lib/cli/repl.js +337 -0
- package/lib/connection.js +1881 -0
- package/lib/core.js +16 -0
- package/lib/csv.js +50 -0
- package/lib/date.js +163 -0
- package/lib/http-api.js +300 -0
- package/lib/jsforce.js +10 -0
- package/lib/logger.js +52 -0
- package/lib/oauth2.js +206 -0
- package/lib/process.js +275 -0
- package/lib/promise.js +164 -0
- package/lib/query.js +881 -0
- package/lib/quick-action.js +90 -0
- package/lib/record-stream.js +305 -0
- package/lib/record.js +107 -0
- package/lib/registry/file-registry.js +48 -0
- package/lib/registry/index.js +3 -0
- package/lib/registry/registry.js +111 -0
- package/lib/require.js +14 -0
- package/lib/soap.js +207 -0
- package/lib/sobject.js +558 -0
- package/lib/soql-builder.js +236 -0
- package/lib/transport.js +233 -0
- package/package.json +110 -0
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Manages Streaming APIs
|
|
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
|
+
Faye = require('faye'),
|
|
12
|
+
StreamingExtension = require('./streaming-extension'),
|
|
13
|
+
jsforce = require('../core');
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Streaming API topic class
|
|
17
|
+
*
|
|
18
|
+
* @class Streaming~Topic
|
|
19
|
+
* @param {Streaming} steaming - Streaming API object
|
|
20
|
+
* @param {String} name - Topic name
|
|
21
|
+
*/
|
|
22
|
+
var Topic = function(streaming, name) {
|
|
23
|
+
this._streaming = streaming;
|
|
24
|
+
this.name = name;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @typedef {Object} Streaming~StreamingMessage
|
|
29
|
+
* @prop {Object} event
|
|
30
|
+
* @prop {Object} event.type - Event type
|
|
31
|
+
* @prop {Record} sobject - Record information
|
|
32
|
+
*/
|
|
33
|
+
/**
|
|
34
|
+
* Subscribe listener to topic
|
|
35
|
+
*
|
|
36
|
+
* @method Streaming~Topic#subscribe
|
|
37
|
+
* @param {Callback.<Streaming~StreamingMesasge>} listener - Streaming message listener
|
|
38
|
+
* @returns {Subscription} - Faye subscription object
|
|
39
|
+
*/
|
|
40
|
+
Topic.prototype.subscribe = function(listener) {
|
|
41
|
+
return this._streaming.subscribe(this.name, listener);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Unsubscribe listener from topic
|
|
46
|
+
*
|
|
47
|
+
* @method Streaming~Topic#unsubscribe
|
|
48
|
+
* @param {Callback.<Streaming~StreamingMesasge>} listener - Streaming message listener
|
|
49
|
+
* @returns {Streaming~Topic}
|
|
50
|
+
*/
|
|
51
|
+
Topic.prototype.unsubscribe = function(listener) {
|
|
52
|
+
this._streaming.unsubscribe(this.name, listener);
|
|
53
|
+
return this;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/*--------------------------------------------*/
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Streaming API Generic Streaming Channel
|
|
60
|
+
*
|
|
61
|
+
* @class Streaming~Channel
|
|
62
|
+
* @param {Streaming} steaming - Streaming API object
|
|
63
|
+
* @param {String} name - Channel name (starts with "/u/")
|
|
64
|
+
*/
|
|
65
|
+
var Channel = function(streaming, name) {
|
|
66
|
+
this._streaming = streaming;
|
|
67
|
+
this._name = name;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Subscribe to channel
|
|
72
|
+
*
|
|
73
|
+
* @param {Callback.<Streaming~StreamingMessage>} listener - Streaming message listener
|
|
74
|
+
* @returns {Subscription} - Faye subscription object
|
|
75
|
+
*/
|
|
76
|
+
Channel.prototype.subscribe = function(listener) {
|
|
77
|
+
return this._streaming.subscribe(this._name, listener);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
Channel.prototype.unsubscribe = function(listener) {
|
|
81
|
+
this._streaming.unsubscribe(this._name, listener);
|
|
82
|
+
return this;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
Channel.prototype.push = function(events, callback) {
|
|
86
|
+
var isArray = _.isArray(events);
|
|
87
|
+
events = isArray ? events : [ events ];
|
|
88
|
+
var conn = this._streaming._conn;
|
|
89
|
+
if (!this._id) {
|
|
90
|
+
this._id = conn.sobject('StreamingChannel').findOne({ Name: this._name }, 'Id')
|
|
91
|
+
.then(function(rec) { return rec.Id });
|
|
92
|
+
}
|
|
93
|
+
return this._id.then(function(id) {
|
|
94
|
+
var channelUrl = '/sobjects/StreamingChannel/' + id + '/push';
|
|
95
|
+
return conn.requestPost(channelUrl, { pushEvents: events });
|
|
96
|
+
}).then(function(rets) {
|
|
97
|
+
return isArray ? rets : rets[0];
|
|
98
|
+
}).thenCall(callback);
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
/*--------------------------------------------*/
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Streaming API class
|
|
105
|
+
*
|
|
106
|
+
* @class
|
|
107
|
+
* @extends events.EventEmitter
|
|
108
|
+
* @param {Connection} conn - Connection object
|
|
109
|
+
*/
|
|
110
|
+
var Streaming = function(conn) {
|
|
111
|
+
this._conn = conn;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
inherits(Streaming, events.EventEmitter);
|
|
115
|
+
|
|
116
|
+
/** @private **/
|
|
117
|
+
Streaming.prototype._createClient = function(forChannelName, extensions) {
|
|
118
|
+
// forChannelName is advisory, for an API workaround. It does not restrict or select the channel.
|
|
119
|
+
var needsReplayFix = typeof forChannelName === 'string' && forChannelName.indexOf('/u/') === 0;
|
|
120
|
+
var endpointUrl = [
|
|
121
|
+
this._conn.instanceUrl,
|
|
122
|
+
// special endpoint "/cometd/replay/xx.x" is only available in 36.0.
|
|
123
|
+
// See https://releasenotes.docs.salesforce.com/en-us/summer16/release-notes/rn_api_streaming_classic_replay.htm
|
|
124
|
+
"cometd" + (needsReplayFix === true && this._conn.version === "36.0" ? "/replay" : ""),
|
|
125
|
+
this._conn.version
|
|
126
|
+
].join('/');
|
|
127
|
+
var fayeClient = new Faye.Client(endpointUrl, {});
|
|
128
|
+
fayeClient.setHeader('Authorization', 'OAuth '+this._conn.accessToken);
|
|
129
|
+
if (extensions instanceof Array) {
|
|
130
|
+
extensions.forEach(function(extension) {
|
|
131
|
+
fayeClient.addExtension(extension);
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
if (fayeClient._dispatcher.getConnectionTypes().indexOf('callback-polling') === -1) {
|
|
135
|
+
// prevent streaming API server error
|
|
136
|
+
fayeClient._dispatcher.selectTransport('long-polling');
|
|
137
|
+
fayeClient._dispatcher._transport.batching = false;
|
|
138
|
+
}
|
|
139
|
+
return fayeClient;
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
/** @private **/
|
|
143
|
+
Streaming.prototype._getFayeClient = function(channelName) {
|
|
144
|
+
var isGeneric = channelName.indexOf('/u/') === 0;
|
|
145
|
+
var clientType = isGeneric ? 'generic' : 'pushTopic';
|
|
146
|
+
if (!this._fayeClients || !this._fayeClients[clientType]) {
|
|
147
|
+
this._fayeClients = this._fayeClients || {};
|
|
148
|
+
this._fayeClients[clientType] = this._createClient(channelName);
|
|
149
|
+
}
|
|
150
|
+
return this._fayeClients[clientType];
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Get named topic
|
|
156
|
+
*
|
|
157
|
+
* @param {String} name - Topic name
|
|
158
|
+
* @returns {Streaming~Topic}
|
|
159
|
+
*/
|
|
160
|
+
Streaming.prototype.topic = function(name) {
|
|
161
|
+
this._topics = this._topics || {};
|
|
162
|
+
var topic = this._topics[name] =
|
|
163
|
+
this._topics[name] || new Topic(this, name);
|
|
164
|
+
return topic;
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Get Channel for Id
|
|
169
|
+
* @param {String} channelId - Id of StreamingChannel object
|
|
170
|
+
* @returns {Streaming~Channel}
|
|
171
|
+
*/
|
|
172
|
+
Streaming.prototype.channel = function(channelId) {
|
|
173
|
+
return new Channel(this, channelId);
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Subscribe topic/channel
|
|
178
|
+
*
|
|
179
|
+
* @param {String} name - Topic name
|
|
180
|
+
* @param {Callback.<Streaming~StreamingMessage>} listener - Streaming message listener
|
|
181
|
+
* @returns {Subscription} - Faye subscription object
|
|
182
|
+
*/
|
|
183
|
+
Streaming.prototype.subscribe = function(name, listener) {
|
|
184
|
+
var channelName = name.indexOf('/') === 0 ? name : '/topic/' + name;
|
|
185
|
+
var fayeClient = this._getFayeClient(channelName);
|
|
186
|
+
return fayeClient.subscribe(channelName, listener);
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Unsubscribe topic
|
|
191
|
+
*
|
|
192
|
+
* @param {String} name - Topic name
|
|
193
|
+
* @param {Callback.<Streaming~StreamingMessage>} listener - Streaming message listener
|
|
194
|
+
* @returns {Streaming}
|
|
195
|
+
*/
|
|
196
|
+
Streaming.prototype.unsubscribe = function(name, listener) {
|
|
197
|
+
var channelName = name.indexOf('/') === 0 ? name : '/topic/' + name;
|
|
198
|
+
var fayeClient = this._getFayeClient(channelName);
|
|
199
|
+
fayeClient.unsubscribe(channelName, listener);
|
|
200
|
+
return this;
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Create a Streaming client, optionally with extensions
|
|
206
|
+
*
|
|
207
|
+
* See Faye docs for implementation details: https://faye.jcoglan.com/browser/extensions.html
|
|
208
|
+
*
|
|
209
|
+
* Example usage:
|
|
210
|
+
*
|
|
211
|
+
* ```javascript
|
|
212
|
+
* // Establish a Salesforce connection. (Details elided)
|
|
213
|
+
* const conn = new jsforce.Connection({ … });
|
|
214
|
+
*
|
|
215
|
+
* const fayeClient = conn.streaming.createClient();
|
|
216
|
+
*
|
|
217
|
+
* const subscription = fayeClient.subscribe(channel, data => {
|
|
218
|
+
* console.log('topic received data', data);
|
|
219
|
+
* });
|
|
220
|
+
*
|
|
221
|
+
* subscription.cancel();
|
|
222
|
+
* ```
|
|
223
|
+
*
|
|
224
|
+
* Example with extensions, using Replay & Auth Failure extensions in a server-side Node.js app:
|
|
225
|
+
*
|
|
226
|
+
* ```javascript
|
|
227
|
+
* // Establish a Salesforce connection. (Details elided)
|
|
228
|
+
* const conn = new jsforce.Connection({ … });
|
|
229
|
+
*
|
|
230
|
+
* const channel = "/event/My_Event__e";
|
|
231
|
+
* const replayId = -2; // -2 is all retained events
|
|
232
|
+
*
|
|
233
|
+
* const exitCallback = () => process.exit(1);
|
|
234
|
+
* const authFailureExt = new jsforce.StreamingExtension.AuthFailure(exitCallback);
|
|
235
|
+
*
|
|
236
|
+
* const replayExt = new jsforce.StreamingExtension.Replay(channel, replayId);
|
|
237
|
+
*
|
|
238
|
+
* const fayeClient = conn.streaming.createClient([
|
|
239
|
+
* authFailureExt,
|
|
240
|
+
* replayExt
|
|
241
|
+
* ]);
|
|
242
|
+
*
|
|
243
|
+
* const subscription = fayeClient.subscribe(channel, data => {
|
|
244
|
+
* console.log('topic received data', data);
|
|
245
|
+
* });
|
|
246
|
+
*
|
|
247
|
+
* subscription.cancel();
|
|
248
|
+
* ```
|
|
249
|
+
*
|
|
250
|
+
* @param {Array} Extensions - Optional, extensions to apply to the Faye client
|
|
251
|
+
* @returns {FayeClient} - Faye client object
|
|
252
|
+
*/
|
|
253
|
+
Streaming.prototype.createClient = function(extensions) {
|
|
254
|
+
return this._createClient(null, extensions);
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
/*--------------------------------------------*/
|
|
258
|
+
/*
|
|
259
|
+
* Register hook in connection instantiation for dynamically adding this API module features
|
|
260
|
+
*/
|
|
261
|
+
jsforce.on('connection:new', function(conn) {
|
|
262
|
+
conn.streaming = new Streaming(conn);
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
/*
|
|
266
|
+
*
|
|
267
|
+
*/
|
|
268
|
+
jsforce.StreamingExtension = StreamingExtension;
|
|
269
|
+
|
|
270
|
+
module.exports = Streaming;
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Manages Tooling APIs
|
|
3
|
+
* @author Shinichi Tomita <shinichi.tomita@gmail.com>
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
8
|
+
var jsforce = require('../core'),
|
|
9
|
+
_ = require('lodash/core'),
|
|
10
|
+
Cache = require('../cache');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* API class for Tooling API call
|
|
14
|
+
*
|
|
15
|
+
* @class
|
|
16
|
+
* @param {Connection} conn - Connection
|
|
17
|
+
*/
|
|
18
|
+
var Tooling = function(conn) {
|
|
19
|
+
this._conn = conn;
|
|
20
|
+
this._logger = conn._logger;
|
|
21
|
+
var delegates = [
|
|
22
|
+
"query",
|
|
23
|
+
"queryMore",
|
|
24
|
+
"_toRecordResult",
|
|
25
|
+
"create",
|
|
26
|
+
"_createSingle",
|
|
27
|
+
"_createParallel",
|
|
28
|
+
"_createMany",
|
|
29
|
+
"insert",
|
|
30
|
+
"retrieve",
|
|
31
|
+
"_retrieveSingle",
|
|
32
|
+
"_retrieveParallel",
|
|
33
|
+
"_retrieveMany",
|
|
34
|
+
"update",
|
|
35
|
+
"_updateSingle",
|
|
36
|
+
"_updateParallel",
|
|
37
|
+
"_updateMany",
|
|
38
|
+
"upsert",
|
|
39
|
+
"del",
|
|
40
|
+
"delete",
|
|
41
|
+
"destroy",
|
|
42
|
+
"_destroySingle",
|
|
43
|
+
"_destroyParallel",
|
|
44
|
+
"_destroyMany",
|
|
45
|
+
"describe",
|
|
46
|
+
"describeGlobal",
|
|
47
|
+
"sobject"
|
|
48
|
+
];
|
|
49
|
+
delegates.forEach(function(method) {
|
|
50
|
+
this[method] = conn.constructor.prototype[method];
|
|
51
|
+
}, this);
|
|
52
|
+
|
|
53
|
+
this.cache = new Cache();
|
|
54
|
+
|
|
55
|
+
var cacheOptions = {
|
|
56
|
+
key: function(type) { return type ? "describe." + type : "describe"; }
|
|
57
|
+
};
|
|
58
|
+
this.describe$ = this.cache.makeCacheable(this.describe, this, cacheOptions);
|
|
59
|
+
this.describe = this.cache.makeResponseCacheable(this.describe, this, cacheOptions);
|
|
60
|
+
this.describeSObject$ = this.describe$;
|
|
61
|
+
this.describeSObject = this.describe;
|
|
62
|
+
|
|
63
|
+
cacheOptions = { key: 'describeGlobal' };
|
|
64
|
+
this.describeGlobal$ = this.cache.makeCacheable(this.describeGlobal, this, cacheOptions);
|
|
65
|
+
this.describeGlobal = this.cache.makeResponseCacheable(this.describeGlobal, this, cacheOptions);
|
|
66
|
+
|
|
67
|
+
this.initialize();
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Initialize tooling API
|
|
72
|
+
* @protected
|
|
73
|
+
*/
|
|
74
|
+
Tooling.prototype.initialize = function() {
|
|
75
|
+
this.sobjects = {};
|
|
76
|
+
this.cache.clear();
|
|
77
|
+
this.cache.get('describeGlobal').removeAllListeners('value');
|
|
78
|
+
this.cache.get('describeGlobal').on('value', _.bind(function(res) {
|
|
79
|
+
if (res.result) {
|
|
80
|
+
var types = _.map(res.result.sobjects, function(so) { return so.name; });
|
|
81
|
+
types.forEach(this.sobject, this);
|
|
82
|
+
}
|
|
83
|
+
}, this));
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* @private
|
|
88
|
+
*/
|
|
89
|
+
Tooling.prototype._baseUrl = function() {
|
|
90
|
+
return this._conn._baseUrl() + "/tooling";
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* @private
|
|
95
|
+
*/
|
|
96
|
+
Tooling.prototype._supports = function(feature) {
|
|
97
|
+
// should return false in order not to use compsite collection
|
|
98
|
+
if (feature === 'sobject-collection') {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
return this._conn._supports.apply(this._conn, arguments);
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* @private
|
|
106
|
+
*/
|
|
107
|
+
Tooling.prototype.request = function() {
|
|
108
|
+
return this._conn.request.apply(this._conn, arguments);
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Execute query by using SOQL
|
|
113
|
+
*
|
|
114
|
+
* @param {String} soql - SOQL string
|
|
115
|
+
* @param {Callback.<QueryResult>} [callback] - Callback function
|
|
116
|
+
* @returns {Query.<QueryResult>}
|
|
117
|
+
*/
|
|
118
|
+
/**
|
|
119
|
+
* Query next record set by using query locator
|
|
120
|
+
*
|
|
121
|
+
* @method Tooling#query
|
|
122
|
+
* @param {String} locator - Next record set locator
|
|
123
|
+
* @param {Callback.<QueryResult>} [callback] - Callback function
|
|
124
|
+
* @returns {Query.<QueryResult>}
|
|
125
|
+
*/
|
|
126
|
+
/**
|
|
127
|
+
* Retrieve specified records
|
|
128
|
+
*
|
|
129
|
+
* @method Tooling#queryMore
|
|
130
|
+
* @param {String} type - SObject Type
|
|
131
|
+
* @param {String|Array.<String>} ids - A record ID or array of record IDs
|
|
132
|
+
* @param {Callback.<Record|Array.<Record>>} [callback] - Callback function
|
|
133
|
+
* @returns {Promise.<Record|Array.<Record>>}
|
|
134
|
+
*/
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Synonym of Tooling#create()
|
|
138
|
+
*
|
|
139
|
+
* @method Tooling#insert
|
|
140
|
+
* @param {String} type - SObject Type
|
|
141
|
+
* @param {Object|Array.<Object>} records - A record or array of records to create
|
|
142
|
+
* @param {Callback.<RecordResult|Array.<RecordResult>>} [callback] - Callback function
|
|
143
|
+
* @returns {Promise.<RecordResult|Array.<RecordResult>>}
|
|
144
|
+
*/
|
|
145
|
+
/**
|
|
146
|
+
* Create records
|
|
147
|
+
*
|
|
148
|
+
* @method Tooling#create
|
|
149
|
+
* @param {String} type - SObject Type
|
|
150
|
+
* @param {Record|Array.<Record>} records - A record or array of records to create
|
|
151
|
+
* @param {Callback.<RecordResult|Array.<RecordResult>>} [callback] - Callback function
|
|
152
|
+
* @returns {Promise.<RecordResult|Array.<RecordResult>>}
|
|
153
|
+
*/
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Update records
|
|
157
|
+
*
|
|
158
|
+
* @method Tooling#update
|
|
159
|
+
* @param {String} type - SObject Type
|
|
160
|
+
* @param {Record|Array.<Record>} records - A record or array of records to update
|
|
161
|
+
* @param {Callback.<RecordResult|Array.<RecordResult>>} [callback] - Callback function
|
|
162
|
+
* @returns {Promise.<RecordResult|Array.<RecordResult>>}
|
|
163
|
+
*/
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Upsert records
|
|
167
|
+
*
|
|
168
|
+
* @method Tooling#upsert
|
|
169
|
+
* @param {String} type - SObject Type
|
|
170
|
+
* @param {Record|Array.<Record>} records - Record or array of records to upsert
|
|
171
|
+
* @param {String} extIdField - External ID field name
|
|
172
|
+
* @param {Callback.<RecordResult|Array.<RecordResult>>} [callback] - Callback
|
|
173
|
+
* @returns {Promise.<RecordResult|Array.<RecordResult>>}
|
|
174
|
+
*/
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Synonym of Tooling#destroy()
|
|
178
|
+
*
|
|
179
|
+
* @method Tooling#delete
|
|
180
|
+
* @param {String} type - SObject Type
|
|
181
|
+
* @param {String|Array.<String>} ids - A ID or array of IDs to delete
|
|
182
|
+
* @param {Callback.<RecordResult|Array.<RecordResult>>} [callback] - Callback
|
|
183
|
+
* @returns {Promise.<RecordResult|Array.<RecordResult>>}
|
|
184
|
+
*/
|
|
185
|
+
/**
|
|
186
|
+
* Synonym of Tooling#destroy()
|
|
187
|
+
*
|
|
188
|
+
* @method Tooling#del
|
|
189
|
+
* @param {String} type - SObject Type
|
|
190
|
+
* @param {String|Array.<String>} ids - A ID or array of IDs to delete
|
|
191
|
+
* @param {Callback.<RecordResult|Array.<RecordResult>>} [callback] - Callback
|
|
192
|
+
* @returns {Promise.<RecordResult|Array.<RecordResult>>}
|
|
193
|
+
*/
|
|
194
|
+
/**
|
|
195
|
+
* Delete records
|
|
196
|
+
*
|
|
197
|
+
* @method Tooling#destroy
|
|
198
|
+
* @param {String} type - SObject Type
|
|
199
|
+
* @param {String|Array.<String>} ids - A ID or array of IDs to delete
|
|
200
|
+
* @param {Callback.<RecordResult|Array.<RecordResult>>} [callback] - Callback
|
|
201
|
+
* @returns {Promise.<RecordResult|Array.<RecordResult>>}
|
|
202
|
+
*/
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Synonym of Tooling#describe()
|
|
206
|
+
*
|
|
207
|
+
* @method Tooling#describeSObject
|
|
208
|
+
* @param {String} type - SObject Type
|
|
209
|
+
* @param {Callback.<DescribeSObjectResult>} [callback] - Callback function
|
|
210
|
+
* @returns {Promise.<DescribeSObjectResult>}
|
|
211
|
+
*/
|
|
212
|
+
/**
|
|
213
|
+
* Describe SObject metadata
|
|
214
|
+
*
|
|
215
|
+
* @method Tooling#describe
|
|
216
|
+
* @param {String} type - SObject Type
|
|
217
|
+
* @param {Callback.<DescribeSObjectResult>} [callback] - Callback function
|
|
218
|
+
* @returns {Promise.<DescribeSObjectResult>}
|
|
219
|
+
*/
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Describe global SObjects
|
|
223
|
+
*
|
|
224
|
+
* @method Tooling#describeGlobal
|
|
225
|
+
* @param {Callback.<DescribeGlobalResult>} [callback] - Callback function
|
|
226
|
+
* @returns {Promise.<DescribeGlobalResult>}
|
|
227
|
+
*/
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Get SObject instance
|
|
231
|
+
*
|
|
232
|
+
* @method Tooling#sobject
|
|
233
|
+
* @param {String} type - SObject Type
|
|
234
|
+
* @returns {SObject}
|
|
235
|
+
*/
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* @typedef {Object} Tooling~ExecuteAnonymousResult
|
|
239
|
+
* @prop {Boolean} compiled - Flag if the query is compiled successfully
|
|
240
|
+
* @prop {String} compileProblem - Error reason in compilation
|
|
241
|
+
* @prop {Boolean} success - Flag if the code is executed successfully
|
|
242
|
+
* @prop {Number} line - Line number for the error
|
|
243
|
+
* @prop {Number} column - Column number for the error
|
|
244
|
+
* @prop {String} exceptionMessage - Exception message
|
|
245
|
+
* @prop {String} exceptionStackTrace - Exception stack trace
|
|
246
|
+
*/
|
|
247
|
+
/**
|
|
248
|
+
* Executes Apex code anonymously
|
|
249
|
+
*
|
|
250
|
+
* @param {String} body - Anonymous Apex code
|
|
251
|
+
* @param {Callback.<Tooling~ExecuteAnonymousResult>} [callback] - Callback function
|
|
252
|
+
* @returns {Promise.<Tooling~ExecuteAnonymousResult>}
|
|
253
|
+
*/
|
|
254
|
+
Tooling.prototype.executeAnonymous = function(body, callback) {
|
|
255
|
+
var url = this._baseUrl() + "/executeAnonymous?anonymousBody=" + encodeURIComponent(body);
|
|
256
|
+
return this.request(url).thenCall(callback);
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Executes Apex tests asynchronously
|
|
261
|
+
*
|
|
262
|
+
* @param {Array.<String>} classids - Comma separated list of class IDs
|
|
263
|
+
* @param {Callback.<Tooling~ExecuteAnonymousResult>} [callback] - Callback function
|
|
264
|
+
* @returns {Promise.<Tooling~ExecuteAnonymousResult>}
|
|
265
|
+
*/
|
|
266
|
+
Tooling.prototype.runTestsAsynchronous = function(classids, callback) {
|
|
267
|
+
var url = this._baseUrl() + "/runTestsAsynchronous/";
|
|
268
|
+
return this._conn.requestPost(url, {classids : classids.join(',')}, undefined, callback);
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Executes Apex tests synchronously
|
|
273
|
+
*
|
|
274
|
+
* @param {Array.<String>} classnames - Comma separated list of class Names
|
|
275
|
+
* @param {Callback.<Tooling~ExecuteAnonymousResult>} [callback] - Callback function
|
|
276
|
+
* @returns {Promise.<Tooling~ExecuteAnonymousResult>}
|
|
277
|
+
*/
|
|
278
|
+
Tooling.prototype.runTestsSynchronous = function(classnames, callback) {
|
|
279
|
+
var url = this._baseUrl() + "/runTestsSynchronous/";
|
|
280
|
+
return this._conn.requestPost(url, {classnames : classnames.join(',')}, undefined, callback);
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* @typedef {Object} Tooling~CompletionsResult
|
|
285
|
+
* @prop {Object} publicDeclarations
|
|
286
|
+
*/
|
|
287
|
+
/**
|
|
288
|
+
* Retrieves available code completions of the referenced type
|
|
289
|
+
*
|
|
290
|
+
* @param {String} [type] - completion type (default 'apex')
|
|
291
|
+
* @param {Callback.<Tooling~CompletionsResult>} [callback] - Callback function
|
|
292
|
+
* @returns {Promise.<Tooling~CompletionsResult>}
|
|
293
|
+
*/
|
|
294
|
+
Tooling.prototype.completions = function(type, callback) {
|
|
295
|
+
if (!_.isString(type)) {
|
|
296
|
+
callback = type;
|
|
297
|
+
type = 'apex';
|
|
298
|
+
}
|
|
299
|
+
var url = this._baseUrl() + "/completions?type=" + encodeURIComponent(type);
|
|
300
|
+
return this.request(url).thenCall(callback);
|
|
301
|
+
};
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
/*--------------------------------------------*/
|
|
305
|
+
/*
|
|
306
|
+
* Register hook in connection instantiation for dynamically adding this API module features
|
|
307
|
+
*/
|
|
308
|
+
jsforce.on('connection:new', function(conn) {
|
|
309
|
+
conn.tooling = new Tooling(conn);
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
module.exports = Tooling;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/*global Sfdc */
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var Duplex = require('readable-stream').Duplex,
|
|
5
|
+
_ = require('lodash/core');
|
|
6
|
+
|
|
7
|
+
function parseHeaders(hs) {
|
|
8
|
+
var headers = {};
|
|
9
|
+
hs.split(/\n/).forEach(function(line) {
|
|
10
|
+
var pair = line.split(/\s*:\s*/);
|
|
11
|
+
var name = pair[0].toLowerCase();
|
|
12
|
+
var value = pair[1];
|
|
13
|
+
headers[name] = value;
|
|
14
|
+
});
|
|
15
|
+
return headers;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
module.exports = {
|
|
19
|
+
|
|
20
|
+
supported: typeof Sfdc === 'object' && typeof Sfdc.canvas !== 'undefined',
|
|
21
|
+
|
|
22
|
+
createRequest: function(signedRequest) {
|
|
23
|
+
return function(params, callback) {
|
|
24
|
+
var response;
|
|
25
|
+
var str = new Duplex();
|
|
26
|
+
str._read = function(size) {
|
|
27
|
+
if (response) {
|
|
28
|
+
str.push(response.body);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
var bufs = [];
|
|
32
|
+
var sent = false;
|
|
33
|
+
str._write = function(chunk, encoding, callback) {
|
|
34
|
+
bufs.push(chunk.toString(encoding));
|
|
35
|
+
callback();
|
|
36
|
+
};
|
|
37
|
+
str.on('finish', function() {
|
|
38
|
+
if (!sent) {
|
|
39
|
+
send(bufs.join(''));
|
|
40
|
+
sent = true;
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
if (params.body || params.body === "" || !/^(put|post|patch)$/i.test(params.method)) {
|
|
44
|
+
send(params.body);
|
|
45
|
+
sent = true;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function send(body) {
|
|
49
|
+
var settings = {
|
|
50
|
+
client: signedRequest.client,
|
|
51
|
+
method: params.method,
|
|
52
|
+
data: body
|
|
53
|
+
};
|
|
54
|
+
if (params.headers) {
|
|
55
|
+
settings.headers = {};
|
|
56
|
+
for (var name in params.headers) {
|
|
57
|
+
if (name.toLowerCase() === 'content-type') {
|
|
58
|
+
settings.contentType = params.headers[name];
|
|
59
|
+
} else {
|
|
60
|
+
settings.headers[name] = params.headers[name];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
settings.success = function(data) {
|
|
65
|
+
var headers = parseHeaders(data.responseHeaders);
|
|
66
|
+
var body = data.payload;
|
|
67
|
+
if (!_.isString(body)) {
|
|
68
|
+
body = JSON.stringify(body);
|
|
69
|
+
}
|
|
70
|
+
response = {
|
|
71
|
+
statusCode : data.status,
|
|
72
|
+
headers: headers,
|
|
73
|
+
body: body
|
|
74
|
+
};
|
|
75
|
+
if (callback) {
|
|
76
|
+
callback(null, response, response.body);
|
|
77
|
+
}
|
|
78
|
+
str.end();
|
|
79
|
+
};
|
|
80
|
+
settings.failure = function(err) {
|
|
81
|
+
if (callback) {
|
|
82
|
+
callback(err);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
Sfdc.canvas.client.ajax(params.url, settings);
|
|
86
|
+
}
|
|
87
|
+
return str;
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
};
|