104 lines
3.6 KiB
TypeScript
104 lines
3.6 KiB
TypeScript
|
|
import type { PrismaClient, SecretBackend, Prisma } from '@prisma/client';
|
||
|
|
|
||
|
|
export interface CreateSecretBackendInput {
|
||
|
|
name: string;
|
||
|
|
type: string;
|
||
|
|
config?: Record<string, unknown>;
|
||
|
|
isDefault?: boolean;
|
||
|
|
description?: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface UpdateSecretBackendInput {
|
||
|
|
config?: Record<string, unknown>;
|
||
|
|
isDefault?: boolean;
|
||
|
|
description?: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface ISecretBackendRepository {
|
||
|
|
findAll(): Promise<SecretBackend[]>;
|
||
|
|
findById(id: string): Promise<SecretBackend | null>;
|
||
|
|
findByName(name: string): Promise<SecretBackend | null>;
|
||
|
|
findDefault(): Promise<SecretBackend | null>;
|
||
|
|
create(data: CreateSecretBackendInput): Promise<SecretBackend>;
|
||
|
|
update(id: string, data: UpdateSecretBackendInput): Promise<SecretBackend>;
|
||
|
|
/**
|
||
|
|
* Atomically clear `isDefault` on every row except the one named, then set
|
||
|
|
* the given row as default. Used by `setDefault`.
|
||
|
|
*/
|
||
|
|
setAsDefault(id: string): Promise<SecretBackend>;
|
||
|
|
delete(id: string): Promise<void>;
|
||
|
|
/** Count secrets that still reference this backend — used to guard delete. */
|
||
|
|
countReferencingSecrets(backendId: string): Promise<number>;
|
||
|
|
}
|
||
|
|
|
||
|
|
export class SecretBackendRepository implements ISecretBackendRepository {
|
||
|
|
constructor(private readonly prisma: PrismaClient) {}
|
||
|
|
|
||
|
|
async findAll(): Promise<SecretBackend[]> {
|
||
|
|
return this.prisma.secretBackend.findMany({ orderBy: { name: 'asc' } });
|
||
|
|
}
|
||
|
|
|
||
|
|
async findById(id: string): Promise<SecretBackend | null> {
|
||
|
|
return this.prisma.secretBackend.findUnique({ where: { id } });
|
||
|
|
}
|
||
|
|
|
||
|
|
async findByName(name: string): Promise<SecretBackend | null> {
|
||
|
|
return this.prisma.secretBackend.findUnique({ where: { name } });
|
||
|
|
}
|
||
|
|
|
||
|
|
async findDefault(): Promise<SecretBackend | null> {
|
||
|
|
return this.prisma.secretBackend.findFirst({ where: { isDefault: true } });
|
||
|
|
}
|
||
|
|
|
||
|
|
async create(data: CreateSecretBackendInput): Promise<SecretBackend> {
|
||
|
|
return this.prisma.$transaction(async (tx) => {
|
||
|
|
if (data.isDefault === true) {
|
||
|
|
await tx.secretBackend.updateMany({ where: { isDefault: true }, data: { isDefault: false } });
|
||
|
|
}
|
||
|
|
return tx.secretBackend.create({
|
||
|
|
data: {
|
||
|
|
name: data.name,
|
||
|
|
type: data.type,
|
||
|
|
config: (data.config ?? {}) as Prisma.InputJsonValue,
|
||
|
|
isDefault: data.isDefault ?? false,
|
||
|
|
description: data.description ?? '',
|
||
|
|
},
|
||
|
|
});
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
async update(id: string, data: UpdateSecretBackendInput): Promise<SecretBackend> {
|
||
|
|
return this.prisma.$transaction(async (tx) => {
|
||
|
|
if (data.isDefault === true) {
|
||
|
|
await tx.secretBackend.updateMany({
|
||
|
|
where: { isDefault: true, NOT: { id } },
|
||
|
|
data: { isDefault: false },
|
||
|
|
});
|
||
|
|
}
|
||
|
|
const updateData: Prisma.SecretBackendUpdateInput = {};
|
||
|
|
if (data.config !== undefined) updateData.config = data.config as Prisma.InputJsonValue;
|
||
|
|
if (data.isDefault !== undefined) updateData.isDefault = data.isDefault;
|
||
|
|
if (data.description !== undefined) updateData.description = data.description;
|
||
|
|
return tx.secretBackend.update({ where: { id }, data: updateData });
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
async setAsDefault(id: string): Promise<SecretBackend> {
|
||
|
|
return this.prisma.$transaction(async (tx) => {
|
||
|
|
await tx.secretBackend.updateMany({
|
||
|
|
where: { isDefault: true, NOT: { id } },
|
||
|
|
data: { isDefault: false },
|
||
|
|
});
|
||
|
|
return tx.secretBackend.update({ where: { id }, data: { isDefault: true } });
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
async delete(id: string): Promise<void> {
|
||
|
|
await this.prisma.secretBackend.delete({ where: { id } });
|
||
|
|
}
|
||
|
|
|
||
|
|
async countReferencingSecrets(backendId: string): Promise<number> {
|
||
|
|
return this.prisma.secret.count({ where: { backendId } });
|
||
|
|
}
|
||
|
|
}
|