Skip to content

Commit

Permalink
Update README
Browse files Browse the repository at this point in the history
  • Loading branch information
dac09 committed Aug 22, 2024
1 parent 0ef44e3 commit cd43150
Showing 1 changed file with 121 additions and 4 deletions.
125 changes: 121 additions & 4 deletions packages/uploads/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,124 @@
# Uploads
# `@redwoodjs/uploads`

This package houses

- Prisma extension for handling uploads
- Base64 file picker uploader (?)
- TUS uploader (?)
- Prisma extension for handling uploads. Currently
a) Query Extension: will save, delete, replace files on disk during CRUD
b) Result Extension: gives you functions like `.withSignedUri` on configured prisma results - which will take the paths, and convert it to a signed url
- Storage adapters e.g. FS and Memory to use with the prisma extension
- Processors - i.e. utility functions which will take [`Files`](https://developer.mozilla.org/en-US/docs/Web/API/File) and save them to storage

## Usage

In `api/src/uploads.ts` - setup uploads - processors, storage and the prisma extension.

```ts
// api/src/lib/uploads.ts

import { UploadsConfig } from '@redwoodjs/uploads'
import { setupUploads } from '@redwoodjs/uploads'
import { FileSystemStorage } from '@redwoodjs/uploads/FileSystemStorage'
import { UrlSigner } from '@redwoodjs/uploads/signedUrl'

const uploadConfig: UploadsConfig = {
// πŸ‘‡ prisma model
profile: {
// πŸ‘‡ pass in fields that are going to be File uploads
// these should be configured as string in the Prisma.schema
fields: ['avatar', 'coverPhoto'],
},
}

// πŸ‘‡ exporting these allows you access elsewhere on the api side
export const storage = new FileSystemStorage({
baseDir: './uploads',
})

// Optional
export const urlSigner = new UrlSigner({
secret: process.env.UPLOADS_SECRET,
endpoint: '/signedUrl',
})

const { uploadsProcessors, prismaExtension, fileListProcessor } = setupUploads(
uploadConfig,
storage,
urlSigner,
)

export { uploadsProcessors, prismaExtension, fileListProcessor }
```

### Configuring db to use the prisma extension

```ts
// api/src/lib/db.ts

import { PrismaClient } from '@prisma/client'

import { emitLogLevels, handlePrismaLogging } from '@redwoodjs/api/logger'

import { logger } from './logger'
import { prismaExtension } from './uploads'

// πŸ‘‡ Notice here we create prisma client, and don't export it yet
export const prismaClient = new PrismaClient({
log: emitLogLevels(['info', 'warn', 'error']),
})

handlePrismaLogging({
db: prismaClient,
logger,
logLevels: ['info', 'warn', 'error'],
})

// πŸ‘‡ Export db after adding uploads extension
export const db = prismaClient.$extends(prismaExtension)
```

## Using Prisma extension

### A) CRUD operations

No need to do anything here, but you have to use processors to supply Prisma with data in the correct format.

### B) Result extensions

```ts
// api/src/services/profiles/profiles.ts

export const profile: QueryResolvers['profile'] = async ({ id }) => {
// πŸ‘‡ await the result from your prisma query
const profile = await db.profile.findUnique({
where: { id },
})

// Convert the avatar and coverPhoto fields to signed URLs
// Note that you still need to add a api endpoint to handle these signed urls
return profile?.withSignedUrl()
}
```

## Using processors

In your services, you can use the preconfigured "processors" to convert Files to strings for Prisma to save into the database. The processors, and storage adapters determine where the file is saved.

```ts
// api/src/services/profiles/profiles.ts

export const updateProfile: MutationResolvers['updateProfile'] = async ({
id,
input,
}) => {
const processedInput = await uploadsProcessors.processProfileUploads(input)

// This becomes a string πŸ‘‡
// The configuration on where it was saved is passed when we setup uploads in src/lib/uploads.ts
// processedInput.avatar = '/mySavePath/profile/avatar/generatedId.jpg'

return db.profile.update({
data: processedInput,
where: { id },
})
}
```

0 comments on commit cd43150

Please sign in to comment.