From 5d0b59f8bd1bd2937365036f5e2abccfcb96ed2a Mon Sep 17 00:00:00 2001 From: Nancy <9d.24.nancy.sangani@gmail.com> Date: Mon, 13 Apr 2026 18:06:33 +0530 Subject: [PATCH 1/3] fix: append | null to composite type attributes in TypeScript generator --- src/server/templates/typescript.ts | 17 +++++++---------- test/db/00-init.sql | 8 +++++++- test/server/typegen.ts | 16 ++++++++++++++++ 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/server/templates/typescript.ts b/src/server/templates/typescript.ts index 352c4ddc..2913c54b 100644 --- a/src/server/templates/typescript.ts +++ b/src/server/templates/typescript.ts @@ -719,17 +719,14 @@ export type Database = { const type = typesById.get(type_id) let tsType = 'unknown' if (type) { - tsType = `${generateNullableUnionTsType( - pgTypeToTsType(schema, type.name, { - types, - schemas, - tables, - views, - }), - true - )}` + tsType = pgTypeToTsType(schema, type.name, { + types, + schemas, + tables, + views, + }) } - return `${JSON.stringify(name)}: ${tsType}` + return `${JSON.stringify(name)}: ${tsType} | null` })} }` ) diff --git a/test/db/00-init.sql b/test/db/00-init.sql index c30e1f4a..0b3456dc 100644 --- a/test/db/00-init.sql +++ b/test/db/00-init.sql @@ -500,4 +500,10 @@ LANGUAGE SQL STABLE AS $$ SELECT interval_test_row.duration_required * 2; -$$; \ No newline at end of file +$$; + +CREATE DOMAIN one_to_ten AS int CHECK (VALUE >= 1 AND VALUE <= 10); +CREATE TYPE composite_type_with_domain_attribute AS ( + name text, + score one_to_ten +); \ No newline at end of file diff --git a/test/server/typegen.ts b/test/server/typegen.ts index 50a0896b..96af5d0a 100644 --- a/test/server/typegen.ts +++ b/test/server/typegen.ts @@ -1060,6 +1060,10 @@ test('typegen: typescript', async () => { composite_type_with_array_attribute: { my_text_array: string[] | null } + composite_type_with_domain_attribute: { + name: string | null + score: unknown | null + } composite_type_with_record_attribute: { todo: Database["public"]["Tables"]["todos"]["Row"] | null } @@ -2285,6 +2289,10 @@ test('typegen w/ one-to-one relationships', async () => { composite_type_with_array_attribute: { my_text_array: string[] | null } + composite_type_with_domain_attribute: { + name: string | null + score: unknown | null + } composite_type_with_record_attribute: { todo: Database["public"]["Tables"]["todos"]["Row"] | null } @@ -3510,6 +3518,10 @@ test('typegen: typescript w/ one-to-one relationships', async () => { composite_type_with_array_attribute: { my_text_array: string[] | null } + composite_type_with_domain_attribute: { + name: string | null + score: unknown | null + } composite_type_with_record_attribute: { todo: Database["public"]["Tables"]["todos"]["Row"] | null } @@ -4740,6 +4752,10 @@ test('typegen: typescript w/ postgrestVersion', async () => { composite_type_with_array_attribute: { my_text_array: string[] | null } + composite_type_with_domain_attribute: { + name: string | null + score: unknown | null + } composite_type_with_record_attribute: { todo: Database["public"]["Tables"]["todos"]["Row"] | null } From 09985f36ece9cbf534b85e08e9014434a2773f47 Mon Sep 17 00:00:00 2001 From: Nancy <9d.24.nancy.sangani@gmail.com> Date: Mon, 13 Apr 2026 18:45:17 +0530 Subject: [PATCH 2/3] test: add composite_type_with_int_attribute and update typegen test snapshots --- test/db/00-init.sql | 10 ++++++++-- test/server/typegen.ts | 45 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/test/db/00-init.sql b/test/db/00-init.sql index 0b3456dc..2bb808f5 100644 --- a/test/db/00-init.sql +++ b/test/db/00-init.sql @@ -502,8 +502,14 @@ AS $$ SELECT interval_test_row.duration_required * 2; $$; -CREATE DOMAIN one_to_ten AS int CHECK (VALUE >= 1 AND VALUE <= 10); +CREATE DOMAIN public.one_to_ten AS int CHECK (VALUE >= 1 AND VALUE <= 10); + CREATE TYPE composite_type_with_domain_attribute AS ( name text, - score one_to_ten + score public.one_to_ten +); + +CREATE TYPE composite_type_with_int_attribute AS ( + a int, + b int ); \ No newline at end of file diff --git a/test/server/typegen.ts b/test/server/typegen.ts index 96af5d0a..6bb8a969 100644 --- a/test/server/typegen.ts +++ b/test/server/typegen.ts @@ -1064,6 +1064,10 @@ test('typegen: typescript', async () => { name: string | null score: unknown | null } + composite_type_with_int_attribute: { + a: number | null + b: number | null + } composite_type_with_record_attribute: { todo: Database["public"]["Tables"]["todos"]["Row"] | null } @@ -2293,6 +2297,10 @@ test('typegen w/ one-to-one relationships', async () => { name: string | null score: unknown | null } + composite_type_with_int_attribute: { + a: number | null + b: number | null + } composite_type_with_record_attribute: { todo: Database["public"]["Tables"]["todos"]["Row"] | null } @@ -3522,6 +3530,10 @@ test('typegen: typescript w/ one-to-one relationships', async () => { name: string | null score: unknown | null } + composite_type_with_int_attribute: { + a: number | null + b: number | null + } composite_type_with_record_attribute: { todo: Database["public"]["Tables"]["todos"]["Row"] | null } @@ -4756,6 +4768,10 @@ test('typegen: typescript w/ postgrestVersion', async () => { name: string | null score: unknown | null } + composite_type_with_int_attribute: { + a: number | null + b: number | null + } composite_type_with_record_attribute: { todo: Database["public"]["Tables"]["todos"]["Row"] | null } @@ -5572,6 +5588,11 @@ test('typegen: go', async () => { type PublicCompositeTypeWithRecordAttribute struct { Todo interface{} \`json:"todo"\` + } + + type PublicCompositeTypeWithDomainAttribute struct { + Name string \`json:"name"\` + Score interface{} \`json:"score"\` }" `) }) @@ -6093,6 +6114,14 @@ test('typegen: swift', async () => { case MyTextArray = "my_text_array" } } + internal struct CompositeTypeWithDomainAttribute: Codable, Hashable, Sendable { + internal let Name: String + internal let Score: OneToTenSelect + internal enum CodingKeys: String, CodingKey { + case Name = "name" + case Score = "score" + } + } internal struct CompositeTypeWithRecordAttribute: Codable, Hashable, Sendable { internal let Todo: TodosSelect internal enum CodingKeys: String, CodingKey { @@ -6624,6 +6653,14 @@ test('typegen: swift w/ public access control', async () => { case MyTextArray = "my_text_array" } } + public struct CompositeTypeWithDomainAttribute: Codable, Hashable, Sendable { + public let Name: String + public let Score: OneToTenSelect + public enum CodingKeys: String, CodingKey { + case Name = "name" + case Score = "score" + } + } public struct CompositeTypeWithRecordAttribute: Codable, Hashable, Sendable { public let Todo: TodosSelect public enum CodingKeys: String, CodingKey { @@ -6662,6 +6699,8 @@ test('typegen: python', async () => { PublicMemeStatus: TypeAlias = Literal["new", "old", "retired"] + PublicOneToTen: TypeAlias = int + class PublicUsers(BaseModel): decimal: Optional[float] = Field(alias="decimal") id: int = Field(alias="id") @@ -6903,7 +6942,11 @@ test('typegen: python', async () => { my_text_array: List[str] = Field(alias="my_text_array") class PublicCompositeTypeWithRecordAttribute(BaseModel): - todo: PublicTodos = Field(alias="todo")" + todo: PublicTodos = Field(alias="todo") + + class PublicCompositeTypeWithDomainAttribute(BaseModel): + name: str = Field(alias="name") + score: PublicOneToTen = Field(alias="score")" `) }) From afd8760bc7e316140ca420fcbe0d852be8ecd66a Mon Sep 17 00:00:00 2001 From: Nancy <9d.24.nancy.sangani@gmail.com> Date: Mon, 13 Apr 2026 19:24:56 +0530 Subject: [PATCH 3/3] test: add composite_type_with_int_attribute and update typegen test snapshots --- src/server/templates/python.ts | 15 +++++++++++++++ test/server/typegen.ts | 29 ++++++++++++++++++++++++++--- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/server/templates/python.ts b/src/server/templates/python.ts index 0d00f475..bffbeb28 100644 --- a/src/server/templates/python.ts +++ b/src/server/templates/python.ts @@ -198,6 +198,20 @@ class PythonEnum implements Serializable { } } +class PythonDomain implements Serializable { + name: string + py_type: PythonType + + constructor(name: string, schema: string, py_type: PythonType) { + this.name = `${formatForPyClassName(schema)}${formatForPyClassName(name)}` + this.py_type = py_type + } + + serialize(): string { + return `${this.name}: TypeAlias = ${this.py_type.serialize()}` + } +} + type PythonType = PythonListType | PythonSimpleType class PythonSimpleType implements Serializable { @@ -327,6 +341,7 @@ const PY_TYPE_MAP: Record = { bool: 'bool', // Numbers + int: 'int', int2: 'int', int4: 'int', int8: 'int', diff --git a/test/server/typegen.ts b/test/server/typegen.ts index 6bb8a969..31158226 100644 --- a/test/server/typegen.ts +++ b/test/server/typegen.ts @@ -5593,6 +5593,11 @@ test('typegen: go', async () => { type PublicCompositeTypeWithDomainAttribute struct { Name string \`json:"name"\` Score interface{} \`json:"score"\` + } + + type PublicCompositeTypeWithIntAttribute struct { + A interface{} \`json:"a"\` + B interface{} \`json:"b"\` }" `) }) @@ -6122,6 +6127,14 @@ test('typegen: swift', async () => { case Score = "score" } } + internal struct CompositeTypeWithIntAttribute: Codable, Hashable, Sendable { + internal let A: AnyJSON + internal let B: AnyJSON + internal enum CodingKeys: String, CodingKey { + case A = "a" + case B = "b" + } + } internal struct CompositeTypeWithRecordAttribute: Codable, Hashable, Sendable { internal let Todo: TodosSelect internal enum CodingKeys: String, CodingKey { @@ -6661,6 +6674,14 @@ test('typegen: swift w/ public access control', async () => { case Score = "score" } } + public struct CompositeTypeWithIntAttribute: Codable, Hashable, Sendable { + public let A: AnyJSON + public let B: AnyJSON + public enum CodingKeys: String, CodingKey { + case A = "a" + case B = "b" + } + } public struct CompositeTypeWithRecordAttribute: Codable, Hashable, Sendable { public let Todo: TodosSelect public enum CodingKeys: String, CodingKey { @@ -6699,8 +6720,6 @@ test('typegen: python', async () => { PublicMemeStatus: TypeAlias = Literal["new", "old", "retired"] - PublicOneToTen: TypeAlias = int - class PublicUsers(BaseModel): decimal: Optional[float] = Field(alias="decimal") id: int = Field(alias="id") @@ -6946,7 +6965,11 @@ test('typegen: python', async () => { class PublicCompositeTypeWithDomainAttribute(BaseModel): name: str = Field(alias="name") - score: PublicOneToTen = Field(alias="score")" + score: PublicOneToTen = Field(alias="score") + + class PublicCompositeTypeWithIntAttribute(BaseModel): + a: int = Field(alias="a") + b: int = Field(alias="b")" `) })