Add recursive flag to folders get endpoint to retrieve all nested folders

This commit is contained in:
carlosmonastyrski
2025-03-21 18:08:22 -03:00
parent 3ffee049ee
commit e2e0f6a346
4 changed files with 34 additions and 4 deletions
+2 -1
View File
@@ -631,7 +631,8 @@ export const FOLDERS = {
workspaceId: "The ID of the project to list folders from.", workspaceId: "The ID of the project to list folders from.",
environment: "The slug of the environment to list folders from.", environment: "The slug of the environment to list folders from.",
path: "The path to list folders from.", path: "The path to list folders from.",
directory: "The directory to list folders from. (Deprecated in favor of path)" directory: "The directory to list folders from. (Deprecated in favor of path)",
recursive: "Whether or not to fetch all folders from the specified base path, and all of its subdirectories."
}, },
GET_BY_ID: { GET_BY_ID: {
folderId: "The ID of the folder to get details." folderId: "The ID of the folder to get details."
@@ -9,6 +9,19 @@ import { readLimit, secretsLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type"; import { AuthMode } from "@app/services/auth/auth-type";
const booleanSchema = z
.union([z.boolean(), z.string().trim()])
.transform((value) => {
if (typeof value === "string") {
// ie if not empty, 0 or false, return true
return Boolean(value) && Number(value) !== 0 && value.toLowerCase() !== "false";
}
return value;
})
.optional()
.default(false);
export const registerSecretFolderRouter = async (server: FastifyZodProvider) => { export const registerSecretFolderRouter = async (server: FastifyZodProvider) => {
server.route({ server.route({
url: "/", url: "/",
@@ -347,11 +360,14 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) =>
.default("/") .default("/")
.transform(prefixWithSlash) .transform(prefixWithSlash)
.transform(removeTrailingSlash) .transform(removeTrailingSlash)
.describe(FOLDERS.LIST.directory) .describe(FOLDERS.LIST.directory),
recursive: booleanSchema.describe(FOLDERS.LIST.recursive)
}), }),
response: { response: {
200: z.object({ 200: z.object({
folders: SecretFoldersSchema.array() folders: SecretFoldersSchema.extend({
relativePath: z.string().optional()
}).array()
}) })
} }
}, },
@@ -401,7 +401,8 @@ export const secretFolderServiceFactory = ({
orderBy, orderBy,
orderDirection, orderDirection,
limit, limit,
offset offset,
recursive
}: TGetFolderDTO) => { }: TGetFolderDTO) => {
// folder list is allowed to be read by anyone // folder list is allowed to be read by anyone
// permission to check does user has access // permission to check does user has access
@@ -420,6 +421,17 @@ export const secretFolderServiceFactory = ({
const parentFolder = await folderDAL.findBySecretPath(projectId, environment, secretPath); const parentFolder = await folderDAL.findBySecretPath(projectId, environment, secretPath);
if (!parentFolder) return []; if (!parentFolder) return [];
if (recursive) {
const recursiveFolders = await folderDAL.findByEnvsDeep({ parentIds: [parentFolder.id] });
// remove the parent folder
return recursiveFolders
.filter((folder) => folder.id !== parentFolder.id)
.map((folder) => ({
...folder,
relativePath: folder.path
}));
}
const folders = await folderDAL.find( const folders = await folderDAL.find(
{ {
envId: env.id, envId: env.id,
@@ -45,6 +45,7 @@ export type TGetFolderDTO = {
orderDirection?: OrderByDirection; orderDirection?: OrderByDirection;
limit?: number; limit?: number;
offset?: number; offset?: number;
recursive?: boolean;
} & TProjectPermission; } & TProjectPermission;
export type TGetFolderByIdDTO = { export type TGetFolderByIdDTO = {