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,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Represents Salesforce QuickAction
|
|
3
|
+
* @author Shinichi Tomita <shinichi.tomita@gmail.com>
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* A class for quick action
|
|
11
|
+
*
|
|
12
|
+
* @protected
|
|
13
|
+
* @constructor
|
|
14
|
+
*/
|
|
15
|
+
var QuickAction = module.exports = function(conn, path) {
|
|
16
|
+
this._conn = conn;
|
|
17
|
+
this._path = path;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @typedef {Object} QuickAction~QuickActionInfo
|
|
22
|
+
* @prop {String} type - Type of the action (e.g. Create, Update, Post, LogACall)
|
|
23
|
+
* @prop {String} name - Name of the action
|
|
24
|
+
* @prop {String} label - Label of the action
|
|
25
|
+
* @prop {Object} urls - Endpoint URL information of the action
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* @typedef {QuickAction~QuickActionInfo} QuickAction~QuickActionDescriveInfo
|
|
29
|
+
* @prop {String} contextSobjectType - Object type used for the action
|
|
30
|
+
* @prop {String} targetSobjectType - Object type of the action to target
|
|
31
|
+
* @prop {String} targetParentField - Field name in the target object which refers parent(context) object record ID.
|
|
32
|
+
* @prop {String} targetRecordTypeId - Record type of the targeted record
|
|
33
|
+
* @prop {Object} layout - Layout sections that comprise an action
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Describe the action's information (including layout, etc.)
|
|
38
|
+
*
|
|
39
|
+
* @param {Callback.<QuickAction~QuickActionDescriveInfo>} [callback] - Callback function
|
|
40
|
+
* @returns {Promise.<QuickAction~QuickActionDescriveInfo>}
|
|
41
|
+
*/
|
|
42
|
+
QuickAction.prototype.describe = function(callback) {
|
|
43
|
+
var url = this._path + "/describe";
|
|
44
|
+
return this._conn.request(url).thenCall(callback);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Retrieve default field values in the action (for given record, if specified)
|
|
49
|
+
*
|
|
50
|
+
* @param {String} [contextId] - ID of record to get default values specific to the record
|
|
51
|
+
* @param {Callback.<Record>} [callback] - Callback function
|
|
52
|
+
* @returns {Promise.<Record>}
|
|
53
|
+
*/
|
|
54
|
+
QuickAction.prototype.defaultValues = function(contextId, callback) {
|
|
55
|
+
if (typeof contextId === 'function') {
|
|
56
|
+
callback = contextId;
|
|
57
|
+
contextId = null;
|
|
58
|
+
}
|
|
59
|
+
var url = this._path + "/defaultValues";
|
|
60
|
+
if (contextId) {
|
|
61
|
+
url += "/" + contextId;
|
|
62
|
+
}
|
|
63
|
+
return this._conn.request(url).thenCall(callback);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @typedef {Object} QuickAction~QuickActionResult
|
|
68
|
+
* @param {String} id - Record id of the action result
|
|
69
|
+
* @param {Array.<String>} feedItemIds - List of IDs for feed item
|
|
70
|
+
* @param {Boolean} success - True if the action successfully completed
|
|
71
|
+
* @param {Boolean} created - True if the action yields a new record
|
|
72
|
+
* @param {String} contextId - Context record ID of the action
|
|
73
|
+
* @param {Array.<Object>} errors - Errors if the action failed
|
|
74
|
+
*/
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Execute the action for given context Id and record information
|
|
78
|
+
*
|
|
79
|
+
* @param {String} contextId - Context record ID of the action
|
|
80
|
+
* @param {Record} record - Input record information for the action
|
|
81
|
+
* @param {Callback.<QuickAction~QuickActionResult>} [callback] - Callback function
|
|
82
|
+
* @returns {Promise.<QuickAction~QuickActionResult>}
|
|
83
|
+
*/
|
|
84
|
+
QuickAction.prototype.execute = function(contextId, record, callback) {
|
|
85
|
+
var body = {
|
|
86
|
+
contextId: contextId,
|
|
87
|
+
record: record
|
|
88
|
+
};
|
|
89
|
+
return this._conn.requestPost(this._path, body).thenCall(callback);
|
|
90
|
+
};
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Represents stream that handles Salesforce record as stream data
|
|
3
|
+
* @author Shinichi Tomita <shinichi.tomita@gmail.com>
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
8
|
+
var events = require('events'),
|
|
9
|
+
stream = require('readable-stream'),
|
|
10
|
+
Duplex = stream.Duplex,
|
|
11
|
+
Transform = stream.Transform,
|
|
12
|
+
PassThrough = stream.PassThrough,
|
|
13
|
+
inherits = require('inherits'),
|
|
14
|
+
_ = require('lodash/core'),
|
|
15
|
+
CSV = require('./csv');
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Class for Record Stream
|
|
20
|
+
*
|
|
21
|
+
* @class
|
|
22
|
+
* @constructor
|
|
23
|
+
* @extends stream.Transform
|
|
24
|
+
*/
|
|
25
|
+
var RecordStream = module.exports = function() {
|
|
26
|
+
RecordStream.super_.call(this, { objectMode: true });
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
inherits(RecordStream, Transform);
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
/*
|
|
33
|
+
* @override
|
|
34
|
+
*/
|
|
35
|
+
RecordStream.prototype._transform = function(record, enc, callback) {
|
|
36
|
+
this.emit('record', record);
|
|
37
|
+
this.push(record);
|
|
38
|
+
callback();
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Get record stream of queried records applying the given mapping function
|
|
43
|
+
*
|
|
44
|
+
* @param {RecordMapFunction} fn - Record mapping function
|
|
45
|
+
* @returns {RecordStream}
|
|
46
|
+
*/
|
|
47
|
+
RecordStream.prototype.map = function(fn) {
|
|
48
|
+
return this.pipe(RecordStream.map(fn));
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Get record stream of queried records, applying the given filter function
|
|
53
|
+
*
|
|
54
|
+
* @param {RecordFilterFunction} fn - Record filtering function
|
|
55
|
+
* @returns {RecordStream}
|
|
56
|
+
*/
|
|
57
|
+
RecordStream.prototype.filter = function(fn) {
|
|
58
|
+
return this.pipe(RecordStream.filter(fn));
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* @class RecordStream.Serializable
|
|
64
|
+
* @extends {RecordStream}
|
|
65
|
+
*/
|
|
66
|
+
var Serializable = RecordStream.Serializable = function() {
|
|
67
|
+
Serializable.super_.call(this);
|
|
68
|
+
this._dataStream = null;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
inherits(Serializable, RecordStream);
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Create readable data stream which emits serialized record data
|
|
75
|
+
*
|
|
76
|
+
* @param {String} [type] - Type of outgoing data format. Currently 'csv' is default value and the only supported.
|
|
77
|
+
* @param {Object} [options] - Options passed to converter
|
|
78
|
+
* @returns {stream.Readable}
|
|
79
|
+
*/
|
|
80
|
+
Serializable.prototype.stream = function(type, options) {
|
|
81
|
+
type = type || 'csv';
|
|
82
|
+
var converter = DataStreamConverters[type];
|
|
83
|
+
if (!converter) {
|
|
84
|
+
throw new Error('Converting [' + type + '] data stream is not supported.');
|
|
85
|
+
}
|
|
86
|
+
if (!this._dataStream) {
|
|
87
|
+
this._dataStream = new PassThrough();
|
|
88
|
+
this.pipe(converter.serialize(options))
|
|
89
|
+
.pipe(this._dataStream);
|
|
90
|
+
}
|
|
91
|
+
return this._dataStream;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* @class RecordStream.Parsable
|
|
97
|
+
* @extends {RecordStream}
|
|
98
|
+
*/
|
|
99
|
+
var Parsable = RecordStream.Parsable = function() {
|
|
100
|
+
Parsable.super_.call(this);
|
|
101
|
+
this._dataStream = null;
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
inherits(Parsable, RecordStream);
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Create writable data stream which accepts serialized record data
|
|
108
|
+
*
|
|
109
|
+
* @param {String} [type] - Type of outgoing data format. Currently 'csv' is default value and the only supported.
|
|
110
|
+
* @param {Object} [options] - Options passed to converter
|
|
111
|
+
* @returns {stream.Readable}
|
|
112
|
+
*/
|
|
113
|
+
Parsable.prototype.stream = function(type, options) {
|
|
114
|
+
type = type || 'csv';
|
|
115
|
+
var converter = DataStreamConverters[type];
|
|
116
|
+
var self = this;
|
|
117
|
+
if (!converter) {
|
|
118
|
+
throw new Error('Converting [' + type + '] data stream is not supported.');
|
|
119
|
+
}
|
|
120
|
+
if (!this._dataStream) {
|
|
121
|
+
this._dataStream = new PassThrough();
|
|
122
|
+
this._parserStream = converter.parse(options).on('error', function(error) { self.emit('error', error); });
|
|
123
|
+
this._parserStream.pipe(this).pipe(new PassThrough({ objectMode: true, highWaterMark: ( 500 * 1000 ) }));
|
|
124
|
+
}
|
|
125
|
+
return this._dataStream;
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
/* @override */
|
|
130
|
+
Parsable.prototype.on = function(ev, fn) {
|
|
131
|
+
if (ev === 'readable' || ev === 'record') {
|
|
132
|
+
this._dataStream.pipe(this._parserStream);
|
|
133
|
+
}
|
|
134
|
+
return Parsable.super_.prototype.on.call(this, ev, fn);
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
/* @override */
|
|
138
|
+
Parsable.prototype.addListener = Parsable.prototype.on;
|
|
139
|
+
|
|
140
|
+
/* --------------------------------------------------- */
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* @callback RecordMapFunction
|
|
144
|
+
* @param {Record} record - Source record to map
|
|
145
|
+
* @returns {Record}
|
|
146
|
+
*/
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Create a record stream which maps records and pass them to downstream
|
|
150
|
+
*
|
|
151
|
+
* @param {RecordMapFunction} fn - Record mapping function
|
|
152
|
+
* @returns {RecordStream.Serializable}
|
|
153
|
+
*/
|
|
154
|
+
RecordStream.map = function(fn) {
|
|
155
|
+
var mapStream = new RecordStream.Serializable();
|
|
156
|
+
mapStream._transform = function(record, enc, callback) {
|
|
157
|
+
var rec = fn(record) || record; // if not returned record, use same record
|
|
158
|
+
this.push(rec);
|
|
159
|
+
callback();
|
|
160
|
+
};
|
|
161
|
+
return mapStream;
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Create mapping stream using given record template
|
|
166
|
+
*
|
|
167
|
+
* @param {Record} record - Mapping record object. In mapping field value, temlate notation can be used to refer field value in source record, if noeval param is not true.
|
|
168
|
+
* @param {Boolean} [noeval] - Disable template evaluation in mapping record.
|
|
169
|
+
* @returns {RecordStream.Serializable}
|
|
170
|
+
*/
|
|
171
|
+
RecordStream.recordMapStream = function(record, noeval) {
|
|
172
|
+
return RecordStream.map(function(rec) {
|
|
173
|
+
var mapped = { Id: rec.Id };
|
|
174
|
+
for (var prop in record) {
|
|
175
|
+
mapped[prop] = noeval ? record[prop] : evalMapping(record[prop], rec);
|
|
176
|
+
}
|
|
177
|
+
return mapped;
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
function evalMapping(value, mapping) {
|
|
181
|
+
if (_.isString(value)) {
|
|
182
|
+
var m = /^\$\{(\w+)\}$/.exec(value);
|
|
183
|
+
if (m) { return mapping[m[1]]; }
|
|
184
|
+
return value.replace(/\$\{(\w+)\}/g, function($0, prop) {
|
|
185
|
+
var v = mapping[prop];
|
|
186
|
+
return _.isNull(v) || _.isUndefined(v) ? "" : String(v);
|
|
187
|
+
});
|
|
188
|
+
} else {
|
|
189
|
+
return value;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* @callback RecordFilterFunction
|
|
196
|
+
* @param {Record} record - Source record to filter
|
|
197
|
+
* @returns {Boolean}
|
|
198
|
+
*/
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Create a record stream which filters records and pass them to downstream
|
|
202
|
+
*
|
|
203
|
+
* @param {RecordFilterFunction} fn - Record filtering function
|
|
204
|
+
* @returns {RecordStream.Serializable}
|
|
205
|
+
*/
|
|
206
|
+
RecordStream.filter = function(fn) {
|
|
207
|
+
var filterStream = new RecordStream.Serializable();
|
|
208
|
+
filterStream._transform = function(record, enc, callback) {
|
|
209
|
+
if (fn(record)) { this.push(record); }
|
|
210
|
+
callback();
|
|
211
|
+
};
|
|
212
|
+
return filterStream;
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* @private
|
|
217
|
+
*/
|
|
218
|
+
function convertRecordForSerialization(record, options) {
|
|
219
|
+
const opts = options || {};
|
|
220
|
+
|
|
221
|
+
function isBuffer(obj) {
|
|
222
|
+
return (
|
|
223
|
+
obj &&
|
|
224
|
+
obj.constructor &&
|
|
225
|
+
typeof obj.constructor.isBuffer === "function" &&
|
|
226
|
+
obj.constructor.isBuffer(obj)
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function keyIdentity(key) {
|
|
231
|
+
return key;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const delimiter = ".";
|
|
235
|
+
const transformKey = keyIdentity;
|
|
236
|
+
const output = {};
|
|
237
|
+
|
|
238
|
+
function step(object, prev) {
|
|
239
|
+
Object.keys(object).forEach(function (key) {
|
|
240
|
+
if (key === "attributes") {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
const value = object[key];
|
|
244
|
+
const isbuffer = isBuffer(value);
|
|
245
|
+
const isobject = typeof value === "object";
|
|
246
|
+
const isnull = value === null;
|
|
247
|
+
|
|
248
|
+
const newKey = prev
|
|
249
|
+
? prev + delimiter + transformKey(key)
|
|
250
|
+
: transformKey(key);
|
|
251
|
+
|
|
252
|
+
if (!isnull && !isbuffer && isobject && Object.keys(value).length) {
|
|
253
|
+
step(value, newKey);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
output[newKey] = isnull && opts.nullValue ? opts.nullValue : value;
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
step(record);
|
|
261
|
+
|
|
262
|
+
return output;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* @private
|
|
267
|
+
*/
|
|
268
|
+
function createPipelineStream(s1, s2) {
|
|
269
|
+
var pipeline = new PassThrough();
|
|
270
|
+
pipeline.on('pipe', function(source) {
|
|
271
|
+
source.unpipe(pipeline);
|
|
272
|
+
source.pipe(s1).pipe(s2);
|
|
273
|
+
});
|
|
274
|
+
pipeline.pipe = function(dest, options) {
|
|
275
|
+
return s2.pipe(dest, options);
|
|
276
|
+
};
|
|
277
|
+
return pipeline;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/** ---------------------------------------------------------------------- **/
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* @private
|
|
284
|
+
*/
|
|
285
|
+
var CSVStreamConverter = {
|
|
286
|
+
serialize: function(options) {
|
|
287
|
+
options = options || {};
|
|
288
|
+
return createPipelineStream(
|
|
289
|
+
RecordStream.map(function(record) {
|
|
290
|
+
return convertRecordForSerialization(record, options);
|
|
291
|
+
}),
|
|
292
|
+
CSV.serializeCSVStream(options)
|
|
293
|
+
);
|
|
294
|
+
},
|
|
295
|
+
parse: function(options) {
|
|
296
|
+
return CSV.parseCSVStream(options);
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* @private
|
|
302
|
+
*/
|
|
303
|
+
var DataStreamConverters = RecordStream.DataStreamConverters = {
|
|
304
|
+
csv: CSVStreamConverter
|
|
305
|
+
};
|
package/lib/record.js
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Represents Salesforce record information
|
|
3
|
+
* @author Shinichi Tomita <shinichi.tomita@gmail.com>
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
8
|
+
var _ = require('lodash/core');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* A simple hash object including record field information
|
|
12
|
+
*
|
|
13
|
+
* @typedef {Object} Record
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Remote reference to record information
|
|
18
|
+
*
|
|
19
|
+
* @protected
|
|
20
|
+
* @class
|
|
21
|
+
* @constructor
|
|
22
|
+
* @param {Connection} conn - Connection object
|
|
23
|
+
* @param {String} type - SObject type
|
|
24
|
+
* @param {String} id - Record ID
|
|
25
|
+
*/
|
|
26
|
+
var RecordReference = module.exports = function(conn, type, id) {
|
|
27
|
+
this._conn = conn;
|
|
28
|
+
this.type = type;
|
|
29
|
+
this.id = id;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Retrieve record field information
|
|
34
|
+
*
|
|
35
|
+
* @param {Object} [options] - Options for rest api.
|
|
36
|
+
* @param {Callback.<Record>} [callback] - Callback function
|
|
37
|
+
* @returns {Promise.<Record>}
|
|
38
|
+
*/
|
|
39
|
+
RecordReference.prototype.retrieve = function(options, callback) {
|
|
40
|
+
if (typeof options === 'function') {
|
|
41
|
+
callback = options;
|
|
42
|
+
options = {};
|
|
43
|
+
}
|
|
44
|
+
return this._conn.retrieve(this.type, this.id, options, callback);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Update record field information
|
|
49
|
+
*
|
|
50
|
+
* @param {Record} record - A Record which includes fields to update
|
|
51
|
+
* @param {Object} [options] - Options for rest api.
|
|
52
|
+
* @param {Callback.<RecordResult>} [callback] - Callback function
|
|
53
|
+
* @returns {Promise.<RecordResult>}
|
|
54
|
+
*/
|
|
55
|
+
RecordReference.prototype.update = function(record, options, callback) {
|
|
56
|
+
if (typeof options === 'function') {
|
|
57
|
+
callback = options;
|
|
58
|
+
options = {};
|
|
59
|
+
}
|
|
60
|
+
record = _.clone(record);
|
|
61
|
+
record.Id = this.id;
|
|
62
|
+
return this._conn.update(this.type, record, options, callback);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Synonym of Record#destroy()
|
|
67
|
+
*
|
|
68
|
+
* @method RecordReference#delete
|
|
69
|
+
* @param {Object} [options] - Options for rest api.
|
|
70
|
+
* @param {Callback.<RecordResult>} [callback] - Callback function
|
|
71
|
+
* @returns {Promise.<RecordResult>}
|
|
72
|
+
*/
|
|
73
|
+
RecordReference.prototype["delete"] =
|
|
74
|
+
/**
|
|
75
|
+
* Synonym of Record#destroy()
|
|
76
|
+
*
|
|
77
|
+
* @method RecordReference#del
|
|
78
|
+
* @param {Callback.<RecordResult>} [callback] - Callback function
|
|
79
|
+
* @returns {Promise.<RecordResult>}
|
|
80
|
+
*/
|
|
81
|
+
RecordReference.prototype.del =
|
|
82
|
+
/**
|
|
83
|
+
* Delete record field
|
|
84
|
+
*
|
|
85
|
+
* @method RecordReference#destroy
|
|
86
|
+
* @param {Object} [options] - Options for rest api.
|
|
87
|
+
* @param {Callback.<RecordResult>} [callback] - Callback function
|
|
88
|
+
* @returns {Promise.<RecordResult>}
|
|
89
|
+
*/
|
|
90
|
+
RecordReference.prototype.destroy = function(options, callback) {
|
|
91
|
+
if (typeof options === 'function') {
|
|
92
|
+
callback = options;
|
|
93
|
+
options = {};
|
|
94
|
+
}
|
|
95
|
+
return this._conn.destroy(this.type, this.id, options, callback);
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Get blob field as stream
|
|
100
|
+
*
|
|
101
|
+
* @param {String} fieldName - Blob field name
|
|
102
|
+
* @returns {stream.Stream}
|
|
103
|
+
*/
|
|
104
|
+
RecordReference.prototype.blob = function(fieldName) {
|
|
105
|
+
var url = [ this._conn._baseUrl(), 'sobjects', this.type, this.id, fieldName ].join('/');
|
|
106
|
+
return this._conn.request(url).stream();
|
|
107
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
var inherits = require('inherits');
|
|
2
|
+
var fs = require('fs');
|
|
3
|
+
var path = require('path');
|
|
4
|
+
var Registry = require('./registry');
|
|
5
|
+
|
|
6
|
+
/* ------------------------------------------------------------------------- */
|
|
7
|
+
|
|
8
|
+
var FileRegistry = function(configFilePath) {
|
|
9
|
+
FileRegistry.super_.call(this);
|
|
10
|
+
this._configFilePath = configFilePath || this._getDefaultConfigFilePath();
|
|
11
|
+
try {
|
|
12
|
+
var data = fs.readFileSync(this._configFilePath, 'utf-8');
|
|
13
|
+
this._registryConfig = JSON.parse(data);
|
|
14
|
+
} catch(e) {}
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
inherits(FileRegistry, Registry);
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
*
|
|
21
|
+
*/
|
|
22
|
+
FileRegistry.prototype._getDefaultConfigFilePath = function() {
|
|
23
|
+
var homeDir = process.env[(process.platform === 'win32') ? 'USERPROFILE' : 'HOME'];
|
|
24
|
+
var configDir = homeDir + "/.jsforce";
|
|
25
|
+
return configDir + "/config.json";
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @private
|
|
30
|
+
*/
|
|
31
|
+
FileRegistry.prototype._saveConfig = function() {
|
|
32
|
+
var data = JSON.stringify(this._registryConfig, null, 4);
|
|
33
|
+
try {
|
|
34
|
+
fs.writeFileSync(this._configFilePath, data);
|
|
35
|
+
fs.chmodSync(this._configFilePath, "600");
|
|
36
|
+
} catch(e) {
|
|
37
|
+
var configDir = path.dirname(this._configFilePath);
|
|
38
|
+
fs.mkdirSync(configDir);
|
|
39
|
+
fs.chmodSync(configDir, "700");
|
|
40
|
+
fs.writeFileSync(this._configFilePath, data);
|
|
41
|
+
fs.chmodSync(this._configFilePath, "600");
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
*
|
|
47
|
+
*/
|
|
48
|
+
module.exports = FileRegistry;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/*global process */
|
|
2
|
+
/**
|
|
3
|
+
* @file Registry for connection information, cached in local file system
|
|
4
|
+
* @author Shinichi Tomita <shinichi.tomita@gmail.com>
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
var _ = require('lodash/core');
|
|
10
|
+
var Connection = require('../connection');
|
|
11
|
+
|
|
12
|
+
/* */
|
|
13
|
+
var Registry = function(configFilePath) {
|
|
14
|
+
this._registryConfig = {};
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @private
|
|
19
|
+
* @override
|
|
20
|
+
*/
|
|
21
|
+
Registry.prototype._saveConfig = function() {
|
|
22
|
+
throw new Error('_saveConfig must be implemented in subclass');
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
Registry.prototype._getClients = function() {
|
|
26
|
+
return this._registryConfig.clients || (this._registryConfig.clients = {});
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
Registry.prototype._getConnections = function() {
|
|
30
|
+
return this._registryConfig.connections || (this._registryConfig.connections = {});
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
Registry.prototype.getConnectionNames = function() {
|
|
34
|
+
return Object.keys(this._getConnections());
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
Registry.prototype.getConnection = function(name) {
|
|
38
|
+
return new Connection(this.getConnectionConfig(name));
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
Registry.prototype.getConnectionConfig = function(name) {
|
|
42
|
+
if (!name) { name = this._registryConfig["default"]; }
|
|
43
|
+
var connections = this._getConnections();
|
|
44
|
+
var connConfig = connections[name];
|
|
45
|
+
if (connConfig) {
|
|
46
|
+
connConfig = _.clone(connConfig);
|
|
47
|
+
if (connConfig.client) {
|
|
48
|
+
connConfig.oauth2 = _.clone(this.getClient(connConfig.client));
|
|
49
|
+
}
|
|
50
|
+
delete connConfig.client;
|
|
51
|
+
}
|
|
52
|
+
return connConfig;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
Registry.prototype.saveConnectionConfig = function(name, connConfig) {
|
|
56
|
+
var connections = this._getConnections();
|
|
57
|
+
connConfig = _.clone(connConfig);
|
|
58
|
+
if (connConfig.oauth2) {
|
|
59
|
+
var clientName = this._findClientName(connConfig.oauth2);
|
|
60
|
+
if (clientName) {
|
|
61
|
+
connConfig.client = clientName;
|
|
62
|
+
}
|
|
63
|
+
delete connConfig.oauth2;
|
|
64
|
+
}
|
|
65
|
+
connections[name] = connConfig;
|
|
66
|
+
this._saveConfig();
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
Registry.prototype._findClientName = function(clientConfig) {
|
|
70
|
+
var clients = this._getClients();
|
|
71
|
+
for (var name in clients) {
|
|
72
|
+
var client = clients[name];
|
|
73
|
+
if (client.clientId === clientConfig.clientId &&
|
|
74
|
+
(client.loginUrl || 'https://login.salesforce.com') === clientConfig.loginUrl) {
|
|
75
|
+
return name;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return null;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
Registry.prototype.setDefaultConnection = function(name) {
|
|
82
|
+
this._registryConfig["default"] = name;
|
|
83
|
+
this._saveConfig();
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
Registry.prototype.removeConnectionConfig = function(name) {
|
|
87
|
+
var connections = this._getConnections();
|
|
88
|
+
delete connections[name];
|
|
89
|
+
this._saveConfig();
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
Registry.prototype.getClient = function(name) {
|
|
93
|
+
var clientConfig = this._getClients()[name];
|
|
94
|
+
return clientConfig && _.clone(clientConfig);
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
Registry.prototype.getClientNames = function() {
|
|
98
|
+
return Object.keys(this._getClients());
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
Registry.prototype.registerClient = function(name, clientConfig) {
|
|
102
|
+
var clients = this._getClients();
|
|
103
|
+
clients[name] = clientConfig;
|
|
104
|
+
this._saveConfig();
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
/* ------------------------------------------------------------------------- */
|
|
110
|
+
|
|
111
|
+
module.exports = Registry;
|
package/lib/require.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var required = require('./_required');
|
|
4
|
+
|
|
5
|
+
module.exports = function(name) {
|
|
6
|
+
if (name === './jsforce' || name === 'jsforce') {
|
|
7
|
+
name = './core';
|
|
8
|
+
}
|
|
9
|
+
var m = required[name];
|
|
10
|
+
if (typeof m === 'undefined') {
|
|
11
|
+
throw new Error("Cannot find module '" + name + "'");
|
|
12
|
+
}
|
|
13
|
+
return m;
|
|
14
|
+
};
|