Skip to main content

Getting Started

1. Database Schema

Add the files table to your database schema:

import { createFilesTable } from '@repo/storage/database'

// Global database
export const filesTable = createFilesTable()

// Or tenant-scoped
import { tenantSchema } from '@repo/auth/database'
export const filesTable = createFilesTable(tenantSchema)

The table includes columns: name, key, bucket, storage, mimeType, size, and deletedAt.

2. Server File Manager

Create a server-side instance in your app:

// lib/files.server.ts
import { env } from '$env/dynamic/private'
import { getGlobalDb } from '$lib/db/managedDb.server'
import { S3Client } from '@aws-sdk/client-s3'
import { FilesRepository, ServerFileManager } from '@repo/storage/server'

export const serverFileManager = new ServerFileManager({
repository: new FilesRepository(getGlobalDb),
s3: {
client: new S3Client({
endpoint: env.PRIVATE_S3_ENDPOINT,
region: 'us-west-1',
forcePathStyle: true,
credentials: {
accessKeyId: env.S3_ACCESS_KEY_ID!,
secretAccessKey: env.S3_SECRET_ACCESS_KEY!,
},
}),
},
})

3. Basic Upload

Define a schema, create a form, and upload a file:

import { FileInput } from '@repo/storage'
import { zaf } from '@repo/form'
import { z } from 'zod'

export const myFormSchema = z.object({
name: z.string(),
file: zaf(z.file(), {
component: FileInput.Root
}),
})
export const createForm = form(myFormSchema, async ({ file, ...data }) => {
await serverFileManager.createBucket('my-bucket')
const { createdFile } = await serverFileManager.sync('my-bucket', { file })
await db.insert(myTable).values({ ...data, fileId: createdFile.id })
})

Next Steps