This commit is contained in:
2026-02-24 12:29:58 +00:00
commit 3fad287a29
58 changed files with 3999 additions and 0 deletions

View File

@@ -0,0 +1,114 @@
import * as plugins from '../plugins.ts';
import { logger } from '../logging.ts';
import type * as interfaces from '../../ts_interfaces/index.ts';
import { BaseProvider, GiteaProvider, GitLabProvider } from '../providers/index.ts';
const CONNECTIONS_FILE = './.nogit/connections.json';
/**
* Manages provider connections - persists to .nogit/connections.json
* and creates provider instances on demand.
*/
export class ConnectionManager {
private connections: interfaces.data.IProviderConnection[] = [];
async init(): Promise<void> {
await this.loadConnections();
}
private async loadConnections(): Promise<void> {
try {
const text = await Deno.readTextFile(CONNECTIONS_FILE);
this.connections = JSON.parse(text);
logger.info(`Loaded ${this.connections.length} connection(s)`);
} catch {
this.connections = [];
logger.debug('No existing connections file found, starting fresh');
}
}
private async saveConnections(): Promise<void> {
// Ensure .nogit directory exists
try {
await Deno.mkdir('./.nogit', { recursive: true });
} catch { /* already exists */ }
await Deno.writeTextFile(CONNECTIONS_FILE, JSON.stringify(this.connections, null, 2));
}
getConnections(): interfaces.data.IProviderConnection[] {
// Return connections without exposing tokens
return this.connections.map((c) => ({ ...c, token: '***' }));
}
getConnection(id: string): interfaces.data.IProviderConnection | undefined {
return this.connections.find((c) => c.id === id);
}
async createConnection(
name: string,
providerType: interfaces.data.TProviderType,
baseUrl: string,
token: string,
): Promise<interfaces.data.IProviderConnection> {
const connection: interfaces.data.IProviderConnection = {
id: crypto.randomUUID(),
name,
providerType,
baseUrl: baseUrl.replace(/\/+$/, ''),
token,
createdAt: Date.now(),
status: 'disconnected',
};
this.connections.push(connection);
await this.saveConnections();
logger.success(`Connection created: ${name} (${providerType})`);
return { ...connection, token: '***' };
}
async updateConnection(
id: string,
updates: { name?: string; baseUrl?: string; token?: string },
): Promise<interfaces.data.IProviderConnection> {
const conn = this.connections.find((c) => c.id === id);
if (!conn) throw new Error(`Connection not found: ${id}`);
if (updates.name) conn.name = updates.name;
if (updates.baseUrl) conn.baseUrl = updates.baseUrl.replace(/\/+$/, '');
if (updates.token) conn.token = updates.token;
await this.saveConnections();
return { ...conn, token: '***' };
}
async deleteConnection(id: string): Promise<void> {
const idx = this.connections.findIndex((c) => c.id === id);
if (idx === -1) throw new Error(`Connection not found: ${id}`);
this.connections.splice(idx, 1);
await this.saveConnections();
logger.info(`Connection deleted: ${id}`);
}
async testConnection(id: string): Promise<{ ok: boolean; error?: string }> {
const provider = this.getProvider(id);
const result = await provider.testConnection();
const conn = this.connections.find((c) => c.id === id)!;
conn.status = result.ok ? 'connected' : 'error';
await this.saveConnections();
return result;
}
/**
* Factory: returns the correct provider instance for a connection ID
*/
getProvider(connectionId: string): BaseProvider {
const conn = this.connections.find((c) => c.id === connectionId);
if (!conn) throw new Error(`Connection not found: ${connectionId}`);
switch (conn.providerType) {
case 'gitea':
return new GiteaProvider(conn.id, conn.baseUrl, conn.token);
case 'gitlab':
return new GitLabProvider(conn.id, conn.baseUrl, conn.token);
default:
throw new Error(`Unknown provider type: ${conn.providerType}`);
}
}
}

34
ts/classes/gitopsapp.ts Normal file
View File

@@ -0,0 +1,34 @@
import { logger } from '../logging.ts';
import { ConnectionManager } from './connectionmanager.ts';
import { OpsServer } from '../opsserver/index.ts';
/**
* Main GitOps application orchestrator
*/
export class GitopsApp {
public connectionManager: ConnectionManager;
public opsServer: OpsServer;
constructor() {
this.connectionManager = new ConnectionManager();
this.opsServer = new OpsServer(this);
}
async start(port = 3000): Promise<void> {
logger.info('Initializing GitOps...');
// Initialize connection manager (loads saved connections)
await this.connectionManager.init();
// Start OpsServer
await this.opsServer.start(port);
logger.success('GitOps initialized successfully');
}
async stop(): Promise<void> {
logger.info('Shutting down GitOps...');
await this.opsServer.stop();
logger.success('GitOps shutdown complete');
}
}