supapup
Version:
⚡ Lightning-fast MCP browser dev tool. Navigate → Get instant structured data. No screenshots needed! Puppeteer: 📸 → CSS selectors → JS eval. Supapup: semantic IDs ready to use. 10x faster, 90% fewer tokens.
223 lines (222 loc) • 7.65 kB
JavaScript
export class StorageTools {
page = null;
cdpSession = null;
async initialize(page) {
this.page = page;
this.cdpSession = await page.target().createCDPSession();
// Enable necessary domains
await this.cdpSession.send('DOMStorage.enable');
}
// LocalStorage operations
async getLocalStorage() {
if (!this.page)
throw new Error('Page not initialized');
const result = await this.page.evaluate(() => {
const items = {};
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
if (key) {
items[key] = localStorage.getItem(key) || '';
}
}
return items;
});
return result;
}
async setLocalStorage(key, value) {
if (!this.page)
throw new Error('Page not initialized');
await this.page.evaluate((k, v) => {
localStorage.setItem(k, v);
}, key, value);
}
async removeLocalStorage(key) {
if (!this.page)
throw new Error('Page not initialized');
await this.page.evaluate((k) => {
localStorage.removeItem(k);
}, key);
}
async clearLocalStorage() {
if (!this.page)
throw new Error('Page not initialized');
await this.page.evaluate(() => {
localStorage.clear();
});
}
// SessionStorage operations
async getSessionStorage() {
if (!this.page)
throw new Error('Page not initialized');
const result = await this.page.evaluate(() => {
const items = {};
for (let i = 0; i < sessionStorage.length; i++) {
const key = sessionStorage.key(i);
if (key) {
items[key] = sessionStorage.getItem(key) || '';
}
}
return items;
});
return result;
}
async setSessionStorage(key, value) {
if (!this.page)
throw new Error('Page not initialized');
await this.page.evaluate((k, v) => {
sessionStorage.setItem(k, v);
}, key, value);
}
async removeSessionStorage(key) {
if (!this.page)
throw new Error('Page not initialized');
await this.page.evaluate((k) => {
sessionStorage.removeItem(k);
}, key);
}
async clearSessionStorage() {
if (!this.page)
throw new Error('Page not initialized');
await this.page.evaluate(() => {
sessionStorage.clear();
});
}
// Cookie operations
async getCookies() {
if (!this.page)
throw new Error('Page not initialized');
const cookies = await this.page.cookies();
return cookies;
}
async setCookie(cookie) {
if (!this.page)
throw new Error('Page not initialized');
await this.page.setCookie(cookie);
}
async deleteCookie(name, url) {
if (!this.page)
throw new Error('Page not initialized');
const cookies = await this.page.cookies(...(url ? [url] : []));
const cookieToDelete = cookies.find(c => c.name === name);
if (cookieToDelete) {
await this.page.deleteCookie(cookieToDelete);
}
}
async clearCookies() {
if (!this.page)
throw new Error('Page not initialized');
// Get all cookies and delete them one by one
const cookies = await this.page.cookies();
for (const cookie of cookies) {
await this.page.deleteCookie(cookie);
}
}
// Clear all storage data
async clearAllStorage() {
if (!this.page)
throw new Error('Page not initialized');
// Clear localStorage and sessionStorage
await this.clearLocalStorage();
await this.clearSessionStorage();
// Clear cookies
await this.clearCookies();
}
// Export/Import storage state
async exportStorageState() {
if (!this.page)
throw new Error('Page not initialized');
const localStorage = await this.getLocalStorage();
const sessionStorage = await this.getSessionStorage();
const cookies = await this.getCookies();
return {
localStorage,
sessionStorage,
cookies
};
}
async importStorageState(data) {
if (!this.page)
throw new Error('Page not initialized');
// Import localStorage
if (data.localStorage) {
await this.clearLocalStorage();
for (const [key, value] of Object.entries(data.localStorage)) {
await this.setLocalStorage(key, value);
}
}
// Import sessionStorage
if (data.sessionStorage) {
await this.clearSessionStorage();
for (const [key, value] of Object.entries(data.sessionStorage)) {
await this.setSessionStorage(key, value);
}
}
// Import cookies
if (data.cookies) {
await this.clearCookies();
for (const cookie of data.cookies) {
await this.setCookie(cookie);
}
}
}
// Storage size and quota
async getStorageInfo() {
if (!this.page)
throw new Error('Page not initialized');
// Use navigator.storage.estimate() which is more widely supported
const result = await this.page.evaluate(async () => {
if ('storage' in navigator && 'estimate' in navigator.storage) {
const estimate = await navigator.storage.estimate();
return {
usage: estimate.usage || 0,
quota: estimate.quota || 0
};
}
// Fallback for browsers that don't support storage.estimate()
return {
usage: 0,
quota: 0
};
});
return result;
}
// Helper to format storage data nicely
formatStorageData(data) {
let output = '📦 Storage State\n';
output += '================\n\n';
if (data.localStorage && Object.keys(data.localStorage).length > 0) {
output += '📂 LocalStorage:\n';
for (const [key, value] of Object.entries(data.localStorage)) {
output += ` • ${key}: ${value.length > 50 ? value.substring(0, 50) + '...' : value}\n`;
}
output += '\n';
}
if (data.sessionStorage && Object.keys(data.sessionStorage).length > 0) {
output += '📋 SessionStorage:\n';
for (const [key, value] of Object.entries(data.sessionStorage)) {
output += ` • ${key}: ${value.length > 50 ? value.substring(0, 50) + '...' : value}\n`;
}
output += '\n';
}
if (data.cookies && data.cookies.length > 0) {
output += '🍪 Cookies:\n';
for (const cookie of data.cookies) {
output += ` • ${cookie.name}: ${cookie.value.length > 30 ? cookie.value.substring(0, 30) + '...' : cookie.value} (${cookie.domain})\n`;
}
}
return output;
}
// Cleanup
async cleanup() {
if (this.cdpSession) {
try {
await this.cdpSession.detach();
}
catch (err) {
// Ignore detach errors
}
}
this.page = null;
this.cdpSession = null;
}
}