├── .github └── workflows │ ├── ci.yml │ └── examples.yml ├── .gitignore ├── Makefile ├── README.md ├── buf.gen.yaml ├── examples ├── .gitignore ├── authors │ ├── mysql │ │ ├── query.sql │ │ └── schema.sql │ ├── postgresql │ │ ├── query.sql │ │ └── schema.sql │ ├── sqlc.yaml │ └── sqlite │ │ ├── query.sql │ │ └── schema.sql ├── bun-mysql2 │ ├── .gitignore │ ├── README.md │ ├── bun.lockb │ ├── package.json │ ├── src │ │ ├── db │ │ │ └── query_sql.ts │ │ └── main.ts │ └── tsconfig.json ├── bun-pg │ ├── .gitignore │ ├── README.md │ ├── bun.lockb │ ├── package.json │ ├── src │ │ ├── db │ │ │ └── query_sql.ts │ │ └── main.ts │ └── tsconfig.json ├── bun-postgres │ ├── .gitignore │ ├── README.md │ ├── bun.lockb │ ├── package.json │ ├── src │ │ ├── db │ │ │ └── query_sql.ts │ │ └── main.ts │ └── tsconfig.json ├── node-better-sqlite3 │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── db │ │ │ └── query_sql.ts │ │ └── main.ts │ └── tsconfig.json ├── node-mysql2 │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── db │ │ │ └── query_sql.ts │ │ └── main.ts │ └── tsconfig.json ├── node-pg │ ├── Makefile │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── db │ │ │ └── query_sql.ts │ │ └── main.ts │ └── tsconfig.json ├── node-postgres │ ├── Makefile │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── db │ │ │ └── query_sql.ts │ │ └── main.ts │ └── tsconfig.json ├── sqlc.dev.yaml └── sqlc.yaml ├── package-lock.json ├── package.json ├── src ├── app.ts ├── drivers │ ├── better-sqlite3.ts │ ├── mysql2.ts │ ├── pg.ts │ ├── postgres.ts │ └── utlis.ts ├── gen │ └── plugin │ │ └── codegen_pb.ts └── logger.ts └── tsconfig.json /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | on: 3 | push: 4 | branches: 5 | - main 6 | pull_request: 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v4 12 | - uses: sqlc-dev/setup-sqlc@v4 13 | with: 14 | sqlc-version: '1.24.0' 15 | - uses: actions/setup-node@v4 16 | - run: wget https://github.com/bytecodealliance/javy/releases/download/v1.2.0/javy-x86_64-linux-v1.2.0.gz 17 | - run: gzip -d javy-x86_64-linux-v1.2.0.gz 18 | - run: chmod +x javy-x86_64-linux-v1.2.0 19 | - run: npm install 20 | - run: npx tsc --noEmit 21 | - run: npx esbuild --bundle src/app.ts --tree-shaking=true --format=esm --target=es2020 --outfile=out.js 22 | - run: ./javy-x86_64-linux-v1.2.0 compile out.js -o examples/plugin.wasm 23 | - run: sqlc -f sqlc.dev.yaml diff 24 | working-directory: examples -------------------------------------------------------------------------------- /.github/workflows/examples.yml: -------------------------------------------------------------------------------- 1 | name: examples 2 | on: 3 | push: 4 | branches: 5 | - main 6 | pull_request: 7 | jobs: 8 | bun-mysql: 9 | runs-on: ubuntu-latest 10 | strategy: 11 | matrix: 12 | include: 13 | - dir: "examples/bun-mysql2" 14 | qs: "mysql" 15 | steps: 16 | - uses: actions/checkout@v4 17 | - uses: sqlc-dev/setup-sqlc@v4 18 | with: 19 | sqlc-version: '1.24.0' 20 | - uses: oven-sh/setup-bun@v1 21 | with: 22 | bun-version: latest 23 | - uses: shogo82148/actions-setup-mysql@v1 24 | with: 25 | mysql-version: "8.1" 26 | - run: bun install 27 | working-directory: ${{ matrix.dir }} 28 | - run: mysql --user="root" --database="mysql" < schema.sql 29 | working-directory: examples/authors/mysql 30 | - run: bun run src/main.ts 31 | working-directory: ${{ matrix.dir }} 32 | env: 33 | DATABASE_URL: mysql://root:@localhost:3306/mysql 34 | 35 | bun-postgresql: 36 | runs-on: ubuntu-latest 37 | strategy: 38 | matrix: 39 | include: 40 | - dir: "examples/bun-postgres" 41 | qs: "postgresql" 42 | - dir: "examples/bun-pg" 43 | qs: "postgresql" 44 | steps: 45 | - uses: actions/checkout@v4 46 | - uses: sqlc-dev/setup-sqlc@v4 47 | with: 48 | sqlc-version: '1.24.0' 49 | - uses: oven-sh/setup-bun@v1 50 | with: 51 | bun-version: latest 52 | - uses: sqlc-dev/action-setup-postgres@master 53 | with: 54 | postgres-version: "16" 55 | id: postgres 56 | - run: bun install 57 | working-directory: ${{ matrix.dir }} 58 | - run: psql -f schema.sql "$DATABASE_URL" 59 | working-directory: examples/authors/postgresql 60 | env: 61 | DATABASE_URL: ${{ steps.postgres.outputs.connection-uri }}?sslmode=disable 62 | - run: bun run src/main.ts 63 | working-directory: ${{ matrix.dir }} 64 | env: 65 | DATABASE_URL: ${{ steps.postgres.outputs.connection-uri }}?sslmode=disable 66 | 67 | node-mysql: 68 | runs-on: ubuntu-latest 69 | strategy: 70 | matrix: 71 | include: 72 | - dir: "examples/node-mysql2" 73 | qs: "mysql" 74 | steps: 75 | - uses: actions/checkout@v4 76 | - uses: sqlc-dev/setup-sqlc@v4 77 | with: 78 | sqlc-version: '1.24.0' 79 | - uses: actions/setup-node@v4 80 | - uses: shogo82148/actions-setup-mysql@v1 81 | with: 82 | mysql-version: "8.1" 83 | - run: npm install 84 | working-directory: ${{ matrix.dir }} 85 | - run: npx tsc 86 | working-directory: ${{ matrix.dir }} 87 | - run: mysql --user="root" --database="mysql" < schema.sql 88 | working-directory: examples/authors/mysql 89 | - run: node ./src/main.js 90 | working-directory: ${{ matrix.dir }} 91 | env: 92 | DATABASE_URL: mysql://root:@localhost:3306/mysql 93 | 94 | node-postgresql: 95 | runs-on: ubuntu-latest 96 | strategy: 97 | matrix: 98 | include: 99 | - dir: "examples/node-postgres" 100 | qs: "postgresql" 101 | - dir: "examples/node-pg" 102 | qs: "postgresql" 103 | steps: 104 | - uses: actions/checkout@v4 105 | - uses: sqlc-dev/setup-sqlc@v4 106 | with: 107 | sqlc-version: '1.24.0' 108 | - uses: actions/setup-node@v4 109 | - uses: sqlc-dev/action-setup-postgres@master 110 | with: 111 | postgres-version: "16" 112 | id: postgres 113 | - run: npm install 114 | working-directory: ${{ matrix.dir }} 115 | - run: npx tsc 116 | working-directory: ${{ matrix.dir }} 117 | - run: psql -f schema.sql "$DATABASE_URL" 118 | working-directory: examples/authors/postgresql 119 | env: 120 | DATABASE_URL: ${{ steps.postgres.outputs.connection-uri }}?sslmode=disable 121 | - run: node ./src/main.js 122 | working-directory: ${{ matrix.dir }} 123 | env: 124 | DATABASE_URL: ${{ steps.postgres.outputs.connection-uri }}?sslmode=disable -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | out.js 3 | *.wasm 4 | javy 5 | tests 6 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: generate 2 | 3 | generate: examples/plugin.wasm examples/sqlc.dev.yaml 4 | cd examples && sqlc-dev -f sqlc.dev.yaml generate 5 | 6 | # https://github.com/bytecodealliance/javy/releases/tag/v1.2.0 7 | examples/plugin.wasm: out.js 8 | ./javy compile out.js -o examples/plugin.wasm 9 | 10 | out.js: src/app.ts $(wildcard src/drivers/*.ts) src/gen/plugin/codegen_pb.ts 11 | npx tsc --noEmit 12 | npx esbuild --bundle src/app.ts --tree-shaking=true --format=esm --target=es2020 --outfile=out.js 13 | 14 | src/gen/plugin/codegen_pb.ts: buf.gen.yaml 15 | buf generate --template buf.gen.yaml buf.build/sqlc/sqlc --path plugin/ 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # sqlc-gen-typescript 2 | 3 | > [!CAUTION] 4 | > Here be dragons! This plugin is still in early access. Expect breaking changes, missing functionality, and sub-optimal output. Please report all issues and errors. Good luck! 5 | 6 | ## Usage 7 | 8 | ```yaml 9 | version: '2' 10 | plugins: 11 | - name: ts 12 | wasm: 13 | url: https://downloads.sqlc.dev/plugin/sqlc-gen-typescript_0.1.3.wasm 14 | sha256: 287df8f6cc06377d67ad5ba02c9e0f00c585509881434d15ea8bd9fc751a9368 15 | sql: 16 | - schema: "schema.sql" 17 | queries: "query.sql" 18 | engine: postgresql 19 | codegen: 20 | - out: src/authors 21 | plugin: ts 22 | options: 23 | runtime: node 24 | driver: postgres 25 | ``` 26 | 27 | ## Supported engines and drivers 28 | 29 | - PostgreSQL via [pg](https://www.npmjs.com/package/pg) or [postgres](https://www.npmjs.com/package/postgres). 30 | - MySQL via [mysql2](https://www.npmjs.com/package/mysql2). 31 | - SQLite via [sqlite3](https://www.npmjs.com/package/better-sqlite3). 32 | 33 | ## Getting started 34 | 35 | This tutorial assumes that the latest version of sqlc is 36 | [installed](https://docs.sqlc.dev/en/latest/overview/install.html) and ready to use. 37 | 38 | We'll generate TypeScript here, but other [language 39 | plugins](https://docs.sqlc.dev/en/latest/reference/language-support.html) are 40 | available. You'll need Bun (or Node.js) installed if you want to build and run a 41 | program with the code sqlc generates, but sqlc itself has no dependencies. 42 | 43 | We'll also rely on sqlc's [managed databases](https://docs.sqlc.dev/en/latest/howto/managed-databases.html), 44 | which require a sqlc Cloud project and auth token. You can get those from 45 | the [sqlc Cloud dashboard](https://dashboard.sqlc.dev/). Managed databases are 46 | an optional feature that improves sqlc's query analysis in many cases, but you 47 | can turn it off simply by removing the `cloud` and `database` sections of your 48 | configuration. 49 | 50 | ### Setting up 51 | 52 | Create a new directory called `sqlc-tutorial` and open it up. 53 | 54 | Initialize a new package. 55 | 56 | ```shell 57 | $ bun init 58 | ``` 59 | 60 | sqlc looks for either a `sqlc.(yaml|yml)` or `sqlc.json` file in the current 61 | directory. In our new directory, create a file named `sqlc.yaml` with the 62 | following contents: 63 | 64 | ```yaml 65 | version: "2" 66 | cloud: 67 | # Replace with your project ID from the sqlc Cloud dashboard 68 | project: "" 69 | plugins: 70 | - name: ts 71 | wasm: 72 | url: https://downloads.sqlc.dev/plugin/sqlc-gen-typescript_0.1.3.wasm 73 | sha256: 287df8f6cc06377d67ad5ba02c9e0f00c585509881434d15ea8bd9fc751a9368 74 | sql: 75 | - engine: "postgresql" 76 | queries: "query.sql" 77 | schema: "schema.sql" 78 | database: 79 | managed: true 80 | codegen: 81 | - out: db 82 | plugin: ts 83 | options: 84 | runtime: node 85 | driver: pg 86 | ``` 87 | 88 | Replace `` with your project ID from the sqlc Cloud dashboard. It 89 | will look something like `01HA8SZH31HKYE9RR3N3N3TSJM`. 90 | 91 | And finally, set the `SQLC_AUTH_TOKEN` environment variable: 92 | 93 | ```shell 94 | export SQLC_AUTH_TOKEN="" 95 | ``` 96 | 97 | ### Schema and queries 98 | 99 | sqlc needs to know your database schema and queries in order to generate code. 100 | In the same directory, create a file named `schema.sql` with the following 101 | content: 102 | 103 | ```sql 104 | CREATE TABLE authors ( 105 | id BIGSERIAL PRIMARY KEY, 106 | name text NOT NULL, 107 | bio text 108 | ); 109 | ``` 110 | 111 | Next, create a `query.sql` file with the following five queries: 112 | 113 | ```sql 114 | -- name: GetAuthor :one 115 | SELECT * FROM authors 116 | WHERE id = $1 LIMIT 1; 117 | 118 | -- name: ListAuthors :many 119 | SELECT * FROM authors 120 | ORDER BY name; 121 | 122 | -- name: CreateAuthor :one 123 | INSERT INTO authors ( 124 | name, bio 125 | ) VALUES ( 126 | $1, $2 127 | ) 128 | RETURNING *; 129 | 130 | -- name: UpdateAuthor :exec 131 | UPDATE authors 132 | set name = $2, 133 | bio = $3 134 | WHERE id = $1; 135 | 136 | -- name: DeleteAuthor :exec 137 | DELETE FROM authors 138 | WHERE id = $1; 139 | ``` 140 | 141 | If you prefer, you can alter the `UpdateAuthor` query to return the updated 142 | record: 143 | 144 | ```sql 145 | -- name: UpdateAuthor :one 146 | UPDATE authors 147 | set name = $2, 148 | bio = $3 149 | WHERE id = $1 150 | RETURNING *; 151 | ``` 152 | 153 | ### Generating code 154 | 155 | You are now ready to generate code. You shouldn't see any output when you run 156 | the `generate` subcommand, unless something goes wrong: 157 | 158 | ```shell 159 | $ sqlc generate 160 | ``` 161 | 162 | You should now have a `tutorial` subdirectory with three files containing Go 163 | source code. These files comprise a Go package named `tutorial`: 164 | 165 | ``` 166 | ├── package.json 167 | ├── query.sql 168 | ├── schema.sql 169 | ├── sqlc.yaml 170 | └── db 171 | ├── query_sql.ts 172 | ``` 173 | 174 | ### Using generated code 175 | 176 | You can use your newly-generated code package from any TypeScript program. 177 | Create a file named `index.ts` and add the following contents: 178 | 179 | ```ts 180 | import { Pool } from "pg"; 181 | 182 | import { 183 | createAuthor, 184 | deleteAuthor, 185 | getAuthor, 186 | listAuthors, 187 | } from "./db/query_sql"; 188 | 189 | async function main() { 190 | const client = new Pool({ connectionString: process.env["DATABASE_URL"] }); 191 | await client.connect(); 192 | 193 | // list all authors 194 | const authors = await listAuthors(client); 195 | console.log(authors); 196 | 197 | // create an author 198 | const author = await createAuthor(client, { 199 | name: "Anders Hejlsberg", 200 | bio: "Original author of Turbo Pascal and co-creator of TypeScript", 201 | }); 202 | if (author === null) { 203 | throw new Error("author not created"); 204 | } 205 | console.log(author); 206 | 207 | // get the author we just created 208 | const anders = await getAuthor(client, { id: author.id }); 209 | if (anders === null) { 210 | throw new Error("anders not found"); 211 | } 212 | console.log(anders); 213 | 214 | // delete the author 215 | await deleteAuthor(client, { id: anders.id }); 216 | } 217 | 218 | (async () => { 219 | await main(); 220 | process.exit() 221 | })(); 222 | ``` 223 | 224 | Before this code will run you'll need to install the `pg` package: 225 | 226 | ```shell 227 | $ bun install pg 228 | ``` 229 | 230 | The program should compile without errors. To make that possible, sqlc generates 231 | readable, **idiomatic** TypeScript code that you otherwise would've had to write 232 | yourself. Take a look in `db/query_sql.ts`. 233 | 234 | Of course for this program to run successfully you'll need to run after setting 235 | the `DATABASE_URL` environment variable. And your database must have the 236 | `authors` table as defined in `schema.sql`. 237 | 238 | ```shell 239 | $ DATABASE_URL="$(sqlc createdb)" bun run index.ts 240 | ``` 241 | 242 | ```shell 243 | $ bun run index.ts 244 | ``` 245 | 246 | You should now have a working program using sqlc's generated TypeScript source 247 | code, and hopefully can see how you'd use sqlc in your own real-world 248 | applications. 249 | 250 | ## Configuration 251 | 252 | ### PostgreSQL and node-postgres 253 | 254 | ```yaml 255 | version: '2' 256 | plugins: 257 | - name: ts 258 | wasm: 259 | url: https://downloads.sqlc.dev/plugin/sqlc-gen-typescript_0.1.3.wasm 260 | sha256: 287df8f6cc06377d67ad5ba02c9e0f00c585509881434d15ea8bd9fc751a9368 261 | sql: 262 | - schema: "schema.sql" 263 | queries: "query.sql" 264 | engine: postgresql 265 | codegen: 266 | - out: db 267 | plugin: ts 268 | options: 269 | runtime: node 270 | driver: pg # npm package name 271 | ``` 272 | 273 | ### PostgreSQL and postgres.js 274 | 275 | ```yaml 276 | version: '2' 277 | plugins: 278 | - name: ts 279 | wasm: 280 | url: https://downloads.sqlc.dev/plugin/sqlc-gen-typescript_0.1.3.wasm 281 | sha256: 287df8f6cc06377d67ad5ba02c9e0f00c585509881434d15ea8bd9fc751a9368 282 | sql: 283 | - schema: "schema.sql" 284 | queries: "query.sql" 285 | engine: postgresql 286 | codegen: 287 | - out: db 288 | plugin: ts 289 | options: 290 | runtime: node 291 | driver: postgres # npm package name 292 | ``` 293 | 294 | 295 | ### MySQL and mysql2 296 | 297 | ```yaml 298 | version: '2' 299 | plugins: 300 | - name: ts 301 | wasm: 302 | url: https://downloads.sqlc.dev/plugin/sqlc-gen-typescript_0.1.3.wasm 303 | sha256: 287df8f6cc06377d67ad5ba02c9e0f00c585509881434d15ea8bd9fc751a9368 304 | sql: 305 | - schema: "schema.sql" 306 | queries: "query.sql" 307 | engine: "mysql" 308 | codegen: 309 | - out: db 310 | plugin: ts 311 | options: 312 | runtime: node 313 | driver: mysql2 # npm package name 314 | ``` 315 | 316 | ### SQLite and better-sqlite3 (Beta) 317 | 318 | ```yaml 319 | version: '2' 320 | plugins: 321 | - name: ts 322 | wasm: 323 | url: https://downloads.sqlc.dev/plugin/sqlc-gen-typescript_0.1.3.wasm 324 | sha256: 287df8f6cc06377d67ad5ba02c9e0f00c585509881434d15ea8bd9fc751a9368 325 | sql: 326 | - schema: "schema.sql" 327 | queries: "query.sql" 328 | engine: sqlite 329 | codegen: 330 | - out: db 331 | plugin: ts 332 | options: 333 | runtime: node 334 | driver: better-sqlite3 # npm package name 335 | ``` 336 | 337 | ## Development 338 | 339 | If you want to build and test sqlc-gen-typescript locally, follow these steps: 340 | 341 | 1. Clone the repository and install dependencies: 342 | ``` 343 | git clone https://github.com/sqlc-dev/sqlc-gen-typescript.git 344 | cd sqlc-gen-typescript 345 | npm install 346 | ``` 347 | 348 | 2. Make your desired changes to the codebase. The main source files are located in the `src` directory. 349 | 350 | 3. If you've made changes that require updating dependencies, run: 351 | ``` 352 | npm install 353 | ``` 354 | 355 | 4. Build the WASM plugin: 356 | Check the `Makefile` for details. 357 | ``` 358 | make out.js 359 | 360 | # Ensure you have Javy installed and available in your PATH 361 | make examples/plugin.wasm 362 | ``` 363 | 364 | 5. To test your local build, create a test project with a `sqlc.yaml` file containing: 365 | 366 | ```yaml 367 | version: '2' 368 | plugins: 369 | - name: ts 370 | wasm: 371 | url: file://{path_to_your_local_wasm_file} 372 | sha256: {sha256_of_your_wasm_file} 373 | sql: 374 | - schema: "schema.sql" 375 | queries: "query.sql" 376 | engine: {your_database_engine} 377 | codegen: 378 | - out: db 379 | plugin: ts 380 | options: 381 | runtime: node 382 | driver: {your_database_driver} 383 | ``` 384 | 385 | Replace the placeholders with appropriate values for your setup. 386 | 387 | 6. Run sqlc in your test project to generate TypeScript code using your local plugin build: 388 | ``` 389 | sqlc generate 390 | ``` 391 | 392 | For more details on sqlc development, refer to the sqlc core development guide. This guide provides additional information on setting up and working with sqlc in general, which may be useful for contributors to this project. 393 | https://docs.sqlc.dev/en/latest/guides/development.html -------------------------------------------------------------------------------- /buf.gen.yaml: -------------------------------------------------------------------------------- 1 | version: v1 2 | plugins: 3 | - plugin: buf.build/bufbuild/es:v1.4.2 4 | opt: target=ts 5 | out: src/gen -------------------------------------------------------------------------------- /examples/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.wasm 3 | *.js -------------------------------------------------------------------------------- /examples/authors/mysql/query.sql: -------------------------------------------------------------------------------- 1 | /* name: GetAuthor :one */ 2 | SELECT * FROM authors 3 | WHERE id = ? LIMIT 1; 4 | 5 | /* name: ListAuthors :many */ 6 | SELECT * FROM authors 7 | ORDER BY name; 8 | 9 | /* name: CreateAuthor :exec */ 10 | INSERT INTO authors ( 11 | name, bio 12 | ) VALUES ( 13 | ?, ? 14 | ); 15 | 16 | /* name: CreateAuthorReturnId :execlastid */ 17 | INSERT INTO authors ( 18 | name, bio 19 | ) VALUES ( 20 | ?, ? 21 | ); 22 | 23 | /* name: DeleteAuthor :exec */ 24 | DELETE FROM authors 25 | WHERE id = ?; 26 | 27 | /* name: Test :one */ 28 | SELECT * FROM node_mysql_types 29 | LIMIT 1; 30 | -------------------------------------------------------------------------------- /examples/authors/mysql/schema.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE authors ( 2 | id BIGINT PRIMARY KEY AUTO_INCREMENT, 3 | name text NOT NULL, 4 | bio text 5 | ); 6 | 7 | CREATE TABLE node_mysql_types ( 8 | c_bit BIT, 9 | c_tinyint TINYINT, 10 | c_bool BOOL, 11 | c_boolean BOOLEAN, 12 | c_smallint SMALLINT, 13 | c_mediumint MEDIUMINT, 14 | c_int INT, 15 | c_integer INTEGER, 16 | c_bigint BIGINT, 17 | c_serial SERIAL, 18 | c_decimal DECIMAL(2,1), 19 | c_dec DEC(2,1), 20 | c_numeric NUMERIC(2,1), 21 | c_fixed FIXED(2,1), 22 | c_float FLOAT, 23 | c_double DOUBLE, 24 | c_double_precision DOUBLE PRECISION, 25 | 26 | /* 11.2 Date and Time Data Types */ 27 | c_date DATE, 28 | c_time TIME, 29 | c_datetime DATETIME, 30 | c_timestamp TIMESTAMP, 31 | c_year YEAR, 32 | 33 | /* 11.3.1 String Data Type Syntax */ 34 | c_char CHAR, 35 | c_nchar NCHAR, 36 | c_national_char NATIONAL CHAR, 37 | c_varchar VARCHAR(10), 38 | c_binary BINARY, 39 | c_varbinary VARBINARY(10), 40 | c_tinyblob TINYBLOB, 41 | c_tinytext TINYTEXT, 42 | c_blob BLOB, 43 | c_text TEXT, 44 | c_mediumblob MEDIUMBLOB, 45 | c_mediumtext MEDIUMTEXT, 46 | c_longblob LONGBLOB, 47 | c_longtext LONGTEXT, 48 | /* c_enum ENUM('a', 'b', 'c'), */ 49 | /* c_set SET('a', 'b', 'c'), */ 50 | 51 | c_json JSON 52 | ); 53 | -------------------------------------------------------------------------------- /examples/authors/postgresql/query.sql: -------------------------------------------------------------------------------- 1 | -- name: GetAuthor :one 2 | SELECT * FROM authors 3 | WHERE id = $1 LIMIT 1; 4 | 5 | -- name: ListAuthors :many 6 | SELECT * FROM authors 7 | ORDER BY name; 8 | 9 | -- name: CreateAuthor :one 10 | INSERT INTO authors ( 11 | name, bio 12 | ) VALUES ( 13 | $1, $2 14 | ) 15 | RETURNING *; 16 | 17 | -- name: DeleteAuthor :exec 18 | DELETE FROM authors 19 | WHERE id = $1; 20 | -------------------------------------------------------------------------------- /examples/authors/postgresql/schema.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE authors ( 2 | id BIGSERIAL PRIMARY KEY, 3 | name text NOT NULL, 4 | bio text 5 | ); 6 | -------------------------------------------------------------------------------- /examples/authors/sqlc.yaml: -------------------------------------------------------------------------------- 1 | version: "2" 2 | cloud: 3 | project: "01HAQMMECEYQYKFJN8MP16QC41" 4 | sql: 5 | - name: postgresql 6 | schema: "postgresql/schema.sql" 7 | queries: "postgresql/query.sql" 8 | engine: "postgresql" 9 | database: 10 | managed: true 11 | - name: mysql 12 | schema: "mysql/schema.sql" 13 | queries: "mysql/query.sql" 14 | engine: "mysql" 15 | database: 16 | managed: true -------------------------------------------------------------------------------- /examples/authors/sqlite/query.sql: -------------------------------------------------------------------------------- 1 | -- name: GetAuthor :one 2 | SELECT * FROM authors 3 | WHERE id = ? LIMIT 1; 4 | 5 | -- name: ListAuthors :many 6 | SELECT * FROM authors 7 | ORDER BY name; 8 | 9 | -- name: CreateAuthor :exec 10 | INSERT INTO authors ( 11 | name, bio 12 | ) VALUES ( 13 | ?, ? 14 | ); 15 | 16 | -- name: DeleteAuthor :exec 17 | DELETE FROM authors 18 | WHERE id = ?; 19 | -------------------------------------------------------------------------------- /examples/authors/sqlite/schema.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE authors ( 2 | id INTEGER PRIMARY KEY AUTOINCREMENT, 3 | name text NOT NULL, 4 | bio text 5 | ); 6 | -------------------------------------------------------------------------------- /examples/bun-mysql2/.gitignore: -------------------------------------------------------------------------------- 1 | # Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore 2 | 3 | # Logs 4 | 5 | logs 6 | _.log 7 | npm-debug.log_ 8 | yarn-debug.log* 9 | yarn-error.log* 10 | lerna-debug.log* 11 | .pnpm-debug.log* 12 | 13 | # Diagnostic reports (https://nodejs.org/api/report.html) 14 | 15 | report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json 16 | 17 | # Runtime data 18 | 19 | pids 20 | _.pid 21 | _.seed 22 | \*.pid.lock 23 | 24 | # Directory for instrumented libs generated by jscoverage/JSCover 25 | 26 | lib-cov 27 | 28 | # Coverage directory used by tools like istanbul 29 | 30 | coverage 31 | \*.lcov 32 | 33 | # nyc test coverage 34 | 35 | .nyc_output 36 | 37 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 38 | 39 | .grunt 40 | 41 | # Bower dependency directory (https://bower.io/) 42 | 43 | bower_components 44 | 45 | # node-waf configuration 46 | 47 | .lock-wscript 48 | 49 | # Compiled binary addons (https://nodejs.org/api/addons.html) 50 | 51 | build/Release 52 | 53 | # Dependency directories 54 | 55 | node_modules/ 56 | jspm_packages/ 57 | 58 | # Snowpack dependency directory (https://snowpack.dev/) 59 | 60 | web_modules/ 61 | 62 | # TypeScript cache 63 | 64 | \*.tsbuildinfo 65 | 66 | # Optional npm cache directory 67 | 68 | .npm 69 | 70 | # Optional eslint cache 71 | 72 | .eslintcache 73 | 74 | # Optional stylelint cache 75 | 76 | .stylelintcache 77 | 78 | # Microbundle cache 79 | 80 | .rpt2_cache/ 81 | .rts2_cache_cjs/ 82 | .rts2_cache_es/ 83 | .rts2_cache_umd/ 84 | 85 | # Optional REPL history 86 | 87 | .node_repl_history 88 | 89 | # Output of 'npm pack' 90 | 91 | \*.tgz 92 | 93 | # Yarn Integrity file 94 | 95 | .yarn-integrity 96 | 97 | # dotenv environment variable files 98 | 99 | .env 100 | .env.development.local 101 | .env.test.local 102 | .env.production.local 103 | .env.local 104 | 105 | # parcel-bundler cache (https://parceljs.org/) 106 | 107 | .cache 108 | .parcel-cache 109 | 110 | # Next.js build output 111 | 112 | .next 113 | out 114 | 115 | # Nuxt.js build / generate output 116 | 117 | .nuxt 118 | dist 119 | 120 | # Gatsby files 121 | 122 | .cache/ 123 | 124 | # Comment in the public line in if your project uses Gatsby and not Next.js 125 | 126 | # https://nextjs.org/blog/next-9-1#public-directory-support 127 | 128 | # public 129 | 130 | # vuepress build output 131 | 132 | .vuepress/dist 133 | 134 | # vuepress v2.x temp and cache directory 135 | 136 | .temp 137 | .cache 138 | 139 | # Docusaurus cache and generated files 140 | 141 | .docusaurus 142 | 143 | # Serverless directories 144 | 145 | .serverless/ 146 | 147 | # FuseBox cache 148 | 149 | .fusebox/ 150 | 151 | # DynamoDB Local files 152 | 153 | .dynamodb/ 154 | 155 | # TernJS port file 156 | 157 | .tern-port 158 | 159 | # Stores VSCode versions used for testing VSCode extensions 160 | 161 | .vscode-test 162 | 163 | # yarn v2 164 | 165 | .yarn/cache 166 | .yarn/unplugged 167 | .yarn/build-state.yml 168 | .yarn/install-state.gz 169 | .pnp.\* 170 | 171 | # IntelliJ based IDEs 172 | .idea 173 | 174 | # Finder (MacOS) folder config 175 | .DS_Store 176 | 177 | -------------------------------------------------------------------------------- /examples/bun-mysql2/README.md: -------------------------------------------------------------------------------- 1 | # bun-mysql2 2 | 3 | To install dependencies: 4 | 5 | ```bash 6 | bun install 7 | ``` 8 | 9 | To run: 10 | 11 | ```bash 12 | bun run src/main.ts 13 | ``` 14 | 15 | This project was created using `bun init` in bun v1.0.11. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime. 16 | -------------------------------------------------------------------------------- /examples/bun-mysql2/bun.lockb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqlc-dev/sqlc-gen-typescript/395a0baf65ec47f189ae033f86d461c7da1431b9/examples/bun-mysql2/bun.lockb -------------------------------------------------------------------------------- /examples/bun-mysql2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bun-mysql2", 3 | "module": "src/main.ts", 4 | "type": "module", 5 | "devDependencies": { 6 | "bun-types": "latest" 7 | }, 8 | "peerDependencies": { 9 | "typescript": "^5.0.0" 10 | }, 11 | "dependencies": { 12 | "mysql2": "^3.6.5" 13 | } 14 | } -------------------------------------------------------------------------------- /examples/bun-mysql2/src/db/query_sql.ts: -------------------------------------------------------------------------------- 1 | // Code generated by sqlc. DO NOT EDIT. 2 | 3 | import mysql, { RowDataPacket, ResultSetHeader } from "mysql2/promise"; 4 | 5 | type Client = mysql.Connection | mysql.Pool; 6 | 7 | export const getAuthorQuery = `-- name: GetAuthor :one 8 | SELECT id, name, bio FROM authors 9 | WHERE id = ? LIMIT 1`; 10 | 11 | export interface GetAuthorArgs { 12 | id: number; 13 | } 14 | 15 | export interface GetAuthorRow { 16 | id: number; 17 | name: string; 18 | bio: string | null; 19 | } 20 | 21 | export async function getAuthor(client: Client, args: GetAuthorArgs): Promise { 22 | const [rows] = await client.query({ 23 | sql: getAuthorQuery, 24 | values: [args.id], 25 | rowsAsArray: true 26 | }); 27 | if (rows.length !== 1) { 28 | return null; 29 | } 30 | const row = rows[0]; 31 | return { 32 | id: row[0], 33 | name: row[1], 34 | bio: row[2] 35 | }; 36 | } 37 | 38 | export const listAuthorsQuery = `-- name: ListAuthors :many 39 | SELECT id, name, bio FROM authors 40 | ORDER BY name`; 41 | 42 | export interface ListAuthorsRow { 43 | id: number; 44 | name: string; 45 | bio: string | null; 46 | } 47 | 48 | export async function listAuthors(client: Client): Promise { 49 | const [rows] = await client.query({ 50 | sql: listAuthorsQuery, 51 | values: [], 52 | rowsAsArray: true 53 | }); 54 | return rows.map(row => { 55 | return { 56 | id: row[0], 57 | name: row[1], 58 | bio: row[2] 59 | }; 60 | }); 61 | } 62 | 63 | export const createAuthorQuery = `-- name: CreateAuthor :exec 64 | INSERT INTO authors ( 65 | name, bio 66 | ) VALUES ( 67 | ?, ? 68 | )`; 69 | 70 | export interface CreateAuthorArgs { 71 | name: string; 72 | bio: string | null; 73 | } 74 | 75 | export async function createAuthor(client: Client, args: CreateAuthorArgs): Promise { 76 | await client.query({ 77 | sql: createAuthorQuery, 78 | values: [args.name, args.bio] 79 | }); 80 | } 81 | 82 | export const createAuthorReturnIdQuery = `-- name: CreateAuthorReturnId :execlastid 83 | INSERT INTO authors ( 84 | name, bio 85 | ) VALUES ( 86 | ?, ? 87 | )`; 88 | 89 | export interface CreateAuthorReturnIdArgs { 90 | name: string; 91 | bio: string | null; 92 | } 93 | 94 | export async function createAuthorReturnId(client: Client, args: CreateAuthorReturnIdArgs): Promise { 95 | const [result] = await client.query({ 96 | sql: createAuthorReturnIdQuery, 97 | values: [args.name, args.bio] 98 | }); 99 | return result?.insertId ?? 0; 100 | } 101 | 102 | export const deleteAuthorQuery = `-- name: DeleteAuthor :exec 103 | DELETE FROM authors 104 | WHERE id = ?`; 105 | 106 | export interface DeleteAuthorArgs { 107 | id: number; 108 | } 109 | 110 | export async function deleteAuthor(client: Client, args: DeleteAuthorArgs): Promise { 111 | await client.query({ 112 | sql: deleteAuthorQuery, 113 | values: [args.id] 114 | }); 115 | } 116 | 117 | export const testQuery = `-- name: Test :one 118 | SELECT c_bit, c_tinyint, c_bool, c_boolean, c_smallint, c_mediumint, c_int, c_integer, c_bigint, c_serial, c_decimal, c_dec, c_numeric, c_fixed, c_float, c_double, c_double_precision, c_date, c_time, c_datetime, c_timestamp, c_year, c_char, c_nchar, c_national_char, c_varchar, c_binary, c_varbinary, c_tinyblob, c_tinytext, c_blob, c_text, c_mediumblob, c_mediumtext, c_longblob, c_longtext, c_json FROM node_mysql_types 119 | LIMIT 1`; 120 | 121 | export interface TestRow { 122 | cBit: Buffer | null; 123 | cTinyint: number | null; 124 | cBool: number | null; 125 | cBoolean: number | null; 126 | cSmallint: number | null; 127 | cMediumint: number | null; 128 | cInt: number | null; 129 | cInteger: number | null; 130 | cBigint: number | null; 131 | cSerial: number; 132 | cDecimal: string | null; 133 | cDec: string | null; 134 | cNumeric: string | null; 135 | cFixed: string | null; 136 | cFloat: number | null; 137 | cDouble: number | null; 138 | cDoublePrecision: number | null; 139 | cDate: Date | null; 140 | cTime: string | null; 141 | cDatetime: Date | null; 142 | cTimestamp: Date | null; 143 | cYear: number | null; 144 | cChar: string | null; 145 | cNchar: string | null; 146 | cNationalChar: string | null; 147 | cVarchar: string | null; 148 | cBinary: Buffer | null; 149 | cVarbinary: Buffer | null; 150 | cTinyblob: Buffer | null; 151 | cTinytext: string | null; 152 | cBlob: Buffer | null; 153 | cText: string | null; 154 | cMediumblob: Buffer | null; 155 | cMediumtext: string | null; 156 | cLongblob: Buffer | null; 157 | cLongtext: string | null; 158 | cJson: any | null; 159 | } 160 | 161 | export async function test(client: Client): Promise { 162 | const [rows] = await client.query({ 163 | sql: testQuery, 164 | values: [], 165 | rowsAsArray: true 166 | }); 167 | if (rows.length !== 1) { 168 | return null; 169 | } 170 | const row = rows[0]; 171 | return { 172 | cBit: row[0], 173 | cTinyint: row[1], 174 | cBool: row[2], 175 | cBoolean: row[3], 176 | cSmallint: row[4], 177 | cMediumint: row[5], 178 | cInt: row[6], 179 | cInteger: row[7], 180 | cBigint: row[8], 181 | cSerial: row[9], 182 | cDecimal: row[10], 183 | cDec: row[11], 184 | cNumeric: row[12], 185 | cFixed: row[13], 186 | cFloat: row[14], 187 | cDouble: row[15], 188 | cDoublePrecision: row[16], 189 | cDate: row[17], 190 | cTime: row[18], 191 | cDatetime: row[19], 192 | cTimestamp: row[20], 193 | cYear: row[21], 194 | cChar: row[22], 195 | cNchar: row[23], 196 | cNationalChar: row[24], 197 | cVarchar: row[25], 198 | cBinary: row[26], 199 | cVarbinary: row[27], 200 | cTinyblob: row[28], 201 | cTinytext: row[29], 202 | cBlob: row[30], 203 | cText: row[31], 204 | cMediumblob: row[32], 205 | cMediumtext: row[33], 206 | cLongblob: row[34], 207 | cLongtext: row[35], 208 | cJson: row[36] 209 | }; 210 | } 211 | 212 | -------------------------------------------------------------------------------- /examples/bun-mysql2/src/main.ts: -------------------------------------------------------------------------------- 1 | import * as mysql from "mysql2/promise"; 2 | 3 | import { 4 | createAuthor, 5 | deleteAuthor, 6 | getAuthor, 7 | listAuthors, 8 | } from "./db/query_sql"; 9 | 10 | async function main() { 11 | const url = new URL(process.env["DATABASE_URL"] ?? ""); 12 | 13 | const client = mysql.createPool({ 14 | host: url.hostname, 15 | port: parseInt(url.port, 10), 16 | user: url.username, 17 | password: url.password, 18 | database: url.pathname.substring(1), 19 | ssl: { 20 | // TODO: FIXME 21 | rejectUnauthorized: false, 22 | }, 23 | }); 24 | 25 | // Create an author 26 | await createAuthor(client, { 27 | name: "Seal", 28 | bio: "Kissed from a rose", 29 | }); 30 | 31 | // List the authors 32 | const authors = await listAuthors(client); 33 | console.log(authors); 34 | 35 | // Get that author 36 | const seal = await getAuthor(client, { id: authors[0].id }); 37 | if (seal === null) { 38 | throw new Error("seal not found"); 39 | } 40 | console.log(seal); 41 | 42 | // Delete the author 43 | await deleteAuthor(client, { id: seal.id }); 44 | } 45 | 46 | (async () => { 47 | try { 48 | await main(); 49 | process.exit(0); 50 | } catch (e) { 51 | console.error(e); 52 | process.exit(1); 53 | } 54 | })(); 55 | -------------------------------------------------------------------------------- /examples/bun-mysql2/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": ["ESNext"], 4 | "module": "esnext", 5 | "target": "esnext", 6 | "moduleResolution": "bundler", 7 | "moduleDetection": "force", 8 | "allowImportingTsExtensions": true, 9 | "noEmit": true, 10 | "composite": true, 11 | "strict": true, 12 | "downlevelIteration": true, 13 | "skipLibCheck": true, 14 | "jsx": "react-jsx", 15 | "allowSyntheticDefaultImports": true, 16 | "forceConsistentCasingInFileNames": true, 17 | "allowJs": true, 18 | "types": [ 19 | "bun-types" // add Bun global 20 | ] 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /examples/bun-pg/.gitignore: -------------------------------------------------------------------------------- 1 | # Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore 2 | 3 | # Logs 4 | 5 | logs 6 | _.log 7 | npm-debug.log_ 8 | yarn-debug.log* 9 | yarn-error.log* 10 | lerna-debug.log* 11 | .pnpm-debug.log* 12 | 13 | # Diagnostic reports (https://nodejs.org/api/report.html) 14 | 15 | report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json 16 | 17 | # Runtime data 18 | 19 | pids 20 | _.pid 21 | _.seed 22 | \*.pid.lock 23 | 24 | # Directory for instrumented libs generated by jscoverage/JSCover 25 | 26 | lib-cov 27 | 28 | # Coverage directory used by tools like istanbul 29 | 30 | coverage 31 | \*.lcov 32 | 33 | # nyc test coverage 34 | 35 | .nyc_output 36 | 37 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 38 | 39 | .grunt 40 | 41 | # Bower dependency directory (https://bower.io/) 42 | 43 | bower_components 44 | 45 | # node-waf configuration 46 | 47 | .lock-wscript 48 | 49 | # Compiled binary addons (https://nodejs.org/api/addons.html) 50 | 51 | build/Release 52 | 53 | # Dependency directories 54 | 55 | node_modules/ 56 | jspm_packages/ 57 | 58 | # Snowpack dependency directory (https://snowpack.dev/) 59 | 60 | web_modules/ 61 | 62 | # TypeScript cache 63 | 64 | \*.tsbuildinfo 65 | 66 | # Optional npm cache directory 67 | 68 | .npm 69 | 70 | # Optional eslint cache 71 | 72 | .eslintcache 73 | 74 | # Optional stylelint cache 75 | 76 | .stylelintcache 77 | 78 | # Microbundle cache 79 | 80 | .rpt2_cache/ 81 | .rts2_cache_cjs/ 82 | .rts2_cache_es/ 83 | .rts2_cache_umd/ 84 | 85 | # Optional REPL history 86 | 87 | .node_repl_history 88 | 89 | # Output of 'npm pack' 90 | 91 | \*.tgz 92 | 93 | # Yarn Integrity file 94 | 95 | .yarn-integrity 96 | 97 | # dotenv environment variable files 98 | 99 | .env 100 | .env.development.local 101 | .env.test.local 102 | .env.production.local 103 | .env.local 104 | 105 | # parcel-bundler cache (https://parceljs.org/) 106 | 107 | .cache 108 | .parcel-cache 109 | 110 | # Next.js build output 111 | 112 | .next 113 | out 114 | 115 | # Nuxt.js build / generate output 116 | 117 | .nuxt 118 | dist 119 | 120 | # Gatsby files 121 | 122 | .cache/ 123 | 124 | # Comment in the public line in if your project uses Gatsby and not Next.js 125 | 126 | # https://nextjs.org/blog/next-9-1#public-directory-support 127 | 128 | # public 129 | 130 | # vuepress build output 131 | 132 | .vuepress/dist 133 | 134 | # vuepress v2.x temp and cache directory 135 | 136 | .temp 137 | .cache 138 | 139 | # Docusaurus cache and generated files 140 | 141 | .docusaurus 142 | 143 | # Serverless directories 144 | 145 | .serverless/ 146 | 147 | # FuseBox cache 148 | 149 | .fusebox/ 150 | 151 | # DynamoDB Local files 152 | 153 | .dynamodb/ 154 | 155 | # TernJS port file 156 | 157 | .tern-port 158 | 159 | # Stores VSCode versions used for testing VSCode extensions 160 | 161 | .vscode-test 162 | 163 | # yarn v2 164 | 165 | .yarn/cache 166 | .yarn/unplugged 167 | .yarn/build-state.yml 168 | .yarn/install-state.gz 169 | .pnp.\* 170 | 171 | # IntelliJ based IDEs 172 | .idea 173 | 174 | # Finder (MacOS) folder config 175 | .DS_Store 176 | 177 | -------------------------------------------------------------------------------- /examples/bun-pg/README.md: -------------------------------------------------------------------------------- 1 | # bun-pg 2 | 3 | To install dependencies: 4 | 5 | ```bash 6 | bun install 7 | ``` 8 | 9 | To run: 10 | 11 | ```bash 12 | bun run src/main.ts 13 | ``` 14 | 15 | This project was created using `bun init` in bun v1.0.11. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime. 16 | -------------------------------------------------------------------------------- /examples/bun-pg/bun.lockb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqlc-dev/sqlc-gen-typescript/395a0baf65ec47f189ae033f86d461c7da1431b9/examples/bun-pg/bun.lockb -------------------------------------------------------------------------------- /examples/bun-pg/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bun-pg", 3 | "module": "src/main.ts", 4 | "type": "module", 5 | "devDependencies": { 6 | "bun-types": "latest" 7 | }, 8 | "peerDependencies": { 9 | "typescript": "^5.0.0" 10 | }, 11 | "dependencies": { 12 | "pg": "^8.11.3" 13 | } 14 | } -------------------------------------------------------------------------------- /examples/bun-pg/src/db/query_sql.ts: -------------------------------------------------------------------------------- 1 | // Code generated by sqlc. DO NOT EDIT. 2 | 3 | import { QueryArrayConfig, QueryArrayResult } from "pg"; 4 | 5 | interface Client { 6 | query: (config: QueryArrayConfig) => Promise; 7 | } 8 | 9 | export const getAuthorQuery = `-- name: GetAuthor :one 10 | SELECT id, name, bio FROM authors 11 | WHERE id = $1 LIMIT 1`; 12 | 13 | export interface GetAuthorArgs { 14 | id: string; 15 | } 16 | 17 | export interface GetAuthorRow { 18 | id: string; 19 | name: string; 20 | bio: string | null; 21 | } 22 | 23 | export async function getAuthor(client: Client, args: GetAuthorArgs): Promise { 24 | const result = await client.query({ 25 | text: getAuthorQuery, 26 | values: [args.id], 27 | rowMode: "array" 28 | }); 29 | if (result.rows.length !== 1) { 30 | return null; 31 | } 32 | const row = result.rows[0]; 33 | return { 34 | id: row[0], 35 | name: row[1], 36 | bio: row[2] 37 | }; 38 | } 39 | 40 | export const listAuthorsQuery = `-- name: ListAuthors :many 41 | SELECT id, name, bio FROM authors 42 | ORDER BY name`; 43 | 44 | export interface ListAuthorsRow { 45 | id: string; 46 | name: string; 47 | bio: string | null; 48 | } 49 | 50 | export async function listAuthors(client: Client): Promise { 51 | const result = await client.query({ 52 | text: listAuthorsQuery, 53 | values: [], 54 | rowMode: "array" 55 | }); 56 | return result.rows.map(row => { 57 | return { 58 | id: row[0], 59 | name: row[1], 60 | bio: row[2] 61 | }; 62 | }); 63 | } 64 | 65 | export const createAuthorQuery = `-- name: CreateAuthor :one 66 | INSERT INTO authors ( 67 | name, bio 68 | ) VALUES ( 69 | $1, $2 70 | ) 71 | RETURNING id, name, bio`; 72 | 73 | export interface CreateAuthorArgs { 74 | name: string; 75 | bio: string | null; 76 | } 77 | 78 | export interface CreateAuthorRow { 79 | id: string; 80 | name: string; 81 | bio: string | null; 82 | } 83 | 84 | export async function createAuthor(client: Client, args: CreateAuthorArgs): Promise { 85 | const result = await client.query({ 86 | text: createAuthorQuery, 87 | values: [args.name, args.bio], 88 | rowMode: "array" 89 | }); 90 | if (result.rows.length !== 1) { 91 | return null; 92 | } 93 | const row = result.rows[0]; 94 | return { 95 | id: row[0], 96 | name: row[1], 97 | bio: row[2] 98 | }; 99 | } 100 | 101 | export const deleteAuthorQuery = `-- name: DeleteAuthor :exec 102 | DELETE FROM authors 103 | WHERE id = $1`; 104 | 105 | export interface DeleteAuthorArgs { 106 | id: string; 107 | } 108 | 109 | export async function deleteAuthor(client: Client, args: DeleteAuthorArgs): Promise { 110 | await client.query({ 111 | text: deleteAuthorQuery, 112 | values: [args.id], 113 | rowMode: "array" 114 | }); 115 | } 116 | 117 | -------------------------------------------------------------------------------- /examples/bun-pg/src/main.ts: -------------------------------------------------------------------------------- 1 | import { Pool } from "pg"; 2 | 3 | import { 4 | createAuthor, 5 | deleteAuthor, 6 | getAuthor, 7 | listAuthors, 8 | } from "./db/query_sql"; 9 | 10 | async function main() { 11 | const client = new Pool({ connectionString: process.env["DATABASE_URL"] }); 12 | await client.connect(); 13 | 14 | // Create an author 15 | const author = await createAuthor(client, { 16 | name: "Seal", 17 | bio: "Kissed from a rose", 18 | }); 19 | if (author === null) { 20 | throw new Error("author not created"); 21 | } 22 | console.log(author); 23 | 24 | // List the authors 25 | const authors = await listAuthors(client); 26 | console.log(authors); 27 | 28 | // Get that author 29 | const seal = await getAuthor(client, { id: author.id }); 30 | if (seal === null) { 31 | throw new Error("seal not found"); 32 | } 33 | console.log(seal); 34 | 35 | // Delete the author 36 | await deleteAuthor(client, { id: seal.id }); 37 | } 38 | 39 | (async () => { 40 | try { 41 | await main(); 42 | process.exit(0); 43 | } catch (e) { 44 | console.error(e); 45 | process.exit(1); 46 | } 47 | })(); 48 | -------------------------------------------------------------------------------- /examples/bun-pg/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": ["ESNext"], 4 | "module": "esnext", 5 | "target": "esnext", 6 | "moduleResolution": "bundler", 7 | "moduleDetection": "force", 8 | "allowImportingTsExtensions": true, 9 | "noEmit": true, 10 | "composite": true, 11 | "strict": true, 12 | "downlevelIteration": true, 13 | "skipLibCheck": true, 14 | "jsx": "react-jsx", 15 | "allowSyntheticDefaultImports": true, 16 | "forceConsistentCasingInFileNames": true, 17 | "allowJs": true, 18 | "types": [ 19 | "bun-types" // add Bun global 20 | ] 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /examples/bun-postgres/.gitignore: -------------------------------------------------------------------------------- 1 | # Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore 2 | 3 | # Logs 4 | 5 | logs 6 | _.log 7 | npm-debug.log_ 8 | yarn-debug.log* 9 | yarn-error.log* 10 | lerna-debug.log* 11 | .pnpm-debug.log* 12 | 13 | # Diagnostic reports (https://nodejs.org/api/report.html) 14 | 15 | report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json 16 | 17 | # Runtime data 18 | 19 | pids 20 | _.pid 21 | _.seed 22 | \*.pid.lock 23 | 24 | # Directory for instrumented libs generated by jscoverage/JSCover 25 | 26 | lib-cov 27 | 28 | # Coverage directory used by tools like istanbul 29 | 30 | coverage 31 | \*.lcov 32 | 33 | # nyc test coverage 34 | 35 | .nyc_output 36 | 37 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 38 | 39 | .grunt 40 | 41 | # Bower dependency directory (https://bower.io/) 42 | 43 | bower_components 44 | 45 | # node-waf configuration 46 | 47 | .lock-wscript 48 | 49 | # Compiled binary addons (https://nodejs.org/api/addons.html) 50 | 51 | build/Release 52 | 53 | # Dependency directories 54 | 55 | node_modules/ 56 | jspm_packages/ 57 | 58 | # Snowpack dependency directory (https://snowpack.dev/) 59 | 60 | web_modules/ 61 | 62 | # TypeScript cache 63 | 64 | \*.tsbuildinfo 65 | 66 | # Optional npm cache directory 67 | 68 | .npm 69 | 70 | # Optional eslint cache 71 | 72 | .eslintcache 73 | 74 | # Optional stylelint cache 75 | 76 | .stylelintcache 77 | 78 | # Microbundle cache 79 | 80 | .rpt2_cache/ 81 | .rts2_cache_cjs/ 82 | .rts2_cache_es/ 83 | .rts2_cache_umd/ 84 | 85 | # Optional REPL history 86 | 87 | .node_repl_history 88 | 89 | # Output of 'npm pack' 90 | 91 | \*.tgz 92 | 93 | # Yarn Integrity file 94 | 95 | .yarn-integrity 96 | 97 | # dotenv environment variable files 98 | 99 | .env 100 | .env.development.local 101 | .env.test.local 102 | .env.production.local 103 | .env.local 104 | 105 | # parcel-bundler cache (https://parceljs.org/) 106 | 107 | .cache 108 | .parcel-cache 109 | 110 | # Next.js build output 111 | 112 | .next 113 | out 114 | 115 | # Nuxt.js build / generate output 116 | 117 | .nuxt 118 | dist 119 | 120 | # Gatsby files 121 | 122 | .cache/ 123 | 124 | # Comment in the public line in if your project uses Gatsby and not Next.js 125 | 126 | # https://nextjs.org/blog/next-9-1#public-directory-support 127 | 128 | # public 129 | 130 | # vuepress build output 131 | 132 | .vuepress/dist 133 | 134 | # vuepress v2.x temp and cache directory 135 | 136 | .temp 137 | .cache 138 | 139 | # Docusaurus cache and generated files 140 | 141 | .docusaurus 142 | 143 | # Serverless directories 144 | 145 | .serverless/ 146 | 147 | # FuseBox cache 148 | 149 | .fusebox/ 150 | 151 | # DynamoDB Local files 152 | 153 | .dynamodb/ 154 | 155 | # TernJS port file 156 | 157 | .tern-port 158 | 159 | # Stores VSCode versions used for testing VSCode extensions 160 | 161 | .vscode-test 162 | 163 | # yarn v2 164 | 165 | .yarn/cache 166 | .yarn/unplugged 167 | .yarn/build-state.yml 168 | .yarn/install-state.gz 169 | .pnp.\* 170 | 171 | # IntelliJ based IDEs 172 | .idea 173 | 174 | # Finder (MacOS) folder config 175 | .DS_Store 176 | 177 | -------------------------------------------------------------------------------- /examples/bun-postgres/README.md: -------------------------------------------------------------------------------- 1 | # bun-postgres 2 | 3 | To install dependencies: 4 | 5 | ```bash 6 | bun install 7 | ``` 8 | 9 | To run: 10 | 11 | ```bash 12 | bun run src/main.ts 13 | ``` 14 | 15 | This project was created using `bun init` in bun v1.0.11. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime. 16 | -------------------------------------------------------------------------------- /examples/bun-postgres/bun.lockb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqlc-dev/sqlc-gen-typescript/395a0baf65ec47f189ae033f86d461c7da1431b9/examples/bun-postgres/bun.lockb -------------------------------------------------------------------------------- /examples/bun-postgres/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bun-postgres", 3 | "module": "src/main.ts", 4 | "type": "module", 5 | "devDependencies": { 6 | "bun-types": "latest" 7 | }, 8 | "peerDependencies": { 9 | "typescript": "^5.0.0" 10 | }, 11 | "dependencies": { 12 | "postgres": "^3.4.3" 13 | } 14 | } -------------------------------------------------------------------------------- /examples/bun-postgres/src/db/query_sql.ts: -------------------------------------------------------------------------------- 1 | // Code generated by sqlc. DO NOT EDIT. 2 | 3 | import { Sql } from "postgres"; 4 | 5 | export const getAuthorQuery = `-- name: GetAuthor :one 6 | SELECT id, name, bio FROM authors 7 | WHERE id = $1 LIMIT 1`; 8 | 9 | export interface GetAuthorArgs { 10 | id: string; 11 | } 12 | 13 | export interface GetAuthorRow { 14 | id: string; 15 | name: string; 16 | bio: string | null; 17 | } 18 | 19 | export async function getAuthor(sql: Sql, args: GetAuthorArgs): Promise { 20 | const rows = await sql.unsafe(getAuthorQuery, [args.id]).values(); 21 | if (rows.length !== 1) { 22 | return null; 23 | } 24 | const row = rows[0]; 25 | if (!row) { 26 | return null; 27 | } 28 | return { 29 | id: row[0], 30 | name: row[1], 31 | bio: row[2] 32 | }; 33 | } 34 | 35 | export const listAuthorsQuery = `-- name: ListAuthors :many 36 | SELECT id, name, bio FROM authors 37 | ORDER BY name`; 38 | 39 | export interface ListAuthorsRow { 40 | id: string; 41 | name: string; 42 | bio: string | null; 43 | } 44 | 45 | export async function listAuthors(sql: Sql): Promise { 46 | return (await sql.unsafe(listAuthorsQuery, []).values()).map(row => ({ 47 | id: row[0], 48 | name: row[1], 49 | bio: row[2] 50 | })); 51 | } 52 | 53 | export const createAuthorQuery = `-- name: CreateAuthor :one 54 | INSERT INTO authors ( 55 | name, bio 56 | ) VALUES ( 57 | $1, $2 58 | ) 59 | RETURNING id, name, bio`; 60 | 61 | export interface CreateAuthorArgs { 62 | name: string; 63 | bio: string | null; 64 | } 65 | 66 | export interface CreateAuthorRow { 67 | id: string; 68 | name: string; 69 | bio: string | null; 70 | } 71 | 72 | export async function createAuthor(sql: Sql, args: CreateAuthorArgs): Promise { 73 | const rows = await sql.unsafe(createAuthorQuery, [args.name, args.bio]).values(); 74 | if (rows.length !== 1) { 75 | return null; 76 | } 77 | const row = rows[0]; 78 | if (!row) { 79 | return null; 80 | } 81 | return { 82 | id: row[0], 83 | name: row[1], 84 | bio: row[2] 85 | }; 86 | } 87 | 88 | export const deleteAuthorQuery = `-- name: DeleteAuthor :exec 89 | DELETE FROM authors 90 | WHERE id = $1`; 91 | 92 | export interface DeleteAuthorArgs { 93 | id: string; 94 | } 95 | 96 | export async function deleteAuthor(sql: Sql, args: DeleteAuthorArgs): Promise { 97 | await sql.unsafe(deleteAuthorQuery, [args.id]); 98 | } 99 | 100 | -------------------------------------------------------------------------------- /examples/bun-postgres/src/main.ts: -------------------------------------------------------------------------------- 1 | import postgres from "postgres"; 2 | 3 | import { 4 | createAuthor, 5 | deleteAuthor, 6 | getAuthor, 7 | listAuthors, 8 | } from "./db/query_sql"; 9 | 10 | async function main() { 11 | const sql = postgres(process.env["DATABASE_URL"] ?? ""); 12 | 13 | // Create an author 14 | const author = await createAuthor(sql, { 15 | name: "Seal", 16 | bio: "Kissed from a rose", 17 | }); 18 | if (author === null) { 19 | throw new Error("author not created"); 20 | } 21 | console.log(author); 22 | 23 | // List the authors 24 | const authors = await listAuthors(sql); 25 | console.log(authors); 26 | 27 | // Get that author 28 | const seal = await getAuthor(sql, { id: author.id }); 29 | if (seal === null) { 30 | throw new Error("seal not found"); 31 | } 32 | console.log(seal); 33 | 34 | // Delete the author 35 | await deleteAuthor(sql, { id: seal.id }); 36 | } 37 | 38 | (async () => { 39 | try { 40 | await main(); 41 | process.exit(0); 42 | } catch (e) { 43 | console.error(e); 44 | process.exit(1); 45 | } 46 | })(); 47 | -------------------------------------------------------------------------------- /examples/bun-postgres/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": ["ESNext"], 4 | "module": "esnext", 5 | "target": "esnext", 6 | "moduleResolution": "bundler", 7 | "moduleDetection": "force", 8 | "allowImportingTsExtensions": true, 9 | "noEmit": true, 10 | "composite": true, 11 | "strict": true, 12 | "downlevelIteration": true, 13 | "skipLibCheck": true, 14 | "jsx": "react-jsx", 15 | "allowSyntheticDefaultImports": true, 16 | "forceConsistentCasingInFileNames": true, 17 | "allowJs": true, 18 | "types": [ 19 | "bun-types" // add Bun global 20 | ] 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /examples/node-better-sqlite3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-better-sqlite3", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "src/main.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "@types/better-sqlite3": "^7.6.9", 13 | "typescript": "^5.2.2" 14 | }, 15 | "dependencies": { 16 | "better-sqlite3": "^9.4.1" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /examples/node-better-sqlite3/src/db/query_sql.ts: -------------------------------------------------------------------------------- 1 | // Code generated by sqlc. DO NOT EDIT. 2 | 3 | import { Database } from "better-sqlite3"; 4 | 5 | export const getAuthorQuery = `-- name: GetAuthor :one 6 | SELECT id, name, bio FROM authors 7 | WHERE id = ? LIMIT 1`; 8 | 9 | export interface GetAuthorArgs { 10 | id: any; 11 | } 12 | 13 | export interface GetAuthorRow { 14 | id: any; 15 | name: any; 16 | bio: any | null; 17 | } 18 | 19 | export async function getAuthor(database: Database, args: GetAuthorArgs): Promise { 20 | const stmt = database.prepare(getAuthorQuery); 21 | const result = await stmt.get(args.id); 22 | if (result == undefined) { 23 | return null; 24 | } 25 | return result as GetAuthorRow; 26 | } 27 | 28 | export const listAuthorsQuery = `-- name: ListAuthors :many 29 | SELECT id, name, bio FROM authors 30 | ORDER BY name`; 31 | 32 | export interface ListAuthorsRow { 33 | id: any; 34 | name: any; 35 | bio: any | null; 36 | } 37 | 38 | export async function listAuthors(database: Database): Promise { 39 | const stmt = database.prepare(listAuthorsQuery); 40 | const result = await stmt.all(); 41 | return result as ListAuthorsRow[]; 42 | } 43 | 44 | export const createAuthorQuery = `-- name: CreateAuthor :exec 45 | INSERT INTO authors ( 46 | name, bio 47 | ) VALUES ( 48 | ?, ? 49 | )`; 50 | 51 | export interface CreateAuthorArgs { 52 | name: any; 53 | bio: any | null; 54 | } 55 | 56 | export async function createAuthor(database: Database, args: CreateAuthorArgs): Promise { 57 | const stmt = database.prepare(createAuthorQuery); 58 | await stmt.run(args.name, args.bio); 59 | } 60 | 61 | export const deleteAuthorQuery = `-- name: DeleteAuthor :exec 62 | DELETE FROM authors 63 | WHERE id = ?`; 64 | 65 | export interface DeleteAuthorArgs { 66 | id: any; 67 | } 68 | 69 | export async function deleteAuthor(database: Database, args: DeleteAuthorArgs): Promise { 70 | const stmt = database.prepare(deleteAuthorQuery); 71 | await stmt.run(args.id); 72 | } 73 | 74 | -------------------------------------------------------------------------------- /examples/node-better-sqlite3/src/main.ts: -------------------------------------------------------------------------------- 1 | import Database from "better-sqlite3"; 2 | import { readFile } from "node:fs/promises"; 3 | import { join } from "node:path"; 4 | 5 | import { 6 | createAuthor, 7 | deleteAuthor, 8 | getAuthor, 9 | listAuthors, 10 | } from "./db/query_sql"; 11 | 12 | interface Author { 13 | id: string; 14 | name: string; 15 | bio: string | null; 16 | } 17 | 18 | async function main() { 19 | const ddl = await readFile(join(__dirname, "../../authors/sqlite/schema.sql"), { encoding: 'utf-8' }); 20 | const database = new Database(":memory:"); 21 | 22 | // Create tables 23 | database.exec(ddl); 24 | 25 | // Create an author 26 | await createAuthor(database, { 27 | name: "Seal", 28 | bio: "Kissed from a rose", 29 | }); 30 | 31 | // List the authors 32 | const authors = await listAuthors(database); 33 | console.log(authors); 34 | 35 | // Get that author 36 | const seal = await getAuthor(database, { id: authors[0].id }); 37 | if (seal === null) { 38 | throw new Error("seal not found"); 39 | } 40 | console.log(seal); 41 | 42 | // Delete the author 43 | await deleteAuthor(database, { id: seal.id }); 44 | } 45 | 46 | (async () => { 47 | try { 48 | await main(); 49 | process.exit(0); 50 | } catch (e) { 51 | console.error(e); 52 | process.exit(1); 53 | } 54 | })(); 55 | -------------------------------------------------------------------------------- /examples/node-better-sqlite3/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig to read more about this file */ 4 | 5 | /* Projects */ 6 | // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ 7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 8 | // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ 9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ 10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 12 | 13 | /* Language and Environment */ 14 | "target": "es2020", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 15 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 16 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 17 | // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ 18 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 19 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ 20 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 21 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ 22 | // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ 23 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 24 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 25 | // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ 26 | 27 | /* Modules */ 28 | "module": "commonjs", /* Specify what module code is generated. */ 29 | // "rootDir": "./", /* Specify the root folder within your source files. */ 30 | // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ 31 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 32 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 33 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 34 | // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ 35 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */ 36 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 37 | // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ 38 | // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ 39 | // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ 40 | // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ 41 | // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ 42 | // "resolveJsonModule": true, /* Enable importing .json files. */ 43 | // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ 44 | // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ 45 | 46 | /* JavaScript Support */ 47 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ 48 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 49 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ 50 | 51 | /* Emit */ 52 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 53 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 54 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 55 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 56 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 57 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ 58 | // "outDir": "./", /* Specify an output folder for all emitted files. */ 59 | // "removeComments": true, /* Disable emitting comments. */ 60 | // "noEmit": true, /* Disable emitting files from a compilation. */ 61 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 62 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ 63 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 64 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 65 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 66 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 67 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 68 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 69 | // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ 70 | // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ 71 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 72 | // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ 73 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 74 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 75 | 76 | /* Interop Constraints */ 77 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 78 | // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ 79 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 80 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ 81 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 82 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 83 | 84 | /* Type Checking */ 85 | "strict": true, /* Enable all strict type-checking options. */ 86 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ 87 | // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ 88 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 89 | // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ 90 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 91 | // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ 92 | // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ 93 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 94 | // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ 95 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ 96 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 97 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 98 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 99 | // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ 100 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 101 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ 102 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 103 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 104 | 105 | /* Completeness */ 106 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 107 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /examples/node-mysql2/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mysql2", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "mysql2", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "mysql2": "^3.6.3" 13 | }, 14 | "devDependencies": { 15 | "@types/node": "^20.9.0", 16 | "typescript": "^5.3.2" 17 | } 18 | }, 19 | "node_modules/@types/node": { 20 | "version": "20.9.0", 21 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.9.0.tgz", 22 | "integrity": "sha512-nekiGu2NDb1BcVofVcEKMIwzlx4NjHlcjhoxxKBNLtz15Y1z7MYf549DFvkHSId02Ax6kGwWntIBPC3l/JZcmw==", 23 | "dev": true, 24 | "dependencies": { 25 | "undici-types": "~5.26.4" 26 | } 27 | }, 28 | "node_modules/denque": { 29 | "version": "2.1.0", 30 | "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", 31 | "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", 32 | "engines": { 33 | "node": ">=0.10" 34 | } 35 | }, 36 | "node_modules/generate-function": { 37 | "version": "2.3.1", 38 | "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", 39 | "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", 40 | "dependencies": { 41 | "is-property": "^1.0.2" 42 | } 43 | }, 44 | "node_modules/iconv-lite": { 45 | "version": "0.6.3", 46 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", 47 | "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", 48 | "dependencies": { 49 | "safer-buffer": ">= 2.1.2 < 3.0.0" 50 | }, 51 | "engines": { 52 | "node": ">=0.10.0" 53 | } 54 | }, 55 | "node_modules/is-property": { 56 | "version": "1.0.2", 57 | "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", 58 | "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==" 59 | }, 60 | "node_modules/long": { 61 | "version": "5.2.3", 62 | "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", 63 | "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" 64 | }, 65 | "node_modules/lru-cache": { 66 | "version": "8.0.5", 67 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz", 68 | "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==", 69 | "engines": { 70 | "node": ">=16.14" 71 | } 72 | }, 73 | "node_modules/mysql2": { 74 | "version": "3.6.3", 75 | "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.6.3.tgz", 76 | "integrity": "sha512-qYd/1CDuW1KYZjD4tzg2O8YS3X/UWuGH8ZMHyMeggMTXL3yOdMisbwZ5SNkHzDGlZXKYLAvV8tMrEH+NUMz3fw==", 77 | "dependencies": { 78 | "denque": "^2.1.0", 79 | "generate-function": "^2.3.1", 80 | "iconv-lite": "^0.6.3", 81 | "long": "^5.2.1", 82 | "lru-cache": "^8.0.0", 83 | "named-placeholders": "^1.1.3", 84 | "seq-queue": "^0.0.5", 85 | "sqlstring": "^2.3.2" 86 | }, 87 | "engines": { 88 | "node": ">= 8.0" 89 | } 90 | }, 91 | "node_modules/named-placeholders": { 92 | "version": "1.1.3", 93 | "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.3.tgz", 94 | "integrity": "sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w==", 95 | "dependencies": { 96 | "lru-cache": "^7.14.1" 97 | }, 98 | "engines": { 99 | "node": ">=12.0.0" 100 | } 101 | }, 102 | "node_modules/named-placeholders/node_modules/lru-cache": { 103 | "version": "7.18.3", 104 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", 105 | "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", 106 | "engines": { 107 | "node": ">=12" 108 | } 109 | }, 110 | "node_modules/safer-buffer": { 111 | "version": "2.1.2", 112 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 113 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 114 | }, 115 | "node_modules/seq-queue": { 116 | "version": "0.0.5", 117 | "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", 118 | "integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==" 119 | }, 120 | "node_modules/sqlstring": { 121 | "version": "2.3.3", 122 | "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz", 123 | "integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==", 124 | "engines": { 125 | "node": ">= 0.6" 126 | } 127 | }, 128 | "node_modules/typescript": { 129 | "version": "5.3.2", 130 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.2.tgz", 131 | "integrity": "sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==", 132 | "dev": true, 133 | "bin": { 134 | "tsc": "bin/tsc", 135 | "tsserver": "bin/tsserver" 136 | }, 137 | "engines": { 138 | "node": ">=14.17" 139 | } 140 | }, 141 | "node_modules/undici-types": { 142 | "version": "5.26.5", 143 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", 144 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", 145 | "dev": true 146 | } 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /examples/node-mysql2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mysql2", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "mysql2": "^3.6.3" 13 | }, 14 | "devDependencies": { 15 | "@types/node": "^20.9.0", 16 | "typescript": "^5.3.2" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /examples/node-mysql2/src/db/query_sql.ts: -------------------------------------------------------------------------------- 1 | // Code generated by sqlc. DO NOT EDIT. 2 | 3 | import mysql, { RowDataPacket, ResultSetHeader } from "mysql2/promise"; 4 | 5 | type Client = mysql.Connection | mysql.Pool; 6 | 7 | export const getAuthorQuery = `-- name: GetAuthor :one 8 | SELECT id, name, bio FROM authors 9 | WHERE id = ? LIMIT 1`; 10 | 11 | export interface GetAuthorArgs { 12 | id: string; 13 | } 14 | 15 | export interface GetAuthorRow { 16 | id: string; 17 | name: string; 18 | bio: string | null; 19 | } 20 | 21 | export async function getAuthor(client: Client, args: GetAuthorArgs): Promise { 22 | const [rows] = await client.query({ 23 | sql: getAuthorQuery, 24 | values: [args.id], 25 | rowsAsArray: true 26 | }); 27 | if (rows.length !== 1) { 28 | return null; 29 | } 30 | const row = rows[0]; 31 | return { 32 | id: row[0], 33 | name: row[1], 34 | bio: row[2] 35 | }; 36 | } 37 | 38 | export const listAuthorsQuery = `-- name: ListAuthors :many 39 | SELECT id, name, bio FROM authors 40 | ORDER BY name`; 41 | 42 | export interface ListAuthorsRow { 43 | id: string; 44 | name: string; 45 | bio: string | null; 46 | } 47 | 48 | export async function listAuthors(client: Client): Promise { 49 | const [rows] = await client.query({ 50 | sql: listAuthorsQuery, 51 | values: [], 52 | rowsAsArray: true 53 | }); 54 | return rows.map(row => { 55 | return { 56 | id: row[0], 57 | name: row[1], 58 | bio: row[2] 59 | }; 60 | }); 61 | } 62 | 63 | export const createAuthorQuery = `-- name: CreateAuthor :exec 64 | INSERT INTO authors ( 65 | name, bio 66 | ) VALUES ( 67 | ?, ? 68 | )`; 69 | 70 | export interface CreateAuthorArgs { 71 | name: string; 72 | bio: string | null; 73 | } 74 | 75 | export async function createAuthor(client: Client, args: CreateAuthorArgs): Promise { 76 | await client.query({ 77 | sql: createAuthorQuery, 78 | values: [args.name, args.bio] 79 | }); 80 | } 81 | 82 | export const createAuthorReturnIdQuery = `-- name: CreateAuthorReturnId :execlastid 83 | INSERT INTO authors ( 84 | name, bio 85 | ) VALUES ( 86 | ?, ? 87 | )`; 88 | 89 | export interface CreateAuthorReturnIdArgs { 90 | name: string; 91 | bio: string | null; 92 | } 93 | 94 | export async function createAuthorReturnId(client: Client, args: CreateAuthorReturnIdArgs): Promise { 95 | const [result] = await client.query({ 96 | sql: createAuthorReturnIdQuery, 97 | values: [args.name, args.bio] 98 | }); 99 | return result?.insertId ?? 0; 100 | } 101 | 102 | export const deleteAuthorQuery = `-- name: DeleteAuthor :exec 103 | DELETE FROM authors 104 | WHERE id = ?`; 105 | 106 | export interface DeleteAuthorArgs { 107 | id: string; 108 | } 109 | 110 | export async function deleteAuthor(client: Client, args: DeleteAuthorArgs): Promise { 111 | await client.query({ 112 | sql: deleteAuthorQuery, 113 | values: [args.id] 114 | }); 115 | } 116 | 117 | export const testQuery = `-- name: Test :one 118 | SELECT c_bit, c_tinyint, c_bool, c_boolean, c_smallint, c_mediumint, c_int, c_integer, c_bigint, c_serial, c_decimal, c_dec, c_numeric, c_fixed, c_float, c_double, c_double_precision, c_date, c_time, c_datetime, c_timestamp, c_year, c_char, c_nchar, c_national_char, c_varchar, c_binary, c_varbinary, c_tinyblob, c_tinytext, c_blob, c_text, c_mediumblob, c_mediumtext, c_longblob, c_longtext, c_json FROM node_mysql_types 119 | LIMIT 1`; 120 | 121 | export interface TestRow { 122 | cBit: Buffer | null; 123 | cTinyint: number | null; 124 | cBool: number | null; 125 | cBoolean: number | null; 126 | cSmallint: number | null; 127 | cMediumint: number | null; 128 | cInt: number | null; 129 | cInteger: number | null; 130 | cBigint: string | null; 131 | cSerial: string; 132 | cDecimal: string | null; 133 | cDec: string | null; 134 | cNumeric: string | null; 135 | cFixed: string | null; 136 | cFloat: number | null; 137 | cDouble: number | null; 138 | cDoublePrecision: number | null; 139 | cDate: Date | null; 140 | cTime: string | null; 141 | cDatetime: Date | null; 142 | cTimestamp: Date | null; 143 | cYear: number | null; 144 | cChar: string | null; 145 | cNchar: string | null; 146 | cNationalChar: string | null; 147 | cVarchar: string | null; 148 | cBinary: Buffer | null; 149 | cVarbinary: Buffer | null; 150 | cTinyblob: Buffer | null; 151 | cTinytext: string | null; 152 | cBlob: Buffer | null; 153 | cText: string | null; 154 | cMediumblob: Buffer | null; 155 | cMediumtext: string | null; 156 | cLongblob: Buffer | null; 157 | cLongtext: string | null; 158 | cJson: any | null; 159 | } 160 | 161 | export async function test(client: Client): Promise { 162 | const [rows] = await client.query({ 163 | sql: testQuery, 164 | values: [], 165 | rowsAsArray: true 166 | }); 167 | if (rows.length !== 1) { 168 | return null; 169 | } 170 | const row = rows[0]; 171 | return { 172 | cBit: row[0], 173 | cTinyint: row[1], 174 | cBool: row[2], 175 | cBoolean: row[3], 176 | cSmallint: row[4], 177 | cMediumint: row[5], 178 | cInt: row[6], 179 | cInteger: row[7], 180 | cBigint: row[8], 181 | cSerial: row[9], 182 | cDecimal: row[10], 183 | cDec: row[11], 184 | cNumeric: row[12], 185 | cFixed: row[13], 186 | cFloat: row[14], 187 | cDouble: row[15], 188 | cDoublePrecision: row[16], 189 | cDate: row[17], 190 | cTime: row[18], 191 | cDatetime: row[19], 192 | cTimestamp: row[20], 193 | cYear: row[21], 194 | cChar: row[22], 195 | cNchar: row[23], 196 | cNationalChar: row[24], 197 | cVarchar: row[25], 198 | cBinary: row[26], 199 | cVarbinary: row[27], 200 | cTinyblob: row[28], 201 | cTinytext: row[29], 202 | cBlob: row[30], 203 | cText: row[31], 204 | cMediumblob: row[32], 205 | cMediumtext: row[33], 206 | cLongblob: row[34], 207 | cLongtext: row[35], 208 | cJson: row[36] 209 | }; 210 | } 211 | 212 | -------------------------------------------------------------------------------- /examples/node-mysql2/src/main.ts: -------------------------------------------------------------------------------- 1 | import * as mysql from "mysql2/promise"; 2 | 3 | import { 4 | createAuthor, 5 | deleteAuthor, 6 | getAuthor, 7 | listAuthors, 8 | } from "./db/query_sql"; 9 | 10 | interface Author { 11 | id: string; 12 | name: string; 13 | bio: string | null; 14 | } 15 | 16 | async function main() { 17 | const url = new URL(process.env["DATABASE_URL"] ?? ""); 18 | 19 | const client = mysql.createPool({ 20 | host: url.hostname, 21 | port: parseInt(url.port, 10), 22 | user: url.username, 23 | password: url.password, 24 | database: url.pathname.substring(1), 25 | supportBigNumbers: true, 26 | bigNumberStrings: true, 27 | ssl: { 28 | // TODO: FIXME 29 | rejectUnauthorized: false, 30 | }, 31 | }); 32 | 33 | // Create an author 34 | await createAuthor(client, { 35 | name: "Seal", 36 | bio: "Kissed from a rose", 37 | }); 38 | 39 | // List the authors 40 | const authors = await listAuthors(client); 41 | console.log(authors); 42 | 43 | // Get that author 44 | const seal = await getAuthor(client, { id: authors[0].id }); 45 | if (seal === null) { 46 | throw new Error("seal not found"); 47 | } 48 | console.log(seal); 49 | 50 | // Delete the author 51 | await deleteAuthor(client, { id: seal.id }); 52 | } 53 | 54 | (async () => { 55 | try { 56 | await main(); 57 | process.exit(0); 58 | } catch (e) { 59 | console.error(e); 60 | process.exit(1); 61 | } 62 | })(); 63 | -------------------------------------------------------------------------------- /examples/node-mysql2/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig to read more about this file */ 4 | 5 | /* Projects */ 6 | // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ 7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 8 | // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ 9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ 10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 12 | 13 | /* Language and Environment */ 14 | "target": "es2020", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 15 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 16 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 17 | // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ 18 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 19 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ 20 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 21 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ 22 | // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ 23 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 24 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 25 | // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ 26 | 27 | /* Modules */ 28 | "module": "commonjs", /* Specify what module code is generated. */ 29 | // "rootDir": "./", /* Specify the root folder within your source files. */ 30 | // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ 31 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 32 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 33 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 34 | // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ 35 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */ 36 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 37 | // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ 38 | // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ 39 | // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ 40 | // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ 41 | // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ 42 | // "resolveJsonModule": true, /* Enable importing .json files. */ 43 | // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ 44 | // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ 45 | 46 | /* JavaScript Support */ 47 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ 48 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 49 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ 50 | 51 | /* Emit */ 52 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 53 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 54 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 55 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 56 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 57 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ 58 | // "outDir": "./", /* Specify an output folder for all emitted files. */ 59 | // "removeComments": true, /* Disable emitting comments. */ 60 | // "noEmit": true, /* Disable emitting files from a compilation. */ 61 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 62 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ 63 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 64 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 65 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 66 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 67 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 68 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 69 | // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ 70 | // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ 71 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 72 | // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ 73 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 74 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 75 | 76 | /* Interop Constraints */ 77 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 78 | // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ 79 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 80 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ 81 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 82 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 83 | 84 | /* Type Checking */ 85 | "strict": true, /* Enable all strict type-checking options. */ 86 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ 87 | // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ 88 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 89 | // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ 90 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 91 | // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ 92 | // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ 93 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 94 | // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ 95 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ 96 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 97 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 98 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 99 | // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ 100 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 101 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ 102 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 103 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 104 | 105 | /* Completeness */ 106 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 107 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /examples/node-pg/Makefile: -------------------------------------------------------------------------------- 1 | run: src/main.js 2 | node ./src/main.js 3 | 4 | src/main.js: src/main.ts src/db/query_sql.ts 5 | npx tsc 6 | -------------------------------------------------------------------------------- /examples/node-pg/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "examples", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "examples", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "pg": "^8.11.3", 13 | "pg-types": "^4.0.1" 14 | }, 15 | "devDependencies": { 16 | "@types/pg": "^8.10.9", 17 | "typescript": "^5.2.2" 18 | } 19 | }, 20 | "node_modules/@types/node": { 21 | "version": "20.9.0", 22 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.9.0.tgz", 23 | "integrity": "sha512-nekiGu2NDb1BcVofVcEKMIwzlx4NjHlcjhoxxKBNLtz15Y1z7MYf549DFvkHSId02Ax6kGwWntIBPC3l/JZcmw==", 24 | "dev": true, 25 | "dependencies": { 26 | "undici-types": "~5.26.4" 27 | } 28 | }, 29 | "node_modules/@types/pg": { 30 | "version": "8.10.9", 31 | "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.10.9.tgz", 32 | "integrity": "sha512-UksbANNE/f8w0wOMxVKKIrLCbEMV+oM1uKejmwXr39olg4xqcfBDbXxObJAt6XxHbDa4XTKOlUEcEltXDX+XLQ==", 33 | "dev": true, 34 | "dependencies": { 35 | "@types/node": "*", 36 | "pg-protocol": "*", 37 | "pg-types": "^4.0.1" 38 | } 39 | }, 40 | "node_modules/buffer-writer": { 41 | "version": "2.0.0", 42 | "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", 43 | "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==", 44 | "engines": { 45 | "node": ">=4" 46 | } 47 | }, 48 | "node_modules/obuf": { 49 | "version": "1.1.2", 50 | "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", 51 | "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" 52 | }, 53 | "node_modules/packet-reader": { 54 | "version": "1.0.0", 55 | "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", 56 | "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" 57 | }, 58 | "node_modules/pg": { 59 | "version": "8.11.3", 60 | "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.3.tgz", 61 | "integrity": "sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g==", 62 | "dependencies": { 63 | "buffer-writer": "2.0.0", 64 | "packet-reader": "1.0.0", 65 | "pg-connection-string": "^2.6.2", 66 | "pg-pool": "^3.6.1", 67 | "pg-protocol": "^1.6.0", 68 | "pg-types": "^2.1.0", 69 | "pgpass": "1.x" 70 | }, 71 | "engines": { 72 | "node": ">= 8.0.0" 73 | }, 74 | "optionalDependencies": { 75 | "pg-cloudflare": "^1.1.1" 76 | }, 77 | "peerDependencies": { 78 | "pg-native": ">=3.0.1" 79 | }, 80 | "peerDependenciesMeta": { 81 | "pg-native": { 82 | "optional": true 83 | } 84 | } 85 | }, 86 | "node_modules/pg-cloudflare": { 87 | "version": "1.1.1", 88 | "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz", 89 | "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==", 90 | "optional": true 91 | }, 92 | "node_modules/pg-connection-string": { 93 | "version": "2.6.2", 94 | "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz", 95 | "integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==" 96 | }, 97 | "node_modules/pg-int8": { 98 | "version": "1.0.1", 99 | "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", 100 | "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", 101 | "engines": { 102 | "node": ">=4.0.0" 103 | } 104 | }, 105 | "node_modules/pg-numeric": { 106 | "version": "1.0.2", 107 | "resolved": "https://registry.npmjs.org/pg-numeric/-/pg-numeric-1.0.2.tgz", 108 | "integrity": "sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==", 109 | "engines": { 110 | "node": ">=4" 111 | } 112 | }, 113 | "node_modules/pg-pool": { 114 | "version": "3.6.1", 115 | "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.1.tgz", 116 | "integrity": "sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==", 117 | "peerDependencies": { 118 | "pg": ">=8.0" 119 | } 120 | }, 121 | "node_modules/pg-protocol": { 122 | "version": "1.6.0", 123 | "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz", 124 | "integrity": "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==" 125 | }, 126 | "node_modules/pg-types": { 127 | "version": "4.0.1", 128 | "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-4.0.1.tgz", 129 | "integrity": "sha512-hRCSDuLII9/LE3smys1hRHcu5QGcLs9ggT7I/TCs0IE+2Eesxi9+9RWAAwZ0yaGjxoWICF/YHLOEjydGujoJ+g==", 130 | "dependencies": { 131 | "pg-int8": "1.0.1", 132 | "pg-numeric": "1.0.2", 133 | "postgres-array": "~3.0.1", 134 | "postgres-bytea": "~3.0.0", 135 | "postgres-date": "~2.0.1", 136 | "postgres-interval": "^3.0.0", 137 | "postgres-range": "^1.1.1" 138 | }, 139 | "engines": { 140 | "node": ">=10" 141 | } 142 | }, 143 | "node_modules/pg/node_modules/pg-types": { 144 | "version": "2.2.0", 145 | "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", 146 | "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", 147 | "dependencies": { 148 | "pg-int8": "1.0.1", 149 | "postgres-array": "~2.0.0", 150 | "postgres-bytea": "~1.0.0", 151 | "postgres-date": "~1.0.4", 152 | "postgres-interval": "^1.1.0" 153 | }, 154 | "engines": { 155 | "node": ">=4" 156 | } 157 | }, 158 | "node_modules/pg/node_modules/postgres-array": { 159 | "version": "2.0.0", 160 | "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", 161 | "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", 162 | "engines": { 163 | "node": ">=4" 164 | } 165 | }, 166 | "node_modules/pg/node_modules/postgres-bytea": { 167 | "version": "1.0.0", 168 | "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", 169 | "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", 170 | "engines": { 171 | "node": ">=0.10.0" 172 | } 173 | }, 174 | "node_modules/pg/node_modules/postgres-date": { 175 | "version": "1.0.7", 176 | "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", 177 | "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", 178 | "engines": { 179 | "node": ">=0.10.0" 180 | } 181 | }, 182 | "node_modules/pg/node_modules/postgres-interval": { 183 | "version": "1.2.0", 184 | "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", 185 | "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", 186 | "dependencies": { 187 | "xtend": "^4.0.0" 188 | }, 189 | "engines": { 190 | "node": ">=0.10.0" 191 | } 192 | }, 193 | "node_modules/pgpass": { 194 | "version": "1.0.5", 195 | "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", 196 | "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", 197 | "dependencies": { 198 | "split2": "^4.1.0" 199 | } 200 | }, 201 | "node_modules/postgres-array": { 202 | "version": "3.0.2", 203 | "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-3.0.2.tgz", 204 | "integrity": "sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==", 205 | "engines": { 206 | "node": ">=12" 207 | } 208 | }, 209 | "node_modules/postgres-bytea": { 210 | "version": "3.0.0", 211 | "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-3.0.0.tgz", 212 | "integrity": "sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==", 213 | "dependencies": { 214 | "obuf": "~1.1.2" 215 | }, 216 | "engines": { 217 | "node": ">= 6" 218 | } 219 | }, 220 | "node_modules/postgres-date": { 221 | "version": "2.0.1", 222 | "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-2.0.1.tgz", 223 | "integrity": "sha512-YtMKdsDt5Ojv1wQRvUhnyDJNSr2dGIC96mQVKz7xufp07nfuFONzdaowrMHjlAzY6GDLd4f+LUHHAAM1h4MdUw==", 224 | "engines": { 225 | "node": ">=12" 226 | } 227 | }, 228 | "node_modules/postgres-interval": { 229 | "version": "3.0.0", 230 | "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-3.0.0.tgz", 231 | "integrity": "sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==", 232 | "engines": { 233 | "node": ">=12" 234 | } 235 | }, 236 | "node_modules/postgres-range": { 237 | "version": "1.1.3", 238 | "resolved": "https://registry.npmjs.org/postgres-range/-/postgres-range-1.1.3.tgz", 239 | "integrity": "sha512-VdlZoocy5lCP0c/t66xAfclglEapXPCIVhqqJRncYpvbCgImF0w67aPKfbqUMr72tO2k5q0TdTZwCLjPTI6C9g==" 240 | }, 241 | "node_modules/split2": { 242 | "version": "4.2.0", 243 | "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", 244 | "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", 245 | "engines": { 246 | "node": ">= 10.x" 247 | } 248 | }, 249 | "node_modules/typescript": { 250 | "version": "5.2.2", 251 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", 252 | "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", 253 | "dev": true, 254 | "bin": { 255 | "tsc": "bin/tsc", 256 | "tsserver": "bin/tsserver" 257 | }, 258 | "engines": { 259 | "node": ">=14.17" 260 | } 261 | }, 262 | "node_modules/undici-types": { 263 | "version": "5.26.5", 264 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", 265 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", 266 | "dev": true 267 | }, 268 | "node_modules/xtend": { 269 | "version": "4.0.2", 270 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", 271 | "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", 272 | "engines": { 273 | "node": ">=0.4" 274 | } 275 | } 276 | } 277 | } 278 | -------------------------------------------------------------------------------- /examples/node-pg/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "examples", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "@types/pg": "^8.10.9", 13 | "typescript": "^5.2.2" 14 | }, 15 | "dependencies": { 16 | "pg": "^8.11.3", 17 | "pg-types": "^4.0.1" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /examples/node-pg/src/db/query_sql.ts: -------------------------------------------------------------------------------- 1 | // Code generated by sqlc. DO NOT EDIT. 2 | 3 | import { QueryArrayConfig, QueryArrayResult } from "pg"; 4 | 5 | interface Client { 6 | query: (config: QueryArrayConfig) => Promise; 7 | } 8 | 9 | export const getAuthorQuery = `-- name: GetAuthor :one 10 | SELECT id, name, bio FROM authors 11 | WHERE id = $1 LIMIT 1`; 12 | 13 | export interface GetAuthorArgs { 14 | id: string; 15 | } 16 | 17 | export interface GetAuthorRow { 18 | id: string; 19 | name: string; 20 | bio: string | null; 21 | } 22 | 23 | export async function getAuthor(client: Client, args: GetAuthorArgs): Promise { 24 | const result = await client.query({ 25 | text: getAuthorQuery, 26 | values: [args.id], 27 | rowMode: "array" 28 | }); 29 | if (result.rows.length !== 1) { 30 | return null; 31 | } 32 | const row = result.rows[0]; 33 | return { 34 | id: row[0], 35 | name: row[1], 36 | bio: row[2] 37 | }; 38 | } 39 | 40 | export const listAuthorsQuery = `-- name: ListAuthors :many 41 | SELECT id, name, bio FROM authors 42 | ORDER BY name`; 43 | 44 | export interface ListAuthorsRow { 45 | id: string; 46 | name: string; 47 | bio: string | null; 48 | } 49 | 50 | export async function listAuthors(client: Client): Promise { 51 | const result = await client.query({ 52 | text: listAuthorsQuery, 53 | values: [], 54 | rowMode: "array" 55 | }); 56 | return result.rows.map(row => { 57 | return { 58 | id: row[0], 59 | name: row[1], 60 | bio: row[2] 61 | }; 62 | }); 63 | } 64 | 65 | export const createAuthorQuery = `-- name: CreateAuthor :one 66 | INSERT INTO authors ( 67 | name, bio 68 | ) VALUES ( 69 | $1, $2 70 | ) 71 | RETURNING id, name, bio`; 72 | 73 | export interface CreateAuthorArgs { 74 | name: string; 75 | bio: string | null; 76 | } 77 | 78 | export interface CreateAuthorRow { 79 | id: string; 80 | name: string; 81 | bio: string | null; 82 | } 83 | 84 | export async function createAuthor(client: Client, args: CreateAuthorArgs): Promise { 85 | const result = await client.query({ 86 | text: createAuthorQuery, 87 | values: [args.name, args.bio], 88 | rowMode: "array" 89 | }); 90 | if (result.rows.length !== 1) { 91 | return null; 92 | } 93 | const row = result.rows[0]; 94 | return { 95 | id: row[0], 96 | name: row[1], 97 | bio: row[2] 98 | }; 99 | } 100 | 101 | export const deleteAuthorQuery = `-- name: DeleteAuthor :exec 102 | DELETE FROM authors 103 | WHERE id = $1`; 104 | 105 | export interface DeleteAuthorArgs { 106 | id: string; 107 | } 108 | 109 | export async function deleteAuthor(client: Client, args: DeleteAuthorArgs): Promise { 110 | await client.query({ 111 | text: deleteAuthorQuery, 112 | values: [args.id], 113 | rowMode: "array" 114 | }); 115 | } 116 | 117 | -------------------------------------------------------------------------------- /examples/node-pg/src/main.ts: -------------------------------------------------------------------------------- 1 | import { Pool } from "pg"; 2 | 3 | import { 4 | createAuthor, 5 | deleteAuthor, 6 | getAuthor, 7 | listAuthors, 8 | } from "./db/query_sql"; 9 | 10 | interface Author { 11 | id: string; 12 | name: string; 13 | bio: string | null; 14 | } 15 | 16 | async function main() { 17 | const client = new Pool({ connectionString: process.env["DATABASE_URL"] }); 18 | await client.connect(); 19 | 20 | // Create an author 21 | const author = await createAuthor(client, { 22 | name: "Seal", 23 | bio: "Kissed from a rose", 24 | }); 25 | if (author === null) { 26 | throw new Error("author not created"); 27 | } 28 | console.log(author); 29 | 30 | // List the authors 31 | const authors = await listAuthors(client); 32 | console.log(authors); 33 | 34 | // Get that author 35 | const seal = await getAuthor(client, { id: author.id }); 36 | if (seal === null) { 37 | throw new Error("seal not found"); 38 | } 39 | console.log(seal); 40 | 41 | // Delete the author 42 | await deleteAuthor(client, { id: seal.id }); 43 | } 44 | 45 | (async () => { 46 | try { 47 | await main(); 48 | process.exit(0); 49 | } catch (e) { 50 | console.error(e); 51 | process.exit(1); 52 | } 53 | })(); 54 | -------------------------------------------------------------------------------- /examples/node-pg/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig to read more about this file */ 4 | 5 | /* Projects */ 6 | // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ 7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 8 | // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ 9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ 10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 12 | 13 | /* Language and Environment */ 14 | "target": "es2020", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 15 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 16 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 17 | // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ 18 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 19 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ 20 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 21 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ 22 | // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ 23 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 24 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 25 | // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ 26 | 27 | /* Modules */ 28 | "module": "commonjs", /* Specify what module code is generated. */ 29 | // "rootDir": "./", /* Specify the root folder within your source files. */ 30 | // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ 31 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 32 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 33 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 34 | // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ 35 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */ 36 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 37 | // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ 38 | // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ 39 | // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ 40 | // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ 41 | // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ 42 | // "resolveJsonModule": true, /* Enable importing .json files. */ 43 | // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ 44 | // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ 45 | 46 | /* JavaScript Support */ 47 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ 48 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 49 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ 50 | 51 | /* Emit */ 52 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 53 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 54 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 55 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 56 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 57 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ 58 | // "outDir": "./", /* Specify an output folder for all emitted files. */ 59 | // "removeComments": true, /* Disable emitting comments. */ 60 | // "noEmit": true, /* Disable emitting files from a compilation. */ 61 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 62 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ 63 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 64 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 65 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 66 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 67 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 68 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 69 | // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ 70 | // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ 71 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 72 | // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ 73 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 74 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 75 | 76 | /* Interop Constraints */ 77 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 78 | // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ 79 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 80 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ 81 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 82 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 83 | 84 | /* Type Checking */ 85 | "strict": true, /* Enable all strict type-checking options. */ 86 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ 87 | // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ 88 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 89 | // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ 90 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 91 | // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ 92 | // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ 93 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 94 | // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ 95 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ 96 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 97 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 98 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 99 | // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ 100 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 101 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ 102 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 103 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 104 | 105 | /* Completeness */ 106 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 107 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /examples/node-postgres/Makefile: -------------------------------------------------------------------------------- 1 | run: src/main.js 2 | node ./src/main.js 3 | 4 | src/main.js: src/main.ts src/db/handwritten_query_sql.ts 5 | npx tsc 6 | -------------------------------------------------------------------------------- /examples/node-postgres/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-postgres", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "node-postgres", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "postgres": "^3.4.3" 13 | }, 14 | "devDependencies": { 15 | "@types/node": "^20.9.0" 16 | } 17 | }, 18 | "node_modules/@types/node": { 19 | "version": "20.9.0", 20 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.9.0.tgz", 21 | "integrity": "sha512-nekiGu2NDb1BcVofVcEKMIwzlx4NjHlcjhoxxKBNLtz15Y1z7MYf549DFvkHSId02Ax6kGwWntIBPC3l/JZcmw==", 22 | "dev": true, 23 | "dependencies": { 24 | "undici-types": "~5.26.4" 25 | } 26 | }, 27 | "node_modules/postgres": { 28 | "version": "3.4.3", 29 | "resolved": "https://registry.npmjs.org/postgres/-/postgres-3.4.3.tgz", 30 | "integrity": "sha512-iHJn4+M9vbTdHSdDzNkC0crHq+1CUdFhx+YqCE+SqWxPjm+Zu63jq7yZborOBF64c8pc58O5uMudyL1FQcHacA==", 31 | "engines": { 32 | "node": ">=12" 33 | }, 34 | "funding": { 35 | "type": "individual", 36 | "url": "https://github.com/sponsors/porsager" 37 | } 38 | }, 39 | "node_modules/undici-types": { 40 | "version": "5.26.5", 41 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", 42 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", 43 | "dev": true 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /examples/node-postgres/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-postgres", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "src/main.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "postgres": "^3.4.3" 13 | }, 14 | "devDependencies": { 15 | "@types/node": "^20.9.0" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /examples/node-postgres/src/db/query_sql.ts: -------------------------------------------------------------------------------- 1 | // Code generated by sqlc. DO NOT EDIT. 2 | 3 | import { Sql } from "postgres"; 4 | 5 | export const getAuthorQuery = `-- name: GetAuthor :one 6 | SELECT id, name, bio FROM authors 7 | WHERE id = $1 LIMIT 1`; 8 | 9 | export interface GetAuthorArgs { 10 | id: string; 11 | } 12 | 13 | export interface GetAuthorRow { 14 | id: string; 15 | name: string; 16 | bio: string | null; 17 | } 18 | 19 | export async function getAuthor(sql: Sql, args: GetAuthorArgs): Promise { 20 | const rows = await sql.unsafe(getAuthorQuery, [args.id]).values(); 21 | if (rows.length !== 1) { 22 | return null; 23 | } 24 | const row = rows[0]; 25 | if (!row) { 26 | return null; 27 | } 28 | return { 29 | id: row[0], 30 | name: row[1], 31 | bio: row[2] 32 | }; 33 | } 34 | 35 | export const listAuthorsQuery = `-- name: ListAuthors :many 36 | SELECT id, name, bio FROM authors 37 | ORDER BY name`; 38 | 39 | export interface ListAuthorsRow { 40 | id: string; 41 | name: string; 42 | bio: string | null; 43 | } 44 | 45 | export async function listAuthors(sql: Sql): Promise { 46 | return (await sql.unsafe(listAuthorsQuery, []).values()).map(row => ({ 47 | id: row[0], 48 | name: row[1], 49 | bio: row[2] 50 | })); 51 | } 52 | 53 | export const createAuthorQuery = `-- name: CreateAuthor :one 54 | INSERT INTO authors ( 55 | name, bio 56 | ) VALUES ( 57 | $1, $2 58 | ) 59 | RETURNING id, name, bio`; 60 | 61 | export interface CreateAuthorArgs { 62 | name: string; 63 | bio: string | null; 64 | } 65 | 66 | export interface CreateAuthorRow { 67 | id: string; 68 | name: string; 69 | bio: string | null; 70 | } 71 | 72 | export async function createAuthor(sql: Sql, args: CreateAuthorArgs): Promise { 73 | const rows = await sql.unsafe(createAuthorQuery, [args.name, args.bio]).values(); 74 | if (rows.length !== 1) { 75 | return null; 76 | } 77 | const row = rows[0]; 78 | if (!row) { 79 | return null; 80 | } 81 | return { 82 | id: row[0], 83 | name: row[1], 84 | bio: row[2] 85 | }; 86 | } 87 | 88 | export const deleteAuthorQuery = `-- name: DeleteAuthor :exec 89 | DELETE FROM authors 90 | WHERE id = $1`; 91 | 92 | export interface DeleteAuthorArgs { 93 | id: string; 94 | } 95 | 96 | export async function deleteAuthor(sql: Sql, args: DeleteAuthorArgs): Promise { 97 | await sql.unsafe(deleteAuthorQuery, [args.id]); 98 | } 99 | 100 | -------------------------------------------------------------------------------- /examples/node-postgres/src/main.ts: -------------------------------------------------------------------------------- 1 | import postgres from "postgres"; 2 | 3 | import { 4 | createAuthor, 5 | deleteAuthor, 6 | getAuthor, 7 | listAuthors, 8 | } from "./db/query_sql"; 9 | 10 | async function main() { 11 | const sql = postgres(process.env["DATABASE_URL"] ?? ""); 12 | 13 | // Create an author 14 | const author = await createAuthor(sql, { 15 | name: "Seal", 16 | bio: "Kissed from a rose", 17 | }); 18 | if (author === null) { 19 | throw new Error("author not created"); 20 | } 21 | console.log(author); 22 | 23 | // List the authors 24 | const authors = await listAuthors(sql); 25 | console.log(authors); 26 | 27 | // Get that author 28 | const seal = await getAuthor(sql, { id: author.id }); 29 | if (seal === null) { 30 | throw new Error("seal not found"); 31 | } 32 | console.log(seal); 33 | 34 | // Delete the author 35 | await deleteAuthor(sql, { id: seal.id }); 36 | } 37 | 38 | (async () => { 39 | try { 40 | await main(); 41 | process.exit(0); 42 | } catch (e) { 43 | console.error(e); 44 | process.exit(1); 45 | } 46 | })(); 47 | -------------------------------------------------------------------------------- /examples/node-postgres/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig to read more about this file */ 4 | 5 | /* Projects */ 6 | // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ 7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 8 | // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ 9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ 10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 12 | 13 | /* Language and Environment */ 14 | "target": "es2020", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 15 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 16 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 17 | // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ 18 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 19 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ 20 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 21 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ 22 | // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ 23 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 24 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 25 | // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ 26 | 27 | /* Modules */ 28 | "module": "commonjs", /* Specify what module code is generated. */ 29 | // "rootDir": "./", /* Specify the root folder within your source files. */ 30 | // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ 31 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 32 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 33 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 34 | // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ 35 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */ 36 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 37 | // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ 38 | // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ 39 | // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ 40 | // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ 41 | // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ 42 | // "resolveJsonModule": true, /* Enable importing .json files. */ 43 | // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ 44 | // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ 45 | 46 | /* JavaScript Support */ 47 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ 48 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 49 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ 50 | 51 | /* Emit */ 52 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 53 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 54 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 55 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 56 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 57 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ 58 | // "outDir": "./", /* Specify an output folder for all emitted files. */ 59 | // "removeComments": true, /* Disable emitting comments. */ 60 | // "noEmit": true, /* Disable emitting files from a compilation. */ 61 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 62 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ 63 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 64 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 65 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 66 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 67 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 68 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 69 | // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ 70 | // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ 71 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 72 | // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ 73 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 74 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 75 | 76 | /* Interop Constraints */ 77 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 78 | // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ 79 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 80 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ 81 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 82 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 83 | 84 | /* Type Checking */ 85 | "strict": true, /* Enable all strict type-checking options. */ 86 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ 87 | // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ 88 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 89 | // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ 90 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 91 | // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ 92 | // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ 93 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 94 | // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ 95 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ 96 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 97 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 98 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 99 | // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ 100 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 101 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ 102 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 103 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 104 | 105 | /* Completeness */ 106 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 107 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /examples/sqlc.dev.yaml: -------------------------------------------------------------------------------- 1 | version: "2" 2 | plugins: 3 | - name: ts 4 | wasm: 5 | url: file://plugin.wasm 6 | sql: 7 | - schema: "authors/postgresql/schema.sql" 8 | queries: "authors/postgresql/query.sql" 9 | engine: "postgresql" 10 | codegen: 11 | - plugin: ts 12 | out: node-pg/src/db 13 | options: 14 | runtime: node 15 | driver: pg 16 | - schema: "authors/postgresql/schema.sql" 17 | queries: "authors/postgresql/query.sql" 18 | engine: "postgresql" 19 | codegen: 20 | - plugin: ts 21 | out: bun-pg/src/db 22 | options: 23 | runtime: bun 24 | driver: pg 25 | - schema: "authors/postgresql/schema.sql" 26 | queries: "authors/postgresql/query.sql" 27 | engine: "postgresql" 28 | codegen: 29 | - plugin: ts 30 | out: node-postgres/src/db 31 | options: 32 | runtime: node 33 | driver: postgres 34 | - schema: "authors/postgresql/schema.sql" 35 | queries: "authors/postgresql/query.sql" 36 | engine: "postgresql" 37 | codegen: 38 | - plugin: ts 39 | out: bun-postgres/src/db 40 | options: 41 | runtime: bun 42 | driver: postgres 43 | - schema: "authors/mysql/schema.sql" 44 | queries: "authors/mysql/query.sql" 45 | engine: "mysql" 46 | codegen: 47 | - plugin: ts 48 | out: node-mysql2/src/db 49 | options: 50 | runtime: node 51 | driver: mysql2 52 | mysql2: 53 | big_number_strings: true 54 | support_big_numbers: true 55 | - schema: "authors/mysql/schema.sql" 56 | queries: "authors/mysql/query.sql" 57 | engine: "mysql" 58 | codegen: 59 | - plugin: ts 60 | out: bun-mysql2/src/db 61 | options: 62 | runtime: bun 63 | driver: mysql2 64 | - schema: "authors/sqlite/schema.sql" 65 | queries: "authors/sqlite/query.sql" 66 | engine: "sqlite" 67 | codegen: 68 | - plugin: ts 69 | out: node-better-sqlite3/src/db 70 | options: 71 | runtime: node 72 | driver: better-sqlite3 73 | -------------------------------------------------------------------------------- /examples/sqlc.yaml: -------------------------------------------------------------------------------- 1 | version: "2" 2 | plugins: 3 | - name: ts 4 | wasm: 5 | url: https://downloads.sqlc.dev/plugin/sqlc-gen-typescript_0.1.3.wasm 6 | sha256: 287df8f6cc06377d67ad5ba02c9e0f00c585509881434d15ea8bd9fc751a9368 7 | sql: 8 | - schema: "authors/postgresql/schema.sql" 9 | queries: "authors/postgresql/query.sql" 10 | engine: "postgresql" 11 | codegen: 12 | - plugin: ts 13 | out: node-pg/src/db 14 | options: 15 | runtime: node 16 | driver: pg 17 | - schema: "authors/postgresql/schema.sql" 18 | queries: "authors/postgresql/query.sql" 19 | engine: "postgresql" 20 | codegen: 21 | - plugin: ts 22 | out: bun-pg/src/db 23 | options: 24 | runtime: bun 25 | driver: pg 26 | - schema: "authors/postgresql/schema.sql" 27 | queries: "authors/postgresql/query.sql" 28 | engine: "postgresql" 29 | codegen: 30 | - plugin: ts 31 | out: node-postgres/src/db 32 | options: 33 | runtime: node 34 | driver: postgres 35 | - schema: "authors/postgresql/schema.sql" 36 | queries: "authors/postgresql/query.sql" 37 | engine: "postgresql" 38 | codegen: 39 | - plugin: ts 40 | out: bun-postgres/src/db 41 | options: 42 | runtime: bun 43 | driver: postgres 44 | - schema: "authors/mysql/schema.sql" 45 | queries: "authors/mysql/query.sql" 46 | engine: "mysql" 47 | codegen: 48 | - plugin: ts 49 | out: node-mysql2/src/db 50 | options: 51 | runtime: node 52 | driver: mysql2 53 | - schema: "authors/mysql/schema.sql" 54 | queries: "authors/mysql/query.sql" 55 | engine: "mysql" 56 | codegen: 57 | - plugin: ts 58 | out: bun-mysql2/src/db 59 | options: 60 | runtime: bun 61 | driver: mysql2 -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "experiment", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "experiment", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "@bufbuild/protobuf": "^1.4.2", 13 | "javy": "^0.1.2" 14 | }, 15 | "devDependencies": { 16 | "esbuild": "^0.19.5", 17 | "typescript": "^5.2.2" 18 | } 19 | }, 20 | "node_modules/@bufbuild/protobuf": { 21 | "version": "1.4.2", 22 | "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-1.4.2.tgz", 23 | "integrity": "sha512-JyEH8Z+OD5Sc2opSg86qMHn1EM1Sa+zj/Tc0ovxdwk56ByVNONJSabuCUbLQp+eKN3rWNfrho0X+3SEqEPXIow==" 24 | }, 25 | "node_modules/@esbuild/android-arm": { 26 | "version": "0.19.5", 27 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.5.tgz", 28 | "integrity": "sha512-bhvbzWFF3CwMs5tbjf3ObfGqbl/17ict2/uwOSfr3wmxDE6VdS2GqY/FuzIPe0q0bdhj65zQsvqfArI9MY6+AA==", 29 | "cpu": [ 30 | "arm" 31 | ], 32 | "dev": true, 33 | "optional": true, 34 | "os": [ 35 | "android" 36 | ], 37 | "engines": { 38 | "node": ">=12" 39 | } 40 | }, 41 | "node_modules/@esbuild/android-arm64": { 42 | "version": "0.19.5", 43 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.5.tgz", 44 | "integrity": "sha512-5d1OkoJxnYQfmC+Zd8NBFjkhyCNYwM4n9ODrycTFY6Jk1IGiZ+tjVJDDSwDt77nK+tfpGP4T50iMtVi4dEGzhQ==", 45 | "cpu": [ 46 | "arm64" 47 | ], 48 | "dev": true, 49 | "optional": true, 50 | "os": [ 51 | "android" 52 | ], 53 | "engines": { 54 | "node": ">=12" 55 | } 56 | }, 57 | "node_modules/@esbuild/android-x64": { 58 | "version": "0.19.5", 59 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.5.tgz", 60 | "integrity": "sha512-9t+28jHGL7uBdkBjL90QFxe7DVA+KGqWlHCF8ChTKyaKO//VLuoBricQCgwhOjA1/qOczsw843Fy4cbs4H3DVA==", 61 | "cpu": [ 62 | "x64" 63 | ], 64 | "dev": true, 65 | "optional": true, 66 | "os": [ 67 | "android" 68 | ], 69 | "engines": { 70 | "node": ">=12" 71 | } 72 | }, 73 | "node_modules/@esbuild/darwin-arm64": { 74 | "version": "0.19.5", 75 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.5.tgz", 76 | "integrity": "sha512-mvXGcKqqIqyKoxq26qEDPHJuBYUA5KizJncKOAf9eJQez+L9O+KfvNFu6nl7SCZ/gFb2QPaRqqmG0doSWlgkqw==", 77 | "cpu": [ 78 | "arm64" 79 | ], 80 | "dev": true, 81 | "optional": true, 82 | "os": [ 83 | "darwin" 84 | ], 85 | "engines": { 86 | "node": ">=12" 87 | } 88 | }, 89 | "node_modules/@esbuild/darwin-x64": { 90 | "version": "0.19.5", 91 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.5.tgz", 92 | "integrity": "sha512-Ly8cn6fGLNet19s0X4unjcniX24I0RqjPv+kurpXabZYSXGM4Pwpmf85WHJN3lAgB8GSth7s5A0r856S+4DyiA==", 93 | "cpu": [ 94 | "x64" 95 | ], 96 | "dev": true, 97 | "optional": true, 98 | "os": [ 99 | "darwin" 100 | ], 101 | "engines": { 102 | "node": ">=12" 103 | } 104 | }, 105 | "node_modules/@esbuild/freebsd-arm64": { 106 | "version": "0.19.5", 107 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.5.tgz", 108 | "integrity": "sha512-GGDNnPWTmWE+DMchq1W8Sd0mUkL+APvJg3b11klSGUDvRXh70JqLAO56tubmq1s2cgpVCSKYywEiKBfju8JztQ==", 109 | "cpu": [ 110 | "arm64" 111 | ], 112 | "dev": true, 113 | "optional": true, 114 | "os": [ 115 | "freebsd" 116 | ], 117 | "engines": { 118 | "node": ">=12" 119 | } 120 | }, 121 | "node_modules/@esbuild/freebsd-x64": { 122 | "version": "0.19.5", 123 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.5.tgz", 124 | "integrity": "sha512-1CCwDHnSSoA0HNwdfoNY0jLfJpd7ygaLAp5EHFos3VWJCRX9DMwWODf96s9TSse39Br7oOTLryRVmBoFwXbuuQ==", 125 | "cpu": [ 126 | "x64" 127 | ], 128 | "dev": true, 129 | "optional": true, 130 | "os": [ 131 | "freebsd" 132 | ], 133 | "engines": { 134 | "node": ">=12" 135 | } 136 | }, 137 | "node_modules/@esbuild/linux-arm": { 138 | "version": "0.19.5", 139 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.5.tgz", 140 | "integrity": "sha512-lrWXLY/vJBzCPC51QN0HM71uWgIEpGSjSZZADQhq7DKhPcI6NH1IdzjfHkDQws2oNpJKpR13kv7/pFHBbDQDwQ==", 141 | "cpu": [ 142 | "arm" 143 | ], 144 | "dev": true, 145 | "optional": true, 146 | "os": [ 147 | "linux" 148 | ], 149 | "engines": { 150 | "node": ">=12" 151 | } 152 | }, 153 | "node_modules/@esbuild/linux-arm64": { 154 | "version": "0.19.5", 155 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.5.tgz", 156 | "integrity": "sha512-o3vYippBmSrjjQUCEEiTZ2l+4yC0pVJD/Dl57WfPwwlvFkrxoSO7rmBZFii6kQB3Wrn/6GwJUPLU5t52eq2meA==", 157 | "cpu": [ 158 | "arm64" 159 | ], 160 | "dev": true, 161 | "optional": true, 162 | "os": [ 163 | "linux" 164 | ], 165 | "engines": { 166 | "node": ">=12" 167 | } 168 | }, 169 | "node_modules/@esbuild/linux-ia32": { 170 | "version": "0.19.5", 171 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.5.tgz", 172 | "integrity": "sha512-MkjHXS03AXAkNp1KKkhSKPOCYztRtK+KXDNkBa6P78F8Bw0ynknCSClO/ztGszILZtyO/lVKpa7MolbBZ6oJtQ==", 173 | "cpu": [ 174 | "ia32" 175 | ], 176 | "dev": true, 177 | "optional": true, 178 | "os": [ 179 | "linux" 180 | ], 181 | "engines": { 182 | "node": ">=12" 183 | } 184 | }, 185 | "node_modules/@esbuild/linux-loong64": { 186 | "version": "0.19.5", 187 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.5.tgz", 188 | "integrity": "sha512-42GwZMm5oYOD/JHqHska3Jg0r+XFb/fdZRX+WjADm3nLWLcIsN27YKtqxzQmGNJgu0AyXg4HtcSK9HuOk3v1Dw==", 189 | "cpu": [ 190 | "loong64" 191 | ], 192 | "dev": true, 193 | "optional": true, 194 | "os": [ 195 | "linux" 196 | ], 197 | "engines": { 198 | "node": ">=12" 199 | } 200 | }, 201 | "node_modules/@esbuild/linux-mips64el": { 202 | "version": "0.19.5", 203 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.5.tgz", 204 | "integrity": "sha512-kcjndCSMitUuPJobWCnwQ9lLjiLZUR3QLQmlgaBfMX23UEa7ZOrtufnRds+6WZtIS9HdTXqND4yH8NLoVVIkcg==", 205 | "cpu": [ 206 | "mips64el" 207 | ], 208 | "dev": true, 209 | "optional": true, 210 | "os": [ 211 | "linux" 212 | ], 213 | "engines": { 214 | "node": ">=12" 215 | } 216 | }, 217 | "node_modules/@esbuild/linux-ppc64": { 218 | "version": "0.19.5", 219 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.5.tgz", 220 | "integrity": "sha512-yJAxJfHVm0ZbsiljbtFFP1BQKLc8kUF6+17tjQ78QjqjAQDnhULWiTA6u0FCDmYT1oOKS9PzZ2z0aBI+Mcyj7Q==", 221 | "cpu": [ 222 | "ppc64" 223 | ], 224 | "dev": true, 225 | "optional": true, 226 | "os": [ 227 | "linux" 228 | ], 229 | "engines": { 230 | "node": ">=12" 231 | } 232 | }, 233 | "node_modules/@esbuild/linux-riscv64": { 234 | "version": "0.19.5", 235 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.5.tgz", 236 | "integrity": "sha512-5u8cIR/t3gaD6ad3wNt1MNRstAZO+aNyBxu2We8X31bA8XUNyamTVQwLDA1SLoPCUehNCymhBhK3Qim1433Zag==", 237 | "cpu": [ 238 | "riscv64" 239 | ], 240 | "dev": true, 241 | "optional": true, 242 | "os": [ 243 | "linux" 244 | ], 245 | "engines": { 246 | "node": ">=12" 247 | } 248 | }, 249 | "node_modules/@esbuild/linux-s390x": { 250 | "version": "0.19.5", 251 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.5.tgz", 252 | "integrity": "sha512-Z6JrMyEw/EmZBD/OFEFpb+gao9xJ59ATsoTNlj39jVBbXqoZm4Xntu6wVmGPB/OATi1uk/DB+yeDPv2E8PqZGw==", 253 | "cpu": [ 254 | "s390x" 255 | ], 256 | "dev": true, 257 | "optional": true, 258 | "os": [ 259 | "linux" 260 | ], 261 | "engines": { 262 | "node": ">=12" 263 | } 264 | }, 265 | "node_modules/@esbuild/linux-x64": { 266 | "version": "0.19.5", 267 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.5.tgz", 268 | "integrity": "sha512-psagl+2RlK1z8zWZOmVdImisMtrUxvwereIdyJTmtmHahJTKb64pAcqoPlx6CewPdvGvUKe2Jw+0Z/0qhSbG1A==", 269 | "cpu": [ 270 | "x64" 271 | ], 272 | "dev": true, 273 | "optional": true, 274 | "os": [ 275 | "linux" 276 | ], 277 | "engines": { 278 | "node": ">=12" 279 | } 280 | }, 281 | "node_modules/@esbuild/netbsd-x64": { 282 | "version": "0.19.5", 283 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.5.tgz", 284 | "integrity": "sha512-kL2l+xScnAy/E/3119OggX8SrWyBEcqAh8aOY1gr4gPvw76la2GlD4Ymf832UCVbmuWeTf2adkZDK+h0Z/fB4g==", 285 | "cpu": [ 286 | "x64" 287 | ], 288 | "dev": true, 289 | "optional": true, 290 | "os": [ 291 | "netbsd" 292 | ], 293 | "engines": { 294 | "node": ">=12" 295 | } 296 | }, 297 | "node_modules/@esbuild/openbsd-x64": { 298 | "version": "0.19.5", 299 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.5.tgz", 300 | "integrity": "sha512-sPOfhtzFufQfTBgRnE1DIJjzsXukKSvZxloZbkJDG383q0awVAq600pc1nfqBcl0ice/WN9p4qLc39WhBShRTA==", 301 | "cpu": [ 302 | "x64" 303 | ], 304 | "dev": true, 305 | "optional": true, 306 | "os": [ 307 | "openbsd" 308 | ], 309 | "engines": { 310 | "node": ">=12" 311 | } 312 | }, 313 | "node_modules/@esbuild/sunos-x64": { 314 | "version": "0.19.5", 315 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.5.tgz", 316 | "integrity": "sha512-dGZkBXaafuKLpDSjKcB0ax0FL36YXCvJNnztjKV+6CO82tTYVDSH2lifitJ29jxRMoUhgkg9a+VA/B03WK5lcg==", 317 | "cpu": [ 318 | "x64" 319 | ], 320 | "dev": true, 321 | "optional": true, 322 | "os": [ 323 | "sunos" 324 | ], 325 | "engines": { 326 | "node": ">=12" 327 | } 328 | }, 329 | "node_modules/@esbuild/win32-arm64": { 330 | "version": "0.19.5", 331 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.5.tgz", 332 | "integrity": "sha512-dWVjD9y03ilhdRQ6Xig1NWNgfLtf2o/STKTS+eZuF90fI2BhbwD6WlaiCGKptlqXlURVB5AUOxUj09LuwKGDTg==", 333 | "cpu": [ 334 | "arm64" 335 | ], 336 | "dev": true, 337 | "optional": true, 338 | "os": [ 339 | "win32" 340 | ], 341 | "engines": { 342 | "node": ">=12" 343 | } 344 | }, 345 | "node_modules/@esbuild/win32-ia32": { 346 | "version": "0.19.5", 347 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.5.tgz", 348 | "integrity": "sha512-4liggWIA4oDgUxqpZwrDhmEfAH4d0iljanDOK7AnVU89T6CzHon/ony8C5LeOdfgx60x5cnQJFZwEydVlYx4iw==", 349 | "cpu": [ 350 | "ia32" 351 | ], 352 | "dev": true, 353 | "optional": true, 354 | "os": [ 355 | "win32" 356 | ], 357 | "engines": { 358 | "node": ">=12" 359 | } 360 | }, 361 | "node_modules/@esbuild/win32-x64": { 362 | "version": "0.19.5", 363 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.5.tgz", 364 | "integrity": "sha512-czTrygUsB/jlM8qEW5MD8bgYU2Xg14lo6kBDXW6HdxKjh8M5PzETGiSHaz9MtbXBYDloHNUAUW2tMiKW4KM9Mw==", 365 | "cpu": [ 366 | "x64" 367 | ], 368 | "dev": true, 369 | "optional": true, 370 | "os": [ 371 | "win32" 372 | ], 373 | "engines": { 374 | "node": ">=12" 375 | } 376 | }, 377 | "node_modules/esbuild": { 378 | "version": "0.19.5", 379 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.5.tgz", 380 | "integrity": "sha512-bUxalY7b1g8vNhQKdB24QDmHeY4V4tw/s6Ak5z+jJX9laP5MoQseTOMemAr0gxssjNcH0MCViG8ONI2kksvfFQ==", 381 | "dev": true, 382 | "hasInstallScript": true, 383 | "bin": { 384 | "esbuild": "bin/esbuild" 385 | }, 386 | "engines": { 387 | "node": ">=12" 388 | }, 389 | "optionalDependencies": { 390 | "@esbuild/android-arm": "0.19.5", 391 | "@esbuild/android-arm64": "0.19.5", 392 | "@esbuild/android-x64": "0.19.5", 393 | "@esbuild/darwin-arm64": "0.19.5", 394 | "@esbuild/darwin-x64": "0.19.5", 395 | "@esbuild/freebsd-arm64": "0.19.5", 396 | "@esbuild/freebsd-x64": "0.19.5", 397 | "@esbuild/linux-arm": "0.19.5", 398 | "@esbuild/linux-arm64": "0.19.5", 399 | "@esbuild/linux-ia32": "0.19.5", 400 | "@esbuild/linux-loong64": "0.19.5", 401 | "@esbuild/linux-mips64el": "0.19.5", 402 | "@esbuild/linux-ppc64": "0.19.5", 403 | "@esbuild/linux-riscv64": "0.19.5", 404 | "@esbuild/linux-s390x": "0.19.5", 405 | "@esbuild/linux-x64": "0.19.5", 406 | "@esbuild/netbsd-x64": "0.19.5", 407 | "@esbuild/openbsd-x64": "0.19.5", 408 | "@esbuild/sunos-x64": "0.19.5", 409 | "@esbuild/win32-arm64": "0.19.5", 410 | "@esbuild/win32-ia32": "0.19.5", 411 | "@esbuild/win32-x64": "0.19.5" 412 | } 413 | }, 414 | "node_modules/javy": { 415 | "version": "0.1.2", 416 | "resolved": "https://registry.npmjs.org/javy/-/javy-0.1.2.tgz", 417 | "integrity": "sha512-z6Z+CV13SXBGxmY5UseWsYNVVR4SWPfOixKGluWi1Dpn594+M2JaGPBrFIIMnFFfi7kJzHCkcTn7CrhJ7JGKsA==" 418 | }, 419 | "node_modules/typescript": { 420 | "version": "5.2.2", 421 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", 422 | "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", 423 | "dev": true, 424 | "bin": { 425 | "tsc": "bin/tsc", 426 | "tsserver": "bin/tsserver" 427 | }, 428 | "engines": { 429 | "node": ">=14.17" 430 | } 431 | } 432 | } 433 | } 434 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "experiment", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "app.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "esbuild": "^0.19.5", 13 | "typescript": "^5.2.2" 14 | }, 15 | "dependencies": { 16 | "@bufbuild/protobuf": "^1.4.2", 17 | "javy": "^0.1.2", 18 | "pg": "^8.11.3" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/app.ts: -------------------------------------------------------------------------------- 1 | // I cant' get this import to work locally. The import in node_modules is 2 | // javy/dist but esbuild requires the import to be javy/fs 3 | // 4 | // @ts-expect-error 5 | import { readFileSync, writeFileSync, STDIO } from "javy/fs"; 6 | import { 7 | EmitHint, 8 | FunctionDeclaration, 9 | NewLineKind, 10 | TypeNode, 11 | ScriptKind, 12 | ScriptTarget, 13 | SyntaxKind, 14 | Node, 15 | NodeFlags, 16 | createPrinter, 17 | createSourceFile, 18 | factory, 19 | } from "typescript"; 20 | 21 | import { 22 | GenerateRequest, 23 | GenerateResponse, 24 | Parameter, 25 | Column, 26 | File, 27 | Query, 28 | } from "./gen/plugin/codegen_pb"; 29 | 30 | import { argName, colName } from "./drivers/utlis"; 31 | import { Driver as Sqlite3Driver } from "./drivers/better-sqlite3"; 32 | import { Driver as PgDriver } from "./drivers/pg"; 33 | import { Driver as PostgresDriver } from "./drivers/postgres"; 34 | import { Mysql2Options, Driver as MysqlDriver } from "./drivers/mysql2"; 35 | 36 | // Read input from stdin 37 | const input = readInput(); 38 | // Call the function with the input 39 | const result = codegen(input); 40 | // Write the result to stdout 41 | writeOutput(result); 42 | 43 | interface Options { 44 | runtime?: string; 45 | driver?: string; 46 | mysql2?: Mysql2Options 47 | } 48 | 49 | interface Driver { 50 | preamble: (queries: Query[]) => Node[]; 51 | columnType: (c?: Column) => TypeNode; 52 | execDecl: ( 53 | name: string, 54 | text: string, 55 | iface: string | undefined, 56 | params: Parameter[] 57 | ) => Node; 58 | execlastidDecl: ( 59 | name: string, 60 | text: string, 61 | iface: string | undefined, 62 | params: Parameter[] 63 | ) => Node; 64 | manyDecl: ( 65 | name: string, 66 | text: string, 67 | argIface: string | undefined, 68 | returnIface: string, 69 | params: Parameter[], 70 | columns: Column[] 71 | ) => Node; 72 | oneDecl: ( 73 | name: string, 74 | text: string, 75 | argIface: string | undefined, 76 | returnIface: string, 77 | params: Parameter[], 78 | columns: Column[] 79 | ) => Node; 80 | } 81 | 82 | function createNodeGenerator(options: Options): Driver { 83 | switch (options.driver) { 84 | case "mysql2": { 85 | return new MysqlDriver(options.mysql2); 86 | } 87 | case "pg": { 88 | return new PgDriver(); 89 | } 90 | case "postgres": { 91 | return new PostgresDriver(); 92 | } 93 | case "better-sqlite3": { 94 | return new Sqlite3Driver(); 95 | } 96 | } 97 | throw new Error(`unknown driver: ${options.driver}`); 98 | } 99 | 100 | function codegen(input: GenerateRequest): GenerateResponse { 101 | let files = []; 102 | let options: Options = {}; 103 | 104 | if (input.pluginOptions.length > 0) { 105 | const text = new TextDecoder().decode(input.pluginOptions); 106 | options = JSON.parse(text) as Options; 107 | } 108 | 109 | const driver = createNodeGenerator(options); 110 | 111 | // TODO: Verify options, parse them from protobuf honestly 112 | 113 | const querymap = new Map(); 114 | 115 | for (const query of input.queries) { 116 | if (!querymap.has(query.filename)) { 117 | querymap.set(query.filename, []); 118 | } 119 | const qs = querymap.get(query.filename); 120 | qs?.push(query); 121 | } 122 | 123 | for (const [filename, queries] of querymap.entries()) { 124 | const nodes = driver.preamble(queries); 125 | 126 | for (const query of queries) { 127 | const colmap = new Map(); 128 | for (let column of query.columns) { 129 | if (!column.name) { 130 | continue; 131 | } 132 | const count = colmap.get(column.name) || 0; 133 | if (count > 0) { 134 | column.name = `${column.name}_${count + 1}`; 135 | } 136 | colmap.set(column.name, count + 1); 137 | } 138 | 139 | const lowerName = query.name[0].toLowerCase() + query.name.slice(1); 140 | const textName = `${lowerName}Query`; 141 | 142 | nodes.push( 143 | queryDecl( 144 | textName, 145 | `-- name: ${query.name} ${query.cmd} 146 | ${query.text}` 147 | ) 148 | ); 149 | 150 | let argIface = undefined; 151 | let returnIface = undefined; 152 | if (query.params.length > 0) { 153 | argIface = `${query.name}Args`; 154 | nodes.push(argsDecl(argIface, driver, query.params)); 155 | } 156 | if (query.columns.length > 0) { 157 | returnIface = `${query.name}Row`; 158 | nodes.push(rowDecl(returnIface, driver, query.columns)); 159 | } 160 | 161 | switch (query.cmd) { 162 | case ":exec": { 163 | nodes.push( 164 | driver.execDecl(lowerName, textName, argIface, query.params) 165 | ); 166 | break; 167 | } 168 | case ":execlastid": { 169 | nodes.push( 170 | driver.execlastidDecl(lowerName, textName, argIface, query.params) 171 | ); 172 | break; 173 | } 174 | case ":one": { 175 | nodes.push( 176 | driver.oneDecl( 177 | lowerName, 178 | textName, 179 | argIface, 180 | returnIface ?? "void", 181 | query.params, 182 | query.columns 183 | ) 184 | ); 185 | break; 186 | } 187 | case ":many": { 188 | nodes.push( 189 | driver.manyDecl( 190 | lowerName, 191 | textName, 192 | argIface, 193 | returnIface ?? "void", 194 | query.params, 195 | query.columns 196 | ) 197 | ); 198 | break; 199 | } 200 | } 201 | if (nodes) { 202 | files.push( 203 | new File({ 204 | name: `${filename.replace(".", "_")}.ts`, 205 | contents: new TextEncoder().encode(printNode(nodes)), 206 | }) 207 | ); 208 | } 209 | } 210 | } 211 | 212 | return new GenerateResponse({ 213 | files: files, 214 | }); 215 | } 216 | 217 | // Read input from stdin 218 | function readInput(): GenerateRequest { 219 | const buffer = readFileSync(STDIO.Stdin); 220 | return GenerateRequest.fromBinary(buffer); 221 | } 222 | 223 | function queryDecl(name: string, sql: string) { 224 | return factory.createVariableStatement( 225 | [factory.createToken(SyntaxKind.ExportKeyword)], 226 | factory.createVariableDeclarationList( 227 | [ 228 | factory.createVariableDeclaration( 229 | factory.createIdentifier(name), 230 | undefined, 231 | undefined, 232 | factory.createNoSubstitutionTemplateLiteral(sql, sql) 233 | ), 234 | ], 235 | NodeFlags.Const //| NodeFlags.Constant | NodeFlags.Constant 236 | ) 237 | ); 238 | } 239 | 240 | function argsDecl( 241 | name: string, 242 | driver: Driver, 243 | params: Parameter[] 244 | ) { 245 | return factory.createInterfaceDeclaration( 246 | [factory.createToken(SyntaxKind.ExportKeyword)], 247 | factory.createIdentifier(name), 248 | undefined, 249 | undefined, 250 | params.map((param, i) => 251 | factory.createPropertySignature( 252 | undefined, 253 | factory.createIdentifier(argName(i, param.column)), 254 | undefined, 255 | driver.columnType(param.column) 256 | ) 257 | ) 258 | ); 259 | } 260 | 261 | function rowDecl( 262 | name: string, 263 | driver: Driver, 264 | columns: Column[] 265 | ) { 266 | return factory.createInterfaceDeclaration( 267 | [factory.createToken(SyntaxKind.ExportKeyword)], 268 | factory.createIdentifier(name), 269 | undefined, 270 | undefined, 271 | columns.map((column, i) => 272 | factory.createPropertySignature( 273 | undefined, 274 | factory.createIdentifier(colName(i, column)), 275 | undefined, 276 | driver.columnType(column) 277 | ) 278 | ) 279 | ); 280 | } 281 | 282 | function printNode(nodes: Node[]): string { 283 | // https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API#creating-and-printing-a-typescript-ast 284 | const resultFile = createSourceFile( 285 | "file.ts", 286 | "", 287 | ScriptTarget.Latest, 288 | /*setParentNodes*/ false, 289 | ScriptKind.TS 290 | ); 291 | const printer = createPrinter({ newLine: NewLineKind.LineFeed }); 292 | let output = "// Code generated by sqlc. DO NOT EDIT.\n\n"; 293 | for (let node of nodes) { 294 | output += printer.printNode(EmitHint.Unspecified, node, resultFile); 295 | output += "\n\n"; 296 | } 297 | return output; 298 | } 299 | 300 | // Write output to stdout 301 | function writeOutput(output: GenerateResponse) { 302 | const encodedOutput = output.toBinary(); 303 | const buffer = new Uint8Array(encodedOutput); 304 | writeFileSync(STDIO.Stdout, buffer); 305 | } 306 | -------------------------------------------------------------------------------- /src/drivers/better-sqlite3.ts: -------------------------------------------------------------------------------- 1 | import { 2 | SyntaxKind, 3 | NodeFlags, 4 | Node, 5 | TypeNode, 6 | factory, 7 | FunctionDeclaration, 8 | } from "typescript"; 9 | 10 | import { Parameter, Column, Query } from "../gen/plugin/codegen_pb"; 11 | import { argName } from "./utlis"; 12 | 13 | function funcParamsDecl(iface: string | undefined, params: Parameter[]) { 14 | let funcParams = [ 15 | factory.createParameterDeclaration( 16 | undefined, 17 | undefined, 18 | factory.createIdentifier("database"), 19 | undefined, 20 | factory.createTypeReferenceNode( 21 | factory.createIdentifier("Database"), 22 | undefined 23 | ), 24 | undefined 25 | ), 26 | ]; 27 | 28 | if (iface && params.length > 0) { 29 | funcParams.push( 30 | factory.createParameterDeclaration( 31 | undefined, 32 | undefined, 33 | factory.createIdentifier("args"), 34 | undefined, 35 | factory.createTypeReferenceNode( 36 | factory.createIdentifier(iface), 37 | undefined 38 | ), 39 | undefined 40 | ) 41 | ); 42 | } 43 | 44 | return funcParams; 45 | } 46 | 47 | export class Driver { 48 | /** 49 | * {@link https://github.com/WiseLibs/better-sqlite3/blob/v9.4.1/docs/api.md#binding-parameters} 50 | * {@link https://github.com/sqlc-dev/sqlc/blob/v1.25.0/internal/codegen/golang/sqlite_type.go} 51 | */ 52 | columnType(column?: Column): TypeNode { 53 | if (column === undefined || column.type === undefined) { 54 | return factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); 55 | } 56 | 57 | let typ: TypeNode = factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); 58 | switch (column.type.name) { 59 | case "int": 60 | case "integer": 61 | case "tinyint": 62 | case "smallint": 63 | case "mediumint": 64 | case "bigint": 65 | case "unsignedbigint": 66 | case "int2": 67 | case "int8": { 68 | // TODO: Improve `BigInt` handling (https://github.com/WiseLibs/better-sqlite3/blob/v9.4.1/docs/integer.md) 69 | typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); 70 | break; 71 | } 72 | case "blob": { 73 | // TODO: Is this correct or node-specific? 74 | typ = factory.createTypeReferenceNode( 75 | factory.createIdentifier("Buffer"), 76 | undefined 77 | ); 78 | break; 79 | } 80 | case "real": 81 | case "double": 82 | case "doubleprecision": 83 | case "float": { 84 | typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); 85 | break; 86 | } 87 | case "boolean": 88 | case "bool": { 89 | typ = factory.createKeywordTypeNode(SyntaxKind.BooleanKeyword); 90 | break; 91 | } 92 | case "date": 93 | case "datetime": 94 | case "timestamp": { 95 | typ = factory.createTypeReferenceNode( 96 | factory.createIdentifier("Date"), 97 | undefined 98 | ); 99 | break; 100 | } 101 | } 102 | 103 | if (column.notNull) { 104 | return typ; 105 | } 106 | 107 | return factory.createUnionTypeNode([ 108 | typ, 109 | factory.createLiteralTypeNode(factory.createNull()), 110 | ]); 111 | } 112 | 113 | preamble(queries: Query[]) { 114 | const imports: Node[] = [ 115 | factory.createImportDeclaration( 116 | undefined, 117 | factory.createImportClause( 118 | false, 119 | undefined, 120 | factory.createNamedImports([ 121 | factory.createImportSpecifier( 122 | false, 123 | undefined, 124 | factory.createIdentifier("Database") 125 | ), 126 | ]) 127 | ), 128 | factory.createStringLiteral("better-sqlite3"), 129 | undefined 130 | ), 131 | ]; 132 | 133 | return imports; 134 | } 135 | 136 | execDecl( 137 | funcName: string, 138 | queryName: string, 139 | argIface: string | undefined, 140 | params: Parameter[] 141 | ) { 142 | const funcParams = funcParamsDecl(argIface, params); 143 | 144 | return factory.createFunctionDeclaration( 145 | [ 146 | factory.createToken(SyntaxKind.ExportKeyword), 147 | factory.createToken(SyntaxKind.AsyncKeyword), 148 | ], 149 | undefined, 150 | factory.createIdentifier(funcName), 151 | undefined, 152 | funcParams, 153 | factory.createTypeReferenceNode(factory.createIdentifier("Promise"), [ 154 | factory.createKeywordTypeNode(SyntaxKind.VoidKeyword), 155 | ]), 156 | factory.createBlock( 157 | [ 158 | factory.createVariableStatement( 159 | undefined, 160 | factory.createVariableDeclarationList( 161 | [ 162 | factory.createVariableDeclaration( 163 | factory.createIdentifier("stmt"), 164 | undefined, 165 | undefined, 166 | factory.createCallExpression( 167 | factory.createPropertyAccessExpression( 168 | factory.createIdentifier("database"), 169 | factory.createIdentifier("prepare") 170 | ), 171 | undefined, 172 | [factory.createIdentifier(queryName)] 173 | ) 174 | ), 175 | ], 176 | NodeFlags.Const | 177 | // ts.NodeFlags.Constant | 178 | // NodeFlags.AwaitContext | 179 | // ts.NodeFlags.Constant | 180 | // NodeFlags.ContextFlags | 181 | NodeFlags.TypeExcludesFlags 182 | ) 183 | ), 184 | factory.createExpressionStatement( 185 | factory.createAwaitExpression( 186 | factory.createCallExpression( 187 | factory.createPropertyAccessExpression( 188 | factory.createIdentifier("stmt"), 189 | factory.createIdentifier("run") 190 | ), 191 | undefined, 192 | params.map((param, i) => 193 | factory.createPropertyAccessExpression( 194 | factory.createIdentifier("args"), 195 | factory.createIdentifier(argName(i, param.column)) 196 | ) 197 | ) 198 | ) 199 | ) 200 | ), 201 | ], 202 | true 203 | ) 204 | ); 205 | } 206 | 207 | oneDecl( 208 | funcName: string, 209 | queryName: string, 210 | argIface: string | undefined, 211 | returnIface: string, 212 | params: Parameter[], 213 | columns: Column[] 214 | ) { 215 | const funcParams = funcParamsDecl(argIface, params); 216 | 217 | return factory.createFunctionDeclaration( 218 | [ 219 | factory.createToken(SyntaxKind.ExportKeyword), 220 | factory.createToken(SyntaxKind.AsyncKeyword), 221 | ], 222 | undefined, 223 | factory.createIdentifier(funcName), 224 | undefined, 225 | funcParams, 226 | factory.createTypeReferenceNode(factory.createIdentifier("Promise"), [ 227 | factory.createUnionTypeNode([ 228 | factory.createTypeReferenceNode( 229 | factory.createIdentifier(returnIface), 230 | undefined 231 | ), 232 | factory.createLiteralTypeNode(factory.createNull()), 233 | ]), 234 | ]), 235 | factory.createBlock( 236 | [ 237 | factory.createVariableStatement( 238 | undefined, 239 | factory.createVariableDeclarationList( 240 | [ 241 | factory.createVariableDeclaration( 242 | factory.createIdentifier("stmt"), 243 | undefined, 244 | undefined, 245 | factory.createCallExpression( 246 | factory.createPropertyAccessExpression( 247 | factory.createIdentifier("database"), 248 | factory.createIdentifier("prepare") 249 | ), 250 | undefined, 251 | [factory.createIdentifier(queryName)] 252 | ) 253 | ), 254 | ], 255 | NodeFlags.Const | 256 | // ts.NodeFlags.Constant | 257 | // NodeFlags.AwaitContext | 258 | // ts.NodeFlags.Constant | 259 | // NodeFlags.ContextFlags | 260 | NodeFlags.TypeExcludesFlags 261 | ) 262 | ), 263 | factory.createVariableStatement( 264 | undefined, 265 | factory.createVariableDeclarationList( 266 | [ 267 | factory.createVariableDeclaration( 268 | factory.createIdentifier("result"), 269 | undefined, 270 | undefined, 271 | factory.createAwaitExpression( 272 | factory.createCallExpression( 273 | factory.createPropertyAccessExpression( 274 | factory.createIdentifier("stmt"), 275 | factory.createIdentifier("get") 276 | ), 277 | undefined, 278 | params.map((param, i) => 279 | factory.createPropertyAccessExpression( 280 | factory.createIdentifier("args"), 281 | factory.createIdentifier(argName(i, param.column)) 282 | ) 283 | ) 284 | ) 285 | ) 286 | ), 287 | ], 288 | NodeFlags.Const | 289 | // ts.NodeFlags.Constant | 290 | NodeFlags.AwaitContext | 291 | // ts.NodeFlags.Constant | 292 | NodeFlags.ContextFlags | 293 | NodeFlags.TypeExcludesFlags 294 | ) 295 | ), 296 | factory.createIfStatement( 297 | factory.createBinaryExpression( 298 | factory.createIdentifier("result"), 299 | factory.createToken(SyntaxKind.EqualsEqualsToken), 300 | factory.createIdentifier("undefined") 301 | ), 302 | factory.createBlock( 303 | [factory.createReturnStatement(factory.createNull())], 304 | true 305 | ), 306 | undefined 307 | ), 308 | factory.createReturnStatement( 309 | factory.createAsExpression( 310 | factory.createIdentifier("result"), 311 | factory.createTypeReferenceNode( 312 | factory.createIdentifier(returnIface), 313 | undefined 314 | ) 315 | ) 316 | ), 317 | ], 318 | true 319 | ) 320 | ); 321 | } 322 | 323 | manyDecl( 324 | funcName: string, 325 | queryName: string, 326 | argIface: string | undefined, 327 | returnIface: string, 328 | params: Parameter[], 329 | columns: Column[] 330 | ) { 331 | const funcParams = funcParamsDecl(argIface, params); 332 | 333 | return factory.createFunctionDeclaration( 334 | [ 335 | factory.createToken(SyntaxKind.ExportKeyword), 336 | factory.createToken(SyntaxKind.AsyncKeyword), 337 | ], 338 | undefined, 339 | factory.createIdentifier(funcName), 340 | undefined, 341 | funcParams, 342 | factory.createTypeReferenceNode(factory.createIdentifier("Promise"), [ 343 | factory.createArrayTypeNode( 344 | factory.createTypeReferenceNode( 345 | factory.createIdentifier(returnIface), 346 | undefined 347 | ) 348 | ), 349 | ]), 350 | factory.createBlock( 351 | [ 352 | factory.createVariableStatement( 353 | undefined, 354 | factory.createVariableDeclarationList( 355 | [ 356 | factory.createVariableDeclaration( 357 | factory.createIdentifier("stmt"), 358 | undefined, 359 | undefined, 360 | factory.createCallExpression( 361 | factory.createPropertyAccessExpression( 362 | factory.createIdentifier("database"), 363 | factory.createIdentifier("prepare") 364 | ), 365 | undefined, 366 | [factory.createIdentifier(queryName)] 367 | ) 368 | ), 369 | ], 370 | NodeFlags.Const | 371 | // ts.NodeFlags.Constant | 372 | // NodeFlags.AwaitContext | 373 | // ts.NodeFlags.Constant | 374 | // NodeFlags.ContextFlags | 375 | NodeFlags.TypeExcludesFlags 376 | ) 377 | ), 378 | factory.createVariableStatement( 379 | undefined, 380 | factory.createVariableDeclarationList( 381 | [ 382 | factory.createVariableDeclaration( 383 | factory.createIdentifier("result"), 384 | undefined, 385 | undefined, 386 | factory.createAwaitExpression( 387 | factory.createCallExpression( 388 | factory.createPropertyAccessExpression( 389 | factory.createIdentifier("stmt"), 390 | factory.createIdentifier("all") 391 | ), 392 | undefined, 393 | params.map((param, i) => 394 | factory.createPropertyAccessExpression( 395 | factory.createIdentifier("args"), 396 | factory.createIdentifier(argName(i, param.column)) 397 | ) 398 | ) 399 | ) 400 | ) 401 | ), 402 | ], 403 | NodeFlags.Const | 404 | // NodeFlags.Constant | 405 | NodeFlags.AwaitContext | 406 | // NodeFlags.Constant | 407 | NodeFlags.ContextFlags | 408 | NodeFlags.TypeExcludesFlags 409 | ) 410 | ), 411 | factory.createReturnStatement( 412 | factory.createAsExpression( 413 | factory.createIdentifier("result"), 414 | factory.createArrayTypeNode( 415 | factory.createTypeReferenceNode( 416 | factory.createIdentifier(returnIface), 417 | undefined 418 | ) 419 | ) 420 | ) 421 | ), 422 | ], 423 | true 424 | ) 425 | ); 426 | } 427 | 428 | execlastidDecl( 429 | funcName: string, 430 | queryName: string, 431 | argIface: string | undefined, 432 | params: Parameter[] 433 | ): FunctionDeclaration { 434 | throw new Error( 435 | "better-sqlite3 driver currently does not support :execlastid" 436 | ); 437 | } 438 | } 439 | -------------------------------------------------------------------------------- /src/drivers/postgres.ts: -------------------------------------------------------------------------------- 1 | import { 2 | SyntaxKind, 3 | NodeFlags, 4 | TypeNode, 5 | factory, 6 | FunctionDeclaration, 7 | } from "typescript"; 8 | 9 | import { Parameter, Column } from "../gen/plugin/codegen_pb"; 10 | import { argName, colName } from "./utlis"; 11 | import { log } from "../logger"; 12 | 13 | function funcParamsDecl(iface: string | undefined, params: Parameter[]) { 14 | let funcParams = [ 15 | factory.createParameterDeclaration( 16 | undefined, 17 | undefined, 18 | factory.createIdentifier("sql"), 19 | undefined, 20 | factory.createTypeReferenceNode( 21 | factory.createIdentifier("Sql"), 22 | undefined 23 | ), 24 | undefined 25 | ), 26 | ]; 27 | 28 | if (iface && params.length > 0) { 29 | funcParams.push( 30 | factory.createParameterDeclaration( 31 | undefined, 32 | undefined, 33 | factory.createIdentifier("args"), 34 | undefined, 35 | factory.createTypeReferenceNode( 36 | factory.createIdentifier(iface), 37 | undefined 38 | ), 39 | undefined 40 | ) 41 | ); 42 | } 43 | 44 | return funcParams; 45 | } 46 | 47 | export class Driver { 48 | columnType(column?: Column): TypeNode { 49 | if (column === undefined || column.type === undefined) { 50 | return factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); 51 | } 52 | // Some of the type names have the `pgcatalog.` prefix. Remove this. 53 | let typeName = column.type.name; 54 | const pgCatalog = "pg_catalog."; 55 | if (typeName.startsWith(pgCatalog)) { 56 | typeName = typeName.slice(pgCatalog.length); 57 | } 58 | let typ: TypeNode = factory.createKeywordTypeNode(SyntaxKind.StringKeyword); 59 | switch (typeName) { 60 | case "aclitem": { 61 | // string 62 | break; 63 | } 64 | case "bigserial": { 65 | // string 66 | break; 67 | } 68 | case "bit": { 69 | // string 70 | break; 71 | } 72 | case "bool": { 73 | typ = factory.createKeywordTypeNode(SyntaxKind.BooleanKeyword); 74 | break; 75 | } 76 | case "box": { 77 | // string 78 | break; 79 | } 80 | case "bpchar": { 81 | // string 82 | break; 83 | } 84 | case "bytea": { 85 | // TODO: Is this correct or node-specific? 86 | typ = factory.createTypeReferenceNode( 87 | factory.createIdentifier("Buffer"), 88 | undefined 89 | ); 90 | break; 91 | } 92 | case "cid": { 93 | // string 94 | break; 95 | } 96 | case "cidr": { 97 | // string 98 | break; 99 | } 100 | case "circle": { 101 | // string 102 | break; 103 | } 104 | case "date": { 105 | typ = factory.createTypeReferenceNode( 106 | factory.createIdentifier("Date"), 107 | undefined 108 | ); 109 | break; 110 | } 111 | case "float4": { 112 | typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); 113 | break; 114 | } 115 | case "float8": { 116 | typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); 117 | break; 118 | } 119 | case "inet": { 120 | // string 121 | break; 122 | } 123 | case "int2": { 124 | typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); 125 | break; 126 | } 127 | case "int4": { 128 | typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); 129 | break; 130 | } 131 | case "int8": { 132 | // string 133 | break; 134 | } 135 | case "interval": { 136 | // string 137 | break; 138 | } 139 | case "json": { 140 | typ = factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); 141 | break; 142 | } 143 | case "jsonb": { 144 | typ = factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); 145 | break; 146 | } 147 | case "line": { 148 | // string 149 | break; 150 | } 151 | case "lseg": { 152 | // string 153 | break; 154 | } 155 | case "madaddr": { 156 | // string 157 | break; 158 | } 159 | case "madaddr8": { 160 | // string 161 | break; 162 | } 163 | case "money": { 164 | // string 165 | break; 166 | } 167 | case "oid": { 168 | typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); 169 | break; 170 | } 171 | case "path": { 172 | // string 173 | break; 174 | } 175 | case "pg_node_tree": { 176 | // string 177 | break; 178 | } 179 | case "pg_snapshot": { 180 | // string 181 | break; 182 | } 183 | case "point": { 184 | // string 185 | break; 186 | } 187 | case "polygon": { 188 | // string 189 | break; 190 | } 191 | case "regproc": { 192 | // string 193 | break; 194 | } 195 | case "regrole": { 196 | // string 197 | break; 198 | } 199 | case "serial": { 200 | typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); 201 | break; 202 | } 203 | case "serial2": { 204 | typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); 205 | break; 206 | } 207 | case "serial4": { 208 | typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); 209 | break; 210 | } 211 | case "serial8": { 212 | // string 213 | break; 214 | } 215 | case "smallserial": { 216 | typ = factory.createKeywordTypeNode(SyntaxKind.NumberKeyword); 217 | break; 218 | } 219 | case "tid": { 220 | // string 221 | break; 222 | } 223 | case "text": { 224 | // string 225 | break; 226 | } 227 | case "time": { 228 | // string 229 | break; 230 | } 231 | case "timetz": { 232 | // string 233 | break; 234 | } 235 | case "timestamp": { 236 | typ = factory.createTypeReferenceNode( 237 | factory.createIdentifier("Date"), 238 | undefined 239 | ); 240 | break; 241 | } 242 | case "timestamptz": { 243 | typ = factory.createTypeReferenceNode( 244 | factory.createIdentifier("Date"), 245 | undefined 246 | ); 247 | break; 248 | } 249 | case "tsquery": { 250 | // string 251 | break; 252 | } 253 | case "tsvector": { 254 | // string 255 | break; 256 | } 257 | case "txid_snapshot": { 258 | // string 259 | break; 260 | } 261 | case "uuid": { 262 | // string 263 | break; 264 | } 265 | case "varbit": { 266 | // string 267 | break; 268 | } 269 | case "varchar": { 270 | // string 271 | break; 272 | } 273 | case "xid": { 274 | // string 275 | break; 276 | } 277 | case "xml": { 278 | // string 279 | break; 280 | } 281 | default: { 282 | log(`unknown type ${column.type?.name}`); 283 | break; 284 | } 285 | } 286 | if (column.isArray || column.arrayDims > 0) { 287 | let dims = Math.max(column.arrayDims || 1); 288 | for (let i = 0; i < dims; i++) { 289 | typ = factory.createArrayTypeNode(typ); 290 | } 291 | } 292 | if (column.notNull) { 293 | return typ; 294 | } 295 | return factory.createUnionTypeNode([ 296 | typ, 297 | factory.createLiteralTypeNode(factory.createNull()), 298 | ]); 299 | } 300 | 301 | preamble(queries: unknown) { 302 | return [ 303 | factory.createImportDeclaration( 304 | undefined, 305 | factory.createImportClause( 306 | false, 307 | undefined, 308 | factory.createNamedImports([ 309 | factory.createImportSpecifier( 310 | false, 311 | undefined, 312 | factory.createIdentifier("Sql") 313 | ), 314 | ]) 315 | ), 316 | factory.createStringLiteral("postgres"), 317 | undefined 318 | ), 319 | ]; 320 | } 321 | 322 | execDecl( 323 | funcName: string, 324 | queryName: string, 325 | argIface: string | undefined, 326 | params: Parameter[] 327 | ) { 328 | const funcParams = funcParamsDecl(argIface, params); 329 | 330 | return factory.createFunctionDeclaration( 331 | [ 332 | factory.createToken(SyntaxKind.ExportKeyword), 333 | factory.createToken(SyntaxKind.AsyncKeyword), 334 | ], 335 | undefined, 336 | factory.createIdentifier(funcName), 337 | undefined, 338 | funcParams, 339 | factory.createTypeReferenceNode(factory.createIdentifier("Promise"), [ 340 | factory.createKeywordTypeNode(SyntaxKind.VoidKeyword), 341 | ]), 342 | factory.createBlock( 343 | [ 344 | factory.createExpressionStatement( 345 | factory.createAwaitExpression( 346 | factory.createCallExpression( 347 | factory.createPropertyAccessExpression( 348 | factory.createIdentifier("sql"), 349 | factory.createIdentifier("unsafe") 350 | ), 351 | undefined, 352 | [ 353 | factory.createIdentifier(queryName), 354 | factory.createArrayLiteralExpression( 355 | params.map((param, i) => 356 | factory.createPropertyAccessExpression( 357 | factory.createIdentifier("args"), 358 | factory.createIdentifier(argName(i, param.column)) 359 | ) 360 | ), 361 | false 362 | ), 363 | ] 364 | ) 365 | ) 366 | ), 367 | ], 368 | true 369 | ) 370 | ); 371 | } 372 | 373 | manyDecl( 374 | funcName: string, 375 | queryName: string, 376 | argIface: string | undefined, 377 | returnIface: string, 378 | params: Parameter[], 379 | columns: Column[] 380 | ) { 381 | const funcParams = funcParamsDecl(argIface, params); 382 | 383 | return factory.createFunctionDeclaration( 384 | [ 385 | factory.createToken(SyntaxKind.ExportKeyword), 386 | factory.createToken(SyntaxKind.AsyncKeyword), 387 | ], 388 | undefined, 389 | factory.createIdentifier(funcName), 390 | undefined, 391 | funcParams, 392 | factory.createTypeReferenceNode(factory.createIdentifier("Promise"), [ 393 | factory.createArrayTypeNode( 394 | factory.createTypeReferenceNode( 395 | factory.createIdentifier(returnIface), 396 | undefined 397 | ) 398 | ), 399 | ]), 400 | factory.createBlock( 401 | [ 402 | factory.createReturnStatement( 403 | factory.createCallExpression( 404 | factory.createPropertyAccessExpression( 405 | factory.createAwaitExpression( 406 | factory.createCallExpression( 407 | factory.createPropertyAccessExpression( 408 | factory.createCallExpression( 409 | factory.createPropertyAccessExpression( 410 | factory.createIdentifier("sql"), 411 | factory.createIdentifier("unsafe") 412 | ), 413 | undefined, 414 | [ 415 | factory.createIdentifier(queryName), 416 | factory.createArrayLiteralExpression( 417 | params.map((param, i) => 418 | factory.createPropertyAccessExpression( 419 | factory.createIdentifier("args"), 420 | factory.createIdentifier( 421 | argName(i, param.column) 422 | ) 423 | ) 424 | ), 425 | false 426 | ), 427 | ] 428 | ), 429 | factory.createIdentifier("values") 430 | ), 431 | undefined, 432 | undefined 433 | ) 434 | ), 435 | factory.createIdentifier("map") 436 | ), 437 | undefined, 438 | [ 439 | factory.createArrowFunction( 440 | undefined, 441 | undefined, 442 | [ 443 | factory.createParameterDeclaration( 444 | undefined, 445 | undefined, 446 | "row" 447 | ), 448 | ], 449 | undefined, 450 | factory.createToken(SyntaxKind.EqualsGreaterThanToken), 451 | factory.createObjectLiteralExpression( 452 | columns.map((col, i) => 453 | factory.createPropertyAssignment( 454 | factory.createIdentifier(colName(i, col)), 455 | factory.createElementAccessExpression( 456 | factory.createIdentifier("row"), 457 | factory.createNumericLiteral(`${i}`) 458 | ) 459 | ) 460 | ), 461 | true 462 | ) 463 | ), 464 | ] 465 | ) 466 | ), 467 | ], 468 | true 469 | ) 470 | ); 471 | } 472 | 473 | oneDecl( 474 | funcName: string, 475 | queryName: string, 476 | argIface: string | undefined, 477 | returnIface: string, 478 | params: Parameter[], 479 | columns: Column[] 480 | ) { 481 | const funcParams = funcParamsDecl(argIface, params); 482 | 483 | return factory.createFunctionDeclaration( 484 | [ 485 | factory.createToken(SyntaxKind.ExportKeyword), 486 | factory.createToken(SyntaxKind.AsyncKeyword), 487 | ], 488 | undefined, 489 | factory.createIdentifier(funcName), 490 | undefined, 491 | funcParams, 492 | factory.createTypeReferenceNode(factory.createIdentifier("Promise"), [ 493 | factory.createUnionTypeNode([ 494 | factory.createTypeReferenceNode( 495 | factory.createIdentifier(returnIface), 496 | undefined 497 | ), 498 | factory.createLiteralTypeNode(factory.createNull()), 499 | ]), 500 | ]), 501 | factory.createBlock( 502 | [ 503 | factory.createVariableStatement( 504 | undefined, 505 | factory.createVariableDeclarationList( 506 | [ 507 | factory.createVariableDeclaration( 508 | factory.createIdentifier("rows"), 509 | undefined, 510 | undefined, 511 | factory.createAwaitExpression( 512 | factory.createCallExpression( 513 | factory.createPropertyAccessExpression( 514 | factory.createCallExpression( 515 | factory.createPropertyAccessExpression( 516 | factory.createIdentifier("sql"), 517 | factory.createIdentifier("unsafe") 518 | ), 519 | undefined, 520 | [ 521 | factory.createIdentifier(queryName), 522 | factory.createArrayLiteralExpression( 523 | params.map((param, i) => 524 | factory.createPropertyAccessExpression( 525 | factory.createIdentifier("args"), 526 | factory.createIdentifier( 527 | argName(i, param.column) 528 | ) 529 | ) 530 | ), 531 | false 532 | ), 533 | ] 534 | ), 535 | factory.createIdentifier("values") 536 | ), 537 | undefined, 538 | undefined 539 | ) 540 | ) 541 | ), 542 | ], 543 | NodeFlags.Const | 544 | // ts.NodeFlags.Constant | 545 | NodeFlags.AwaitContext | 546 | // ts.NodeFlags.Constant | 547 | NodeFlags.ContextFlags | 548 | NodeFlags.TypeExcludesFlags 549 | ) 550 | ), 551 | factory.createIfStatement( 552 | factory.createBinaryExpression( 553 | factory.createPropertyAccessExpression( 554 | factory.createIdentifier("rows"), 555 | factory.createIdentifier("length") 556 | ), 557 | factory.createToken(SyntaxKind.ExclamationEqualsEqualsToken), 558 | factory.createNumericLiteral("1") 559 | ), 560 | factory.createBlock( 561 | [factory.createReturnStatement(factory.createNull())], 562 | true 563 | ), 564 | undefined 565 | ), 566 | factory.createVariableStatement( 567 | undefined, 568 | factory.createVariableDeclarationList( 569 | [ 570 | factory.createVariableDeclaration( 571 | "row", 572 | undefined, 573 | undefined, 574 | factory.createElementAccessExpression( 575 | factory.createIdentifier("rows"), 576 | factory.createNumericLiteral("0") 577 | ) 578 | ), 579 | ], 580 | NodeFlags.Const 581 | ) 582 | ), 583 | factory.createIfStatement( 584 | factory.createPrefixUnaryExpression( 585 | SyntaxKind.ExclamationToken, 586 | factory.createIdentifier("row") 587 | ), 588 | factory.createBlock( 589 | [factory.createReturnStatement(factory.createNull())], 590 | true 591 | ), 592 | undefined 593 | ), 594 | factory.createReturnStatement( 595 | factory.createObjectLiteralExpression( 596 | columns.map((col, i) => 597 | factory.createPropertyAssignment( 598 | factory.createIdentifier(colName(i, col)), 599 | factory.createElementAccessExpression( 600 | factory.createIdentifier("row"), 601 | factory.createNumericLiteral(`${i}`) 602 | ) 603 | ) 604 | ), 605 | true 606 | ) 607 | ), 608 | ], 609 | true 610 | ) 611 | ); 612 | } 613 | 614 | execlastidDecl( 615 | funcName: string, 616 | queryName: string, 617 | argIface: string | undefined, 618 | params: Parameter[] 619 | ): FunctionDeclaration { 620 | throw new Error("postgres driver currently does not support :execlastid"); 621 | } 622 | } 623 | -------------------------------------------------------------------------------- /src/drivers/utlis.ts: -------------------------------------------------------------------------------- 1 | import { Column } from "../gen/plugin/codegen_pb"; 2 | 3 | // https://stackoverflow.com/questions/40710628/how-to-convert-snake-case-to-camelcase 4 | export function fieldName( 5 | prefix: string, 6 | index: number, 7 | column?: Column 8 | ): string { 9 | let name = `${prefix}_${index}`; 10 | if (column) { 11 | name = column.name; 12 | } 13 | return name 14 | .toLowerCase() 15 | .replace(/([_][a-z])/g, (group) => group.toUpperCase().replace("_", "")); 16 | } 17 | 18 | export function argName(index: number, column?: Column): string { 19 | return fieldName("arg", index, column); 20 | } 21 | 22 | export function colName(index: number, column?: Column): string { 23 | return fieldName("col", index, column); 24 | } 25 | -------------------------------------------------------------------------------- /src/logger.ts: -------------------------------------------------------------------------------- 1 | // I cant' get this import to work locally. The import in node_modules is 2 | // javy/dist but esbuild requires the import to be javy/fs 3 | // 4 | // @ts-expect-error 5 | import { readFileSync, writeFileSync, STDIO } from "javy/fs"; 6 | 7 | export function log(msg: string) { 8 | const encoder = new TextEncoder(); 9 | writeFileSync(STDIO.Stderr, encoder.encode(msg)); 10 | } 11 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig to read more about this file */ 4 | 5 | /* Projects */ 6 | // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ 7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 8 | // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ 9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ 10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 12 | 13 | /* Language and Environment */ 14 | "target": "es2020", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 15 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 16 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 17 | // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ 18 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 19 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ 20 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 21 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ 22 | // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ 23 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 24 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 25 | // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ 26 | 27 | /* Modules */ 28 | "module": "commonjs", /* Specify what module code is generated. */ 29 | // "rootDir": "./", /* Specify the root folder within your source files. */ 30 | // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ 31 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 32 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 33 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 34 | // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ 35 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */ 36 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 37 | // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ 38 | // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ 39 | // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ 40 | // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ 41 | // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ 42 | // "resolveJsonModule": true, /* Enable importing .json files. */ 43 | // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ 44 | // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ 45 | 46 | /* JavaScript Support */ 47 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ 48 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 49 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ 50 | 51 | /* Emit */ 52 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 53 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 54 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 55 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 56 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 57 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ 58 | // "outDir": "./", /* Specify an output folder for all emitted files. */ 59 | // "removeComments": true, /* Disable emitting comments. */ 60 | // "noEmit": true, /* Disable emitting files from a compilation. */ 61 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 62 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ 63 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 64 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 65 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 66 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 67 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 68 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 69 | // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ 70 | // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ 71 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 72 | // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ 73 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 74 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 75 | 76 | /* Interop Constraints */ 77 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 78 | // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ 79 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 80 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ 81 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 82 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 83 | 84 | /* Type Checking */ 85 | "strict": true, /* Enable all strict type-checking options. */ 86 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ 87 | // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ 88 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 89 | // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ 90 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 91 | // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ 92 | // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ 93 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 94 | // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ 95 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ 96 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 97 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 98 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 99 | // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ 100 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 101 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ 102 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 103 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 104 | 105 | /* Completeness */ 106 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 107 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 108 | }, 109 | "include": [ 110 | "src/*.ts", 111 | ] 112 | } 113 | --------------------------------------------------------------------------------