chore: import upstream snapshot with attribution
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
Publish CLI Package / publish-npm (push) Has been cancelled
Publish Python SDK / publish-pypi (push) Has been cancelled
Publish TypeScript SDK / publish-npm (push) Has been cancelled
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
Publish CLI Package / publish-npm (push) Has been cancelled
Publish Python SDK / publish-pypi (push) Has been cancelled
Publish TypeScript SDK / publish-npm (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,792 @@
|
||||
import { z } from 'zod'
|
||||
import {
|
||||
batchPresignedUploadResponseSchema,
|
||||
presignedUploadResponseSchema,
|
||||
} from '@/lib/api/contracts/file-uploads'
|
||||
import { workspaceFileIdSchema } from '@/lib/api/contracts/primitives'
|
||||
import {
|
||||
type ContractBodyInput,
|
||||
type ContractJsonResponse,
|
||||
type ContractParamsInput,
|
||||
type ContractQueryInput,
|
||||
defineRouteContract,
|
||||
} from '@/lib/api/contracts/types'
|
||||
import {
|
||||
FileInputSchema,
|
||||
RawFileInputArraySchema,
|
||||
RawFileInputSchema,
|
||||
} from '@/lib/uploads/utils/file-schemas'
|
||||
|
||||
const jsonResponseSchema = z.unknown()
|
||||
|
||||
function formatFileSize(bytes: number): string {
|
||||
if (!Number.isFinite(bytes) || bytes <= 0) return '0 Bytes'
|
||||
const k = 1024
|
||||
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']
|
||||
const i = Math.min(Math.floor(Math.log(bytes) / Math.log(k)), sizes.length - 1)
|
||||
const value = bytes / k ** i
|
||||
return `${value.toFixed(value >= 100 || i === 0 ? 0 : 1)} ${sizes[i]}`
|
||||
}
|
||||
|
||||
const multipartPartUrlSchema = z.object({
|
||||
partNumber: z.number(),
|
||||
url: z.string(),
|
||||
blockId: z.string().optional(),
|
||||
})
|
||||
|
||||
const multipartCompletedUploadSchema = z.object({
|
||||
success: z.literal(true),
|
||||
location: z.string(),
|
||||
path: z.string(),
|
||||
key: z.string(),
|
||||
})
|
||||
|
||||
export const initiateMultipartResponseSchema = z.object({
|
||||
uploadId: z.string(),
|
||||
key: z.string(),
|
||||
uploadToken: z.string(),
|
||||
})
|
||||
|
||||
export const getMultipartPartUrlsResponseSchema = z.object({
|
||||
presignedUrls: z.array(multipartPartUrlSchema),
|
||||
})
|
||||
|
||||
export const completeMultipartResponseSchema = z.union([
|
||||
multipartCompletedUploadSchema,
|
||||
z.object({
|
||||
results: z.array(multipartCompletedUploadSchema),
|
||||
}),
|
||||
])
|
||||
|
||||
export const abortMultipartResponseSchema = z.object({
|
||||
success: z.literal(true),
|
||||
})
|
||||
|
||||
export const multipartUploadResponseSchema = z.union([
|
||||
initiateMultipartResponseSchema,
|
||||
getMultipartPartUrlsResponseSchema,
|
||||
completeMultipartResponseSchema,
|
||||
abortMultipartResponseSchema,
|
||||
])
|
||||
|
||||
const connectionFields = {
|
||||
host: z.string().min(1, 'Host is required'),
|
||||
port: z.coerce.number().int().positive().default(22),
|
||||
username: z.string().min(1, 'Username is required'),
|
||||
password: z.string().nullish(),
|
||||
privateKey: z.string().nullish(),
|
||||
passphrase: z.string().nullish(),
|
||||
}
|
||||
|
||||
export function requirePasswordOrPrivateKey<S extends z.ZodType>(schema: S): S {
|
||||
return schema.refine(
|
||||
(value) => {
|
||||
const connection = value as { password?: string | null; privateKey?: string | null }
|
||||
return Boolean(connection.password || connection.privateKey)
|
||||
},
|
||||
{ message: 'Either password or privateKey must be provided' }
|
||||
) as S
|
||||
}
|
||||
|
||||
export const boxUploadBodySchema = z.object({
|
||||
accessToken: z.string().min(1, 'Access token is required'),
|
||||
parentFolderId: z.string().min(1, 'Parent folder ID is required'),
|
||||
file: FileInputSchema.optional().nullable(),
|
||||
fileContent: z.string().optional().nullable(),
|
||||
fileName: z.string().optional().nullable(),
|
||||
})
|
||||
|
||||
export const dropboxUploadBodySchema = z.object({
|
||||
accessToken: z.string().min(1, 'Access token is required'),
|
||||
path: z.string().min(1, 'Destination path is required'),
|
||||
file: FileInputSchema.optional().nullable(),
|
||||
fileContent: z.string().optional().nullable(),
|
||||
fileName: z.string().optional().nullable(),
|
||||
mode: z.enum(['add', 'overwrite']).optional().nullable(),
|
||||
autorename: z.boolean().optional().nullable(),
|
||||
mute: z.boolean().optional().nullable(),
|
||||
})
|
||||
|
||||
export const jupyterUploadBodySchema = z.object({
|
||||
serverUrl: z.string().min(1, 'Server URL is required'),
|
||||
token: z.string().min(1, 'Token is required'),
|
||||
directory: z.string().optional().nullable(),
|
||||
file: FileInputSchema.optional().nullable(),
|
||||
fileContent: z.string().optional().nullable(),
|
||||
fileName: z.string().optional().nullable(),
|
||||
})
|
||||
|
||||
export const wordpressUploadBodySchema = z.object({
|
||||
accessToken: z.string().min(1, 'Access token is required'),
|
||||
siteId: z.string().min(1, 'Site ID is required'),
|
||||
file: RawFileInputSchema.optional().nullable(),
|
||||
filename: z.string().optional().nullable(),
|
||||
title: z.string().optional().nullable(),
|
||||
caption: z.string().optional().nullable(),
|
||||
altText: z.string().optional().nullable(),
|
||||
description: z.string().optional().nullable(),
|
||||
})
|
||||
|
||||
export const sftpListBodySchema = requirePasswordOrPrivateKey(
|
||||
z.object({
|
||||
...connectionFields,
|
||||
remotePath: z.string().min(1, 'Remote path is required'),
|
||||
detailed: z.boolean().default(false),
|
||||
})
|
||||
)
|
||||
|
||||
export const sftpDeleteBodySchema = requirePasswordOrPrivateKey(
|
||||
z.object({
|
||||
...connectionFields,
|
||||
remotePath: z.string().min(1, 'Remote path is required'),
|
||||
recursive: z.boolean().default(false),
|
||||
})
|
||||
)
|
||||
|
||||
export const sftpMkdirBodySchema = requirePasswordOrPrivateKey(
|
||||
z.object({
|
||||
...connectionFields,
|
||||
remotePath: z.string().min(1, 'Remote path is required'),
|
||||
recursive: z.boolean().default(false),
|
||||
})
|
||||
)
|
||||
|
||||
export const sftpDownloadBodySchema = requirePasswordOrPrivateKey(
|
||||
z.object({
|
||||
...connectionFields,
|
||||
remotePath: z.string().min(1, 'Remote path is required'),
|
||||
encoding: z.enum(['utf-8', 'base64']).default('utf-8'),
|
||||
})
|
||||
)
|
||||
|
||||
export const sftpUploadBodySchema = requirePasswordOrPrivateKey(
|
||||
z.object({
|
||||
...connectionFields,
|
||||
remotePath: z.string().min(1, 'Remote path is required'),
|
||||
files: RawFileInputArraySchema.optional().nullable(),
|
||||
fileContent: z.string().nullish(),
|
||||
fileName: z.string().nullish(),
|
||||
overwrite: z.boolean().default(true),
|
||||
permissions: z.string().nullish(),
|
||||
})
|
||||
)
|
||||
|
||||
export const sshCheckCommandExistsBodySchema = requirePasswordOrPrivateKey(
|
||||
z.object({
|
||||
...connectionFields,
|
||||
commandName: z.string().min(1, 'Command name is required'),
|
||||
})
|
||||
)
|
||||
|
||||
export const sshCheckFileExistsBodySchema = requirePasswordOrPrivateKey(
|
||||
z.object({
|
||||
...connectionFields,
|
||||
path: z.string().min(1, 'Path is required'),
|
||||
type: z.enum(['file', 'directory', 'any']).default('any'),
|
||||
})
|
||||
)
|
||||
|
||||
export const sshCreateDirectoryBodySchema = requirePasswordOrPrivateKey(
|
||||
z.object({
|
||||
...connectionFields,
|
||||
path: z.string().min(1, 'Path is required'),
|
||||
recursive: z.boolean().default(true),
|
||||
permissions: z.string().default('0755'),
|
||||
})
|
||||
)
|
||||
|
||||
export const sshDeleteFileBodySchema = requirePasswordOrPrivateKey(
|
||||
z.object({
|
||||
...connectionFields,
|
||||
path: z.string().min(1, 'Path is required'),
|
||||
recursive: z.boolean().default(false),
|
||||
force: z.boolean().default(false),
|
||||
})
|
||||
)
|
||||
|
||||
export const sshDownloadFileBodySchema = requirePasswordOrPrivateKey(
|
||||
z.object({
|
||||
...connectionFields,
|
||||
remotePath: z.string().min(1, 'Remote path is required'),
|
||||
})
|
||||
)
|
||||
|
||||
export const sshExecuteCommandBodySchema = requirePasswordOrPrivateKey(
|
||||
z.object({
|
||||
...connectionFields,
|
||||
command: z.string().min(1, 'Command is required'),
|
||||
workingDirectory: z.string().nullish(),
|
||||
})
|
||||
)
|
||||
|
||||
export const sshExecuteScriptBodySchema = requirePasswordOrPrivateKey(
|
||||
z.object({
|
||||
...connectionFields,
|
||||
script: z.string().min(1, 'Script content is required'),
|
||||
interpreter: z.string().default('/bin/bash'),
|
||||
workingDirectory: z.string().nullish(),
|
||||
})
|
||||
)
|
||||
|
||||
export const sshGetSystemInfoBodySchema = requirePasswordOrPrivateKey(z.object(connectionFields))
|
||||
|
||||
export const sshListDirectoryBodySchema = requirePasswordOrPrivateKey(
|
||||
z.object({
|
||||
...connectionFields,
|
||||
path: z.string().min(1, 'Path is required'),
|
||||
detailed: z.boolean().default(true),
|
||||
recursive: z.boolean().default(false),
|
||||
})
|
||||
)
|
||||
|
||||
export const sshMoveRenameBodySchema = requirePasswordOrPrivateKey(
|
||||
z.object({
|
||||
...connectionFields,
|
||||
sourcePath: z.string().min(1, 'Source path is required'),
|
||||
destinationPath: z.string().min(1, 'Destination path is required'),
|
||||
overwrite: z.boolean().default(false),
|
||||
})
|
||||
)
|
||||
|
||||
export const sshReadFileContentBodySchema = requirePasswordOrPrivateKey(
|
||||
z.object({
|
||||
...connectionFields,
|
||||
path: z.string().min(1, 'Path is required'),
|
||||
encoding: z.string().default('utf-8'),
|
||||
maxSize: z.coerce.number().min(0.01).max(50).default(10),
|
||||
})
|
||||
)
|
||||
|
||||
export const sshUploadFileBodySchema = requirePasswordOrPrivateKey(
|
||||
z.object({
|
||||
...connectionFields,
|
||||
fileContent: z.string().min(1, 'File content is required'),
|
||||
fileName: z.string().min(1, 'File name is required'),
|
||||
remotePath: z.string().min(1, 'Remote path is required'),
|
||||
permissions: z.string().nullish(),
|
||||
overwrite: z.boolean().default(true),
|
||||
})
|
||||
)
|
||||
|
||||
export const sshWriteFileContentBodySchema = requirePasswordOrPrivateKey(
|
||||
z.object({
|
||||
...connectionFields,
|
||||
path: z.string().min(1, 'Path is required'),
|
||||
content: z.string(),
|
||||
mode: z.enum(['overwrite', 'append', 'create']).default('overwrite'),
|
||||
permissions: z.string().nullish(),
|
||||
})
|
||||
)
|
||||
|
||||
export const storageContextSchema = z.enum([
|
||||
'knowledge-base',
|
||||
'chat',
|
||||
'copilot',
|
||||
'mothership',
|
||||
'execution',
|
||||
'workspace',
|
||||
'profile-pictures',
|
||||
'og-images',
|
||||
'logs',
|
||||
'workspace-logos',
|
||||
])
|
||||
|
||||
export const fileDownloadBodySchema = z
|
||||
.object({
|
||||
key: z.string().optional(),
|
||||
name: z.string().optional(),
|
||||
url: z
|
||||
.string()
|
||||
.url()
|
||||
.refine((value) => ['http:', 'https:'].includes(new URL(value).protocol), {
|
||||
message: 'URL must use http or https',
|
||||
})
|
||||
.optional(),
|
||||
})
|
||||
.passthrough()
|
||||
|
||||
export const fileParseBodySchema = z
|
||||
.object({
|
||||
filePath: z
|
||||
.union([z.string(), z.array(z.string()).max(10, 'At most 10 files can be parsed at once')])
|
||||
.optional(),
|
||||
fileType: z.string().optional().default(''),
|
||||
headers: z.record(z.string(), z.string()).optional(),
|
||||
workspaceId: z.string().optional().default(''),
|
||||
workflowId: z.string().optional(),
|
||||
executionId: z.string().optional(),
|
||||
})
|
||||
.passthrough()
|
||||
|
||||
export const fileDeleteBodySchema = z
|
||||
.object({
|
||||
filePath: z.string().optional(),
|
||||
context: storageContextSchema.optional(),
|
||||
})
|
||||
.passthrough()
|
||||
|
||||
const MAX_FILE_SIZE = 100 * 1024 * 1024
|
||||
export const validUploadTypes = [
|
||||
'knowledge-base',
|
||||
'chat',
|
||||
'copilot',
|
||||
'profile-pictures',
|
||||
'mothership',
|
||||
'workspace-logos',
|
||||
'execution',
|
||||
] as const
|
||||
|
||||
export const uploadTypeSchema = z.enum(validUploadTypes)
|
||||
|
||||
export const presignedUploadQuerySchema = z.object({
|
||||
type: uploadTypeSchema,
|
||||
})
|
||||
|
||||
export const presignedUrlBodySchema = z
|
||||
.object({
|
||||
fileName: z
|
||||
.string({ error: 'fileName is required and cannot be empty' })
|
||||
.refine((value) => value.trim().length > 0, {
|
||||
message: 'fileName is required and cannot be empty',
|
||||
}),
|
||||
contentType: z
|
||||
.string({ error: 'contentType is required and cannot be empty' })
|
||||
.refine((value) => value.trim().length > 0, {
|
||||
message: 'contentType is required and cannot be empty',
|
||||
}),
|
||||
fileSize: z
|
||||
.number({ error: 'fileSize must be a positive number' })
|
||||
.positive('fileSize must be a positive number')
|
||||
.superRefine((val, ctx) => {
|
||||
if (val > MAX_FILE_SIZE) {
|
||||
ctx.addIssue({
|
||||
code: 'custom',
|
||||
message: `File size ${formatFileSize(val)} exceeds maximum allowed size of ${formatFileSize(MAX_FILE_SIZE)}`,
|
||||
})
|
||||
}
|
||||
}),
|
||||
userId: z.string().optional(),
|
||||
chatId: z.string().optional(),
|
||||
})
|
||||
.passthrough()
|
||||
|
||||
export const batchPresignedUrlBodySchema = z
|
||||
.object({
|
||||
files: z
|
||||
.array(
|
||||
z
|
||||
.object({
|
||||
fileName: z.string().refine((value) => value.trim().length > 0, {
|
||||
message: 'fileName is required for all files',
|
||||
}),
|
||||
contentType: z.string().refine((value) => value.trim().length > 0, {
|
||||
message: 'contentType is required for all files',
|
||||
}),
|
||||
fileSize: z.number(),
|
||||
})
|
||||
.passthrough()
|
||||
.superRefine((file, ctx) => {
|
||||
const name = typeof file.fileName === 'string' ? file.fileName : 'file'
|
||||
if (!Number.isFinite(file.fileSize) || file.fileSize <= 0) {
|
||||
ctx.addIssue({
|
||||
code: 'custom',
|
||||
path: ['fileSize'],
|
||||
message: `${name} is empty (fileSize must be greater than 0)`,
|
||||
})
|
||||
} else if (file.fileSize > MAX_FILE_SIZE) {
|
||||
ctx.addIssue({
|
||||
code: 'custom',
|
||||
path: ['fileSize'],
|
||||
message: `${name} (${formatFileSize(file.fileSize)}) exceeds maximum allowed size of ${formatFileSize(MAX_FILE_SIZE)}`,
|
||||
})
|
||||
}
|
||||
})
|
||||
)
|
||||
.min(1, 'files array is required and cannot be empty')
|
||||
.max(100, 'Cannot process more than 100 files at once'),
|
||||
})
|
||||
.passthrough()
|
||||
|
||||
export const multipartActionSchema = z.enum(['initiate', 'get-part-urls', 'complete', 'abort'])
|
||||
|
||||
export const initiateMultipartBodySchema = z
|
||||
.object({
|
||||
fileName: z.string(),
|
||||
contentType: z.string(),
|
||||
fileSize: z.number(),
|
||||
workspaceId: z.string({ error: 'workspaceId is required' }).min(1, 'workspaceId is required'),
|
||||
context: z.string().optional(),
|
||||
})
|
||||
.passthrough()
|
||||
|
||||
export const tokenBoundMultipartBodySchema = z
|
||||
.object({
|
||||
uploadToken: z.string().optional(),
|
||||
})
|
||||
.passthrough()
|
||||
|
||||
export const getMultipartPartUrlsBodySchema = tokenBoundMultipartBodySchema.extend({
|
||||
partNumbers: z.array(z.number()),
|
||||
})
|
||||
|
||||
export const completeMultipartBodySchema = z
|
||||
.object({
|
||||
uploadToken: z.string().optional(),
|
||||
parts: z.unknown().optional(),
|
||||
uploads: z
|
||||
.array(
|
||||
z
|
||||
.object({
|
||||
uploadToken: z.string().optional(),
|
||||
parts: z.unknown().optional(),
|
||||
})
|
||||
.passthrough()
|
||||
)
|
||||
.optional(),
|
||||
})
|
||||
.passthrough()
|
||||
|
||||
export type CompleteMultipartBody = z.output<typeof completeMultipartBodySchema>
|
||||
|
||||
export const uploadFilesFormFilesSchema = z.preprocess(
|
||||
(value) => (Array.isArray(value) ? value.filter((entry) => entry instanceof File) : value),
|
||||
z.array(z.custom<File>((value) => value instanceof File)).min(1, 'No files provided')
|
||||
)
|
||||
|
||||
export const uploadFilesFormFieldsSchema = z.object({
|
||||
workflowId: z.string().nullable(),
|
||||
executionId: z.string().nullable(),
|
||||
workspaceId: z.string().nullable(),
|
||||
context: z.string().nullable(),
|
||||
})
|
||||
|
||||
export const fileServeParamsSchema = z.object({
|
||||
path: z.array(z.string()).min(1),
|
||||
})
|
||||
|
||||
export const fileServeQuerySchema = z.object({
|
||||
raw: z.string().nullish(),
|
||||
/** Content version (the file record's `updatedAt`). Present => the URL is content-immutable and may be cached indefinitely by the browser. */
|
||||
v: z.string().nullish(),
|
||||
})
|
||||
|
||||
export const fileViewParamsSchema = z.object({
|
||||
id: workspaceFileIdSchema,
|
||||
})
|
||||
|
||||
export const fileExportParamsSchema = z.object({
|
||||
id: workspaceFileIdSchema,
|
||||
})
|
||||
|
||||
export const boxUploadContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/tools/box/upload',
|
||||
body: boxUploadBodySchema,
|
||||
response: { mode: 'json', schema: jsonResponseSchema },
|
||||
})
|
||||
|
||||
export const dropboxUploadContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/tools/dropbox/upload',
|
||||
body: dropboxUploadBodySchema,
|
||||
response: { mode: 'json', schema: jsonResponseSchema },
|
||||
})
|
||||
|
||||
export const jupyterUploadContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/tools/jupyter/upload',
|
||||
body: jupyterUploadBodySchema,
|
||||
response: { mode: 'json', schema: jsonResponseSchema },
|
||||
})
|
||||
|
||||
export const wordpressUploadContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/tools/wordpress/upload',
|
||||
body: wordpressUploadBodySchema,
|
||||
response: { mode: 'json', schema: jsonResponseSchema },
|
||||
})
|
||||
|
||||
export const sftpListContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/tools/sftp/list',
|
||||
body: sftpListBodySchema,
|
||||
response: { mode: 'json', schema: jsonResponseSchema },
|
||||
})
|
||||
|
||||
export const sftpDeleteContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/tools/sftp/delete',
|
||||
body: sftpDeleteBodySchema,
|
||||
response: { mode: 'json', schema: jsonResponseSchema },
|
||||
})
|
||||
|
||||
export const sftpMkdirContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/tools/sftp/mkdir',
|
||||
body: sftpMkdirBodySchema,
|
||||
response: { mode: 'json', schema: jsonResponseSchema },
|
||||
})
|
||||
|
||||
export const sftpDownloadContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/tools/sftp/download',
|
||||
body: sftpDownloadBodySchema,
|
||||
response: { mode: 'json', schema: jsonResponseSchema },
|
||||
})
|
||||
|
||||
export const sftpUploadContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/tools/sftp/upload',
|
||||
body: sftpUploadBodySchema,
|
||||
response: { mode: 'json', schema: jsonResponseSchema },
|
||||
})
|
||||
|
||||
export const sshCheckCommandExistsContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/tools/ssh/check-command-exists',
|
||||
body: sshCheckCommandExistsBodySchema,
|
||||
response: { mode: 'json', schema: jsonResponseSchema },
|
||||
})
|
||||
|
||||
export const sshCheckFileExistsContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/tools/ssh/check-file-exists',
|
||||
body: sshCheckFileExistsBodySchema,
|
||||
response: { mode: 'json', schema: jsonResponseSchema },
|
||||
})
|
||||
|
||||
export const sshCreateDirectoryContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/tools/ssh/create-directory',
|
||||
body: sshCreateDirectoryBodySchema,
|
||||
response: { mode: 'json', schema: jsonResponseSchema },
|
||||
})
|
||||
|
||||
export const sshDeleteFileContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/tools/ssh/delete-file',
|
||||
body: sshDeleteFileBodySchema,
|
||||
response: { mode: 'json', schema: jsonResponseSchema },
|
||||
})
|
||||
|
||||
export const sshDownloadFileContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/tools/ssh/download-file',
|
||||
body: sshDownloadFileBodySchema,
|
||||
response: { mode: 'json', schema: jsonResponseSchema },
|
||||
})
|
||||
|
||||
export const sshExecuteCommandContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/tools/ssh/execute-command',
|
||||
body: sshExecuteCommandBodySchema,
|
||||
response: { mode: 'json', schema: jsonResponseSchema },
|
||||
})
|
||||
|
||||
export const sshExecuteScriptContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/tools/ssh/execute-script',
|
||||
body: sshExecuteScriptBodySchema,
|
||||
response: { mode: 'json', schema: jsonResponseSchema },
|
||||
})
|
||||
|
||||
export const sshGetSystemInfoContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/tools/ssh/get-system-info',
|
||||
body: sshGetSystemInfoBodySchema,
|
||||
response: { mode: 'json', schema: jsonResponseSchema },
|
||||
})
|
||||
|
||||
export const sshListDirectoryContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/tools/ssh/list-directory',
|
||||
body: sshListDirectoryBodySchema,
|
||||
response: { mode: 'json', schema: jsonResponseSchema },
|
||||
})
|
||||
|
||||
export const sshMoveRenameContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/tools/ssh/move-rename',
|
||||
body: sshMoveRenameBodySchema,
|
||||
response: { mode: 'json', schema: jsonResponseSchema },
|
||||
})
|
||||
|
||||
export const sshReadFileContentContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/tools/ssh/read-file-content',
|
||||
body: sshReadFileContentBodySchema,
|
||||
response: { mode: 'json', schema: jsonResponseSchema },
|
||||
})
|
||||
|
||||
export const sshUploadFileContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/tools/ssh/upload-file',
|
||||
body: sshUploadFileBodySchema,
|
||||
response: { mode: 'json', schema: jsonResponseSchema },
|
||||
})
|
||||
|
||||
export const sshWriteFileContentContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/tools/ssh/write-file-content',
|
||||
body: sshWriteFileContentBodySchema,
|
||||
response: { mode: 'json', schema: jsonResponseSchema },
|
||||
})
|
||||
|
||||
export const fileDownloadContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/files/download',
|
||||
body: fileDownloadBodySchema,
|
||||
response: { mode: 'json', schema: jsonResponseSchema },
|
||||
})
|
||||
|
||||
export const fileParseContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/files/parse',
|
||||
body: fileParseBodySchema,
|
||||
response: { mode: 'json', schema: jsonResponseSchema },
|
||||
})
|
||||
|
||||
export const fileDeleteContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/files/delete',
|
||||
body: fileDeleteBodySchema,
|
||||
response: { mode: 'json', schema: jsonResponseSchema },
|
||||
})
|
||||
|
||||
export const fileUploadContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/files/upload',
|
||||
response: { mode: 'json', schema: jsonResponseSchema },
|
||||
})
|
||||
|
||||
export const presignedUploadContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/files/presigned',
|
||||
query: presignedUploadQuerySchema,
|
||||
body: presignedUrlBodySchema,
|
||||
response: { mode: 'json', schema: presignedUploadResponseSchema },
|
||||
})
|
||||
|
||||
export const presignedUploadBodyContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/files/presigned',
|
||||
body: presignedUrlBodySchema,
|
||||
response: { mode: 'json', schema: presignedUploadResponseSchema },
|
||||
})
|
||||
|
||||
export const batchPresignedUploadContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/files/presigned/batch',
|
||||
query: presignedUploadQuerySchema,
|
||||
body: batchPresignedUrlBodySchema,
|
||||
response: { mode: 'json', schema: batchPresignedUploadResponseSchema },
|
||||
})
|
||||
|
||||
export const batchPresignedUploadBodyContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/files/presigned/batch',
|
||||
body: batchPresignedUrlBodySchema,
|
||||
response: { mode: 'json', schema: batchPresignedUploadResponseSchema },
|
||||
})
|
||||
|
||||
export const multipartUploadContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/files/multipart',
|
||||
response: { mode: 'json', schema: multipartUploadResponseSchema },
|
||||
})
|
||||
|
||||
export const initiateMultipartUploadContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/files/multipart',
|
||||
body: initiateMultipartBodySchema,
|
||||
response: { mode: 'json', schema: initiateMultipartResponseSchema },
|
||||
})
|
||||
|
||||
export const getMultipartPartUrlsContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/files/multipart',
|
||||
body: getMultipartPartUrlsBodySchema,
|
||||
response: { mode: 'json', schema: getMultipartPartUrlsResponseSchema },
|
||||
})
|
||||
|
||||
export const completeMultipartUploadContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/files/multipart',
|
||||
body: completeMultipartBodySchema,
|
||||
response: { mode: 'json', schema: completeMultipartResponseSchema },
|
||||
})
|
||||
|
||||
export const abortMultipartUploadContract = defineRouteContract({
|
||||
method: 'POST',
|
||||
path: '/api/files/multipart',
|
||||
body: tokenBoundMultipartBodySchema,
|
||||
response: { mode: 'json', schema: abortMultipartResponseSchema },
|
||||
})
|
||||
|
||||
export const fileServeContract = defineRouteContract({
|
||||
method: 'GET',
|
||||
path: '/api/files/serve/[...path]',
|
||||
params: fileServeParamsSchema,
|
||||
query: fileServeQuerySchema,
|
||||
response: { mode: 'binary' },
|
||||
})
|
||||
|
||||
export const fileViewContract = defineRouteContract({
|
||||
method: 'GET',
|
||||
path: '/api/files/view/[id]',
|
||||
params: fileViewParamsSchema,
|
||||
response: { mode: 'binary' },
|
||||
})
|
||||
|
||||
export const fileExportContract = defineRouteContract({
|
||||
method: 'GET',
|
||||
path: '/api/files/export/[id]',
|
||||
params: fileExportParamsSchema,
|
||||
response: { mode: 'binary' },
|
||||
})
|
||||
|
||||
export type BoxUploadBody = ContractBodyInput<typeof boxUploadContract>
|
||||
export type BoxUploadResponse = ContractJsonResponse<typeof boxUploadContract>
|
||||
export type DropboxUploadBody = ContractBodyInput<typeof dropboxUploadContract>
|
||||
export type DropboxUploadResponse = ContractJsonResponse<typeof dropboxUploadContract>
|
||||
export type JupyterUploadBody = ContractBodyInput<typeof jupyterUploadContract>
|
||||
export type JupyterUploadResponse = ContractJsonResponse<typeof jupyterUploadContract>
|
||||
export type WordPressUploadBody = ContractBodyInput<typeof wordpressUploadContract>
|
||||
export type WordPressUploadResponse = ContractJsonResponse<typeof wordpressUploadContract>
|
||||
export type SftpDownloadBody = ContractBodyInput<typeof sftpDownloadContract>
|
||||
export type SftpUploadBody = ContractBodyInput<typeof sftpUploadContract>
|
||||
export type SftpDeleteBody = ContractBodyInput<typeof sftpDeleteContract>
|
||||
export type SftpMkdirBody = ContractBodyInput<typeof sftpMkdirContract>
|
||||
export type SshCheckCommandExistsBody = ContractBodyInput<typeof sshCheckCommandExistsContract>
|
||||
export type SshCheckFileExistsBody = ContractBodyInput<typeof sshCheckFileExistsContract>
|
||||
export type SshCreateDirectoryBody = ContractBodyInput<typeof sshCreateDirectoryContract>
|
||||
export type SshDeleteFileBody = ContractBodyInput<typeof sshDeleteFileContract>
|
||||
export type SshDownloadFileBody = ContractBodyInput<typeof sshDownloadFileContract>
|
||||
export type SshExecuteCommandBody = ContractBodyInput<typeof sshExecuteCommandContract>
|
||||
export type SshExecuteScriptBody = ContractBodyInput<typeof sshExecuteScriptContract>
|
||||
export type SshGetSystemInfoBody = ContractBodyInput<typeof sshGetSystemInfoContract>
|
||||
export type SshListDirectoryBody = ContractBodyInput<typeof sshListDirectoryContract>
|
||||
export type SshMoveRenameBody = ContractBodyInput<typeof sshMoveRenameContract>
|
||||
export type SshReadFileContentBody = ContractBodyInput<typeof sshReadFileContentContract>
|
||||
export type SshUploadFileBody = ContractBodyInput<typeof sshUploadFileContract>
|
||||
export type SshWriteFileContentBody = ContractBodyInput<typeof sshWriteFileContentContract>
|
||||
export type FileDownloadBody = ContractBodyInput<typeof fileDownloadContract>
|
||||
export type FileDownloadResponse = ContractJsonResponse<typeof fileDownloadContract>
|
||||
export type FileParseBody = ContractBodyInput<typeof fileParseContract>
|
||||
export type FileParseResponse = ContractJsonResponse<typeof fileParseContract>
|
||||
export type FileDeleteBody = ContractBodyInput<typeof fileDeleteContract>
|
||||
export type FileDeleteResponse = ContractJsonResponse<typeof fileDeleteContract>
|
||||
export type PresignedUploadQuery = ContractQueryInput<typeof presignedUploadContract>
|
||||
export type PresignedUploadBody = ContractBodyInput<typeof presignedUploadContract>
|
||||
export type PresignedUploadResponse = ContractJsonResponse<typeof presignedUploadContract>
|
||||
export type BatchPresignedUploadQuery = ContractQueryInput<typeof batchPresignedUploadContract>
|
||||
export type BatchPresignedUploadBody = ContractBodyInput<typeof batchPresignedUploadContract>
|
||||
export type BatchPresignedUploadResponse = ContractJsonResponse<typeof batchPresignedUploadContract>
|
||||
export type MultipartAction = z.output<typeof multipartActionSchema>
|
||||
export type InitiateMultipartBody = z.output<typeof initiateMultipartBodySchema>
|
||||
export type TokenBoundMultipartBody = z.output<typeof tokenBoundMultipartBodySchema>
|
||||
export type GetMultipartPartUrlsBody = z.output<typeof getMultipartPartUrlsBodySchema>
|
||||
export type FileServeParams = ContractParamsInput<typeof fileServeContract>
|
||||
export type FileServeQuery = ContractQueryInput<typeof fileServeContract>
|
||||
export type FileViewParams = ContractParamsInput<typeof fileViewContract>
|
||||
export type FileExportParams = ContractParamsInput<typeof fileExportContract>
|
||||
Reference in New Issue
Block a user