Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(rw-uploads): Create uploads package with prisma extension #11154

Closed
wants to merge 37 commits into from

Conversation

dac09
Copy link
Contributor

@dac09 dac09 commented Aug 5, 2024

Small(er) PR with just the Prisma extension, and new uploads package.

This PR does the following:

  • creates new @redwoodjs/uploads package. This is configured to be a dual esm/cjs package.
  • exports prisma extension with legacy support e.g.
    import {
      createUploadsExtension,
      UploadsConfig,
    } from '@redwoodjs/uploads/prisma'
    
  • scaffolds unit test structure for prisma extension
  • the prisma extension does the following:
    a) If a base64 or TUS upload URL string is sent, it saves or moves it to a file
    b) Adds a withDataUri result extension, to make it easier to deal with files e.g.
Screenshot 2024-08-05 at 23 09 04

Outstanding:

  • Types not coming through correctly on results extension. This is probably package setup
  • Add more unit tests

@dac09 dac09 added the release:feature This PR introduces a new feature label Aug 5, 2024
@dac09 dac09 added this to the next-release milestone Aug 5, 2024
dac09 added 18 commits August 5, 2024 23:15
Just need to make sure the type of compute in results extensions is correct
…rw-uploads

* 'feat/rw-uploads' of github.com:dac09/redwood:
  chore(tsconfig.build): Fix type checking for tests etc (redwoodjs#11167)
  chore(config): migrate renovate config (redwoodjs#11157)
  fix(deps): update prisma monorepo to v5.18.0 (redwoodjs#11165)
  chore(fixture): Rebuild test project fixture (redwoodjs#11166)
  chore(ci): Print full diff when check-test-project-fixture fails (redwoodjs#11164)
  chore(rwjs/vite): Rename build script and format source (redwoodjs#11163)
  chore(tsconfig): Format vite tsconfig (redwoodjs#11162)
  RSC: RSA: Better match error handling with how we generally do it in RW (redwoodjs#11161)
  RSC: RSA: Add more comments to the basic 'use server' check (redwoodjs#11160)
  RSC: RSA: Remove unused check for '$$id' (redwoodjs#11159)
  RSC: Fix red squiggles in transform client tests (redwoodjs#11156)
  RSC: Improve type safety in RSC transform plugins (redwoodjs#11155)
@dac09 dac09 marked this pull request as ready for review August 7, 2024 14:43
@dac09 dac09 requested a review from cannikin August 7, 2024 14:44
@cannikin
Copy link
Member

cannikin commented Aug 7, 2024

There's the third case of just a regular form submit, what's the behavior like in that case? You could simulate an RSC Server Action by having a form submit to an API function (like api/src/functions/SubmitHandler.js). Have the file field in that form literally just be a plain <input type="field"> or the built-in <FileField> form helper. In the function you'd have to pull the data out of event somehow...does a Web Request just contain a string body or does it get parsed for you? But however it works, call db.contact.create() with the resulting data and it should save the upload just like the other two.

Copy link
Contributor Author

dac09 commented Aug 7, 2024

Lambda functions don’t play well with multipart form data - this is why I don’t want to assume anything about the delivery mechanism with form submits yet! You would probably receive the data, save it to a file and pass the path to prisma (the same way I was doing form posts, but all within the receiving function)

@cannikin
Copy link
Member

cannikin commented Aug 7, 2024

There's a lot of file-system specific stuff in the Prisma extension...I was imagining these functions are called on an instance of an adapter, and it's the adapter that actually puts the file where it needs to go. So you can hot-swap them and have a whole new storage backend.

I was imagining the adapter exposes probably 3 total functions:

  • fetch
  • store
  • delete

So the Prisma extension doesn't know/care about where the file is going, it just uses the appropriate adapter:

async create({ query, args }) {
  const uploadArgs = await adapter.store(
    uploadFields,
    args,
  )

  return query(uploadArgs)
},

The modelConfig and tusConfig could be sent into the adapter when it gets initialized and then it can be used internally, no need to send it in again every time. The adapter is setup something like:

# api/src/lib/uploads.js
export const adapter = new FileStore({ modelConfig, tusConfig })

And then maybe that adapter is given to the Prisma extension when you $extends it? I can't remember the exact syntax but something like:

import { adapter } from 'src/lib/uploads'

// other db setup stuff...

export const db = ogDb.$extends(createUploadsExtension(adapter))

Let's pair soon and discuss!

@dac09 dac09 marked this pull request as draft August 9, 2024 05:12
@dac09
Copy link
Contributor Author

dac09 commented Aug 15, 2024

Closing this, will create another PR. Design has changed quite a lot!

@dac09 dac09 closed this Aug 15, 2024
@Josh-Walker-GM Josh-Walker-GM removed this from the next-release milestone Sep 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release:feature This PR introduces a new feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants