uppy icon indicating copy to clipboard operation
uppy copied to clipboard

Integration guide for NestJS uppy companion.js

Open JacobSiegle opened this issue 2 years ago • 4 comments

Initial checklist

  • [X] I understand this is a feature request and questions should be posted in the Community Forum
  • [X] I searched issues and couldn’t find anything (or linked relevant results below)

Problem

It's not straightforward on how to use uppy companion with NestJS. Haven't gotten it to work myself yet so some notes that might be helpful.

NestJS already uses body-parser so I think you can ignore this part of the setup.

You can read about integrating express-session here - https://docs.nestjs.com/techniques/session#session

Last step - app.use('/companion', companionApp) just seems like it causes my app to die / I cannot access the companion endpoint. Not sure it it's possible to make a nestjs controller @All that could expose the companion and plugin endpoints correctly.

Solution

Docs on how to integrate with NestJS

Alternatives

Host in standalone mode

JacobSiegle avatar Sep 30 '22 12:09 JacobSiegle

Did you figure it out ? @JacobSiegle

ken-kuro avatar Feb 07 '23 13:02 ken-kuro

I did not, I was trying to throw it together for a hackathon type event but just ended up not using companion.js for that. Might look into it again in the near future but tbd 🤷‍♂️

JacobSiegle avatar Feb 07 '23 14:02 JacobSiegle

Anyone succedded?

yf-hk avatar Nov 10 '23 07:11 yf-hk

Here's my implementation. It sort of works. Need to do more experiments

import { ValidationPipe } from '@nestjs/common'
import { NestFactory } from '@nestjs/core'
import type { NestExpressApplication } from '@nestjs/platform-express'
import * as companion from '@uppy/companion'
import * as session from 'express-session'

import { envConfig } from '~/configs'

import { AppModule } from './app.module'

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule)

  app.useGlobalPipes(new ValidationPipe())
  app.enableCors()
  app.use(
    session({
      secret: envConfig.SESSION_SECRET,
      resave: false,
      saveUninitialized: false,
    })
  )
  app.use(
    companion.app({
      providerOptions: {
        drive: {
          key: envConfig.GOOGLE_DRIVE_KEY,
          secret: envConfig.GOOGLE_DRIVE_SECRET,
        },
      },
      server: {
        host: `${envConfig.UPPY_COMPANION_HOST}:${envConfig.UPPY_COMPANION_PORT}`,
        protocol: envConfig.UPPY_COMPANION_PROTOCOL,
        path: envConfig.UPPY_COMPANION_PATH,
      },
      filePath: envConfig.UPPY_COMPANION_FILE_PATH,
      secret: envConfig.UPPY_COMPANION_SECRET,
      uploadUrls: [envConfig.UPPY_COMPANION_UPLOAD_URL],
      metrics: true,
      enableUrlEndpoints: true,
    }).app
  )
  await app.listen(envConfig.PORT)
  const server = app.getHttpServer()
  companion.socket(server)
  app.disable('x-powered-by')
}
bootstrap()

yf-hk avatar Nov 11 '23 09:11 yf-hk