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

Generate types for views as well #385

Closed
enyo opened this issue Aug 18, 2022 · 16 comments · Fixed by #427
Closed

Generate types for views as well #385

enyo opened this issue Aug 18, 2022 · 16 comments · Fixed by #427
Labels
enhancement New feature or request

Comments

@enyo
Copy link

enyo commented Aug 18, 2022

When running supabase gen types typescript only types for tables are generated. This makes it difficult to select data from views.

@enyo enyo added the enhancement New feature or request label Aug 18, 2022
@enyo
Copy link
Author

enyo commented Aug 18, 2022

As a workaround this works well for now:

interface DatabaseWithViews extends Database {
  public: Database['public'] & {
    Tables: Database['public']['Tables'] & {
      my_view_name: {
        Row: {
          view_column: string
          // etc...
        }
      }
    }
  }
}

const supabase = createClient<DatabaseWithViews>(url, anonKey);

EDIT: actually, strike that. I don't know why, but extending the interface doesn't work. It always returns any

@soedirgo
Copy link
Member

It's not feasible to generate types for views since view definitions are dynamic - e.g. we don't know the column information for a view, since columns are tied to tables, not views.

I'll see if I can extend supabase-js to allow you to add additional Tables in the near future.

@enyo
Copy link
Author

enyo commented Aug 23, 2022

Excellent @soedirgo . I think it's fine if they need to be added manually, but atm I don't think it's possible? I don't understand why extending the Database the way I did in my previous post didn't work.

@soedirgo
Copy link
Member

soedirgo commented Aug 24, 2022

I think I figured it out - can you do this instead?

import { Database } from './types'

type DatabaseWithViews = Database & {
  public: {
    Tables: {
      my_view_name: {
        Row: { ... }
        ...
      }
    }
  }
}

I don't think it's necessary to modify supabase-js to support this after all, though we should document this in our docs.

@profiluefter
Copy link

profiluefter commented Aug 24, 2022

PostgREST successfully generates types for views in the OpenAPI endpoint (http://localhost:54321/rest/v1/?apikey=). Can't this be used?

I haven't looked at the code but would have expected that this OpenAPI definition would be used for generating the TypeScript types. Given that there's already the requirement that a supabase instance has to be running it should be possible to use the OpenAPI information for views.

In my current situation (not yet upgraded to V2) it makes more sense to just use any OpenAPI generator.

@soedirgo
Copy link
Member

It doesn't seem to be perfect - e.g. if I create a view with a column now() as now_col, the OpenAPI description will say you can insert and supply the now_col, but it'll return an error if you actually do that. Also, it doesn't take into account table fields that must not be supplied, e.g. for generated columns.

But the choice to use a separate tool (supabase/postgres-meta) is because of development velocity - it's much faster to release a fix on postgres-meta & update the image version in the CLI, than it is to release a fix on PostgREST and wait for it to be deployed on the hosted platform.

@enyo
Copy link
Author

enyo commented Aug 28, 2022

I think I figured it out - can you do this instead?

import { Database } from './types'

type DatabaseWithViews = Database & {
[...]

I didn't get this to work. It's the same issue as with my attempt of extending the interface. When I use this type, all the type inference breaks. The data objects returned by the supabase calls are any.

@soedirgo
Copy link
Member

Needs support from the postgrest-js side for views - will loop back here once that's updated

@soedirgo
Copy link
Member

soedirgo commented Sep 6, 2022

postgrest-js has been updated to support views.

@enyo
Copy link
Author

enyo commented Sep 6, 2022

@soedirgo so does this mean that views are now included in the generated output, or that creating this union type now works?

@soedirgo
Copy link
Member

soedirgo commented Sep 6, 2022

Views are now included in the generated types. I believe you need CLI v1.3.0+ and postgrest-js@2.0.0-rc.5+ for it (npm update @supabase/postgrest-js should do it).

@enyo
Copy link
Author

enyo commented Sep 9, 2022

Very cool. Just in case anybody else was looking for this: I needed to restart supabase locally for this to work. Simply upgrading the cli wasn't enough.

@enyo
Copy link
Author

enyo commented Sep 21, 2022

@soedirgo at the moment, all fields in views are type | null. Is there anything we can do to avoid all fields being nullable?

@soedirgo
Copy link
Member

I don't think so - this is a limitation on the Postgres side, it doesn't store column nullability accurately for views. I believe you get the same thing from PostgREST's OpenAPI.

@profiluefter
Copy link

It's possible to manually set the nullability for views to make the generated types work. This, however, doesn't check if what you're doing is actually correct so make sure that the columns you are setting to not null are actually definitely not null.

I don't know if there are other implications of changing these values so make sure you understand it better than I do before using this in an important project.

UPDATE pg_catalog.pg_attribute
SET attnotnull = TRUE
WHERE (attrelid, attname) IN
      (('view_name'::regclass, 'column_1'),
       ('view_name'::regclass, 'column_2'),
       ('view_name'::regclass, 'column_3'));

@soedirgo
Copy link
Member

@profiluefter Thanks! We actually implicitly assume view columns are nullable in the typegen, so that needs to be updated as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants