Skip to content

Request to dynamic import @supabase/node-fetch #1303

Open
@liyachun01

Description

@liyachun01

Chore

Describe the chore

Request update the static import of @supabase/node-fetch in src/lib/fetch.ts:

import nodeFetch, { Headers as NodeFetchHeaders } from '@supabase/node-fetch'
type Fetch = typeof fetch
export const resolveFetch = (customFetch?: Fetch): Fetch => {
let _fetch: Fetch
if (customFetch) {
_fetch = customFetch
} else if (typeof fetch === 'undefined') {
_fetch = nodeFetch as unknown as Fetch
} else {
_fetch = fetch
}
return (...args: Parameters<Fetch>) => _fetch(...args)
}

export const resolveHeadersConstructor = () => {
if (typeof Headers === 'undefined') {
return NodeFetchHeaders
}
return Headers
}

Use dynamic import('@supabase/node-fetch') to avoid possible Cannot read property 'bind' of undefined error.

Additional context

Related to this issue supabase/postgrest-js#574.

Using @supabase/supabase-js, a user is able to provide custom fetch by providing a global.fetch option. However, with @supabase/node-fetch statically imported, a Cannot read property 'bind' of undefined error may throw at runtime.

TypeError: Cannot read property 'bind' of undefined
    at path/to/node_modules/@supabase/node-fetch/browser.js

The error is thrown when the runtime environment does not have native fetch on globalObject at all.

https://github.com/supabase/node-fetch/blob/bd8f50a4ae647e56cda296b8301d7dff01d4a87b/browser.js#L18.

/* @supabase/node-fetch/browser.js#L18 */
export default globalObject.fetch.bind(globalObject);

In some other @supabase/ packages like @supabase/auth-js, the fetch is resolved using a resolveFetch function:

https://github.com/supabase/auth-js/blob/8af88b6f4e41872b73e84c40f71793dab6c62126/src/lib/helpers.ts#L93-L104.

/* @supabase/auth-js/src/lib/helpers.ts#L93-L104. */
export const resolveFetch = (customFetch?: Fetch): Fetch => {
  let _fetch: Fetch
  if (customFetch) {
    _fetch = customFetch
  } else if (typeof fetch === 'undefined') {
    _fetch = (...args) =>
      import('@supabase/node-fetch' as any).then(({ default: fetch }) => fetch(...args))
  } else {
    _fetch = fetch
  }
  return (...args) => _fetch(...args)
}

This way, the node-fetch import is safe. We could also implement this for nodeFetch and Headers imported here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions