Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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.
// ==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