jsforce
Version:
Salesforce API Library for JavaScript
1,225 lines (1,198 loc) • 159 kB
JavaScript
import _Object$getOwnPropertySymbols from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols";
import _filterInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/filter";
import _Object$getOwnPropertyDescriptor from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor";
import _forEachInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/for-each";
import _Object$getOwnPropertyDescriptors from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptors";
import _Object$defineProperties from "@babel/runtime-corejs3/core-js-stable/object/define-properties";
import _Object$defineProperty from "@babel/runtime-corejs3/core-js-stable/object/define-property";
import _Reflect$construct from "@babel/runtime-corejs3/core-js-stable/reflect/construct";
import _Array$from from "@babel/runtime-corejs3/core-js-stable/array/from";
import _Symbol from "@babel/runtime-corejs3/core-js-stable/symbol";
import _getIteratorMethod from "@babel/runtime-corejs3/core-js/get-iterator-method";
import _typeof from "@babel/runtime-corejs3/helpers/typeof";
import _asyncToGenerator from "@babel/runtime-corejs3/helpers/asyncToGenerator";
import _slicedToArray from "@babel/runtime-corejs3/helpers/slicedToArray";
import _toConsumableArray from "@babel/runtime-corejs3/helpers/toConsumableArray";
import _objectWithoutProperties from "@babel/runtime-corejs3/helpers/objectWithoutProperties";
import _classCallCheck from "@babel/runtime-corejs3/helpers/classCallCheck";
import _createClass from "@babel/runtime-corejs3/helpers/createClass";
import _possibleConstructorReturn from "@babel/runtime-corejs3/helpers/possibleConstructorReturn";
import _getPrototypeOf from "@babel/runtime-corejs3/helpers/getPrototypeOf";
import _inherits from "@babel/runtime-corejs3/helpers/inherits";
import _defineProperty from "@babel/runtime-corejs3/helpers/defineProperty";
var _excluded = ["fields", "includes", "sort"],
_excluded2 = ["conditions", "fields"];
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof _Symbol && _getIteratorMethod(r) || r["@@iterator"]; if (!t) { if (_Array$isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
function _unsupportedIterableToArray(r, a) { if (r) { var _context38; if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = _sliceInstanceProperty(_context38 = {}.toString.call(r)).call(_context38, 8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? _Array$from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
import _regeneratorRuntime from "@babel/runtime-corejs3/regenerator";
import "core-js/modules/es.error.cause.js";
import "core-js/modules/es.array.includes.js";
import "core-js/modules/es.array.join.js";
import "core-js/modules/es.array.push.js";
import "core-js/modules/es.array.sort.js";
import "core-js/modules/es.function.name.js";
import "core-js/modules/es.object.to-string.js";
import "core-js/modules/es.regexp.exec.js";
import "core-js/modules/es.regexp.test.js";
import "core-js/modules/es.regexp.to-string.js";
import "core-js/modules/es.string.includes.js";
import "core-js/modules/es.string.split.js";
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? _Reflect$construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
function ownKeys(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = _filterInstanceProperty(o).call(o, function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var _context36, _context37; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty(_context36 = ownKeys(Object(t), !0)).call(_context36, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : _forEachInstanceProperty(_context37 = ownKeys(Object(t))).call(_context37, function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
import _reduceInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/reduce";
import _sortInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/sort";
import _includesInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/includes";
import _JSON$stringify from "@babel/runtime-corejs3/core-js-stable/json/stringify";
import _Promise from "@babel/runtime-corejs3/core-js-stable/promise";
import _Array$isArray from "@babel/runtime-corejs3/core-js-stable/array/is-array";
import _mapInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/map";
import _concatInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/concat";
import _Object$entries from "@babel/runtime-corejs3/core-js-stable/object/entries";
import _Object$keys from "@babel/runtime-corejs3/core-js-stable/object/keys";
import _sliceInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/slice";
/**
* @file Manages query for records in Salesforce
* @author Shinichi Tomita <shinichi.tomita@gmail.com>
*/
import { EventEmitter } from 'events';
import { getLogger } from './util/logger';
import RecordStream, { Serializable } from './record-stream';
import { createSOQL } from './soql-builder';
/**
*
*/
/**
*
*/
/**
*
*/
var ResponseTargetValues = ['QueryResult', 'Records', 'SingleRecord', 'Count'];
export var ResponseTargets = _reduceInstanceProperty(ResponseTargetValues).call(ResponseTargetValues, function (values, target) {
return _objectSpread(_objectSpread({}, values), {}, _defineProperty({}, target, target));
}, {});
// QRT extends 'Count'
/**
*
*/
var DEFAULT_BULK_THRESHOLD = 200;
var DEFAULT_BULK_API_VERSION = 1;
/**
* Query
*/
export var Query = /*#__PURE__*/function (_EventEmitter) {
/**
*
*/
function Query(conn, config, options) {
var _this;
_classCallCheck(this, Query);
_this = _callSuper(this, Query);
_defineProperty(_this, "_config", {});
_defineProperty(_this, "_children", []);
_defineProperty(_this, "_executed", false);
_defineProperty(_this, "_finished", false);
_defineProperty(_this, "_chaining", false);
_defineProperty(_this, "totalSize", 0);
_defineProperty(_this, "totalFetched", 0);
_defineProperty(_this, "records", []);
/**
* Synonym of Query#skip()
*/
_defineProperty(_this, "offset", _this.skip);
/**
* Synonym of Query#sort()
*/
_defineProperty(_this, "orderby", _sortInstanceProperty(_this));
/**
* Synonym of Query#execute()
*/
_defineProperty(_this, "exec", _this.execute);
/**
* Synonym of Query#execute()
*/
_defineProperty(_this, "run", _this.execute);
/**
* Synonym of Query#destroy()
*/
_defineProperty(_this, "delete", _this.destroy);
/**
* Synonym of Query#destroy()
*/
_defineProperty(_this, "del", _this.destroy);
_this._conn = conn;
_this._logger = conn._logLevel ? Query._logger.createInstance(conn._logLevel) : Query._logger;
if (typeof config === 'string') {
_this._soql = config;
_this._logger.debug("config is soql: ".concat(config));
} else if (typeof config.locator === 'string') {
var locator = config.locator;
_this._logger.debug("config is locator: ".concat(locator));
_this._locator = _includesInstanceProperty(locator).call(locator, '/') ? _this.urlToLocator(locator) : locator;
} else {
_this._logger.debug("config is QueryConfig: ".concat(_JSON$stringify(config)));
var _ref = config,
_fields = _ref.fields,
includes = _includesInstanceProperty(_ref),
_sort2 = _sortInstanceProperty(_ref),
_config = _objectWithoutProperties(_ref, _excluded);
_this._config = _config;
_this.select(_fields);
if (includes) {
_this.includeChildren(includes);
}
if (_sort2) {
_sortInstanceProperty(_this).call(_this, _sort2);
}
}
_this._options = _objectSpread({
headers: {},
maxFetch: 10000,
autoFetch: false,
scanAll: false,
responseTarget: 'QueryResult'
}, options || {});
// promise instance
_this._promise = new _Promise(function (resolve, reject) {
_this.on('response', resolve);
_this.on('error', reject);
});
_this._stream = new Serializable();
_this.on('record', function (record) {
return _this._stream.push(record);
});
_this.on('end', function () {
return _this._stream.push(null);
});
_this.on('error', function (err) {
try {
_this._stream.emit('error', err);
} catch (e) {
// eslint-disable-line no-empty
}
});
return _this;
}
/**
* Select fields to include in the returning result
*/
_inherits(Query, _EventEmitter);
return _createClass(Query, [{
key: "select",
value: function select() {
var fields = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '*';
if (this._soql) {
throw Error('Cannot set select fields for the query which has already built SOQL.');
}
function toFieldArray(fields) {
var _context, _context2, _context4, _context5;
return typeof fields === 'string' ? fields.split(/\s*,\s*/) : _Array$isArray(fields) ? _reduceInstanceProperty(_context = _mapInstanceProperty(_context2 = fields).call(_context2, toFieldArray)).call(_context, function (fs, f) {
var _context3;
return _concatInstanceProperty(_context3 = []).call(_context3, _toConsumableArray(fs), _toConsumableArray(f));
}, []) : _reduceInstanceProperty(_context4 = _mapInstanceProperty(_context5 = _Object$entries(fields)).call(_context5, function (_ref2) {
var _ref3 = _slicedToArray(_ref2, 2),
f = _ref3[0],
v = _ref3[1];
if (typeof v === 'number' || typeof v === 'boolean') {
return v ? [f] : [];
} else {
var _context6;
return _mapInstanceProperty(_context6 = toFieldArray(v)).call(_context6, function (p) {
var _context7;
return _concatInstanceProperty(_context7 = "".concat(f, ".")).call(_context7, p);
});
}
})).call(_context4, function (fs, f) {
var _context8;
return _concatInstanceProperty(_context8 = []).call(_context8, _toConsumableArray(fs), _toConsumableArray(f));
}, []);
}
if (fields) {
this._config.fields = toFieldArray(fields);
}
// force convert query record type without changing instance;
return this;
}
/**
* Set query conditions to filter the result records
*/
}, {
key: "where",
value: function where(conditions) {
if (this._soql) {
throw Error('Cannot set where conditions for the query which has already built SOQL.');
}
this._config.conditions = conditions;
return this;
}
/**
* Limit the returning result
*/
}, {
key: "limit",
value: function limit(_limit) {
if (this._soql) {
throw Error('Cannot set limit for the query which has already built SOQL.');
}
this._config.limit = _limit;
return this;
}
/**
* Skip records
*/
}, {
key: "skip",
value: function skip(offset) {
if (this._soql) {
throw Error('Cannot set skip/offset for the query which has already built SOQL.');
}
this._config.offset = offset;
return this;
}
}, {
key: "sort",
value: function (_sort) {
function sort(_x, _x2) {
return _sort.apply(this, arguments);
}
sort.toString = function () {
return _sort.toString();
};
return sort;
}(function (sort, dir) {
if (this._soql) {
throw Error('Cannot set sort for the query which has already built SOQL.');
}
if (typeof sort === 'string' && typeof dir !== 'undefined') {
this._config.sort = [[sort, dir]];
} else {
this._config.sort = sort;
}
return this;
})
}, {
key: "include",
value: function include(childRelName, conditions, fields) {
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
if (this._soql) {
throw Error('Cannot include child relationship into the query which has already built SOQL.');
}
var childConfig = {
fields: fields === null ? undefined : fields,
table: childRelName,
conditions: conditions === null ? undefined : conditions,
limit: options.limit,
offset: options.offset,
sort: _sortInstanceProperty(options)
};
// eslint-disable-next-line no-use-before-define
var childQuery = new SubQuery(this._conn, childRelName, childConfig, this);
this._children.push(childQuery);
return childQuery;
}
/**
* Include child relationship queries, but not moving down to the children context
*/
}, {
key: "includeChildren",
value: function includeChildren(includes) {
if (this._soql) {
throw Error('Cannot include child relationship into the query which has already built SOQL.');
}
for (var _i = 0, _arr = _Object$keys(includes); _i < _arr.length; _i++) {
var crname = _arr[_i];
var _ref4 = includes[crname],
_conditions = _ref4.conditions,
_fields2 = _ref4.fields,
_options = _objectWithoutProperties(_ref4, _excluded2);
this.include(crname, _conditions, _fields2, _options);
}
return this;
}
/**
* Setting maxFetch query option
*/
}, {
key: "maxFetch",
value: function maxFetch(_maxFetch) {
this._options.maxFetch = _maxFetch;
return this;
}
/**
* Switching auto fetch mode
*/
}, {
key: "autoFetch",
value: function autoFetch(_autoFetch) {
this._options.autoFetch = _autoFetch;
return this;
}
/**
* Set flag to scan all records including deleted and archived.
*/
}, {
key: "scanAll",
value: function scanAll(_scanAll) {
this._options.scanAll = _scanAll;
return this;
}
/**
*
*/
}, {
key: "setResponseTarget",
value: function setResponseTarget(responseTarget) {
if (responseTarget in ResponseTargets) {
this._options.responseTarget = responseTarget;
}
// force change query response target without changing instance
return this;
}
/**
* Execute query and fetch records from server.
*/
}, {
key: "execute",
value: function execute() {
var _this2 = this;
var options_ = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
if (this._executed) {
throw new Error('re-executing already executed query');
}
if (this._finished) {
throw new Error('executing already closed query');
}
var options = {
headers: options_.headers || this._options.headers,
responseTarget: options_.responseTarget || this._options.responseTarget,
autoFetch: options_.autoFetch || this._options.autoFetch,
maxFetch: options_.maxFetch || this._options.maxFetch,
scanAll: options_.scanAll || this._options.scanAll
};
// collect fetched records in array
// only when response target is Records and
// either callback or chaining promises are available to this query.
this.once('fetch', function () {
if (options.responseTarget === ResponseTargets.Records && _this2._chaining) {
_this2._logger.debug('--- collecting all fetched records ---');
var records = [];
var onRecord = function onRecord(record) {
return records.push(record);
};
_this2.on('record', onRecord);
_this2.once('end', function () {
_this2.removeListener('record', onRecord);
_this2.emit('response', records, _this2);
});
}
});
// flag to prevent re-execution
this._executed = true;
_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
return _regeneratorRuntime.wrap(function _callee$(_context9) {
while (1) switch (_context9.prev = _context9.next) {
case 0:
// start actual query
_this2._logger.debug('>>> Query start >>>');
_context9.prev = 1;
_context9.next = 4;
return _this2._execute(options);
case 4:
_this2._logger.debug('*** Query finished ***');
_context9.next = 11;
break;
case 7:
_context9.prev = 7;
_context9.t0 = _context9["catch"](1);
_this2._logger.debug('--- Query error ---', _context9.t0);
_this2.emit('error', _context9.t0);
case 11:
case "end":
return _context9.stop();
}
}, _callee, null, [[1, 7]]);
}))();
// return Query instance for chaining
return this;
}
}, {
key: "locatorToUrl",
value: function locatorToUrl() {
return this._locator ? [this._conn._baseUrl(), '/query/', this._locator].join('') : '';
}
}, {
key: "urlToLocator",
value: function urlToLocator(url) {
return url.split('/').pop();
}
}, {
key: "constructResponse",
value: function constructResponse(rawDone, responseTarget) {
var _this$records$, _this$records;
switch (responseTarget) {
case 'Count':
return this.totalSize;
case 'SingleRecord':
return (_this$records$ = (_this$records = this.records) === null || _this$records === void 0 ? void 0 : _this$records[0]) !== null && _this$records$ !== void 0 ? _this$records$ : null;
case 'Records':
return this.records;
// QueryResult is default response target
default:
return _objectSpread(_objectSpread({}, {
records: this.records,
totalSize: this.totalSize,
done: rawDone !== null && rawDone !== void 0 ? rawDone : true // when no records, done is omitted
}), this._locator ? {
nextRecordsUrl: this.locatorToUrl()
} : {});
}
}
/**
* @private
*/
}, {
key: "_execute",
value: (function () {
var _execute2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2(options) {
var _this$records2, _context10, _data$records$length, _data$records;
var headers, responseTarget, autoFetch, maxFetch, scanAll, url, soql, data, recordKeys, _iterator, _step, record, _iterator2, _step2, key, _field, numRecords, totalFetched, i, _record, response;
return _regeneratorRuntime.wrap(function _callee2$(_context11) {
while (1) switch (_context11.prev = _context11.next) {
case 0:
headers = options.headers, responseTarget = options.responseTarget, autoFetch = options.autoFetch, maxFetch = options.maxFetch, scanAll = options.scanAll;
this._logger.debug('execute with options', options);
if (!this._locator) {
_context11.next = 6;
break;
}
url = this.locatorToUrl();
_context11.next = 11;
break;
case 6:
_context11.next = 8;
return this.toSOQL();
case 8:
soql = _context11.sent;
this._logger.debug("SOQL = ".concat(soql));
url = [this._conn._baseUrl(), '/', scanAll ? 'queryAll' : 'query', '?q=', encodeURIComponent(soql)].join('');
case 11:
_context11.next = 13;
return this._conn.request({
method: 'GET',
url: url,
headers: headers
});
case 13:
data = _context11.sent;
this.emit('fetch');
this.totalSize = data.totalSize;
// If autoFetch is true, fetch all records for any subqueries
if (!(autoFetch && data.records.length > 0)) {
_context11.next = 59;
break;
}
recordKeys = _Object$keys(data.records[0]);
_iterator = _createForOfIteratorHelper(data.records);
_context11.prev = 19;
_iterator.s();
case 21:
if ((_step = _iterator.n()).done) {
_context11.next = 51;
break;
}
record = _step.value;
_iterator2 = _createForOfIteratorHelper(recordKeys);
_context11.prev = 24;
_iterator2.s();
case 26:
if ((_step2 = _iterator2.n()).done) {
_context11.next = 41;
break;
}
key = _step2.value;
_field = record[key];
if (!(_field && _typeof(_field) === 'object' && 'records' in _field && 'nextRecordsUrl' in _field)) {
_context11.next = 39;
break;
}
_context11.t0 = _objectSpread;
_context11.t1 = _objectSpread({}, _field);
_context11.t2 = {};
_context11.next = 35;
return this._fetchAllSubqueryRecords(record, key, headers);
case 35:
_context11.t3 = _context11.sent;
_context11.t4 = undefined;
_context11.t5 = {
records: _context11.t3,
done: true,
nextRecordsUrl: _context11.t4
};
record[key] = (0, _context11.t0)(_context11.t1, _context11.t2, _context11.t5);
case 39:
_context11.next = 26;
break;
case 41:
_context11.next = 46;
break;
case 43:
_context11.prev = 43;
_context11.t6 = _context11["catch"](24);
_iterator2.e(_context11.t6);
case 46:
_context11.prev = 46;
_iterator2.f();
return _context11.finish(46);
case 49:
_context11.next = 21;
break;
case 51:
_context11.next = 56;
break;
case 53:
_context11.prev = 53;
_context11.t7 = _context11["catch"](19);
_iterator.e(_context11.t7);
case 56:
_context11.prev = 56;
_iterator.f();
return _context11.finish(56);
case 59:
this.records = (_this$records2 = this.records) === null || _this$records2 === void 0 ? void 0 : _concatInstanceProperty(_this$records2).call(_this$records2, maxFetch - this.records.length > data.records.length ? data.records : _sliceInstanceProperty(_context10 = data.records).call(_context10, 0, maxFetch - this.records.length));
this._locator = data.nextRecordsUrl ? this.urlToLocator(data.nextRecordsUrl) : undefined;
this._finished = this._finished || data.done || !autoFetch || this.records.length === maxFetch ||
// this is what the response looks like when there are no results
data.records.length === 0 && data.done === undefined;
// streaming record instances
numRecords = (_data$records$length = (_data$records = data.records) === null || _data$records === void 0 ? void 0 : _data$records.length) !== null && _data$records$length !== void 0 ? _data$records$length : 0;
totalFetched = this.totalFetched;
i = 0;
case 65:
if (!(i < numRecords)) {
_context11.next = 75;
break;
}
if (!(totalFetched >= maxFetch)) {
_context11.next = 69;
break;
}
this._finished = true;
return _context11.abrupt("break", 75);
case 69:
_record = data.records[i];
this.emit('record', _record, totalFetched, this);
totalFetched += 1;
case 72:
i++;
_context11.next = 65;
break;
case 75:
this.totalFetched = totalFetched;
if (!this._finished) {
_context11.next = 83;
break;
}
response = this.constructResponse(data.done, responseTarget); // only fire response event when it should be notified per fetch
if (responseTarget !== ResponseTargets.Records) {
this.emit('response', response, this);
}
this.emit('end');
return _context11.abrupt("return", response);
case 83:
return _context11.abrupt("return", this._execute(options));
case 84:
case "end":
return _context11.stop();
}
}, _callee2, this, [[19, 53, 56, 59], [24, 43, 46, 49]]);
}));
function _execute(_x3) {
return _execute2.apply(this, arguments);
}
return _execute;
}()
/**
* Obtain readable stream instance
*/
)
}, {
key: "stream",
value: function stream() {
var type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'csv';
if (!this._finished && !this._executed) {
this.execute({
autoFetch: true
});
}
return type === 'record' ? this._stream : this._stream.stream(type);
}
/**
* Pipe the queried records to another stream
* This is for backward compatibility; Query is not a record stream instance anymore in 2.0.
* If you want a record stream instance, use `Query#stream('record')`.
*/
}, {
key: "pipe",
value: function pipe(stream) {
return this.stream('record').pipe(stream);
}
/**
* @protected
*/
}, {
key: "_expandFields",
value: (function () {
var _expandFields2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee4(sobject_) {
var _context12, _context13, _context14, _context16, _context17;
var _this$_config, _this$_config$fields, fields, _this$_config$table, table, sobject, _yield$Promise$all, _yield$Promise$all2, efields;
return _regeneratorRuntime.wrap(function _callee4$(_context18) {
while (1) switch (_context18.prev = _context18.next) {
case 0:
if (!this._soql) {
_context18.next = 2;
break;
}
throw new Error('Cannot expand fields for the query which has already built SOQL.');
case 2:
_this$_config = this._config, _this$_config$fields = _this$_config.fields, fields = _this$_config$fields === void 0 ? [] : _this$_config$fields, _this$_config$table = _this$_config.table, table = _this$_config$table === void 0 ? '' : _this$_config$table;
sobject = sobject_ || table;
this._logger.debug(_concatInstanceProperty(_context12 = "_expandFields: sobject = ".concat(sobject, ", fields = ")).call(_context12, fields.join(', ')));
_context18.next = 7;
return _Promise.all(_concatInstanceProperty(_context13 = [this._expandAsteriskFields(sobject, fields)]).call(_context13, _toConsumableArray(_mapInstanceProperty(_context14 = this._children).call(_context14, /*#__PURE__*/function () {
var _ref6 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3(childQuery) {
return _regeneratorRuntime.wrap(function _callee3$(_context15) {
while (1) switch (_context15.prev = _context15.next) {
case 0:
_context15.next = 2;
return childQuery._expandFields();
case 2:
return _context15.abrupt("return", []);
case 3:
case "end":
return _context15.stop();
}
}, _callee3);
}));
return function (_x5) {
return _ref6.apply(this, arguments);
};
}()))));
case 7:
_yield$Promise$all = _context18.sent;
_yield$Promise$all2 = _slicedToArray(_yield$Promise$all, 1);
efields = _yield$Promise$all2[0];
this._config.fields = efields;
this._config.includes = _reduceInstanceProperty(_context16 = _mapInstanceProperty(_context17 = this._children).call(_context17, function (cquery) {
var cconfig = cquery._query._config;
return [cconfig.table, cconfig];
})).call(_context16, function (includes, _ref7) {
var _ref8 = _slicedToArray(_ref7, 2),
ctable = _ref8[0],
cconfig = _ref8[1];
return _objectSpread(_objectSpread({}, includes), {}, _defineProperty({}, ctable, cconfig));
}, {});
case 12:
case "end":
return _context18.stop();
}
}, _callee4, this);
}));
function _expandFields(_x4) {
return _expandFields2.apply(this, arguments);
}
return _expandFields;
}()
/**
*
*/
)
}, {
key: "_findRelationObject",
value: (function () {
var _findRelationObject2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee5(relName) {
var _context19;
var table, sobject, upperRname, _iterator3, _step3, cr;
return _regeneratorRuntime.wrap(function _callee5$(_context20) {
while (1) switch (_context20.prev = _context20.next) {
case 0:
table = this._config.table;
if (table) {
_context20.next = 3;
break;
}
throw new Error('No table information provided in the query');
case 3:
this._logger.debug(_concatInstanceProperty(_context19 = "finding table for relation \"".concat(relName, "\" in \"")).call(_context19, table, "\"..."));
_context20.next = 6;
return this._conn.describe$(table);
case 6:
sobject = _context20.sent;
upperRname = relName.toUpperCase();
_iterator3 = _createForOfIteratorHelper(sobject.childRelationships);
_context20.prev = 9;
_iterator3.s();
case 11:
if ((_step3 = _iterator3.n()).done) {
_context20.next = 17;
break;
}
cr = _step3.value;
if (!((cr.relationshipName || '').toUpperCase() === upperRname && cr.childSObject)) {
_context20.next = 15;
break;
}
return _context20.abrupt("return", cr.childSObject);
case 15:
_context20.next = 11;
break;
case 17:
_context20.next = 22;
break;
case 19:
_context20.prev = 19;
_context20.t0 = _context20["catch"](9);
_iterator3.e(_context20.t0);
case 22:
_context20.prev = 22;
_iterator3.f();
return _context20.finish(22);
case 25:
throw new Error("No child relationship found: ".concat(relName));
case 26:
case "end":
return _context20.stop();
}
}, _callee5, this, [[9, 19, 22, 25]]);
}));
function _findRelationObject(_x6) {
return _findRelationObject2.apply(this, arguments);
}
return _findRelationObject;
}()
/**
*
*/
)
}, {
key: "_expandAsteriskFields",
value: (function () {
var _expandAsteriskFields2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee7(sobject, fields) {
var _this3 = this;
var expandedFields;
return _regeneratorRuntime.wrap(function _callee7$(_context23) {
while (1) switch (_context23.prev = _context23.next) {
case 0:
_context23.next = 2;
return _Promise.all(_mapInstanceProperty(fields).call(fields, /*#__PURE__*/function () {
var _ref9 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee6(field) {
return _regeneratorRuntime.wrap(function _callee6$(_context21) {
while (1) switch (_context21.prev = _context21.next) {
case 0:
return _context21.abrupt("return", _this3._expandAsteriskField(sobject, field));
case 1:
case "end":
return _context21.stop();
}
}, _callee6);
}));
return function (_x9) {
return _ref9.apply(this, arguments);
};
}()));
case 2:
expandedFields = _context23.sent;
return _context23.abrupt("return", _reduceInstanceProperty(expandedFields).call(expandedFields, function (eflds, flds) {
var _context22;
return _concatInstanceProperty(_context22 = []).call(_context22, _toConsumableArray(eflds), _toConsumableArray(flds));
}, []));
case 4:
case "end":
return _context23.stop();
}
}, _callee7);
}));
function _expandAsteriskFields(_x7, _x8) {
return _expandAsteriskFields2.apply(this, arguments);
}
return _expandAsteriskFields;
}()
/**
*
*/
)
}, {
key: "_expandAsteriskField",
value: (function () {
var _expandAsteriskField2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee8(sobject, field) {
var _context24;
var fpath, _context26, so, rname, _iterator4, _step4, f, rfield, referenceTo, rtable, fpaths;
return _regeneratorRuntime.wrap(function _callee8$(_context27) {
while (1) switch (_context27.prev = _context27.next) {
case 0:
this._logger.debug(_concatInstanceProperty(_context24 = "expanding field \"".concat(field, "\" in \"")).call(_context24, sobject, "\"..."));
fpath = field.split('.');
if (!(fpath[fpath.length - 1] === '*')) {
_context27.next = 34;
break;
}
_context27.next = 5;
return this._conn.describe$(sobject);
case 5:
so = _context27.sent;
this._logger.debug("table ".concat(sobject, " has been described"));
if (!(fpath.length > 1)) {
_context27.next = 33;
break;
}
rname = fpath.shift();
_iterator4 = _createForOfIteratorHelper(so.fields);
_context27.prev = 10;
_iterator4.s();
case 12:
if ((_step4 = _iterator4.n()).done) {
_context27.next = 24;
break;
}
f = _step4.value;
if (!(f.relationshipName && rname && f.relationshipName.toUpperCase() === rname.toUpperCase())) {
_context27.next = 22;
break;
}
rfield = f;
referenceTo = rfield.referenceTo || [];
rtable = referenceTo.length === 1 ? referenceTo[0] : 'Name';
_context27.next = 20;
return this._expandAsteriskField(rtable, fpath.join('.'));
case 20:
fpaths = _context27.sent;
return _context27.abrupt("return", _mapInstanceProperty(fpaths).call(fpaths, function (fp) {
var _context25;
return _concatInstanceProperty(_context25 = "".concat(rname, ".")).call(_context25, fp);
}));
case 22:
_context27.next = 12;
break;
case 24:
_context27.next = 29;
break;
case 26:
_context27.prev = 26;
_context27.t0 = _context27["catch"](10);
_iterator4.e(_context27.t0);
case 29:
_context27.prev = 29;
_iterator4.f();
return _context27.finish(29);
case 32:
return _context27.abrupt("return", []);
case 33:
return _context27.abrupt("return", _mapInstanceProperty(_context26 = so.fields).call(_context26, function (f) {
return f.name;
}));
case 34:
return _context27.abrupt("return", [field]);
case 35:
case "end":
return _context27.stop();
}
}, _callee8, this, [[10, 26, 29, 32]]);
}));
function _expandAsteriskField(_x10, _x11) {
return _expandAsteriskField2.apply(this, arguments);
}
return _expandAsteriskField;
}()
/**
* Explain plan for executing query
*/
)
}, {
key: "explain",
value: (function () {
var _explain = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee9() {
var soql, url;
return _regeneratorRuntime.wrap(function _callee9$(_context28) {
while (1) switch (_context28.prev = _context28.next) {
case 0:
_context28.next = 2;
return this.toSOQL();
case 2:
soql = _context28.sent;
this._logger.debug("SOQL = ".concat(soql));
url = "/query/?explain=".concat(encodeURIComponent(soql));
return _context28.abrupt("return", this._conn.request(url));
case 6:
case "end":
return _context28.stop();
}
}, _callee9, this);
}));
function explain() {
return _explain.apply(this, arguments);
}
return explain;
}()
/**
* Return SOQL expression for the query
*/
)
}, {
key: "toSOQL",
value: (function () {
var _toSOQL = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee10() {
return _regeneratorRuntime.wrap(function _callee10$(_context29) {
while (1) switch (_context29.prev = _context29.next) {
case 0:
if (!this._soql) {
_context29.next = 2;
break;
}
return _context29.abrupt("return", this._soql);
case 2:
_context29.next = 4;
return this._expandFields();
case 4:
return _context29.abrupt("return", createSOQL(this._config));
case 5:
case "end":
return _context29.stop();
}
}, _callee10, this);
}));
function toSOQL() {
return _toSOQL.apply(this, arguments);
}
return toSOQL;
}()
/**
* Promise/A+ interface
* http://promises-aplus.github.io/promises-spec/
*
* Delegate to deferred promise, return promise instance for query result
*/
)
}, {
key: "then",
value: function then(onResolve, onReject) {
this._chaining = true;
if (!this._finished && !this._executed) {
this.execute();
}
if (!this._promise) {
throw new Error('invalid state: promise is not set after query execution');
}
return this._promise.then(onResolve, onReject);
}
}, {
key: "catch",
value: function _catch(onReject) {
return this.then(null, onReject);
}
}, {
key: "promise",
value: function promise() {
// TODO(cristian): verify this is correct
return _Promise.resolve(this);
}
/**
* Bulk delete queried records
*/
}, {
key: "destroy",
value: function destroy(type, options) {
var _options$bulkApiVersi,
_this4 = this;
if (_typeof(type) === 'object' && type !== null) {
options = type;
type = undefined;
}
options = options || {};
var type_ = type || this._config.table;
if (!type_) {
throw new Error('SOQL based query needs SObject type information to bulk delete.');
}
// Set the threshold number to pass to bulk API
var thresholdNum = options.allowBulk === false ? -1 : typeof options.bulkThreshold === 'number' ? options.bulkThreshold :
// determine threshold if the connection version supports SObject collection API or not
this._conn._ensureVersion(42) ? DEFAULT_BULK_THRESHOLD : this._conn._maxRequest / 2;
var bulkApiVersion = (_options$bulkApiVersi = options.bulkApiVersion) !== null && _options$bulkApiVersi !== void 0 ? _options$bulkApiVersi : DEFAULT_BULK_API_VERSION;
return new _Promise(function (resolve, reject) {
var createBatch = function createBatch() {
return _this4._conn.sobject(type_).deleteBulk().on('response', resolve).on('error', reject);
};
var records = [];
var batch = null;
var handleRecord = function handleRecord(rec) {
if (!rec.Id) {
var err = new Error('Queried record does not include Salesforce record ID.');
_this4.emit('error', err);
return;
}
var record = {
Id: rec.Id
};
if (batch) {
batch.write(record);
} else {
records.push(record);
if (thresholdNum >= 0 && records.length > thresholdNum && bulkApiVersion === 1) {
// Use bulk delete instead of SObject REST API
batch = createBatch();
for (var _i2 = 0, _records = records; _i2 < _records.length; _i2++) {
var _record2 = _records[_i2];
batch.write(_record2);
}
records = [];
}
}
};
var handleEnd = function handleEnd() {
if (batch) {
batch.end();
} else {
var ids = _mapInstanceProperty(records).call(records, function (record) {
return record.Id;
});
if (records.length > thresholdNum && bulkApiVersion === 2) {
_this4._conn.bulk2.loadAndWaitForResults({
object: type_,
operation: 'delete',
input: records
}).then(function (allResults) {
return resolve(_this4.mapBulkV2ResultsToSaveResults(allResults));
}, reject);
} else {
_this4._conn.sobject(type_).destroy(ids, {
allowRecursive: true
}).then(resolve, reject);
}
}
};
_this4.stream('record').on('data', handleRecord).on('end', handleEnd).on('error', reject);
});
}
}, {
key: "update",
value: function update(mapping, type, options) {
var _options$bulkApiVersi2,
_this5 = this;
if (_typeof(type) === 'object' && type !== null) {
options = type;
type = undefined;
}
options = options || {};
var type_ = type || this._config && this._config.table;
if (!type_) {
throw new Error('SOQL based query needs SObject type information to bulk update.');
}
var updateStream = typeof mapping === 'function' ? _mapInstanceProperty(RecordStream).call(RecordStream, mapping) : RecordStream.recordMapStream(mapping, options.skipRecordTemplateEval);
// Set the threshold number to pass to bulk API
var thresholdNum = options.allowBulk === false ? -1 : typeof options.bulkThreshold === 'number' ? options.bulkThreshold :
// determine threshold if the connection version supports SObject collection API or not
this._conn._ensureVersion(42) ? DEFAULT_BULK_THRESHOLD : this._conn._maxRequest / 2;
var bulkApiVersion = (_options$bulkApiVersi2 = options.bulkApiVersion) !== null && _options$bulkApiVersi2 !== void 0 ? _options$bulkApiVersi2 : DEFAULT_BULK_API_VERSION;
return new _Promise(function (resolve, reject) {
var createBatch = function createBatch() {
return _this5._conn.sobject(type_).updateBulk().on('response', resolve).on('error', reject);
};
var records = [];
var batch = null;
var handleRecord = function handleRecord(record) {
if (batch) {
batch.write(record);
} else {
records.push(record);
}
if (thresholdNum >= 0 && records.length > thresholdNum && bulkApiVersion === 1) {
// Use bulk update instead of SObject REST API
batch = createBatch();
for (var _i3 = 0, _records2 = records; _i3 < _records2.length; _i3++) {
var _record3 = _records2[_i3];
batch.write(_record3);
}
records = [];
}
};
var handleEnd = function handleEnd() {
if (batch) {
batch.end();
} else {
if (records.length > thresholdNum && bulkApiVersion === 2) {
_this5._conn.bulk2.loadAndWaitForResults({
object: type_,
operation: 'update',
input: records
}).then(function (allResults) {
return resolve(_this5.mapBulkV2ResultsToSaveResults(allResults));
}, reject);
} else {
_this5._conn.sobject(type_).update(records, {
allowRecursive: true
}).then(resolve, reject);
}
}
};
_this5.stream('record').on('error', reject).pipe(updateStream).on('data', handleRecord).on('end', handleEnd).on('error', reject);
});
}
}, {
key: "mapBulkV2ResultsToSaveResults",
value: function mapBulkV2ResultsToSaveResults(bulkJobAllResults) {
var _context30, _context31, _context32;
var successSaveResults = _mapInstanceProperty(_context30 = bulkJobAllResults.successfulResults).call(_context30, function (r) {
var saveResult = {
id: r.sf__Id,
success: true,
errors: []
};
return saveResult;
});
var failedSaveResults = _mapInstanceProperty(_context31 = bulkJobAllResults.failedResults).call(_context31, function (r) {
var saveResult = {
success: false,
errors: [{
errorCode: r.sf__Error,
message: r.sf__Error
}]
};
return saveResult;
});
return _concatInstanceProperty(_context32 = []).call(_context32, _toConsumableArray(successSaveResults), _toConsumableArray(failedSaveResults));
}
/**
* Fetches all records for a subquery field by following nextRecordsUrl
* @private
*/
}, {
key: "_fetchAllSubqueryRecords",
value: (function () {
var _fetchAllSubqueryRecords2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee11(record, fieldName, headers) {
var subqueryField, allRecords, nextRecordsUrl, data;
return _regeneratorRuntime.wrap(function _callee11$(_context33) {
while (1) switch (_context33.prev = _context33.next) {
case 0:
subqueryField = record[fieldName];
if (!(!subqueryField || !subqueryField.records)) {
_context33.next = 3;
break;
}
return _context33.abrupt("return", []);
case 3:
allRecords = _toConsumableArray(subqueryField.records);
nextRecordsUrl = subqueryField.nextRecordsUrl;
case 5:
if (!nextRecordsUrl) {
_context33.next = 13;
break;
}
_context33.next = 8;
return this._conn.request({
method: 'GET',
url: nextRecordsUrl,
// Use the full URL as provided by Salesforce
headers: headers
});
case 8: