UNPKG

jsforce

Version:

Salesforce API Library for JavaScript

1,110 lines (1,081 loc) 113 kB
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