mirror of
https://github.com/nicotsx/ironmount.git
synced 2025-12-10 12:10:51 +01:00
refactor: unify backend and frontend servers (#3)
* refactor: unify backend and frontend servers * refactor: correct paths for openapi & drizzle * refactor: move api-client to client * fix: drizzle paths * chore: fix linting issues * fix: form reset issue
This commit is contained in:
373
app/server/modules/volumes/volume.dto.ts
Normal file
373
app/server/modules/volumes/volume.dto.ts
Normal file
@@ -0,0 +1,373 @@
|
||||
import { type } from "arktype";
|
||||
import { describeRoute, resolver } from "hono-openapi";
|
||||
import { BACKEND_STATUS, BACKEND_TYPES, volumeConfigSchema } from "~/schemas/volumes";
|
||||
|
||||
export const volumeSchema = type({
|
||||
id: "number",
|
||||
name: "string",
|
||||
type: type.valueOf(BACKEND_TYPES),
|
||||
status: type.valueOf(BACKEND_STATUS),
|
||||
lastError: "string | null",
|
||||
createdAt: "number",
|
||||
updatedAt: "number",
|
||||
lastHealthCheck: "number",
|
||||
config: volumeConfigSchema,
|
||||
autoRemount: "boolean",
|
||||
});
|
||||
|
||||
export type VolumeDto = typeof volumeSchema.infer;
|
||||
|
||||
/**
|
||||
* List all volumes
|
||||
*/
|
||||
export const listVolumesResponse = volumeSchema.array();
|
||||
export type ListVolumesDto = typeof listVolumesResponse.infer;
|
||||
|
||||
export const listVolumesDto = describeRoute({
|
||||
description: "List all volumes",
|
||||
tags: ["Volumes"],
|
||||
operationId: "listVolumes",
|
||||
responses: {
|
||||
200: {
|
||||
description: "A list of volumes",
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: resolver(listVolumesResponse),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Create a new volume
|
||||
*/
|
||||
export const createVolumeBody = type({
|
||||
name: "string",
|
||||
config: volumeConfigSchema,
|
||||
});
|
||||
|
||||
export const createVolumeResponse = volumeSchema;
|
||||
export type CreateVolumeDto = typeof createVolumeResponse.infer;
|
||||
|
||||
export const createVolumeDto = describeRoute({
|
||||
description: "Create a new volume",
|
||||
operationId: "createVolume",
|
||||
tags: ["Volumes"],
|
||||
responses: {
|
||||
201: {
|
||||
description: "Volume created successfully",
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: resolver(createVolumeResponse),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Delete a volume
|
||||
*/
|
||||
export const deleteVolumeResponse = type({
|
||||
message: "string",
|
||||
});
|
||||
export type DeleteVolumeDto = typeof deleteVolumeResponse.infer;
|
||||
|
||||
export const deleteVolumeDto = describeRoute({
|
||||
description: "Delete a volume",
|
||||
operationId: "deleteVolume",
|
||||
tags: ["Volumes"],
|
||||
responses: {
|
||||
200: {
|
||||
description: "Volume deleted successfully",
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: resolver(deleteVolumeResponse),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const statfsSchema = type({
|
||||
total: "number",
|
||||
used: "number",
|
||||
free: "number",
|
||||
});
|
||||
|
||||
const getVolumeResponse = type({
|
||||
volume: volumeSchema,
|
||||
statfs: statfsSchema,
|
||||
});
|
||||
|
||||
export type GetVolumeDto = typeof getVolumeResponse.infer;
|
||||
/**
|
||||
* Get a volume
|
||||
*/
|
||||
export const getVolumeDto = describeRoute({
|
||||
description: "Get a volume by name",
|
||||
operationId: "getVolume",
|
||||
tags: ["Volumes"],
|
||||
responses: {
|
||||
200: {
|
||||
description: "Volume details",
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: resolver(getVolumeResponse),
|
||||
},
|
||||
},
|
||||
},
|
||||
404: {
|
||||
description: "Volume not found",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Update a volume
|
||||
*/
|
||||
export const updateVolumeBody = type({
|
||||
autoRemount: "boolean?",
|
||||
config: volumeConfigSchema.optional(),
|
||||
});
|
||||
|
||||
export type UpdateVolumeBody = typeof updateVolumeBody.infer;
|
||||
|
||||
export const updateVolumeResponse = volumeSchema;
|
||||
export type UpdateVolumeDto = typeof updateVolumeResponse.infer;
|
||||
|
||||
export const updateVolumeDto = describeRoute({
|
||||
description: "Update a volume's configuration",
|
||||
operationId: "updateVolume",
|
||||
tags: ["Volumes"],
|
||||
responses: {
|
||||
200: {
|
||||
description: "Volume updated successfully",
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: resolver(updateVolumeResponse),
|
||||
},
|
||||
},
|
||||
},
|
||||
404: {
|
||||
description: "Volume not found",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Test connection
|
||||
*/
|
||||
export const testConnectionBody = type({
|
||||
config: volumeConfigSchema,
|
||||
});
|
||||
|
||||
export const testConnectionResponse = type({
|
||||
success: "boolean",
|
||||
message: "string",
|
||||
});
|
||||
export type TestConnectionDto = typeof testConnectionResponse.infer;
|
||||
|
||||
export const testConnectionDto = describeRoute({
|
||||
description: "Test connection to backend",
|
||||
operationId: "testConnection",
|
||||
tags: ["Volumes"],
|
||||
responses: {
|
||||
200: {
|
||||
description: "Connection test result",
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: resolver(testConnectionResponse),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Mount volume
|
||||
*/
|
||||
export const mountVolumeResponse = type({
|
||||
error: "string?",
|
||||
status: type.valueOf(BACKEND_STATUS),
|
||||
});
|
||||
export type MountVolumeDto = typeof mountVolumeResponse.infer;
|
||||
|
||||
export const mountVolumeDto = describeRoute({
|
||||
description: "Mount a volume",
|
||||
operationId: "mountVolume",
|
||||
tags: ["Volumes"],
|
||||
responses: {
|
||||
200: {
|
||||
description: "Volume mounted successfully",
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: resolver(mountVolumeResponse),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Unmount volume
|
||||
*/
|
||||
export const unmountVolumeResponse = type({
|
||||
error: "string?",
|
||||
status: type.valueOf(BACKEND_STATUS),
|
||||
});
|
||||
export type UnmountVolumeDto = typeof unmountVolumeResponse.infer;
|
||||
|
||||
export const unmountVolumeDto = describeRoute({
|
||||
description: "Unmount a volume",
|
||||
operationId: "unmountVolume",
|
||||
tags: ["Volumes"],
|
||||
responses: {
|
||||
200: {
|
||||
description: "Volume unmounted successfully",
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: resolver(unmountVolumeResponse),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const healthCheckResponse = type({
|
||||
error: "string?",
|
||||
status: type.valueOf(BACKEND_STATUS),
|
||||
});
|
||||
export type HealthCheckDto = typeof healthCheckResponse.infer;
|
||||
|
||||
export const healthCheckDto = describeRoute({
|
||||
description: "Perform a health check on a volume",
|
||||
operationId: "healthCheckVolume",
|
||||
tags: ["Volumes"],
|
||||
responses: {
|
||||
200: {
|
||||
description: "Volume health check result",
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: resolver(healthCheckResponse),
|
||||
},
|
||||
},
|
||||
},
|
||||
404: {
|
||||
description: "Volume not found",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Get containers using a volume
|
||||
*/
|
||||
const containerSchema = type({
|
||||
id: "string",
|
||||
name: "string",
|
||||
state: "string",
|
||||
image: "string",
|
||||
});
|
||||
|
||||
export const listContainersResponse = containerSchema.array();
|
||||
export type ListContainersDto = typeof listContainersResponse.infer;
|
||||
|
||||
export const getContainersDto = describeRoute({
|
||||
description: "Get containers using a volume by name",
|
||||
operationId: "getContainersUsingVolume",
|
||||
tags: ["Volumes"],
|
||||
responses: {
|
||||
200: {
|
||||
description: "List of containers using the volume",
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: resolver(listContainersResponse),
|
||||
},
|
||||
},
|
||||
},
|
||||
404: {
|
||||
description: "Volume not found",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* List files in a volume
|
||||
*/
|
||||
const fileEntrySchema = type({
|
||||
name: "string",
|
||||
path: "string",
|
||||
type: type.enumerated("file", "directory"),
|
||||
size: "number?",
|
||||
modifiedAt: "number?",
|
||||
});
|
||||
|
||||
export const listFilesResponse = type({
|
||||
files: fileEntrySchema.array(),
|
||||
path: "string",
|
||||
});
|
||||
export type ListFilesDto = typeof listFilesResponse.infer;
|
||||
|
||||
export const listFilesDto = describeRoute({
|
||||
description: "List files in a volume directory",
|
||||
operationId: "listFiles",
|
||||
tags: ["Volumes"],
|
||||
parameters: [
|
||||
{
|
||||
in: "query",
|
||||
name: "path",
|
||||
required: false,
|
||||
schema: {
|
||||
type: "string",
|
||||
},
|
||||
description: "Subdirectory path to list (relative to volume root)",
|
||||
},
|
||||
],
|
||||
responses: {
|
||||
200: {
|
||||
description: "List of files in the volume",
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: resolver(listFilesResponse),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Browse filesystem directories
|
||||
*/
|
||||
export const browseFilesystemResponse = type({
|
||||
directories: fileEntrySchema.array(),
|
||||
path: "string",
|
||||
});
|
||||
export type BrowseFilesystemDto = typeof browseFilesystemResponse.infer;
|
||||
|
||||
export const browseFilesystemDto = describeRoute({
|
||||
description: "Browse directories on the host filesystem",
|
||||
operationId: "browseFilesystem",
|
||||
tags: ["Volumes"],
|
||||
parameters: [
|
||||
{
|
||||
in: "query",
|
||||
name: "path",
|
||||
required: false,
|
||||
schema: {
|
||||
type: "string",
|
||||
},
|
||||
description: "Directory path to browse (absolute path, defaults to /)",
|
||||
},
|
||||
],
|
||||
responses: {
|
||||
200: {
|
||||
description: "List of directories in the specified path",
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: resolver(browseFilesystemResponse),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user