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

Vite plugin allows custom telefunc context #106

Closed
hugo082 opened this issue Apr 4, 2024 · 1 comment
Closed

Vite plugin allows custom telefunc context #106

hugo082 opened this issue Apr 4, 2024 · 1 comment

Comments

@hugo082
Copy link

hugo082 commented Apr 4, 2024

AFAIK currently the vite plugin doesn't allow to declare a custom middleware and so managing the telefunc context. This is really pain full as it prevent us from using it as soon as authenticated calls are required on the API.

{
name: 'telefunc:devConfig:serverMiddleware',
apply: apply('dev', { skipMiddlewareMode: true, onlyViteCli: true }),
// Ensure that SvelteKit's configureServer() has precedence, see https://github.com/brillout/telefunc/pull/54
enforce: 'post',
configureServer(server) {
return () => {
addTelefuncMiddleware(server.middlewares)
}
},
},

function addTelefuncMiddleware(middlewares: ConnectServer) {
middlewares.use((req, res, next) => {
if (res.headersSent) return next()
const url = req.originalUrl || req.url
if (!url) return next()
if (url !== '/_telefunc') return next()
// https://stackoverflow.com/questions/12497358/handling-text-plain-in-express-via-connect/12497793#12497793
// Alternative: https://www.npmjs.com/package/raw-body
let body = ''
let bodyPromiseResolve: () => void
let bodyPromise = new Promise((r) => (bodyPromiseResolve = () => r(undefined)))
req.setEncoding('utf8')
req.on('data', function (chunk) {
body += chunk
})
req.on('end', () => {
bodyPromiseResolve()
})
bodyPromise.then(async () => {
const httpResponse = await telefunc({ url, method: req.method!, body })
res.setHeader('Content-Type', httpResponse.contentType)
res.statusCode = httpResponse.statusCode
res.end(httpResponse.body)
})
})
}

It would be great to be able to pass a plugin option to register custom behaviour like:

// vite.config.ts
export default defineConfig({
  plugins: [
    telefunc({
      serverMiddleware: 'src/server.ts'
    })
  ],
  // ...
})
// serc/server.ts
export default async (req, res) => {
  const context = {
    // ...
  }

  const httpResponse = await telefunc({
    url: request.url ?? '/',
    body: request.body,
    method: request.method ?? 'POST',
    context,
  })

  response.setHeader('content-type', httpResponse.contentType)
  response.status(httpResponse.statusCode).send(httpResponse.body)
}

ℹ️ Note that the same behaviour is applied to the preview command here: https://github.com/brillout/telefunc/blob/main/telefunc/node/vite/plugins/previewConfig.ts#L22

@brillout
Copy link
Owner

brillout commented Apr 5, 2024

You can actually do that, see for example:

const context = { user: retrieveUser(req) }

The automatically injected middleware you're referring to isn't really supposed to be used by end-users. (It's only used for creating minimal /examples/.) Admittedly it's confusing and it's something the docs and examples should clarify (it's on the radar).

I guess we can close this, but let me know if you still have questions.

(Btw. in case your company is up for it, we're looking for sponsors.)

@brillout brillout closed this as not planned Won't fix, can't repro, duplicate, stale Apr 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants