Giter VIP home page Giter VIP logo

supabase / supabase-js Goto Github PK

View Code? Open in Web Editor NEW
2.8K 38.0 217.0 4.7 MB

An isomorphic Javascript client for Supabase. Query your Supabase database, subscribe to realtime events, upload and download files, browse typescript examples, invoke postgres functions via rpc, invoke supabase edge functions, query pgvector.

Home Page: https://supabase.com

License: MIT License

JavaScript 1.71% TypeScript 98.29%
client-library database isomorphic javascript js mit-license node-js nuxt orm postgres

supabase-js's Introduction

supabase-js - Isomorphic JavaScript Client for Supabase.

Usage

First of all, you need to install the library:

npm install @supabase/supabase-js

Then you're able to import the library and establish the connection with the database:

import { createClient } from '@supabase/supabase-js'

// Create a single supabase client for interacting with your database
const supabase = createClient('https://xyzcompany.supabase.co', 'public-anon-key')

UMD

You can use plain <script>s to import supabase-js from CDNs, like:

<script src="https://cdn.jsdelivr.net/npm/@supabase/supabase-js@2"></script>

or even:

<script src="https://unpkg.com/@supabase/supabase-js@2"></script>

Then you can use it from a global supabase variable:

<script>
  const { createClient } = supabase
  const _supabase = createClient('https://xyzcompany.supabase.co', 'public-anon-key')

  console.log('Supabase Instance: ', _supabase)
  // ...
</script>

ESM

You can use <script type="module"> to import supabase-js from CDNs, like:

<script type="module">
  import { createClient } from 'https://cdn.jsdelivr.net/npm/@supabase/supabase-js/+esm'
  const supabase = createClient('https://xyzcompany.supabase.co', 'public-anon-key')

  console.log('Supabase Instance: ', supabase)
  // ...
</script>

Deno

You can use supabase-js in the Deno runtime via esm.sh:

import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'

Custom fetch implementation

supabase-js uses the cross-fetch library to make HTTP requests, but an alternative fetch implementation can be provided as an option. This is most useful in environments where cross-fetch is not compatible, for instance Cloudflare Workers:

import { createClient } from '@supabase/supabase-js'

// Provide a custom `fetch` implementation as an option
const supabase = createClient('https://xyzcompany.supabase.co', 'public-anon-key', {
  global: {
    fetch: (...args) => fetch(...args),
  },
})

Sponsors

We are building the features of Firebase using enterprise-grade, open source products. We support existing communities wherever possible, and if the products don’t exist we build them and open source them ourselves. Thanks to these sponsors who are making the OSS ecosystem better for everyone.

New Sponsor

Badges

Coverage Status

supabase-js's People

Contributors

alaister avatar ananya2001-an avatar awalias avatar bnjmnt4n avatar darora avatar delgado3d avatar dependabot-preview[bot] avatar dependabot[bot] avatar dragarcia avatar dshukertjr avatar egor-romanov avatar fernandolguevara avatar filipecabaco avatar ftonato avatar hf avatar inian avatar j0 avatar jordienr avatar kamilogorek avatar kangmingtay avatar kiwicopple avatar laktek avatar mansueli avatar phamhieu avatar ramirond avatar soedirgo avatar thebengeu avatar thorwebdev avatar vonovak avatar w3b6x9 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

supabase-js's Issues

Auth routes fail if the database contains a `users` table

Steps to replicate:

  1. Start a new project on Supabase
  2. Add the API details to test/integration/testAuth.js
  3. Run the tests -> success
  4. Add a table in the database (eg: countries)
  5. Run the tests -> success
  6. Add a users table in the database (template below)
  7. Run the tests -> fail

Example template to use:

CREATE TABLE public.users (
  id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
  inserted_at timestamp without time zone DEFAULT timezone('utc'::text, now()) NOT NULL,
  updated_at timestamp without time zone DEFAULT timezone('utc'::text, now()) NOT NULL,
  data jsonb DEFAULT null,
  username text
);

RPC fails when using an extension feature inside Postgres stored function

Bug report

Describe the bug

When attempting to call a Postgres stored function which utilizes an extension function via .rpc(), the response fails and returns 404

To Reproduce

I have created a stored function called search_stations inside Postgres. It accepts 2 parameters - search_value TEXT and result_limit INTEGER. It returns a TABLE, and all returned fields and types are correctly defined.

This function uses the SIMILARITY function, as well as the distance (<->) operator, both from the pg_trgm extension. This extension shows as enabled in the dashboard.

I have verified that results return correctly when running the following query from within pgAdmin as well as the Supabase dashboard:

SELECT * FROM search_stations('Leeds', 10)

However, when I do the following inside my codebase using supabase-js:

await SupabaseClient.rpc("search_stations", {
    search_value: "Leeds",
    result_limit: 10
});

The following error occurs:

{
  "error": {
    "hint": "No function matches the given name and argument types. You might need to add explicit type casts.",
    "details": null,
    "code": "42883",
    "message": "function similarity(text, text) does not exist"
  },
  "data": null,
  "count": null,
  "status": 404,
  "statusText": "Not Found",
  "body": null
}

I am able to correctly call other stored functions in my database, but none of them utilize features from any extensions.

Expected behavior

The function should not throw an error and should instead return the results of the function.

Screenshots

N/A

System information

  • OS: Windows 10 X64
  • Browser (if applies): N/A - request running via Node (14.14.0)
  • Version of supabase-js: 1.7.7
  • Version of Node.js: 14.14.0

Additional context

I am able to correctly call other stored functions in my database and results are correctly returned, but none of those other functions utilize features from a extensions.

I have tried explicitly setting extensions.similarity for all the calls to similarity inside my function, but this returns the following when run via rpc():

{
  "error": {
    "hint": null,
    "details": null,
    "code": "42501",
    "message": "permission denied for schema extensions"
  },
  "data": null,
  "count": null,
  "status": 403,
  "statusText": "Forbidden",
  "body": null
}

Isomorphism breaks due to Websockets when using SSR

Bug report

Describe the bug

When importing createClient into a SvelteKit project, the following error is raised:

5:49:56 PM [vite] Error when evaluating SSR module /node_modules/websocket/lib/browser.js?v=f34fcf64:
Error: Could not determine global this
    at /node_modules/websocket/lib/browser.js?v=f34fcf64:7:28
    at instantiateModule (/home/ixxie/repos/minex/node_modules/vite/dist/node/chunks/dep-66eb515d.js:69030:166)

It seems to come from this block of code in the Websockets package.

To Reproduce

npm init svelte@next
npm install
npm install --save-prod @supabase/supabase-js
sed -i "s/<script>/<script>\n\timport { createClient } from '@supabase\/supabase-js';/" ./src/routes/index.svelte
npm run dev

Expected behavior

Import should work without error

Screenshots

If applicable, add screenshots to help explain your problem.

System information

  • Version of supabase-js: 1.11.2
  • Version of Node.js: 14.15.4

Additional context

This was discovered after resolving #153, after which @kiwicopple recommended I create a new issue.

Multi-schema in test suite

The test suite includes a test for multi-schema on PostgREST:

describe('test multi schema', () => {
const supabase = createClient('http://localhost:8000', 'examplekey', {schema: 'personal'})
it('should return a value from the other schema', async () => {
const response = await supabase
.from('users')
.eq('username', 'leroyjenkins')
.select('*')
assert(response.body.length === 1)
assert(response.body[0].username === 'leroyjenkins')
})

But adding schemas on-the-fly on KPS hasn't been implemented yet: https://github.com/supabase/infrastructure/issues/33.

I've also seen other weird quirks while testing #13, will figure it out before merging it.

Deno / Deno Deploy compatibility

Feature request

Is your feature request related to a problem? Please describe.

I tried importing a Skypack and jspm version of the supabase-js client library, without success. I can create issues for the problems if you want, but since no one has brought up Deno yet I thought I'd start with a feature request.

Also, it would be really cool to be able to use Supabase with the new Deno Deploy service, just announced a couple of weeks ago.

https://deno.com/deploy

Describe the solution you'd like

Compatibility and instructions on how to use Deno / Deno Deploy with Supabase.

Describe alternatives you've considered

Using Node, of course :p but Deno is really nice to use and seems ambitious and forward thinking, similar to Supabase.

Additional context

Add any other context or screenshots about the feature request here.

upload to storage from backend (node)

Feature request

It's not currently possible to upload a file to supabase.storage using only NodeJS.

Is your feature request related to a problem? Please describe.

My backend does processing of user media files. It downloads them from supabase.storage and after processing should be able to upload back.

Describe the solution you'd like

I would like to have an overload of upload function that accepts path to a file or a stream.

Describe alternatives you've considered

I looked through docs and couldn't find any.

Duplicates based on capitalization in Auth.

Bug report

If users type in the same email but with a capital letter on signup, it'll create a second account under that same email.

Expected behavior

Should be able to detect capital letters and sign users into the same account or block a registration if the email is taken.

Screenshots

Screen Shot 2021-04-29 at 9 30 29 PM

Screen Shot 2021-04-29 at 9 31 29 PM

System information

  • OS: macOS
  • Browser: Chrome
  • Version of Node.js: 14.16
  • Framework: NextJS

Storage Auth

Chore

Describe the chore

Not sure we are passing in the JWT headers to the storage API? like this

return new PostgrestClient(this.restUrl, {

Additional context

If we do this, should we also set the owner of the file? This would make RLS policies easier

Auth: Change DX of user management

Feature request

Is your feature request related to a problem? Please describe.

As it stands today, you have to do

try {
const {
  body: { user },
} = await supabase.auth.signup(
  '[email protected]',
  'password'
)
...

To get the user object, and

...} catch (error) {
      console.log('Error message:', error.response.body.error_description);
    } 

to get to the error message.

Describe the solution you'd like

my preferred DX would be

const { error, user } = await supabase.auth.signup(
  '[email protected]',
  'password'
);
if (error) alert(error);

However, I know that @awalias is a big fan of returning the whole response object, which I personally find rather distracting. Maybe we can do something like

const { error, user, raw_response } = await supabase.auth.signup(
  '[email protected]',
  'password'
);
if (error) alert(error);

To give folks the option to access the raw object, but not overload folks who don't care about most of the stuff in the raw response. Wdyt? This probably warrants a new issue?

Describe alternatives you've considered

Solve via documentation? Not ideal IMO.

Additional context

Relates to supabase/supabase#143

Provider login refreshes page after callback?

Bug report

Describe the bug

When calling the supabase.auth.signIn({ provider }) method, after the provider redirect, the response payload returns to the login page, but a sudden page refresh occurs, causing the response to result in a null state. It does not happen when the grant_type is password, only when trying to use a provider login. The local storage session is properly set.

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository:

  1. Go to https://github.com/Anstroy/alacena-vue-3.git
  2. Clone the repo and install dependencies and add supabase url and key
  3. Start repo using yarn serve
  4. Try logging in using a provider.
  5. Take a look at the console. The console.log within services/supabase login function should output the response, but you will see it outputs the response then suddenly swaps to null, due to what seems like a sudden page refresh.

Expected behavior

Response from callback should return to the callback URL and a page refresh after the site has returned should not occur?

Screenshots

Will work on getting screenshots.

System information

  • OS: Windows
  • Browser (if applies) Brave
  • Version of supabase-js: latest
  • Version of Node.js: 12.18.3

Updates are not working

Bug report

Describe the bug

I am running an update on a single row in the table wedding and it is 404ing. I've confirmed I am using the correct id and table. It seems the request being made is not correct.

Here is the code:

  async update(weddingId, wedding) {
	// weddingId = c81c8ab3-9fc5-41d6-9a68-843109ba95b0
	// wedding = {slug: "yes-"}
    return await SupabaseService
      .from<Wedding>('wedding')
      .update(wedding)
      .eq('id', weddingId);
  }

The request url is:

https://wqzrlmhkwwtfqmbwirha.supabase.co/rest/v1/wedding?slug=eq.y&id=neq.c81c8ab3-9fc5-41d6-9a68-843109ba95b0&slug=eq.ye&id=neq.c81c8ab3-9fc5-41d6-9a68-843109ba95b0&slug=eq.yes&id=neq.c81c8ab3-9fc5-41d6-9a68-843109ba95b0&slug=eq.yes-&id=neq.c81c8ab3-9fc5-41d6-9a68-843109ba95b0&id=eq.c81c8ab3-9fc5-41d6-9a68-843109ba95b0

If you break that down:

> queryString.parse('?slug=eq.y&id=neq.c81c8ab3-9fc5-41d6-9a68-843109ba95b0&slug=eq.ye&id=neq.c81c8ab3-9fc5-41d6-9a68-843109ba95b0&slug=eq.yes&id=neq.c81c8ab3-9fc5-41d6-9a68-843109ba95b0&slug=eq.yes-&id=neq.c81c8ab3-9fc5-41d6-9a68-843109ba95b0&id=eq.c81c8ab3-9fc5-41d6-9a68-843109ba95b0')
[Object: null prototype] {
  '?slug': 'eq.y',
  id: [
    'neq.c81c8ab3-9fc5-41d6-9a68-843109ba95b0',
    'neq.c81c8ab3-9fc5-41d6-9a68-843109ba95b0',
    'neq.c81c8ab3-9fc5-41d6-9a68-843109ba95b0',
    'neq.c81c8ab3-9fc5-41d6-9a68-843109ba95b0',
    'eq.c81c8ab3-9fc5-41d6-9a68-843109ba95b0'
  ],
  slug: [ 'eq.ye', 'eq.yes', 'eq.yes-' ]
}

Why are both neq and eq being applied and why is neq there 4 times? Also, why is slug there? The slug was not included in the filter, just in the body.

Screenshots

Screen Shot 2020-08-31 at 10 54 35 AM

System information

  • Version of supabase-js: v0.36.4
  • Version of Node.js: v12.12.0

auth.session() and auth.user() return null in SPA app when called right after createClient

Bug report

Describe the bug

database.auth.session() and database.auth.user() are both null when called right after const database = createClient(SUPABASE_URL, SUPABASE_ANON_KEY) in a SPA app.

Steps to reproduce the behavior, please provide code snippets or a repository:

Just try the code

Expected behavior

I expect database.auth.session() and database.auth.user() to not return null if a user is connected. I need to check that in my router to change the route if needed, yet can't without doing some custom code because of the null issue. The storage being synchronous, the returns shouldn't be null.

System information

  • OS: Mac OS
  • Browser (if applies) [e.g. chrome, safari]
  • Version of supabase-js: latest
  • Version of Node.js: latest

Authentication not working properly in a nuxt SPA app.

Bug report

Authentication not working properly in a vue/nuxt SPA app.

Describe the bug

Whenever I call auth.signIn() it refreshes my page, and any code after is ignored. It does load the session into localstorage, but doesn't let me handle the response from the call.
So I can't check for user or errors after calling auth.signIn(). The only thing I can do is put a function in mounted to check if this.$supabase.auth.user() exists after page refresh, and then I can router.push to a welcome page if so. But that obviously isn't desired behavior.

To Reproduce

Here's the code for my sign in page.

export default {
  data: function () {
    return {
      //v-model to form inputs
      form: {
        email: '',
        password: ''
      }
    }
  },
  methods: {
    // called on form submit
    async onSubmit () {
      try {
        const { error, session, user } = await this.$supabase.auth.signIn({
          email: this.form.email,
          password: this.form.password,
        })
        //none of the following code is called due to page refresh
        if (error) {
          console.error('Error thrown:', error.message)
        }
        if (user) {
          console.log(user)
        }
      } catch (error) {
        console.error('Error thrown:', error.message)
      }
    }
  },
  mounted: function () {
    //check if supabase session exists
    const user = this.$supabase.auth.user()
    if (user) {
      //save user data to vuex
       this.$store.commit('LOG_IN', user)
       //redirect to main page
       this.$router.push('/')
    }
  }
}

Expected behavior

I expect auth.signIn() to not cause page refresh so that I can properly handle the response and possible errors.

Screenshots

System information

  • OS: WSL 2
  • Browser (if applies): Chrome/Edge
  • Version of supabase-js: 1.7.7
  • Version of Node.js: 14.15.4
  • Nuxt: 2.14.12

Additional context

Compilation errors with TypeScript

Improve documentation

Link

https://supabase.io/docs/client/installing

Describe the problem

Hi, I wasn't sure whether to file this as a bug report or a documentation issue as I am not sure which it is.

Typescript and Node really aren't my forte so sorry if this is something basic, but after running the install steps at the above link and then following the createClient example (https://supabase.io/docs/client/initializing) I run into the following compilation errors while compiling with Typescript:

node_modules/@supabase/gotrue-js/dist/main/GoTrueClient.d.ts:19:29 - error TS2304: Cannot find name 'Storage'.
19 protected localStorage: Storage;

node_modules/@supabase/gotrue-js/dist/main/GoTrueClient.d.ts:38:24 - error TS2304: Cannot find name 'Storage'.
38 localStorage?: Storage;

node_modules/@supabase/postgrest-js/dist/main/lib/types.d.ts:33:20 - error TS2304: Cannot find name 'URL'.
33 protected url: URL;

node_modules/@supabase/supabase-js/dist/main/lib/SupabaseAuthClient.d.ts:11:24 - error TS2304: Cannot find name 'Storage'.
11 localStorage?: Storage;

node_modules/@supabase/supabase-js/dist/main/lib/types.d.ts:27:20 - error TS2304: Cannot find name 'Storage'.
27 localStorage?: Storage;

Describe the improvement

If there are additional steps required to work with Typescript, it would be nice if the documentation provided direction. Or if it already exists, maybe just a link on the installation page to the Typescript-specific documentation.

Thanks :-)

How to set/get the JWT secret?

Question

Is there a way to get or set the secret used to sign the JWT access tokens? My use case is to use the Supabase-generated tokens for authorization in other micro-services, so having the secret will help verify their signatures.

Undefined `confirmed_at` on signup

Bug report

Describe the bug

When calling the signup method while email confirmations are enabled, an error is thrown: TypeError: Cannot read property 'confirmed_at' of undefined.

To Reproduce

First enable email confirmations in Supabase dashboard. Then:

const supabase = client.createClient(SUPABASE_URL, SUPABASE_API_KEY);
const createUser = async () => {
  try {
    const { body: { user } } = await supabase.auth.signup("[email protected]", "password");
    return user
  } catch (e) {
    return Promise.reject(e)
  }
};

createUser()
  .then(res => console.log(res))
  .catch(err => console.log(err))

Looks like the error is happening here:

if (response.status === 200 && response['body']['user']['confirmed_at']) {

The response returned doesn't include a user key in the body. I think the body is the user object itself.

Expected behavior

Signup should return response from POST request to /signup on auth url .

System information

  • OS: macOS
  • Version of supabase-js: 0.36.4
  • Version of Node.js: 14.5.0

Major DX change: response and error handling

Decision

We've decided to make a major change to support a better developer experience for working with supabase-js. Instead of throwing an error, we will return the error object as part of the response.

Example

Given a successful query, e.g. const response = await supabase.from('products').select('*'), response will be:

{
  "error": null,
  "data": [...],
  "status": 200,
  "statusCode": 200,
  "statusText": "",
  "body": [...] // for backwards compatibility: `body === data`
}

Given a bad query, e.g. const response = await supabase.from('productx').select('*'), response will be:

{
  "error": {
    "code": 404,
    "message": "relation \"public.productx\" does not exist",
    "details": null,
    "hint": null
  },
  "data": null,
  "status": 404,
  "statusCode": 404,
  "statusText": "",
  "body": null // for backwards compatibility: `body === data`
}

Future DX

This will enable the following experience:

const { error, data: products } = await supabase.from('products').select('*')
if (error) {
  alert(error.message)
  return // abort
}
console.log(`Found ${products.length} products.`)

Additional context

Inspiration has been taken from https://github.com/vercel/swr#quick-start:

import useSWR from 'swr'

function Profile() {
  const { data, error } = useSWR('/api/user', fetcher)

  if (error) return <div>failed to load</div>
  if (!data) return <div>loading...</div>
  return <div>hello {data.name}!</div>
}

as well as Stripe.js : https://stripe.com/docs/js/payment_methods/create_payment_method
image

Headers provided to Supabase client are not used in requests

Bug report

Describe the bug

Headers passed to the supabase client upon creation are not sent as part of requests made by the client.

To Reproduce

Note: This reproduction example assumes that you are querying a storage bucket that has policies applied so that only authenticated users may read from the bucket, and that the request is being made outside of a browser environment e.g. from a Next.js API route.

  1. Initialize a supabase client, passing in custom headers for the client, e.g.
import { createClient } from '@supabase/supabase-js'

const supabase = createClient(url, anonKey, {
  headers: {
    apiKey: anonKey,
    Authorization: `Bearer ${jwt}`
  }
})
  1. Make a request using that client, e.g.
const result = await supabase.storage.from('avatars').download(avatarURL)
  1. Observe that the request does not return the expected result, as the request made by the client does not use the Authorization header that was provided on creation

Expected behavior

Supabase client uses the headers provided in the call to createClient when making requests.

In the example above this would set the Authorization header on the request to the Storage API, allowing the server to make a request to the restricted content on behalf of the user.

Screenshots

N/A

System information

  • OS: N/A
  • Browser: N/A
  • Version of supabase-js: 1.11.9
  • Version of Node.js: 14.16.1

Additional context

This issue was created off the back of this comment, and is discussed further in that thread.

Permission denied for stored procedure that updates user's email address in auth.users

I created a stored procedure (aka function) in the database that I hoped would allow the user's email address to be updated from the supabase JS client. When I ran it, I was met with an error message: 'permission denied for schema auth'

Here's what my 'CREATE FUNCTION' query looks like:

CREATE FUNCTION updateauthemail (new_email text, auth_id text)
RETURNS text AS $updated_data$
	DECLARE
		updated_data text;
	BEGIN
		UPDATE auth.users set email = new_email where id = auth_id;
		RETURN updated_data;
END;
$updated_data$ LANGUAGE plpgsql;

Do I need to add something to the function when creating it, or pass a certain param through the JS client on my Node.js server? Here's the function I'm calling through the JS client:

const { data: rpcData, error: rpcErr } = await supabase.rpc(
      "updateauthemail",
      {
        auth_id: authId,
        new_email: updatedData.email,
      }
    );

Originally posted by @dayvista in supabase/supabase#573 (reply in thread)

Error build Angular 11 + Vercel

Deploy in Vercel appears this error

21:16:32.252 | ERROR in node_modules/@supabase/supabase-js/dist/main/SupabaseClient.d.ts:38:9 - error TS1086: An accessor cannot be declared in an ambient context.
21:16:32.252 | 38 get storage(): SupabaseStorageClient;

Add option to prevent "updates" on unmodified updates.

Possible implementation:

const mySubscription = supabase
  .from('countries')
  .on('UPDATE', payload => {  })
  .subscribe({ ignoreDuplicates: true })

Object comparisons in JS aren't very "performant" (if there is such a word), so we will want to make the ignoreDuplicates = false by default.

Context:

image

Instantiating supabase from unpkg stopped working

Bug report

Instantiating supabase from unpkg stopped working.

Describe the bug

Below results in Cannot read 'createClient' of undefined. It used to work.

<script src="https://unpkg.com/@supabase/supabase-js"></script>
<script>
    const supabaseUrl = 'my supabase url'
    const supabaseAnonKey = 'my anon key'
    var supabase = supabase.createClient(supabaseUrl, supabaseAnonKey)
</script>

Expected behavior

It is expected that the above code or a similar construct will work. Maybe the API changed?

Auth error: undefined is not an object (evaluating 'this.localStorage.setItem')

I'm using the latest version of expo with react native. When I run the supabase.auth.signup function, it creates the user in the database, but does not return a user object. The error shows an issue with local storage.

createUser = async (email, password) => {
	const { user, session, error } = await supabase.auth.signUp({
		email: email,
		password: password,
	})
	.then(function (response) { 
		console.log(response)
		return response
	})
}

[Unhandled promise rejection: TypeError: undefined is not an object (evaluating 'this.localStorage.removeItem')]
- node_modules/@supabase/supabase-js/dist/main/SupabaseClient.js:107:47 in __awaiter$argument_3
- node_modules/regenerator-runtime/runtime.js:63:36 in tryCatch
- node_modules/regenerator-runtime/runtime.js:293:29 in invoke
* http://127.0.0.1:19000/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&hot=false&minify=false:283503:72 in <unknown>
- node_modules/react-native/node_modules/promise/setimmediate/core.js:45:6 in tryCallTwo
- node_modules/react-native/node_modules/promise/setimmediate/core.js:200:22 in doResolve
- node_modules/react-native/node_modules/promise/setimmediate/core.js:66:11 in Promise
* http://127.0.0.1:19000/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&hot=false&minify=false:283482:35 in <unknown>
- node_modules/whatwg-url-without-unicode/lib/URLSearchParams.js:57:7 in iface.is
- node_modules/regenerator-runtime/runtime.js:63:36 in tryCatch
- node_modules/regenerator-runtime/runtime.js:293:29 in invoke
* http://127.0.0.1:19000/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&hot=false&minify=false:283503:72 in <unknown>
- node_modules/react-native/node_modules/promise/setimmediate/core.js:45:6 in tryCallTwo
- node_modules/react-native/node_modules/promise/setimmediate/core.js:200:22 in doResolve
- node_modules/react-native/node_modules/promise/setimmediate/core.js:66:11 in Promise
* http://127.0.0.1:19000/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&hot=false&minify=false:283482:35 in <unknown>
* screens/UserCardScreen.js:312:19 in render
- node_modules/regenerator-runtime/runtime.js:63:36 in tryCatch
- node_modules/regenerator-runtime/runtime.js:293:29 in invoke
- node_modules/regenerator-runtime/runtime.js:63:36 in tryCatch
- node_modules/regenerator-runtime/runtime.js:154:27 in invoke
- node_modules/regenerator-runtime/runtime.js:189:16 in PromiseImpl$argument_0
- node_modules/react-native/node_modules/promise/setimmediate/core.js:45:6 in tryCallTwo
- node_modules/react-native/node_modules/promise/setimmediate/core.js:200:22 in doResolve
- node_modules/react-native/node_modules/promise/setimmediate/core.js:66:11 in Promise
- node_modules/regenerator-runtime/runtime.js:188:15 in callInvokeWithMethodAndArg
- node_modules/regenerator-runtime/runtime.js:211:38 in enqueue
- node_modules/regenerator-runtime/runtime.js:238:8 in exports.async
* screens/UserCardScreen.js:308:69 in render
* http://127.0.0.1:19000/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&hot=false&minify=false:275518:81 in _callee2$
- node_modules/regenerator-runtime/runtime.js:63:36 in tryCatch
- node_modules/regenerator-runtime/runtime.js:293:29 in invoke
- node_modules/regenerator-runtime/runtime.js:63:36 in tryCatch
- node_modules/regenerator-runtime/runtime.js:154:27 in invoke
- node_modules/regenerator-runtime/runtime.js:189:16 in PromiseImpl$argument_0
- node_modules/react-native/node_modules/promise/setimmediate/core.js:45:6 in tryCallTwo
- node_modules/react-native/node_modules/promise/setimmediate/core.js:200:22 in doResolve
- node_modules/react-native/node_modules/promise/setimmediate/core.js:66:11 in Promise
- node_modules/regenerator-runtime/runtime.js:188:15 in callInvokeWithMethodAndArg
- node_modules/regenerator-runtime/runtime.js:211:38 in enqueue
- node_modules/regenerator-runtime/runtime.js:238:8 in exports.async
* screens/UserCardScreen.js:104:15 in initialRequest
- node_modules/react-native/Libraries/Pressability/Pressability.js:691:17 in _performTransitionSideEffects
- node_modules/react-native/Libraries/Pressability/Pressability.js:628:6 in _receiveSignal
- node_modules/react-native/Libraries/Pressability/Pressability.js:524:8 in responderEventHandlers.onResponderRelease
- node_modules/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js:265:4 in invokeGuardedCallbackImpl
- node_modules/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js:476:2 in invokeGuardedCallback
- node_modules/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js:500:2 in invokeGuardedCallbackAndCatchFirstError
- node_modules/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js:597:41 in executeDispatch
- node_modules/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js:621:19 in executeDispatchesInOrder
- node_modules/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js:2521:28 in executeDispatchesAndRelease
* [native code]:null in forEach
- node_modules/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js:836:4 in forEachAccumulated
- node_modules/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js:2546:20 in runEventsInBatch
- node_modules/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js:2702:18 in runExtractedPluginEventsInBatch
- node_modules/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js:2639:35 in batchedUpdates$argument_0
- node_modules/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js:17712:13 in batchedUpdates$1
- node_modules/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js:2492:29 in batchedUpdates
- node_modules/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js:2638:16 in _receiveRootNodeIDEvent
- node_modules/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js:2767:27 in receiveTouches
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:416:4 in __callFunction
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:109:6 in __guard$argument_0
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:364:10 in __guard
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:108:4 in callFunctionReturnFlushedQueue
* [native code]:null in callFunctionReturnFlushedQueue


This is what the console returns when I try to log the object

Object {
  "data": null,
  "error": [TypeError: undefined is not an object (evaluating 'this.localStorage.setItem')],
  "session": null,
  "user": null,
}


undefined is not an object (evaluating 'this.localStorage.setItem')
- node_modules/@supabase/supabase-js/dist/main/SupabaseClient.js:107:31 in _closeSubscription
- node_modules/whatwg-url-without-unicode/lib/URLSearchParams-impl.js:11:0 in <global>
- node_modules/whatwg-url-without-unicode/lib/URLSearchParams-impl.js:76:4 in URLSearchParamsImpl#getAll
- node_modules/whatwg-url-without-unicode/lib/URLSearchParams.js:81:56 in iface.convert
- node_modules/regenerator-runtime/runtime.js:63:36 in tryCatch
- node_modules/regenerator-runtime/runtime.js:293:29 in invoke
* http://127.0.0.1:19000/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&hot=false&minify=false:283485:29 in fulfilled
- node_modules/react-native/node_modules/promise/setimmediate/core.js:37:13 in tryCallOne
- node_modules/react-native/node_modules/promise/setimmediate/core.js:123:24 in setImmediate$argument_0
- node_modules/react-native/Libraries/Core/Timers/JSTimers.js:130:14 in _callTimer
- node_modules/react-native/Libraries/Core/Timers/JSTimers.js:181:14 in _callImmediatesPass
- node_modules/react-native/Libraries/Core/Timers/JSTimers.js:441:30 in callImmediates
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:387:6 in __callImmediates
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:135:6 in __guard$argument_0
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:364:10 in __guard
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:134:4 in flushedQueue
* [native code]:null in flushedQueue
* [native code]:null in invokeCallbackAndReturnFlushedQueue

Update user data

Question

How can you update user data? Here are the possibilities I see:

  1. I see there is user_metadata but don't see a way to update it.
  2. I could add a table called user and join on the UID the signup generates. If that is the case how can we create a foreign key to the auth'd user row?

add `unwrap()` method to supabase client

Feature request

add an unwrap() method or a an either monad left() method to pull the data out of a postgrest response.

Is your feature request related to a problem? Please describe.

Not exactly a problem, but the way the client is designed requires every database query to individually handle database failures. For the most part, I want to assume that the query succeeded, and throw an error if it did not. That makes most of my db calls look like this:

  const res = await context.supabase
    .from<tables['my_table']>('my_table')
    .select()
    .filter('status', 'eq', 'COMPLETED')
    .limit(1)
  if (res.error) throw new Error(`SupabaseError: query failed: \n${res.error}`)

Describe the solution you'd like

The solution I would like best, would be to add a method which can optionally unwrap the { error: object } | { data: object[] } response from supabase into just the data field. If there is an error present, the client should throw an error. This should not break any existing workflows, its just an optional convenience method.

Usage:

const data: table['my_table'] = await supabase.from<table['my_table']>('my_table')
  .select()
  .unwrap()

// handling an error:
try {
  const data = await supabase.from('my_table').delete().unwrap()
} catch (e) {
  if (e.name === 'SupabaseError') {
    // handle it
  } else {
    throw e
  }
}

Describe alternatives you've considered

I have attempted building this on top of the supabase client, but because of the way queries are built, I need to use proxies:

  const supabase_proxy_handler = {
    get: function (target: any, prop: string) {
      if (prop === 'unwrap') {
        return new Promise((resolve, reject) => {
          target.then((res: PostgrestResponse) => {
            if (res.error) throw new Error(`SupabaseError: query failed: \n${JSON.stringify(res.error)}`)
            else return res.data
          })
        })
      } else {
        return target[prop]
      }
    },
  }
  const supabase_proxy = new Proxy(supabase, supabase_proxy_handler)

This technically works, but manipulating the types to include the unwrap() method is harder.

Additional context

unwrap is a common pattern in several languages & libraries. Here is an example in rust: https://doc.rust-lang.org/rust-by-example/error/option_unwrap.html

"XMLHttpRequest is not defined" on sveltekit endpoints when deployed on Vercel

Bug report

Describe the bug

Using the client for auth or for querying the database in a sveltekit endpoint throw an error :

{
  data: null,
  error: ReferenceError: XMLHttpRequest is not defined
      at file:///var/task/server/app.mjs:2522:21
      at new Promise (<anonymous>)
      at fetch2 (file:///var/task/server/app.mjs:2517:16)
      at file:///var/task/server/app.mjs:2646:7
      at new Promise (<anonymous>)
      at file:///var/task/server/app.mjs:2645:12
      at Generator.next (<anonymous>)
      at file:///var/task/server/app.mjs:2619:67
      at new Promise (<anonymous>)
      at __awaiter$8 (file:///var/task/server/app.mjs:2601:10)
}

To Reproduce

I made a repository exposing the issue : https://github.com/Pixselve/supabase-sveltekit-endpoints
Click on a button to fetch the endpoint and observe the cloud functions logs on Vercel.

Expected behavior

Requests should not fail and should give the appropriate data.

System information

  • OS: Vercel Node.js Runtime
  • Version of supabase-js: 1.10.0
  • Version of Node.js: 14

How to handle fields like confirmationToken, resetPasswordToken, etc?

How to handle fields like confirmationToken, resetPasswordToken, etc?

Should these be attached to user_metadata or in a separate table?

Ideally I'd like to keep all auth-related stuff within the user auth object, perhaps within the user_metadata field. But I don't see a way to initialize or update that field with the API (perhaps it's meant for internal Supabase stuff?). For now I'll create a separate table to handle resetting passwords, confirmation tokens, etc, but I wanted to get a sense of where this type of information should be stored from the community.

Problem running javascript-auth example

Bug report

I'm trying to recreate the javascript-auth example. I copied all of the files from the directory and added my supabase URL and supabase key where indicated.

When I run the repo with npm run dev, the local page loads with two errors:

  • Uncaught ReferenceError: process is not defined
  • Uncaught ReferenceError: Supabase is not defined

When I try entering an email address and password to create a user, the page refreshes with the email and password values in the URL, although no user is created in my Supabase project and no email is received on the email address indicated

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository:

  1. Clone the javascript-auth folder
  2. In index.js, add the Supabase URL and Supabase key where indicated
  3. On terminal, run `npm run dev'
  4. When the local page loads, in the Sign Up section, an email address and password and click the "submit query" button
  5. See error

Expected behavior

I expected:

  1. To receive a visual confirmation on the page of the submitted query
  2. To receive an email confirmation at the email address indicated
  3. To see a new user created in my Supabase project

Screenshots

This is what I'm seeing on page load

Screen Shot 2021-01-17 at 7 21 16 PM

When I submit a sign-up query, here is the response in the CLI

Screen Shot 2021-01-17 at 7 22 09 PM

System information

  • OS: [macOS
  • Browser (if applies): Chrome, Firefox
  • Version of supabase-js: No version of supabase-js in the repository, I presume because it's loaded via an unpkg script?
  • Version of Node.js: [e.g. 12.10.0]

Additional context

In this example, I did not run npm install @supabase/supabase-js, because I didn't see an instruction to do that.

However, I reproduced a javascript-auth instance to attempt that fix, and I saw the same behavior even after running npm install @supabase/supabase-js on the repo

Trouble with svelte/sapper template

Sapper#rollup throws warnings on import

Supabase is amazing, so thank you!

I'm trying to use it with svelte/sapper and running into some hiccups. It seems there's some underlying problem with rollup and maybe ES versions, and in the end it runs but with a large number of warnings that clutter feedback in npm run dev.

To Reproduce

  1. Start with a fresh sapper template
npx degit sveltejs/template fresh
cd fresh 
npm i
  1. Install supabase-js npm i --save @supabase/supabase-js
  2. Import in src/App.svelte
	import { createClient } from '@supabase/supabase-js'
  1. Run npm run build to see a rollup error suggesting @rollup/plugin-json


src/main.js → public/build/bundle.js...
(!) `this` has been rewritten to `undefined`
https://rollupjs.org/guide/en/#error-this-is-undefined
node_modules/@supabase/supabase-js/dist/module/SupabaseClient.js
1: var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
                    ^
2:     function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3:     return new (P || (P = Promise))(function (resolve, reject) {
...and 1 other occurrence
node_modules/@supabase/realtime-js/dist/module/RealtimeClient.js
1: var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
                    ^
2:     function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3:     return new (P || (P = Promise))(function (resolve, reject) {
...and 1 other occurrence
node_modules/@supabase/gotrue-js/dist/module/GoTrueApi.js
1: var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
                    ^
2:     function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3:     return new (P || (P = Promise))(function (resolve, reject) {
...and 1 other occurrence

...and 3 other files
[!] Error: Unexpected token (Note that you need @rollup/plugin-json to import JSON files)
node_modules/websocket/package.json (2:9)
1: {
2:   "_from": "websocket@^1.0.31",
            ^
3:   "_id": "[email protected]",
4:   "_inBundle": false,
Error: Unexpected token (Note that you need @rollup/plugin-json to import JSON files)
    at error (/repos/voboda/fresh-3/node_modules/rollup/dist/shared/rollup.js:4528:30)
    at Module.error (/repos/voboda/fresh-3/node_modules/rollup/dist/shared/rollup.js:9935:16)
    at tryParse (/repos/voboda/fresh-3/node_modules/rollup/dist/shared/rollup.js:9794:23)
    at Module.setSource (/repos/voboda/fresh-3/node_modules/rollup/dist/shared/rollup.js:10242:19)
    at ModuleLoader.addModuleSource (/repos/voboda/fresh-3/node_modules/rollup/dist/shared/rollup.js:18525:20)
    at ModuleLoader.fetchModule (/repos/voboda/fresh-3/node_modules/rollup/dist/shared/rollup.js:18581:9)
    at async Promise.all (index 0)
    at ModuleLoader.fetchStaticDependencies (/repos/voboda/fresh-3/node_modules/rollup/dist/shared/rollup.js:18606:34)
    at async Promise.all (index 0)
    at ModuleLoader.fetchModule (/repos/voboda/fresh-3/node_modules/rollup/dist/shared/rollup.js:18583:9)

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] build: `rollup -c`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

  1. Install the requested rollup plugin per instructions
    npm install @rollup/plugin-json --save-dev
    And modify rollup.config.js accordingly, adding:
import json from '@rollup/plugin-json';

and modifying the plugins section:

...
        plugins: [
                json(),
                svelte({
                        compilerOptions: {

...

And running npm run build again, you should see the following warning:



src/main.js → public/build/bundle.js...
(!) `this` has been rewritten to `undefined`
https://rollupjs.org/guide/en/#error-this-is-undefined
node_modules/@supabase/supabase-js/dist/module/SupabaseClient.js
1: var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
                    ^
2:     function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3:     return new (P || (P = Promise))(function (resolve, reject) {
...and 1 other occurrence
node_modules/@supabase/realtime-js/dist/module/RealtimeClient.js
1: var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
                    ^
2:     function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3:     return new (P || (P = Promise))(function (resolve, reject) {
...and 1 other occurrence
node_modules/@supabase/gotrue-js/dist/module/GoTrueApi.js
1: var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
                    ^
2:     function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3:     return new (P || (P = Promise))(function (resolve, reject) {
...and 1 other occurrence

...and 3 other files
created public/build/bundle.js in 1s

Expected behavior

As a novice developer, it's alarming to see these warnings -- I'm not sure if they're significant.

In a more complex application, these warning messages are repeated many more times, cluttering the output of npm run dev on each rebuild. How can this be resolved so the warnings don't occur?

Notes

Having searched a little, I found some notes referring to this.__awaiter as a Typescript helper for earlier ES versions that don't have async/await. These lines seem to be from the GoTrue packages. Might this have something to do with combining various ES versions in rollup?

I also noticed that I don't get this problem when using snowpack and svelte, so this seems to be isolated to sapper or rollup.

This is getting beyond my level of understanding of JS versions and build tools, but I thought it might be worth reporting here, since Sapper and Supabase are such complimentary combo.

System information

  • Manjaro Linux (Arch-based)
  • Node 15.6.0

package.json:

{
  "name": "svelte-app",
  "version": "1.0.0",
  "scripts": {
    "build": "rollup -c",
    "dev": "rollup -c -w",
    "start": "sirv public"
  },
  "devDependencies": {
    "@rollup/plugin-commonjs": "^17.0.0",
    "@rollup/plugin-json": "^4.1.0",
    "@rollup/plugin-node-resolve": "^11.0.0",
    "rollup": "^2.3.4",
    "rollup-plugin-css-only": "^3.1.0",
    "rollup-plugin-livereload": "^2.0.0",
    "rollup-plugin-svelte": "^7.0.0",
    "rollup-plugin-terser": "^7.0.0",
    "svelte": "^3.0.0"
  },
  "dependencies": {
    "@supabase/supabase-js": "^1.3.2",
    "sirv-cli": "^1.0.0"
  }
}```

Thanks!

createSignedURL returning two properties, broken URL generated

Bug report

Describe the bug

The storage createSignedURL function is returning a result of { signedUrl, signedURL }. The signedUrl should be the one with the full URL to download the file. But on the end of this URL, it has undefined. The signedURL contains the rest of the URL that should be appended to the domain and path in signedUrl.

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository:

  1. call createSignedURL.
  2. Inspect the returned value.

Expected behavior

Only one signedUrl property in the returned object, with the full URL properly present.

Screenshots

The returned value looks like this:

{
  "data": {
    "signedURL": "/object/sign/test/test.png?token=blahblahblah",
    "signedUrl": "https://example.supabase.co/storage/v1undefined",
    "error": null
  }
}

Outdated autogenerated documentation

Hey all, I was trying supabase on a local project and I tried to do the following:

    const response = await supabase.auth.signup({  email,  password })

Which gives the following error:

{"code":400,"msg":"Could not read Signup params: json: cannot unmarshal object into Go struct field SignupParams.email of type string"}

This was on my autogenerated docs under User Management.

Upon digging deeper I realize that the official docs have the right syntax, which is not a function that takes an object but two arguments.

This worked:

    const response = await supabase.auth.signup(email,  password)

Anyway, didn’t know if this was the right place to post this but thought I shared. Also using the opportunity to thank you for such a cool project!

storage.from().list() has limit: 0 by default

Bug report

Describe the bug

storage.from().list() without prefix argument returns empty result. According to types and docs it is optional but it is required in the api. If I use empty string it works as intended.

EDIT: After further inspection I found out that it is not caused by path being empty, but search options contains limit: 0 by default which causes the empty array.

To Reproduce

  1. Create a bucket with some files.
  2. Call: supabase.storage.from("gallery").list()
  3. Supabase returns empty result
  4. Call: supabase.storage.from("gallery").list("", { limit: 10 )
  5. Supabase returns list of all files

Expected behavior

If the list function is called without prefix, it should use "" instead.

System information

  • OS: macOS
  • Version of supabase-js: 1.7.6
  • Version of Node.js: 14.12.0

SupabaseClient returned when `.select()` is not included on query

Bug report

Describe the bug

When I do not include .select('*') on the query the SupabaseClient is returned and the request is not made. The documentation says: "If not used, all columns in the table will be returned." so both should work based on that wording.

With select

  async getAll() {
    const res = await SupabaseService
      .from<InvitationQuestion>('invitation_question')
	  .select('*')
      .eq('wedding_id', this.weddingId)
    return res.body;
  }

res result:
Screen Shot 2020-08-31 at 11 06 19 AM

Without select

  async getAll() {
    const res = await SupabaseService
      .from<InvitationQuestion>('invitation_question')
      .eq('wedding_id', this.weddingId)
    return res.body;
  }

res result:
Screen Shot 2020-08-31 at 11 07 19 AM

  • Version of supabase-js: v0.36.4

supabase-js fails with @sveltejs/kit (warning, sveltejs/kit is experimental)

Bug report

adding

import { createClient } from '@supabase/supabase-js'

into any script tag in a svelte project will cause a 500.

Describe the bug

I believe this has to do with svelte kit renders being executed on both the server side and client side. It also appears to be related to the javascript parser they use (meriyah). Starting the project, and opening a page containing the supabase import results in the following error:

500
[778:36]: Unexpected token: 'get'

SyntaxError: [778:36]: Unexpected token: 'get'
    at report (/home/andrew/Code/development/telebum3/web/node_modules/.pnpm/@sveltejs/[email protected]/node_modules/node_modules/.pnpm/[email protected]/node_modules/meriyah/dist/meriyah.esm.js:182:11)
    at matchOrInsertSemicolon (/home/andrew/Code/development/telebum3/web/node_modules/.pnpm/@sveltejs/[email protected]/node_modules/node_modules/.pnpm/[email protected]/node_modules/meriyah/dist/meriyah.esm.js:2096:9)
    at parseLetIdentOrVarDeclarationStatement (/home/andrew/Code/development/telebum3/web/node_modules/.pnpm/@sveltejs/[email protected]/node_modules/node_modules/.pnpm/[email protected]/node_modules/meriyah/dist/meriyah.esm.js:3024:9)
    at parseStatementListItem (/home/andrew/Code/development/telebum3/web/node_modules/.pnpm/@sveltejs/[email protected]/node_modules/node_modules/.pnpm/[email protected]/node_modules/meriyah/dist/meriyah.esm.js:2595:20)
    at parseBlock (/home/andrew/Code/development/telebum3/web/node_modules/.pnpm/@sveltejs/[email protected]/node_modules/node_modules/.pnpm/[email protected]/node_modules/meriyah/dist/meriyah.esm.js:2692:19)
    at parseTryStatement (/home/andrew/Code/development/telebum3/web/node_modules/.pnpm/@sveltejs/[email protected]/node_modules/node_modules/.pnpm/[email protected]/node_modules/meriyah/dist/meriyah.esm.js:2958:19)
    at parseStatement (/home/andrew/Code/development/telebum3/web/node_modules/.pnpm/@sveltejs/[email protected]/node_modules/node_modules/.pnpm/[email protected]/node_modules/meriyah/dist/meriyah.esm.js:2641:20)
    at parseStatementListItem (/home/andrew/Code/development/telebum3/web/node_modules/.pnpm/@sveltejs/[email protected]/node_modules/node_modules/.pnpm/[email protected]/node_modules/meriyah/dist/meriyah.esm.js:2611:20)
    at parseFunctionBody (/home/andrew/Code/development/telebum3/web/node_modules/.pnpm/@sveltejs/[email protected]/node_modules/node_modules/.pnpm/[email protected]/node_modules/meriyah/dist/meriyah.esm.js:3800:19)
    at parseFunctionExpression (/home/andrew/Code/development/telebum3/web/node_modules/.pnpm/@sveltejs/[email protected]/node_modules/node_modules/.pnpm/[email protected]/node_modules/meriyah/dist/meriyah.esm.js:4389:18)

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository:
repro repo: https://github.com/andykais/supabase-svelte-kit-bug-repro

  1. npm install
  2. npm run dev
  3. Go to http://localhost:3000
  4. See error

Expected behavior

supabase should ideally work in both the client and server environments of svelte kit.

Screenshots

N/A

System information

  • OS: Linux, macOS
  • Browser: Firefox & Chrome
  • Version of supabase-js: 1.0.7
  • Version of Node.js: 14.15.1

Additional context

Note: this is an error that is present in an experimental web framework. It is therefore likely a result of this project not being fully featured. Still, this feels like it is worth tracking.

I attempted dropping the supabase-js built files into the meriyah online compiler to see if the errors were visible there. However it appeared to compile the js code without any issue. There may be specific knobs that svelte kit has tweaked which cause the Unexpected token error, but I am unsure.

Tree shaking

Feature request

Tree-shaking is currently not possible with the supabase-js library because SupabaseClient is implemented using classes. Neither Webpack or Rollup supports tree-shaking class methods.

Is your feature request related to a problem? Please describe.

Supabase bundle size is quite small compared to others (firebase, amplify), but it will only increase as more features are added. Projects that do not use all the features that Supabase provides will regardless pay the cost. Firebase has realized this with their new Modular Javascript SDK.

Describe the solution you'd like

Instead of initializing a single Supabase client, here's a modular API proposal:

// initSupabase.js
const supabaseClient = createClient(supabaseUrl, supabaseKey);
// Does not automatically instantiate RealtimeClient, PostgrestClient, etc.
// Features can be opted in as such:
export const db = getPostgrest(supabaseClient);
export const realtime = getRealtime(supabaseClient);
export const auth = getAuth(supabaseClient);
export const storage = getStorage(supabaseClient);
// some-random-component.js
import { db, realtime } from './initSupabase';

const { data, error } = await db
  .from('cities')
  .select()

const mySubscription = realtime
  .from('*')
  .on('*', payload => {
    console.log('Change received!', payload)
  })
  .subscribe()

While this won't eliminate every piece of unused code, it's a start to enabling opt-in for specific features.

Caveats

  • Will break the current stable API, but can be remedied w/ codemods.
  • Not sure if SupabaseAuthClient can be separated as all other modules rely on that

If this is something you guys think is worth pursuing, I'd be happy to start working on a PR!

error TypeError: Cannot read property 'getItem' of undefined

Bug report

error TypeError: Cannot read property 'getItem' of undefined

Description

When I run Deno JS it gives me this error:
error TypeError: Cannot read property 'getItem' of undefined
at y.getItem (https://unpkg.com/@supabase/[email protected]/dist/umd/supabase.js:1:3822)
at n._recoverSession (https://unpkg.com/@supabase/[email protected]/dist/umd/supabase.js:1:13862)
at new w (https://unpkg.com/@supabase/[email protected]/dist/umd/supabase.js:1:9242)
at new n (https://unpkg.com/@supabase/[email protected]/dist/umd/supabase.js:1:53270)
at t.default._initSupabaseAuthClient (https://unpkg.com/@supabase/[email protected]/dist/umd/supabase.js:1:51187)
at new t.default (https://unpkg.com/@supabase/[email protected]/dist/umd/supabase.js:1:50233)
at Object.t.createClient (https://unpkg.com/@supabase/[email protected]/dist/umd/supabase.js:1:53083)
at file:///C:/Users/server.js:8:30 # replaced my file name
at ()
TypeError: Cannot read property 'getItem' of undefined
at y.getItem (https://unpkg.com/@supabase/[email protected]/dist/umd/supabase.js:1:3822)
at n. (https://unpkg.com/@supabase/[email protected]/dist/umd/supabase.js:1:14223)
at Generator.next ()
at https://unpkg.com/@supabase/[email protected]/dist/umd/supabase.js:1:8543
at new Promise ()
at b (https://unpkg.com/@supabase/[email protected]/dist/umd/supabase.js:1:8288)
at n._recoverAndRefresh (https://unpkg.com/@supabase/[email protected]/dist/umd/supabase.js:1:14147)
at new w (https://unpkg.com/@supabase/[email protected]/dist/umd/supabase.js:1:9265)
at new n (https://unpkg.com/@supabase/[email protected]/dist/umd/supabase.js:1:53270)
at t.default._initSupabaseAuthClient (https://unpkg.com/@supabase/[email protected]/dist/umd/supabase.js:1:51187)
Error getting session from URL.

To Reproduce

  1. Install Deno JS
  2. import "https://unpkg.com/@supabase/supabase-js";
  3. const SERVICE_KEY = 'your-key';
    const SUPABASE_URL = "https://xyz.supabase.co"
  4. deno run --allow-net server.js
  5. See error

Even though it shows an error, everything works well anyway. Is this a warning message then?

Expected behavior

Everything should have worked without errors.

Screenshots

image
image

System information

  • OS: Windows 10
  • Browser: Brave
  • Version of supabase-js: 1.11.9
  • Version of Deno JS: 1.5.3

Program doesn't terminate even after removing subscription

Bug report

Describe the bug

I would expect the program to terminate if there are no open realtime subscriptions.

To Reproduce

const { createClient } = require("@supabase/supabase-js");
const supabase = createClient(process.env.SUPABASE_URL, process.env.supabaseKey);

const res = supabase
  .from("table")
  .on("*", (payload) => {
    console.log("Change received!", payload);
  })
  .subscribe();

setTimeout(() => {
  console.log(1), supabase.removeSubscription(res);
}, 1000);

Expected behavior

I would expect that running this script would exit after the subscription has been removed. Looks like something is still pending in the event loop which prevents the program from exiting?

Additional context

Add any other context about the problem here.

Invalid source map

Bug report

Describe the bug

sources refers to a file that's not in the distribution

{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,MAAM,kBAAkB,CAAA;AAG7C,cAAc,qBAAqB,CAAA;AACnC,cAAc,uBAAuB,CAAA;AAErC;;GAEG;AACH,MAAM,YAAY,GAAG,CACnB,WAAmB,EACnB,WAAmB,EACnB,OAA+B,EAC/B,EAAE;IACF,OAAO,IAAI,cAAc,CAAC,WAAW,EAAE,WAAW,EAAE,OAAO,CAAC,CAAA;AAC9D,CAAC,CAAA;AAED,OAAO,EACL,YAAY,EACZ,cAAc,GAKf,CAAA"}

To Reproduce

npm install --save @supabase/supabase-js
 cat node_modules/@supabase/supabase-js/dist/module/index.js.map 

Expected behavior

I'm not a source map expert, so I'm not quite sure the best way to fix this. I think you'd either want to distribute the source in the npm package or inline it to the sourcemap

Additional context

I don't use Supabase, but work on SvelteKit and users are reporting issues that seem to be caused by trying to load this file that doesn't exist. sveltejs/kit#673 (comment)

Supabase auth interface missing informiation

Bug report

Describe the bug

The Supabase auth object has keys on it like the accessToken, supabaseKey, authUrl, etc. which are missing from the Typescript interface definition: https://github.com/supabase/supabase-js/blob/master/src/index.d.ts#L92

Existing keys:

    signup: (email: string, password: string) => Promise<SupabaseAuthResponse>
    login: (email: string, password: string) => Promise<SupabaseAuthResponse>
    user: () => Promise<SupabaseAuthUser>
    logout: () => Promise<void>

Keys to be added:

	accessToken: string
	authHeader: () => {…}
	authUrl: string
	autoRefreshToken: boolean
	callRefreshToken: () => {…}
	currentUser: SupabaseAuthUser
	persistSession: boolean
	recoverSession: () => {…}
	refreshToken: string
	removeSavedSession: () => {…}
	saveSession: () => {…}
	supabaseKey: string

Return values for supabase.rpc

The docs say the return values of supabase.rpc are { data, error }. But I am getting the return values as { body, status, statusCode, statusText }

// this works
const { body, status, statusCode, statusText } = await supabase.rpc('funcName', params); 

// this doesn't
const { data, error } = await supabase.rpc('funcName', params); 

Should we update the docs? Or we can consider changing the return values to data and error to keep it consistent with the other supabase-js functions.

Call rpc void function returns json parsing error

Bug report

Describe the bug

My store_sentry_event function used to be defined like this:

create or replace function public.store_sentry_event(json_content jsonb)
  returns void security definer
  language sql
as $$
  insert into private.sentry_event (received, content)
  values(transaction_timestamp(), json_content);
$$;

But I noticed that my code that calls that function directly via SupbaseClient.rpc() started failing with error:

Uncaught (in promise) SyntaxError: JSON.parse: unexpected end of data at line 1 column 1 of the JSON data

supabase/supabase#762

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository:

  1. Create a void function
  2. Call void function from supabase client
  3. See Json pasing error

When no `supabaseKey` is passed in it throws an error

Chore

Describe the chore

if createClient is called and the supabaseKey passed in is null or undefined then a non-specfic error thrown. This can happen if you make a call like this:

    return createClient(
      process.env.SUPABASE_URL,
      process.env.SUPABASE_PUBLIC_KEY
    );

and the env variable is empty.

The error is:

TypeError: Cannot read property 'length' of undefined
    at SupabaseClient.initClient (/Users/zlwaterfield/programming/switch-log/node_modules/@supabase/supabase-js/lib/index.js:7:263)
    at SupabaseClient.select (/Users/zlwaterfield/programming/switch-log/node_modules/@supabase/supabase-js/lib/index.js:7:920)
    at CategoryRepository.findByLabel (webpack-internal:///./repositories/CategoryRepository.ts:12:54)
    at LogEntry._findCategory (webpack-internal:///./services/LogEntryService.ts:86:42)
    at LogEntry.timeStart (webpack-internal:///./services/LogEntryService.ts:17:31)
    at __webpack_exports__.default (webpack-internal:///./pages/api/log.ts:11:31)
    at apiResolver (/Users/zlwaterfield/programming/switch-log/node_modules/next/dist/next-server/server/api-utils.js:8:7)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at async DevServer.handleApiRequest (/Users/zlwaterfield/programming/switch-log/node_modules/next/dist/next-server/server/next-server.js:45:397)
    at async Object.fn (/Users/zlwaterfield/programming/switch-log/node_modules/next/dist/next-server/server/next-server.js:37:176)

We should add validation that the supabaseKey is passed in or at least fix this line so the error is better handled.

Uncaught ReferenceError: process is not defined

Bug report

Describe the bug

Using Angular, creating the client produce this error on the console: Uncaught ReferenceError: process is not defined

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository:

  1. Create Angular project
  2. Install supabase-js
  3. Create angular service
  4. Import createClient with supabase-js on top of the newly created service
  5. Add that on top of the file, after the import const supabase = createClient('yoururl', 'yourkey')
  6. Link service to component
  7. See result in console

Expected behavior

No errors should happen

System information

  • OS: MacOS Big Sur
  • Browser (if applies) Firefox
  • Version of supabase-js: v1.1.3
  • Version of Node.js: v12.18.3

Export types for use by downstream librarys

Feature request

Is your feature request related to a problem? Please describe.

Yes. Because the supabase-js does not export all types from the gotrue-js nor realtime-js libraries, client side developers cannot fully type their projects.

For example, you cannot do the following without these additional exports:

const subscriptionRef = useRef<null | RealtimeSubscription>(null)

or

.on('*', (payload: SupabaseRealtimePayload<Todos>) => {

or

const [supabase, setSupabase] = useState<undefined | SupabaseClient>()

Describe the solution you'd like

Export additional types for client side use

Describe alternatives you've considered

None

Additional context

Related: supabase/auth-js#28.

Row level query subscription not listening to deletes.

Bug report

Describe the bug

Realtime subscription of row level query is not able to listen to changes of type delete

To Reproduce

Here is a snippet of my code:

supabase.from(`posts:author=eq.${user.id}`)
        .on('*', (payload) => {
          console.log('changes: ', payload)
          fetchNewPosts();
        })
        .subscribe()

Expected behavior

It should be able to listen to all types of changes. But it only works for INSERT and UPDATE.

Screenshots

None.

System information

  • OS: Windows
  • Browser: chrome
  • Version of supabase-js: 1.2.1
  • Version of Node.js: v15..0.1

Additional context

None.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.