Last active
January 2, 2016 10:29
-
-
Save jeffdonthemic/8290347 to your computer and use it in GitHub Desktop.
Sample script for with Promises for updating an Apex class in Force.com using the Tooling API with node.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var Q = require("q"), | |
request = require('request'); | |
// call with the following | |
// var apexClassId = "01pi0000004kbvAAAQ"; // the id of the apex class to update | |
// var newCode = "public class Test1 { public void sayHelloOnceAgain() { } }"; // pass in some code | |
// var connetion = resp object from nforce org.authenticate | |
function updateApex(apexClassId, newCode, connection) { | |
var deferred = Q.defer(); | |
var bearer = connection.access_token; | |
console.log("==== STARTING NEW DEPLOY ===="); | |
createContainer() | |
.then(addUpdatedCode) | |
.then(deploy) | |
.then(function(results) { | |
deferred.resolve(results); | |
}) | |
.fail(function(err) { | |
console.log("== failure: " + err); | |
deferred.reject(err); | |
}); | |
function deleteContainer(metadataContainerId) { | |
var deferred = Q.defer(); | |
var options = { | |
url: connection.instance_url + '/services/data/v28.0/tooling/sobjects/MetadataContainer/' + metadataContainerId, | |
method: 'DELETE', | |
headers: { | |
'Content-Type': 'application/json', | |
'Authorization': 'Bearer ' + bearer | |
} | |
}; | |
function callback(error, response, body) { | |
if (!error && response.statusCode == 204) { | |
console.log("Deleted deployment container: " + metadataContainerId); | |
deferred.resolve("Deployment complete!"); | |
} else { | |
console.log(response.statusCode); | |
var result = JSON.parse(body); | |
deferred.reject("Failed to delete metadata container."); | |
console.log(result); | |
} | |
} | |
// make the request | |
request(options, callback); | |
return deferred.promise; | |
} | |
function checkDeployState(containerAsyncRequestId) { | |
var options = { | |
url: connection.instance_url + '/services/data/v28.0/tooling/sobjects/ContainerAsyncRequest/' + containerAsyncRequestId, | |
headers: { | |
'Content-Type': 'application/json', | |
'Authorization': 'Bearer ' + bearer | |
} | |
}; | |
function callback(error, response, body) { | |
if (!error && response.statusCode == 200) { | |
var result = JSON.parse(body); | |
if (result.State === "Queued") { | |
console.log("Status is currently queued. Checking deploy state again."); | |
checkDeployState(containerAsyncRequestId); | |
} else { | |
if (result.State === "Completed") { | |
console.log("W00t! Code successfully deployed"); | |
} else if (result.State === "Failed") { | |
console.log("Deployment failed with: "); | |
console.log(result.CompilerErrors); | |
} else if (result.State === "Error") { | |
console.log("Deployment failed with error: "); | |
console.log(result.ErrorMsg); | |
} else { | |
console.log("Deploy finished with a status of: " + result.State); | |
console.log(result); | |
} | |
deleteContainer(result.MetadataContainerId); | |
} | |
} else { | |
var result = JSON.parse(body); | |
console.log(result); | |
} | |
} | |
// make the request | |
request(options, callback); | |
} | |
function createContainer() { | |
var deferred = Q.defer(); | |
var options = { | |
url: connection.instance_url + '/services/data/v28.0/tooling/sobjects/MetadataContainer', | |
method: 'POST', | |
body: '{"Name":"AwesomeContainer"}', | |
headers: { | |
'Content-Type': 'application/json', | |
'Authorization': 'Bearer ' + bearer | |
} | |
}; | |
function callback(error, response, body) { | |
if (!error && response.statusCode == 201) { | |
var result = JSON.parse(body); | |
console.log("Created MetadataContainer: " + result.id) | |
deferred.resolve(result.id); | |
} else { | |
console.log(response.statusCode); | |
var result = JSON.parse(body); | |
deferred.reject("Failed to create a metadata container."); | |
console.log(result); | |
} | |
} | |
// make the request | |
request(options, callback); | |
return deferred.promise; | |
} | |
function addUpdatedCode(metadataContainerId) { | |
var deferred = Q.defer(); | |
var options = { | |
url: connection.instance_url + '/services/data/v28.0/tooling/sobjects/ApexClassMember', | |
method: 'POST', | |
body: '{"MetadataContainerId":"'+metadataContainerId+'", "ContentEntityId":"'+apexClassId+'", "body": "'+newCode+'"}', | |
headers: { | |
'Content-Type': 'application/json', | |
'Authorization': 'Bearer ' + bearer | |
} | |
}; | |
function callback(error, response, body) { | |
if (!error && response.statusCode == 201) { | |
var result = JSON.parse(body); | |
console.log("Created ApexClassMember: " + result.id) | |
deferred.resolve(metadataContainerId); | |
} else { | |
console.log(response.statusCode); | |
var result = JSON.parse(body); | |
deferred.reject("Failed to add updated code."); | |
console.log(result); | |
} | |
} | |
// make the request | |
request(options, callback); | |
return deferred.promise; | |
} | |
function deploy(metadataContainerId) { | |
var deferred = Q.defer(); | |
var options = { | |
url: connection.instance_url + '/services/data/v28.0/tooling/sobjects/ContainerAsyncRequest', | |
method: 'POST', | |
body: '{"MetadataContainerId":"'+metadataContainerId+'", "isCheckOnly": false}', | |
headers: { | |
'Content-Type': 'application/json', | |
'Authorization': 'Bearer ' + bearer | |
} | |
}; | |
function callback(error, response, body) { | |
if (!error && response.statusCode == 201) { | |
var result = JSON.parse(body); | |
console.log("Deployed code with id: " + result.id); | |
// check the state of the deployment | |
checkDeployState(result.id); | |
deferred.resolve(metadataContainerId); | |
} else { | |
console.log(response.statusCode); | |
var result = JSON.parse(body); | |
deferred.reject("Failed to deploy code."); | |
console.log(result); | |
} | |
} | |
// make the request | |
request(options, callback); | |
return deferred.promise; | |
} | |
return deferred.promise; | |
} | |
exports.updateApex = updateApex; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment