refactor: string params
This commit is contained in:
parent
e9a2b42d6d
commit
f37ae0484b
7 changed files with 24 additions and 93 deletions
|
|
@ -497,7 +497,7 @@ export const listFilesInfiniteOptions = (options: Options<ListFilesData>) =>
|
||||||
DefaultError,
|
DefaultError,
|
||||||
InfiniteData<ListFilesResponse>,
|
InfiniteData<ListFilesResponse>,
|
||||||
QueryKey<Options<ListFilesData>>,
|
QueryKey<Options<ListFilesData>>,
|
||||||
number | Pick<QueryKey<Options<ListFilesData>>[0], "body" | "headers" | "path" | "query">
|
string | Pick<QueryKey<Options<ListFilesData>>[0], "body" | "headers" | "path" | "query">
|
||||||
>(
|
>(
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
{
|
{
|
||||||
|
|
@ -814,7 +814,7 @@ export const listSnapshotFilesInfiniteOptions = (options: Options<ListSnapshotFi
|
||||||
DefaultError,
|
DefaultError,
|
||||||
InfiniteData<ListSnapshotFilesResponse>,
|
InfiniteData<ListSnapshotFilesResponse>,
|
||||||
QueryKey<Options<ListSnapshotFilesData>>,
|
QueryKey<Options<ListSnapshotFilesData>>,
|
||||||
number | Pick<QueryKey<Options<ListSnapshotFilesData>>[0], "body" | "headers" | "path" | "query">
|
string | Pick<QueryKey<Options<ListSnapshotFilesData>>[0], "body" | "headers" | "path" | "query">
|
||||||
>(
|
>(
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -682,18 +682,9 @@ export type ListFilesData = {
|
||||||
id: string;
|
id: string;
|
||||||
};
|
};
|
||||||
query?: {
|
query?: {
|
||||||
/**
|
limit?: string;
|
||||||
* Subdirectory path to list (relative to volume root)
|
offset?: string;
|
||||||
*/
|
|
||||||
path?: string;
|
path?: string;
|
||||||
/**
|
|
||||||
* Offset for pagination (default: 0)
|
|
||||||
*/
|
|
||||||
offset?: number;
|
|
||||||
/**
|
|
||||||
* Maximum number of files to return (default: 100, max: 1000)
|
|
||||||
*/
|
|
||||||
limit?: number;
|
|
||||||
};
|
};
|
||||||
url: "/api/v1/volumes/{id}/files";
|
url: "/api/v1/volumes/{id}/files";
|
||||||
};
|
};
|
||||||
|
|
@ -1736,15 +1727,9 @@ export type ListSnapshotFilesData = {
|
||||||
snapshotId: string;
|
snapshotId: string;
|
||||||
};
|
};
|
||||||
query?: {
|
query?: {
|
||||||
|
limit?: string;
|
||||||
|
offset?: string;
|
||||||
path?: string;
|
path?: string;
|
||||||
/**
|
|
||||||
* Offset for pagination (default: 0)
|
|
||||||
*/
|
|
||||||
offset?: number;
|
|
||||||
/**
|
|
||||||
* Maximum number of files to return (default: 500, max: 1000)
|
|
||||||
*/
|
|
||||||
limit?: number;
|
|
||||||
};
|
};
|
||||||
url: "/api/v1/repositories/{id}/snapshots/{snapshotId}/files";
|
url: "/api/v1/repositories/{id}/snapshots/{snapshotId}/files";
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -143,11 +143,10 @@ export const repositoriesController = new Hono()
|
||||||
validator("query", listSnapshotFilesQuery),
|
validator("query", listSnapshotFilesQuery),
|
||||||
async (c) => {
|
async (c) => {
|
||||||
const { id, snapshotId } = c.req.param();
|
const { id, snapshotId } = c.req.param();
|
||||||
const { path } = c.req.valid("query");
|
const { path, ...query } = c.req.valid("query");
|
||||||
|
|
||||||
const decodedPath = path ? decodeURIComponent(path) : undefined;
|
const decodedPath = path ? decodeURIComponent(path) : undefined;
|
||||||
|
|
||||||
const query = c.req.query();
|
|
||||||
const offset = Math.max(0, Number.parseInt(query.offset ?? "0", 10) || 0);
|
const offset = Math.max(0, Number.parseInt(query.offset ?? "0", 10) || 0);
|
||||||
const limit = Math.min(1000, Math.max(1, Number.parseInt(query.limit ?? "500", 10) || 500));
|
const limit = Math.min(1000, Math.max(1, Number.parseInt(query.limit ?? "500", 10) || 500));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -262,43 +262,14 @@ export type ListSnapshotFilesDto = typeof listSnapshotFilesResponse.infer;
|
||||||
|
|
||||||
export const listSnapshotFilesQuery = type({
|
export const listSnapshotFilesQuery = type({
|
||||||
path: "string?",
|
path: "string?",
|
||||||
|
offset: "string.integer?",
|
||||||
|
limit: "string.integer?",
|
||||||
});
|
});
|
||||||
|
|
||||||
export const listSnapshotFilesDto = describeRoute({
|
export const listSnapshotFilesDto = describeRoute({
|
||||||
description: "List files and directories in a snapshot",
|
description: "List files and directories in a snapshot",
|
||||||
tags: ["Repositories"],
|
tags: ["Repositories"],
|
||||||
operationId: "listSnapshotFiles",
|
operationId: "listSnapshotFiles",
|
||||||
parameters: [
|
|
||||||
{
|
|
||||||
in: "query",
|
|
||||||
name: "path",
|
|
||||||
required: false,
|
|
||||||
schema: {
|
|
||||||
type: "string",
|
|
||||||
},
|
|
||||||
description: "Subdirectory path to list",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
in: "query",
|
|
||||||
name: "offset",
|
|
||||||
required: false,
|
|
||||||
schema: {
|
|
||||||
type: "integer",
|
|
||||||
default: 0,
|
|
||||||
},
|
|
||||||
description: "Offset for pagination (default: 0)",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
in: "query",
|
|
||||||
name: "limit",
|
|
||||||
required: false,
|
|
||||||
schema: {
|
|
||||||
type: "integer",
|
|
||||||
default: 500,
|
|
||||||
},
|
|
||||||
description: "Maximum number of files to return (default: 500, max: 1000)",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
responses: {
|
responses: {
|
||||||
200: {
|
200: {
|
||||||
description: "List of files and directories in the snapshot",
|
description: "List of files and directories in the snapshot",
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import {
|
||||||
type ListFilesDto,
|
type ListFilesDto,
|
||||||
browseFilesystemDto,
|
browseFilesystemDto,
|
||||||
type BrowseFilesystemDto,
|
type BrowseFilesystemDto,
|
||||||
|
listFilesQuery,
|
||||||
} from "./volume.dto";
|
} from "./volume.dto";
|
||||||
import { volumeService } from "./volume.service";
|
import { volumeService } from "./volume.service";
|
||||||
import { getVolumePath } from "./helpers";
|
import { getVolumePath } from "./helpers";
|
||||||
|
|
@ -104,15 +105,14 @@ export const volumeController = new Hono()
|
||||||
|
|
||||||
return c.json({ error, status }, 200);
|
return c.json({ error, status }, 200);
|
||||||
})
|
})
|
||||||
.get("/:id/files", listFilesDto, async (c) => {
|
.get("/:id/files", validator("query", listFilesQuery), listFilesDto, async (c) => {
|
||||||
const { id } = c.req.param();
|
const { id } = c.req.param();
|
||||||
const subPath = c.req.query("path");
|
const { path, ...query } = c.req.valid("query");
|
||||||
const offsetParam = c.req.query("offset");
|
|
||||||
const offset = offsetParam ? parseInt(offsetParam, 10) : 0;
|
|
||||||
const limitParam = c.req.query("limit");
|
|
||||||
const limit = limitParam ? parseInt(limitParam, 10) : undefined;
|
|
||||||
|
|
||||||
const result = await volumeService.listFiles(id, subPath, offset, limit);
|
const offset = Math.max(0, Number.parseInt(query.offset ?? "0", 10) || 0);
|
||||||
|
const limit = Math.min(1000, Math.max(1, Number.parseInt(query.limit ?? "500", 10) || 500));
|
||||||
|
|
||||||
|
const result = await volumeService.listFiles(id, path, offset, limit);
|
||||||
|
|
||||||
const response = {
|
const response = {
|
||||||
files: result.files,
|
files: result.files,
|
||||||
|
|
|
||||||
|
|
@ -283,41 +283,16 @@ export const listFilesResponse = type({
|
||||||
});
|
});
|
||||||
export type ListFilesDto = typeof listFilesResponse.infer;
|
export type ListFilesDto = typeof listFilesResponse.infer;
|
||||||
|
|
||||||
|
export const listFilesQuery = type({
|
||||||
|
path: "string?",
|
||||||
|
offset: "string.integer?",
|
||||||
|
limit: "string.integer?",
|
||||||
|
});
|
||||||
|
|
||||||
export const listFilesDto = describeRoute({
|
export const listFilesDto = describeRoute({
|
||||||
description: "List files in a volume directory",
|
description: "List files in a volume directory",
|
||||||
operationId: "listFiles",
|
operationId: "listFiles",
|
||||||
tags: ["Volumes"],
|
tags: ["Volumes"],
|
||||||
parameters: [
|
|
||||||
{
|
|
||||||
in: "query",
|
|
||||||
name: "path",
|
|
||||||
required: false,
|
|
||||||
schema: {
|
|
||||||
type: "string",
|
|
||||||
},
|
|
||||||
description: "Subdirectory path to list (relative to volume root)",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
in: "query",
|
|
||||||
name: "offset",
|
|
||||||
required: false,
|
|
||||||
schema: {
|
|
||||||
type: "integer",
|
|
||||||
default: 0,
|
|
||||||
},
|
|
||||||
description: "Offset for pagination (default: 0)",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
in: "query",
|
|
||||||
name: "limit",
|
|
||||||
required: false,
|
|
||||||
schema: {
|
|
||||||
type: "integer",
|
|
||||||
default: 100,
|
|
||||||
},
|
|
||||||
description: "Maximum number of files to return (default: 100, max: 1000)",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
responses: {
|
responses: {
|
||||||
200: {
|
200: {
|
||||||
description: "List of files in the volume",
|
description: "List of files in the volume",
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import { serverEvents } from "../../core/events";
|
||||||
import { volumeConfigSchema, type BackendConfig } from "~/schemas/volumes";
|
import { volumeConfigSchema, type BackendConfig } from "~/schemas/volumes";
|
||||||
import { type } from "arktype";
|
import { type } from "arktype";
|
||||||
import { getOrganizationId } from "~/server/core/request-context";
|
import { getOrganizationId } from "~/server/core/request-context";
|
||||||
|
import { isNodeJSErrnoException } from "~/server/utils/fs";
|
||||||
|
|
||||||
async function encryptSensitiveFields(config: BackendConfig): Promise<BackendConfig> {
|
async function encryptSensitiveFields(config: BackendConfig): Promise<BackendConfig> {
|
||||||
switch (config.backend) {
|
switch (config.backend) {
|
||||||
|
|
@ -373,7 +374,7 @@ const listFiles = async (
|
||||||
hasMore: startOffset + entries.length < total,
|
hasMore: startOffset + entries.length < total,
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if ((error as NodeJS.ErrnoException).code === "ENOENT") {
|
if (isNodeJSErrnoException(error) && error.code === "ENOENT") {
|
||||||
throw new NotFoundError("Directory not found");
|
throw new NotFoundError("Directory not found");
|
||||||
}
|
}
|
||||||
throw new InternalServerError(`Failed to list files: ${toMessage(error)}`);
|
throw new InternalServerError(`Failed to list files: ${toMessage(error)}`);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue