This commit is contained in:
carlosmonastyrski
2025-05-06 08:11:50 -03:00
parent c6e56f0380
commit 32a3e1d200
17 changed files with 895 additions and 28 deletions

View File

@@ -74,6 +74,24 @@ import {
TExternalKms,
TExternalKmsInsert,
TExternalKmsUpdate,
TFolderCheckpointResources,
TFolderCheckpointResourcesInsert,
TFolderCheckpointResourcesUpdate,
TFolderCheckpoints,
TFolderCheckpointsInsert,
TFolderCheckpointsUpdate,
TFolderCommitChanges,
TFolderCommitChangesInsert,
TFolderCommitChangesUpdate,
TFolderCommits,
TFolderCommitsInsert,
TFolderCommitsUpdate,
TFolderTreeCheckpointResources,
TFolderTreeCheckpointResourcesInsert,
TFolderTreeCheckpointResourcesUpdate,
TFolderTreeCheckpoints,
TFolderTreeCheckpointsInsert,
TFolderTreeCheckpointsUpdate,
TGateways,
TGatewaysInsert,
TGatewaysUpdate,
@@ -1048,5 +1066,35 @@ declare module "knex/types/tables" {
TGithubOrgSyncConfigsInsert,
TGithubOrgSyncConfigsUpdate
>;
[TableName.FolderCommit]: KnexOriginal.CompositeTableType<
TFolderCommits,
TFolderCommitsInsert,
TFolderCommitsUpdate
>;
[TableName.FolderCommitChanges]: KnexOriginal.CompositeTableType<
TFolderCommitChanges,
TFolderCommitChangesInsert,
TFolderCommitChangesUpdate
>;
[TableName.FolderCheckpoint]: KnexOriginal.CompositeTableType<
TFolderCheckpoints,
TFolderCheckpointsInsert,
TFolderCheckpointsUpdate
>;
[TableName.FolderCheckpointResources]: KnexOriginal.CompositeTableType<
TFolderCheckpointResources,
TFolderCheckpointResourcesInsert,
TFolderCheckpointResourcesUpdate
>;
[TableName.FolderTreeCheckpoint]: KnexOriginal.CompositeTableType<
TFolderTreeCheckpoints,
TFolderTreeCheckpointsInsert,
TFolderTreeCheckpointsUpdate
>;
[TableName.FolderTreeCheckpointResources]: KnexOriginal.CompositeTableType<
TFolderTreeCheckpointResources,
TFolderTreeCheckpointResourcesInsert,
TFolderTreeCheckpointResourcesUpdate
>;
}
}

View File

@@ -0,0 +1,130 @@
import { Knex } from "knex";
import { TableName } from "../schemas";
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
export async function up(knex: Knex): Promise<void> {
const hasFolderCommitTable = await knex.schema.hasTable(TableName.FolderCommit);
if (!hasFolderCommitTable) {
await knex.schema.createTable(TableName.FolderCommit, (t) => {
t.bigIncrements("id").primary();
t.string("actorName").notNullable();
t.string("actorType").notNullable();
t.string("message");
t.timestamp("date").notNullable().defaultTo(knex.fn.now());
t.uuid("folderId").notNullable();
t.foreign("folderId").references("id").inTable(TableName.SecretFolder).onDelete("CASCADE");
t.timestamps(true, true, true);
t.index("folderId");
});
}
const hasFolderCommitChangesTable = await knex.schema.hasTable(TableName.FolderCommitChanges);
if (!hasFolderCommitChangesTable) {
await knex.schema.createTable(TableName.FolderCommitChanges, (t) => {
t.uuid("id").primary().defaultTo(knex.fn.uuid());
t.bigInteger("folderCommitId").notNullable();
t.foreign("folderCommitId").references("id").inTable(TableName.FolderCommit).onDelete("CASCADE");
t.string("changeType").notNullable();
t.uuid("secretVersionId");
t.foreign("secretVersionId").references("id").inTable(TableName.SecretVersionV2).onDelete("CASCADE");
t.uuid("folderVersionId");
t.foreign("folderVersionId").references("id").inTable(TableName.SecretFolderVersion).onDelete("CASCADE");
t.timestamps(true, true, true);
t.index("folderCommitId");
t.index("secretVersionId");
t.index("folderVersionId");
});
}
const hasFolderCheckpointTable = await knex.schema.hasTable(TableName.FolderCheckpoint);
if (!hasFolderCheckpointTable) {
await knex.schema.createTable(TableName.FolderCheckpoint, (t) => {
t.uuid("id").primary().defaultTo(knex.fn.uuid());
t.bigInteger("folderCommitId").notNullable();
t.foreign("folderCommitId").references("id").inTable(TableName.FolderCommit).onDelete("CASCADE");
t.timestamp("date").notNullable().defaultTo(knex.fn.now());
t.timestamps(true, true, true);
t.index("folderCommitId");
});
}
const hasFolderCheckpointResourcesTable = await knex.schema.hasTable(TableName.FolderCheckpointResources);
if (!hasFolderCheckpointResourcesTable) {
await knex.schema.createTable(TableName.FolderCheckpointResources, (t) => {
t.uuid("id").primary().defaultTo(knex.fn.uuid());
t.uuid("folderCheckpointId").notNullable();
t.foreign("folderCheckpointId").references("id").inTable(TableName.FolderCheckpoint).onDelete("CASCADE");
t.uuid("secretVersionId");
t.foreign("secretVersionId").references("id").inTable(TableName.SecretVersionV2).onDelete("CASCADE");
t.uuid("folderVersionId");
t.foreign("folderVersionId").references("id").inTable(TableName.SecretFolderVersion).onDelete("CASCADE");
t.timestamps(true, true, true);
t.index("folderCheckpointId");
t.index("secretVersionId");
t.index("folderVersionId");
});
}
const hasFolderTreeCheckpointTable = await knex.schema.hasTable(TableName.FolderTreeCheckpoint);
if (!hasFolderTreeCheckpointTable) {
await knex.schema.createTable(TableName.FolderTreeCheckpoint, (t) => {
t.uuid("id").primary().defaultTo(knex.fn.uuid());
t.bigInteger("folderCommitId").notNullable();
t.foreign("folderCommitId").references("id").inTable(TableName.FolderCommit).onDelete("CASCADE");
t.timestamp("date").notNullable().defaultTo(knex.fn.now());
t.timestamps(true, true, true);
t.index("folderCommitId");
});
}
const hasFolderTreeCheckpointResourcesTable = await knex.schema.hasTable(TableName.FolderTreeCheckpointResources);
if (!hasFolderTreeCheckpointResourcesTable) {
await knex.schema.createTable(TableName.FolderTreeCheckpointResources, (t) => {
t.uuid("id").primary().defaultTo(knex.fn.uuid());
t.uuid("folderTreeCheckpointId").notNullable();
t.foreign("folderTreeCheckpointId").references("id").inTable(TableName.FolderTreeCheckpoint).onDelete("CASCADE");
t.uuid("folderId").notNullable();
t.foreign("folderId").references("id").inTable(TableName.SecretFolder).onDelete("CASCADE");
t.bigInteger("folderCommitId").notNullable();
t.foreign("folderCommitId").references("id").inTable(TableName.FolderCommit).onDelete("CASCADE");
t.timestamps(true, true, true);
t.index("folderTreeCheckpointId");
t.index("folderId");
t.index("folderCommitId");
});
}
await createOnUpdateTrigger(knex, TableName.FolderCommit);
await createOnUpdateTrigger(knex, TableName.FolderCommitChanges);
await createOnUpdateTrigger(knex, TableName.FolderCheckpoint);
await createOnUpdateTrigger(knex, TableName.FolderCheckpointResources);
await createOnUpdateTrigger(knex, TableName.FolderTreeCheckpoint);
await createOnUpdateTrigger(knex, TableName.FolderTreeCheckpointResources);
}
export async function down(knex: Knex): Promise<void> {
await dropOnUpdateTrigger(knex, TableName.FolderTreeCheckpointResources);
await knex.schema.dropTableIfExists(TableName.FolderTreeCheckpointResources);
await dropOnUpdateTrigger(knex, TableName.FolderTreeCheckpoint);
await knex.schema.dropTableIfExists(TableName.FolderTreeCheckpoint);
await dropOnUpdateTrigger(knex, TableName.FolderCheckpointResources);
await knex.schema.dropTableIfExists(TableName.FolderCheckpointResources);
await dropOnUpdateTrigger(knex, TableName.FolderCheckpoint);
await knex.schema.dropTableIfExists(TableName.FolderCheckpoint);
await dropOnUpdateTrigger(knex, TableName.FolderCommitChanges);
await knex.schema.dropTableIfExists(TableName.FolderCommitChanges);
await dropOnUpdateTrigger(knex, TableName.FolderCommit);
await knex.schema.dropTableIfExists(TableName.FolderCommit);
}

View File

@@ -0,0 +1,23 @@
// Code generated by automation script, DO NOT EDIT.
// Automated by pulling database and generating zod schema
// To update. Just run npm run generate:schema
// Written by akhilmhdh.
import { z } from "zod";
import { TImmutableDBKeys } from "./models";
export const FolderCheckpointResourcesSchema = z.object({
id: z.string().uuid(),
folderCheckpointId: z.string().uuid(),
secretVersionId: z.string().uuid().nullable().optional(),
folderVersionId: z.string().uuid().nullable().optional(),
createdAt: z.date(),
updatedAt: z.date()
});
export type TFolderCheckpointResources = z.infer<typeof FolderCheckpointResourcesSchema>;
export type TFolderCheckpointResourcesInsert = Omit<z.input<typeof FolderCheckpointResourcesSchema>, TImmutableDBKeys>;
export type TFolderCheckpointResourcesUpdate = Partial<
Omit<z.input<typeof FolderCheckpointResourcesSchema>, TImmutableDBKeys>
>;

View File

@@ -0,0 +1,20 @@
// Code generated by automation script, DO NOT EDIT.
// Automated by pulling database and generating zod schema
// To update. Just run npm run generate:schema
// Written by akhilmhdh.
import { z } from "zod";
import { TImmutableDBKeys } from "./models";
export const FolderCheckpointsSchema = z.object({
id: z.string().uuid(),
folderCommitId: z.coerce.number(),
date: z.date(),
createdAt: z.date(),
updatedAt: z.date()
});
export type TFolderCheckpoints = z.infer<typeof FolderCheckpointsSchema>;
export type TFolderCheckpointsInsert = Omit<z.input<typeof FolderCheckpointsSchema>, TImmutableDBKeys>;
export type TFolderCheckpointsUpdate = Partial<Omit<z.input<typeof FolderCheckpointsSchema>, TImmutableDBKeys>>;

View File

@@ -0,0 +1,22 @@
// Code generated by automation script, DO NOT EDIT.
// Automated by pulling database and generating zod schema
// To update. Just run npm run generate:schema
// Written by akhilmhdh.
import { z } from "zod";
import { TImmutableDBKeys } from "./models";
export const FolderCommitChangesSchema = z.object({
id: z.string().uuid(),
folderCommitId: z.coerce.number(),
changeType: z.string(),
secretVersionId: z.string().uuid().nullable().optional(),
folderVersionId: z.string().uuid().nullable().optional(),
createdAt: z.date(),
updatedAt: z.date()
});
export type TFolderCommitChanges = z.infer<typeof FolderCommitChangesSchema>;
export type TFolderCommitChangesInsert = Omit<z.input<typeof FolderCommitChangesSchema>, TImmutableDBKeys>;
export type TFolderCommitChangesUpdate = Partial<Omit<z.input<typeof FolderCommitChangesSchema>, TImmutableDBKeys>>;

View File

@@ -0,0 +1,23 @@
// Code generated by automation script, DO NOT EDIT.
// Automated by pulling database and generating zod schema
// To update. Just run npm run generate:schema
// Written by akhilmhdh.
import { z } from "zod";
import { TImmutableDBKeys } from "./models";
export const FolderCommitsSchema = z.object({
id: z.coerce.number(),
actorName: z.string(),
actorType: z.string(),
message: z.string().nullable().optional(),
date: z.date(),
folderId: z.string().uuid(),
createdAt: z.date(),
updatedAt: z.date()
});
export type TFolderCommits = z.infer<typeof FolderCommitsSchema>;
export type TFolderCommitsInsert = Omit<z.input<typeof FolderCommitsSchema>, TImmutableDBKeys>;
export type TFolderCommitsUpdate = Partial<Omit<z.input<typeof FolderCommitsSchema>, TImmutableDBKeys>>;

View File

@@ -0,0 +1,26 @@
// Code generated by automation script, DO NOT EDIT.
// Automated by pulling database and generating zod schema
// To update. Just run npm run generate:schema
// Written by akhilmhdh.
import { z } from "zod";
import { TImmutableDBKeys } from "./models";
export const FolderTreeCheckpointResourcesSchema = z.object({
id: z.string().uuid(),
folderTreeCheckpointId: z.string().uuid(),
folderId: z.string().uuid(),
folderCommitId: z.coerce.number(),
createdAt: z.date(),
updatedAt: z.date()
});
export type TFolderTreeCheckpointResources = z.infer<typeof FolderTreeCheckpointResourcesSchema>;
export type TFolderTreeCheckpointResourcesInsert = Omit<
z.input<typeof FolderTreeCheckpointResourcesSchema>,
TImmutableDBKeys
>;
export type TFolderTreeCheckpointResourcesUpdate = Partial<
Omit<z.input<typeof FolderTreeCheckpointResourcesSchema>, TImmutableDBKeys>
>;

View File

@@ -0,0 +1,20 @@
// Code generated by automation script, DO NOT EDIT.
// Automated by pulling database and generating zod schema
// To update. Just run npm run generate:schema
// Written by akhilmhdh.
import { z } from "zod";
import { TImmutableDBKeys } from "./models";
export const FolderTreeCheckpointsSchema = z.object({
id: z.string().uuid(),
folderCommitId: z.coerce.number(),
date: z.date(),
createdAt: z.date(),
updatedAt: z.date()
});
export type TFolderTreeCheckpoints = z.infer<typeof FolderTreeCheckpointsSchema>;
export type TFolderTreeCheckpointsInsert = Omit<z.input<typeof FolderTreeCheckpointsSchema>, TImmutableDBKeys>;
export type TFolderTreeCheckpointsUpdate = Partial<Omit<z.input<typeof FolderTreeCheckpointsSchema>, TImmutableDBKeys>>;

View File

@@ -22,6 +22,12 @@ export * from "./dynamic-secret-leases";
export * from "./dynamic-secrets";
export * from "./external-group-org-role-mappings";
export * from "./external-kms";
export * from "./folder-checkpoint-resources";
export * from "./folder-checkpoints";
export * from "./folder-commit-changes";
export * from "./folder-commits";
export * from "./folder-tree-checkpoint-resources";
export * from "./folder-tree-checkpoints";
export * from "./gateways";
export * from "./git-app-install-sessions";
export * from "./git-app-org";

View File

@@ -152,7 +152,13 @@ export enum TableName {
MicrosoftTeamsIntegrations = "microsoft_teams_integrations",
ProjectMicrosoftTeamsConfigs = "project_microsoft_teams_configs",
SecretReminderRecipients = "secret_reminder_recipients",
GithubOrgSyncConfig = "github_org_sync_configs"
GithubOrgSyncConfig = "github_org_sync_configs",
FolderCommit = "folder_commits",
FolderCommitChanges = "folder_commit_changes",
FolderCheckpoint = "folder_checkpoints",
FolderCheckpointResources = "folder_checkpoint_resources",
FolderTreeCheckpoint = "folder_tree_checkpoints",
FolderTreeCheckpointResources = "folder_tree_checkpoint_resources"
}
export type TImmutableDBKeys = "id" | "createdAt" | "updatedAt";

View File

@@ -17,44 +17,44 @@ export const getDefaultOnPremFeatures = (): TFeatureSet => ({
environmentsUsed: 0,
identityLimit: null,
identitiesUsed: 0,
dynamicSecret: false,
dynamicSecret: true,
secretVersioning: true,
pitRecovery: false,
ipAllowlisting: false,
rbac: false,
githubOrgSync: false,
customRateLimits: false,
customAlerts: false,
secretAccessInsights: false,
auditLogs: false,
pitRecovery: true,
ipAllowlisting: true,
rbac: true,
githubOrgSync: true,
customRateLimits: true,
customAlerts: true,
secretAccessInsights: true,
auditLogs: true,
auditLogsRetentionDays: 0,
auditLogStreams: false,
auditLogStreams: true,
auditLogStreamLimit: 3,
samlSSO: false,
hsm: false,
oidcSSO: false,
scim: false,
ldap: false,
groups: false,
samlSSO: true,
hsm: true,
oidcSSO: true,
scim: true,
ldap: true,
groups: true,
status: null,
trial_end: null,
has_used_trial: true,
secretApproval: false,
secretRotation: false,
caCrl: false,
instanceUserManagement: false,
externalKms: false,
secretApproval: true,
secretRotation: true,
caCrl: true,
instanceUserManagement: true,
externalKms: true,
rateLimits: {
readLimit: 60,
writeLimit: 200,
secretsLimit: 40
},
pkiEst: false,
enforceMfa: false,
projectTemplates: false,
kmip: false,
gateway: false,
sshHostGroups: false
pkiEst: true,
enforceMfa: true,
projectTemplates: true,
kmip: true,
gateway: true,
sshHostGroups: true
});
export const setupLicenseRequestWithStore = (baseURL: string, refreshUrl: string, licenseKey: string) => {

View File

@@ -0,0 +1,79 @@
import { Knex } from "knex";
import { TDbClient } from "@app/db";
import { TableName, TFolderCheckpointResources, TFolderCheckpoints } from "@app/db/schemas";
import { DatabaseError } from "@app/lib/errors";
import { ormify, selectAllTableCols } from "@app/lib/knex";
export type TFolderCheckpointResourcesDALFactory = ReturnType<typeof folderCheckpointResourcesDALFactory>;
type ResourceWithCheckpointInfo = TFolderCheckpointResources & {
folderCommitId: string;
date: Date;
};
export const folderCheckpointResourcesDALFactory = (db: TDbClient) => {
const folderCheckpointResourcesOrm = ormify<TFolderCheckpointResources>(db, TableName.FolderCheckpointResources);
const findByCheckpointId = async (folderCheckpointId: string, tx?: Knex): Promise<TFolderCheckpointResources[]> => {
try {
const docs = await (tx || db.replicaNode())<TFolderCheckpointResources>(TableName.FolderCheckpointResources)
.where({ folderCheckpointId })
.select(selectAllTableCols(TableName.FolderCheckpointResources));
return docs;
} catch (error) {
throw new DatabaseError({ error, name: "FindByCheckpointId" });
}
};
const findBySecretVersionId = async (secretVersionId: string, tx?: Knex): Promise<ResourceWithCheckpointInfo[]> => {
try {
const docs = await (tx || db.replicaNode())<
TFolderCheckpointResources & Pick<TFolderCheckpoints, "folderCommitId" | "date">
>(TableName.FolderCheckpointResources)
.where({ secretVersionId })
.select(selectAllTableCols(TableName.FolderCheckpointResources))
.join(
TableName.FolderCheckpoint,
`${TableName.FolderCheckpointResources}.folderCheckpointId`,
`${TableName.FolderCheckpoint}.id`
)
.select(
db.ref("folderCommitId").withSchema(TableName.FolderCheckpoint),
db.ref("date").withSchema(TableName.FolderCheckpoint)
);
return docs;
} catch (error) {
throw new DatabaseError({ error, name: "FindBySecretVersionId" });
}
};
const findByFolderVersionId = async (folderVersionId: string, tx?: Knex): Promise<ResourceWithCheckpointInfo[]> => {
try {
const docs = await (tx || db.replicaNode())<
TFolderCheckpointResources & Pick<TFolderCheckpoints, "folderCommitId" | "date">
>(TableName.FolderCheckpointResources)
.where({ folderVersionId })
.select(selectAllTableCols(TableName.FolderCheckpointResources))
.join(
TableName.FolderCheckpoint,
`${TableName.FolderCheckpointResources}.folderCheckpointId`,
`${TableName.FolderCheckpoint}.id`
)
.select(
db.ref("folderCommitId").withSchema(TableName.FolderCheckpoint),
db.ref("date").withSchema(TableName.FolderCheckpoint)
);
return docs;
} catch (error) {
throw new DatabaseError({ error, name: "FindByFolderVersionId" });
}
};
return {
...folderCheckpointResourcesOrm,
findByCheckpointId,
findBySecretVersionId,
findByFolderVersionId
};
};

View File

@@ -0,0 +1,86 @@
import { Knex } from "knex";
import { TDbClient } from "@app/db";
import { TableName, TFolderCheckpoints } from "@app/db/schemas";
import { DatabaseError } from "@app/lib/errors";
import { ormify, selectAllTableCols } from "@app/lib/knex";
export type TFolderCheckpointDALFactory = ReturnType<typeof folderCheckpointDALFactory>;
type CheckpointWithCommitInfo = TFolderCheckpoints & {
actorName: string;
actorType: string;
message: string | null;
commitDate: Date;
folderId: string;
};
export const folderCheckpointDALFactory = (db: TDbClient) => {
const folderCheckpointOrm = ormify<TFolderCheckpoints>(db, TableName.FolderCheckpoint);
const findByCommitId = async (folderCommitId: string, tx?: Knex): Promise<TFolderCheckpoints | undefined> => {
try {
const doc = await (tx || db.replicaNode())<TFolderCheckpoints>(TableName.FolderCheckpoint)
.where({ folderCommitId })
.select(selectAllTableCols(TableName.FolderCheckpoint))
.first();
return doc;
} catch (error) {
throw new DatabaseError({ error, name: "FindByCommitId" });
}
};
const findByFolderId = async (folderId: string, limit?: number, tx?: Knex): Promise<CheckpointWithCommitInfo[]> => {
try {
let query = (tx || db.replicaNode())(TableName.FolderCheckpoint)
.join(TableName.FolderCommit, `${TableName.FolderCheckpoint}.folderCommitId`, `${TableName.FolderCommit}.id`)
.where({ folderId })
.select(selectAllTableCols(TableName.FolderCheckpoint))
.select(
db.ref("actorName").withSchema(TableName.FolderCommit),
db.ref("actorType").withSchema(TableName.FolderCommit),
db.ref("message").withSchema(TableName.FolderCommit),
db.ref("date").withSchema(TableName.FolderCommit).as("commitDate"),
db.ref("folderId").withSchema(TableName.FolderCommit)
)
.orderBy(`${TableName.FolderCheckpoint}.date`, "desc");
if (limit !== undefined) {
query = query.limit(limit);
}
const docs = await query;
return docs;
} catch (error) {
throw new DatabaseError({ error, name: "FindByFolderId" });
}
};
const findLatestByFolderId = async (folderId: string, tx?: Knex): Promise<CheckpointWithCommitInfo | undefined> => {
try {
const doc = await (tx || db.replicaNode())(TableName.FolderCheckpoint)
.join(TableName.FolderCommit, `${TableName.FolderCheckpoint}.folderCommitId`, `${TableName.FolderCommit}.id`)
.where({ folderId })
.select(selectAllTableCols(TableName.FolderCheckpoint))
.select(
db.ref("actorName").withSchema(TableName.FolderCommit),
db.ref("actorType").withSchema(TableName.FolderCommit),
db.ref("message").withSchema(TableName.FolderCommit),
db.ref("date").withSchema(TableName.FolderCommit).as("commitDate"),
db.ref("folderId").withSchema(TableName.FolderCommit)
)
.orderBy(`${TableName.FolderCheckpoint}.date`, "desc")
.first();
return doc;
} catch (error) {
throw new DatabaseError({ error, name: "FindLatestByFolderId" });
}
};
return {
...folderCheckpointOrm,
findByCommitId,
findByFolderId,
findLatestByFolderId
};
};

View File

@@ -0,0 +1,80 @@
import { Knex } from "knex";
import { TDbClient } from "@app/db";
import { TableName, TFolderCommitChanges, TFolderCommits } from "@app/db/schemas";
import { DatabaseError } from "@app/lib/errors";
import { ormify, selectAllTableCols } from "@app/lib/knex";
export type TFolderCommitChangesDALFactory = ReturnType<typeof folderCommitChangesDALFactory>;
type CommitChangeWithCommitInfo = TFolderCommitChanges & {
actorName: string;
actorType: string;
message: string | null;
date: Date;
folderId: string;
};
export const folderCommitChangesDALFactory = (db: TDbClient) => {
const folderCommitChangesOrm = ormify<TFolderCommitChanges>(db, TableName.FolderCommitChanges);
const findByCommitId = async (folderCommitId: string, tx?: Knex): Promise<TFolderCommitChanges[]> => {
try {
const docs = await (tx || db.replicaNode())<TFolderCommitChanges>(TableName.FolderCommitChanges)
.where({ folderCommitId })
.select(selectAllTableCols(TableName.FolderCommitChanges));
return docs;
} catch (error) {
throw new DatabaseError({ error, name: "FindByCommitId" });
}
};
const findBySecretVersionId = async (secretVersionId: string, tx?: Knex): Promise<CommitChangeWithCommitInfo[]> => {
try {
const docs = await (tx || db.replicaNode())<
TFolderCommitChanges & Pick<TFolderCommits, "actorName" | "actorType" | "message" | "date" | "folderId">
>(TableName.FolderCommitChanges)
.where({ secretVersionId })
.select(selectAllTableCols(TableName.FolderCommitChanges))
.join(TableName.FolderCommit, `${TableName.FolderCommitChanges}.folderCommitId`, `${TableName.FolderCommit}.id`)
.select(
db.ref("actorName").withSchema(TableName.FolderCommit),
db.ref("actorType").withSchema(TableName.FolderCommit),
db.ref("message").withSchema(TableName.FolderCommit),
db.ref("date").withSchema(TableName.FolderCommit),
db.ref("folderId").withSchema(TableName.FolderCommit)
);
return docs;
} catch (error) {
throw new DatabaseError({ error, name: "FindBySecretVersionId" });
}
};
const findByFolderVersionId = async (folderVersionId: string, tx?: Knex): Promise<CommitChangeWithCommitInfo[]> => {
try {
const docs = await (tx || db.replicaNode())<
TFolderCommitChanges & Pick<TFolderCommits, "actorName" | "actorType" | "message" | "date" | "folderId">
>(TableName.FolderCommitChanges)
.where({ folderVersionId })
.select(selectAllTableCols(TableName.FolderCommitChanges))
.join(TableName.FolderCommit, `${TableName.FolderCommitChanges}.folderCommitId`, `${TableName.FolderCommit}.id`)
.select(
db.ref("actorName").withSchema(TableName.FolderCommit),
db.ref("actorType").withSchema(TableName.FolderCommit),
db.ref("message").withSchema(TableName.FolderCommit),
db.ref("date").withSchema(TableName.FolderCommit),
db.ref("folderId").withSchema(TableName.FolderCommit)
);
return docs;
} catch (error) {
throw new DatabaseError({ error, name: "FindByFolderVersionId" });
}
};
return {
...folderCommitChangesOrm,
findByCommitId,
findBySecretVersionId,
findByFolderVersionId
};
};

View File

@@ -0,0 +1,56 @@
import { Knex } from "knex";
import { TDbClient } from "@app/db";
import { TableName, TFolderCommits } from "@app/db/schemas";
import { DatabaseError } from "@app/lib/errors";
import { ormify, selectAllTableCols } from "@app/lib/knex";
export type TFolderCommitDALFactory = ReturnType<typeof folderCommitDALFactory>;
export const folderCommitDALFactory = (db: TDbClient) => {
const folderCommitOrm = ormify<TFolderCommits>(db, TableName.FolderCommit);
const findByFolderId = async (folderId: string, tx?: Knex): Promise<TFolderCommits[]> => {
try {
const docs = await (tx || db.replicaNode())<TFolderCommits>(TableName.FolderCommit)
.where({ folderId })
.select(selectAllTableCols(TableName.FolderCommit))
.orderBy("date", "desc");
return docs;
} catch (error) {
throw new DatabaseError({ error, name: "FindByFolderId" });
}
};
const findById = async (id: string, tx?: Knex): Promise<TFolderCommits | undefined> => {
try {
const doc = await (tx || db.replicaNode())<TFolderCommits>(TableName.FolderCommit)
.where({ id })
.select(selectAllTableCols(TableName.FolderCommit))
.first();
return doc;
} catch (error) {
throw new DatabaseError({ error, name: "FindById" });
}
};
const findLatestCommit = async (folderId: string, tx?: Knex): Promise<TFolderCommits | undefined> => {
try {
const doc = await (tx || db.replicaNode())<TFolderCommits>(TableName.FolderCommit)
.where({ folderId })
.select(selectAllTableCols(TableName.FolderCommit))
.orderBy("date", "desc")
.first();
return doc;
} catch (error) {
throw new DatabaseError({ error, name: "FindLatestCommit" });
}
};
return {
...folderCommitOrm,
findByFolderId,
findById,
findLatestCommit
};
};

View File

@@ -0,0 +1,131 @@
import { Knex } from "knex";
import { TDbClient } from "@app/db";
import {
TableName,
TEnvironments,
TFolderTreeCheckpointResources,
TFolderTreeCheckpoints,
TSecretFolders
} from "@app/db/schemas";
import { DatabaseError } from "@app/lib/errors";
import { ormify, selectAllTableCols } from "@app/lib/knex";
export type TFolderTreeCheckpointResourcesDALFactory = ReturnType<typeof folderTreeCheckpointResourcesDALFactory>;
type ResourceWithCheckpointInfo = TFolderTreeCheckpointResources & {
folderCommitId: string;
date: Date;
};
type ResourceWithFolderInfo = TFolderTreeCheckpointResources & {
name: string;
parentId: string | null;
slug: string;
envName: string;
};
export const folderTreeCheckpointResourcesDALFactory = (db: TDbClient) => {
const folderTreeCheckpointResourcesOrm = ormify<TFolderTreeCheckpointResources>(
db,
TableName.FolderTreeCheckpointResources
);
const findByTreeCheckpointId = async (
folderTreeCheckpointId: string,
tx?: Knex
): Promise<TFolderTreeCheckpointResources[]> => {
try {
const docs = await (tx || db.replicaNode())<TFolderTreeCheckpointResources>(
TableName.FolderTreeCheckpointResources
)
.where({ folderTreeCheckpointId })
.select(selectAllTableCols(TableName.FolderTreeCheckpointResources));
return docs;
} catch (error) {
throw new DatabaseError({ error, name: "FindByTreeCheckpointId" });
}
};
const findByFolderId = async (folderId: string, tx?: Knex): Promise<ResourceWithCheckpointInfo[]> => {
try {
const docs = await (tx || db.replicaNode())<
TFolderTreeCheckpointResources & Pick<TFolderTreeCheckpoints, "folderCommitId" | "date">
>(TableName.FolderTreeCheckpointResources)
.where({ folderId })
.select(selectAllTableCols(TableName.FolderTreeCheckpointResources))
.join(
TableName.FolderTreeCheckpoint,
`${TableName.FolderTreeCheckpointResources}.folderTreeCheckpointId`,
`${TableName.FolderTreeCheckpoint}.id`
)
.select(
db.ref("folderCommitId").withSchema(TableName.FolderTreeCheckpoint),
db.ref("date").withSchema(TableName.FolderTreeCheckpoint)
);
return docs;
} catch (error) {
throw new DatabaseError({ error, name: "FindByFolderId" });
}
};
const findByFolderCommitId = async (
folderCommitId: string,
tx?: Knex
): Promise<(TFolderTreeCheckpointResources & { date: Date })[]> => {
try {
const docs = await (tx || db.replicaNode())<
TFolderTreeCheckpointResources & Pick<TFolderTreeCheckpoints, "date">
>(TableName.FolderTreeCheckpointResources)
.where({ folderCommitId })
.select(selectAllTableCols(TableName.FolderTreeCheckpointResources))
.join(
TableName.FolderTreeCheckpoint,
`${TableName.FolderTreeCheckpointResources}.folderTreeCheckpointId`,
`${TableName.FolderTreeCheckpoint}.id`
)
.select(db.ref("date").withSchema(TableName.FolderTreeCheckpoint));
return docs;
} catch (error) {
throw new DatabaseError({ error, name: "FindByFolderCommitId" });
}
};
const findFoldersInTreeCheckpoint = async (
folderTreeCheckpointId: string,
tx?: Knex
): Promise<ResourceWithFolderInfo[]> => {
try {
const docs = await (tx || db.replicaNode())<
TFolderTreeCheckpointResources &
Pick<TSecretFolders, "name" | "parentId"> &
Pick<TEnvironments, "slug"> & { envName: string }
>(TableName.FolderTreeCheckpointResources)
.where({ folderTreeCheckpointId })
.select(selectAllTableCols(TableName.FolderTreeCheckpointResources))
.join(
TableName.SecretFolder,
`${TableName.FolderTreeCheckpointResources}.folderId`,
`${TableName.SecretFolder}.id`
)
.join(TableName.Environment, `${TableName.SecretFolder}.envId`, `${TableName.Environment}.id`)
.select(
db.ref("name").withSchema(TableName.SecretFolder),
db.ref("parentId").withSchema(TableName.SecretFolder),
db.ref("slug").withSchema(TableName.Environment),
db.ref("name").withSchema(TableName.Environment).as("envName")
);
return docs;
} catch (error) {
throw new DatabaseError({ error, name: "FindFoldersInTreeCheckpoint" });
}
};
return {
...folderTreeCheckpointResourcesOrm,
findByTreeCheckpointId,
findByFolderId,
findByFolderCommitId,
findFoldersInTreeCheckpoint
};
};

View File

@@ -0,0 +1,111 @@
import { Knex } from "knex";
import { TDbClient } from "@app/db";
import { TableName, TFolderCommits, TFolderTreeCheckpoints } from "@app/db/schemas";
import { DatabaseError } from "@app/lib/errors";
import { ormify, selectAllTableCols } from "@app/lib/knex";
export type TFolderTreeCheckpointDALFactory = ReturnType<typeof folderTreeCheckpointDALFactory>;
type TreeCheckpointWithCommitInfo = TFolderTreeCheckpoints & {
actorName: string;
actorType: string;
message: string | null;
commitDate: Date;
folderId: string;
};
export const folderTreeCheckpointDALFactory = (db: TDbClient) => {
const folderTreeCheckpointOrm = ormify<TFolderTreeCheckpoints>(db, TableName.FolderTreeCheckpoint);
const findByCommitId = async (folderCommitId: string, tx?: Knex): Promise<TFolderTreeCheckpoints | undefined> => {
try {
const doc = await (tx || db.replicaNode())<TFolderTreeCheckpoints>(TableName.FolderTreeCheckpoint)
.where({ folderCommitId })
.select(selectAllTableCols(TableName.FolderTreeCheckpoint))
.first();
return doc;
} catch (error) {
throw new DatabaseError({ error, name: "FindByCommitId" });
}
};
const findByProjectId = async (
projectId: string,
limit?: number,
tx?: Knex
): Promise<TreeCheckpointWithCommitInfo[]> => {
try {
const query = (tx || db.replicaNode())<
TFolderTreeCheckpoints &
Pick<TFolderCommits, "actorName" | "actorType" | "message" | "folderId"> & { commitDate: Date }
>(TableName.FolderTreeCheckpoint)
.join(
TableName.FolderCommit,
`${TableName.FolderTreeCheckpoint}.folderCommitId`,
`${TableName.FolderCommit}.id`
)
.join(TableName.SecretFolder, `${TableName.FolderCommit}.folderId`, `${TableName.SecretFolder}.id`)
.join(TableName.Environment, `${TableName.SecretFolder}.envId`, `${TableName.Environment}.id`)
.where({ projectId })
.select(selectAllTableCols(TableName.FolderTreeCheckpoint))
.select(
db.ref("actorName").withSchema(TableName.FolderCommit),
db.ref("actorType").withSchema(TableName.FolderCommit),
db.ref("message").withSchema(TableName.FolderCommit),
db.ref("date").withSchema(TableName.FolderCommit).as("commitDate"),
db.ref("folderId").withSchema(TableName.FolderCommit)
)
.orderBy(`${TableName.FolderTreeCheckpoint}.date`, "desc");
if (limit) {
void query.limit(limit);
}
const docs = await query;
return docs;
} catch (error) {
throw new DatabaseError({ error, name: "FindByProjectId" });
}
};
const findLatestByProjectId = async (
projectId: string,
tx?: Knex
): Promise<TreeCheckpointWithCommitInfo | undefined> => {
try {
const doc = await (tx || db.replicaNode())<
TFolderTreeCheckpoints &
Pick<TFolderCommits, "actorName" | "actorType" | "message" | "folderId"> & { commitDate: Date }
>(TableName.FolderTreeCheckpoint)
.join(
TableName.FolderCommit,
`${TableName.FolderTreeCheckpoint}.folderCommitId`,
`${TableName.FolderCommit}.id`
)
.join(TableName.SecretFolder, `${TableName.FolderCommit}.folderId`, `${TableName.SecretFolder}.id`)
.join(TableName.Environment, `${TableName.SecretFolder}.envId`, `${TableName.Environment}.id`)
.where({ projectId })
.select(selectAllTableCols(TableName.FolderTreeCheckpoint))
.select(
db.ref("actorName").withSchema(TableName.FolderCommit),
db.ref("actorType").withSchema(TableName.FolderCommit),
db.ref("message").withSchema(TableName.FolderCommit),
db.ref("date").withSchema(TableName.FolderCommit).as("commitDate"),
db.ref("folderId").withSchema(TableName.FolderCommit)
)
.orderBy(`${TableName.FolderTreeCheckpoint}.date`, "desc")
.first();
return doc;
} catch (error) {
throw new DatabaseError({ error, name: "FindLatestByProjectId" });
}
};
return {
...folderTreeCheckpointOrm,
findByCommitId,
findByProjectId,
findLatestByProjectId
};
};