mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-29 22:55:24 +00:00
feat: move the terminal fully into the ssh-terminal plugin (B9)
This commit is contained in:
1 parent
535126fd1b
commit
79d77678c9
309 files changed
+41789
-14958
No files matched your search
@@ -1,160 +0,0 @@
|
||||
import { and, desc, eq, inArray, sql } from "drizzle-orm";
|
||||
import { commandHistory } from "../db/schema.js";
|
||||
import type { DatabaseContext } from "./database-context.js";
|
||||
import { rowsAffected } from "./mutation-result.js";
|
||||
import { insertReturning } from "./returning.js";
|
||||
|
||||
export type CommandHistoryRecord = typeof commandHistory.$inferSelect;
|
||||
|
||||
export class CommandHistoryRepository {
|
||||
constructor(
|
||||
private readonly context: DatabaseContext,
|
||||
private readonly onWrite?: () => void | Promise<void>,
|
||||
) {}
|
||||
|
||||
async create(
|
||||
userId: string,
|
||||
hostId: number,
|
||||
command: string,
|
||||
executedAt = new Date().toISOString(),
|
||||
): Promise<CommandHistoryRecord> {
|
||||
const [created] = await insertReturning(this.context, commandHistory, {
|
||||
userId,
|
||||
hostId,
|
||||
command,
|
||||
executedAt,
|
||||
});
|
||||
await this.afterWrite();
|
||||
return created;
|
||||
}
|
||||
|
||||
async listUniqueCommandsForHost(
|
||||
userId: string,
|
||||
hostId: number,
|
||||
limit = 500,
|
||||
): Promise<string[]> {
|
||||
const rows = await this.context.drizzle
|
||||
.select({
|
||||
command: commandHistory.command,
|
||||
maxExecutedAt: sql<number>`MAX(${commandHistory.executedAt})`,
|
||||
})
|
||||
.from(commandHistory)
|
||||
.where(
|
||||
and(
|
||||
eq(commandHistory.userId, userId),
|
||||
eq(commandHistory.hostId, hostId),
|
||||
),
|
||||
)
|
||||
.groupBy(commandHistory.command)
|
||||
.orderBy(desc(sql`MAX(${commandHistory.executedAt})`))
|
||||
.limit(limit);
|
||||
|
||||
return rows.map((row) => row.command);
|
||||
}
|
||||
|
||||
async listCommandsForHost(
|
||||
userId: string,
|
||||
hostId: number,
|
||||
limit = 200,
|
||||
): Promise<string[]> {
|
||||
const rows = await this.context.drizzle
|
||||
.select({
|
||||
id: commandHistory.id,
|
||||
command: commandHistory.command,
|
||||
})
|
||||
.from(commandHistory)
|
||||
.where(
|
||||
and(
|
||||
eq(commandHistory.userId, userId),
|
||||
eq(commandHistory.hostId, hostId),
|
||||
),
|
||||
)
|
||||
.orderBy(desc(commandHistory.executedAt))
|
||||
.limit(limit);
|
||||
|
||||
return rows.map((row) => row.command);
|
||||
}
|
||||
|
||||
async deleteCommandForHost(
|
||||
userId: string,
|
||||
hostId: number,
|
||||
command: string,
|
||||
): Promise<number> {
|
||||
const result = await this.context.drizzle
|
||||
.delete(commandHistory)
|
||||
.where(
|
||||
and(
|
||||
eq(commandHistory.userId, userId),
|
||||
eq(commandHistory.hostId, hostId),
|
||||
eq(commandHistory.command, command),
|
||||
),
|
||||
);
|
||||
|
||||
if (rowsAffected(result) > 0) {
|
||||
await this.afterWrite();
|
||||
}
|
||||
|
||||
return rowsAffected(result);
|
||||
}
|
||||
|
||||
async deleteByUserAndHost(userId: string, hostId: number): Promise<number> {
|
||||
const result = await this.context.drizzle
|
||||
.delete(commandHistory)
|
||||
.where(
|
||||
and(
|
||||
eq(commandHistory.userId, userId),
|
||||
eq(commandHistory.hostId, hostId),
|
||||
),
|
||||
);
|
||||
|
||||
if (rowsAffected(result) > 0) {
|
||||
await this.afterWrite();
|
||||
}
|
||||
|
||||
return rowsAffected(result);
|
||||
}
|
||||
|
||||
async deleteByHostId(hostId: number): Promise<number> {
|
||||
const result = await this.context.drizzle
|
||||
.delete(commandHistory)
|
||||
.where(eq(commandHistory.hostId, hostId));
|
||||
|
||||
if (rowsAffected(result) > 0) {
|
||||
await this.afterWrite();
|
||||
}
|
||||
|
||||
return rowsAffected(result);
|
||||
}
|
||||
|
||||
async deleteByHostIds(hostIds: number[]): Promise<number> {
|
||||
if (hostIds.length === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const result = await this.context.drizzle
|
||||
.delete(commandHistory)
|
||||
.where(inArray(commandHistory.hostId, hostIds));
|
||||
|
||||
if (rowsAffected(result) > 0) {
|
||||
await this.afterWrite();
|
||||
}
|
||||
|
||||
return rowsAffected(result);
|
||||
}
|
||||
|
||||
async deleteByUserId(userId: string): Promise<number> {
|
||||
const result = await this.context.drizzle
|
||||
.delete(commandHistory)
|
||||
.where(eq(commandHistory.userId, userId));
|
||||
|
||||
if (rowsAffected(result) > 0) {
|
||||
await this.afterWrite();
|
||||
}
|
||||
|
||||
return rowsAffected(result);
|
||||
}
|
||||
|
||||
private async afterWrite(): Promise<void> {
|
||||
await this.onWrite?.();
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,6 @@ import { NotificationChannelRepository } from "./notification-channel-repository
|
||||
import { AutomationRepository } from "./automation-repository.js";
|
||||
import { ApiKeyRepository } from "./api-key-repository.js";
|
||||
import { AuditLogRepository } from "./audit-log-repository.js";
|
||||
import { CommandHistoryRepository } from "./command-history-repository.js";
|
||||
import { CredentialRepository } from "./credential-repository.js";
|
||||
import { DashboardServiceLinkRepository } from "./dashboard-service-link-repository.js";
|
||||
import { DismissedAlertRepository } from "./dismissed-alert-repository.js";
|
||||
@@ -184,13 +183,6 @@ export function createCurrentAuditLogRepository(): AuditLogRepository {
|
||||
);
|
||||
}
|
||||
|
||||
export function createCurrentCommandHistoryRepository(): CommandHistoryRepository {
|
||||
return new CommandHistoryRepository(
|
||||
createCurrentRepositoryContext(),
|
||||
createCurrentRepositoryWriteHook("command_history_repository_write"),
|
||||
);
|
||||
}
|
||||
|
||||
export function createCurrentCredentialRepository(): CredentialRepository {
|
||||
return new CredentialRepository(
|
||||
createCurrentRepositoryContext(),
|
||||
|
||||
Reference in new issue
Block a user