UNPKG

jsforce2

Version:

Salesforce API Library for JavaScript

1,416 lines (1,270 loc) 244 kB
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g=(g.jsforce||(g.jsforce = {}));g=(g.modules||(g.modules = {}));g=(g.api||(g.api = {}));g.Metadata = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ (function (process,Buffer){ /*global process, Buffer */ /** * @file Manages Salesforce Metadata API * @author Shinichi Tomita <shinichi.tomita@gmail.com> */ 'use strict'; var inherits = window.jsforce.require('inherits'), events = window.jsforce.require('events'), stream = window.jsforce.require('readable-stream'), _ = window.jsforce.require('lodash/core'), jsforce = window.jsforce.require('./core'), Promise = window.jsforce.require('./promise'), SOAP = window.jsforce.require('./soap'); /*--------------------------------------------*/ /** * Class for Salesforce Metadata API * * @class * @param {Connection} conn - Connection object */ var Metadata = module.exports = function(conn) { this._conn = conn; }; /** * Polling interval in milliseconds * @type {Number} */ Metadata.prototype.pollInterval = 1000; /** * Polling timeout in milliseconds * @type {Number} */ Metadata.prototype.pollTimeout = 10000; /** * Call Metadata API SOAP endpoint * * @private */ Metadata.prototype._invoke = function(method, message, callback) { var soapEndpoint = new SOAP(this._conn, { xmlns: "http://soap.sforce.com/2006/04/metadata", endpointUrl: this._conn.instanceUrl + "/services/Soap/m/" + this._conn.version }); return soapEndpoint.invoke(method, message).then(function(res) { return res.result; }).thenCall(callback); }; /** * @typedef {Object} Metadata~MetadataInfo * @prop {String} fullName - The name of the component */ /** * Asynchronously adds one or more new metadata components to the organization. * * @param {String} type - The type of metadata to create * @param {Metadata~MetadataInfo|Array.<Metadata~MetadataInfo>} metadata - Metadata to create * @param {Callback.<Metadata~AsyncResult|Array.<Metadata~AsyncResult>>} [callback] - Callback function * @returns {Metadata~AsyncResultLocator} */ Metadata.prototype.createAsync = function(type, metadata, callback) { if (Number(this._conn.version) > 30) { throw new Error("Async metadata CRUD calls are not supported on ver 31.0 or later."); } var convert = function(md) { md["@xsi:type"] = type; return md; }; var isArray = _.isArray(metadata); metadata = isArray ? _.map(metadata, convert) : convert(metadata); var res = this._invoke("create", { metadata: metadata }); return new AsyncResultLocator(this, res, isArray).thenCall(callback); }; /** * @typedef {Object} Metadata~SaveResult * @prop {Boolean} success - True if metadata is successfully saved * @prop {String} fullName - Full name of metadata object */ /** * @private */ function convertToSaveResult(result) { var saveResult = _.clone(result); saveResult.success = saveResult.success === 'true'; return saveResult; } /** * @typedef {Object} Metadata~UpsertResult * @prop {Boolean} success - True if metadata is successfully saved * @prop {String} fullName - Full name of metadata object * @prop {Boolean} created - True if metadata is newly created */ /** * @private */ function convertToUpsertResult(result) { var upsertResult = convertToSaveResult(result); upsertResult.created = upsertResult.created === 'true'; return upsertResult; } /** * Synonym of Metadata#create(). * * @method Metadata#createSync * @param {String} type - The type of metadata to create * @param {Metadata~MetadataInfo|Array.<Metadata~MetadataInfo>} metadata - Metadata to create * @param {Callback.<Metadata~SaveResult|Array.<Metadata~SaveResult>>} [callback] - Callback function * @returns {Promise.<Metadata~SaveResult|Array.<Metadata~SaveResult>>} */ /** * Synchronously adds one or more new metadata components to the organization. * * @method Metadata#create * @param {String} type - The type of metadata to create * @param {Metadata~MetadataInfo|Array.<Metadata~MetadataInfo>} metadata - Metadata to create * @param {Callback.<Metadata~SaveResult|Array.<Metadata~SaveResult>>} [callback] - Callback function * @returns {Promise.<Metadata~SaveResult|Array.<Metadata~SaveResult>>} */ Metadata.prototype.createSync = Metadata.prototype.create = function(type, metadata, callback) { var convert = function(md) { md["@xsi:type"] = type; return md; }; var isArray = _.isArray(metadata); metadata = isArray ? _.map(metadata, convert) : convert(metadata); return this._invoke("createMetadata", { metadata: metadata }).then(function(results) { return _.isArray(results) ? _.map(results, convertToSaveResult) : convertToSaveResult(results); }).thenCall(callback); }; /** * @private */ function convertToMetadataInfo(rec) { var metadataInfo = _.clone(rec); delete metadataInfo.$; return metadataInfo; } /** * Synonym of Metadata#read() * * @method Metadata#readSync * @param {String} type - The type of metadata to read * @param {String|Array.<String>} fullNames - full name(s) of metadata objects to read * @param {Callback.<Metadata~MetadataInfo|Array.<Metadata~MetadataInfo>>} [callback] - Callback function * @returns {Promise.<Array.<Metadata~MetadataInfo|Array.<Metadata~MetadataInfo>>>} */ /** * Synchronously read specified metadata components in the organization. * * @method Metadata#read * @param {String} type - The type of metadata to read * @param {String|Array.<String>} fullNames - full name(s) of metadata objects to read * @param {Callback.<Metadata~MetadataInfo|Array.<Metadata~MetadataInfo>>} [callback] - Callback function * @returns {Promise.<Array.<Metadata~MetadataInfo|Array.<Metadata~MetadataInfo>>>} */ Metadata.prototype.readSync = Metadata.prototype.read = function(type, fullNames, callback) { return this._invoke("readMetadata", { type: type, fullNames: fullNames }).then(function(res) { return _.isArray(res.records) ? _.map(res.records, convertToMetadataInfo) : convertToMetadataInfo(res.records); }).thenCall(callback); }; /** * @typedef {Object} Metadata~UpdateMetadataInfo * @prop {String} currentName - The API name of the component or field before the update * @prop {Metadata~MetadataInfo} metadata - Full specification of the component or field you wish to update */ /** * Asynchronously updates one or more metadata components in the organization. * * @param {String} type - The type of metadata to update * @param {Metadata~UpdateMetadataInfo|Array.<Metadata~UpdateMetadataInfo>} updateMetadata - Updating metadata * @param {Callback.<Metadata~AsyncResult|Array.<Metadata~AsyncResult>>} [callback] - Callback function * @returns {Metadata~AsyncResultLocator} */ Metadata.prototype.updateAsync = function(type, updateMetadata, callback) { if (Number(this._conn.version) > 30) { throw new Error("Async metadata CRUD calls are not supported on ver 31.0 or later."); } var convert = function(umd) { umd.metadata["@xsi:type"] = type; return umd; }; var isArray = _.isArray(updateMetadata); updateMetadata = isArray ? _.map(updateMetadata, convert) : convert(updateMetadata); var res = this._invoke("update", { updateMetadata: updateMetadata }); return new AsyncResultLocator(this, res, isArray).thenCall(callback); }; /** * Synonym of Metadata#update(). * * @method Metadata#updateSync * @param {String} type - The type of metadata to update * @param {Metadata~MetadataInfo|Array.<Metadata~MetadataInfo>} updateMetadata - Updating metadata * @param {Callback.<Metadata~SaveResult|Array.<Metadata~SaveResult>>} [callback] - Callback function * @returns {Promise.<Metadata~SaveResult|Array.<Metadata~SaveResult>>} */ /** * Synchronously updates one or more metadata components in the organization. * * @method Metadata#update * @param {String} type - The type of metadata to update * @param {Metadata~MetadataInfo|Array.<Metadata~MetadataInfo>} updateMetadata - Updating metadata * @param {Callback.<Metadata~SaveResult|Array.<Metadata~SaveResult>>} [callback] - Callback function * @returns {Promise.<Metadata~SaveResult|Array.<Metadata~SaveResult>>} */ Metadata.prototype.updateSync = Metadata.prototype.update = function(type, metadata, callback) { var convert = function(md) { md["@xsi:type"] = type; return md; }; var isArray = _.isArray(metadata); metadata = isArray ? _.map(metadata, convert) : convert(metadata); return this._invoke("updateMetadata", { metadata: metadata }).then(function(results) { return _.isArray(results) ? _.map(results, convertToSaveResult) : convertToSaveResult(results); }).thenCall(callback); }; /** * Synonym of Metadata#upsert(). * * @method Metadata#upsertSync * @param {String} type - The type of metadata to upsert * @param {Metadata~MetadataInfo|Array.<Metadata~MetadataInfo>} metadata - Upserting metadata * @param {Callback.<Metadata~UpsertResult|Array.<Metadata~UpsertResult>>} [callback] - Callback function * @returns {Promise.<Metadata~UpsertResult|Array.<Metadata~UpsertResult>>} */ /** * Upserts one or more components in your organization's data. * * @method Metadata#upsert * @param {String} type - The type of metadata to upsert * @param {Metadata~MetadataInfo|Array.<Metadata~MetadataInfo>} metadata - Upserting metadata * @param {Callback.<Metadata~UpsertResult|Array.<Metadata~UpsertResult>>} [callback] - Callback function * @returns {Promise.<Metadata~UpsertResult|Array.<Metadata~UpsertResult>>} */ Metadata.prototype.upsertSync = Metadata.prototype.upsert = function(type, metadata, callback) { var convert = function(md) { md["@xsi:type"] = type; return md; }; var isArray = _.isArray(metadata); metadata = isArray ? _.map(metadata, convert) : convert(metadata); return this._invoke("upsertMetadata", { metadata: metadata }).then(function(results) { return _.isArray(results) ? _.map(results, convertToUpsertResult) : convertToUpsertResult(results); }).thenCall(callback); }; /** * Asynchronously deletes specified metadata components in the organization. * * @param {String} type - The type of metadata to delete * @param {String|Metadata~MetadataInfo|Array.<String>|Array.<Metadata~MetadataInfo>} metadata - The fullName of metadata or metadata info to delete. If it is passed in fullName, the type parameter should not be empty. * @param {Callback.<Metadata~AsyncResult|Array.<Metadata~AsyncResult>>} [callback] - Callback function * @returns {Metadata~AsyncResultLocator} */ Metadata.prototype.deleteAsync = function(type, metadata, callback) { if (Number(this._conn.version) > 30) { throw new Error("Async metadata CRUD calls are not supported on ver 31.0 or later."); } var convert = function(md) { if (_.isString(md)) { md = { fullName : md }; } md["@xsi:type"] = type; return md; }; var isArray = _.isArray(metadata); metadata = isArray ? _.map(metadata, convert) : convert(metadata); var res = this._invoke("delete", { metadata: metadata }); return new AsyncResultLocator(this, res, isArray).thenCall(callback); }; /** * Synonym of Metadata#delete(). * * @deprecated * @method Metadata#del * @param {String} [type] - The type of metadata to delete * @param {String|Metadata~MetadataInfo|Array.<String>|Array.<Metadata~MetadataInfo>} metadata - The fullName of metadata or metadata info to delete. If it is passed in fullName, the type parameter should not be empty. * @param {Callback.<Metadata~AsyncResult|Array.<Metadata~AsyncResult>>} [callback] - Callback function * @returns {Metadata~AsyncResultLocator} */ /** * Synonym of Metadata#delete(). * * @method Metadata#deleteSync * @param {String} type - The type of metadata to delete * @param {String|Array.<String>} fullNames - The fullName of metadata to delete. * @param {Callback.<Metadata~SaveResult|Array.<Metadata~SaveResult>>} [callback] - Callback function * @returns {Promise.<Metadata~SaveResult|Array.<Metadata~SaveResult>>} */ /** * Synchronously deletes specified metadata components in the organization. * * @method Metadata#delete * @param {String} type - The type of metadata to delete * @param {String|Array.<String>} fullNames - The fullName of metadata to delete. * @param {Callback.<Metadata~SaveResult|Array.<Metadata~SaveResult>>} [callback] - Callback function * @returns {Promise.<Metadata~SaveResult|Array.<Metadata~SaveResult>>} */ Metadata.prototype.del = Metadata.prototype.deleteSync = Metadata.prototype["delete"] = function(type, fullNames, callback) { return this._invoke("deleteMetadata", { type: type, fullNames: fullNames }).then(function(results) { return _.isArray(results) ? _.map(results, convertToSaveResult) : convertToSaveResult(results); }).thenCall(callback); }; /** * Rename fullname of a metadata component in the organization * * @param {String} type - The type of metadata to delete * @param {String} oldFullName - The original fullName of metadata * @param {String} newFullName - The new fullName of metadata * @param {Callback.<Metadata~SaveResult>} [callback] - Callback function * @returns {Promise.<Metadata~SaveResult>} */ Metadata.prototype.rename = function(type, oldFullName, newFullName, callback) { return this._invoke("renameMetadata", { type: type, oldFullName: oldFullName, newFullName: newFullName }).then(function(result) { return convertToSaveResult(result); }).thenCall(callback); }; /** * Checks the status of asynchronous metadata calls * * @param {String|Array.<String>} ids - The asynchronous process ID(s) * @param {Callback.<Metadata~AsyncResult|Array.<Metadata~AsyncResult>>} [callback] - Callback function * @returns {Metadata~AsyncResultLocator} */ Metadata.prototype.checkStatus = function(ids, callback) { var isArray = _.isArray(ids); var res = this._invoke("checkStatus", { asyncProcessId: ids }); return new AsyncResultLocator(this, res, isArray).thenCall(callback); }; /** * @typedef {Object} Metadata~DescribeMetadataResult * @prop {Array.<Object>} metadataObjects - One or more metadata components and their attributes * @prop {Array.<String>} metadataObjects.childXmlNames - List of child sub-components for this component * @prop {String} metadataObjects.directoryName - The name of the directory in the .zip file that contains this component * @prop {Boolean} metadataObjects.inFolder - Indicates whether the component is in a folder or not * @prop {Boolean} metadataObjects.metaFile - Indicates whether the component requires an accompanying metadata file * @prop {String} metadataObjects.suffix - The file suffix for this component * @prop {String} metadataObjects.xmlName - The name of the root element in the metadata file for this component * @prop {String} organizationNamespace - The namespace of the organization * @prop {Boolean} partialSaveAllowed - Indicates whether rollbackOnError is allowed or not * @prop {Boolean} testRequired - Indicates whether tests are required or not */ /** * Retrieves the metadata which describes your organization, including Apex classes and triggers, * custom objects, custom fields on standard objects, tab sets that define an app, * and many other components. * * @param {String} [version] - The API version for which you want metadata; for example, 29.0 * @param {Callback.<Metadata~DescribeMetadataResult>} [callback] - Callback function * @returns {Promise.<Metadata~DescribeMetadataResult>} */ Metadata.prototype.describe = function(version, callback) { if (!_.isString(version)) { callback = version; version = this._conn.version; } return this._invoke("describeMetadata", { asOfVersion: version }).then(function(res) { res.metadataObjects = _.isArray(res.metadataObjects) ? res.metadataObjects : [ res.metadataObjects ]; res.metadataObjects = _.map(res.metadataObjects, function(mo) { if (mo.childXmlNames) { mo.childXmlNames = _.isArray(mo.childXmlNames) ? mo.childXmlNames: [ mo.childXmlNames ]; } mo.inFolder = mo.inFolder === 'true'; mo.metaFile = mo.metaFile === 'true'; return mo; }); res.partialSaveAllowed = res.partialSaveAllowed === 'true'; res.testRequired = res.testRequired === 'true'; return res; }).thenCall(callback); }; /** * @typedef {Object} Metadata~ListMetadataQuery * @prop {String} type - The metadata type, such as CustomObject, CustomField, or ApexClass * @prop {String} [folder] - The folder associated with the component. */ /** * @typedef {Object} Metadata~FileProperties * @prop {String} type - The metadata type, such as CustomObject, CustomField, or ApexClass * @prop {String} createdById - ID of the user who created the file * @prop {String} createdByName - Name of the user who created the file * @prop {String} createdDate - Date and time when the file was created * @prop {String} fileName - Name of the file * @prop {String} fullName - The file developer name used as a unique identifier for API access * @prop {String} id - ID of the file * @prop {String} lastModifiedById - ID of the user who last modified the file * @prop {String} lastModifiedByName - Name of the user who last modified the file * @prop {String} lastModifiedDate - Date and time that the file was last modified * @prop {String} [manageableState] - Indicates the manageable state of the specified component if it is contained in a package * @prop {String} [namespacePrefix] - The namespace prefix of the component */ /** * Retrieves property information about metadata components in your organization * * @param {Metadata~ListMetadataQuery|Array.<Metadata~ListMetadataQuery>} queries - The criteria object(s) specifing metadata to list * @param {String} [version] - The API version for which you want metadata; for example, 29.0 * @param {Callback.<Array.<Metadata~FileProperties>>} [callback] - Callback function * @returns {Promise.<Array.<Metadata~FileProperties>>} */ Metadata.prototype.list = function(queries, version, callback) { if (!_.isString(version)) { callback = version; version = this._conn.version; } if (!_.isArray(queries)) { queries = [ queries ]; } return this._invoke("listMetadata", { queries: queries, asOfVersion: version }, callback); }; /** * @typedef {Object} Metadata~RetrieveRequest */ /** * Retrieves XML file representations of components in an organization * * @param {Metadata~RetrieveRequest} request - Options for determining which packages or files are retrieved * @param {Callback.<Metadata~AsyncResult>} [callback] - Callback function * @returns {Metadata~RetrieveResultLocator} */ Metadata.prototype.retrieve = function(request, callback) { var res = this._invoke("retrieve", { request: request }); return new RetrieveResultLocator(this, res).thenCall(callback); }; /** * Checks the status of declarative metadata call retrieve() and returns the zip file contents * * @param {String} id - Async process id returned from previous retrieve request * @param {Callback.<Metadata~RetrieveResult>} [callback] - Callback function * @returns {Promise.<Metadata~RetrieveResult>} */ Metadata.prototype.checkRetrieveStatus = function(id, callback) { return this._invoke("checkRetrieveStatus", { asyncProcessId: id }, callback); }; /** * Deploy components into an organization using zipped file representations * * @param {stream.Stream|Buffer|String} zipInput - Zipped file input source in readable stream, binary buffer or Base64-encoded string * @param {Object} [options] - Options used in deployment * @param {Boolean} [options.allowMissingFiles] - Specifies whether a deploy succeeds even if files that are specified in package.xml but are not in the .zip file or not. * @param {Boolean} [options.autoUpdatePackage] - If a file is in the .zip file but not specified in package.xml, specifies whether the file should be automatically added to the package or not. * @param {Boolean} [options.checkOnly] - Indicates whether Apex classes and triggers are saved to the organization as part of the deployment (false) or not (true). * @param {Boolean} [options.ignoreWarnings] - Indicates whether a warning should allow a deployment to complete successfully (true) or not (false). Defaults to false. * @param {Boolean} [options.performRetrieve] - Indicates whether a retrieve() call is performed immediately after the deployment (true) or not (false). * @param {Boolean} [options.purgeOnDelete] - If true, the deleted components in the destructiveChanges.xml manifest file aren't stored in the Recycle Bin. * @param {Boolean} [options.rollbackOnError] - Indicates whether any failure causes a complete rollback (true) or not (false). * @param {Boolean} [options.runAllTests] - If true, all Apex tests defined in the organization are run. * @param {Array.<String>} [options.runTests] - A list of Apex tests to be run during deployment. * @param {Boolean} [options.singlePackage] - Indicates whether the specified .zip file points to a directory structure with a single package (true) or a set of packages (false). * @param {Callback.<Metadata~AsyncResult>} [callback] - Callback function * @returns {Metadata~DeployResultLocator} */ Metadata.prototype.deploy = function(zipInput, options, callback) { if (!options || _.isFunction(options)) { callback = options; options = {}; } var deferred = Promise.defer(); if (_.isObject(zipInput) && _.isFunction(zipInput.pipe)) { var bufs = []; zipInput.on('data', function(d) { bufs.push(d); }); zipInput.on('end', function() { deferred.resolve(Buffer.concat(bufs).toString('base64')); }); // zipInput.resume(); } else if (zipInput instanceof Buffer) { deferred.resolve(zipInput.toString('base64')); } else if (zipInput instanceof String || typeof zipInput === 'string') { deferred.resolve(zipInput); } else { throw "Unexpected zipInput type"; } var self = this; var res = deferred.promise.then(function(zipContentB64) { return self._invoke("deploy", { ZipFile: zipContentB64, DeployOptions: options }, callback); }); return new DeployResultLocator(this, res).thenCall(callback); }; /** * Checks the status of declarative metadata call deploy() * * @param {String} id - Async process id returned from previous deploy request * @param {Boolean} [includeDetails] - Sets the DeployResult object to include details information (default: false) * @param {Callback.<Metadata~DeployResult>} [callback] - Callback function * @returns {Promise.<Metadata~DeployResult>} */ Metadata.prototype.checkDeployStatus = function(id, includeDetails, callback) { if (_.isObject(includeDetails) || _.isBoolean(includeDetails)) { includeDetails = !!includeDetails; } else { callback = includeDetails; includeDetails = false; } return this._invoke("checkDeployStatus", { asyncProcessId: id, includeDetails : includeDetails }).then(function(res) { res.done = res.done === 'true'; res.success = res.success === 'true'; res.checkOnly = res.checkOnly === 'true'; res.runTestsEnabled = res.runTestsEnabled === 'true'; if (res.ignoreWarnings) { res.ignoreWarnings = res.ignoreWarnings === 'true'; } if (res.rollbackOnError) { res.rollbackOnError = res.rollbackOnError === 'true'; } res.numberComponentErrors = Number(res.numberComponentErrors); res.numberComponentsDeployed = Number(res.numberComponentsDeployed); res.numberComponentsTotal = Number(res.numberComponentsTotal); res.numberTestErrors = Number(res.numberTestErrors); res.numberTestsCompleted = Number(res.numberTestsCompleted); res.numberTestsTotal = Number(res.numberTestsTotal); return res; }).thenCall(callback); }; /*--------------------------------------------*/ /** * @typedef {Object} Metadata~AsyncResult * @prop {Boolean} done - Indicates whether the call has completed or not * @prop {String} id - ID of the component being created, updated, deleted, deployed, or retrieved * @prop {String} state - The state four possible values: Queued, InProgress, Completed, and Error. * @prop {String} [statusCode] - If an error occurred during the create(), update(), or delete() call, a status code is returned * @prop {String} [message] - Message corresponding to the statusCode field returned */ /** * The locator class for Metadata API asynchronous call result * * @protected * @class Metadata~AsyncResultLocator * @extends events.EventEmitter * @implements Promise.<Metadata~AsyncResult|Array.<Metadata~AsyncResult>> * @param {Metadata} meta - Metadata API object * @param {Promise.<Metadata~AsyncResult|Array.<Metadata~AsyncResult>>} results - Promise object for async result info * @param {Boolean} [isArray] - Indicates whether the async request is given in array or single object */ var AsyncResultLocator = function(meta, results, isArray) { this._meta = meta; this._results = results; this._isArray = isArray; }; inherits(AsyncResultLocator, events.EventEmitter); /** * Promise/A+ interface * http://promises-aplus.github.io/promises-spec/ * * Delegate to deferred promise, return promise instance for batch result * * @method Metadata~AsyncResultLocator#then */ AsyncResultLocator.prototype.then = function(onResolve, onReject) { var self = this; return this._results.then(function(results) { var convertType = function(res) { if (res.$ && res.$["xsi:nil"] === 'true') { return null; } res.done = res.done === 'true'; return res; }; results = _.isArray(results) ? _.map(results, convertType) : convertType(results); if (self._isArray && !_.isArray(results)) { results = [ results ]; } return onResolve(results); }, onReject); }; /** * Promise/A+ extension * Call "then" using given node-style callback function * * @method Metadata~AsyncResultLocator#thenCall */ AsyncResultLocator.prototype.thenCall = function(callback) { return _.isFunction(callback) ? this.then(function(res) { process.nextTick(function() { callback(null, res); }); }, function(err) { process.nextTick(function() { callback(err); }); }) : this; }; /** * Check the status of async request * * @method Metadata~AsyncResultLocator#check * @param {Callback.<Metadata~AsyncResult|Array.<Metadata~AsyncResult>>} [callback] - Callback function * @returns {Promise.<Metadata~AsyncResult|Array.<Metadata~AsyncResult>>} */ AsyncResultLocator.prototype.check = function(callback) { var self = this; var meta = this._meta; return this.then(function(results) { var ids = _.isArray(results) ? _.map(results, function(res){ return res.id; }) : results.id; self._ids = ids; return meta.checkStatus(ids); }).thenCall(callback); }; /** * Polling until async call status becomes complete or error * * @method Metadata~AsyncResultLocator#poll * @param {Number} interval - Polling interval in milliseconds * @param {Number} timeout - Polling timeout in milliseconds */ AsyncResultLocator.prototype.poll = function(interval, timeout) { var self = this; var startTime = new Date().getTime(); var poll = function() { var now = new Date().getTime(); if (startTime + timeout < now) { var errMsg = "Polling time out."; if (self._ids) { errMsg += " Process Id = " + self._ids; } self.emit('error', new Error(errMsg)); return; } self.check().then(function(results) { var done = true; var resultArr = _.isArray(results) ? results : [ results ]; for (var i=0, len=resultArr.length; i<len; i++) { var result = resultArr[i]; if (result && !result.done) { self.emit('progress', result); done = false; } } if (done) { self.emit('complete', results); } else { setTimeout(poll, interval); } }, function(err) { self.emit('error', err); }); }; setTimeout(poll, interval); }; /** * Check and wait until the async requests become in completed status * * @method Metadata~AsyncResultLocator#complete * @param {Callback.<Metadata~AsyncResult|Array.<Metadata~AsyncResult>>} [callback] - Callback function * @returns {Promise.<Metadata~AsyncResult|Array.<Metadata~AsyncResult>>} */ AsyncResultLocator.prototype.complete = function(callback) { var deferred = Promise.defer(); this.on('complete', function(results) { deferred.resolve(results); }); this.on('error', function(err) { deferred.reject(err); }); var meta = this._meta; this.poll(meta.pollInterval, meta.pollTimeout); return deferred.promise.thenCall(callback); }; /*--------------------------------------------*/ /** * The locator class to track retreive() Metadata API call result * * @protected * @class Metadata~RetrieveResultLocator * @extends Metadata~AsyncResultLocator * @param {Metadata} meta - Metadata API object * @param {Promise.<Metadata~AsyncResult>} result - Promise object for async result of retrieve call() */ var RetrieveResultLocator = function(meta, result) { RetrieveResultLocator.super_.call(this, meta, result); }; inherits(RetrieveResultLocator, AsyncResultLocator); /** * @typedef {Object} Metadata~RetrieveResult * @prop {Array.<Metadata~FileProperties>} fileProperties - Contains information about the properties of each component in the .zip file, and the manifest file package.xml * @prop {String} id - ID of the component being retrieved * @prop {Array.<Object>} messages - Contains information about the success or failure of the retrieve() call * @prop {String} zipFile - The zip file returned by the retrieve request. Base 64-encoded binary data */ /** * Check and wait until the async request becomes in completed status, * and retrieve the result data. * * @memthod Metadata~RetrieveResultLocator#complete * @param {Callback.<Metadata~RetrieveResult>} [callback] - Callback function * @returns {Promise.<Metadata~RetrieveResult>} */ RetrieveResultLocator.prototype.complete = function(callback) { var meta = this._meta; return RetrieveResultLocator.super_.prototype.complete.call(this).then(function(result) { return meta.checkRetrieveStatus(result.id); }).thenCall(callback); }; /** * Change the retrieved result to Node.js readable stream * * @method Metadata~RetrieveResultLocator#stream * @returns {stream.Readable} */ RetrieveResultLocator.prototype.stream = function() { var self = this; var resultStream = new stream.Readable(); var reading = false; resultStream._read = function() { if (reading) { return; } reading = true; self.complete(function(err, result) { if (err) { resultStream.emit('error', err); } else { resultStream.push(Buffer.from(result.zipFile, 'base64')); resultStream.push(null); } }); }; return resultStream; }; /*--------------------------------------------*/ /** * The locator class to track deploy() Metadata API call result * * @protected * @class Metadata~DeployResultLocator * @extends Metadata~AsyncResultLocator * @param {Metadata} meta - Metadata API object * @param {Promise.<Metadata~AsyncResult>} result - Promise object for async result of deploy() call */ var DeployResultLocator = function(meta, result) { DeployResultLocator.super_.call(this, meta, result); }; inherits(DeployResultLocator, AsyncResultLocator); /** * @typedef {Object} Metadata~DeployResult * @prop {String} id - ID of the component being deployed * @prop {Boolean} checkOnly - Indicates whether this deployment is being used to check the validity of the deployed files without making any changes in the organization or not * @prop {String} completedDate - Timestamp for when the deployment process ended * @prop {String} createdDate - Timestamp for when the deploy() call was received * @prop {Array.<Object>} [details] - Provides the details of a deployment that is in-progress or ended, if includeDetails is set to true in checkDeployStatus() call * @prop {Boolean} done - Indicates whether the server finished processing the deploy() call for the specified id * @prop {String} [errorMessage] - Message corresponding to the values in the errorStatusCode field * @prop {String} [errorStatusCode] - If an error occurred during the deploy() call, a status code is returned, and the message corresponding to the status code is returned in the errorMessagefield * @prop {Boolean} [ignoreWarnings] - Specifies whether a deployment should continue even if the deployment generates warnings * @prop {String} lastModifiedDate - Timestamp of the last update for the deployment process * @prop {Number} numberComponentErrors - The number of components that generated errors during this deployment * @prop {Number} numberComponentsDeployed - The number of components deployed in the deployment process * @prop {Number} numberComponentsTotal - The total number of components in the deployment * @prop {Number} numberTestErrors - The number of Apex tests that have generated errors during this deployment * @prop {Number} numberTestsCompleted - The number of completedApex tests for this deployment * @prop {Number} numberTestsTotal - The total number of Apex tests for this deployment * @prop {Boolean} [rollbackOnError] - Indicates whether any failure causes a complete rollback or not. Default is true. * @prop {String} startDate - Timestamp for when the deployment process began * @prop {String} status - Indicates the current state of the deployment * @prop {Boolean} success - Indicates whether the deployment was successful or not */ /** * Check and wait until the async request becomes in completed status, * and retrieve the result data. * * @method Metadata~DeployResultLocator#complete * @param {Callback.<Metadata~DeployResult>} [callback] - Callback function * @returns {Promise.<Metadata~DeployResult>} */ DeployResultLocator.prototype.complete = function(includeDetails, callback) { if (_.isFunction(includeDetails)) { callback = includeDetails; includeDetails = false; } var meta = this._meta; return DeployResultLocator.super_.prototype.complete.call(this).then(function(result) { return meta.checkDeployStatus(result.id, includeDetails); }).thenCall(callback); }; /*--------------------------------------------*/ /* * Register hook in connection instantiation for dynamically adding this API module features */ jsforce.on('connection:new', function(conn) { conn.metadata = new Metadata(conn); }); }).call(this,require('_process'),require("buffer").Buffer) },{"_process":5,"buffer":3}],2:[function(require,module,exports){ 'use strict' exports.byteLength = byteLength exports.toByteArray = toByteArray exports.fromByteArray = fromByteArray var lookup = [] var revLookup = [] var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' for (var i = 0, len = code.length; i < len; ++i) { lookup[i] = code[i] revLookup[code.charCodeAt(i)] = i } // Support decoding URL-safe base64 strings, as Node.js does. // See: https://en.wikipedia.org/wiki/Base64#URL_applications revLookup['-'.charCodeAt(0)] = 62 revLookup['_'.charCodeAt(0)] = 63 function getLens (b64) { var len = b64.length if (len % 4 > 0) { throw new Error('Invalid string. Length must be a multiple of 4') } // Trim off extra bytes after placeholder bytes are found // See: https://github.com/beatgammit/base64-js/issues/42 var validLen = b64.indexOf('=') if (validLen === -1) validLen = len var placeHoldersLen = validLen === len ? 0 : 4 - (validLen % 4) return [validLen, placeHoldersLen] } // base64 is 4/3 + up to two characters of the original data function byteLength (b64) { var lens = getLens(b64) var validLen = lens[0] var placeHoldersLen = lens[1] return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen } function _byteLength (b64, validLen, placeHoldersLen) { return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen } function toByteArray (b64) { var tmp var lens = getLens(b64) var validLen = lens[0] var placeHoldersLen = lens[1] var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen)) var curByte = 0 // if there are placeholders, only get up to the last complete 4 chars var len = placeHoldersLen > 0 ? validLen - 4 : validLen for (var i = 0; i < len; i += 4) { tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)] arr[curByte++] = (tmp >> 16) & 0xFF arr[curByte++] = (tmp >> 8) & 0xFF arr[curByte++] = tmp & 0xFF } if (placeHoldersLen === 2) { tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4) arr[curByte++] = tmp & 0xFF } if (placeHoldersLen === 1) { tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2) arr[curByte++] = (tmp >> 8) & 0xFF arr[curByte++] = tmp & 0xFF } return arr } function tripletToBase64 (num) { return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F] } function encodeChunk (uint8, start, end) { var tmp var output = [] for (var i = start; i < end; i += 3) { tmp = ((uint8[i] << 16) & 0xFF0000) + ((uint8[i + 1] << 8) & 0xFF00) + (uint8[i + 2] & 0xFF) output.push(tripletToBase64(tmp)) } return output.join('') } function fromByteArray (uint8) { var tmp var len = uint8.length var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes var parts = [] var maxChunkLength = 16383 // must be multiple of 3 // go through the array every three bytes, we'll deal with trailing stuff later for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { parts.push(encodeChunk( uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength) )) } // pad the end with zeros, but make sure to not forget the extra bytes if (extraBytes === 1) { tmp = uint8[len - 1] parts.push( lookup[tmp >> 2] + lookup[(tmp << 4) & 0x3F] + '==' ) } else if (extraBytes === 2) { tmp = (uint8[len - 2] << 8) + uint8[len - 1] parts.push( lookup[tmp >> 10] + lookup[(tmp >> 4) & 0x3F] + lookup[(tmp << 2) & 0x3F] + '=' ) } return parts.join('') } },{}],3:[function(require,module,exports){ /*! * The buffer module from node.js, for the browser. * * @author Feross Aboukhadijeh <https://feross.org> * @license MIT */ /* eslint-disable no-proto */ 'use strict' var base64 = require('base64-js') var ieee754 = require('ieee754') exports.Buffer = Buffer exports.SlowBuffer = SlowBuffer exports.INSPECT_MAX_BYTES = 50 var K_MAX_LENGTH = 0x7fffffff exports.kMaxLength = K_MAX_LENGTH /** * If `Buffer.TYPED_ARRAY_SUPPORT`: * === true Use Uint8Array implementation (fastest) * === false Print warning and recommend using `buffer` v4.x which has an Object * implementation (most compatible, even IE6) * * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, * Opera 11.6+, iOS 4.2+. * * We report that the browser does not support typed arrays if the are not subclassable * using __proto__. Firefox 4-29 lacks support for adding new properties to `Uint8Array` * (See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438). IE 10 lacks support * for __proto__ and has a buggy typed array implementation. */ Buffer.TYPED_ARRAY_SUPPORT = typedArraySupport() if (!Buffer.TYPED_ARRAY_SUPPORT && typeof console !== 'undefined' && typeof console.error === 'function') { console.error( 'This browser lacks typed array (Uint8Array) support which is required by ' + '`buffer` v5.x. Use `buffer` v4.x if you require old browser support.' ) } function typedArraySupport () { // Can typed array instances can be augmented? try { var arr = new Uint8Array(1) arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }} return arr.foo() === 42 } catch (e) { return false } } Object.defineProperty(Buffer.prototype, 'parent', { get: function () { if (!(this instanceof Buffer)) { return undefined } return this.buffer } }) Object.defineProperty(Buffer.prototype, 'offset', { get: function () { if (!(this instanceof Buffer)) { return undefined } return this.byteOffset } }) function createBuffer (length) { if (length > K_MAX_LENGTH) { throw new RangeError('Invalid typed array length') } // Return an augmented `Uint8Array` instance var buf = new Uint8Array(length) buf.__proto__ = Buffer.prototype return buf } /** * The Buffer constructor returns instances of `Uint8Array` that have their * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of * `Uint8Array`, so the returned instances will have all the node `Buffer` methods * and the `Uint8Array` methods. Square bracket notation works as expected -- it * returns a single octet. * * The `Uint8Array` prototype remains unmodified. */ function Buffer (arg, encodingOrOffset, length) { // Common case. if (typeof arg === 'number') { if (typeof encodingOrOffset === 'string') { throw new Error( 'If encoding is specified then the first argument must be a string' ) } return allocUnsafe(arg) } return from(arg, encodingOrOffset, length) } // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97 if (typeof Symbol !== 'undefined' && Symbol.species && Buffer[Symbol.species] === Buffer) { Object.defineProperty(Buffer, Symbol.species, { value: null, configurable: true, enumerable: false, writable: false }) } Buffer.poolSize = 8192 // not used by this implementation function from (value, encodingOrOffset, length) { if (typeof value === 'number') { throw new TypeError('"value" argument must not be a number') } if (isArrayBuffer(value) || (value && isArrayBuffer(value.buffer))) { return fromArrayBuffer(value, encodingOrOffset, length) } if (typeof value === 'string') { return fromString(value, encodingOrOffset) } return fromObject(value) } /** * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError * if value is a number. * Buffer.from(str[, encoding]) * Buffer.from(array) * Buffer.from(buffer) * Buffer.from(arrayBuffer[, byteOffset[, length]]) **/ Buffer.from = function (value, encodingOrOffset, length) { return from(value, encodingOrOffset, length) } // Note: Change prototype *after* Buffer.from is defined to workaround Chrome bug: // https://github.com/feross/buffer/pull/148 Buffer.prototype.__proto__ = Uint8Array.prototype Buffer.__proto__ = Uint8Array function assertSize (size) { if (typeof size !== 'number') { throw new TypeError('"size" argument must be of type number') } else if (size < 0) { throw new RangeError('"size" argument must not be negative') } } function alloc (size, fill, encoding) { assertSize(size) if (size <= 0) { return createBuffer(size) } if (fill !== undefined) { // Only pay attention to encoding if it's a string. This // prevents accidentally sending in a number that would // be interpretted as a start offset. return typeof encoding === 'string' ? createBuffer(size).fill(fill, encoding) : createBuffer(size).fill(fill) } return createBuffer(size) } /** * Creates a new filled Buffer instance. * alloc(size[, fill[, encoding]]) **/ Buffer.alloc = function (size, fill, encoding) { return alloc(size, fill, encoding) } function allocUnsafe (size) { assertSize(size) return createBuffer(size < 0 ? 0 : checked(size) | 0) } /** * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance. * */ Buffer.allocUnsafe = function (size) { return allocUnsafe(size) } /** * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance. */ Buffer.allocUnsafeSlow = function (size) { return allocUnsafe(size) } function fromString (string, encoding) { if (typeof encoding !== 'string' || encoding === '') { encoding = 'utf8' } if (!Buffer.isEncoding(encoding)) { throw new TypeError('Unknown encoding: ' + encoding) } var length = byteLength(string, encoding) | 0 var buf = createBuffer(length) var actual = buf.write(string, encoding) if (actual !== length) { // Writing a hex string, for example, that contains invalid characters will // cause everything after the first invalid character to be ignored. (e.g. // 'abxxcd' will be treated as 'ab') buf = buf.slice(0, actual) } return buf } function fromArrayLike (array) { var length = array.length < 0 ? 0 : checked(array.length) | 0 var buf = createBuffer(length) for (var i = 0; i < length; i += 1) { buf[i] = array[i] & 255 } return buf } function fromArrayBuffer (array, byteOffset, length) { if (byteOffset < 0 || array.byteLength < byteOffset) { throw new RangeError('"offset" is outside of buffer bounds') } if (array.byteLength < byteOffset + (length || 0)) { throw new RangeError('"length" is outside of buffer bounds') } var buf if (byteOffset === undefined && length === undefined) { buf = new Uint8Array(array) } else if (length === undefined) { buf = new Uint8Array(array, byteOffset) } else { buf = new Uint8Array(array, byteOffset, length) } // Return an augmented `Uint8Array` instance buf.__proto__ = Buffer.prototype return buf } function fromObject (obj) { if (Buffer.isBuffer(obj)) { var len = checked(obj.length) | 0 var buf = createBuffer(len) if (buf.length === 0) { return buf } obj.copy(buf, 0, 0, len) return buf } if (obj) { if (ArrayBuffer.isView(obj) || 'length' in obj) { if (typeof obj.length !== 'number' || numberIsNaN(obj.length)) { return createBuffer(0) } return fromArrayLike(obj) } if (obj.type === 'Buffer' && Array.isArray(obj.data)) { return fromArrayLike(obj.data) } } throw new TypeError('The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object.') } function checked (length) { // Note: cannot use `length < K_MAX_LENGTH` here because that fails when // length is NaN (which is otherwise coerced to zero.) if (length >= K_MAX_LENGTH) { throw new RangeError('Attempt to allocate Buffer larger than maximum ' + 'size: 0x' + K_MAX_LENGTH.toString(16) + ' bytes') } return length | 0 } function SlowBuffer (length) { if (+length != length) { // eslint-disable-line eqeqeq length = 0 } return Buffer.alloc(+length) } Buffer.isBuffer = function isBuffer (b) { return b != null && b._isBuffer === true } Buffer.compare = function compare (a, b) { if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { throw new TypeError('Arguments must be Buffers') } if (a === b) return 0 var x = a.length var y = b.length for (var i = 0, len = Math.min(x, y); i < len; ++i) { if (a[i] !== b[i]) { x = a[i] y = b[i] break } } if (x < y) return -1 if (y < x) return 1 return 0 } Buffer.isEncoding = function isEncoding (encoding) { switch (String(encoding).toLowerCase()) { case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'latin1': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': return true default: return false } } Buffer.concat = function concat (list, length) { if (!Array.isArray(list)) { throw new TypeError('"list" argument must be an Array of Buffers') } if (list.length === 0) { return Buffer.alloc(0) } var i if (length === undefined) { length = 0 for (i = 0; i < list.length; ++i) { length += list[i].length } } var buffer = Buffer.allocUnsafe(length) var pos = 0 for (i = 0; i < list.length; ++i) { var buf = list[i] if (ArrayBuffer.isView(buf)) { buf = Buffer.from(buf) } if (!Buffer.isBuffer(buf)) { throw new TypeError('"list" argument must be an Array of Buffers') } buf.copy(buffer, pos) pos += buf.length } return buffer } function byteLength (string, encoding) { if (Buffer.isBuffer(string)) { return string.length } if (ArrayBuffer.isView(string) || isArrayBuffer(string)) { return string.byteLength } if (typeof string !== 'string') { string = '' + string } var len = string.length if (len === 0) return 0 // Use a for loop to avoid recursion var loweredCase = false for (;;) { switch (encoding) { case 'ascii': case 'latin1': case 'binary': return len case 'utf8': case 'utf-8': case undefined: return utf8ToBytes(string).len