@@ -2,32 +2,20 @@ import { readFileSync, writeFileSync, STDIO } from "javy/fs";
22import {
33 EmitHint ,
44 NewLineKind ,
5- TypeNode ,
65 ScriptKind ,
76 ScriptTarget ,
87 SyntaxKind ,
98 Node ,
10- NodeFlags ,
119 createPrinter ,
1210 createSourceFile ,
1311 factory ,
1412} from "typescript" ;
1513
16- import {
17- GenerateRequest ,
18- GenerateResponse ,
19- Parameter ,
20- Column ,
21- File ,
22- Query ,
23- } from "./gen/plugin/codegen_pb" ;
24-
25- import { argName , colName } from "./drivers/utlis" ;
14+ import { GenerateRequest , GenerateResponse , File } from "./gen/plugin/codegen_pb" ;
2615
16+ import { argName , colName } from "./drivers/utils" ;
2717import { assertUniqueNames } from "./validate" ;
28- import { Driver as PgDriver } from "./drivers/pg" ;
29- import { Driver as PostgresDriver } from "./drivers/postgres" ;
30- import { Driver as BunSqlDriver } from "./drivers/bun-sql" ;
18+ import * as postgres from "./drivers/postgres" ;
3119
3220// Read input from stdin
3321const input = readInput ( ) ;
@@ -36,68 +24,10 @@ const result = codegen(input);
3624// Write the result to stdout
3725writeOutput ( result ) ;
3826
39- interface Options {
40- runtime ?: string ;
41- driver ?: string ;
42- }
43-
44- interface Driver {
45- preamble : ( queries : Query [ ] ) => Node [ ] ;
46- columnType : ( c ?: Column ) => TypeNode ;
47- execDecl : ( name : string , text : string , iface : string | undefined , params : Parameter [ ] ) => Node ;
48- execlastidDecl : (
49- name : string ,
50- text : string ,
51- iface : string | undefined ,
52- params : Parameter [ ] ,
53- ) => Node ;
54- manyDecl : (
55- name : string ,
56- text : string ,
57- argIface : string | undefined ,
58- returnIface : string ,
59- params : Parameter [ ] ,
60- columns : Column [ ] ,
61- ) => Node ;
62- oneDecl : (
63- name : string ,
64- text : string ,
65- argIface : string | undefined ,
66- returnIface : string ,
67- params : Parameter [ ] ,
68- columns : Column [ ] ,
69- ) => Node ;
70- }
71-
72- function createNodeGenerator ( options : Options ) : Driver {
73- switch ( options . driver ) {
74- case "pg" : {
75- return new PgDriver ( ) ;
76- }
77- case "postgres" : {
78- return new PostgresDriver ( ) ;
79- }
80- case "bun-sql" : {
81- return new BunSqlDriver ( ) ;
82- }
83- }
84- throw new Error ( `unknown driver: ${ options . driver } ` ) ;
85- }
86-
8727function codegen ( input : GenerateRequest ) : GenerateResponse {
8828 let files = [ ] ;
89- let options : Options = { } ;
90-
91- if ( input . pluginOptions . length > 0 ) {
92- const text = new TextDecoder ( ) . decode ( input . pluginOptions ) ;
93- options = JSON . parse ( text ) as Options ;
94- }
95-
96- const driver = createNodeGenerator ( options ) ;
9729
98- // TODO: Verify options, parse them from protobuf honestly
99-
100- const querymap = new Map < string , Query [ ] > ( ) ;
30+ const querymap = new Map < string , typeof input . queries > ( ) ;
10131
10232 for ( const query of input . queries ) {
10333 if ( ! querymap . has ( query . filename ) ) {
@@ -108,61 +38,84 @@ function codegen(input: GenerateRequest): GenerateResponse {
10838 }
10939
11040 for ( const [ filename , queries ] of querymap . entries ( ) ) {
111- const nodes = driver . preamble ( queries ) ;
41+ const nodes : Node [ ] = [ ... postgres . preamble ( ) ] ;
11242
11343 for ( const query of queries ) {
11444 const lowerName = query . name [ 0 ] . toLowerCase ( ) + query . name . slice ( 1 ) ;
115- const textName = `${ lowerName } Query` ;
116-
117- nodes . push (
118- queryDecl (
119- textName ,
120- `-- name: ${ query . name } ${ query . cmd }
121- ${ query . text } `,
122- ) ,
123- ) ;
12445
12546 let argIface = undefined ;
12647 let returnIface = undefined ;
48+
12749 if ( query . params . length > 0 ) {
12850 argIface = `${ query . name } Args` ;
51+ const names = query . params . map ( ( param , i ) => argName ( i , param . column ) ) ;
52+ assertUniqueNames ( {
53+ kind : "argument" ,
54+ queryName : query . name ,
55+ fileName : filename ,
56+ names,
57+ } ) ;
58+
12959 nodes . push (
130- argsDecl ( {
131- name : argIface ,
132- driver,
133- params : query . params ,
134- queryName : query . name ,
135- fileName : filename ,
136- } ) ,
60+ factory . createInterfaceDeclaration (
61+ [ factory . createToken ( SyntaxKind . ExportKeyword ) ] ,
62+ factory . createIdentifier ( argIface ) ,
63+ undefined ,
64+ undefined ,
65+ query . params . map ( ( param , i ) =>
66+ factory . createPropertySignature (
67+ undefined ,
68+ factory . createIdentifier ( argName ( i , param . column ) ) ,
69+ undefined ,
70+ postgres . columnType ( param . column ) ,
71+ ) ,
72+ ) ,
73+ ) ,
13774 ) ;
13875 }
76+
13977 if ( query . columns . length > 0 ) {
14078 returnIface = `${ query . name } Row` ;
79+ const names = query . columns . map ( ( column , i ) => colName ( i , column ) ) ;
80+ assertUniqueNames ( {
81+ kind : "column" ,
82+ queryName : query . name ,
83+ fileName : filename ,
84+ names,
85+ } ) ;
86+
14187 nodes . push (
142- rowDecl ( {
143- name : returnIface ,
144- driver,
145- columns : query . columns ,
146- queryName : query . name ,
147- fileName : filename ,
148- } ) ,
88+ factory . createInterfaceDeclaration (
89+ [ factory . createToken ( SyntaxKind . ExportKeyword ) ] ,
90+ factory . createIdentifier ( returnIface ) ,
91+ undefined ,
92+ undefined ,
93+ query . columns . map ( ( column , i ) =>
94+ factory . createPropertySignature (
95+ undefined ,
96+ factory . createIdentifier ( colName ( i , column ) ) ,
97+ undefined ,
98+ postgres . columnType ( column ) ,
99+ ) ,
100+ ) ,
101+ ) ,
149102 ) ;
150103 }
151104
152105 switch ( query . cmd ) {
153106 case ":exec" : {
154- nodes . push ( driver . execDecl ( lowerName , textName , argIface , query . params ) ) ;
107+ nodes . push ( postgres . execDecl ( lowerName , query . text , argIface , query . params ) ) ;
155108 break ;
156109 }
157110 case ":execlastid" : {
158- nodes . push ( driver . execlastidDecl ( lowerName , textName , argIface , query . params ) ) ;
111+ nodes . push ( postgres . execlastidDecl ( lowerName , query . text , argIface , query . params ) ) ;
159112 break ;
160113 }
161114 case ":one" : {
162115 nodes . push (
163- driver . oneDecl (
116+ postgres . oneDecl (
164117 lowerName ,
165- textName ,
118+ query . text ,
166119 argIface ,
167120 returnIface ?? "void" ,
168121 query . params ,
@@ -173,9 +126,9 @@ ${query.text}`,
173126 }
174127 case ":many" : {
175128 nodes . push (
176- driver . manyDecl (
129+ postgres . manyDecl (
177130 lowerName ,
178- textName ,
131+ query . text ,
179132 argIface ,
180133 returnIface ?? "void" ,
181134 query . params ,
@@ -185,15 +138,14 @@ ${query.text}`,
185138 break ;
186139 }
187140 }
188- if ( nodes ) {
189- files . push (
190- new File ( {
191- name : `${ filename . replace ( "." , "_" ) } .ts` ,
192- contents : new TextEncoder ( ) . encode ( printNode ( nodes ) ) ,
193- } ) ,
194- ) ;
195- }
196141 }
142+
143+ files . push (
144+ new File ( {
145+ name : `${ filename . replace ( "." , "_" ) } .ts` ,
146+ contents : new TextEncoder ( ) . encode ( printNode ( nodes ) ) ,
147+ } ) ,
148+ ) ;
197149 }
198150
199151 return new GenerateResponse ( {
@@ -207,87 +159,7 @@ function readInput(): GenerateRequest {
207159 return GenerateRequest . fromBinary ( buffer ) ;
208160}
209161
210- function queryDecl ( name : string , sql : string ) {
211- return factory . createVariableStatement (
212- [ factory . createToken ( SyntaxKind . ExportKeyword ) ] ,
213- factory . createVariableDeclarationList (
214- [
215- factory . createVariableDeclaration (
216- factory . createIdentifier ( name ) ,
217- undefined ,
218- undefined ,
219- factory . createNoSubstitutionTemplateLiteral ( sql , sql ) ,
220- ) ,
221- ] ,
222- NodeFlags . Const , //| NodeFlags.Constant | NodeFlags.Constant
223- ) ,
224- ) ;
225- }
226-
227- function argsDecl ( options : {
228- name : string ;
229- driver : Driver ;
230- params : Parameter [ ] ;
231- queryName : string ;
232- fileName : string ;
233- } ) {
234- const names = options . params . map ( ( param , i ) => argName ( i , param . column ) ) ;
235- assertUniqueNames ( {
236- kind : "argument" ,
237- queryName : options . queryName ,
238- fileName : options . fileName ,
239- names,
240- } ) ;
241-
242- return factory . createInterfaceDeclaration (
243- [ factory . createToken ( SyntaxKind . ExportKeyword ) ] ,
244- factory . createIdentifier ( options . name ) ,
245- undefined ,
246- undefined ,
247- options . params . map ( ( param , i ) =>
248- factory . createPropertySignature (
249- undefined ,
250- factory . createIdentifier ( argName ( i , param . column ) ) ,
251- undefined ,
252- options . driver . columnType ( param . column ) ,
253- ) ,
254- ) ,
255- ) ;
256- }
257-
258- function rowDecl ( options : {
259- name : string ;
260- driver : Driver ;
261- columns : Column [ ] ;
262- queryName : string ;
263- fileName : string ;
264- } ) {
265- const names = options . columns . map ( ( column , i ) => colName ( i , column ) ) ;
266- assertUniqueNames ( {
267- kind : "column" ,
268- queryName : options . queryName ,
269- fileName : options . fileName ,
270- names,
271- } ) ;
272-
273- return factory . createInterfaceDeclaration (
274- [ factory . createToken ( SyntaxKind . ExportKeyword ) ] ,
275- factory . createIdentifier ( options . name ) ,
276- undefined ,
277- undefined ,
278- options . columns . map ( ( column , i ) =>
279- factory . createPropertySignature (
280- undefined ,
281- factory . createIdentifier ( colName ( i , column ) ) ,
282- undefined ,
283- options . driver . columnType ( column ) ,
284- ) ,
285- ) ,
286- ) ;
287- }
288-
289162function printNode ( nodes : Node [ ] ) : string {
290- // https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API#creating-and-printing-a-typescript-ast
291163 const resultFile = createSourceFile (
292164 "file.ts" ,
293165 "" ,
0 commit comments