apiWrapper.ts 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. import type { JwtPayload } from '@supabase/supabase-js'
  2. import type { NextApiRequest, NextApiResponse } from 'next'
  3. import { IS_PLATFORM } from '../constants'
  4. import { apiAuthenticate } from './apiAuthenticate'
  5. import { ResponseError, ResponseFailure } from '@/types'
  6. export function isResponseOk<T>(response: T | ResponseFailure | undefined): response is T {
  7. if (response === undefined || response === null) {
  8. return false
  9. }
  10. if (response instanceof ResponseError) {
  11. return false
  12. }
  13. if (typeof response === 'object' && 'error' in response && Boolean(response.error)) {
  14. return false
  15. }
  16. return true
  17. }
  18. // Purpose of this apiWrapper is to function like a global catchall for ANY errors
  19. // It's a safety net as the API service should never drop, nor fail
  20. async function apiWrapper(
  21. req: NextApiRequest,
  22. res: NextApiResponse,
  23. handler: (
  24. req: NextApiRequest,
  25. res: NextApiResponse,
  26. claims?: JwtPayload
  27. ) => Promise<NextApiResponse | Response | void>,
  28. options?: { withAuth: boolean }
  29. ): Promise<NextApiResponse | Response | void> {
  30. try {
  31. const { withAuth } = options || {}
  32. let claims: JwtPayload | undefined
  33. if (IS_PLATFORM && withAuth) {
  34. const response = await apiAuthenticate(req, res)
  35. if (!isResponseOk(response)) {
  36. return res.status(401).json({
  37. error: {
  38. message: `Unauthorized: ${response.error.message}`,
  39. },
  40. })
  41. }
  42. claims = response
  43. }
  44. return handler(req, res, claims)
  45. } catch (error) {
  46. return res.status(500).json({ error })
  47. }
  48. }
  49. export { apiWrapper }
  50. export default apiWrapper