faf-cli
Version:
😽 TURBO-CAT: The Rapid Catalytic Converter • Project DNA ✨ for ANY AI • Fully Integrated with React, Next.js, Svelte, TypeScript, Vite & n8n • FREE FOREVER • 10,000+ developers • Championship Edition
197 lines • 6.87 kB
JavaScript
;
/**
* Email opt-in system for FAF CLI
* Respectful, one-time only, completely optional
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.hasAskedForEmail = hasAskedForEmail;
exports.isSubscribed = isSubscribed;
exports.promptEmailOptIn = promptEmailOptIn;
exports.subscribeViaFlag = subscribeViaFlag;
exports.showSubscriptionStatus = showSubscriptionStatus;
exports.unsubscribe = unsubscribe;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const os_1 = __importDefault(require("os"));
const inquirer_1 = __importDefault(require("inquirer"));
const colors_1 = require("../fix-once/colors");
const FAF_DIR = path_1.default.join(os_1.default.homedir(), '.faf');
const EMAIL_FLAG_FILE = path_1.default.join(FAF_DIR, '.email-asked');
const EMAIL_STORE_FILE = path_1.default.join(FAF_DIR, '.email-subscribed');
/**
* Ensure .faf directory exists
*/
function ensureFafDir() {
if (!fs_1.default.existsSync(FAF_DIR)) {
fs_1.default.mkdirSync(FAF_DIR, { recursive: true });
}
}
/**
* Check if we've already asked for email
*/
function hasAskedForEmail() {
return fs_1.default.existsSync(EMAIL_FLAG_FILE);
}
/**
* Mark that we've asked for email (never ask again)
*/
function markEmailAsked() {
ensureFafDir();
fs_1.default.writeFileSync(EMAIL_FLAG_FILE, new Date().toISOString());
}
/**
* Check if user is subscribed
*/
function isSubscribed() {
return fs_1.default.existsSync(EMAIL_STORE_FILE);
}
/**
* Subscribe to updates
*/
async function subscribeEmail(email) {
try {
// Store locally first
ensureFafDir();
fs_1.default.writeFileSync(EMAIL_STORE_FILE, JSON.stringify({
email,
subscribedAt: new Date().toISOString(),
source: 'cli',
version: process.env.npm_package_version || 'unknown'
}));
// Try to send to server (don't block if it fails)
fetch('https://formspree.io/f/xnngaegg', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email,
source: 'cli',
version: process.env.npm_package_version,
type: 'FAF CLI Email Notifications',
timestamp: new Date().toISOString()
})
}).catch(() => {
// Silently fail - we have it stored locally
});
return true;
}
catch (error) {
return false;
}
}
/**
* Prompt for email opt-in (one time only)
*/
async function promptEmailOptIn(options = {}) {
// Skip if:
// - Already asked
// - In CI environment
// - Quiet mode
// - Non-interactive terminal
if (hasAskedForEmail() ||
process.env.CI ||
options.quiet ||
!process.stdin.isTTY) {
return;
}
// Mark as asked immediately (even if they skip)
markEmailAsked();
console.log();
console.log(colors_1.chalk.cyan('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
console.log(colors_1.chalk.cyan.bold(' 📧 New Version Notifications'));
console.log(colors_1.chalk.cyan('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
console.log();
console.log(' Get notified when we release:');
console.log(colors_1.chalk.gray(' • New versions with features'));
console.log(colors_1.chalk.gray(' • Breaking changes that affect you'));
console.log(colors_1.chalk.gray(' • Critical security updates'));
console.log();
console.log(colors_1.chalk.gray(' (Only major releases, remove anytime)'));
console.log();
const { wantsUpdates } = await inquirer_1.default.prompt([
{
type: 'confirm',
name: 'wantsUpdates',
message: 'Add your email for version notifications?',
default: false
}
]);
if (wantsUpdates) {
const { email } = await inquirer_1.default.prompt([
{
type: 'input',
name: 'email',
message: 'Your email:',
validate: (input) => {
if (!input)
return 'Email is required';
if (!input.includes('@'))
return 'Please enter a valid email';
return true;
}
}
]);
const success = await subscribeEmail(email);
if (success) {
console.log();
console.log(colors_1.chalk.green(' ✅ Added! You\'ll get notified of new versions.'));
console.log(colors_1.chalk.gray(' (Remove anytime with: faf notifications --remove)'));
}
}
else {
console.log();
console.log(colors_1.chalk.gray(' No problem! You can add your email later with: faf notifications'));
}
console.log();
}
/**
* Allow manual subscription via flag
*/
async function subscribeViaFlag(email) {
if (!email || !email.includes('@')) {
console.log(colors_1.chalk.red('Invalid email address'));
return;
}
const success = await subscribeEmail(email);
if (success) {
console.log(colors_1.chalk.green(`✅ Added ${email} for version notifications`));
}
else {
console.log(colors_1.chalk.red('Failed to add email. Please try again later.'));
}
}
/**
* Show notification status
*/
function showSubscriptionStatus() {
if (isSubscribed()) {
try {
const data = JSON.parse(fs_1.default.readFileSync(EMAIL_STORE_FILE, 'utf-8'));
console.log(colors_1.chalk.green(`📧 Email added: ${data.email}`));
console.log(colors_1.chalk.gray(` Added on: ${new Date(data.subscribedAt).toLocaleDateString()}`));
console.log(colors_1.chalk.gray(' Remove with: faf notifications --remove'));
}
catch {
console.log(colors_1.chalk.green('📧 Your email is added for notifications'));
}
}
else {
console.log(colors_1.chalk.gray('📧 No email added for notifications'));
console.log(colors_1.chalk.gray(' Add with: faf notifications'));
}
}
/**
* Remove email from notifications
*/
function unsubscribe() {
if (fs_1.default.existsSync(EMAIL_STORE_FILE)) {
fs_1.default.unlinkSync(EMAIL_STORE_FILE);
console.log(colors_1.chalk.green('✅ Email removed from notifications'));
}
else {
console.log(colors_1.chalk.gray('No email was added'));
}
}
//# sourceMappingURL=email-opt-in.js.map