gh-legacy
Version:
A powerful GitHub CLI tool for automatic repository ownership transfer to trusted beneficiaries after periods of inactivity
87 lines (75 loc) • 2.83 kB
JavaScript
// commands/addBeneficiary.js
const fs = require('fs');
const path = require('path');
const CONFIG_PATH = path.join(__dirname, '../db.json');
function validateTimeFormat(timeStr) {
const validUnits = ['minutes', 'minute', 'hours', 'hour', 'days', 'day', 'weeks', 'week', 'months', 'month', 'years', 'year'];
const parts = timeStr.split(' ');
if (parts.length !== 2) return false;
const [value, unit] = parts;
const num = parseInt(value);
if (isNaN(num) || num <= 0) return false;
return validUnits.includes(unit.toLowerCase());
}
exports.addBeneficiary = (options) => {
const { repo, email, accessAfter, githubUsername } = options;
if (!repo || !email || !accessAfter || !githubUsername) {
console.error('❌ Missing required fields. Use: gh-legacy add-beneficiary <repo> <email> <githubUsername> <accessAfter>');
console.error('Example: gh-legacy add-beneficiary owner/repo user@email.com username "3 months"');
return;
}
// Validate repo format
if (!repo.includes('/')) {
console.error('❌ Repository must be in format: owner/repo');
return;
}
// Validate email format
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(email)) {
console.error('❌ Invalid email format');
return;
}
// Validate time format
if (!validateTimeFormat(accessAfter)) {
console.error('❌ Invalid time format. Use: "X minutes/hours/days/weeks/months/years"');
console.error('Examples: "5 minutes", "3 months", "1 year"');
return;
}
let config;
if (fs.existsSync(CONFIG_PATH)) {
config = JSON.parse(fs.readFileSync(CONFIG_PATH));
} else {
config = { lastHeartbeat: new Date().toISOString(), beneficiaries: [] };
}
// Check if beneficiary already exists for this repo
const existingIndex = config.beneficiaries.findIndex(b =>
b.repo === repo && b.githubUsername === githubUsername
);
if (existingIndex !== -1) {
// Update existing beneficiary
config.beneficiaries[existingIndex] = {
repo,
email,
githubUsername,
accessAfter,
granted: false,
addedAt: new Date().toISOString()
};
console.log(`✅ Updated beneficiary ${email} for repo ${repo}`);
} else {
// Add new beneficiary
config.beneficiaries.push({
repo,
email,
githubUsername,
accessAfter,
granted: false,
addedAt: new Date().toISOString()
});
console.log(`✅ Added beneficiary ${email} for repo ${repo}`);
}
fs.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2));
console.log(`📅 Access will be granted after ${accessAfter} of inactivity`);
console.log(`👤 GitHub username: ${githubUsername}`);
console.log(`📧 Email: ${email}`);
};