@@ -66,6 +66,55 @@ function enumTypeDecl(name: string, enumDef: Enum): Node {
6666 ) ;
6767}
6868
69+ function jsonTypeDecls ( ) : Node [ ] {
70+ return [
71+ factory . createTypeAliasDeclaration (
72+ [ factory . createToken ( SyntaxKind . ExportKeyword ) ] ,
73+ factory . createIdentifier ( "JsonPrimitive" ) ,
74+ undefined ,
75+ factory . createUnionTypeNode ( [
76+ factory . createKeywordTypeNode ( SyntaxKind . StringKeyword ) ,
77+ factory . createKeywordTypeNode ( SyntaxKind . NumberKeyword ) ,
78+ factory . createKeywordTypeNode ( SyntaxKind . BooleanKeyword ) ,
79+ factory . createLiteralTypeNode ( factory . createNull ( ) ) ,
80+ ] ) ,
81+ ) ,
82+ factory . createTypeAliasDeclaration (
83+ [ factory . createToken ( SyntaxKind . ExportKeyword ) ] ,
84+ factory . createIdentifier ( "JsonValue" ) ,
85+ undefined ,
86+ factory . createUnionTypeNode ( [
87+ factory . createTypeReferenceNode ( factory . createIdentifier ( "JsonPrimitive" ) , undefined ) ,
88+ factory . createTypeOperatorNode (
89+ SyntaxKind . ReadonlyKeyword ,
90+ factory . createArrayTypeNode (
91+ factory . createTypeReferenceNode ( factory . createIdentifier ( "JsonValue" ) , undefined ) ,
92+ ) ,
93+ ) ,
94+ factory . createTypeLiteralNode ( [
95+ factory . createIndexSignature (
96+ [ factory . createToken ( SyntaxKind . ReadonlyKeyword ) ] ,
97+ [
98+ factory . createParameterDeclaration (
99+ undefined ,
100+ undefined ,
101+ factory . createIdentifier ( "key" ) ,
102+ undefined ,
103+ factory . createKeywordTypeNode ( SyntaxKind . StringKeyword ) ,
104+ undefined ,
105+ ) ,
106+ ] ,
107+ factory . createUnionTypeNode ( [
108+ factory . createTypeReferenceNode ( factory . createIdentifier ( "JsonValue" ) , undefined ) ,
109+ factory . createKeywordTypeNode ( SyntaxKind . UndefinedKeyword ) ,
110+ ] ) ,
111+ ) ,
112+ ] ) ,
113+ ] ) ,
114+ ) ,
115+ ] ;
116+ }
117+
69118/**
70119 * Convert snake_case to PascalCase
71120 */
@@ -101,6 +150,7 @@ function codegen(input: GenerateRequest): GenerateResponse {
101150
102151 // Track enums used in this file
103152 const fileEnums = new Set < string > ( ) ;
153+ let fileUsesJson = false ;
104154
105155 for ( const query of queries ) {
106156 const lowerName = query . name [ 0 ] . toLowerCase ( ) + query . name . slice ( 1 ) ;
@@ -125,6 +175,9 @@ function codegen(input: GenerateRequest): GenerateResponse {
125175 fileEnums . add ( enumName ) ;
126176 usedEnums . add ( enumName ) ;
127177 }
178+ if ( postgres . isJsonColumn ( param . column ) ) {
179+ fileUsesJson = true ;
180+ }
128181 }
129182
130183 try {
@@ -168,6 +221,9 @@ function codegen(input: GenerateRequest): GenerateResponse {
168221 fileEnums . add ( enumName ) ;
169222 usedEnums . add ( enumName ) ;
170223 }
224+ if ( postgres . isJsonColumn ( col ) ) {
225+ fileUsesJson = true ;
226+ }
171227 }
172228
173229 try {
@@ -232,7 +288,12 @@ function codegen(input: GenerateRequest): GenerateResponse {
232288 }
233289 }
234290
235- // Add enum type declarations at the beginning of the file (after imports)
291+ // Add shared JSON and enum type declarations at the beginning of the file (after imports)
292+ const sharedTypeNodes : Node [ ] = [ ] ;
293+ if ( fileUsesJson ) {
294+ sharedTypeNodes . push ( ...jsonTypeDecls ( ) ) ;
295+ }
296+
236297 const enumNodes : Node [ ] = [ ] ;
237298 for ( const enumName of fileEnums ) {
238299 const enumDef = enumMap . get ( enumName ) ;
@@ -243,7 +304,7 @@ function codegen(input: GenerateRequest): GenerateResponse {
243304
244305 // Insert enum declarations after the preamble (imports)
245306 const preambleLength = postgres . preamble ( ) . length ;
246- nodes . splice ( preambleLength , 0 , ...enumNodes ) ;
307+ nodes . splice ( preambleLength , 0 , ...sharedTypeNodes , ... enumNodes ) ;
247308
248309 files . push (
249310 new File ( {
0 commit comments