UNPKG

repoweaver

Version:

A GitHub App that skillfully weaves multiple templates together to create and update repositories with intelligent merge strategies

247 lines 10.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Database = void 0; const sqlite3_1 = require("sqlite3"); const util_1 = require("util"); class Database { constructor(dbPath) { this.db = new sqlite3_1.Database(dbPath); this.runAsync = (0, util_1.promisify)(this.db.run.bind(this.db)); this.getAsync = (0, util_1.promisify)(this.db.get.bind(this.db)); this.allAsync = (0, util_1.promisify)(this.db.all.bind(this.db)); } async initialize() { await this.createTables(); } async createTables() { const createInstallationsTable = ` CREATE TABLE IF NOT EXISTS installations ( id INTEGER PRIMARY KEY, account TEXT NOT NULL, account_type TEXT NOT NULL, suspended BOOLEAN DEFAULT FALSE, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ) `; const createUserSessionsTable = ` CREATE TABLE IF NOT EXISTS user_sessions ( user_id INTEGER PRIMARY KEY, login TEXT NOT NULL, access_token TEXT NOT NULL, installation_id INTEGER, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (installation_id) REFERENCES installations(id) ) `; const createRepositoryConfigsTable = ` CREATE TABLE IF NOT EXISTS repository_configs ( id INTEGER PRIMARY KEY AUTOINCREMENT, installation_id INTEGER NOT NULL, repository TEXT NOT NULL, templates TEXT NOT NULL, merge_strategy TEXT DEFAULT 'merge', exclude_patterns TEXT DEFAULT '[]', auto_update BOOLEAN DEFAULT TRUE, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (installation_id) REFERENCES installations(id), UNIQUE(installation_id, repository) ) `; const createJobsTable = ` CREATE TABLE IF NOT EXISTS jobs ( id INTEGER PRIMARY KEY AUTOINCREMENT, type TEXT NOT NULL, installation_id INTEGER NOT NULL, target_repository TEXT NOT NULL, template_repository TEXT NOT NULL, status TEXT DEFAULT 'pending', result TEXT, error TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (installation_id) REFERENCES installations(id) ) `; const createTemplateConfigsTable = ` CREATE TABLE IF NOT EXISTS template_configurations ( id INTEGER PRIMARY KEY AUTOINCREMENT, template_repository TEXT NOT NULL, target_repository TEXT NOT NULL, installation_id INTEGER NOT NULL, auto_update BOOLEAN DEFAULT TRUE, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (installation_id) REFERENCES installations(id), UNIQUE(template_repository, target_repository, installation_id) ) `; const createInstallationConfigsTable = ` CREATE TABLE IF NOT EXISTS installation_configs ( installation_id INTEGER PRIMARY KEY, auto_configure_templates BOOLEAN DEFAULT FALSE, default_templates TEXT DEFAULT '[]', created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (installation_id) REFERENCES installations(id) ) `; await this.runAsync(createInstallationsTable); await this.runAsync(createUserSessionsTable); await this.runAsync(createRepositoryConfigsTable); await this.runAsync(createJobsTable); await this.runAsync(createTemplateConfigsTable); await this.runAsync(createInstallationConfigsTable); } async createInstallation(installation) { const sql = ` INSERT INTO installations (id, account, account_type) VALUES (?, ?, ?) `; await this.runAsync(sql, [installation.id, installation.account, installation.accountType]); } async deleteInstallation(installationId) { const sql = 'DELETE FROM installations WHERE id = ?'; await this.runAsync(sql, [installationId]); } async suspendInstallation(installationId) { const sql = 'UPDATE installations SET suspended = TRUE, updated_at = CURRENT_TIMESTAMP WHERE id = ?'; await this.runAsync(sql, [installationId]); } async unsuspendInstallation(installationId) { const sql = 'UPDATE installations SET suspended = FALSE, updated_at = CURRENT_TIMESTAMP WHERE id = ?'; await this.runAsync(sql, [installationId]); } async createUserSession(session) { const sql = ` INSERT OR REPLACE INTO user_sessions (user_id, login, access_token, installation_id) VALUES (?, ?, ?, ?) `; await this.runAsync(sql, [session.userId, session.login, session.accessToken, session.installationId]); } async getUserSessionByToken(accessToken) { const sql = 'SELECT * FROM user_sessions WHERE access_token = ?'; const row = await this.getAsync(sql, [accessToken]); if (!row) return null; return { userId: row.user_id, login: row.login, accessToken: row.access_token, installationId: row.installation_id, createdAt: new Date(row.created_at), }; } async deleteUserSession(userId) { const sql = 'DELETE FROM user_sessions WHERE user_id = ?'; await this.runAsync(sql, [userId]); } async addRepositoryToInstallation(installationId, repository, fullName) { // For now, we'll just log this. In a full implementation, you might want to track which repositories are available console.log(`Repository ${fullName} added to installation ${installationId}`); } async removeRepositoryFromInstallation(installationId, repository) { // Clean up any configurations for this repository await this.deleteRepositoryConfig(`${installationId}/${repository}`); } async saveRepositoryConfig(config) { const sql = ` INSERT OR REPLACE INTO repository_configs (installation_id, repository, templates, merge_strategy, exclude_patterns, auto_update) VALUES (?, ?, ?, ?, ?, ?) `; await this.runAsync(sql, [config.installationId, config.repository, JSON.stringify(config.templates), config.mergeStrategy, JSON.stringify(config.excludePatterns), config.autoUpdate]); } async getRepositoryConfig(installationId, repository) { const sql = 'SELECT * FROM repository_configs WHERE installation_id = ? AND repository = ?'; const row = await this.getAsync(sql, [installationId, repository]); if (!row) return null; return { installationId: row.installation_id, repository: row.repository, templates: JSON.parse(row.templates), mergeStrategy: row.merge_strategy, excludePatterns: JSON.parse(row.exclude_patterns), autoUpdate: row.auto_update === 1, createdAt: new Date(row.created_at), updatedAt: new Date(row.updated_at), }; } async deleteRepositoryConfig(repository) { const sql = 'DELETE FROM repository_configs WHERE repository = ?'; await this.runAsync(sql, [repository]); } async queueJob(job) { const sql = ` INSERT INTO jobs (type, installation_id, target_repository, template_repository, status) VALUES (?, ?, ?, ?, ?) `; await this.runAsync(sql, [job.type, job.installationId, job.targetRepository, job.templateRepository, job.status]); } async getQueuedJobs(limit = 10) { const sql = 'SELECT * FROM jobs WHERE status = "pending" ORDER BY created_at LIMIT ?'; const rows = await this.allAsync(sql, [limit]); return rows.map((row) => ({ id: row.id, type: row.type, installationId: row.installation_id, targetRepository: row.target_repository, templateRepository: row.template_repository, status: row.status, result: row.result ? JSON.parse(row.result) : undefined, error: row.error, createdAt: new Date(row.created_at), updatedAt: row.updated_at ? new Date(row.updated_at) : undefined, })); } async updateJobStatus(jobId, status, result, error) { const sql = ` UPDATE jobs SET status = ?, result = ?, error = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ? `; await this.runAsync(sql, [status, result ? JSON.stringify(result) : null, error, jobId]); } async getTemplateConfigurations(templateRepository) { const sql = 'SELECT * FROM template_configurations WHERE template_repository = ?'; const rows = await this.allAsync(sql, [templateRepository]); return rows.map((row) => ({ templateRepository: row.template_repository, targetRepository: row.target_repository, installationId: row.installation_id, autoUpdate: row.auto_update === 1, })); } async getInstallationConfig(installationId) { const sql = 'SELECT * FROM installation_configs WHERE installation_id = ?'; const row = await this.getAsync(sql, [installationId]); if (!row) return null; return { installationId: row.installation_id, autoConfigureTemplates: row.auto_configure_templates === 1, defaultTemplates: JSON.parse(row.default_templates), }; } async saveInstallationConfig(config) { const sql = ` INSERT OR REPLACE INTO installation_configs (installation_id, auto_configure_templates, default_templates) VALUES (?, ?, ?) `; await this.runAsync(sql, [config.installationId, config.autoConfigureTemplates, JSON.stringify(config.defaultTemplates)]); } async close() { return new Promise((resolve, reject) => { this.db.close((err) => { if (err) reject(err); else resolve(); }); }); } } exports.Database = Database; //# sourceMappingURL=database.js.map