my-homelab-configs/apps/demos-static/public/dev-toolbelt/dev-toolbelt.js

50 lines
1.9 KiB
JavaScript

const input = document.getElementById('tool-input');
const output = document.getElementById('tool-output');
const logFilter = document.getElementById('log-filter');
function setOutput(value) {
output.textContent = value;
}
function decodeBase64Url(value) {
const normalized = value.replace(/-/g, '+').replace(/_/g, '/');
const padded = normalized.padEnd(Math.ceil(normalized.length / 4) * 4, '=');
return decodeURIComponent(atob(padded).split('').map((char) => `%${char.charCodeAt(0).toString(16).padStart(2, '0')}`).join(''));
}
document.getElementById('format-json').addEventListener('click', () => {
try {
setOutput(JSON.stringify(JSON.parse(input.value), null, 2));
} catch (error) {
setOutput(`JSON parse error: ${error.message}`);
}
});
document.getElementById('decode-jwt').addEventListener('click', () => {
try {
const parts = input.value.trim().split('.');
if (parts.length < 2) throw new Error('Expected header.payload.signature');
setOutput(JSON.stringify({ header: JSON.parse(decodeBase64Url(parts[0])), payload: JSON.parse(decodeBase64Url(parts[1])) }, null, 2));
} catch (error) {
setOutput(`JWT decode error: ${error.message}`);
}
});
document.getElementById('parse-url').addEventListener('click', () => {
try {
const url = new URL(input.value.trim());
const params = {};
url.searchParams.forEach((value, key) => { params[key] = value; });
setOutput(JSON.stringify({ protocol: url.protocol, host: url.host, pathname: url.pathname, query: params, hash: url.hash }, null, 2));
} catch (error) {
setOutput(`URL parse error: ${error.message}`);
}
});
document.getElementById('filter-logs').addEventListener('click', () => {
const needle = logFilter.value.trim().toLowerCase();
const lines = input.value.split('\n');
const result = needle ? lines.filter((line) => line.toLowerCase().includes(needle)) : lines;
setOutput(result.join('\n') || 'No matching lines.');
});