feat: Implement repositories for authentication, certificates, metrics, and platform services
- Added AuthRepository for user and settings management with CRUD operations. - Introduced CertificateRepository to handle domains, certificates, and requirements. - Created MetricsRepository for managing metrics and logs. - Developed PlatformRepository for platform services and resources management. - Established RegistryRepository for registry and token operations. - Implemented ServiceRepository for CRUD operations on services. - Defined types and interfaces in types.ts for database interactions.
This commit is contained in:
123
ts/database/repositories/registry.repository.ts
Normal file
123
ts/database/repositories/registry.repository.ts
Normal file
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
* Registry Repository
|
||||
* Handles CRUD operations for registries and registry_tokens tables
|
||||
*/
|
||||
|
||||
import { BaseRepository } from '../base.repository.ts';
|
||||
import type { IRegistry, IRegistryToken } from '../../types.ts';
|
||||
|
||||
export class RegistryRepository extends BaseRepository {
|
||||
// ============ Registries ============
|
||||
|
||||
async createRegistry(registry: Omit<IRegistry, 'id'>): Promise<IRegistry> {
|
||||
const now = Date.now();
|
||||
this.query(
|
||||
'INSERT INTO registries (url, username, password_encrypted, created_at) VALUES (?, ?, ?, ?)',
|
||||
[registry.url, registry.username, registry.passwordEncrypted, now]
|
||||
);
|
||||
|
||||
return this.getRegistryByURL(registry.url)!;
|
||||
}
|
||||
|
||||
getRegistryByURL(url: string): IRegistry | null {
|
||||
const rows = this.query('SELECT * FROM registries WHERE url = ?', [url]);
|
||||
return rows.length > 0 ? this.rowToRegistry(rows[0]) : null;
|
||||
}
|
||||
|
||||
getAllRegistries(): IRegistry[] {
|
||||
const rows = this.query('SELECT * FROM registries ORDER BY created_at DESC');
|
||||
return rows.map((row) => this.rowToRegistry(row));
|
||||
}
|
||||
|
||||
deleteRegistry(url: string): void {
|
||||
this.query('DELETE FROM registries WHERE url = ?', [url]);
|
||||
}
|
||||
|
||||
private rowToRegistry(row: any): IRegistry {
|
||||
return {
|
||||
id: Number(row.id || row[0]),
|
||||
url: String(row.url || row[1]),
|
||||
username: String(row.username || row[2]),
|
||||
passwordEncrypted: String(row.password_encrypted || row[3]),
|
||||
createdAt: Number(row.created_at || row[4]),
|
||||
};
|
||||
}
|
||||
|
||||
// ============ Registry Tokens ============
|
||||
|
||||
createToken(token: Omit<IRegistryToken, 'id'>): IRegistryToken {
|
||||
const scopeJson = Array.isArray(token.scope) ? JSON.stringify(token.scope) : token.scope;
|
||||
|
||||
this.query(
|
||||
`INSERT INTO registry_tokens (name, token_hash, token_type, scope, expires_at, created_at, last_used_at, created_by)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
[
|
||||
token.name,
|
||||
token.tokenHash,
|
||||
token.type,
|
||||
scopeJson,
|
||||
token.expiresAt,
|
||||
token.createdAt,
|
||||
token.lastUsedAt,
|
||||
token.createdBy,
|
||||
]
|
||||
);
|
||||
|
||||
const rows = this.query('SELECT * FROM registry_tokens WHERE id = last_insert_rowid()');
|
||||
return this.rowToToken(rows[0]);
|
||||
}
|
||||
|
||||
getTokenById(id: number): IRegistryToken | null {
|
||||
const rows = this.query('SELECT * FROM registry_tokens WHERE id = ?', [id]);
|
||||
return rows.length > 0 ? this.rowToToken(rows[0]) : null;
|
||||
}
|
||||
|
||||
getTokenByHash(tokenHash: string): IRegistryToken | null {
|
||||
const rows = this.query('SELECT * FROM registry_tokens WHERE token_hash = ?', [tokenHash]);
|
||||
return rows.length > 0 ? this.rowToToken(rows[0]) : null;
|
||||
}
|
||||
|
||||
getAllTokens(): IRegistryToken[] {
|
||||
const rows = this.query('SELECT * FROM registry_tokens ORDER BY created_at DESC');
|
||||
return rows.map((row) => this.rowToToken(row));
|
||||
}
|
||||
|
||||
getTokensByType(type: 'global' | 'ci'): IRegistryToken[] {
|
||||
const rows = this.query('SELECT * FROM registry_tokens WHERE token_type = ? ORDER BY created_at DESC', [type]);
|
||||
return rows.map((row) => this.rowToToken(row));
|
||||
}
|
||||
|
||||
updateTokenLastUsed(id: number): void {
|
||||
this.query('UPDATE registry_tokens SET last_used_at = ? WHERE id = ?', [Date.now(), id]);
|
||||
}
|
||||
|
||||
deleteToken(id: number): void {
|
||||
this.query('DELETE FROM registry_tokens WHERE id = ?', [id]);
|
||||
}
|
||||
|
||||
private rowToToken(row: any): IRegistryToken {
|
||||
let scope: 'all' | string[];
|
||||
const scopeRaw = row.scope || row[4];
|
||||
if (scopeRaw === 'all') {
|
||||
scope = 'all';
|
||||
} else {
|
||||
try {
|
||||
scope = JSON.parse(String(scopeRaw));
|
||||
} catch {
|
||||
scope = 'all';
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
id: Number(row.id || row[0]),
|
||||
name: String(row.name || row[1]),
|
||||
tokenHash: String(row.token_hash || row[2]),
|
||||
type: String(row.token_type || row[3]) as IRegistryToken['type'],
|
||||
scope,
|
||||
expiresAt: row.expires_at || row[5] ? Number(row.expires_at || row[5]) : null,
|
||||
createdAt: Number(row.created_at || row[6]),
|
||||
lastUsedAt: row.last_used_at || row[7] ? Number(row.last_used_at || row[7]) : null,
|
||||
createdBy: String(row.created_by || row[8]),
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user