A simple tool which lets you scrape twitter accounts and crosspost them to bluesky accounts! Comes with a CLI and a webapp for managing profiles! Works with images/videos/link embeds/threads.
1import fs from 'node:fs';
2import path from 'node:path';
3import { fileURLToPath } from 'node:url';
4
5const __filename = fileURLToPath(import.meta.url);
6const __dirname = path.dirname(__filename);
7
8const APP_ROOT_DIR = path.join(__dirname, '..');
9const DEFAULT_DATA_DIR = path.join(APP_ROOT_DIR, 'data');
10
11function resolveConfiguredDataDir(rawValue: string | undefined): string | undefined {
12 const value = rawValue?.trim();
13 if (!value) {
14 return undefined;
15 }
16 return path.isAbsolute(value) ? value : path.resolve(APP_ROOT_DIR, value);
17}
18
19const configuredDataDir = resolveConfiguredDataDir(process.env.TWEETS2BSKY_DATA_DIR || process.env.APP_DATA_DIR);
20
21export const DATA_DIR = configuredDataDir ?? DEFAULT_DATA_DIR;
22export const USING_EXTERNAL_DATA_DIR = Boolean(configuredDataDir);
23
24export const LEGACY_CONFIG_FILE = path.join(APP_ROOT_DIR, 'config.json');
25export const DATA_CONFIG_FILE = path.join(DATA_DIR, 'config.json');
26export const ACTIVE_CONFIG_FILE = USING_EXTERNAL_DATA_DIR ? DATA_CONFIG_FILE : LEGACY_CONFIG_FILE;
27
28export const DB_PATH = path.join(DATA_DIR, 'database.sqlite');
29export const JWT_SECRET_FILE_PATH = path.join(DATA_DIR, '.jwt-secret');
30export const UPDATE_LOG_DIR = DATA_DIR;
31
32fs.mkdirSync(DATA_DIR, { recursive: true });