Last active
February 25, 2022 17:40
-
-
Save metadaddy/b1ba2335326eea64b37ef9b173bd4594 to your computer and use it in GitHub Desktop.
UserScript to erase all the deleted custom objects from a Salesforce org with one click. In Classic UI, go to Setup | Create | Objects | Deleted Objects and the script should be available.
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
// ==UserScript== | |
// @name Purge All Deleted Objects | |
// @description Erase all deleted custom objects from the Salesforce org | |
// @include https://*.salesforce.com/p/setup/custent/DeletedEntitiesList?* | |
// ==/UserScript== | |
// UserScripts: https://github.com/quoid/userscripts | |
// Sometimes, when you're testing Salesforce metadata operations, you end up with a | |
// lot of deleted custom objects in your org. There's no API to erase a deleted object, | |
// and it's tedious to click through them one by one clicking Erase, then confirm, so I | |
// created this UserScript to erase all the deleted custom objects from the org with | |
// one click. In Classic UI, go to Setup | Create | Objects | Deleted Objects and the | |
// script should be available. | |
const eraseAll = () => { | |
let timer = 0; | |
let count = 0; | |
let done = 0; | |
let linkMap = {}; | |
// Find all the 'Erase' links | |
[].slice.call(document.querySelectorAll('a'), 0).forEach(function(aEl) { | |
// if the text of the aEl Node equals the text 'Erase': | |
if (aEl.textContent === 'Erase') { | |
// Build a map so we can get back to the element from the URL | |
linkMap[aEl.href] = aEl; | |
// Keep track of number of objects so we can refresh the page at the right time | |
count++; | |
// Fetch the links asynchronously at regular intervals | |
setTimeout(() => { | |
console.log(`Fetching ${aEl.href}`); | |
// Turn link orange when the request is in flight | |
aEl.style.color = 'orange'; | |
fetch(aEl.href).then(response => { | |
done++; | |
console.log(`Fetched ${response.url}, status: ${response.status}`) | |
// Turn link black if the request succeeded, red if it failed | |
linkMap[response.url].style.color = response.ok ? 'black' : 'red'; | |
if (done == count) { | |
// We're all done - reload the page to show the empty list | |
location.reload(); | |
} | |
}); | |
}, timer); | |
// One per second is about as fast as you can go | |
timer += 1000; | |
} | |
}); | |
console.log(`${count} objects to delete`); | |
} | |
const main = () => { | |
// Make an 'Erase All' button | |
buttonEl = document.createElement("button"); | |
buttonEl.appendChild(document.createTextNode("Erase All")); | |
buttonEl.addEventListener('click', eraseAll); | |
// Put the button under the 'Deleted Custom Objects' header above the list | |
[].slice.call(document.querySelectorAll('h3'), 0).forEach(function(h3El) { | |
// if the text of the h3El Node contains the text 'Deleted Custom Objects': | |
if (h3El.textContent.indexOf('Deleted Custom Objects') > -1) { | |
h3El.insertAdjacentElement('afterend', buttonEl); | |
} | |
}); | |
} | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment