Skip to content

Hardcoded metadata resulting in broken TypeScript type generation from the Supabase CLI #716

Closed
@yingw787

Description

@yingw787

Bug report

  • I confirm this is a bug with Supabase, not with my own application.
  • I confirm I have searched the Docs, GitHub Discussions, and Discord.

Describe the bug

For differing PostgreSQL schemas outside of schema public, the hardcoded Postgres metadata for schema public does not work, and creates a TypeScript type error.

To Reproduce

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

  1. Install Supabase v1.144.7 in a TypeScript repository.
  2. Create a PostgreSQL schema:
--- Create a new schema named `openai`.
CREATE SCHEMA openai;

--- Set the search path to include the new schema.
SET
  search_path TO openai,
  public;

-- Grant privileges to all tables for various Supabase roles so that the
-- Supabase client instantiated with the public Supabase access token can fetch
-- data, and RLS policies are still enforced per user.
GRANT USAGE ON SCHEMA openai TO postgres,
anon,
authenticated,
service_role,
dashboard_user;

ALTER DEFAULT PRIVILEGES IN SCHEMA openai
GRANT ALL ON TABLES TO postgres,
anon,
authenticated,
service_role,
dashboard_user;

COMMENT ON SCHEMA openai IS 'Schema for storing third-party API calls with OpenAI. This is important for e.g. archiving full conversation messages with OpenAI, which does not have an interface for exporting this information yet since the assistants functionality came out in beta a few days ago as of 11/08/2023.'
  1. Start Supabase using npx supabase start
  2. Reset the Supabase database using npx supabase db reset
  3. Generate the TypeScript types using command or similar: npx supabase gen types typescript --local --schema openai > src/types/supabase-schema-openai-types.ts

Expected behavior

A TypeScript file describing all of the tables, enums, and otherwise TypeScript-migrated models that I can use in a TypeScript project.

However, instead I am receiving this result:

export type Json =
  | string
  | number
  | boolean
  | null
  | { [key: string]: Json | undefined }
  | Json[]

export interface Database {
  openai: {
    Tables: {
      assistants: {
        Row: {
          assistant_id: string | null
          checksum: string | null
          created_at: string
          file_ids: Json | null
          id: number
          model: string | null
          name: string | null
          prompt: string | null
          raw_json_response: Json
          tools: Json | null
          updated_at: string
        }
        Insert: {
          assistant_id?: string | null
          checksum?: string | null
          created_at?: string
          file_ids?: Json | null
          id?: never
          model?: string | null
          name?: string | null
          prompt?: string | null
          raw_json_response: Json
          tools?: Json | null
          updated_at?: string
        }
        Update: {
          assistant_id?: string | null
          checksum?: string | null
          created_at?: string
          file_ids?: Json | null
          id?: never
          model?: string | null
          name?: string | null
          prompt?: string | null
          raw_json_response?: Json
          tools?: Json | null
          updated_at?: string
        }
        Relationships: []
      }
      messages: {
        Row: {
          assistant_id: string | null
          checksum: string | null
          created_at: string
          id: number
          message_id: string | null
          openai_created_at: number | null
          raw_json_response: Json
          role: string | null
          run_id: string | null
          thread_id: string | null
          updated_at: string
        }
        Insert: {
          assistant_id?: string | null
          checksum?: string | null
          created_at?: string
          id?: never
          message_id?: string | null
          openai_created_at?: number | null
          raw_json_response: Json
          role?: string | null
          run_id?: string | null
          thread_id?: string | null
          updated_at?: string
        }
        Update: {
          assistant_id?: string | null
          checksum?: string | null
          created_at?: string
          id?: never
          message_id?: string | null
          openai_created_at?: number | null
          raw_json_response?: Json
          role?: string | null
          run_id?: string | null
          thread_id?: string | null
          updated_at?: string
        }
        Relationships: []
      }
      runs: {
        Row: {
          assistant_id: string | null
          checksum: string | null
          created_at: string
          file_ids: Json | null
          id: number
          model: string | null
          raw_json_response: Json
          run_id: string | null
          status: string | null
          thread_id: string | null
          tools: Json | null
          updated_at: string
        }
        Insert: {
          assistant_id?: string | null
          checksum?: string | null
          created_at?: string
          file_ids?: Json | null
          id?: never
          model?: string | null
          raw_json_response: Json
          run_id?: string | null
          status?: string | null
          thread_id?: string | null
          tools?: Json | null
          updated_at?: string
        }
        Update: {
          assistant_id?: string | null
          checksum?: string | null
          created_at?: string
          file_ids?: Json | null
          id?: never
          model?: string | null
          raw_json_response?: Json
          run_id?: string | null
          status?: string | null
          thread_id?: string | null
          tools?: Json | null
          updated_at?: string
        }
        Relationships: []
      }
      threads: {
        Row: {
          checksum: string | null
          created_at: string
          deleted: boolean | null
          id: number
          raw_json_response: Json
          thread_id: string | null
          updated_at: string
        }
        Insert: {
          checksum?: string | null
          created_at?: string
          deleted?: boolean | null
          id?: never
          raw_json_response: Json
          thread_id?: string | null
          updated_at?: string
        }
        Update: {
          checksum?: string | null
          created_at?: string
          deleted?: boolean | null
          id?: never
          raw_json_response?: Json
          thread_id?: string | null
          updated_at?: string
        }
        Relationships: []
      }
    }
    Views: {
      [_ in never]: never
    }
    Functions: {
      [_ in never]: never
    }
    Enums: {
      [_ in never]: never
    }
    CompositeTypes: {
      [_ in never]: never
    }
  }
}

export type Tables<
  PublicTableNameOrOptions extends
    | keyof (Database["public"]["Tables"] & Database["public"]["Views"])
    | { schema: keyof Database },
  TableName extends PublicTableNameOrOptions extends { schema: keyof Database }
    ? keyof (Database[PublicTableNameOrOptions["schema"]]["Tables"] &
        Database[PublicTableNameOrOptions["schema"]]["Views"])
    : never = never
> = PublicTableNameOrOptions extends { schema: keyof Database }
  ? (Database[PublicTableNameOrOptions["schema"]]["Tables"] &
      Database[PublicTableNameOrOptions["schema"]]["Views"])[TableName] extends {
      Row: infer R
    }
    ? R
    : never
  : PublicTableNameOrOptions extends keyof (Database["public"]["Tables"] &
      Database["public"]["Views"])
  ? (Database["public"]["Tables"] &
      Database["public"]["Views"])[PublicTableNameOrOptions] extends {
      Row: infer R
    }
    ? R
    : never
  : never

export type TablesInsert<
  PublicTableNameOrOptions extends
    | keyof Database["public"]["Tables"]
    | { schema: keyof Database },
  TableName extends PublicTableNameOrOptions extends { schema: keyof Database }
    ? keyof Database[PublicTableNameOrOptions["schema"]]["Tables"]
    : never = never
> = PublicTableNameOrOptions extends { schema: keyof Database }
  ? Database[PublicTableNameOrOptions["schema"]]["Tables"][TableName] extends {
      Insert: infer I
    }
    ? I
    : never
  : PublicTableNameOrOptions extends keyof Database["public"]["Tables"]
  ? Database["public"]["Tables"][PublicTableNameOrOptions] extends {
      Insert: infer I
    }
    ? I
    : never
  : never

export type TablesUpdate<
  PublicTableNameOrOptions extends
    | keyof Database["public"]["Tables"]
    | { schema: keyof Database },
  TableName extends PublicTableNameOrOptions extends { schema: keyof Database }
    ? keyof Database[PublicTableNameOrOptions["schema"]]["Tables"]
    : never = never
> = PublicTableNameOrOptions extends { schema: keyof Database }
  ? Database[PublicTableNameOrOptions["schema"]]["Tables"][TableName] extends {
      Update: infer U
    }
    ? U
    : never
  : PublicTableNameOrOptions extends keyof Database["public"]["Tables"]
  ? Database["public"]["Tables"][PublicTableNameOrOptions] extends {
      Update: infer U
    }
    ? U
    : never
  : never

export type Enums<
  PublicEnumNameOrOptions extends
    | keyof Database["public"]["Enums"]
    | { schema: keyof Database },
  EnumName extends PublicEnumNameOrOptions extends { schema: keyof Database }
    ? keyof Database[PublicEnumNameOrOptions["schema"]]["Enums"]
    : never = never
> = PublicEnumNameOrOptions extends { schema: keyof Database }
  ? Database[PublicEnumNameOrOptions["schema"]]["Enums"][EnumName]
  : PublicEnumNameOrOptions extends keyof Database["public"]["Enums"]
  ? Database["public"]["Enums"][PublicEnumNameOrOptions]
  : never

Screenshots

N/A

System information

  • OS: Ubuntu 22.04.3 LTS
  • Browser: N/A, running from terminal
  • Version of supabase-js: 2.38.4
  • Version of Node.js: 21.5.0

Additional context

Described issue to Supabase support and they confirmed it's an issue with the metadata. Happy to take a shot at updating this and learning to become a contributor.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions