feat: fixed eslint and resolved all eslint issues

This commit is contained in:
Akhil Mohan
2024-01-30 22:30:42 +05:30
parent 7c4dd5000f
commit 5855cc660a
147 changed files with 1165 additions and 938 deletions
@@ -1,3 +1,6 @@
/* eslint-disable @typescript-eslint/no-unsafe-return */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
// TODO(akhilmhdh): Fix this when licence service gets it type
import { z } from "zod";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
@@ -26,7 +26,6 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => {
},
onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req) => {
const role = await server.services.orgRole.createRole(
req.permission.id,
req.params.organizationId,
@@ -58,7 +57,6 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => {
},
onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req) => {
const role = await server.services.orgRole.updateRole(
req.permission.id,
req.params.organizationId,
@@ -85,7 +83,6 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => {
},
onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req) => {
const role = await server.services.orgRole.deleteRole(
req.permission.id,
req.params.organizationId,
@@ -114,7 +111,6 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => {
},
onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req) => {
const roles = await server.services.orgRole.listRoles(
req.permission.id,
req.params.organizationId
@@ -139,7 +135,6 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => {
},
onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req) => {
const { permissions, membership } = await server.services.orgRole.getUserPermission(
req.permission.id,
req.params.organizationId
@@ -141,7 +141,6 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
},
onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req) => {
const { permissions, membership } = await server.services.projectRole.getUserPermission(
req.permission.id,
req.params.projectId
+10
View File
@@ -1,3 +1,11 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-unsafe-return */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-unsafe-argument */
// All the any rules are disabled because passport typesense with fastify is really poor
import { Authenticator } from "@fastify/passport";
import fastifySession from "@fastify/session";
import { MultiSamlStrategy } from "@node-saml/passport-saml";
@@ -33,6 +41,7 @@ export const registerSamlRouter = async (server: FastifyZodProvider) => {
new MultiSamlStrategy(
{
passReqToCallback: true,
// eslint-disable-next-line
getSamlOptions: async (req, done) => {
try {
const { ssoIdentifier } = req.params;
@@ -67,6 +76,7 @@ export const registerSamlRouter = async (server: FastifyZodProvider) => {
}
}
},
// eslint-disable-next-line
async (req, profile, cb) => {
try {
const serverCfg = getServerCfg();
@@ -111,17 +111,18 @@ export const registerSecretApprovalPolicyRouter = async (server: FastifyZodProvi
}),
response: {
200: z.object({
approvals: sapPubSchema.merge(z.object({approvers:z.string().array()})).array()
approvals: sapPubSchema.merge(z.object({ approvers: z.string().array() })).array()
})
}
},
onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req) => {
const approvals = await server.services.secretApprovalPolicy.getSecretApprovalPolicyByProjectId({
actor: req.permission.type,
actorId: req.permission.id,
projectId: req.query.workspaceId
});
const approvals =
await server.services.secretApprovalPolicy.getSecretApprovalPolicyByProjectId({
actor: req.permission.type,
actorId: req.permission.id,
projectId: req.query.workspaceId
});
return { approvals };
}
});
@@ -137,7 +138,7 @@ export const registerSecretApprovalPolicyRouter = async (server: FastifyZodProvi
}),
response: {
200: z.object({
policy: sapPubSchema.merge(z.object({approvers:z.string().array()})).optional()
policy: sapPubSchema.merge(z.object({ approvers: z.string().array() })).optional()
})
}
},
@@ -174,11 +174,13 @@ export const registerSecretApprovalRequestRouter = async (server: FastifyZodProv
...req.auditLogInfo,
event: {
type: isClosing ? EventType.SECRET_APPROVAL_CLOSED : EventType.SECRET_APPROVAL_REOPENED,
// eslint-disable-next-line
metadata: {
[isClosing ? ("closedBy" as const) : ("reopenedBy" as const)]:
approval.statusChangeBy as string,
secretApprovalRequestId: approval.id,
secretApprovalRequestSlug: approval.slug
// eslint-disable-next-line
} as any
// akhilmhdh: had to apply any to avoid ts issue with this
}
@@ -48,10 +48,10 @@ export const auditLogDALFactory = (db: TDbClient) => {
.limit(limit)
.offset(offset);
if (startDate) {
sqlQuery.where("createdAt", ">=", startDate);
void sqlQuery.where("createdAt", ">=", startDate);
}
if (endDate) {
sqlQuery.where("createdAt", "<=", endDate);
void sqlQuery.where("createdAt", "<=", endDate);
}
const docs = await sqlQuery;
return docs;
@@ -39,7 +39,7 @@ export const setupLicenceRequestWithStore = (
let token: string;
const licenceReq = axios.create({
baseURL,
timeout: 35 * 1000,
timeout: 35 * 1000
// signal: AbortSignal.timeout(60 * 1000)
});
@@ -47,7 +47,7 @@ export const setupLicenceRequestWithStore = (
const appCfg = getConfig();
const {
data: { token: authToken }
} = await request.post(
} = await request.post<{ token: string }>(
refreshUrl,
{},
{
@@ -75,18 +75,18 @@ export const setupLicenceRequestWithStore = (
licenceReq.interceptors.response.use(
(response) => response,
async (err) => {
const originalRequest = err.config;
const originalRequest = (err as AxiosError).config;
// eslint-disable-next-line
if ((err as AxiosError)?.response?.status === 401 && !originalRequest._retry) {
if ((err as AxiosError)?.response?.status === 401 && !(originalRequest as any)._retry) {
// eslint-disable-next-line
originalRequest._retry = true;
(originalRequest as any)._retry = true; // injected
// refresh
await refreshLicence();
licenceReq.defaults.headers.common.Authorization = `Bearer ${token}`;
return licenceReq(originalRequest);
return licenceReq(originalRequest!);
}
return Promise.reject(err);
@@ -13,7 +13,7 @@ export const licenseDALFactory = (db: TDbClient) => {
.where({ status: OrgMembershipStatus.Accepted })
.andWhere((bd) => {
if (orgId) {
bd.where({ orgId });
void bd.where({ orgId });
}
})
.count();
@@ -1,3 +1,9 @@
/* eslint-disable @typescript-eslint/no-unsafe-return */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
// eslint-disable @typescript-eslint/no-unsafe-assignment
// TODO(akhilmhdh): With tony find out the api structure and fill it here
import { ForbiddenError } from "@casl/ability";
import NodeCache from "node-cache";
@@ -92,7 +98,7 @@ export const licenseServiceFactory = ({
// else it would reach catch statement
isValidLicense = true;
} catch (error) {
logger.error(`init-license: encountered an error when init license [error=${error}]`);
logger.error(`init-license: encountered an error when init license [error]`, error);
}
};
@@ -119,7 +125,10 @@ export const licenseServiceFactory = ({
return currentPlan;
}
} catch (error) {
logger.error(`getPlan: encountered an error when fetching pan [orgId=${orgId}] [projectId=${projectId}] [error=${error}]`);
logger.error(
`getPlan: encountered an error when fetching pan [orgId=${orgId}] [projectId=${projectId}] [error]`,
error
);
return onPremFeatures;
}
return onPremFeatures;
@@ -136,7 +145,7 @@ export const licenseServiceFactory = ({
if (instanceType === InstanceType.Cloud) {
const {
data: { customerId }
} = await licenseServerCloudApi.request.post(
} = await licenseServerCloudApi.request.post<{ customerId: string }>(
"/api/license-server/v1/customers",
{
email,
@@ -239,17 +239,29 @@ export const buildServiceTokenProjectPermission = (
const { can, build } = new AbilityBuilder<MongoAbility<ProjectPermissionSet>>(createMongoAbility);
scopes.forEach(({ secretPath, environment }) => {
if (canWrite) {
// TODO: @Akhi
// @ts-expect-error type
can(ProjectPermissionActions.Edit, ProjectPermissionSub.Secrets, { secretPath: { $glob: secretPath }, environment });
// @ts-expect-error type
can(ProjectPermissionActions.Create, ProjectPermissionSub.Secrets, { secretPath: { $glob: secretPath }, environment });
// @ts-expect-error type
can(ProjectPermissionActions.Delete, ProjectPermissionSub.Secrets, {secretPath: { $glob: secretPath }, environment });
// TODO: @Akhi
// @ts-expect-error type
can(ProjectPermissionActions.Edit, ProjectPermissionSub.Secrets, {
secretPath: { $glob: secretPath },
environment
});
// @ts-expect-error type
can(ProjectPermissionActions.Create, ProjectPermissionSub.Secrets, {
secretPath: { $glob: secretPath },
environment
});
// @ts-expect-error type
can(ProjectPermissionActions.Delete, ProjectPermissionSub.Secrets, {
secretPath: { $glob: secretPath },
environment
});
}
if (canRead) {
// @ts-expect-error type
can(ProjectPermissionActions.Read, ProjectPermissionSub.Secrets, { secretPath: { $glob: secretPath }, environment });
// @ts-expect-error type
can(ProjectPermissionActions.Read, ProjectPermissionSub.Secrets, {
secretPath: { $glob: secretPath },
environment
});
}
});
@@ -258,6 +270,8 @@ export const buildServiceTokenProjectPermission = (
export const projectNoAccessPermissions = buildNoAccessProjectPermission();
/* eslint-disable */
/**
* Extracts and formats permissions from a CASL Ability object or a raw permission set.
* @param ability
@@ -287,3 +301,5 @@ export const isAtLeastAsPrivilegedWorkspace = (
return set1.size >= set2.size;
};
/* eslint-enable */
@@ -239,9 +239,9 @@ export const samlConfigServiceFactory = ({
"64f23239a5d4ed17f1e544c4": "9256337f-e3da-43d7-8266-39c9276e8426",
"65348e49db355e6e4782571f": "b8a227c7-843e-410e-8982-b4976a599b69",
"657a219fc8a80c2eff97eb38": "fcab1573-ae7f-4fcf-9645-646207acf035"
};
};
const id = UUIDToMongoId[dto.id] ?? dto.id
const id = UUIDToMongoId[dto.id] ?? dto.id;
ssoConfig = await samlConfigDAL.findById(id);
}
@@ -252,7 +252,7 @@ export const samlConfigServiceFactory = ({
const { permission } = await permissionService.getOrgPermission(
dto.actor,
dto.actorId,
ssoConfig!.orgId
ssoConfig.orgId
);
ForbiddenError.from(permission).throwUnlessCan(
OrgPermissionActions.Read,
@@ -400,7 +400,7 @@ export const samlConfigServiceFactory = ({
isUserCompleted,
...(relayState
? {
callbackPort: JSON.parse(relayState).callbackPort as string
callbackPort: (JSON.parse(relayState) as { callbackPort: string }).callbackPort
}
: {})
},
@@ -18,6 +18,7 @@ export const secretApprovalPolicyDALFactory = (db: TDbClient) => {
const sapFindQuery = (tx: Knex, filter: TFindFilter<TSecretApprovalPolicies>) =>
tx(TableName.SecretApprovalPolicy)
// eslint-disable-next-line
.where(buildFindFilter(filter))
.join(
TableName.Environment,
@@ -1,7 +1,12 @@
import { Knex } from "knex";
import { TDbClient } from "@app/db";
import { SecretApprovalRequestsSchema, TableName, TSecretApprovalRequests } from "@app/db/schemas";
import {
SecretApprovalRequestsSchema,
TableName,
TSecretApprovalRequests,
TSecretApprovalRequestsSecrets
} from "@app/db/schemas";
import { DatabaseError } from "@app/lib/errors";
import {
ormify,
@@ -125,10 +130,11 @@ export const secretApprovalRequestDALFactory = (db: TDbClient) => {
`${TableName.SecretApprovalPolicyApprover}.policyId`
)
.where({ projectId })
.andWhere((bd) =>
bd
.where(`${TableName.SecretApprovalPolicyApprover}.approverId`, membershipId)
.orWhere(`${TableName.SecretApprovalRequest}.committerId`, membershipId)
.andWhere(
(bd) =>
void bd
.where(`${TableName.SecretApprovalPolicyApprover}.approverId`, membershipId)
.orWhere(`${TableName.SecretApprovalRequest}.committerId`, membershipId)
)
.select("status", `${TableName.SecretApprovalRequest}.id`)
.groupBy(`${TableName.SecretApprovalRequest}.id`, "status")
@@ -141,11 +147,13 @@ export const secretApprovalRequestDALFactory = (db: TDbClient) => {
return {
open: parseInt(
(docs.find(({ status }) => status === RequestState.Open)?.count as string) || "0",
(docs.find(({ status }) => status === RequestState.Open) as { count: string })?.count ||
"0",
10
),
closed: parseInt(
(docs.find(({ status }) => status === RequestState.Closed)?.count as string) || "0",
(docs.find(({ status }) => status === RequestState.Closed) as { count: string })?.count ||
"0",
10
)
};
@@ -195,7 +203,7 @@ export const secretApprovalRequestDALFactory = (db: TDbClient) => {
`${TableName.SecretApprovalRequest}.id`,
`${TableName.SecretApprovalRequestReviewer}.requestId`
)
.leftJoin(
.leftJoin<TSecretApprovalRequestsSecrets>(
TableName.SecretApprovalRequestSecret,
`${TableName.SecretApprovalRequestSecret}.requestId`,
`${TableName.SecretApprovalRequest}.id`
@@ -208,10 +216,11 @@ export const secretApprovalRequestDALFactory = (db: TDbClient) => {
committerId: committer
})
)
.andWhere((bd) =>
bd
.where(`${TableName.SecretApprovalPolicyApprover}.approverId`, membershipId)
.orWhere(`${TableName.SecretApprovalRequest}.committerId`, membershipId)
.andWhere(
(bd) =>
void bd
.where(`${TableName.SecretApprovalPolicyApprover}.approverId`, membershipId)
.orWhere(`${TableName.SecretApprovalRequest}.committerId`, membershipId)
)
.select(selectAllTableCols(TableName.SecretApprovalRequest))
.select(
@@ -1,7 +1,7 @@
import { Knex } from "knex";
import { TDbClient } from "@app/db";
import { SecretApprovalRequestsSecretsSchema, TableName } from "@app/db/schemas";
import { SecretApprovalRequestsSecretsSchema, TableName, TSecretTags } from "@app/db/schemas";
import { DatabaseError } from "@app/lib/errors";
import { ormify, selectAllTableCols, sqlNestRelationships } from "@app/lib/knex";
@@ -45,7 +45,7 @@ export const secretApprovalRequestSecretDALFactory = (db: TDbClient) => {
`${TableName.SecretVersionTag}.${TableName.SecretVersion}Id`,
`${TableName.SecretVersion}.id`
)
.leftJoin(
.leftJoin<TSecretTags>(
db.ref(TableName.SecretTag).as("secVerTag"),
`${TableName.SecretVersionTag}.${TableName.SecretTag}Id`,
db.ref("id").withSchema("secVerTag")
@@ -192,9 +192,13 @@ export const secretApprovalRequestSecretDALFactory = (db: TDbClient) => {
secVerTagSlug: slug,
secVerTagColor: color
}) => ({
// eslint-disable-next-line
id,
// eslint-disable-next-line
name,
// eslint-disable-next-line
slug,
// eslint-disable-next-line
color
})
}
@@ -1,3 +1,8 @@
/* eslint-disable @typescript-eslint/no-unsafe-argument */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-return */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable no-param-reassign */
import axios from "axios";
import jmespath from "jmespath";
@@ -37,7 +42,7 @@ export const interpolate = (data: any, getValue: (key: string) => unknown) => {
if ((data as { ref: string })?.ref) return getValue((data as { ref: string }).ref);
const temp = data as Record<string, unknown>; // for converting ts object to record type
Object.keys(temp).forEach((key) => {
temp[key as keyof typeof temp] = interpolate(data[key as keyof typeof temp], getValue);
temp[key] = interpolate(data[key], getValue);
});
}
return data;
@@ -6,6 +6,7 @@ import {
infisicalSymmetricEncypt
} from "@app/lib/crypto/encryption";
import { daysToMillisecond, secondsToMillis } from "@app/lib/dates";
import { BadRequestError } from "@app/lib/errors";
import { logger } from "@app/lib/logger";
import { alphaNumericNanoId } from "@app/lib/nanoid";
import { QueueJobs, QueueName, TQueueServiceFactory } from "@app/queue";
@@ -34,7 +35,6 @@ import {
TSecretRotationDbFn,
TSecretRotationEncData
} from "./secret-rotation-queue-types";
import { BadRequestError } from "@app/lib/errors";
export type TSecretRotationQueueFactory = ReturnType<typeof secretRotationQueueFactory>;
@@ -70,7 +70,7 @@ export const secretRotationQueueFactory = ({
}: TSecretRotationQueueFactoryDep) => {
const addToQueue = async (rotationId: string, interval: number) => {
const appCfg = getConfig();
queue.queue(
await queue.queue(
QueueName.SecretRotation,
QueueJobs.SecretRotation,
{ rotationId },
@@ -265,7 +265,7 @@ export const secretRotationQueueFactory = ({
return {
...el,
secretId: id,
secretBlindIndex: el.secretBlindIndex as string
secretBlindIndex: el.secretBlindIndex
};
}),
tx
@@ -288,7 +288,7 @@ export const secretRotationQueueFactory = ({
logger.error(error);
if (error instanceof DisableRotationErrors) {
if (job.id) {
queue.stopRepeatableJobByJobId(QueueName.SecretRotation, job.id);
await queue.stopRepeatableJobByJobId(QueueName.SecretRotation, job.id);
}
}
@@ -1,7 +1,7 @@
import { Knex } from "knex";
import { TDbClient } from "@app/db";
import { TableName,TGitAppOrgInsert } from "@app/db/schemas";
import { TableName, TGitAppOrgInsert } from "@app/db/schemas";
import { DatabaseError } from "@app/lib/errors";
import { ormify } from "@app/lib/knex";
@@ -1,7 +1,7 @@
import { Knex } from "knex";
import { TDbClient } from "@app/db";
import { TableName,TGitAppInstallSessionsInsert } from "@app/db/schemas";
import { TableName, TGitAppInstallSessionsInsert } from "@app/db/schemas";
import { DatabaseError } from "@app/lib/errors";
import { ormify } from "@app/lib/knex";
@@ -1,7 +1,7 @@
import { Knex } from "knex";
import { TDbClient } from "@app/db";
import { TableName,TSecretScanningGitRisksInsert } from "@app/db/schemas";
import { TableName, TSecretScanningGitRisksInsert } from "@app/db/schemas";
import { DatabaseError } from "@app/lib/errors";
import { ormify } from "@app/lib/knex";
@@ -1,3 +1,4 @@
import { Octokit } from "@octokit/rest";
import { exec } from "child_process";
import { mkdir, readFile, rm, writeFile } from "fs";
import { tmpdir } from "os";
@@ -11,7 +12,7 @@ export function createTempFolder(): Promise<string> {
const tempFolderName = Math.random().toString(36).substring(2);
const tempFolderPath = join(tempDir, tempFolderName);
mkdir(tempFolderPath, (err: any) => {
mkdir(tempFolderPath, (err) => {
if (err) {
reject(err);
} else {
@@ -115,7 +116,7 @@ export function convertKeysToLowercase<T>(obj: T): T {
}
export async function scanFullRepoContentAndGetFindings(
octokit: any,
octokit: Octokit,
installationId: string,
repositoryFullName: string
): Promise<SecretMatch[]> {
@@ -125,11 +126,13 @@ export async function scanFullRepoContentAndGetFindings(
try {
const {
data: { token }
} = await octokit.apps.createInstallationAccessToken({ installation_id: installationId });
} = await octokit.apps.createInstallationAccessToken({
installation_id: Number(installationId)
});
await cloneRepo(token, repositoryFullName, repoPath);
await runInfisicalScanOnRepo(repoPath, findingsPath);
const findingsData = await readFindingsFile(findingsPath);
return JSON.parse(findingsData);
return JSON.parse(findingsData) as SecretMatch[];
} finally {
await deleteTempFolder(tempFolder);
}
@@ -144,7 +147,7 @@ export async function scanContentAndGetFindings(textContent: string): Promise<Se
await writeTextToFile(filePath, textContent);
await runInfisicalScan(filePath, findingsPath);
const findingsData = await readFindingsFile(findingsPath);
return JSON.parse(findingsData);
return JSON.parse(findingsData) as SecretMatch[];
} finally {
await deleteTempFolder(tempFolder);
}
@@ -96,8 +96,8 @@ export const secretScanningQueueFactory = ({
path: filepath
});
const { data }: any = fileContentsResponse;
const fileContent = Buffer.from(data.content, "base64").toString();
const { data } = fileContentsResponse;
const fileContent = Buffer.from((data as { content: string }).content, "base64").toString();
// eslint-disable-next-line
const findings = await scanContentAndGetFindings(`\n${fileContent}`); // extra line to count lines correctly
@@ -118,7 +118,7 @@ export const secretScanningQueueFactory = ({
}
await secretScanningDAL.transaction(async (tx) => {
if (!Object.keys(allFindingsByFingerprint).length) return;
secretScanningDAL.upsert(
await secretScanningDAL.upsert(
Object.keys(allFindingsByFingerprint).map((key) => ({
installationId,
email: allFindingsByFingerprint[key].Email,
@@ -186,7 +186,9 @@ export const secretScanningQueueFactory = ({
});
const findings = await scanFullRepoContentAndGetFindings(
octokit,
// this is because of collision of octokit in probot and github
// eslint-disable-next-line
octokit as any,
installationId,
repository.fullName
);
@@ -170,9 +170,7 @@ export const secretScanningServiceFactory = ({
await secretScanningDAL.transaction(async (tx) => {
if (repositoryIds.length) {
await Promise.all(
repositoryIds.map((repoId) =>
secretScanningDAL.delete({ repositoryId: repoId }, tx)
)
repositoryIds.map((repoId) => secretScanningDAL.delete({ repositoryId: repoId }, tx))
);
}
await gitAppOrgDAL.delete({ installationId }, tx);
@@ -162,7 +162,8 @@ export const snapshotDALFactory = (db: TDbClient) => {
try {
const data = await (tx || db)
.withRecursive("parent", (qb) => {
qb.from(TableName.Snapshot)
void qb
.from(TableName.Snapshot)
.leftJoin<TSecretSnapshotFolders>(
TableName.SnapshotFolder,
`${TableName.SnapshotFolder}.snapshotId`,
@@ -180,35 +181,36 @@ export const snapshotDALFactory = (db: TDbClient) => {
db.ref("folderId").withSchema(TableName.SecretFolderVersion).as("folderVerId")
)
.where(`${TableName.Snapshot}.id`, snapshotId)
.union((cb) =>
cb
.select(selectAllTableCols(TableName.Snapshot))
.select({ depth: db.raw("parent.depth + 1") })
.select(
db.ref("name").withSchema(TableName.SecretFolderVersion).as("folderVerName"),
db.ref("folderId").withSchema(TableName.SecretFolderVersion).as("folderVerId")
)
.from(TableName.Snapshot)
.join<TSecretSnapshots, TSecretSnapshots & { secretId: string; max: number }>(
db(TableName.Snapshot)
.groupBy("folderId")
.max("createdAt")
.select("folderId")
.as("latestVersion"),
`${TableName.Snapshot}.createdAt`,
"latestVersion.max"
)
.leftJoin<TSecretSnapshotFolders>(
TableName.SnapshotFolder,
`${TableName.SnapshotFolder}.snapshotId`,
`${TableName.Snapshot}.id`
)
.leftJoin<TSecretFolderVersions>(
TableName.SecretFolderVersion,
`${TableName.SnapshotFolder}.folderVersionId`,
`${TableName.SecretFolderVersion}.id`
)
.join("parent", "parent.folderVerId", `${TableName.Snapshot}.folderId`)
.union(
(cb) =>
void cb
.select(selectAllTableCols(TableName.Snapshot))
.select({ depth: db.raw("parent.depth + 1") })
.select(
db.ref("name").withSchema(TableName.SecretFolderVersion).as("folderVerName"),
db.ref("folderId").withSchema(TableName.SecretFolderVersion).as("folderVerId")
)
.from(TableName.Snapshot)
.join<TSecretSnapshots, TSecretSnapshots & { secretId: string; max: number }>(
db(TableName.Snapshot)
.groupBy("folderId")
.max("createdAt")
.select("folderId")
.as("latestVersion"),
`${TableName.Snapshot}.createdAt`,
"latestVersion.max"
)
.leftJoin<TSecretSnapshotFolders>(
TableName.SnapshotFolder,
`${TableName.SnapshotFolder}.snapshotId`,
`${TableName.Snapshot}.id`
)
.leftJoin<TSecretFolderVersions>(
TableName.SecretFolderVersion,
`${TableName.SnapshotFolder}.folderVersionId`,
`${TableName.SecretFolderVersion}.id`
)
.join("parent", "parent.folderVerId", `${TableName.Snapshot}.folderId`)
);
})
.orderBy("depth", "asc")
@@ -285,7 +287,7 @@ export const snapshotDALFactory = (db: TDbClient) => {
label: "secretVersions" as const,
mapper: (el) => ({
...SecretVersionsSchema.parse(el),
latestSecretVersion: el.latestSecretVersion
latestSecretVersion: el.latestSecretVersion as number
}),
childrenMapper: [
{
@@ -307,7 +309,7 @@ export const snapshotDALFactory = (db: TDbClient) => {
mapper: ({ folderVerId: id, folderVerName: name, latestFolderVersion }) => ({
id,
name,
latestFolderVersion
latestFolderVersion: latestFolderVersion as number
})
}
]