build-in-public-bot
Version:
AI-powered CLI bot for automating build-in-public tweets with code screenshots
152 lines • 5.47 kB
JavaScript
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.StorageService = void 0;
const promises_1 = __importDefault(require("fs/promises"));
const path_1 = __importDefault(require("path"));
const config_1 = require("./config");
const errors_1 = require("../utils/errors");
class StorageService {
static instance;
historyPath;
draftsPath;
storagePath;
constructor() {
const configDir = this.getStorageDir();
this.historyPath = path_1.default.join(configDir, 'history.json');
this.draftsPath = path_1.default.join(configDir, 'drafts.json');
this.storagePath = path_1.default.join(configDir, 'storage.json');
}
getStorageDir() {
if (process.env.NODE_ENV === 'test' && process.env.TEST_HOME) {
return path_1.default.join(process.env.TEST_HOME, '.bip');
}
const configService = config_1.ConfigService.getInstance();
return configService.getConfigDir();
}
static getInstance() {
if (!StorageService.instance) {
StorageService.instance = new StorageService();
}
return StorageService.instance;
}
async initialize() {
try {
const configDir = this.getStorageDir();
await promises_1.default.mkdir(configDir, { recursive: true });
try {
await promises_1.default.access(this.storagePath);
}
catch {
await promises_1.default.writeFile(this.storagePath, JSON.stringify({ tweets: [], drafts: [] }, null, 2), 'utf-8');
}
}
catch (error) {
throw new errors_1.StorageError('Failed to initialize storage', error);
}
}
async saveTweet(tweet) {
try {
const history = await this.getHistory();
history.unshift(tweet);
if (history.length > 100) {
history.splice(100);
}
await promises_1.default.writeFile(this.historyPath, JSON.stringify(history, null, 2));
}
catch (error) {
throw new errors_1.FileError('Failed to save tweet to history', error);
}
}
async getTweets(limit) {
return this.getHistory(limit);
}
async getHistory(limit) {
try {
const data = await promises_1.default.readFile(this.historyPath, 'utf-8');
const history = JSON.parse(data);
const tweets = history.map((tweet) => ({
...tweet,
createdAt: new Date(tweet.createdAt)
}));
return limit ? tweets.slice(0, limit) : tweets;
}
catch (error) {
if (error.code === 'ENOENT') {
return [];
}
throw new errors_1.FileError('Failed to read tweet history', error);
}
}
async saveDraft(draft) {
try {
const drafts = await this.getDrafts();
draft.id = `draft-${Date.now()}`;
drafts.unshift(draft);
if (drafts.length > 20) {
drafts.splice(20);
}
await promises_1.default.writeFile(this.draftsPath, JSON.stringify(drafts, null, 2));
}
catch (error) {
throw new errors_1.FileError('Failed to save draft', error);
}
}
async getDrafts() {
try {
const data = await promises_1.default.readFile(this.draftsPath, 'utf-8');
const drafts = JSON.parse(data);
return drafts.map((draft) => ({
...draft,
createdAt: new Date(draft.createdAt)
}));
}
catch (error) {
if (error.code === 'ENOENT') {
return [];
}
throw new errors_1.FileError('Failed to read drafts', error);
}
}
async getDraft(id) {
try {
const drafts = await this.getDrafts();
return drafts.find(d => d.id === id ||
d.id === `draft-${id}` ||
d.id.endsWith(`-${id}`)) || null;
}
catch (error) {
throw new errors_1.FileError('Failed to get draft', error);
}
}
async deleteDraft(id) {
try {
const drafts = await this.getDrafts();
const filtered = drafts.filter(d => d.id !== id);
await promises_1.default.writeFile(this.draftsPath, JSON.stringify(filtered, null, 2));
}
catch (error) {
throw new errors_1.FileError('Failed to delete draft', error);
}
}
async clear(type) {
try {
if (!type || type === 'tweets') {
await promises_1.default.writeFile(this.historyPath, JSON.stringify([], null, 2));
}
if (!type || type === 'drafts') {
await promises_1.default.writeFile(this.draftsPath, JSON.stringify([], null, 2));
}
if (!type) {
await promises_1.default.writeFile(this.storagePath, JSON.stringify({ tweets: [], drafts: [] }, null, 2), 'utf-8');
}
}
catch (error) {
throw new errors_1.StorageError('Failed to clear storage', error);
}
}
}
exports.StorageService = StorageService;
//# sourceMappingURL=storage.js.map
;