jsforce
Version:
Salesforce API Library for JavaScript
1,110 lines (1,081 loc) • 113 kB
JavaScript
import _Reflect$construct from "@babel/runtime-corejs3/core-js-stable/reflect/construct";
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 _sliceInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/slice";
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 _readOnlyError from "@babel/runtime-corejs3/helpers/readOnlyError";
import _objectWithoutProperties from "@babel/runtime-corejs3/helpers/objectWithoutProperties";
import _defineProperty from "@babel/runtime-corejs3/helpers/defineProperty";
import _wrapNativeSuper from "@babel/runtime-corejs3/helpers/wrapNativeSuper";
import _asyncToGenerator from "@babel/runtime-corejs3/helpers/asyncToGenerator";
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";
var _excluded = ["Id", "type", "attributes"],
_excluded2 = ["path", "responseType"];
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 _context25; if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = _sliceInstanceProperty(_context25 = {}.toString.call(r)).call(_context25, 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; }
function ownKeys(e, r) { var t = _Object$keys2(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 _context23, _context24; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty(_context23 = ownKeys(Object(t), !0)).call(_context23, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : _forEachInstanceProperty(_context24 = ownKeys(Object(t))).call(_context24, function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
import _regeneratorRuntime from "@babel/runtime-corejs3/regenerator";
import _trimInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/trim";
import _concatInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/concat";
import _Promise from "@babel/runtime-corejs3/core-js-stable/promise";
import _Array$isArray from "@babel/runtime-corejs3/core-js-stable/array/is-array";
import _Object$keys2 from "@babel/runtime-corejs3/core-js-stable/object/keys";
import _parseInt from "@babel/runtime-corejs3/core-js-stable/parse-int";
import _setTimeout from "@babel/runtime-corejs3/core-js-stable/set-timeout";
import _mapInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/map";
import _includesInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/includes";
import "core-js/modules/es.error.cause.js";
import "core-js/modules/es.array.iterator.js";
import "core-js/modules/es.array.join.js";
import "core-js/modules/es.array.push.js";
import "core-js/modules/es.function.name.js";
import "core-js/modules/es.map.js";
import "core-js/modules/es.object.keys.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.set.js";
import "core-js/modules/es.string.match.js";
import "core-js/modules/es.string.replace.js";
import "core-js/modules/web.dom-exception.constructor.js";
import "core-js/modules/web.dom-exception.stack.js";
import "core-js/modules/web.dom-exception.to-string-tag.js";
import "core-js/modules/web.structured-clone.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; })(); }
/**
* @file Manages Salesforce Bulk API related operations
* @author Shinichi Tomita <shinichi.tomita@gmail.com>
*/
import { EventEmitter } from 'events';
import { Writable } from 'stream';
import joinStreams from 'multistream';
import { Serializable, Parsable } from '../record-stream';
import HttpApi from '../http-api';
import { registerModule } from '../jsforce';
import { concatStreamsAsDuplex } from '../util/stream';
import is from '@sindresorhus/is';
/*--------------------------------------------*/
// In `HttpApi.parseResponseBody` we use xml2js to parse the XML response,
// all these props are of type `string` due to how we convert XML -> JSON:
// https://github.com/Leonidas-from-XIV/node-xml2js/issues/108
//
// TODO: xml2js allows to define value processing functions, maybe do it for the next major release?
/**
* Class for Bulk API Job
*/
export var Job = /*#__PURE__*/function (_EventEmitter) {
/**
*
*/
function Job(bulk, type, operation, options, jobId) {
var _this;
_classCallCheck(this, Job);
_this = _callSuper(this, Job);
_this._bulk = bulk;
_this.type = type;
_this.operation = operation;
_this.options = options || {};
_this.id = jobId !== null && jobId !== void 0 ? jobId : null;
_this.state = _this.id ? 'Open' : 'Unknown';
_this._batches = {};
// default error handler to keep the latest error
_this.on('error', function (error) {
return _this._error = error;
});
return _this;
}
/**
* Return latest jobInfo from cache
*/
_inherits(Job, _EventEmitter);
return _createClass(Job, [{
key: "info",
value: function info() {
// if cache is not available, check the latest
if (!this._jobInfo) {
this._jobInfo = this.check();
}
return this._jobInfo;
}
/**
* Open new job and get jobinfo
*/
}, {
key: "open",
value: function open() {
var _this2 = this;
var bulk = this._bulk;
var options = this.options;
// if sobject type / operation is not provided
if (!this.type || !this.operation) {
throw new Error('type / operation is required to open a new job');
}
// if not requested opening job
if (!this._jobInfo) {
var _context, _context2, _context3, _context4, _context5;
var _operation = this.operation.toLowerCase();
if (_operation === 'harddelete') {
_operation = 'hardDelete';
}
if (_operation === 'queryall') {
_operation = 'queryAll';
}
var body = _trimInstanceProperty(_context = _concatInstanceProperty(_context2 = _concatInstanceProperty(_context3 = _concatInstanceProperty(_context4 = _concatInstanceProperty(_context5 = "\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<jobInfo xmlns=\"http://www.force.com/2009/06/asyncapi/dataload\">\n <operation>".concat(_operation, "</operation>\n <object>")).call(_context5, this.type, "</object>\n ")).call(_context4, options.extIdField ? "<externalIdFieldName>".concat(options.extIdField, "</externalIdFieldName>") : '', "\n ")).call(_context3, options.concurrencyMode ? "<concurrencyMode>".concat(options.concurrencyMode, "</concurrencyMode>") : '', "\n ")).call(_context2, options.assignmentRuleId ? "<assignmentRuleId>".concat(options.assignmentRuleId, "</assignmentRuleId>") : '', "\n <contentType>CSV</contentType>\n</jobInfo>\n ")).call(_context);
this._jobInfo = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
var res;
return _regeneratorRuntime.wrap(function _callee$(_context6) {
while (1) switch (_context6.prev = _context6.next) {
case 0:
_context6.prev = 0;
_context6.next = 3;
return bulk._request({
method: 'POST',
path: '/job',
body: body,
headers: {
'Content-Type': 'application/xml; charset=utf-8'
},
responseType: 'application/xml'
});
case 3:
res = _context6.sent;
_this2.emit('open', res.jobInfo);
_this2.id = res.jobInfo.id;
_this2.state = res.jobInfo.state;
return _context6.abrupt("return", res.jobInfo);
case 10:
_context6.prev = 10;
_context6.t0 = _context6["catch"](0);
_this2.emit('error', _context6.t0);
throw _context6.t0;
case 14:
case "end":
return _context6.stop();
}
}, _callee, null, [[0, 10]]);
}))();
}
return this._jobInfo;
}
/**
* Create a new batch instance in the job
*/
}, {
key: "createBatch",
value: function createBatch() {
var _this3 = this;
var batch = new Batch(this);
batch.on('queue', function () {
_this3._batches[batch.id] = batch;
});
return batch;
}
/**
* Get a batch instance specified by given batch ID
*/
}, {
key: "batch",
value: function batch(batchId) {
var batch = this._batches[batchId];
if (!batch) {
batch = new Batch(this, batchId);
this._batches[batchId] = batch;
}
return batch;
}
/**
* Check the latest job status from server
*/
}, {
key: "check",
value: function check() {
var _this4 = this;
var bulk = this._bulk;
var logger = bulk._logger;
this._jobInfo = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
var jobId, res;
return _regeneratorRuntime.wrap(function _callee2$(_context7) {
while (1) switch (_context7.prev = _context7.next) {
case 0:
_context7.next = 2;
return _this4.ready();
case 2:
jobId = _context7.sent;
_context7.next = 5;
return bulk._request({
method: 'GET',
path: '/job/' + jobId,
responseType: 'application/xml'
});
case 5:
res = _context7.sent;
logger.debug(res.jobInfo);
_this4.id = res.jobInfo.id;
_this4.type = res.jobInfo.object;
_this4.operation = res.jobInfo.operation;
_this4.state = res.jobInfo.state;
return _context7.abrupt("return", res.jobInfo);
case 12:
case "end":
return _context7.stop();
}
}, _callee2);
}))();
return this._jobInfo;
}
/**
* Wait till the job is assigned to server
*/
}, {
key: "ready",
value: function ready() {
return this.id ? _Promise.resolve(this.id) : this.open().then(function (_ref3) {
var id = _ref3.id;
return id;
});
}
/**
* List all registered batch info in job
*/
}, {
key: "list",
value: (function () {
var _list = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3() {
var bulk, logger, jobId, res, batchInfoList;
return _regeneratorRuntime.wrap(function _callee3$(_context8) {
while (1) switch (_context8.prev = _context8.next) {
case 0:
bulk = this._bulk;
logger = bulk._logger;
_context8.next = 4;
return this.ready();
case 4:
jobId = _context8.sent;
_context8.next = 7;
return bulk._request({
method: 'GET',
path: '/job/' + jobId + '/batch',
responseType: 'application/xml'
});
case 7:
res = _context8.sent;
logger.debug(res.batchInfoList.batchInfo);
batchInfoList = _Array$isArray(res.batchInfoList.batchInfo) ? res.batchInfoList.batchInfo : [res.batchInfoList.batchInfo];
return _context8.abrupt("return", batchInfoList);
case 11:
case "end":
return _context8.stop();
}
}, _callee3, this);
}));
function list() {
return _list.apply(this, arguments);
}
return list;
}()
/**
* Close opened job
*/
)
}, {
key: "close",
value: (function () {
var _close = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee4() {
var jobInfo;
return _regeneratorRuntime.wrap(function _callee4$(_context9) {
while (1) switch (_context9.prev = _context9.next) {
case 0:
if (this.id) {
_context9.next = 2;
break;
}
return _context9.abrupt("return");
case 2:
_context9.prev = 2;
_context9.next = 5;
return this._changeState('Closed');
case 5:
jobInfo = _context9.sent;
this.id = null;
this.emit('close', jobInfo);
return _context9.abrupt("return", jobInfo);
case 11:
_context9.prev = 11;
_context9.t0 = _context9["catch"](2);
this.emit('error', _context9.t0);
throw _context9.t0;
case 15:
case "end":
return _context9.stop();
}
}, _callee4, this, [[2, 11]]);
}));
function close() {
return _close.apply(this, arguments);
}
return close;
}()
/**
* Set the status to abort
*/
)
}, {
key: "abort",
value: (function () {
var _abort = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee5() {
var jobInfo;
return _regeneratorRuntime.wrap(function _callee5$(_context10) {
while (1) switch (_context10.prev = _context10.next) {
case 0:
if (this.id) {
_context10.next = 2;
break;
}
return _context10.abrupt("return");
case 2:
_context10.prev = 2;
_context10.next = 5;
return this._changeState('Aborted');
case 5:
jobInfo = _context10.sent;
this.id = null;
this.emit('abort', jobInfo);
return _context10.abrupt("return", jobInfo);
case 11:
_context10.prev = 11;
_context10.t0 = _context10["catch"](2);
this.emit('error', _context10.t0);
throw _context10.t0;
case 15:
case "end":
return _context10.stop();
}
}, _callee5, this, [[2, 11]]);
}));
function abort() {
return _abort.apply(this, arguments);
}
return abort;
}()
/**
* @private
*/
)
}, {
key: "_changeState",
value: (function () {
var _changeState2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee7(state) {
var _this5 = this;
var bulk, logger;
return _regeneratorRuntime.wrap(function _callee7$(_context13) {
while (1) switch (_context13.prev = _context13.next) {
case 0:
bulk = this._bulk;
logger = bulk._logger;
this._jobInfo = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee6() {
var _context11;
var jobId, body, res;
return _regeneratorRuntime.wrap(function _callee6$(_context12) {
while (1) switch (_context12.prev = _context12.next) {
case 0:
_context12.next = 2;
return _this5.ready();
case 2:
jobId = _context12.sent;
body = _trimInstanceProperty(_context11 = " \n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n <jobInfo xmlns=\"http://www.force.com/2009/06/asyncapi/dataload\">\n <state>".concat(state, "</state>\n</jobInfo>\n ")).call(_context11);
_context12.next = 6;
return bulk._request({
method: 'POST',
path: '/job/' + jobId,
body: body,
headers: {
'Content-Type': 'application/xml; charset=utf-8'
},
responseType: 'application/xml'
});
case 6:
res = _context12.sent;
logger.debug(res.jobInfo);
_this5.state = res.jobInfo.state;
return _context12.abrupt("return", res.jobInfo);
case 10:
case "end":
return _context12.stop();
}
}, _callee6);
}))();
return _context13.abrupt("return", this._jobInfo);
case 4:
case "end":
return _context13.stop();
}
}, _callee7, this);
}));
function _changeState(_x) {
return _changeState2.apply(this, arguments);
}
return _changeState;
}())
}]);
}(EventEmitter);
/*--------------------------------------------*/
var PollingTimeoutError = /*#__PURE__*/function (_Error) {
/**
*
*/
function PollingTimeoutError(message, jobId, batchId) {
var _this6;
_classCallCheck(this, PollingTimeoutError);
_this6 = _callSuper(this, PollingTimeoutError, [message]);
_this6.name = 'PollingTimeout';
_this6.jobId = jobId;
_this6.batchId = batchId;
return _this6;
}
_inherits(PollingTimeoutError, _Error);
return _createClass(PollingTimeoutError);
}(/*#__PURE__*/_wrapNativeSuper(Error));
/*--------------------------------------------*/
/**
* Batch (extends Writable)
*/
export var Batch = /*#__PURE__*/function (_Writable) {
/**
*
*/
function Batch(job, id) {
var _this7;
_classCallCheck(this, Batch);
_this7 = _callSuper(this, Batch, [{
objectMode: true
}]);
_defineProperty(_this7, "run", _this7.execute);
_defineProperty(_this7, "exec", _this7.execute);
_this7.job = job;
_this7.id = id;
_this7._bulk = job._bulk;
// default error handler to keep the latest error
_this7.on('error', function (error) {
return _this7._error = error;
});
//
// setup data streams
//
var converterOptions = {
nullValue: '#N/A'
};
var uploadStream = _this7._uploadStream = new Serializable();
var uploadDataStream = uploadStream.stream('csv', converterOptions);
var downloadStream = _this7._downloadStream = new Parsable();
var downloadDataStream = downloadStream.stream('csv', converterOptions);
_this7.on('finish', function () {
return uploadStream.end();
});
uploadDataStream.once('readable', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee8() {
return _regeneratorRuntime.wrap(function _callee8$(_context14) {
while (1) switch (_context14.prev = _context14.next) {
case 0:
_context14.prev = 0;
_context14.next = 3;
return _this7.job.ready();
case 3:
// pipe upload data to batch API request stream
uploadDataStream.pipe(_this7._createRequestStream());
_context14.next = 9;
break;
case 6:
_context14.prev = 6;
_context14.t0 = _context14["catch"](0);
_this7.emit('error', _context14.t0);
case 9:
case "end":
return _context14.stop();
}
}, _callee8, null, [[0, 6]]);
})));
// duplex data stream, opened access to API programmers by Batch#stream()
_this7._dataStream = concatStreamsAsDuplex(uploadDataStream, downloadDataStream);
return _this7;
}
/**
* Connect batch API and create stream instance of request/response
*
* @private
*/
_inherits(Batch, _Writable);
return _createClass(Batch, [{
key: "_createRequestStream",
value: function _createRequestStream() {
var _this8 = this;
var bulk = this._bulk;
var logger = bulk._logger;
var req = bulk._request({
method: 'POST',
path: '/job/' + this.job.id + '/batch',
headers: {
'Content-Type': 'text/csv'
},
responseType: 'application/xml'
});
_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee9() {
var res;
return _regeneratorRuntime.wrap(function _callee9$(_context15) {
while (1) switch (_context15.prev = _context15.next) {
case 0:
_context15.prev = 0;
_context15.next = 3;
return req;
case 3:
res = _context15.sent;
logger.debug(res.batchInfo);
_this8.id = res.batchInfo.id;
_this8.emit('queue', res.batchInfo);
_context15.next = 12;
break;
case 9:
_context15.prev = 9;
_context15.t0 = _context15["catch"](0);
_this8.emit('error', _context15.t0);
case 12:
case "end":
return _context15.stop();
}
}, _callee9, null, [[0, 9]]);
}))();
return req.stream();
}
/**
* Implementation of Writable
*/
}, {
key: "_write",
value: function _write(record_, enc, cb) {
var Id = record_.Id,
type = record_.type,
attributes = record_.attributes,
rrec = _objectWithoutProperties(record_, _excluded);
var record;
switch (this.job.operation) {
case 'insert':
record = rrec;
break;
case 'delete':
case 'hardDelete':
record = {
Id: Id
};
break;
default:
record = _objectSpread({
Id: Id
}, rrec);
}
this._uploadStream.write(record, enc, cb);
}
/**
* Returns duplex stream which accepts CSV data input and batch result output
*/
}, {
key: "stream",
value: function stream() {
return this._dataStream;
}
/**
* Execute batch operation
*/
}, {
key: "execute",
value: function execute(input) {
var _this9 = this;
// if batch is already executed
if (this._result) {
throw new Error('Batch already executed.');
}
this._result = new _Promise(function (resolve, reject) {
_this9.once('response', resolve);
_this9.once('error', reject);
});
if (is.nodeStream(input)) {
// if input has stream.Readable interface
input.pipe(this._dataStream);
} else {
var recordData = structuredClone(input);
if (_Array$isArray(recordData)) {
var _iterator = _createForOfIteratorHelper(recordData),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var record = _step.value;
for (var _i = 0, _Object$keys = _Object$keys2(record); _i < _Object$keys.length; _i++) {
var key = _Object$keys[_i];
if (typeof record[key] === 'boolean') {
record[key] = String(record[key]);
}
}
this.write(record);
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
this.end();
} else if (typeof recordData === 'string') {
this._dataStream.write(recordData, 'utf8');
this._dataStream.end();
}
}
// return Batch instance for chaining
return this;
}
}, {
key: "then",
value:
/**
* Promise/A+ interface
* Delegate to promise, return promise instance for batch result
*/
function then(onResolved, onReject) {
if (!this._result) {
this.execute();
}
return this._result.then(onResolved, onReject);
}
/**
* Check the latest batch status in server
*/
}, {
key: "check",
value: (function () {
var _check = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee10() {
var bulk, logger, jobId, batchId, res;
return _regeneratorRuntime.wrap(function _callee10$(_context16) {
while (1) switch (_context16.prev = _context16.next) {
case 0:
bulk = this._bulk;
logger = bulk._logger;
jobId = this.job.id;
batchId = this.id;
if (!(!jobId || !batchId)) {
_context16.next = 6;
break;
}
throw new Error('Batch not started.');
case 6:
_context16.next = 8;
return bulk._request({
method: 'GET',
path: '/job/' + jobId + '/batch/' + batchId,
responseType: 'application/xml'
});
case 8:
res = _context16.sent;
logger.debug(res.batchInfo);
return _context16.abrupt("return", res.batchInfo);
case 11:
case "end":
return _context16.stop();
}
}, _callee10, this);
}));
function check() {
return _check.apply(this, arguments);
}
return check;
}()
/**
* Polling the batch result and retrieve
*/
)
}, {
key: "poll",
value: function _poll(interval, timeout) {
var _this10 = this;
var jobId = this.job.id;
var batchId = this.id;
if (!jobId || !batchId) {
throw new Error('Batch not started.');
}
var startTime = new Date().getTime();
var endTime = startTime + timeout;
if (timeout === 0) {
var _context17;
throw new PollingTimeoutError(_concatInstanceProperty(_context17 = "Skipping polling because of timeout = 0ms. Job Id = ".concat(jobId, " | Batch Id = ")).call(_context17, batchId), jobId, batchId);
}
var _poll = /*#__PURE__*/function () {
var _ref7 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee11() {
var now, err, res;
return _regeneratorRuntime.wrap(function _callee11$(_context18) {
while (1) switch (_context18.prev = _context18.next) {
case 0:
now = new Date().getTime();
if (!(endTime < now)) {
_context18.next = 5;
break;
}
err = new PollingTimeoutError('Polling time out. Job Id = ' + jobId + ' , batch Id = ' + batchId, jobId, batchId);
_this10.emit('error', err);
return _context18.abrupt("return");
case 5:
_context18.prev = 5;
_context18.next = 8;
return _this10.check();
case 8:
res = _context18.sent;
_context18.next = 15;
break;
case 11:
_context18.prev = 11;
_context18.t0 = _context18["catch"](5);
_this10.emit('error', _context18.t0);
return _context18.abrupt("return");
case 15:
if (res.state === 'Failed') {
if (_parseInt(res.numberRecordsProcessed, 10) > 0) {
_this10.retrieve();
} else {
_this10.emit('error', new Error(res.stateMessage));
}
} else if (res.state === 'Completed') {
_this10.retrieve();
} else if (res.state === 'NotProcessed') {
_this10.emit('error', new Error('Job has been aborted'));
} else {
_this10.emit('inProgress', res);
_setTimeout(_poll, interval);
}
case 16:
case "end":
return _context18.stop();
}
}, _callee11, null, [[5, 11]]);
}));
return function poll() {
return _ref7.apply(this, arguments);
};
}();
_setTimeout(_poll, interval);
}
/**
* Retrieve batch result
*/
}, {
key: "retrieve",
value: (function () {
var _retrieve = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee12() {
var bulk, jobId, job, batchId, resp, results, _context19, res, resultId, _res;
return _regeneratorRuntime.wrap(function _callee12$(_context20) {
while (1) switch (_context20.prev = _context20.next) {
case 0:
bulk = this._bulk;
jobId = this.job.id;
job = this.job;
batchId = this.id;
if (!(!jobId || !batchId)) {
_context20.next = 6;
break;
}
throw new Error('Batch not started.');
case 6:
_context20.prev = 6;
_context20.next = 9;
return bulk._request({
method: 'GET',
path: '/job/' + jobId + '/batch/' + batchId + '/result'
});
case 9:
resp = _context20.sent;
if (job.operation === 'query' || job.operation === 'queryAll') {
res = resp;
resultId = res['result-list'].result;
results = _mapInstanceProperty(_context19 = _Array$isArray(resultId) ? resultId : [resultId]).call(_context19, function (id) {
return {
id: id,
batchId: batchId,
jobId: jobId
};
});
} else {
_res = resp;
results = _mapInstanceProperty(_res).call(_res, function (ret) {
return {
id: ret.Id || null,
success: ret.Success === 'true',
created: ret.Created === 'true',
errors: ret.Error ? [ret.Error] : []
};
});
}
this.emit('response', results);
return _context20.abrupt("return", results);
case 15:
_context20.prev = 15;
_context20.t0 = _context20["catch"](6);
this.emit('error', _context20.t0);
throw _context20.t0;
case 19:
case "end":
return _context20.stop();
}
}, _callee12, this, [[6, 15]]);
}));
function retrieve() {
return _retrieve.apply(this, arguments);
}
return retrieve;
}()
/**
* Fetch query batch result as a record stream
*
* @param {String} resultId - Result id
* @returns {RecordStream} - Record stream, convertible to CSV data stream
*/
)
}, {
key: "result",
value: function result(resultId) {
var jobId = this.job.id;
var batchId = this.id;
if (!jobId || !batchId) {
throw new Error('Batch not started.');
}
var resultStream = new Parsable();
var resultDataStream = resultStream.stream('csv');
this._bulk._request({
method: 'GET',
path: '/job/' + jobId + '/batch/' + batchId + '/result/' + resultId,
responseType: 'application/octet-stream'
}).stream().pipe(resultDataStream);
return resultStream;
}
}]);
}(Writable);
/*--------------------------------------------*/
/**
*
*/
var BulkApi = /*#__PURE__*/function (_HttpApi) {
function BulkApi() {
_classCallCheck(this, BulkApi);
return _callSuper(this, BulkApi, arguments);
}
_inherits(BulkApi, _HttpApi);
return _createClass(BulkApi, [{
key: "beforeSend",
value: function beforeSend(request) {
var _this$_conn$accessTok;
request.headers = _objectSpread(_objectSpread({}, request.headers), {}, {
'X-SFDC-SESSION': (_this$_conn$accessTok = this._conn.accessToken) !== null && _this$_conn$accessTok !== void 0 ? _this$_conn$accessTok : ''
});
}
}, {
key: "isSessionExpired",
value: function isSessionExpired(response) {
var _context21;
return response.statusCode === 400 && _includesInstanceProperty(_context21 = response.body).call(_context21, '<exceptionCode>InvalidSessionId</exceptionCode>');
}
}, {
key: "hasErrorInResponseBody",
value: function hasErrorInResponseBody(body) {
return !!body.error;
}
}, {
key: "parseError",
value: function parseError(body) {
return {
errorCode: body.error.exceptionCode,
message: body.error.exceptionMessage
};
}
}]);
}(HttpApi);
/*--------------------------------------------*/
/**
* Class for Bulk API
*
* @class
*/
export var Bulk = /*#__PURE__*/function () {
/**
*
*/
function Bulk(conn) {
_classCallCheck(this, Bulk);
/**
* Polling interval in milliseconds
*
* Default: 1000 (1 second)
*/
_defineProperty(this, "pollInterval", 1000);
/**
* Polling timeout in milliseconds
*
* Default: 30000 (30 seconds)
*/
_defineProperty(this, "pollTimeout", 30000);
this._conn = conn;
this._logger = conn._logger;
}
/**
*
*/
return _createClass(Bulk, [{
key: "_request",
value: function _request(request_) {
var conn = this._conn;
var path = request_.path,
responseType = request_.responseType,
rreq = _objectWithoutProperties(request_, _excluded2);
var baseUrl = [conn.instanceUrl, 'services/async', conn.version].join('/');
var request = _objectSpread(_objectSpread({}, rreq), {}, {
url: baseUrl + path
});
return new BulkApi(this._conn, {
responseType: responseType
}).request(request);
}
/**
* Create and start bulkload job and batch
*
* This method will return a Batch instance (writable stream)
* which you can write records into as a CSV string.
*
* Batch also implements the a promise interface so you can `await` this method to get the job results.
*
* @example
* // Insert an array of records and get the job results
*
* const res = await connection.bulk.load('Account', 'insert', accounts)
*
* @example
* // Insert records from a csv file using the returned batch stream
*
* const csvFile = fs.createReadStream('accounts.csv')
*
* const batch = conn.bulk.load('Account', 'insert')
*
* // The `response` event is emitted when the job results are retrieved
* batch.on('response', res => {
* console.log(res)
* })
* csvFile.pipe(batch.stream())
*
*
*/
}, {
key: "load",
value: function load(type, operation, optionsOrInput, input) {
var _this11 = this;
var options = {};
if (typeof optionsOrInput === 'string' || _Array$isArray(optionsOrInput) || is.nodeStream(optionsOrInput)) {
// when options is not plain hash object, it is omitted
input = optionsOrInput;
} else {
options = optionsOrInput;
}
var job = this.createJob(type, operation, options);
var batch = job.createBatch();
var cleanup = function cleanup() {
return job.close();
};
var cleanupOnError = function cleanupOnError(err) {
if (err.name !== 'PollingTimeout') {
cleanup();
}
};
batch.on('response', cleanup);
batch.on('error', cleanupOnError);
batch.on('queue', function () {
batch === null || batch === void 0 || batch.poll(_this11.pollInterval, _this11.pollTimeout);
});
return batch.execute(input);
}
/**
* Execute bulk query and get record stream
*/
}, {
key: "query",
value: (function () {
var _query = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee13(soql) {
var _this12 = this;
var m, type, recordStream, dataStream, results, streams;
return _regeneratorRuntime.wrap(function _callee13$(_context22) {
while (1) switch (_context22.prev = _context22.next) {
case 0:
m = soql.replace(/\([\s\S]+\)/g, '').match(/FROM\s+(\w+)/i);
if (m) {
_context22.next = 3;
break;
}
throw new Error('No sobject type found in query, maybe caused by invalid SOQL.');
case 3:
type = m[1];
recordStream = new Parsable();
dataStream = recordStream.stream('csv');
_context22.next = 8;
return this.load(type, 'query', soql);
case 8:
results = _context22.sent;
streams = _mapInstanceProperty(results).call(results, function (result) {
return _this12.job(result.jobId).batch(result.batchId).result(result.id).stream();
});
joinStreams(streams).pipe(dataStream);
return _context22.abrupt("return", recordStream);
case 12:
case "end":
return _context22.stop();
}
}, _callee13, this);
}));
function query(_x2) {
return _query.apply(this, arguments);
}
return query;
}()
/**
* Create a new job instance
*/
)
}, {
key: "createJob",
value: function createJob(type, operation) {
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
return new Job(this, type, operation, options);
}
/**
* Get a job instance specified by given job ID
*
* @param {String} jobId - Job ID
* @returns {Bulk~Job}
*/
}, {
key: "job",
value: function job(jobId) {
return new Job(this, null, null, null, jobId);
}
}]);
}();
/*--------------------------------------------*/
/*
* Register hook in connection instantiation for dynamically adding this API module features
*/
registerModule('bulk', function (conn) {
return new Bulk(conn);
});
export default Bulk;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJFdmVudEVtaXR0ZXIiLCJXcml0YWJsZSIsImpvaW5TdHJlYW1zIiwiU2VyaWFsaXphYmxlIiwiUGFyc2FibGUiLCJIdHRwQXBpIiwicmVnaXN0ZXJNb2R1bGUiLCJjb25jYXRTdHJlYW1zQXNEdXBsZXgiLCJpcyIsIkpvYiIsIl9FdmVudEVtaXR0ZXIiLCJidWxrIiwidHlwZSIsIm9wZXJhdGlvbiIsIm9wdGlvbnMiLCJqb2JJZCIsIl90aGlzIiwiX2NsYXNzQ2FsbENoZWNrIiwiX2NhbGxTdXBlciIsIl9idWxrIiwiaWQiLCJzdGF0ZSIsIl9iYXRjaGVzIiwib24iLCJlcnJvciIsIl9lcnJvciIsIl9pbmhlcml0cyIsIl9jcmVhdGVDbGFzcyIsImtleSIsInZhbHVlIiwiaW5mbyIsIl9qb2JJbmZvIiwiY2hlY2siLCJvcGVuIiwiX3RoaXMyIiwiRXJyb3IiLCJfY29udGV4dCIsIl9jb250ZXh0MiIsIl9jb250ZXh0MyIsIl9jb250ZXh0NCIsIl9jb250ZXh0NSIsInRvTG93ZXJDYXNlIiwiYm9keSIsIl90cmltSW5zdGFuY2VQcm9wZXJ0eSIsIl9jb25jYXRJbnN0YW5jZVByb3BlcnR5IiwiY29uY2F0IiwiY2FsbCIsImV4dElkRmllbGQiLCJjb25jdXJyZW5jeU1vZGUiLCJhc3NpZ25tZW50UnVsZUlkIiwiX2FzeW5jVG9HZW5lcmF0b3IiLCJfcmVnZW5lcmF0b3JSdW50aW1lIiwibWFyayIsIl9jYWxsZWUiLCJyZXMiLCJ3cmFwIiwiX2NhbGxlZSQiLCJfY29udGV4dDYiLCJwcmV2IiwibmV4dCIsIl9yZXF1ZXN0IiwibWV0aG9kIiwicGF0aCIsImhlYWRlcnMiLCJyZXNwb25zZVR5cGUiLCJzZW50IiwiZW1pdCIsImpvYkluZm8iLCJhYnJ1cHQiLCJ0MCIsInN0b3AiLCJjcmVhdGVCYXRjaCIsIl90aGlzMyIsImJhdGNoIiwiQmF0Y2giLCJiYXRjaElkIiwiX3RoaXM0IiwibG9nZ2VyIiwiX2xvZ2dlciIsIl9jYWxsZWUyIiwiX2NhbGxlZTIkIiwiX2NvbnRleHQ3IiwicmVhZHkiLCJkZWJ1ZyIsIm9iamVjdCIsIl9Qcm9taXNlIiwicmVzb2x2ZSIsInRoZW4iLCJfcmVmMyIsIl9saXN0IiwiX2NhbGxlZTMiLCJiYXRjaEluZm9MaXN0IiwiX2NhbGxlZTMkIiwiX2NvbnRleHQ4IiwiYmF0Y2hJbmZvIiwiX0FycmF5JGlzQXJyYXkiLCJsaXN0IiwiYXBwbHkiLCJhcmd1bWVudHMiLCJfY2xvc2UiLCJfY2FsbGVlNCIsIl9jYWxsZWU0JCIsIl9jb250ZXh0OSIsIl9jaGFuZ2VTdGF0ZSIsImNsb3NlIiwiX2Fib3J0IiwiX2NhbGxlZTUiLCJfY2FsbGVlNSQiLCJfY29udGV4dDEwIiwiYWJvcnQiLCJfY2hhbmdlU3RhdGUyIiwiX2NhbGxlZTciLCJfdGhpczUiLCJfY2FsbGVlNyQiLCJfY29udGV4dDEzIiwiX2NhbGxlZTYiLCJfY29udGV4dDExIiwiX2NhbGxlZTYkIiwiX2NvbnRleHQxMiIsIl94IiwiUG9sbGluZ1RpbWVvdXRFcnJvciIsIl9FcnJvciIsIm1lc3NhZ2UiLCJfdGhpczYiLCJuYW1lIiwiX3dyYXBOYXRpdmVTdXBlciIsIl9Xcml0YWJsZSIsImpvYiIsIl90aGlzNyIsIm9iamVjdE1vZGUiLCJfZGVmaW5lUHJvcGVydHkiLCJleGVjdXRlIiwiY29udmVydGVyT3B0aW9ucyIsIm51bGxWYWx1ZSIsInVwbG9hZFN0cmVhbSIsIl91cGxvYWRTdHJlYW0iLCJ1cGxvYWREYXRhU3RyZWFtIiwic3RyZWFtIiwiZG93bmxvYWRTdHJlYW0iLCJfZG93bmxvYWRTdHJlYW0iLCJkb3dubG9hZERhdGFTdHJlYW0iLCJlbmQiLCJvbmNlIiwiX2NhbGxlZTgiLCJfY2FsbGVlOCQiLCJfY29udGV4dDE0IiwicGlwZSIsIl9jcmVhdGVSZXF1ZXN0U3RyZWFtIiwiX2RhdGFTdHJlYW0iLCJfdGhpczgiLCJyZXEiLCJfY2FsbGVlOSIsIl9jYWxsZWU5JCIsIl9jb250ZXh0MTUiLCJfd3JpdGUiLCJyZWNvcmRfIiwiZW5jIiwiY2IiLCJJZCIsImF0dHJpYnV0ZXMiLCJycmVjIiwiX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzIiwiX2V4Y2x1ZGVkIiwicmVjb3JkIiwiX29iamVjdFNwcmVhZCIsIndyaXRlIiwiaW5wdXQiLCJfdGhpczkiLCJfcmVzdWx0IiwicmVqZWN0Iiwibm9kZVN0cmVhbSIsInJlY29yZERhdGEiLCJzdHJ1Y3R1cmVkQ2xvbmUiLCJfaXRlcmF0b3IiLCJfY3JlYXRlRm9yT2ZJdGVyYXRvckhlbHBlciIsIl9zdGVwIiwicyIsIm4iLCJkb25lIiwiX2kiLCJfT2JqZWN0JGtleXMiLCJfT2JqZWN0JGtleXMyIiwibGVuZ3RoIiwiU3RyaW5nIiwiZXJyIiwiZSIsImYiLCJvblJlc29sdmVkIiwib25SZWplY3QiLCJfY2hlY2siLCJfY2FsbGVlMTAiLCJfY2FsbGVlMTAkIiwiX2NvbnRleHQxNiIsInBvbGwiLCJpbnRlcnZhbCIsInRpbWVvdXQiLCJfdGhpczEwIiwic3RhcnRUaW1lIiwiRGF0ZSIsImdldFRpbWUiLCJlbmRUaW1lIiwiX2NvbnRleHQxNyIsIl9yZWY3IiwiX2NhbGxlZTExIiwibm93IiwiX2NhbGxlZTExJCIsIl9jb250ZXh0MTgiLCJfcGFyc2VJbnQiLCJudW1iZXJSZWNvcmRzUHJvY2Vzc2VkIiwicmV0cmlldmUiLCJzdGF0ZU1lc3NhZ2UiLCJfc2V0VGltZW91dCIsIl9yZXRyaWV2ZSIsIl9jYWxsZWUxMiIsInJlc3AiLCJyZXN1bHRzIiwiX2NvbnRleHQxOSIsInJlc3VsdElkIiwiX3JlcyIsIl9jYWxsZWUxMiQiLCJfY29udGV4dDIwIiwicmVzdWx0IiwiX21hcEluc3RhbmNlUHJvcGVydHkiLCJyZXQiLCJzdWNjZXNzIiwiU3VjY2VzcyIsImNyZWF0ZWQiLCJDcmVhdGVkIiwiZXJyb3JzIiwicmVzdWx0U3RyZWFtIiwicmVzdWx0RGF0YVN0cmVhbSIsIkJ1bGtBcGkiLCJfSHR0cEFwaSIsImJlZm9yZVNlbmQiLCJyZXF1ZXN0IiwiX3RoaXMkX2Nvbm4kYWNjZXNzVG9rIiwiX2Nvbm4iLCJhY2Nlc3NUb2tlbiIsImlzU2Vzc2lvbkV4cGlyZWQiLCJyZXNwb25zZSIsIl9jb250ZXh0MjEiLCJzdGF0dXNDb2RlIiwiX2luY2x1ZGVzSW5zdGFuY2VQcm9wZXJ0eSIsImhhc0Vycm9ySW5SZXNwb25zZUJvZHkiLCJwYXJzZUVycm9yIiwiZXJyb3JDb2RlIiwiZXhjZXB0aW9uQ29kZSIsImV4Y2VwdGlvbk1lc3NhZ2UiLCJCdWxrIiwiY29ubiIsInJlcXVlc3RfIiwicnJlcSIsIl9leGNsdWRlZDIiLCJiYXNlVXJsIiwiaW5zdGFuY2VVcmwiLCJ2ZXJzaW9uIiwiam9pbiIsInVybCIsImxvYWQiLCJvcHRpb25zT3JJbnB1dCIsIl90aGlzMTEiLCJjcmVhdGVKb2IiLCJjbGVhbnVwIiwiY2xlYW51cE9uRXJyb3IiLCJwb2xsSW50ZXJ2YWwiLCJwb2xsVGltZW91dCIsIl9xdWVyeSIsIl9jYWxsZWUxMyIsInNvcWwiLCJfdGhpczEyIiwibSIsInJlY29yZFN0cmVhbSIsImRhdGFTdHJlYW0iLCJzdHJlYW1zIiwiX2NhbGxlZTEzJCIsIl9jb250ZXh0MjIiLCJyZXBsYWNlIiwibWF0Y2giLCJxdWVyeSIsIl94MiIsInVuZGVmaW5lZCJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hcGkvYnVsay50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBmaWxlIE1hbmFnZXMgU2FsZXNmb3JjZSBCdWxrIEFQSSByZWxhdGVkIG9wZXJhdGlvbnNcbiAqIEBhdXRob3IgU2hpbmljaGkgVG9taXRhIDxzaGluaWNoaS50b21pdGFAZ21haWwuY29tPlxuICovXG5pbXBvcnQgeyBFdmVudEVtaXR0ZXIgfSBmcm9tICdldmVudHMnO1xuaW1wb3J0IHsgRHVwbGV4LCBSZWFkYWJsZSwgV3JpdGFibGUgfSBmcm9tICdzdHJlYW0nO1xuaW1wb3J0IGpvaW5TdHJlYW1zIGZyb20gJ211bHRpc3RyZWFtJztcbmltcG9ydCBDb25uZWN0aW9uIGZyb20gJy4uL2Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgU2VyaWFsaXphYmxlLCBQYXJzYWJsZSB9IGZyb20gJy4uL3JlY29yZC1zdHJlYW0nO1xuaW1wb3J0IEh0dHBBcGkgZnJvbSAnLi4vaHR0cC1hcGknO1xuaW1wb3J0IHsgcmVnaXN0ZXJNb2R1bGUgfSBmcm9tICcuLi9qc2ZvcmNlJztcbmltcG9ydCB7IExvZ2dlciB9IGZyb20gJy4uL3V0aWwvbG9nZ2VyJztcbmltcG9ydCB7IGNvbmNhdFN0cmVhbXNBc0R1cGxleCB9IGZyb20gJy4uL3V0aWwvc3RyZWFtJztcbmltcG9ydCB7XG4gIEh0dHBNZXRob2RzLFxuICBIdHRwUmVxdWVzdCxcbiAgSHR0cFJlc3BvbnNlLFxuICBSZWNvcmQsXG4gIFNjaGVtYSxcbn0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IGlzIGZyb20gJ0BzaW5kcmVzb3JodXMvaXMnO1xuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuZXhwb3J0IHR5cGUgQnVsa09wZXJhdGlvbiA9XG4gIHwgJ2luc2VydCdcbiAgfCAndXBkYXRlJ1xuICB8ICd1cHNlcnQnXG4gIHwgJ2RlbGV0ZSdcbiAgfCAnaGFyZERlbGV0ZSdcbiAgfCAncXVlcnknXG4gIHwgJ3F1ZXJ5QWxsJztcblxuZXhwb3J0IHR5cGUgQnVsa09wdGlvbnMgPSB7XG4gIGV4dElkRmllbGQ/OiBzdHJpbmc7XG4gIGNvbmN1cnJlbmN5TW9kZT86ICdTZXJpYWwnIHwgJ1BhcmFsbGVsJztcbiAgYXNzaWdubWVudFJ1bGVJZD86IHN0cmluZztcbn07XG5cbmV4cG9ydCB0eXBlIEpvYlN0YXRlID0gJ09wZW4nIHwgJ0Nsb3NlZCcgfCAnQWJvcnRlZCcgfCAnRmFpbGVkJyB8ICdVbmtub3duJyB8ICdOb3RQcm9jZXNzZWQnO1xuXG4vLyBJbiBgSHR0cEFwaS5wYXJzZVJlc3BvbnNlQm9keWAgd2UgdXNlIHhtbDJqcyB0byBwYXJzZSB0aGUgWE1MIHJlc3BvbnNlLFxuLy8gYWxsIHRoZXNlIHByb3BzIGFyZSBvZiB0eXBlIGBzdHJpbmdgIGR1ZSB0byBob3cgd2UgY29udmVydCBYTUwgLT4gSlNPTjpcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9MZW9uaWRhcy1mcm9tLVhJVi9ub2RlLXhtbDJqcy9pc3N1ZXMvMTA4XG4vL1xuLy8gVE9ETzogeG1sMmpzIGFsbG93cyB0byBkZWZpbmUgdmFsdWUgcHJvY2Vzc2luZyBmdW5jdGlvbnMsIG1heWJlIGRvIGl0IGZvciB0aGUgbmV4dCBtYWpvciByZWxlYXNlP1xuZXhwb3J0IHR5cGUgSm9iSW5mbyA9IHtcbiAgaWQ6IHN0cmluZztcbiAgb2JqZWN0OiBzdHJpbmc7XG4gIG9wZXJhdGlvbjogQnVsa09wZXJhdGlvbjtcbiAgc3RhdGU6IEpvYlN0YXRlO1xuICBjcmVhdGVkQnlJZDogc3RyaW5nO1xuICBjcmVhdGVkRGF0ZTogc3RyaW5nO1xuICBzeXN0ZW1Nb2RzdGFtcDogc3RyaW5nO1xuICBjb25jdXJyZW5jeU1vZGU6IHN0cmluZztcbiAgY29udGVudFR5cGU6IHN0cmluZztcbiAgbnVtYmVyQmF0Y2hlc1F1ZXVlZDogc3RyaW5nO1xuICBudW1iZXJCYXRjaGVzSW5Qcm9ncmVzczogc3RyaW5nO1xuICBudW1iZXJCYXRjaGVzQ29tcGxldGVkOiBzdHJpbmc7XG4gIG51bWJlckJhdGNoZXNGYWlsZWQ6IHN0cmluZztcbiAgbnVtYmVyQmF0Y2hlc1RvdGFsOiBzdHJpbmc7XG4gIG51bWJlclJlY29yZHNQcm9jZXNzZWQ6IHN0cmluZztcbiAgbnVtYmVyUmV0cmllczogc3RyaW5nO1xuICBhcGlWZXJzaW9uOiBzdHJpbmc7XG4gIG51bWJlclJlY29yZHNGYWlsZWQ6IHN0cmluZztcbiAgdG90YWxQcm9jZXNzaW5nVGltZTogc3RyaW5nO1xuICBhcGlBY3RpdmVQcm9jZXNzaW5nVGltZTogc3RyaW5nO1xuICBhcGV4UHJvY2Vzc2luZ1RpbWU6IHN0cmluZztcbn07XG5cbnR5cGUgSm9iSW5mb1Jlc3BvbnNlID0ge1xuICBqb2JJbmZvOiBKb2JJbmZvO1xufTtcblxuZXhwb3J0IHR5cGUgQmF0Y2hTdGF0ZSA9XG4gIHwgJ1F1ZXVlZCdcbiAgfCAnSW5Qcm9ncmVzcydcbiAgfCAnQ29tcGxldGVkJ1xuICB8ICdGYWlsZWQnXG4gIHwgJ05vdFByb2Nlc3NlZCc7XG5cbmV4cG9ydCB0eXBlIEJhdGNoSW5mbyA9IHtcbiAgaWQ6IHN0cmluZztcbiAgam9iSWQ6IHN0cmluZztcbiAgc3RhdGU6IEJhdGNoU3RhdGU7XG4gIHN0YXRlTWVzc2FnZTogc3RyaW5nO1xuICBudW1iZXJSZWNvcmRzUHJvY2Vzc2VkOiBzdHJpbmc7XG4gIG51bWJlclJlY29yZHNGYWlsZWQ6IHN0cmluZztcbiAgdG90YWxQcm9jZXNzaW5nVGltZTogc3RyaW5nO1xufTtcblxudHlwZSBCYXRjaEluZm9SZXNwb25zZSA9IHtcbiAgYmF0Y2hJbmZvOiBCYXRjaEluZm87XG59O1xuXG50eXBlIEJhdGNoSW5mb0xpc3RSZXNwb25zZSA9IHtcbiAgYmF0Y2hJbmZvTGlzdDoge1xuICAgIGJhdGNoSW5mbzogQmF0Y2hJbmZvIHwgQmF0Y2hJbmZvW107XG4gIH07XG59O1xuXG5leHBvcnQgdHlwZSBCdWxrUXVlcnlCYXRjaFJlc3VsdCA9IEFycmF5PHtcbiAgaWQ6IHN0cmluZztcbiAgYmF0Y2hJZDogc3RyaW5nO1xuICBqb2JJZDogc3RyaW5nO1xufT47XG5cbmV4cG9ydCB0eXBlIEJ1bGtJbmdlc3RCYXRjaFJlc3VsdCA9IEFycmF5PHtcbiAgaWQ6IHN0cmluZyB8IG51bGw7XG4gIHN1Y2Nlc3M6IGJvb2xlYW47XG4gIGNyZWF0ZWQ6IGJvb2xlYW47XG4gIGVycm9yczogc3RyaW5nW107XG59PjtcblxuZXhwb3J0IHR5cGUgQmF0Y2hSZXN1bHQ8T3ByIGV4dGVuZHMgQnVsa09wZXJhdGlvbj4gPSBPcHIgZXh0ZW5kc1xuICB8ICdxdWVyeSdcbiAgfCAncXVlcnlBbGwnXG4gID8gQnVsa1F1ZXJ5QmF0Y2hSZXN1bHRcbiAgOiBCdWxrSW5nZXN0QmF0Y2hSZXN1bHQ7XG5cbnR5cGUgQnVsa0luZ2VzdFJlc3VsdFJlc3BvbnNlID0gQXJyYXk8e1xuICBJZDogc3RyaW5nO1xuICBTdWNjZXNzOiBzdHJpbmc7XG4gIENyZWF0ZWQ6IHN0cmluZztcbiAgRXJyb3I6IHN0cmluZztcbn0+O1xuXG50eXBlIEJ1bGtRdWVyeVJlc3VsdFJlc3BvbnNlID0ge1xuICAncmVzdWx0LWxpc3QnOiB7XG4gICAgcmVzdWx0OiBzdHJpbmcgfCBzdHJpbmdbXTtcbiAgfTtcbn07XG5cbmV4cG9ydCB0eXBlIEJ1bGtSZXF1ZXN0ID0ge1xuICBtZXRob2Q6IEh0dHBNZXRob2RzO1xuICBwYXRoPzogc3RyaW5nO1xuICBib2R5Pzogc3RyaW5nO1xuICBoZWFkZXJzPzogeyBbbmFtZTogc3RyaW5nXTogc3RyaW5nIH07XG4gIHJlc3BvbnNlVHlwZT86IHN0cmluZztcbn07XG5cbi8qKlxuICogQ2xhc3MgZm9yIEJ1bGsgQV