Skip to content
1 change: 1 addition & 0 deletions src/server/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export const GENERATE_TYPES_DEFAULT_SCHEMA =
process.env.PG_META_GENERATE_TYPES_DEFAULT_SCHEMA || 'public'
export const GENERATE_TYPES_DETECT_ONE_TO_ONE_RELATIONSHIPS =
process.env.PG_META_GENERATE_TYPES_DETECT_ONE_TO_ONE_RELATIONSHIPS === 'true'
export const POSTGREST_VERSION = process.env.PG_META_POSTGREST_VERSION
export const GENERATE_TYPES_SWIFT_ACCESS_CONTROL = process.env
.PG_META_GENERATE_TYPES_SWIFT_ACCESS_CONTROL
? (process.env.PG_META_GENERATE_TYPES_SWIFT_ACCESS_CONTROL as AccessControl)
Expand Down
3 changes: 3 additions & 0 deletions src/server/routes/generators/typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export default async (fastify: FastifyInstance) => {
excluded_schemas?: string
included_schemas?: string
detect_one_to_one_relationships?: string
postgrest_version?: string
}
}>('/', async (request, reply) => {
const config = createConnectionConfig(request)
Expand All @@ -19,6 +20,7 @@ export default async (fastify: FastifyInstance) => {
const includedSchemas =
request.query.included_schemas?.split(',').map((schema) => schema.trim()) ?? []
const detectOneToOneRelationships = request.query.detect_one_to_one_relationships === 'true'
const postgrestVersion = request.query.postgrest_version

const pgMeta: PostgresMeta = new PostgresMeta(config)
const { data: generatorMeta, error: generatorMetaError } = await getGeneratorMetadata(pgMeta, {
Expand All @@ -34,6 +36,7 @@ export default async (fastify: FastifyInstance) => {
return applyTypescriptTemplate({
...generatorMeta,
detectOneToOneRelationships,
postgrestVersion,
})
})
}
2 changes: 2 additions & 0 deletions src/server/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
PG_CONNECTION,
PG_META_HOST,
PG_META_PORT,
POSTGREST_VERSION,
} from './constants.js'
import { apply as applyTypescriptTemplate } from './templates/typescript.js'
import { apply as applyGoTemplate } from './templates/go.js'
Expand Down Expand Up @@ -129,6 +130,7 @@ async function getTypeOutput(): Promise<string | null> {
),
types: types!,
detectOneToOneRelationships: GENERATE_TYPES_DETECT_ONE_TO_ONE_RELATIONSHIPS,
postgrestVersion: POSTGREST_VERSION,
}

switch (GENERATE_TYPES?.toLowerCase()) {
Expand Down
121 changes: 66 additions & 55 deletions src/server/templates/typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ export const apply = async ({
functions,
types,
detectOneToOneRelationships,
postgrestVersion,
}: GeneratorMetadata & {
detectOneToOneRelationships: boolean
postgrestVersion?: string
}): Promise<string> => {
const columnsByTableId = Object.fromEntries<PostgresColumn[]>(
[...tables, ...foreignTables, ...views, ...materializedViews].map((t) => [t.id, []])
Expand All @@ -32,10 +34,19 @@ export const apply = async ({
.sort(({ name: a }, { name: b }) => a.localeCompare(b))
.forEach((c) => columnsByTableId[c.table_id].push(c))

const internal_supabase_schema = postgrestVersion
? `// Allows to automatically instanciate createClient with right options
// instead of createClient<Database, { PostgrestVersion: 'XX' }>(URL, KEY)
__InternalSupabase: {
PostgrestVersion: '${postgrestVersion}'
}`
: ''

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

export type Database = {
${internal_supabase_schema}
${schemas
.sort(({ name: a }, { name: b }) => a.localeCompare(b))
.map((schema) => {
Expand Down Expand Up @@ -433,110 +444,110 @@ export type Database = {
})}
}

type DefaultSchema = Database[Extract<keyof Database, ${JSON.stringify(GENERATE_TYPES_DEFAULT_SCHEMA)}>]
type DatabaseWithoutInternals = Omit<Database, '__InternalSupabase'>

type DefaultSchema = DatabaseWithoutInternals[Extract<keyof Database, ${JSON.stringify(GENERATE_TYPES_DEFAULT_SCHEMA)}>]

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

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

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

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

export type CompositeTypes<
PublicCompositeTypeNameOrOptions extends
| keyof DefaultSchema["CompositeTypes"]
| { schema: keyof Database },
| { schema: keyof DatabaseWithoutInternals },
CompositeTypeName extends PublicCompositeTypeNameOrOptions extends {
schema: keyof Database
schema: keyof DatabaseWithoutInternals
}
? keyof Database[PublicCompositeTypeNameOrOptions["schema"]]["CompositeTypes"]
: never = never,
> = PublicCompositeTypeNameOrOptions extends { schema: keyof Database }
? Database[PublicCompositeTypeNameOrOptions["schema"]]["CompositeTypes"][CompositeTypeName]
? keyof DatabaseWithoutInternals[PublicCompositeTypeNameOrOptions["schema"]]["CompositeTypes"]
: never = never
> = PublicCompositeTypeNameOrOptions extends { schema: keyof DatabaseWithoutInternals }
? DatabaseWithoutInternals[PublicCompositeTypeNameOrOptions["schema"]]["CompositeTypes"][CompositeTypeName]
: PublicCompositeTypeNameOrOptions extends keyof DefaultSchema["CompositeTypes"]
? DefaultSchema["CompositeTypes"][PublicCompositeTypeNameOrOptions]
: never
? DefaultSchema["CompositeTypes"][PublicCompositeTypeNameOrOptions]
: never

export const Constants = {
${schemas
Expand Down
Loading