diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b036a762..522e93b8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: ['16', '18', '19'] + node-version: ['16', '18'] name: Test (node ${{ matrix.node-version }}.x) steps: - uses: actions/checkout@v3 diff --git a/README.md b/README.md index 1566b155..7f6f51ab 100644 --- a/README.md +++ b/README.md @@ -18,18 +18,21 @@ No need to map or translate your DB schema to TypeScript, PgTyped automatically 4. Useful parameter interpolation helpers for arrays and objects. 5. No need to define your DB schema in TypeScript, your running DB is the live source of type data. 6. Prevents SQL injections by not doing explicit parameter substitution. Instead, queries and parameters are sent separately to the DB driver, allowing parameter substitution to be safely done by the PostgreSQL server. +7. Native ESM support. Runtime dependencies are also provided as CommonJS. ### Documentation -Visit our new documentation page at [https://pgtyped.now.sh/](https://pgtyped.now.sh/) +Visit our documentation page at [https://pgtyped.vercel.app/](https://pgtyped.vercel.app/) ### Getting started -1. `npm install @pgtyped/cli @pgtyped/query typescript` (typescript is a required peer dependency for pgtyped) -2. Create a PgTyped `config.json` file. -3. Run `npx pgtyped -w -c config.json` to start PgTyped in watch mode. +1. `npm install -D @pgtyped/cli typescript` (typescript is a required peer dependency for pgtyped) +2. `npm install @pgtyped/runtime` (`@pgtyped/runtime` is the only required runtime dependency of pgtyped) +3. Create a PgTyped `config.json` file. +4. Run `npx pgtyped -w -c config.json` to start PgTyped in watch mode. -Refer to the [example app](./packages/example/README.md) for a preconfigured example. +More info on getting started can be found in the [Getting Started](https://pgtyped.vercel.app/docs/getting-started) page. +You can also refer to the [example app](./packages/example/README.md) for a preconfigured example. ### Example @@ -101,7 +104,7 @@ main(); ### Resources -1. [Configuring Pgtyped](https://pgtyped.vercel.app/docs/cli) +1. [Configuring pgTyped](https://pgtyped.vercel.app/docs/cli) 2. [Writing queries in SQL files](https://pgtyped.vercel.app/docs/sql-file-intro) 3. [Advanced queries and parameter expansions in SQL files](https://pgtyped.vercel.app/docs/sql-file) 4. [Writing queries in TS files](https://pgtyped.vercel.app/docs/ts-file-intro) diff --git a/docs-new/docs/getting-started.md b/docs-new/docs/getting-started.md index 5ce0f538..71b6855a 100644 --- a/docs-new/docs/getting-started.md +++ b/docs-new/docs/getting-started.md @@ -6,7 +6,8 @@ sidebar_label: Getting Started ### Installation -1. `npm install @pgtyped/cli @pgtyped/query typescript` (TS is a required peer dependency) +1. `npm install -D @pgtyped/cli typescript` (typescript is a required peer dependency for pgtyped) +2. `npm install @pgtyped/runtime` (runtime is the only required runtime dependency for pgtyped) 2. Create a PgTyped `config.json` file. 3. Run `npx pgtyped -w -c config.json` to start PgTyped in watch mode. diff --git a/docs-new/docs/ts-file-intro.md b/docs-new/docs/ts-file-intro.md index 27fdebd6..966e97e2 100644 --- a/docs-new/docs/ts-file-intro.md +++ b/docs-new/docs/ts-file-intro.md @@ -9,7 +9,7 @@ PgTyped supports inlined queries using the `sql` template literal. To see how that works lets write some queries in `users/queries.ts`: ```ts title="users/queries.ts" -import { sql } from '@pgtyped/query'; +import { sql } from '@pgtyped/runtime'; import { ISelectUserIdsQuery } from './queries.types.ts'; export const selectUserIds = sql< @@ -45,7 +45,7 @@ export interface ISelectUserIdsResult { We can now pass the `ISelectUserIdsQuery` as a generic parameter to our query in `users/queries.ts`: ```ts title="users/queries.ts" -import { sql } from '@pgtyped/query'; +import { sql } from '@pgtyped/runtime'; import { ISelectUserIdsQuery } from './queries.types.ts'; export const selectUserIds = sql< diff --git a/docs-new/docs/ts-file.md b/docs-new/docs/ts-file.md index d4960833..fc9ff0b3 100644 --- a/docs-new/docs/ts-file.md +++ b/docs-new/docs/ts-file.md @@ -8,7 +8,7 @@ PgTyped also supports parsing queries from TS files. Such queries must be tagged with an `sql` template literal, like this: ```ts -import { sql } from '@pgtyped/query'; +import { sql } from '@pgtyped/runtime'; const getUsersWithComments = sql` SELECT u.* FROM users u @@ -21,7 +21,7 @@ PgTyped will then scan your project for such `sql` tags and generate types for e Once the type files have been generated you can import them to type your query: ```ts -import { sql } from '@pgtyped/query'; +import { sql } from '@pgtyped/runtime'; import { IGetUsersWithCommentsQuery } from './sample.types'; const getUsersWithComments = sql` diff --git a/jest.config.ts b/jest.config.ts new file mode 100644 index 00000000..bb75cce2 --- /dev/null +++ b/jest.config.ts @@ -0,0 +1,24 @@ +import type { Config } from 'jest'; + +const config: Config = { + snapshotFormat: { + escapeString: true, + printBasicPrototype: true, + }, + roots: ['src'], + moduleNameMapper: { + '^(\\.{1,2}/.*)\\.js$': '$1', + }, + transform: { + '^.+\\.tsx?$': [ + 'ts-jest', + { + useESM: true, + }, + ], + }, + preset: 'ts-jest/presets/default-esm', + testRegex: '\\.test\\.tsx?$', +}; + +export default config; diff --git a/package-lock.json b/package-lock.json index 4441e8f4..afc684ac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,6 +41,11 @@ "node": ">=6.0.0" } }, + "node_modules/@assemblyscript/loader": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@assemblyscript/loader/-/loader-0.10.1.tgz", + "integrity": "sha512-H71nDOOL8Y7kWRLqf6Sums+01Q5msqBW2KhDUTemh1tvY04eSkSXrK0uj/4mmY0Xr16/3zyZmsrxN7CKuRbNRg==" + }, "node_modules/@babel/code-frame": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", @@ -617,6 +622,358 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@esbuild/android-arm": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.4.tgz", + "integrity": "sha512-R9GCe2xl2XDSc2XbQB63mFiFXHIVkOP+ltIxICKXqUPrFX97z6Z7vONCLQM1pSOLGqfLrGi3B7nbhxmFY/fomg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.4.tgz", + "integrity": "sha512-91VwDrl4EpxBCiG6h2LZZEkuNvVZYJkv2T9gyLG/mhGG1qrM7i5SwUcg/hlSPnL/4hDT0TFcF35/XMGSn0bemg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.4.tgz", + "integrity": "sha512-mGSqhEPL7029XL7QHNPxPs15JVa02hvZvysUcyMP9UXdGFwncl2WU0bqx+Ysgzd+WAbv8rfNa73QveOxAnAM2w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.4.tgz", + "integrity": "sha512-tTyJRM9dHvlMPt1KrBFVB5OW1kXOsRNvAPtbzoKazd5RhD5/wKlXk1qR2MpaZRYwf4WDMadt0Pv0GwxB41CVow==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.4.tgz", + "integrity": "sha512-phQuC2Imrb3TjOJwLN8EO50nb2FHe8Ew0OwgZDH1SV6asIPGudnwTQtighDF2EAYlXChLoMJwqjAp4vAaACq6w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.4.tgz", + "integrity": "sha512-oH6JUZkocgmjzzYaP5juERLpJQSwazdjZrTPgLRmAU2bzJ688x0vfMB/WTv4r58RiecdHvXOPC46VtsMy/mepg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.4.tgz", + "integrity": "sha512-U4iWGn/9TrAfpAdfd56eO0pRxIgb0a8Wj9jClrhT8hvZnOnS4dfMPW7o4fn15D/KqoiVYHRm43jjBaTt3g/2KA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.4.tgz", + "integrity": "sha512-S2s9xWTGMTa/fG5EyMGDeL0wrWVgOSQcNddJWgu6rG1NCSXJHs76ZP9AsxjB3f2nZow9fWOyApklIgiTGZKhiw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.4.tgz", + "integrity": "sha512-UkGfQvYlwOaeYJzZG4cLV0hCASzQZnKNktRXUo3/BMZvdau40AOz9GzmGA063n1piq6VrFFh43apRDQx8hMP2w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.4.tgz", + "integrity": "sha512-3lqFi4VFo/Vwvn77FZXeLd0ctolIJH/uXkH3yNgEk89Eh6D3XXAC9/iTPEzeEpsNE5IqGIsFa5Z0iPeOh25IyA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.4.tgz", + "integrity": "sha512-HqpWZkVslDHIwdQ9D+gk7NuAulgQvRxF9no54ut/M55KEb3mi7sQS3GwpPJzSyzzP0UkjQVN7/tbk88/CaX4EQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.4.tgz", + "integrity": "sha512-d/nMCKKh/SVDbqR9ju+b78vOr0tNXtfBjcp5vfHONCCOAL9ad8gN9dC/u+UnH939pz7wO+0u/x9y1MaZcb/lKA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.4.tgz", + "integrity": "sha512-lOD9p2dmjZcNiTU+sGe9Nn6G3aYw3k0HBJies1PU0j5IGfp6tdKOQ6mzfACRFCqXjnBuTqK7eTYpwx09O5LLfg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.4.tgz", + "integrity": "sha512-mTGnwWwVshAjGsd8rP+K6583cPDgxOunsqqldEYij7T5/ysluMHKqUIT4TJHfrDFadUwrghAL6QjER4FeqQXoA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.4.tgz", + "integrity": "sha512-AQYuUGp50XM29/N/dehADxvc2bUqDcoqrVuijop1Wv72SyxT6dDB9wjUxuPZm2HwIM876UoNNBMVd+iX/UTKVQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.4.tgz", + "integrity": "sha512-+AsFBwKgQuhV2shfGgA9YloxLDVjXgUEWZum7glR5lLmV94IThu/u2JZGxTgjYby6kyXEx8lKOqP5rTEVBR0Rw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.4.tgz", + "integrity": "sha512-zD1TKYX9553OiLS/qkXPMlWoELYkH/VkzRYNKEU+GwFiqkq0SuxsKnsCg5UCdxN3cqd+1KZ8SS3R+WG/Hxy2jQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.4.tgz", + "integrity": "sha512-PY1NjEsLRhPEFFg1AV0/4Or/gR+q2dOb9s5rXcPuCjyHRzbt8vnHJl3vYj+641TgWZzTFmSUnZbzs1zwTzjeqw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.4.tgz", + "integrity": "sha512-B3Z7s8QZQW9tKGleMRXvVmwwLPAUoDCHs4WZ2ElVMWiortLJFowU1NjAhXOKjDgC7o9ByeVcwyOlJ+F2r6ZgmQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.4.tgz", + "integrity": "sha512-0HCu8R3mY/H5V7N6kdlsJkvrT591bO/oRZy8ztF1dhgNU5xD5tAh5bKByT1UjTGjp/VVBsl1PDQ3L18SfvtnBQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.4.tgz", + "integrity": "sha512-VUjhVDQycse1gLbe06pC/uaA0M+piQXJpdpNdhg8sPmeIZZqu5xPoGWVCmcsOO2gaM2cywuTYTHkXRozo3/Nkg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.4.tgz", + "integrity": "sha512-0kLAjs+xN5OjhTt/aUA6t48SfENSCKgGPfExADYTOo/UCn0ivxos9/anUVeSfg+L+2O9xkFxvJXIJfG+Q4sYSg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@gar/promisify": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", @@ -3655,10 +4012,18 @@ "resolved": "packages/example", "link": true }, + "node_modules/@pgtyped/parser": { + "resolved": "packages/parser", + "link": true + }, "node_modules/@pgtyped/query": { "resolved": "packages/query", "link": true }, + "node_modules/@pgtyped/runtime": { + "resolved": "packages/runtime", + "link": true + }, "node_modules/@pgtyped/wire": { "resolved": "packages/wire", "link": true @@ -3775,6 +4140,7 @@ "resolved": "https://registry.npmjs.org/@types/chalk/-/chalk-2.2.0.tgz", "integrity": "sha512-1zzPV9FDe1I/WHhRkf9SNgqtRJWZqrBWgu7JGveuHmmyR9CnAPCie2N/x+iHrgnpYBIcCJWHBoMRv2TRWktsvw==", "deprecated": "This is a stub types definition for chalk (https://github.com/chalk/chalk). chalk provides its own type definitions, so you don't need @types/chalk installed!", + "dev": true, "dependencies": { "chalk": "*" } @@ -3783,6 +4149,7 @@ "version": "4.1.7", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", "integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==", + "dev": true, "dependencies": { "@types/ms": "*" } @@ -3987,7 +4354,8 @@ "node_modules/@types/ms": { "version": "0.7.31", "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", - "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==" + "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==", + "dev": true }, "node_modules/@types/node": { "version": "18.11.18", @@ -4003,7 +4371,8 @@ "node_modules/@types/nunjucks": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/@types/nunjucks/-/nunjucks-3.2.1.tgz", - "integrity": "sha512-hUh5HIC7peH+0MvlYU5KM2RydWxG1mBceivHsQGwlelU9zlczLICyJmjMwgjkI3m0+N50n46GVHkw35lIim6LQ==" + "integrity": "sha512-hUh5HIC7peH+0MvlYU5KM2RydWxG1mBceivHsQGwlelU9zlczLICyJmjMwgjkI3m0+N50n46GVHkw35lIim6LQ==", + "dev": true }, "node_modules/@types/parse-json": { "version": "4.0.0", @@ -4015,6 +4384,7 @@ "version": "8.6.6", "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.6.6.tgz", "integrity": "sha512-O2xNmXebtwVekJDD+02udOncjVcMZQuTEQEMpKJ0ZRf5E7/9JJX3izhKUcUifBkyKpljyUM6BTgy2trmviKlpw==", + "dev": true, "dependencies": { "@types/node": "*", "pg-protocol": "*", @@ -4106,6 +4476,15 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/add-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz", @@ -4441,7 +4820,6 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, "funding": [ { "type": "github", @@ -5631,6 +6009,43 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/esbuild": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.4.tgz", + "integrity": "sha512-zBn9MeCwT7W5F1a3lXClD61ip6vQM+H8Msb0w8zMT4ZKBpDg+rFAraNyWCDelB/2L6M3g6AXHPnsyvjMFnxtFw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.17.4", + "@esbuild/android-arm64": "0.17.4", + "@esbuild/android-x64": "0.17.4", + "@esbuild/darwin-arm64": "0.17.4", + "@esbuild/darwin-x64": "0.17.4", + "@esbuild/freebsd-arm64": "0.17.4", + "@esbuild/freebsd-x64": "0.17.4", + "@esbuild/linux-arm": "0.17.4", + "@esbuild/linux-arm64": "0.17.4", + "@esbuild/linux-ia32": "0.17.4", + "@esbuild/linux-loong64": "0.17.4", + "@esbuild/linux-mips64el": "0.17.4", + "@esbuild/linux-ppc64": "0.17.4", + "@esbuild/linux-riscv64": "0.17.4", + "@esbuild/linux-s390x": "0.17.4", + "@esbuild/linux-x64": "0.17.4", + "@esbuild/netbsd-x64": "0.17.4", + "@esbuild/openbsd-x64": "0.17.4", + "@esbuild/sunos-x64": "0.17.4", + "@esbuild/win32-arm64": "0.17.4", + "@esbuild/win32-ia32": "0.17.4", + "@esbuild/win32-x64": "0.17.4" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -5703,6 +6118,11 @@ "node": ">=4.0" } }, + "node_modules/eventemitter-asyncresource": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eventemitter-asyncresource/-/eventemitter-asyncresource-1.0.0.tgz", + "integrity": "sha512-39F7TBIV0G7gTelxwbEqnwhp90eqCPON1k0NwNfwhgKn4Co4ybUbj2pECcXT0B3ztRKZ7Pw1JujUUgmQJHcVAQ==" + }, "node_modules/eventemitter3": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", @@ -6324,6 +6744,21 @@ "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", "dev": true }, + "node_modules/hdr-histogram-js": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hdr-histogram-js/-/hdr-histogram-js-2.0.3.tgz", + "integrity": "sha512-Hkn78wwzWHNCp2uarhzQ2SGFLU3JY8SBDDd3TAABK4fc30wm+MuPOrg5QVFVfkKOQd6Bfz3ukJEI+q9sXEkK1g==", + "dependencies": { + "@assemblyscript/loader": "^0.10.1", + "base64-js": "^1.2.0", + "pako": "^1.0.3" + } + }, + "node_modules/hdr-histogram-percentiles-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hdr-histogram-percentiles-obj/-/hdr-histogram-percentiles-obj-3.0.0.tgz", + "integrity": "sha512-7kIufnBqdsBGcSZLPJwqHT3yhk1QTsSlFsVD3kx5ixH/AlgBs9yM1q6DPhXZ8f8gtdqgh7N7/5btRLpQsS2gHw==" + }, "node_modules/hosted-git-info": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", @@ -8268,19 +8703,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -8968,7 +9390,8 @@ "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true }, "node_modules/merge2": { "version": "1.4.1", @@ -9307,6 +9730,20 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, + "node_modules/nice-napi": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nice-napi/-/nice-napi-1.0.2.tgz", + "integrity": "sha512-px/KnJAJZf5RuBGcfD+Sp2pAKq0ytz8j+1NehvgIGFkvtvFrDM3T8E4x/JJODXK9WZow8RRGrbA9QQ3hs+pDhA==", + "hasInstallScript": true, + "optional": true, + "os": [ + "!win32" + ], + "dependencies": { + "node-addon-api": "^3.0.0", + "node-gyp-build": "^4.2.2" + } + }, "node_modules/no-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", @@ -9320,7 +9757,7 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", - "dev": true + "devOptional": true }, "node_modules/node-fetch": { "version": "2.6.8", @@ -9392,7 +9829,7 @@ "version": "4.6.0", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==", - "dev": true, + "devOptional": true, "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", @@ -10476,6 +10913,11 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -10715,6 +11157,19 @@ "node": ">= 6" } }, + "node_modules/piscina": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/piscina/-/piscina-3.2.0.tgz", + "integrity": "sha512-yn/jMdHRw+q2ZJhFhyqsmANcbF6V2QwmD84c6xRau+QpQOmtrBCoRGdvTfeuFDYXB5W2m6MfLkjkvQa9lUSmIA==", + "dependencies": { + "eventemitter-asyncresource": "^1.0.0", + "hdr-histogram-js": "^2.0.1", + "hdr-histogram-percentiles-obj": "^3.0.0" + }, + "optionalDependencies": { + "nice-napi": "^1.0.2" + } + }, "node_modules/pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -12012,6 +12467,14 @@ "readable-stream": "3" } }, + "node_modules/tinypool": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.3.0.tgz", + "integrity": "sha512-NX5KeqHOBZU6Bc0xj9Vr5Szbb1j8tUHIeD18s41aDJaPeC5QTdEhK0SpdpUrZlj2nv5cctNcSjaKNanXlfcVEQ==", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -12196,15 +12659,6 @@ } } }, - "node_modules/ts-node/node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/ts-parse-database-url": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/ts-parse-database-url/-/ts-parse-database-url-1.0.3.tgz", @@ -12997,7 +13451,7 @@ "license": "MIT", "dependencies": { "@pgtyped/query": "^1.1.0", - "@types/nunjucks": "^3.1.3", + "@pgtyped/wire": "^1.1.0", "camel-case": "^4.1.1", "chalk": "^4.0.0", "chokidar": "^3.3.1", @@ -13007,9 +13461,10 @@ "glob": "^8.0.0", "io-ts": "^2.2.20", "io-ts-reporters": "^2.0.1", - "jest-worker": "^26.3.0", "nunjucks": "3.2.3", "pascal-case": "^3.1.1", + "piscina": "^3.2.0", + "tinypool": "^0.3.0", "ts-parse-database-url": "^1.0.3", "yargs": "^17.0.1" }, @@ -13020,7 +13475,11 @@ "@types/debug": "4.1.7", "@types/fs-extra": "11.0.1", "@types/glob": "8.0.1", + "@types/nunjucks": "^3.1.3", "@types/yargs": "17.0.20" + }, + "engines": { + "node": ">=14.16" } }, "packages/example": { @@ -13030,13 +13489,80 @@ "dependencies": { "@pgtyped/cli": "^1.1.0", "@pgtyped/query": "^1.1.0", - "@types/pg": "8.6.6", "expect": "27.5.1", "pg": "8.7.3", "typescript": "4.9.4" }, "devDependencies": { - "ts-node": "10.8.2" + "@types/pg": "8.6.6", + "ts-node": "10.9.1" + }, + "engines": { + "node": ">=14.16" + } + }, + "packages/example/node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "packages/parser": { + "name": "@pgtyped/parser", + "version": "1.1.0", + "license": "MIT", + "dependencies": { + "antlr4ts": "0.5.0-alpha.4", + "chalk": "^4.1.0", + "debug": "^4.1.1" + }, + "devDependencies": { + "@types/chalk": "^2.2.0", + "@types/debug": "^4.1.4", + "antlr4ts-cli": "0.5.0-alpha.4" + }, + "engines": { + "node": ">=14.16" + }, + "peerDependencies": { + "typescript": "3.1 - 4" } }, "packages/query": { @@ -13044,15 +13570,35 @@ "version": "1.1.0", "license": "MIT", "dependencies": { + "@pgtyped/runtime": "^1.1.0", "@pgtyped/wire": "^1.1.0", + "chalk": "^4.1.0", + "debug": "^4.1.1" + }, + "devDependencies": { "@types/chalk": "^2.2.0", - "@types/debug": "^4.1.4", - "antlr4ts": "0.5.0-alpha.4", + "@types/debug": "^4.1.4" + }, + "engines": { + "node": ">=14.16" + } + }, + "packages/runtime": { + "name": "@pgtyped/runtime", + "version": "1.1.0", + "license": "MIT", + "dependencies": { + "@pgtyped/parser": "^1.1.0", "chalk": "^4.1.0", "debug": "^4.1.1" }, "devDependencies": { - "antlr4ts-cli": "0.5.0-alpha.4" + "@types/chalk": "^2.2.0", + "@types/debug": "^4.1.4", + "esbuild": "^0.17.4" + }, + "engines": { + "node": ">=14.16" }, "peerDependencies": { "typescript": "3.1 - 4" @@ -13082,6 +13628,11 @@ "@jridgewell/trace-mapping": "^0.3.9" } }, + "@assemblyscript/loader": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@assemblyscript/loader/-/loader-0.10.1.tgz", + "integrity": "sha512-H71nDOOL8Y7kWRLqf6Sums+01Q5msqBW2KhDUTemh1tvY04eSkSXrK0uj/4mmY0Xr16/3zyZmsrxN7CKuRbNRg==" + }, "@babel/code-frame": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", @@ -13521,6 +14072,160 @@ } } }, + "@esbuild/android-arm": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.4.tgz", + "integrity": "sha512-R9GCe2xl2XDSc2XbQB63mFiFXHIVkOP+ltIxICKXqUPrFX97z6Z7vONCLQM1pSOLGqfLrGi3B7nbhxmFY/fomg==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.4.tgz", + "integrity": "sha512-91VwDrl4EpxBCiG6h2LZZEkuNvVZYJkv2T9gyLG/mhGG1qrM7i5SwUcg/hlSPnL/4hDT0TFcF35/XMGSn0bemg==", + "dev": true, + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.4.tgz", + "integrity": "sha512-mGSqhEPL7029XL7QHNPxPs15JVa02hvZvysUcyMP9UXdGFwncl2WU0bqx+Ysgzd+WAbv8rfNa73QveOxAnAM2w==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.4.tgz", + "integrity": "sha512-tTyJRM9dHvlMPt1KrBFVB5OW1kXOsRNvAPtbzoKazd5RhD5/wKlXk1qR2MpaZRYwf4WDMadt0Pv0GwxB41CVow==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.4.tgz", + "integrity": "sha512-phQuC2Imrb3TjOJwLN8EO50nb2FHe8Ew0OwgZDH1SV6asIPGudnwTQtighDF2EAYlXChLoMJwqjAp4vAaACq6w==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.4.tgz", + "integrity": "sha512-oH6JUZkocgmjzzYaP5juERLpJQSwazdjZrTPgLRmAU2bzJ688x0vfMB/WTv4r58RiecdHvXOPC46VtsMy/mepg==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.4.tgz", + "integrity": "sha512-U4iWGn/9TrAfpAdfd56eO0pRxIgb0a8Wj9jClrhT8hvZnOnS4dfMPW7o4fn15D/KqoiVYHRm43jjBaTt3g/2KA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.4.tgz", + "integrity": "sha512-S2s9xWTGMTa/fG5EyMGDeL0wrWVgOSQcNddJWgu6rG1NCSXJHs76ZP9AsxjB3f2nZow9fWOyApklIgiTGZKhiw==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.4.tgz", + "integrity": "sha512-UkGfQvYlwOaeYJzZG4cLV0hCASzQZnKNktRXUo3/BMZvdau40AOz9GzmGA063n1piq6VrFFh43apRDQx8hMP2w==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.4.tgz", + "integrity": "sha512-3lqFi4VFo/Vwvn77FZXeLd0ctolIJH/uXkH3yNgEk89Eh6D3XXAC9/iTPEzeEpsNE5IqGIsFa5Z0iPeOh25IyA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.4.tgz", + "integrity": "sha512-HqpWZkVslDHIwdQ9D+gk7NuAulgQvRxF9no54ut/M55KEb3mi7sQS3GwpPJzSyzzP0UkjQVN7/tbk88/CaX4EQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.4.tgz", + "integrity": "sha512-d/nMCKKh/SVDbqR9ju+b78vOr0tNXtfBjcp5vfHONCCOAL9ad8gN9dC/u+UnH939pz7wO+0u/x9y1MaZcb/lKA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.4.tgz", + "integrity": "sha512-lOD9p2dmjZcNiTU+sGe9Nn6G3aYw3k0HBJies1PU0j5IGfp6tdKOQ6mzfACRFCqXjnBuTqK7eTYpwx09O5LLfg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.4.tgz", + "integrity": "sha512-mTGnwWwVshAjGsd8rP+K6583cPDgxOunsqqldEYij7T5/ysluMHKqUIT4TJHfrDFadUwrghAL6QjER4FeqQXoA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.4.tgz", + "integrity": "sha512-AQYuUGp50XM29/N/dehADxvc2bUqDcoqrVuijop1Wv72SyxT6dDB9wjUxuPZm2HwIM876UoNNBMVd+iX/UTKVQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.4.tgz", + "integrity": "sha512-+AsFBwKgQuhV2shfGgA9YloxLDVjXgUEWZum7glR5lLmV94IThu/u2JZGxTgjYby6kyXEx8lKOqP5rTEVBR0Rw==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.4.tgz", + "integrity": "sha512-zD1TKYX9553OiLS/qkXPMlWoELYkH/VkzRYNKEU+GwFiqkq0SuxsKnsCg5UCdxN3cqd+1KZ8SS3R+WG/Hxy2jQ==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.4.tgz", + "integrity": "sha512-PY1NjEsLRhPEFFg1AV0/4Or/gR+q2dOb9s5rXcPuCjyHRzbt8vnHJl3vYj+641TgWZzTFmSUnZbzs1zwTzjeqw==", + "dev": true, + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.4.tgz", + "integrity": "sha512-B3Z7s8QZQW9tKGleMRXvVmwwLPAUoDCHs4WZ2ElVMWiortLJFowU1NjAhXOKjDgC7o9ByeVcwyOlJ+F2r6ZgmQ==", + "dev": true, + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.4.tgz", + "integrity": "sha512-0HCu8R3mY/H5V7N6kdlsJkvrT591bO/oRZy8ztF1dhgNU5xD5tAh5bKByT1UjTGjp/VVBsl1PDQ3L18SfvtnBQ==", + "dev": true, + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.4.tgz", + "integrity": "sha512-VUjhVDQycse1gLbe06pC/uaA0M+piQXJpdpNdhg8sPmeIZZqu5xPoGWVCmcsOO2gaM2cywuTYTHkXRozo3/Nkg==", + "dev": true, + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.4.tgz", + "integrity": "sha512-0kLAjs+xN5OjhTt/aUA6t48SfENSCKgGPfExADYTOo/UCn0ivxos9/anUVeSfg+L+2O9xkFxvJXIJfG+Q4sYSg==", + "dev": true, + "optional": true + }, "@gar/promisify": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", @@ -15986,6 +16691,7 @@ "version": "file:packages/cli", "requires": { "@pgtyped/query": "^1.1.0", + "@pgtyped/wire": "^1.1.0", "@types/debug": "4.1.7", "@types/fs-extra": "11.0.1", "@types/glob": "8.0.1", @@ -16000,9 +16706,10 @@ "glob": "^8.0.0", "io-ts": "^2.2.20", "io-ts-reporters": "^2.0.1", - "jest-worker": "^26.3.0", "nunjucks": "3.2.3", "pascal-case": "^3.1.1", + "piscina": "^3.2.0", + "tinypool": "^0.3.0", "ts-parse-database-url": "^1.0.3", "yargs": "^17.0.1" } @@ -16015,22 +16722,66 @@ "@types/pg": "8.6.6", "expect": "27.5.1", "pg": "8.7.3", - "ts-node": "10.8.2", + "ts-node": "10.9.1", "typescript": "4.9.4" + }, + "dependencies": { + "ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "requires": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + } + } + } + }, + "@pgtyped/parser": { + "version": "file:packages/parser", + "requires": { + "@types/chalk": "^2.2.0", + "@types/debug": "^4.1.4", + "antlr4ts": "0.5.0-alpha.4", + "antlr4ts-cli": "0.5.0-alpha.4", + "chalk": "^4.1.0", + "debug": "^4.1.1" } }, "@pgtyped/query": { "version": "file:packages/query", "requires": { + "@pgtyped/runtime": "^1.1.0", "@pgtyped/wire": "^1.1.0", "@types/chalk": "^2.2.0", "@types/debug": "^4.1.4", - "antlr4ts": "0.5.0-alpha.4", - "antlr4ts-cli": "0.5.0-alpha.4", "chalk": "^4.1.0", "debug": "^4.1.1" } }, + "@pgtyped/runtime": { + "version": "file:packages/runtime", + "requires": { + "@pgtyped/parser": "^1.1.0", + "@types/chalk": "^2.2.0", + "@types/debug": "^4.1.4", + "chalk": "^4.1.0", + "debug": "^4.1.1", + "esbuild": "^0.17.4" + } + }, "@pgtyped/wire": { "version": "file:packages/wire", "requires": { @@ -16146,6 +16897,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/@types/chalk/-/chalk-2.2.0.tgz", "integrity": "sha512-1zzPV9FDe1I/WHhRkf9SNgqtRJWZqrBWgu7JGveuHmmyR9CnAPCie2N/x+iHrgnpYBIcCJWHBoMRv2TRWktsvw==", + "dev": true, "requires": { "chalk": "*" } @@ -16154,6 +16906,7 @@ "version": "4.1.7", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", "integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==", + "dev": true, "requires": { "@types/ms": "*" } @@ -16333,7 +17086,8 @@ "@types/ms": { "version": "0.7.31", "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", - "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==" + "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==", + "dev": true }, "@types/node": { "version": "18.11.18", @@ -16349,7 +17103,8 @@ "@types/nunjucks": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/@types/nunjucks/-/nunjucks-3.2.1.tgz", - "integrity": "sha512-hUh5HIC7peH+0MvlYU5KM2RydWxG1mBceivHsQGwlelU9zlczLICyJmjMwgjkI3m0+N50n46GVHkw35lIim6LQ==" + "integrity": "sha512-hUh5HIC7peH+0MvlYU5KM2RydWxG1mBceivHsQGwlelU9zlczLICyJmjMwgjkI3m0+N50n46GVHkw35lIim6LQ==", + "dev": true }, "@types/parse-json": { "version": "4.0.0", @@ -16361,6 +17116,7 @@ "version": "8.6.6", "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.6.6.tgz", "integrity": "sha512-O2xNmXebtwVekJDD+02udOncjVcMZQuTEQEMpKJ0ZRf5E7/9JJX3izhKUcUifBkyKpljyUM6BTgy2trmviKlpw==", + "dev": true, "requires": { "@types/node": "*", "pg-protocol": "*", @@ -16442,6 +17198,12 @@ "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", "dev": true }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true + }, "add-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz", @@ -16706,8 +17468,7 @@ "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, "before-after-hook": { "version": "2.2.3", @@ -17588,6 +18349,36 @@ "is-arrayish": "^0.2.1" } }, + "esbuild": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.4.tgz", + "integrity": "sha512-zBn9MeCwT7W5F1a3lXClD61ip6vQM+H8Msb0w8zMT4ZKBpDg+rFAraNyWCDelB/2L6M3g6AXHPnsyvjMFnxtFw==", + "dev": true, + "requires": { + "@esbuild/android-arm": "0.17.4", + "@esbuild/android-arm64": "0.17.4", + "@esbuild/android-x64": "0.17.4", + "@esbuild/darwin-arm64": "0.17.4", + "@esbuild/darwin-x64": "0.17.4", + "@esbuild/freebsd-arm64": "0.17.4", + "@esbuild/freebsd-x64": "0.17.4", + "@esbuild/linux-arm": "0.17.4", + "@esbuild/linux-arm64": "0.17.4", + "@esbuild/linux-ia32": "0.17.4", + "@esbuild/linux-loong64": "0.17.4", + "@esbuild/linux-mips64el": "0.17.4", + "@esbuild/linux-ppc64": "0.17.4", + "@esbuild/linux-riscv64": "0.17.4", + "@esbuild/linux-s390x": "0.17.4", + "@esbuild/linux-x64": "0.17.4", + "@esbuild/netbsd-x64": "0.17.4", + "@esbuild/openbsd-x64": "0.17.4", + "@esbuild/sunos-x64": "0.17.4", + "@esbuild/win32-arm64": "0.17.4", + "@esbuild/win32-ia32": "0.17.4", + "@esbuild/win32-x64": "0.17.4" + } + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -17637,6 +18428,11 @@ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true }, + "eventemitter-asyncresource": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eventemitter-asyncresource/-/eventemitter-asyncresource-1.0.0.tgz", + "integrity": "sha512-39F7TBIV0G7gTelxwbEqnwhp90eqCPON1k0NwNfwhgKn4Co4ybUbj2pECcXT0B3ztRKZ7Pw1JujUUgmQJHcVAQ==" + }, "eventemitter3": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", @@ -18115,6 +18911,21 @@ "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", "dev": true }, + "hdr-histogram-js": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hdr-histogram-js/-/hdr-histogram-js-2.0.3.tgz", + "integrity": "sha512-Hkn78wwzWHNCp2uarhzQ2SGFLU3JY8SBDDd3TAABK4fc30wm+MuPOrg5QVFVfkKOQd6Bfz3ukJEI+q9sXEkK1g==", + "requires": { + "@assemblyscript/loader": "^0.10.1", + "base64-js": "^1.2.0", + "pako": "^1.0.3" + } + }, + "hdr-histogram-percentiles-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hdr-histogram-percentiles-obj/-/hdr-histogram-percentiles-obj-3.0.0.tgz", + "integrity": "sha512-7kIufnBqdsBGcSZLPJwqHT3yhk1QTsSlFsVD3kx5ixH/AlgBs9yM1q6DPhXZ8f8gtdqgh7N7/5btRLpQsS2gHw==" + }, "hosted-git-info": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", @@ -19601,16 +20412,6 @@ "string-length": "^4.0.1" } }, - "jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - } - }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -20155,7 +20956,8 @@ "merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true }, "merge2": { "version": "1.4.1", @@ -20420,6 +21222,16 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, + "nice-napi": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nice-napi/-/nice-napi-1.0.2.tgz", + "integrity": "sha512-px/KnJAJZf5RuBGcfD+Sp2pAKq0ytz8j+1NehvgIGFkvtvFrDM3T8E4x/JJODXK9WZow8RRGrbA9QQ3hs+pDhA==", + "optional": true, + "requires": { + "node-addon-api": "^3.0.0", + "node-gyp-build": "^4.2.2" + } + }, "no-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", @@ -20433,7 +21245,7 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", - "dev": true + "devOptional": true }, "node-fetch": { "version": "2.6.8", @@ -20558,7 +21370,7 @@ "version": "4.6.0", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==", - "dev": true + "devOptional": true }, "node-int64": { "version": "0.4.0", @@ -21308,6 +22120,11 @@ } } }, + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -21490,6 +22307,17 @@ "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", "dev": true }, + "piscina": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/piscina/-/piscina-3.2.0.tgz", + "integrity": "sha512-yn/jMdHRw+q2ZJhFhyqsmANcbF6V2QwmD84c6xRau+QpQOmtrBCoRGdvTfeuFDYXB5W2m6MfLkjkvQa9lUSmIA==", + "requires": { + "eventemitter-asyncresource": "^1.0.0", + "hdr-histogram-js": "^2.0.1", + "hdr-histogram-percentiles-obj": "^3.0.0", + "nice-napi": "^1.0.2" + } + }, "pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -22463,6 +23291,11 @@ "readable-stream": "3" } }, + "tinypool": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.3.0.tgz", + "integrity": "sha512-NX5KeqHOBZU6Bc0xj9Vr5Szbb1j8tUHIeD18s41aDJaPeC5QTdEhK0SpdpUrZlj2nv5cctNcSjaKNanXlfcVEQ==" + }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -22571,14 +23404,6 @@ "make-error": "^1.1.1", "v8-compile-cache-lib": "^3.0.1", "yn": "3.1.1" - }, - "dependencies": { - "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true - } } }, "ts-parse-database-url": { diff --git a/package.json b/package.json index c1184bbf..318046ad 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "author": "Adel Salakh", "license": "MIT", "scripts": { + "clean": "rm -r packages/*/lib", "build": "lerna run build", "watch": "lerna run --parallel watch", "lint": "tslint --project tsconfig.json -t verbose", diff --git a/packages/cli/.npmignore b/packages/cli/.npmignore deleted file mode 100644 index b50b4c42..00000000 --- a/packages/cli/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -src/**/* -lib/**/*.test.* -tsconfig.json -*.tgz \ No newline at end of file diff --git a/packages/cli/jest.config.ts b/packages/cli/jest.config.ts new file mode 100644 index 00000000..bb75cce2 --- /dev/null +++ b/packages/cli/jest.config.ts @@ -0,0 +1,24 @@ +import type { Config } from 'jest'; + +const config: Config = { + snapshotFormat: { + escapeString: true, + printBasicPrototype: true, + }, + roots: ['src'], + moduleNameMapper: { + '^(\\.{1,2}/.*)\\.js$': '$1', + }, + transform: { + '^.+\\.tsx?$': [ + 'ts-jest', + { + useESM: true, + }, + ], + }, + preset: 'ts-jest/presets/default-esm', + testRegex: '\\.test\\.tsx?$', +}; + +export default config; diff --git a/packages/cli/package.json b/packages/cli/package.json index 0c710b96..204f526a 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,41 +1,41 @@ { "name": "@pgtyped/cli", "version": "1.1.0", + "type": "module", "main": "lib/index.js", + "exports": { + "./*": { + "import": "./lib/index.js", + "types": "./lib/index.d.ts" + } + }, "license": "MIT", "repository": { "type": "git", "url": "https://github.com/adelsz/pgtyped.git" }, + "files": [ + "lib" + ], + "engines": { + "node": ">=14.16" + }, "homepage": "https://github.com/adelsz/pgtyped", "publishConfig": { "access": "public" }, "scripts": { - "test": "jest", - "build": "tsc --declaration", + "test": "NODE_OPTIONS='--experimental-vm-modules' jest", + "build": "tsc", "check": "tsc --noEmit", - "watch": "tsc --declaration --watch --preserveWatchOutput" + "watch": "tsc --watch --preserveWatchOutput" }, "bin": { - "pgtyped": "./lib/index.js" - }, - "jest": { - "roots": [ - "src" - ], - "testRegex": "\\.test\\.tsx?$", - "transform": { - "^.+\\.tsx?$": "ts-jest" - }, - "snapshotFormat": { - "escapeString": true, - "printBasicPrototype": true - } + "pgtyped": "lib/index.js" }, "dependencies": { "@pgtyped/query": "^1.1.0", - "@types/nunjucks": "^3.1.3", + "@pgtyped/wire": "^1.1.0", "camel-case": "^4.1.1", "chalk": "^4.0.0", "chokidar": "^3.3.1", @@ -45,16 +45,21 @@ "glob": "^8.0.0", "io-ts": "^2.2.20", "io-ts-reporters": "^2.0.1", - "jest-worker": "^26.3.0", "nunjucks": "3.2.3", "pascal-case": "^3.1.1", + "piscina": "^3.2.0", + "tinypool": "^0.3.0", "ts-parse-database-url": "^1.0.3", "yargs": "^17.0.1" }, "devDependencies": { + "@types/nunjucks": "^3.1.3", "@types/debug": "4.1.7", "@types/fs-extra": "11.0.1", "@types/glob": "8.0.1", "@types/yargs": "17.0.20" + }, + "peerDependencies": { + "typescript": "3.1 - 4" } } diff --git a/packages/query/src/loader/typescript/__snapshots__/index.test.ts.snap b/packages/cli/src/__snapshots__/parseTypescript.test.ts.snap similarity index 100% rename from packages/query/src/loader/typescript/__snapshots__/index.test.ts.snap rename to packages/cli/src/__snapshots__/parseTypescript.test.ts.snap diff --git a/packages/cli/src/config.ts b/packages/cli/src/config.ts index 9faf7078..d1d4583b 100644 --- a/packages/cli/src/config.ts +++ b/packages/cli/src/config.ts @@ -1,12 +1,16 @@ /** @fileoverview Config file parser */ -import * as Either from 'fp-ts/lib/Either'; +import { createRequire } from 'module'; +import * as Either from 'fp-ts/lib/Either.js'; import { join, isAbsolute } from 'path'; import * as t from 'io-ts'; import { reporter } from 'io-ts-reporters'; import tls from 'tls'; -import parseDatabaseUri, { DatabaseConfig } from 'ts-parse-database-url'; -import { TypeMapping } from './types'; +import { default as dbUrlModule, DatabaseConfig } from 'ts-parse-database-url'; +import { TypeMapping } from './types.js'; + +// module import hack +const { default: parseDatabaseUri } = dbUrlModule as any; const transformCodecProps = { include: t.string, @@ -96,6 +100,8 @@ function convertParsedURLToDBConfig({ }; } +const require = createRequire(import.meta.url); + export function parseConfig( path: string, argConnectionUri?: string, diff --git a/packages/cli/src/generator.test.ts b/packages/cli/src/generator.test.ts index febe0d0a..1a290076 100644 --- a/packages/cli/src/generator.test.ts +++ b/packages/cli/src/generator.test.ts @@ -1,16 +1,16 @@ -import * as queryModule from '@pgtyped/query'; -import { parseSQLFile, parseTypeScriptFile } from '@pgtyped/query'; +import { ParameterTransform } from '@pgtyped/runtime'; + +import { parseSQLFile } from '@pgtyped/parser'; import { IQueryTypes } from '@pgtyped/query/lib/actions'; -import { ParsedConfig } from './config'; +import { ParsedConfig } from './config.js'; import { escapeComment, generateInterface, queryToTypeDeclarations, + ProcessingMode, } from './generator'; -import { ProcessingMode } from './index'; -import { DefaultTypeMapping, TypeAllocator } from './types'; - -const getTypesMocked = jest.spyOn(queryModule, 'getTypes').mockName('getTypes'); +import { parseCode as parseTypeScriptFile } from './parseTypescript.js'; +import { DefaultTypeMapping, TypeAllocator } from './types.js'; const partialConfig = { hungarianNotation: true } as ParsedConfig; @@ -56,20 +56,20 @@ describe('query-to-interface translation', () => { mapping: [ { name: 'userId', - type: queryModule.ParamTransform.Scalar, + type: ParameterTransform.Scalar, assignedIndex: 1, required: false, }, ], }, }; - getTypesMocked.mockResolvedValue(mockTypes); + const typeSource = async (_: any) => mockTypes; const types = new TypeAllocator(DefaultTypeMapping); // Test out imports types.use({ name: 'PreparedQuery', from: '@pgtyped/query' }); const result = await queryToTypeDeclarations( parsedQuery(mode, queryString), - null, + typeSource, types, partialConfig, ); @@ -118,25 +118,25 @@ export interface IGetNotificationsQuery { mapping: [ { name: 'notification', - type: queryModule.ParamTransform.Pick, + type: ParameterTransform.Pick, dict: { payload: { name: 'payload', assignedIndex: 1, required: false, - type: queryModule.ParamTransform.Scalar, + type: ParameterTransform.Scalar, }, user_id: { name: 'user_id', assignedIndex: 2, required: false, - type: queryModule.ParamTransform.Scalar, + type: ParameterTransform.Scalar, }, type: { name: 'type', assignedIndex: 3, required: false, - type: queryModule.ParamTransform.Scalar, + type: ParameterTransform.Scalar, }, }, }, @@ -144,10 +144,10 @@ export interface IGetNotificationsQuery { }, }; const types = new TypeAllocator(DefaultTypeMapping); - getTypesMocked.mockResolvedValue(mockTypes); + const typeSource = async (_: any) => mockTypes; const result = await queryToTypeDeclarations( parsedQuery(mode, queryString), - null, + typeSource, types, partialConfig, ); @@ -207,19 +207,19 @@ export interface IInsertNotificationsQuery { mapping: [ { name: 'userName', - type: queryModule.ParamTransform.Scalar, + type: ParameterTransform.Scalar, required: false, assignedIndex: 1, }, { name: 'userId', - type: queryModule.ParamTransform.Scalar, + type: ParameterTransform.Scalar, required: false, assignedIndex: 2, }, { name: 'userNote', - type: queryModule.ParamTransform.Scalar, + type: ParameterTransform.Scalar, required: false, assignedIndex: 3, }, @@ -227,10 +227,10 @@ export interface IInsertNotificationsQuery { }, }; const types = new TypeAllocator(DefaultTypeMapping); - getTypesMocked.mockResolvedValue(mockTypes); + const typeSource = async (_: any) => mockTypes; const result = await queryToTypeDeclarations( parsedQuery(mode, queryString), - null, + typeSource, types, partialConfig, ); @@ -288,20 +288,20 @@ export interface IDeleteUsersQuery { mapping: [ { name: 'userId', - type: queryModule.ParamTransform.Scalar, + type: ParameterTransform.Scalar, required: false, assignedIndex: 1, }, ], }, }; - getTypesMocked.mockResolvedValue(mockTypes); + const typeSource = async (_: any) => mockTypes; const types = new TypeAllocator(DefaultTypeMapping); // Test out imports types.use({ name: 'PreparedQuery', from: '@pgtyped/query' }); const result = await queryToTypeDeclarations( parsedQuery(mode, queryString), - null, + typeSource, types, { camelCaseColumnNames: true, hungarianNotation: true } as ParsedConfig, ); @@ -364,20 +364,20 @@ export interface IGetNotificationsQuery { mapping: [ { name: 'userIds', - type: queryModule.ParamTransform.Spread, + type: ParameterTransform.Spread, assignedIndex: 1, required: false, }, ], }, }; - getTypesMocked.mockResolvedValue(mockTypes); + const typeSource = async (_: any) => mockTypes; const types = new TypeAllocator(DefaultTypeMapping); // Test out imports types.use({ name: 'PreparedQuery', from: '@pgtyped/query' }); const result = await queryToTypeDeclarations( parsedQuery(mode, queryString), - null, + typeSource, types, { camelCaseColumnNames: true, hungarianNotation: true } as ParsedConfig, ); @@ -436,20 +436,20 @@ export interface IGetNotificationsQuery { mapping: [ { name: 'userId', - type: queryModule.ParamTransform.Scalar, + type: ParameterTransform.Scalar, required: false, assignedIndex: 1, }, ], }, }; - getTypesMocked.mockResolvedValue(mockTypes); + const typeSource = async (_: any) => mockTypes; const types = new TypeAllocator(DefaultTypeMapping); // Test out imports types.use({ name: 'PreparedQuery', from: '@pgtyped/query' }); const result = await queryToTypeDeclarations( parsedQuery(mode, queryString), - null, + typeSource, types, partialConfig, ); @@ -508,20 +508,20 @@ export interface IGetNotificationsQuery { mapping: [ { name: 'userId', - type: queryModule.ParamTransform.Scalar, + type: ParameterTransform.Scalar, required: false, assignedIndex: 1, }, ], }, }; - getTypesMocked.mockResolvedValue(mockTypes); + const typeSource = async (_: any) => mockTypes; const types = new TypeAllocator(DefaultTypeMapping); // Test out imports types.use({ name: 'PreparedQuery', from: '@pgtyped/query' }); const result = await queryToTypeDeclarations( parsedQuery(mode, queryString), - null, + typeSource, types, partialConfig, ); diff --git a/packages/cli/src/generator.ts b/packages/cli/src/generator.ts index 5f3814ba..8f0d0094 100644 --- a/packages/cli/src/generator.ts +++ b/packages/cli/src/generator.ts @@ -1,22 +1,30 @@ import { - getTypes, - ParamTransform, - parseSQLFile, - parseTypeScriptFile, - prettyPrintEvents, processSQLQueryIR, processTSQueryAST, + ParameterTransform, +} from '@pgtyped/runtime'; + +import { + parseSQLFile, + prettyPrintEvents, queryASTToIR, SQLQueryAST, SQLQueryIR, TSQueryAST, -} from '@pgtyped/query'; +} from '@pgtyped/parser'; + +import { getTypes, TypeSource } from '@pgtyped/query'; import { camelCase } from 'camel-case'; import { pascalCase } from 'pascal-case'; import path from 'path'; -import { ParsedConfig } from './config'; -import { ProcessingMode } from './index'; -import { TypeAllocator, TypeMapping } from './types'; +import { ParsedConfig } from './config.js'; +import { TypeAllocator, TypeMapping } from './types.js'; +import { parseCode as parseTypescriptFile } from './parseTypescript.js'; + +export enum ProcessingMode { + SQL = 'sql-file', + TS = 'query-file', +} export interface IField { fieldName: string; @@ -62,7 +70,7 @@ type ParsedQuery = export async function queryToTypeDeclarations( parsedQuery: ParsedQuery, - connection: any, + typeSource: TypeSource, types: TypeAllocator, config: ParsedConfig, ): Promise { @@ -76,7 +84,7 @@ export async function queryToTypeDeclarations( queryData = processSQLQueryIR(queryASTToIR(parsedQuery.ast)); } - const typeData = await getTypes(queryData, connection); + const typeData = await typeSource(queryData); const interfaceName = pascalCase(queryName); const interfacePrefix = config.hungarianNotation ? 'I' : ''; @@ -130,10 +138,10 @@ export async function queryToTypeDeclarations( const { params } = paramMetadata; for (const param of paramMetadata.mapping) { if ( - param.type === ParamTransform.Scalar || - param.type === ParamTransform.Spread + param.type === ParameterTransform.Scalar || + param.type === ParameterTransform.Spread ) { - const isArray = param.type === ParamTransform.Spread; + const isArray = param.type === ParameterTransform.Spread; const assignedIndex = param.assignedIndex instanceof Array ? param.assignedIndex[0] @@ -150,7 +158,7 @@ export async function queryToTypeDeclarations( fieldType: isArray ? `readonly (${tsTypeName})[]` : tsTypeName, }); } else { - const isArray = param.type === ParamTransform.PickSpread; + const isArray = param.type === ParameterTransform.PickSpread; let fieldType = Object.values(param.dict) .map((p) => { const paramType = types.use(params[p.assignedIndex - 1]); @@ -241,10 +249,11 @@ async function generateTypedecsFromFile( ): Promise { const results: ITypedQuery[] = []; const interfacePrefix = config.hungarianNotation ? 'I' : ''; + const typeSource: TypeSource = (query) => getTypes(query, connection); const { queries, events } = mode === 'ts' - ? parseTypeScriptFile(contents, fileName) + ? parseTypescriptFile(contents, fileName) : parseSQLFile(contents); if (events.length > 0) { prettyPrintEvents(contents, events); @@ -258,7 +267,7 @@ async function generateTypedecsFromFile( const sqlQueryAST = queryAST as SQLQueryAST; const result = await queryToTypeDeclarations( { ast: sqlQueryAST, mode: ProcessingMode.SQL }, - connection, + typeSource, types, config, ); @@ -285,7 +294,7 @@ async function generateTypedecsFromFile( ast: tsQueryAST, mode: ProcessingMode.TS, }, - connection, + typeSource, types, config, ); @@ -314,7 +323,7 @@ export async function generateDeclarationFile( const types = new TypeAllocator(TypeMapping(config.typesOverrides)); if (mode === 'sql') { - types.use({ name: 'PreparedQuery', from: '@pgtyped/query' }); + types.use({ name: 'PreparedQuery', from: '@pgtyped/runtime' }); } const typeDecs = await generateTypedecsFromFile( contents, diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index 1ef31296..2a035a27 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -1,54 +1,41 @@ #!/usr/bin/env node -import { AsyncQueue, startup } from '@pgtyped/query'; -import JestWorker from 'jest-worker'; +import { startup } from '@pgtyped/query'; +import { AsyncQueue } from '@pgtyped/wire'; import chokidar from 'chokidar'; import glob from 'glob'; import nun from 'nunjucks'; import yargs from 'yargs'; import { hideBin } from 'yargs/helpers'; -import { parseConfig, ParsedConfig, TransformConfig } from './config'; -import { debug } from './util'; -import { WorkerInterface, processFile } from './worker'; +import { debug } from './util.js'; +import { parseConfig, ParsedConfig, TransformConfig } from './config.js'; import path from 'path'; +import WorkerPool from 'piscina'; + // tslint:disable:no-console nun.configure({ autoescape: false }); -export enum ProcessingMode { - SQL = 'sql-file', - TS = 'query-file', -} - interface TransformJob { files: string[]; transform: TransformConfig; } class FileProcessor { - private readonly worker: WorkerInterface; + private readonly pool: WorkerPool; public readonly workQueue: Promise[] = []; constructor(private readonly config: ParsedConfig) { - this.worker = new JestWorker(require.resolve('./worker'), { - exposedMethods: ['processFile'], - setupArgs: [this.config], - computeWorkerKey: (method, fileName): string | null => { - switch (method) { - case processFile.name: - return fileName as string; - default: - return null; - } - }, - }) as WorkerInterface; - this.worker.getStdout().pipe(process.stdout); - this.worker.getStderr().pipe(process.stderr); + this.pool = new WorkerPool({ + filename: new URL('./worker.js', import.meta.url).href, + workerData: config, + }); + console.log(`Using a pool of ${this.pool.threads.length} threads.`); } public async shutdown() { - await this.worker.end(); + await this.pool.destroy(); } public push(job: TransformJob) { @@ -57,7 +44,10 @@ class FileProcessor { try { fileName = path.relative(process.cwd(), fileName); console.log(`Processing ${fileName}`); - const result = await this.worker.processFile(fileName, job.transform); + const result = await this.pool.run({ + fileName, + transform: job.transform, + }); if (result.skipped) { console.log( `Skipped ${fileName}: no changes or no queries detected`, @@ -76,7 +66,7 @@ class FileProcessor { console.log(`Error processing file: ${JSON.stringify(err)}`); } if (this.config.failOnError) { - await this.worker.end(); + await this.pool.destroy(); process.exit(1); } } @@ -86,10 +76,13 @@ class FileProcessor { } async function main( - config: ParsedConfig, + cfg: ParsedConfig | Promise, + // tslint:disable-next-line:no-shadowed-variable isWatchMode: boolean, + // tslint:disable-next-line:no-shadowed-variable fileOverride?: string, ) { + const config = await cfg; const connection = new AsyncQueue(); debug('starting codegenerator'); await startup(config.db, connection); @@ -143,64 +136,61 @@ async function main( } } -if (require.main === module) { - const args = yargs(hideBin(process.argv)) - .version() - .env() - .options({ - config: { - alias: 'c', - type: 'string', - description: 'Config file path', - demandOption: true, - }, - watch: { - alias: 'w', - description: 'Watch mode', - type: 'boolean', - }, - uri: { - type: 'string', - description: 'DB connection URI (overrides config)', - }, - file: { - alias: 'f', - type: 'string', - conflicts: 'watch', - description: - 'File path (process single file, incompatible with --watch)', - }, - }) - .epilogue( - 'For more information, find our manual at https://pgtyped.vercel.app/', - ) - .parseSync(); - - const { - watch: isWatchMode, - file: fileOverride, - config: configPath, - uri: connectionUri, - } = args; - - if (typeof configPath !== 'string') { - console.log('Config file required. See help -h for details.\nExiting.'); - process.exit(0); - } +const args = yargs(hideBin(process.argv)) + .version() + .env() + .options({ + config: { + alias: 'c', + type: 'string', + description: 'Config file path', + demandOption: true, + }, + watch: { + alias: 'w', + description: 'Watch mode', + type: 'boolean', + }, + uri: { + type: 'string', + description: 'DB connection URI (overrides config)', + }, + file: { + alias: 'f', + type: 'string', + conflicts: 'watch', + description: 'File path (process single file, incompatible with --watch)', + }, + }) + .epilogue( + 'For more information, find our manual at https://pgtyped.vercel.app/', + ) + .parseSync(); + +const { + watch: isWatchMode, + file: fileOverride, + config: configPath, + uri: connectionUri, +} = args; + +if (typeof configPath !== 'string') { + console.log('Config file required. See help -h for details.\nExiting.'); + process.exit(0); +} - if (isWatchMode && fileOverride) { - console.log('File override is not compatible with watch mode.\nExiting.'); - process.exit(0); - } +if (isWatchMode && fileOverride) { + console.log('File override is not compatible with watch mode.\nExiting.'); + process.exit(0); +} - try { - const config = parseConfig(configPath, connectionUri); - main(config, isWatchMode || false, fileOverride).catch((e) => - debug('error in main: %o', e.message), - ); - } catch (e) { - console.error('Failed to parse config file:'); - console.error((e as any).message); - process.exit(); - } +try { + const config = parseConfig(configPath, connectionUri); + main(config, isWatchMode || false, fileOverride).catch((e) => + debug('error in main: %o', e.message), + ); +} catch (e) { + console.error('Failed to parse config file:'); + console.error((e as any).message); + process.exit(); } diff --git a/packages/query/src/loader/typescript/index.test.ts b/packages/cli/src/parseTypescript.test.ts similarity index 91% rename from packages/query/src/loader/typescript/index.test.ts rename to packages/cli/src/parseTypescript.test.ts index bdddd390..b76297b7 100644 --- a/packages/query/src/loader/typescript/index.test.ts +++ b/packages/cli/src/parseTypescript.test.ts @@ -1,4 +1,4 @@ -import parseCode from './index'; +import { parseCode } from './parseTypescript.js'; test('parser finds string template in correct file', () => { const fileContent = ` diff --git a/packages/query/src/loader/typescript/index.ts b/packages/cli/src/parseTypescript.ts similarity index 78% rename from packages/query/src/loader/typescript/index.ts rename to packages/cli/src/parseTypescript.ts index 35cdbab9..b15efdee 100644 --- a/packages/query/src/loader/typescript/index.ts +++ b/packages/cli/src/parseTypescript.ts @@ -1,16 +1,12 @@ -import * as ts from 'typescript'; -import parseQuery, { Query } from './query'; -import { ParseEvent } from '../sql/logger'; - -export const parseTSQuery = parseQuery; - -export type TSQueryAST = Query; +import ts from 'typescript'; interface INode { queryName: string; queryText: string; } +import { parseTSQuery, TSQueryAST, ParseEvent } from '@pgtyped/parser'; + export type TSParseResult = { queries: TSQueryAST[]; events: ParseEvent[] }; export function parseFile(sourceFile: ts.SourceFile): TSParseResult { @@ -41,7 +37,7 @@ export function parseFile(sourceFile: ts.SourceFile): TSParseResult { const queries: TSQueryAST[] = []; const events: ParseEvent[] = []; for (const node of foundNodes) { - const { query, events: qEvents } = parseQuery( + const { query, events: qEvents } = parseTSQuery( node.queryText, node.queryName, ); @@ -52,7 +48,7 @@ export function parseFile(sourceFile: ts.SourceFile): TSParseResult { return { queries, events }; } -const parseCode = (fileContent: string, fileName = 'unnamed.ts') => { +export const parseCode = (fileContent: string, fileName = 'unnamed.ts') => { const sourceFile = ts.createSourceFile( fileName, fileContent, @@ -61,5 +57,3 @@ const parseCode = (fileContent: string, fileName = 'unnamed.ts') => { ); return parseFile(sourceFile); }; - -export default parseCode; diff --git a/packages/cli/src/types.test.ts b/packages/cli/src/types.test.ts index f2877448..765b00c1 100644 --- a/packages/cli/src/types.test.ts +++ b/packages/cli/src/types.test.ts @@ -1,4 +1,4 @@ -import { DefaultTypeMapping, TypeAllocator } from './types'; +import { DefaultTypeMapping, TypeAllocator } from './types.js'; describe('TypeAllocator', () => { test('Allows overrides', () => { diff --git a/packages/cli/src/types.ts b/packages/cli/src/types.ts index 0c5390be..e053a8de 100644 --- a/packages/cli/src/types.ts +++ b/packages/cli/src/types.ts @@ -6,7 +6,7 @@ import { isImport, MappableType, Type, -} from '@pgtyped/query/lib/type'; +} from '@pgtyped/query'; const String: Type = { name: 'string' }; const Number: Type = { name: 'number' }; diff --git a/packages/cli/src/worker.ts b/packages/cli/src/worker.ts index 5368201f..85f0c436 100644 --- a/packages/cli/src/worker.ts +++ b/packages/cli/src/worker.ts @@ -1,27 +1,31 @@ import nun from 'nunjucks'; import path from 'path'; import fs from 'fs-extra'; -import JestWorker from 'jest-worker'; -import { generateDeclarationFile } from './generator'; -import { AsyncQueue, startup } from '@pgtyped/query'; -import { ParsedConfig, TransformConfig } from './config'; +import { generateDeclarationFile } from './generator.js'; +import { startup } from '@pgtyped/query'; +import { ParsedConfig, TransformConfig } from './config.js'; +import { AsyncQueue } from '@pgtyped/wire'; +import worker from 'piscina'; +let connected = false; const connection = new AsyncQueue(); -let config: ParsedConfig; +const config: ParsedConfig = worker.workerData; -export async function setup(c: ParsedConfig) { - config = c; - await startup(config.db, connection); -} - -export async function processFile( - fileName: string, - transform: TransformConfig, -): Promise<{ +export default async function processFile({ + fileName, + transform, +}: { + fileName: string; + transform: TransformConfig; +}): Promise<{ skipped: boolean; typeDecsLength: number; relativePath: string; }> { + if (!connected) { + await startup(config.db, connection); + connected = true; + } const ppath = path.parse(fileName); let decsFileName; if (transform.emitTemplate) { @@ -61,7 +65,3 @@ export async function processFile( relativePath, }; } - -export interface WorkerInterface extends JestWorker { - processFile: typeof processFile; -} diff --git a/packages/example/.gitignore b/packages/example/.gitignore index 9ecc448c..36a7b2ce 100644 --- a/packages/example/.gitignore +++ b/packages/example/.gitignore @@ -1,3 +1,5 @@ node_modules coverage -lib \ No newline at end of file +lib +lib-cjs +!lib-cjs/package.json diff --git a/packages/example/README.md b/packages/example/README.md index c0fa22a1..db958c81 100644 --- a/packages/example/README.md +++ b/packages/example/README.md @@ -14,8 +14,9 @@ Try starting PgTyped and editing them to see live query type generation. `git clone git@github.com:adelsz/pgtyped.git pgtyped` 2. `cd pgtyped/packages/example` 3. `npm install` -4. `docker-compose run watch` -5. Try editing queries in the SQL and TS files and see how PgTyped handles it. +4. `npm run build` +5. `docker-compose run watch` +6. Try editing queries in the SQL and TS files and see how PgTyped handles it. The dockerized setup isn't required and is included for convenience. It creates a PostgreSQL DB, loading it with the schema and seed records defined in `sql/schema.sql`. diff --git a/packages/example/docker-compose.yml b/packages/example/docker-compose.yml index b0c3e7b5..c16954a4 100644 --- a/packages/example/docker-compose.yml +++ b/packages/example/docker-compose.yml @@ -39,5 +39,11 @@ services: <<: *build depends_on: - build - command: npx ts-node src/index.ts + command: node lib/index.js + + test-cjs: + <<: *build + depends_on: + - build + command: node lib-cjs/index.js diff --git a/packages/example/lib-cjs/package.json b/packages/example/lib-cjs/package.json new file mode 100644 index 00000000..5bbefffb --- /dev/null +++ b/packages/example/lib-cjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/packages/example/package.json b/packages/example/package.json index 7101d949..93acfa23 100644 --- a/packages/example/package.json +++ b/packages/example/package.json @@ -6,29 +6,30 @@ "private": true, "homepage": "", "license": "MIT", - "main": "lib/index.js", + "exports": "./lib/index.js", + "type": "module", "directories": { "lib": "lib" }, - "files": [ - "lib" - ], + "engines": { + "node": ">=14.16" + }, "scripts": { - "test": "docker-compose run build && docker-compose run test", + "test": "docker-compose run build && docker-compose run test && docker-compose run test-cjs", "typegen": "pgtyped -c config.json", - "build": "tsc --declaration", - "watch": "tsc --declaration --watch --preserveWatchOutput", + "build": "tsc && tsc --module commonjs --outDir lib-cjs", + "watch": "tsc --watch --preserveWatchOutput", "check": "tsc --noEmit" }, "dependencies": { "@pgtyped/cli": "^1.1.0", "@pgtyped/query": "^1.1.0", - "@types/pg": "8.6.6", "expect": "27.5.1", "pg": "8.7.3", "typescript": "4.9.4" }, "devDependencies": { - "ts-node": "10.8.2" + "@types/pg": "8.6.6", + "ts-node": "10.9.1" } } diff --git a/packages/example/src/books/books.queries.ts b/packages/example/src/books/books.queries.ts index 1109f3b8..6ff1c5fb 100644 --- a/packages/example/src/books/books.queries.ts +++ b/packages/example/src/books/books.queries.ts @@ -1,5 +1,5 @@ /** Types generated for queries found in "src/books/books.sql" */ -import { PreparedQuery } from '@pgtyped/query'; +import { PreparedQuery } from '@pgtyped/runtime'; export type category = 'novel' | 'science-fiction' | 'thriller'; diff --git a/packages/example/src/comments/comments.queries.ts b/packages/example/src/comments/comments.queries.ts index c02069e9..8d53544b 100644 --- a/packages/example/src/comments/comments.queries.ts +++ b/packages/example/src/comments/comments.queries.ts @@ -1,5 +1,5 @@ /** Types generated for queries found in "src/comments/comments.sql" */ -import { PreparedQuery } from '@pgtyped/query'; +import { PreparedQuery } from '@pgtyped/runtime'; /** 'GetAllComments' parameters type */ export interface IGetAllCommentsParams { diff --git a/packages/example/src/index.ts b/packages/example/src/index.ts index ecfe5899..f0c9c845 100644 --- a/packages/example/src/index.ts +++ b/packages/example/src/index.ts @@ -1,5 +1,6 @@ import expect from 'expect'; -import { Client } from 'pg'; +import pg from 'pg'; +const {Client} = pg; import { aggregateEmailsAndTest, findBookUnicode, @@ -9,16 +10,16 @@ import { updateBooks, updateBooksCustom, updateBooksRankNotNull, -} from './books/books.queries'; -import { getAllComments } from './comments/comments.queries'; +} from './books/books.queries.js'; +import { getAllComments } from './comments/comments.queries.js'; import { insertNotification, insertNotifications, -} from './notifications/notifications'; +} from './notifications/notifications.js'; import { sendNotifications, thresholdFrogs, -} from './notifications/notifications.queries'; +} from './notifications/notifications.queries.js'; // tslint:disable:no-console diff --git a/packages/example/src/notifications/notifications.queries.ts b/packages/example/src/notifications/notifications.queries.ts index e7e6d7eb..6f6a413a 100644 --- a/packages/example/src/notifications/notifications.queries.ts +++ b/packages/example/src/notifications/notifications.queries.ts @@ -1,5 +1,5 @@ /** Types generated for queries found in "src/notifications/notifications.sql" */ -import { PreparedQuery } from '@pgtyped/query'; +import { PreparedQuery } from '@pgtyped/runtime'; export type notification_type = 'deadline' | 'notification' | 'reminder'; diff --git a/packages/example/src/notifications/notifications.ts b/packages/example/src/notifications/notifications.ts index 25991f68..bd51f42d 100644 --- a/packages/example/src/notifications/notifications.ts +++ b/packages/example/src/notifications/notifications.ts @@ -1,9 +1,9 @@ -import { sql } from '@pgtyped/query'; +import { sql } from '@pgtyped/runtime'; import { IInsertNotificationQuery, IInsertNotificationsQuery, IGetAllNotificationsQuery, -} from './notifications.types'; +} from './notifications.types.js'; // Table order is (user_id, payload, type) export const insertNotifications = sql` diff --git a/packages/example/src/users/sample.ts b/packages/example/src/users/sample.ts index 451a70e6..bb46cd62 100644 --- a/packages/example/src/users/sample.ts +++ b/packages/example/src/users/sample.ts @@ -1,5 +1,5 @@ -import { sql } from '@pgtyped/query'; -import { IGetUsersWithCommentsQuery } from './sample.types'; +import { sql } from '@pgtyped/runtime'; +import { IGetUsersWithCommentsQuery } from './sample.types.js'; import { Client } from 'pg'; export async function getUsersWithComment( diff --git a/packages/example/tsconfig.json b/packages/example/tsconfig.json index 182e0817..9378db42 100644 --- a/packages/example/tsconfig.json +++ b/packages/example/tsconfig.json @@ -1,28 +1,18 @@ { "compilerOptions": { "target": "ES6", - "module": "commonjs", - /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ + "module": "ES2020", "sourceMap": true, - /* Generates corresponding '.map' file. */ "strict": true, - /* Enable all strict type-checking options. */ "noImplicitAny": true, - /* Raise error on expressions and declarations with an implied 'any' type. */ "strictNullChecks": true, - /* Enable strict null checks. */ "strictFunctionTypes": true, - /* Enable strict checking of function types. */ "strictBindCallApply": true, - /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ "strictPropertyInitialization": true, - /* Enable strict checking of property initialization in classes. */ "esModuleInterop": true, - /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ "outDir": "./lib/", - /* Redirect output structure to the directory. */ - "rootDir": "./src/" - /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + "rootDir": "./src/", + "moduleResolution": "node" }, "exclude": [ "lib" diff --git a/packages/parser/.gitignore b/packages/parser/.gitignore new file mode 100644 index 00000000..9ecc448c --- /dev/null +++ b/packages/parser/.gitignore @@ -0,0 +1,3 @@ +node_modules +coverage +lib \ No newline at end of file diff --git a/packages/parser/README.md b/packages/parser/README.md new file mode 100644 index 00000000..c67d1831 --- /dev/null +++ b/packages/parser/README.md @@ -0,0 +1,5 @@ +## @pgtyped/runtime + +This package provides SQL and TS query parsing for pgTyped. + +Refer to [README](https://github.com/adelsz/pgtyped) for details. diff --git a/packages/parser/jest.config.ts b/packages/parser/jest.config.ts new file mode 100644 index 00000000..bb75cce2 --- /dev/null +++ b/packages/parser/jest.config.ts @@ -0,0 +1,24 @@ +import type { Config } from 'jest'; + +const config: Config = { + snapshotFormat: { + escapeString: true, + printBasicPrototype: true, + }, + roots: ['src'], + moduleNameMapper: { + '^(\\.{1,2}/.*)\\.js$': '$1', + }, + transform: { + '^.+\\.tsx?$': [ + 'ts-jest', + { + useESM: true, + }, + ], + }, + preset: 'ts-jest/presets/default-esm', + testRegex: '\\.test\\.tsx?$', +}; + +export default config; diff --git a/packages/parser/package.json b/packages/parser/package.json new file mode 100644 index 00000000..351b83eb --- /dev/null +++ b/packages/parser/package.json @@ -0,0 +1,46 @@ +{ + "name": "@pgtyped/parser", + "version": "1.1.0", + "type": "module", + "exports": { + ".": { + "import": "./lib/index.js", + "types": "./lib/index.d.ts" + } + }, + "main": "lib/index.js", + "types": "lib/index.d.ts", + "files": [ + "lib" + ], + "engines": { + "node": ">=14.16" + }, + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/adelsz/pgtyped.git" + }, + "homepage": "https://github.com/adelsz/pgtyped", + "publishConfig": { + "access": "public" + }, + "scripts": { + "test": "NODE_OPTIONS='--experimental-vm-modules' jest", + "build": "tsc", + "check": "tsc --noEmit", + "watch": "tsc --declaration --watch --preserveWatchOutput", + "parsegen-sql": "antlr4ts -visitor -Xexact-output-dir -o src/loader/sql/parser src/loader/sql/grammar/*.g4", + "parsegen-ts": "antlr4ts -visitor -Xexact-output-dir -o src/loader/typescript/parser src/loader/typescript/grammar/*.g4" + }, + "dependencies": { + "antlr4ts": "0.5.0-alpha.4", + "chalk": "^4.1.0", + "debug": "^4.1.1" + }, + "devDependencies": { + "@types/chalk": "^2.2.0", + "@types/debug": "^4.1.4", + "antlr4ts-cli": "0.5.0-alpha.4" + } +} diff --git a/packages/parser/src/index.ts b/packages/parser/src/index.ts new file mode 100644 index 00000000..af27a43f --- /dev/null +++ b/packages/parser/src/index.ts @@ -0,0 +1,17 @@ +export { + default as parseTSQuery, + Query as TSQueryAST, +} from './loader/typescript/query.js'; + +export { Param, ParamKey, ParamType } from './loader/typescript/query.js'; + +export { + default as parseSQLFile, + SQLQueryAST, + ParseEvent, + SQLQueryIR, + prettyPrintEvents, + queryASTToIR, + assert, + TransformType, +} from './loader/sql/index.js'; diff --git a/packages/query/src/loader/sql/__snapshots__/index.test.ts.snap b/packages/parser/src/loader/sql/__snapshots__/index.test.ts.snap similarity index 100% rename from packages/query/src/loader/sql/__snapshots__/index.test.ts.snap rename to packages/parser/src/loader/sql/__snapshots__/index.test.ts.snap diff --git a/packages/query/src/loader/sql/grammar/SQLLexer.g4 b/packages/parser/src/loader/sql/grammar/SQLLexer.g4 similarity index 100% rename from packages/query/src/loader/sql/grammar/SQLLexer.g4 rename to packages/parser/src/loader/sql/grammar/SQLLexer.g4 diff --git a/packages/query/src/loader/sql/grammar/SQLParser.g4 b/packages/parser/src/loader/sql/grammar/SQLParser.g4 similarity index 100% rename from packages/query/src/loader/sql/grammar/SQLParser.g4 rename to packages/parser/src/loader/sql/grammar/SQLParser.g4 diff --git a/packages/query/src/loader/sql/index.test.ts b/packages/parser/src/loader/sql/index.test.ts similarity index 99% rename from packages/query/src/loader/sql/index.test.ts rename to packages/parser/src/loader/sql/index.test.ts index 6846a61e..20fcf4bc 100644 --- a/packages/query/src/loader/sql/index.test.ts +++ b/packages/parser/src/loader/sql/index.test.ts @@ -1,4 +1,4 @@ -import parse from './index'; +import parse from './index.js'; test('Named query', () => { const text = ` diff --git a/packages/query/src/loader/sql/index.ts b/packages/parser/src/loader/sql/index.ts similarity index 94% rename from packages/query/src/loader/sql/index.ts rename to packages/parser/src/loader/sql/index.ts index bcd81dfa..0d541744 100644 --- a/packages/query/src/loader/sql/index.ts +++ b/packages/parser/src/loader/sql/index.ts @@ -1,19 +1,23 @@ -import { SQLParserListener } from './parser/SQLParserListener'; +import { SQLParserListener } from './parser/SQLParserListener.js'; import { CharStreams, CommonTokenStream } from 'antlr4ts'; -import { ParseTreeWalker } from 'antlr4ts/tree/ParseTreeWalker'; -import { SQLLexer } from './parser/SQLLexer'; +import { ParseTreeWalker } from 'antlr4ts/tree/ParseTreeWalker.js'; +import { SQLLexer } from './parser/SQLLexer.js'; import { IgnoredCommentContext, KeyContext, ParamIdContext, ParamNameContext, QueryNameContext, - SpreadTransformContext, SQLParser, StatementBodyContext, -} from './parser/SQLParser'; -import { Logger, ParseEvent, ParseEventType, ParseWarningType } from './logger'; -import { Interval } from 'antlr4ts/misc'; +} from './parser/SQLParser.js'; +import { + Logger, + ParseEvent, + ParseEventType, + ParseWarningType, +} from './logger.js'; +import { Interval } from 'antlr4ts/misc/index.js'; export enum TransformType { Scalar = 'scalar', @@ -305,7 +309,7 @@ export function queryASTToIR(query: SQLQueryAST): SQLQueryIR { }; } -export { prettyPrintEvents } from './logger'; +export { prettyPrintEvents, ParseEvent } from './logger.js'; export type SQLQueryAST = QueryAST; export type SQLQueryIR = QueryIR; export default parseText; diff --git a/packages/query/src/loader/sql/logger.ts b/packages/parser/src/loader/sql/logger.ts similarity index 99% rename from packages/query/src/loader/sql/logger.ts rename to packages/parser/src/loader/sql/logger.ts index 9307d452..8e2c466b 100644 --- a/packages/query/src/loader/sql/logger.ts +++ b/packages/parser/src/loader/sql/logger.ts @@ -1,6 +1,6 @@ import chalk, { ChalkFunction } from 'chalk'; import { ANTLRErrorListener } from 'antlr4ts'; -import { RecognitionException } from 'antlr4ts/RecognitionException'; +import { RecognitionException } from 'antlr4ts/RecognitionException.js'; interface CodeInterval { a: number; diff --git a/packages/query/src/loader/sql/parser/SQLLexer.ts b/packages/parser/src/loader/sql/parser/SQLLexer.ts similarity index 94% rename from packages/query/src/loader/sql/parser/SQLLexer.ts rename to packages/parser/src/loader/sql/parser/SQLLexer.ts index 4a43362e..91564dd6 100644 --- a/packages/query/src/loader/sql/parser/SQLLexer.ts +++ b/packages/parser/src/loader/sql/parser/SQLLexer.ts @@ -1,18 +1,18 @@ // Generated from src/loader/sql/grammar/SQLLexer.g4 by ANTLR 4.9.0-SNAPSHOT -import { ATN } from "antlr4ts/atn/ATN"; -import { ATNDeserializer } from "antlr4ts/atn/ATNDeserializer"; -import { CharStream } from "antlr4ts/CharStream"; -import { Lexer } from "antlr4ts/Lexer"; -import { LexerATNSimulator } from "antlr4ts/atn/LexerATNSimulator"; -import { NotNull } from "antlr4ts/Decorators"; -import { Override } from "antlr4ts/Decorators"; -import { RuleContext } from "antlr4ts/RuleContext"; -import { Vocabulary } from "antlr4ts/Vocabulary"; -import { VocabularyImpl } from "antlr4ts/VocabularyImpl"; - -import * as Utils from "antlr4ts/misc/Utils"; +import { ATN } from "antlr4ts/atn/ATN.js"; +import { ATNDeserializer } from "antlr4ts/atn/ATNDeserializer.js"; +import { CharStream } from "antlr4ts/CharStream.js"; +import { Lexer } from "antlr4ts/Lexer.js"; +import { LexerATNSimulator } from "antlr4ts/atn/LexerATNSimulator.js"; +import { NotNull } from "antlr4ts/Decorators.js"; +import { Override } from "antlr4ts/Decorators.js"; +import { RuleContext } from "antlr4ts/RuleContext.js"; +import { Vocabulary } from "antlr4ts/Vocabulary.js"; +import { VocabularyImpl } from "antlr4ts/VocabularyImpl.js"; + +import * as Utils from "antlr4ts/misc/Utils.js"; export class SQLLexer extends Lexer { diff --git a/packages/query/src/loader/sql/parser/SQLParser.ts b/packages/parser/src/loader/sql/parser/SQLParser.ts similarity index 98% rename from packages/query/src/loader/sql/parser/SQLParser.ts rename to packages/parser/src/loader/sql/parser/SQLParser.ts index 7584c969..a4745398 100644 --- a/packages/query/src/loader/sql/parser/SQLParser.ts +++ b/packages/parser/src/loader/sql/parser/SQLParser.ts @@ -1,30 +1,30 @@ // Generated from src/loader/sql/grammar/SQLParser.g4 by ANTLR 4.9.0-SNAPSHOT -import { ATN } from "antlr4ts/atn/ATN"; -import { ATNDeserializer } from "antlr4ts/atn/ATNDeserializer"; -import { FailedPredicateException } from "antlr4ts/FailedPredicateException"; -import { NotNull } from "antlr4ts/Decorators"; -import { NoViableAltException } from "antlr4ts/NoViableAltException"; -import { Override } from "antlr4ts/Decorators"; -import { Parser } from "antlr4ts/Parser"; -import { ParserRuleContext } from "antlr4ts/ParserRuleContext"; -import { ParserATNSimulator } from "antlr4ts/atn/ParserATNSimulator"; -import { ParseTreeListener } from "antlr4ts/tree/ParseTreeListener"; -import { ParseTreeVisitor } from "antlr4ts/tree/ParseTreeVisitor"; -import { RecognitionException } from "antlr4ts/RecognitionException"; -import { RuleContext } from "antlr4ts/RuleContext"; +import { ATN } from "antlr4ts/atn/ATN.js"; +import { ATNDeserializer } from "antlr4ts/atn/ATNDeserializer.js"; +import { FailedPredicateException } from "antlr4ts/FailedPredicateException.js"; +import { NotNull } from "antlr4ts/Decorators.js"; +import { NoViableAltException } from "antlr4ts/NoViableAltException.js"; +import { Override } from "antlr4ts/Decorators.js"; +import { Parser } from "antlr4ts/Parser.js"; +import { ParserRuleContext } from "antlr4ts/ParserRuleContext.js"; +import { ParserATNSimulator } from "antlr4ts/atn/ParserATNSimulator.js"; +import { ParseTreeListener } from "antlr4ts/tree/ParseTreeListener.js"; +import { ParseTreeVisitor } from "antlr4ts/tree/ParseTreeVisitor.js"; +import { RecognitionException } from "antlr4ts/RecognitionException.js"; +import { RuleContext } from "antlr4ts/RuleContext.js"; //import { RuleVersion } from "antlr4ts/RuleVersion"; -import { TerminalNode } from "antlr4ts/tree/TerminalNode"; -import { Token } from "antlr4ts/Token"; -import { TokenStream } from "antlr4ts/TokenStream"; -import { Vocabulary } from "antlr4ts/Vocabulary"; -import { VocabularyImpl } from "antlr4ts/VocabularyImpl"; +import { TerminalNode } from "antlr4ts/tree/TerminalNode.js"; +import { Token } from "antlr4ts/Token.js"; +import { TokenStream } from "antlr4ts/TokenStream.js"; +import { Vocabulary } from "antlr4ts/Vocabulary.js"; +import { VocabularyImpl } from "antlr4ts/VocabularyImpl.js"; -import * as Utils from "antlr4ts/misc/Utils"; +import * as Utils from "antlr4ts/misc/Utils.js"; -import { SQLParserListener } from "./SQLParserListener"; -import { SQLParserVisitor } from "./SQLParserVisitor"; +import { SQLParserListener } from "./SQLParserListener.js"; +import { SQLParserVisitor } from "./SQLParserVisitor.js"; export class SQLParser extends Parser { diff --git a/packages/query/src/loader/sql/parser/SQLParserListener.ts b/packages/parser/src/loader/sql/parser/SQLParserListener.ts similarity index 85% rename from packages/query/src/loader/sql/parser/SQLParserListener.ts rename to packages/parser/src/loader/sql/parser/SQLParserListener.ts index 72b5fbbf..a998316c 100644 --- a/packages/query/src/loader/sql/parser/SQLParserListener.ts +++ b/packages/parser/src/loader/sql/parser/SQLParserListener.ts @@ -1,27 +1,27 @@ // Generated from src/loader/sql/grammar/SQLParser.g4 by ANTLR 4.9.0-SNAPSHOT -import { ParseTreeListener } from "antlr4ts/tree/ParseTreeListener"; - -import { InputContext } from "./SQLParser"; -import { QueryContext } from "./SQLParser"; -import { QueryDefContext } from "./SQLParser"; -import { IgnoredCommentContext } from "./SQLParser"; -import { StatementContext } from "./SQLParser"; -import { StatementBodyContext } from "./SQLParser"; -import { WordContext } from "./SQLParser"; -import { ParamContext } from "./SQLParser"; -import { ParamIdContext } from "./SQLParser"; -import { NameTagContext } from "./SQLParser"; -import { ParamTagContext } from "./SQLParser"; -import { ParamTransformContext } from "./SQLParser"; -import { TransformRuleContext } from "./SQLParser"; -import { SpreadTransformContext } from "./SQLParser"; -import { PickTransformContext } from "./SQLParser"; -import { SpreadPickTransformContext } from "./SQLParser"; -import { KeyContext } from "./SQLParser"; -import { QueryNameContext } from "./SQLParser"; -import { ParamNameContext } from "./SQLParser"; +import { ParseTreeListener } from "antlr4ts/tree/ParseTreeListener.js"; + +import { InputContext } from "./SQLParser.js"; +import { QueryContext } from "./SQLParser.js"; +import { QueryDefContext } from "./SQLParser.js"; +import { IgnoredCommentContext } from "./SQLParser.js"; +import { StatementContext } from "./SQLParser.js"; +import { StatementBodyContext } from "./SQLParser.js"; +import { WordContext } from "./SQLParser.js"; +import { ParamContext } from "./SQLParser.js"; +import { ParamIdContext } from "./SQLParser.js"; +import { NameTagContext } from "./SQLParser.js"; +import { ParamTagContext } from "./SQLParser.js"; +import { ParamTransformContext } from "./SQLParser.js"; +import { TransformRuleContext } from "./SQLParser.js"; +import { SpreadTransformContext } from "./SQLParser.js"; +import { PickTransformContext } from "./SQLParser.js"; +import { SpreadPickTransformContext } from "./SQLParser.js"; +import { KeyContext } from "./SQLParser.js"; +import { QueryNameContext } from "./SQLParser.js"; +import { ParamNameContext } from "./SQLParser.js"; /** diff --git a/packages/query/src/loader/sql/parser/SQLParserVisitor.ts b/packages/parser/src/loader/sql/parser/SQLParserVisitor.ts similarity index 80% rename from packages/query/src/loader/sql/parser/SQLParserVisitor.ts rename to packages/parser/src/loader/sql/parser/SQLParserVisitor.ts index 165e4d66..170d463d 100644 --- a/packages/query/src/loader/sql/parser/SQLParserVisitor.ts +++ b/packages/parser/src/loader/sql/parser/SQLParserVisitor.ts @@ -1,27 +1,27 @@ // Generated from src/loader/sql/grammar/SQLParser.g4 by ANTLR 4.9.0-SNAPSHOT -import { ParseTreeVisitor } from "antlr4ts/tree/ParseTreeVisitor"; - -import { InputContext } from "./SQLParser"; -import { QueryContext } from "./SQLParser"; -import { QueryDefContext } from "./SQLParser"; -import { IgnoredCommentContext } from "./SQLParser"; -import { StatementContext } from "./SQLParser"; -import { StatementBodyContext } from "./SQLParser"; -import { WordContext } from "./SQLParser"; -import { ParamContext } from "./SQLParser"; -import { ParamIdContext } from "./SQLParser"; -import { NameTagContext } from "./SQLParser"; -import { ParamTagContext } from "./SQLParser"; -import { ParamTransformContext } from "./SQLParser"; -import { TransformRuleContext } from "./SQLParser"; -import { SpreadTransformContext } from "./SQLParser"; -import { PickTransformContext } from "./SQLParser"; -import { SpreadPickTransformContext } from "./SQLParser"; -import { KeyContext } from "./SQLParser"; -import { QueryNameContext } from "./SQLParser"; -import { ParamNameContext } from "./SQLParser"; +import { ParseTreeVisitor } from "antlr4ts/tree/ParseTreeVisitor.js"; + +import { InputContext } from "./SQLParser.js"; +import { QueryContext } from "./SQLParser.js"; +import { QueryDefContext } from "./SQLParser.js"; +import { IgnoredCommentContext } from "./SQLParser.js"; +import { StatementContext } from "./SQLParser.js"; +import { StatementBodyContext } from "./SQLParser.js"; +import { WordContext } from "./SQLParser.js"; +import { ParamContext } from "./SQLParser.js"; +import { ParamIdContext } from "./SQLParser.js"; +import { NameTagContext } from "./SQLParser.js"; +import { ParamTagContext } from "./SQLParser.js"; +import { ParamTransformContext } from "./SQLParser.js"; +import { TransformRuleContext } from "./SQLParser.js"; +import { SpreadTransformContext } from "./SQLParser.js"; +import { PickTransformContext } from "./SQLParser.js"; +import { SpreadPickTransformContext } from "./SQLParser.js"; +import { KeyContext } from "./SQLParser.js"; +import { QueryNameContext } from "./SQLParser.js"; +import { ParamNameContext } from "./SQLParser.js"; /** diff --git a/packages/query/src/loader/typescript/__snapshots__/query.test.ts.snap b/packages/parser/src/loader/typescript/__snapshots__/query.test.ts.snap similarity index 100% rename from packages/query/src/loader/typescript/__snapshots__/query.test.ts.snap rename to packages/parser/src/loader/typescript/__snapshots__/query.test.ts.snap diff --git a/packages/query/src/loader/typescript/grammar/QueryLexer.g4 b/packages/parser/src/loader/typescript/grammar/QueryLexer.g4 similarity index 100% rename from packages/query/src/loader/typescript/grammar/QueryLexer.g4 rename to packages/parser/src/loader/typescript/grammar/QueryLexer.g4 diff --git a/packages/query/src/loader/typescript/grammar/QueryParser.g4 b/packages/parser/src/loader/typescript/grammar/QueryParser.g4 similarity index 100% rename from packages/query/src/loader/typescript/grammar/QueryParser.g4 rename to packages/parser/src/loader/typescript/grammar/QueryParser.g4 diff --git a/packages/query/src/loader/typescript/parser/QueryLexer.ts b/packages/parser/src/loader/typescript/parser/QueryLexer.ts similarity index 91% rename from packages/query/src/loader/typescript/parser/QueryLexer.ts rename to packages/parser/src/loader/typescript/parser/QueryLexer.ts index b7158800..05990a4d 100644 --- a/packages/query/src/loader/typescript/parser/QueryLexer.ts +++ b/packages/parser/src/loader/typescript/parser/QueryLexer.ts @@ -1,18 +1,18 @@ // Generated from src/loader/typescript/grammar/QueryLexer.g4 by ANTLR 4.9.0-SNAPSHOT -import { ATN } from "antlr4ts/atn/ATN"; -import { ATNDeserializer } from "antlr4ts/atn/ATNDeserializer"; -import { CharStream } from "antlr4ts/CharStream"; -import { Lexer } from "antlr4ts/Lexer"; -import { LexerATNSimulator } from "antlr4ts/atn/LexerATNSimulator"; -import { NotNull } from "antlr4ts/Decorators"; -import { Override } from "antlr4ts/Decorators"; -import { RuleContext } from "antlr4ts/RuleContext"; -import { Vocabulary } from "antlr4ts/Vocabulary"; -import { VocabularyImpl } from "antlr4ts/VocabularyImpl"; - -import * as Utils from "antlr4ts/misc/Utils"; +import { ATN } from "antlr4ts/atn/ATN.js"; +import { ATNDeserializer } from "antlr4ts/atn/ATNDeserializer.js"; +import { CharStream } from "antlr4ts/CharStream.js"; +import { Lexer } from "antlr4ts/Lexer.js"; +import { LexerATNSimulator } from "antlr4ts/atn/LexerATNSimulator.js"; +import { NotNull } from "antlr4ts/Decorators.js"; +import { Override } from "antlr4ts/Decorators.js"; +import { RuleContext } from "antlr4ts/RuleContext.js"; +import { Vocabulary } from "antlr4ts/Vocabulary.js"; +import { VocabularyImpl } from "antlr4ts/VocabularyImpl.js"; + +import * as Utils from "antlr4ts/misc/Utils.js"; export class QueryLexer extends Lexer { diff --git a/packages/query/src/loader/typescript/parser/QueryParser.ts b/packages/parser/src/loader/typescript/parser/QueryParser.ts similarity index 97% rename from packages/query/src/loader/typescript/parser/QueryParser.ts rename to packages/parser/src/loader/typescript/parser/QueryParser.ts index a7841586..9850b848 100644 --- a/packages/query/src/loader/typescript/parser/QueryParser.ts +++ b/packages/parser/src/loader/typescript/parser/QueryParser.ts @@ -1,30 +1,30 @@ // Generated from src/loader/typescript/grammar/QueryParser.g4 by ANTLR 4.9.0-SNAPSHOT -import { ATN } from "antlr4ts/atn/ATN"; -import { ATNDeserializer } from "antlr4ts/atn/ATNDeserializer"; -import { FailedPredicateException } from "antlr4ts/FailedPredicateException"; -import { NotNull } from "antlr4ts/Decorators"; -import { NoViableAltException } from "antlr4ts/NoViableAltException"; -import { Override } from "antlr4ts/Decorators"; -import { Parser } from "antlr4ts/Parser"; -import { ParserRuleContext } from "antlr4ts/ParserRuleContext"; -import { ParserATNSimulator } from "antlr4ts/atn/ParserATNSimulator"; -import { ParseTreeListener } from "antlr4ts/tree/ParseTreeListener"; -import { ParseTreeVisitor } from "antlr4ts/tree/ParseTreeVisitor"; -import { RecognitionException } from "antlr4ts/RecognitionException"; -import { RuleContext } from "antlr4ts/RuleContext"; +import { ATN } from "antlr4ts/atn/ATN.js"; +import { ATNDeserializer } from "antlr4ts/atn/ATNDeserializer.js"; +import { FailedPredicateException } from "antlr4ts/FailedPredicateException.js"; +import { NotNull } from "antlr4ts/Decorators.js"; +import { NoViableAltException } from "antlr4ts/NoViableAltException.js"; +import { Override } from "antlr4ts/Decorators.js"; +import { Parser } from "antlr4ts/Parser.js"; +import { ParserRuleContext } from "antlr4ts/ParserRuleContext.js"; +import { ParserATNSimulator } from "antlr4ts/atn/ParserATNSimulator.js"; +import { ParseTreeListener } from "antlr4ts/tree/ParseTreeListener.js"; +import { ParseTreeVisitor } from "antlr4ts/tree/ParseTreeVisitor.js"; +import { RecognitionException } from "antlr4ts/RecognitionException.js"; +import { RuleContext } from "antlr4ts/RuleContext.js"; //import { RuleVersion } from "antlr4ts/RuleVersion"; -import { TerminalNode } from "antlr4ts/tree/TerminalNode"; -import { Token } from "antlr4ts/Token"; -import { TokenStream } from "antlr4ts/TokenStream"; -import { Vocabulary } from "antlr4ts/Vocabulary"; -import { VocabularyImpl } from "antlr4ts/VocabularyImpl"; +import { TerminalNode } from "antlr4ts/tree/TerminalNode.js"; +import { Token } from "antlr4ts/Token.js"; +import { TokenStream } from "antlr4ts/TokenStream.js"; +import { Vocabulary } from "antlr4ts/Vocabulary.js"; +import { VocabularyImpl } from "antlr4ts/VocabularyImpl.js"; -import * as Utils from "antlr4ts/misc/Utils"; +import * as Utils from "antlr4ts/misc/Utils.js"; -import { QueryParserListener } from "./QueryParserListener"; -import { QueryParserVisitor } from "./QueryParserVisitor"; +import { QueryParserListener } from "./QueryParserListener.js"; +import { QueryParserVisitor } from "./QueryParserVisitor.js"; export class QueryParser extends Parser { diff --git a/packages/query/src/loader/typescript/parser/QueryParserListener.ts b/packages/parser/src/loader/typescript/parser/QueryParserListener.ts similarity index 86% rename from packages/query/src/loader/typescript/parser/QueryParserListener.ts rename to packages/parser/src/loader/typescript/parser/QueryParserListener.ts index f16fd7f4..a2485c1b 100644 --- a/packages/query/src/loader/typescript/parser/QueryParserListener.ts +++ b/packages/parser/src/loader/typescript/parser/QueryParserListener.ts @@ -1,19 +1,19 @@ // Generated from src/loader/typescript/grammar/QueryParser.g4 by ANTLR 4.9.0-SNAPSHOT -import { ParseTreeListener } from "antlr4ts/tree/ParseTreeListener"; - -import { InputContext } from "./QueryParser"; -import { QueryContext } from "./QueryParser"; -import { ParamContext } from "./QueryParser"; -import { IgnoredContext } from "./QueryParser"; -import { ScalarParamContext } from "./QueryParser"; -import { PickParamContext } from "./QueryParser"; -import { ArrayPickParamContext } from "./QueryParser"; -import { ArrayParamContext } from "./QueryParser"; -import { ScalarParamNameContext } from "./QueryParser"; -import { ParamNameContext } from "./QueryParser"; -import { PickKeyContext } from "./QueryParser"; +import { ParseTreeListener } from "antlr4ts/tree/ParseTreeListener.js"; + +import { InputContext } from "./QueryParser.js"; +import { QueryContext } from "./QueryParser.js"; +import { ParamContext } from "./QueryParser.js"; +import { IgnoredContext } from "./QueryParser.js"; +import { ScalarParamContext } from "./QueryParser.js"; +import { PickParamContext } from "./QueryParser.js"; +import { ArrayPickParamContext } from "./QueryParser.js"; +import { ArrayParamContext } from "./QueryParser.js"; +import { ScalarParamNameContext } from "./QueryParser.js"; +import { ParamNameContext } from "./QueryParser.js"; +import { PickKeyContext } from "./QueryParser.js"; /** diff --git a/packages/query/src/loader/typescript/parser/QueryParserVisitor.ts b/packages/parser/src/loader/typescript/parser/QueryParserVisitor.ts similarity index 80% rename from packages/query/src/loader/typescript/parser/QueryParserVisitor.ts rename to packages/parser/src/loader/typescript/parser/QueryParserVisitor.ts index 235aaf3b..d62bd404 100644 --- a/packages/query/src/loader/typescript/parser/QueryParserVisitor.ts +++ b/packages/parser/src/loader/typescript/parser/QueryParserVisitor.ts @@ -1,19 +1,19 @@ // Generated from src/loader/typescript/grammar/QueryParser.g4 by ANTLR 4.9.0-SNAPSHOT -import { ParseTreeVisitor } from "antlr4ts/tree/ParseTreeVisitor"; - -import { InputContext } from "./QueryParser"; -import { QueryContext } from "./QueryParser"; -import { ParamContext } from "./QueryParser"; -import { IgnoredContext } from "./QueryParser"; -import { ScalarParamContext } from "./QueryParser"; -import { PickParamContext } from "./QueryParser"; -import { ArrayPickParamContext } from "./QueryParser"; -import { ArrayParamContext } from "./QueryParser"; -import { ScalarParamNameContext } from "./QueryParser"; -import { ParamNameContext } from "./QueryParser"; -import { PickKeyContext } from "./QueryParser"; +import { ParseTreeVisitor } from "antlr4ts/tree/ParseTreeVisitor.js"; + +import { InputContext } from "./QueryParser.js"; +import { QueryContext } from "./QueryParser.js"; +import { ParamContext } from "./QueryParser.js"; +import { IgnoredContext } from "./QueryParser.js"; +import { ScalarParamContext } from "./QueryParser.js"; +import { PickParamContext } from "./QueryParser.js"; +import { ArrayPickParamContext } from "./QueryParser.js"; +import { ArrayParamContext } from "./QueryParser.js"; +import { ScalarParamNameContext } from "./QueryParser.js"; +import { ParamNameContext } from "./QueryParser.js"; +import { PickKeyContext } from "./QueryParser.js"; /** diff --git a/packages/query/src/loader/typescript/query.test.ts b/packages/parser/src/loader/typescript/query.test.ts similarity index 100% rename from packages/query/src/loader/typescript/query.test.ts rename to packages/parser/src/loader/typescript/query.test.ts diff --git a/packages/query/src/loader/typescript/query.ts b/packages/parser/src/loader/typescript/query.ts similarity index 93% rename from packages/query/src/loader/typescript/query.ts rename to packages/parser/src/loader/typescript/query.ts index 0e3c5cb9..e3f4f265 100644 --- a/packages/query/src/loader/typescript/query.ts +++ b/packages/parser/src/loader/typescript/query.ts @@ -1,18 +1,17 @@ -import { QueryParserListener } from './parser/QueryParserListener'; +import { QueryParserListener } from './parser/QueryParserListener.js'; import { CharStreams, CommonTokenStream } from 'antlr4ts'; -import { ParseTreeWalker } from 'antlr4ts/tree/ParseTreeWalker'; -import { QueryLexer } from './parser/QueryLexer'; +import { ParseTreeWalker } from 'antlr4ts/tree/ParseTreeWalker.js'; +import { QueryLexer } from './parser/QueryLexer.js'; import { - ArrayParamContext, ParamContext, ParamNameContext, PickKeyContext, QueryContext, QueryParser, ScalarParamNameContext, -} from './parser/QueryParser'; -import { Logger, ParseEvent } from '../sql/logger'; -import { Interval } from 'antlr4ts/misc'; +} from './parser/QueryParser.js'; +import { Logger, ParseEvent } from '../sql/logger.js'; +import { Interval } from 'antlr4ts/misc/index.js'; export enum ParamType { Scalar = 'scalar', diff --git a/packages/parser/tsconfig.json b/packages/parser/tsconfig.json new file mode 100644 index 00000000..869082e1 --- /dev/null +++ b/packages/parser/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./lib/", + "rootDir": "./src/", + "declaration": true, + }, + "exclude": ["lib"], + "include": ["./src"] +} diff --git a/packages/query/.npmignore b/packages/query/.npmignore deleted file mode 100644 index b50b4c42..00000000 --- a/packages/query/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -src/**/* -lib/**/*.test.* -tsconfig.json -*.tgz \ No newline at end of file diff --git a/packages/query/README.md b/packages/query/README.md index 13605c6a..00fa5d06 100644 --- a/packages/query/README.md +++ b/packages/query/README.md @@ -1,28 +1,6 @@ ## @pgtyped/query -This package provides the `sql` tagged template. -The `sql` tagged template requires a generic parameter: ``. -For each query PgTyped generates an interface that can be used in this parameter to type your query. - -To run a query defined with the `sql` tagged template, call the `sql.run` method. -The `sql.run` method automatically enforces correct input `TParams` and output `TResult` types. - -```js -public run: ( - params: TParams, - dbConnection: IDatabaseConnection, -) => Promise; -``` - -Here `dbConnection` is any object that satisifies the `IDatabaseConnection` interface. It is used to actually send the query to the DB for execution. - -``` -interface IDatabaseConnection { - query: (query: string, bindings: any[]) => Promise<{ rows: any[] }>; -} -``` - -This is usually the `client` object created with [node-postgres](https://github.com/brianc/node-postgres), but can be any other connection of your choice. +This package provides protocol utilities for PgTyped queries. This package is part of the pgtyped project. Refer to [README](https://github.com/adelsz/pgtyped) for details. diff --git a/packages/query/jest.config.ts b/packages/query/jest.config.ts new file mode 100644 index 00000000..bb75cce2 --- /dev/null +++ b/packages/query/jest.config.ts @@ -0,0 +1,24 @@ +import type { Config } from 'jest'; + +const config: Config = { + snapshotFormat: { + escapeString: true, + printBasicPrototype: true, + }, + roots: ['src'], + moduleNameMapper: { + '^(\\.{1,2}/.*)\\.js$': '$1', + }, + transform: { + '^.+\\.tsx?$': [ + 'ts-jest', + { + useESM: true, + }, + ], + }, + preset: 'ts-jest/presets/default-esm', + testRegex: '\\.test\\.tsx?$', +}; + +export default config; diff --git a/packages/query/package.json b/packages/query/package.json index 959aeeba..fd1099fd 100644 --- a/packages/query/package.json +++ b/packages/query/package.json @@ -1,8 +1,21 @@ { "name": "@pgtyped/query", "version": "1.1.0", + "type": "module", + "exports": { + ".": { + "import": "./lib/index.js", + "types": "./lib/index.d.ts" + } + }, "main": "lib/index.js", "types": "lib/index.d.ts", + "files": [ + "lib" + ], + "engines": { + "node": ">=14.16" + }, "license": "MIT", "repository": { "type": "git", @@ -13,38 +26,19 @@ "access": "public" }, "scripts": { - "test": "jest", - "build": "tsc --declaration", + "test": "NODE_OPTIONS='--experimental-vm-modules' jest", + "build": "tsc", "check": "tsc --noEmit", - "watch": "tsc --declaration --watch --preserveWatchOutput", - "parsegen-sql": "antlr4ts -visitor -Xexact-output-dir -o src/loader/sql/parser src/loader/sql/grammar/*.g4", - "parsegen-ts": "antlr4ts -visitor -Xexact-output-dir -o src/loader/typescript/parser src/loader/typescript/grammar/*.g4" - }, - "jest": { - "roots": [ - "src" - ], - "testRegex": "\\.test\\.tsx?$", - "transform": { - "^.+\\.tsx?$": "ts-jest" - }, - "snapshotFormat": { - "escapeString": true, - "printBasicPrototype": true - } + "watch": "tsc --watch --preserveWatchOutput" }, "dependencies": { + "@pgtyped/runtime": "^1.1.0", "@pgtyped/wire": "^1.1.0", - "@types/chalk": "^2.2.0", - "@types/debug": "^4.1.4", - "antlr4ts": "0.5.0-alpha.4", "chalk": "^4.1.0", "debug": "^4.1.1" }, "devDependencies": { - "antlr4ts-cli": "0.5.0-alpha.4" - }, - "peerDependencies": { - "typescript": "3.1 - 4" + "@types/chalk": "^2.2.0", + "@types/debug": "^4.1.4" } } diff --git a/packages/query/src/actions.test.ts b/packages/query/src/actions.test.ts index 3307417a..c2017009 100644 --- a/packages/query/src/actions.test.ts +++ b/packages/query/src/actions.test.ts @@ -1,4 +1,4 @@ -import { generateHash, reduceTypeRows } from './actions'; +import { generateHash, reduceTypeRows } from './actions.js'; test('test postgres md5 hash generation', () => { const salt = [0x81, 0xcc, 0x95, 0x8b]; diff --git a/packages/query/src/actions.ts b/packages/query/src/actions.ts index 54edb02f..e46dc68d 100644 --- a/packages/query/src/actions.ts +++ b/packages/query/src/actions.ts @@ -2,13 +2,13 @@ import { AsyncQueue, messages, PreparedObjectType } from '@pgtyped/wire'; import crypto from 'crypto'; import debugBase from 'debug'; import * as tls from 'tls'; -import { IInterpolatedQuery, QueryParam } from './preprocessor'; +import type { InterpolatedQuery, QueryParameter } from '@pgtyped/runtime'; import { checkServerFinalMessage, createClientSASLContinueResponse, createInitialSASLResponse, -} from './sasl-helpers'; -import { DatabaseTypeKind, isEnum, MappableType } from './type'; +} from './sasl-helpers.js'; +import { DatabaseTypeKind, isEnum, MappableType } from './type.js'; const debugQuery = debugBase('client:query'); @@ -146,7 +146,7 @@ export async function runQuery(query: string, queue: AsyncQueue) { export interface IQueryTypes { paramMetadata: { - mapping: QueryParam[]; + mapping: QueryParameter[]; params: MappableType[]; }; returnTypes: Array<{ @@ -383,7 +383,7 @@ async function getComments( } export async function getTypes( - queryData: IInterpolatedQuery, + queryData: InterpolatedQuery, queue: AsyncQueue, ): Promise { const typeData = await getTypeData(queryData.query, queue); diff --git a/packages/query/src/index.ts b/packages/query/src/index.ts index 7e955b4b..31be39d3 100644 --- a/packages/query/src/index.ts +++ b/packages/query/src/index.ts @@ -1,27 +1,17 @@ -export { getTypes, startup, IParseError } from './actions'; +import { InterpolatedQuery } from '@pgtyped/runtime'; +import { IParseError, IQueryTypes } from './actions.js'; -export { - ParamTransform, - IQueryParameters, - IInterpolatedQuery, -} from './preprocessor'; - -export { processTSQueryAST } from './preprocessor-ts'; -export { processSQLQueryIR } from './preprocessor-sql'; - -export { AsyncQueue } from '@pgtyped/wire'; - -export { - default as parseTypeScriptFile, - TSQueryAST, -} from './loader/typescript'; +export { getTypes, startup, IParseError, IQueryTypes } from './actions.js'; export { - default as parseSQLFile, - SQLQueryAST, - SQLQueryIR, - prettyPrintEvents, - queryASTToIR, -} from './loader/sql'; + isAlias, + isEnum, + isEnumArray, + isImport, + MappableType, + Type, +} from './type.js'; -export { default as sql, TaggedQuery, PreparedQuery } from './tag'; +export type TypeSource = ( + queryData: InterpolatedQuery, +) => Promise; diff --git a/packages/query/src/sasl-helpers.test.ts b/packages/query/src/sasl-helpers.test.ts index c317bb94..8a77d3c5 100644 --- a/packages/query/src/sasl-helpers.test.ts +++ b/packages/query/src/sasl-helpers.test.ts @@ -2,7 +2,7 @@ import { checkServerFinalMessage, createClientSASLContinueResponse, createInitialSASLResponse, -} from './sasl-helpers'; +} from './sasl-helpers.js'; test('createInitialSASLResponse', () => { const { clientNonce, response } = createInitialSASLResponse(); diff --git a/packages/query/src/sasl-helpers.ts b/packages/query/src/sasl-helpers.ts index 232291a9..4940ed7f 100644 --- a/packages/query/src/sasl-helpers.ts +++ b/packages/query/src/sasl-helpers.ts @@ -1,7 +1,7 @@ /** * SASL-helpers for authentication using SASL */ -import { cString } from '@pgtyped/wire/lib/helpers'; +import { cString } from '@pgtyped/wire'; import crypto from 'crypto'; export function createInitialSASLResponse(): { diff --git a/packages/query/tsconfig.json b/packages/query/tsconfig.json index d48ff986..95f2e757 100644 --- a/packages/query/tsconfig.json +++ b/packages/query/tsconfig.json @@ -1,8 +1,8 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "./lib/" /* Redirect output structure to the directory. */, - "rootDir": "./src/" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + "outDir": "./lib/", + "rootDir": "./src/", }, "exclude": ["lib"], "include": ["./src"] diff --git a/packages/runtime/.gitignore b/packages/runtime/.gitignore new file mode 100644 index 00000000..9ecc448c --- /dev/null +++ b/packages/runtime/.gitignore @@ -0,0 +1,3 @@ +node_modules +coverage +lib \ No newline at end of file diff --git a/packages/runtime/README.md b/packages/runtime/README.md new file mode 100644 index 00000000..d14e5808 --- /dev/null +++ b/packages/runtime/README.md @@ -0,0 +1,28 @@ +## @pgtyped/runtime + +This package provides the `sql` tagged template. +The `sql` tagged template requires a generic parameter: ``. +For each query PgTyped generates an interface that can be used in this parameter to type your query. + +To run a query defined with the `sql` tagged template, call the `sql.run` method. +The `sql.run` method automatically enforces correct input `TParams` and output `TResult` types. + +```js +public run: ( + params: TParams, + dbConnection: IDatabaseConnection, +) => Promise; +``` + +Here `dbConnection` is any object that satisifies the `IDatabaseConnection` interface. It is used to actually send the query to the DB for execution. + +``` +interface IDatabaseConnection { + query: (query: string, bindings: any[]) => Promise<{ rows: any[] }>; +} +``` + +This is usually the `client` object created with [node-postgres](https://github.com/brianc/node-postgres), but can be any other connection of your choice. + +This package is part of the pgtyped project. +Refer to [README](https://github.com/adelsz/pgtyped) for details. diff --git a/packages/runtime/jest.config.ts b/packages/runtime/jest.config.ts new file mode 100644 index 00000000..bb75cce2 --- /dev/null +++ b/packages/runtime/jest.config.ts @@ -0,0 +1,24 @@ +import type { Config } from 'jest'; + +const config: Config = { + snapshotFormat: { + escapeString: true, + printBasicPrototype: true, + }, + roots: ['src'], + moduleNameMapper: { + '^(\\.{1,2}/.*)\\.js$': '$1', + }, + transform: { + '^.+\\.tsx?$': [ + 'ts-jest', + { + useESM: true, + }, + ], + }, + preset: 'ts-jest/presets/default-esm', + testRegex: '\\.test\\.tsx?$', +}; + +export default config; diff --git a/packages/runtime/package.json b/packages/runtime/package.json new file mode 100644 index 00000000..ac0c27c2 --- /dev/null +++ b/packages/runtime/package.json @@ -0,0 +1,46 @@ +{ + "name": "@pgtyped/runtime", + "version": "1.1.0", + "type": "module", + "exports": { + ".": { + "types": "./lib/index.d.ts", + "import": "./lib/index.js", + "require": "./lib/index.cjs", + "default": "./lib/index.js" + } + }, + "types": "lib/index.d.ts", + "files": [ + "lib" + ], + "engines": { + "node": ">=14.16" + }, + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/adelsz/pgtyped.git" + }, + "homepage": "https://github.com/adelsz/pgtyped", + "publishConfig": { + "access": "public" + }, + "scripts": { + "test": "NODE_OPTIONS='--experimental-vm-modules' jest", + "build:cjs": "esbuild --bundle --sourcemap --platform=node --target=node14 src/index.ts --minify --external:chalk --external:antlr4ts --outfile=lib/index.cjs", + "build": "tsc && npm run build:cjs", + "check": "tsc --noEmit", + "watch": "tsc --watch --preserveWatchOutput" + }, + "dependencies": { + "@pgtyped/parser": "^1.1.0", + "chalk": "^4.1.0", + "debug": "^4.1.1" + }, + "devDependencies": { + "@types/chalk": "^2.2.0", + "@types/debug": "^4.1.4", + "esbuild": "^0.17.4" + } +} diff --git a/packages/runtime/src/index.ts b/packages/runtime/src/index.ts new file mode 100644 index 00000000..b8633da2 --- /dev/null +++ b/packages/runtime/src/index.ts @@ -0,0 +1,11 @@ +export { + ParameterTransform, + QueryParameters, + InterpolatedQuery, + QueryParameter, +} from './preprocessor.js'; + +export { processTSQueryAST } from './preprocessor-ts.js'; +export { processSQLQueryIR } from './preprocessor-sql.js'; + +export { sql, TaggedQuery, PreparedQuery } from './tag.js'; diff --git a/packages/query/src/preprocessor-sql.test.ts b/packages/runtime/src/preprocessor-sql.test.ts similarity index 92% rename from packages/query/src/preprocessor-sql.test.ts rename to packages/runtime/src/preprocessor-sql.test.ts index cd41aa88..770f7059 100644 --- a/packages/query/src/preprocessor-sql.test.ts +++ b/packages/runtime/src/preprocessor-sql.test.ts @@ -1,6 +1,6 @@ -import parseSQLQuery, { queryASTToIR } from './loader/sql'; -import { processSQLQueryIR } from './preprocessor-sql'; -import { ParamTransform } from './preprocessor'; +import { queryASTToIR, parseSQLFile as parseSQLQuery } from '@pgtyped/parser'; +import { processSQLQueryIR } from './preprocessor-sql.js'; +import { ParameterTransform } from './preprocessor.js'; test('(SQL) no params', () => { const query = ` @@ -79,13 +79,13 @@ test('(SQL) two scalar params', () => { assignedIndex: 1, name: 'id', required: false, - type: ParamTransform.Scalar, + type: ParameterTransform.Scalar, }, { assignedIndex: 2, name: 'age', required: false, - type: ParamTransform.Scalar, + type: ParameterTransform.Scalar, }, ], bindings: [], @@ -122,7 +122,7 @@ test('(SQL) one param used twice', () => { assignedIndex: 1, name: 'id', required: false, - type: ParamTransform.Scalar, + type: ParameterTransform.Scalar, }, ], bindings: [], @@ -161,7 +161,7 @@ test('(SQL) array param', () => { mapping: [ { name: 'ages', - type: ParamTransform.Spread, + type: ParameterTransform.Spread, required: false, assignedIndex: 1, }, @@ -202,7 +202,7 @@ test('(SQL) array param used twice', () => { { name: 'ages', required: false, - type: ParamTransform.Spread, + type: ParameterTransform.Spread, assignedIndex: 1, }, ], @@ -242,13 +242,13 @@ test('(SQL) array and scalar param', () => { mapping: [ { name: 'ages', - type: ParamTransform.Spread, + type: ParameterTransform.Spread, required: false, assignedIndex: 1, }, { name: 'userId', - type: ParamTransform.Scalar, + type: ParameterTransform.Scalar, required: false, assignedIndex: 2, }, @@ -288,18 +288,18 @@ test('(SQL) pick param', () => { mapping: [ { name: 'user', - type: ParamTransform.Pick, + type: ParameterTransform.Pick, dict: { name: { assignedIndex: 1, name: 'name', - type: ParamTransform.Scalar, + type: ParameterTransform.Scalar, required: false, }, age: { assignedIndex: 2, name: 'age', - type: ParamTransform.Scalar, + type: ParameterTransform.Scalar, required: false, }, }, @@ -340,18 +340,18 @@ test('(SQL) pick param used twice', () => { mapping: [ { name: 'user', - type: ParamTransform.Pick, + type: ParameterTransform.Pick, dict: { name: { assignedIndex: 1, name: 'name', - type: ParamTransform.Scalar, + type: ParameterTransform.Scalar, required: false, }, age: { assignedIndex: 2, name: 'age', - type: ParamTransform.Scalar, + type: ParameterTransform.Scalar, required: false, }, }, @@ -392,17 +392,17 @@ test('(SQL) pickSpread param', () => { const expectedMapping = [ { name: 'users', - type: ParamTransform.PickSpread, + type: ParameterTransform.PickSpread, dict: { name: { name: 'name', - type: ParamTransform.Scalar, + type: ParameterTransform.Scalar, required: false, assignedIndex: 1, }, age: { name: 'age', - type: ParamTransform.Scalar, + type: ParameterTransform.Scalar, required: false, assignedIndex: 2, }, @@ -450,17 +450,17 @@ test('(SQL) pickSpread param used twice', () => { const expectedMapping = [ { name: 'users', - type: ParamTransform.PickSpread, + type: ParameterTransform.PickSpread, dict: { name: { name: 'name', - type: ParamTransform.Scalar, + type: ParameterTransform.Scalar, required: false, assignedIndex: 1, }, age: { name: 'age', - type: ParamTransform.Scalar, + type: ParameterTransform.Scalar, required: false, assignedIndex: 2, }, @@ -505,7 +505,7 @@ test('(SQL) scalar param required and optional', () => { assignedIndex: 1, name: 'id', required: true, - type: ParamTransform.Scalar, + type: ParameterTransform.Scalar, }, ], bindings: [], @@ -544,18 +544,18 @@ test('(SQL) pick param required', () => { mapping: [ { name: 'user', - type: ParamTransform.Pick, + type: ParameterTransform.Pick, dict: { name: { assignedIndex: 1, name: 'name', - type: ParamTransform.Scalar, + type: ParameterTransform.Scalar, required: true, }, age: { assignedIndex: 2, name: 'age', - type: ParamTransform.Scalar, + type: ParameterTransform.Scalar, required: false, }, }, @@ -596,7 +596,7 @@ test('(SQL) array param required', () => { mapping: [ { name: 'ages', - type: ParamTransform.Spread, + type: ParameterTransform.Spread, required: true, assignedIndex: 1, }, diff --git a/packages/query/src/preprocessor-sql.ts b/packages/runtime/src/preprocessor-sql.ts similarity index 78% rename from packages/query/src/preprocessor-sql.ts rename to packages/runtime/src/preprocessor-sql.ts index 71ed9150..5259bbdd 100644 --- a/packages/query/src/preprocessor-sql.ts +++ b/packages/runtime/src/preprocessor-sql.ts @@ -1,23 +1,23 @@ -import { assert, SQLQueryIR, TransformType } from './loader/sql'; +import { assert, SQLQueryIR, TransformType } from '@pgtyped/parser'; import { - IInterpolatedQuery, - INestedParameters, - IQueryParameters, - IScalarArrayParam, - IScalarParam, - ParamTransform, - QueryParam, + InterpolatedQuery, + NestedParameters, + QueryParameters, + ScalarArrayParameter, + ScalarParameter, + ParameterTransform, + QueryParameter, replaceIntervals, Scalar, -} from './preprocessor'; +} from './preprocessor.js'; /* Processes query AST formed by new parser from pure SQL files */ export const processSQLQueryIR = ( queryIR: SQLQueryIR, - passedParams?: IQueryParameters, -): IInterpolatedQuery => { + passedParams?: QueryParameters, +): InterpolatedQuery => { const bindings: Scalar[] = []; - const paramMapping: QueryParam[] = []; + const paramMapping: QueryParameter[] = []; const usedParams = queryIR.params.filter( (p) => p.name in queryIR.usedParamSet, ); @@ -39,10 +39,10 @@ export const processSQLQueryIR = ( const idx = i++; paramMapping.push({ name: usedParam.name, - type: ParamTransform.Spread, + type: ParameterTransform.Spread, assignedIndex: idx, required: usedParam.required, - } as IScalarArrayParam); + } as ScalarArrayParameter); sub = `$${idx}`; } usedParam.locs.forEach((loc) => @@ -57,7 +57,7 @@ export const processSQLQueryIR = ( // Handle pick transform if (usedParam.transform.type === TransformType.PickTuple) { const dict: { - [key: string]: IScalarParam; + [key: string]: ScalarParameter; } = {}; const sub = usedParam.transform.keys .map(({ name, required }) => { @@ -65,13 +65,11 @@ export const processSQLQueryIR = ( dict[name] = { name, required, - type: ParamTransform.Scalar, + type: ParameterTransform.Scalar, assignedIndex: idx, - } as IScalarParam; + } as ScalarParameter; if (passedParams) { - const paramValue = passedParams[ - usedParam.name - ] as INestedParameters; + const paramValue = passedParams[usedParam.name] as NestedParameters; const val = paramValue[name]; bindings.push(val); } @@ -81,7 +79,7 @@ export const processSQLQueryIR = ( if (!passedParams) { paramMapping.push({ name: usedParam.name, - type: ParamTransform.Pick, + type: ParameterTransform.Pick, dict, }); } @@ -99,7 +97,7 @@ export const processSQLQueryIR = ( if (usedParam.transform.type === TransformType.PickArraySpread) { let sub: string; if (passedParams) { - const passedParam = passedParams[usedParam.name] as INestedParameters[]; + const passedParam = passedParams[usedParam.name] as NestedParameters[]; sub = passedParam .map((entity) => { assert(usedParam.transform.type === TransformType.PickArraySpread); @@ -115,7 +113,7 @@ export const processSQLQueryIR = ( .join('),('); } else { const dict: { - [key: string]: IScalarParam; + [key: string]: ScalarParameter; } = {}; sub = usedParam.transform.keys .map(({ name, required }) => { @@ -123,15 +121,15 @@ export const processSQLQueryIR = ( dict[name] = { name, required, - type: ParamTransform.Scalar, + type: ParameterTransform.Scalar, assignedIndex: idx, - } as IScalarParam; + } as ScalarParameter; return `$${idx}`; }) .join(','); paramMapping.push({ name: usedParam.name, - type: ParamTransform.PickSpread, + type: ParameterTransform.PickSpread, dict, }); } @@ -153,10 +151,10 @@ export const processSQLQueryIR = ( } else { paramMapping.push({ name: usedParam.name, - type: ParamTransform.Scalar, + type: ParameterTransform.Scalar, assignedIndex, required: usedParam.required, - } as IScalarParam); + } as ScalarParameter); } usedParam.locs.forEach((loc) => diff --git a/packages/query/src/preprocessor-ts.test.ts b/packages/runtime/src/preprocessor-ts.test.ts similarity index 91% rename from packages/query/src/preprocessor-ts.test.ts rename to packages/runtime/src/preprocessor-ts.test.ts index 1f610cf3..2a46a104 100644 --- a/packages/query/src/preprocessor-ts.test.ts +++ b/packages/runtime/src/preprocessor-ts.test.ts @@ -1,6 +1,6 @@ -import { parseTSQuery } from './loader/typescript'; -import { ParamTransform } from './preprocessor'; -import { processTSQueryAST } from './preprocessor-ts'; +import { parseTSQuery } from '@pgtyped/parser'; +import { ParameterTransform } from './preprocessor.js'; +import { processTSQueryAST } from './preprocessor-ts.js'; test('(TS) name parameter interpolation', () => { const query = 'SELECT id, name from users where id = $id and age > $age'; @@ -125,18 +125,18 @@ test('(TS) single value list parameter interpolation', () => { mapping: [ { name: 'user', - type: ParamTransform.Pick, + type: ParameterTransform.Pick, dict: { name: { assignedIndex: 1, name: 'name', - type: ParamTransform.Scalar, + type: ParameterTransform.Scalar, required: false, }, age: { assignedIndex: 2, name: 'age', - type: ParamTransform.Scalar, + type: ParameterTransform.Scalar, required: false, }, }, @@ -186,13 +186,13 @@ test('(TS) multiple value list (array) parameter mapping', () => { mapping: [ { name: 'ages', - type: ParamTransform.Spread, + type: ParameterTransform.Spread, required: false, assignedIndex: [1], }, { name: 'otherAges', - type: ParamTransform.Spread, + type: ParameterTransform.Spread, required: false, assignedIndex: [2], }, @@ -236,17 +236,17 @@ test('(TS) multiple value list parameter mapping', () => { mapping: [ { name: 'users', - type: ParamTransform.PickSpread, + type: ParameterTransform.PickSpread, dict: { name: { name: 'name', - type: ParamTransform.Scalar, + type: ParameterTransform.Scalar, required: false, assignedIndex: 1, }, age: { name: 'age', - type: ParamTransform.Scalar, + type: ParameterTransform.Scalar, required: false, assignedIndex: 2, }, @@ -271,17 +271,17 @@ test('(TS) multiple value list parameter mapping twice', () => { mapping: [ { name: 'users', - type: ParamTransform.PickSpread, + type: ParameterTransform.PickSpread, dict: { name: { name: 'name', - type: ParamTransform.Scalar, + type: ParameterTransform.Scalar, required: false, assignedIndex: 1, }, age: { name: 'age', - type: ParamTransform.Scalar, + type: ParameterTransform.Scalar, required: false, assignedIndex: 2, }, @@ -416,41 +416,41 @@ test('(TS) all kinds mapping ', () => { mapping: [ { name: 'userId', - type: ParamTransform.Scalar, + type: ParameterTransform.Scalar, required: false, assignedIndex: 1, }, { name: 'age', - type: ParamTransform.Scalar, + type: ParameterTransform.Scalar, required: true, assignedIndex: 2, }, { name: 'users', - type: ParamTransform.Spread, + type: ParameterTransform.Spread, required: false, assignedIndex: [3], }, { name: 'user', - type: ParamTransform.Pick, + type: ParameterTransform.Pick, dict: { id: { name: 'id', - type: ParamTransform.Scalar, + type: ParameterTransform.Scalar, required: false, assignedIndex: 4, }, age: { name: 'age', - type: ParamTransform.Scalar, + type: ParameterTransform.Scalar, required: true, assignedIndex: 6, }, parentId: { name: 'parentId', - type: ParamTransform.Scalar, + type: ParameterTransform.Scalar, required: false, assignedIndex: 5, }, @@ -458,17 +458,17 @@ test('(TS) all kinds mapping ', () => { }, { name: 'comments', - type: ParamTransform.PickSpread, + type: ParameterTransform.PickSpread, dict: { id: { name: 'id', - type: ParamTransform.Scalar, + type: ParameterTransform.Scalar, required: true, assignedIndex: 7, }, text: { name: 'text', - type: ParamTransform.Scalar, + type: ParameterTransform.Scalar, required: false, assignedIndex: 8, }, @@ -492,7 +492,7 @@ test('(TS) required spread', () => { mapping: [ { name: 'users', - type: ParamTransform.Spread, + type: ParameterTransform.Spread, required: true, assignedIndex: [1], }, diff --git a/packages/query/src/preprocessor-ts.ts b/packages/runtime/src/preprocessor-ts.ts similarity index 74% rename from packages/query/src/preprocessor-ts.ts rename to packages/runtime/src/preprocessor-ts.ts index 9b1d7f57..85a3326b 100644 --- a/packages/query/src/preprocessor-ts.ts +++ b/packages/runtime/src/preprocessor-ts.ts @@ -1,30 +1,29 @@ -import { TSQueryAST } from './loader/typescript'; -import { Param, ParamKey, ParamType } from './loader/typescript/query'; -import { assert } from './loader/sql'; +import { TSQueryAST, assert } from '@pgtyped/parser'; +import { Param, ParamKey, ParamType } from '@pgtyped/parser'; import { - IDictArrayParam, - IDictParam, - IInterpolatedQuery, - INestedParameters, - IQueryParameters, - IScalarArrayParam, - IScalarParam, - ParamTransform, - QueryParam, + DictArrayParameter, + DictParameter, + InterpolatedQuery, + NestedParameters, + QueryParameters, + ScalarArrayParameter, + ScalarParameter, + ParameterTransform, + QueryParameter, replaceIntervals, Scalar, -} from './preprocessor'; +} from './preprocessor.js'; function processScalar( { name, required }: Param, nextIndex: number, - existingConfig?: IScalarParam, - parameters?: IQueryParameters, + existingConfig?: ScalarParameter, + parameters?: QueryParameters, ): { replacement: string; bindings: Scalar[]; nextIndex: number; - config: IScalarParam; + config: ScalarParameter; } { let index = nextIndex; const bindings = []; @@ -37,7 +36,7 @@ function processScalar( replacement = `$${assignedIndex}`; config = { assignedIndex, - type: ParamTransform.Scalar, + type: ParameterTransform.Scalar, name, required, }; @@ -53,13 +52,13 @@ function processScalar( function processScalarArray( { name, required }: Param, nextIndex: number, - existingConfig?: IScalarArrayParam, - parameters?: IQueryParameters, + existingConfig?: ScalarArrayParameter, + parameters?: QueryParameters, ): { replacement: string; bindings: Scalar[]; nextIndex: number; - config: IScalarArrayParam; + config: ScalarArrayParameter; } { let index = nextIndex; const bindings: Scalar[] = []; @@ -80,7 +79,7 @@ function processScalarArray( } config = { assignedIndex, - type: ParamTransform.Spread, + type: ParameterTransform.Spread, name, required, }; @@ -94,19 +93,23 @@ function processObject( paramName: string, keys: ParamKey[], nextIndex: number, - existingConfig?: IDictParam, - parameters?: IQueryParameters, + existingConfig?: DictParameter, + parameters?: QueryParameters, ): { replacement: string; bindings: Scalar[]; nextIndex: number; - config: IDictParam; + config: DictParameter; } { let index = nextIndex; const bindings: Scalar[] = []; const config = existingConfig || - ({ name: paramName, type: ParamTransform.Pick, dict: {} } as IDictParam); + ({ + name: paramName, + type: ParameterTransform.Pick, + dict: {}, + } as DictParameter); const keyIndices = keys.map(({ name, required }) => { if (name in config.dict) { @@ -120,10 +123,10 @@ function processObject( assignedIndex, name, required, - type: ParamTransform.Scalar, + type: ParameterTransform.Scalar, }; if (parameters) { - const value = (parameters[paramName] as INestedParameters)[name]; + const value = (parameters[paramName] as NestedParameters)[name]; bindings.push(value); } return `$${assignedIndex}`; @@ -137,13 +140,13 @@ function processObjectArray( paramName: string, keys: ParamKey[], nextIndex: number, - existingConfig?: IDictArrayParam, - parameters?: IQueryParameters, + existingConfig?: DictArrayParameter, + parameters?: QueryParameters, ): { replacement: string; bindings: Scalar[]; nextIndex: number; - config: IDictArrayParam; + config: DictArrayParameter; } { let index = nextIndex; const bindings: Scalar[] = []; @@ -151,13 +154,13 @@ function processObjectArray( existingConfig || ({ name: paramName, - type: ParamTransform.PickSpread, + type: ParameterTransform.PickSpread, dict: {}, - } as IDictArrayParam); + } as DictArrayParameter); let replacement; if (parameters) { - const values = parameters[paramName] as INestedParameters[]; + const values = parameters[paramName] as NestedParameters[]; if (values.length > 0) { replacement = values .map((val) => @@ -186,7 +189,7 @@ function processObjectArray( assignedIndex, name, required, - type: ParamTransform.Scalar, + type: ParameterTransform.Scalar, }; return `$${assignedIndex}`; }); @@ -199,29 +202,33 @@ function processObjectArray( /* Processes query strings produced by old parser from SQL-in-TS statements */ export const processTSQueryAST = ( query: TSQueryAST, - parameters?: IQueryParameters, -): IInterpolatedQuery => { + parameters?: QueryParameters, +): InterpolatedQuery => { const bindings: Scalar[] = []; - const baseMap: { [param: string]: QueryParam } = {}; + const baseMap: { [param: string]: QueryParameter } = {}; let i = 0; const intervals: { a: number; b: number; sub: string }[] = []; for (const param of query.params) { let sub: string; let paramBindings: Scalar[] = []; - let config: QueryParam; + let config: QueryParameter; let result; if (param.selection.type === ParamType.Scalar) { - const prevConfig = baseMap[param.name] as IScalarParam | undefined; + const prevConfig = baseMap[param.name] as ScalarParameter | undefined; result = processScalar(param, i, prevConfig, parameters); } if (param.selection.type === ParamType.ScalarArray) { - const prevConfig = baseMap[param.name] as IScalarArrayParam | undefined; + const prevConfig = baseMap[param.name] as + | ScalarArrayParameter + | undefined; result = processScalarArray(param, i, prevConfig, parameters); } if (param.selection.type === ParamType.Object) { - const prevConfig: IDictParam = (baseMap[param.name] as IDictParam) || { + const prevConfig: DictParameter = (baseMap[ + param.name + ] as DictParameter) || { name: param.name, - type: ParamTransform.Pick, + type: ParameterTransform.Pick, dict: {}, }; result = processObject( @@ -233,11 +240,11 @@ export const processTSQueryAST = ( ); } if (param.selection.type === ParamType.ObjectArray) { - const prevConfig: IDictArrayParam = (baseMap[ + const prevConfig: DictArrayParameter = (baseMap[ param.name - ] as IDictArrayParam) || { + ] as DictArrayParameter) || { name: param.name, - type: ParamTransform.PickSpread, + type: ParameterTransform.PickSpread, dict: {}, }; result = processObjectArray( diff --git a/packages/query/src/preprocessor.ts b/packages/runtime/src/preprocessor.ts similarity index 57% rename from packages/query/src/preprocessor.ts rename to packages/runtime/src/preprocessor.ts index 325937bc..8168ba32 100644 --- a/packages/query/src/preprocessor.ts +++ b/packages/runtime/src/preprocessor.ts @@ -1,63 +1,63 @@ export type Scalar = string | number | null; -export enum ParamTransform { +export enum ParameterTransform { Scalar, Spread, Pick, PickSpread, } -export interface IScalarParam { +export interface ScalarParameter { name: string; - type: ParamTransform.Scalar; + type: ParameterTransform.Scalar; required: boolean; assignedIndex: number; } -export interface IDictParam { +export interface DictParameter { name: string; - type: ParamTransform.Pick; + type: ParameterTransform.Pick; dict: { - [key: string]: IScalarParam; + [key: string]: ScalarParameter; }; } -export interface IScalarArrayParam { +export interface ScalarArrayParameter { name: string; - type: ParamTransform.Spread; + type: ParameterTransform.Spread; required: boolean; assignedIndex: number | number[]; } -export interface IDictArrayParam { +export interface DictArrayParameter { name: string; - type: ParamTransform.PickSpread; + type: ParameterTransform.PickSpread; dict: { - [key: string]: IScalarParam; + [key: string]: ScalarParameter; }; } -export type QueryParam = - | IScalarParam - | IScalarArrayParam - | IDictParam - | IDictArrayParam; +export type QueryParameter = + | ScalarParameter + | ScalarArrayParameter + | DictParameter + | DictArrayParameter; -export interface IInterpolatedQuery { +export interface InterpolatedQuery { query: string; - mapping: QueryParam[]; + mapping: QueryParameter[]; bindings: Scalar[]; } -export interface INestedParameters { +export interface NestedParameters { [subParamName: string]: Scalar; } -export interface IQueryParameters { +export interface QueryParameters { [paramName: string]: | Scalar - | INestedParameters + | NestedParameters | Scalar[] - | INestedParameters[]; + | NestedParameters[]; } export function replaceIntervals( diff --git a/packages/query/src/tag.ts b/packages/runtime/src/tag.ts similarity index 86% rename from packages/query/src/tag.ts rename to packages/runtime/src/tag.ts index f535b3e2..7f242bc8 100644 --- a/packages/query/src/tag.ts +++ b/packages/runtime/src/tag.ts @@ -1,7 +1,6 @@ -import { QueryIR } from './loader/sql'; -import { parseTSQuery, TSQueryAST } from './loader/typescript'; -import { processSQLQueryIR } from './preprocessor-sql'; -import { processTSQueryAST } from './preprocessor-ts'; +import { SQLQueryIR, parseTSQuery, TSQueryAST } from '@pgtyped/parser'; +import { processSQLQueryIR } from './preprocessor-sql.js'; +import { processTSQueryAST } from './preprocessor-ts.js'; export interface IDatabaseConnection { query: (query: string, bindings: any[]) => Promise<{ rows: any[] }>; @@ -53,7 +52,7 @@ interface ITypePair { result: any; } -const sql = ( +export const sql = ( stringsArray: TemplateStringsArray, ) => { const { query } = parseTSQuery(stringsArray[0]); @@ -67,9 +66,9 @@ export class PreparedQuery { dbConnection: IDatabaseConnection, ) => Promise>; - private readonly queryIR: QueryIR; + private readonly queryIR: SQLQueryIR; - constructor(queryIR: QueryIR) { + constructor(queryIR: SQLQueryIR) { this.queryIR = queryIR; this.run = async (params, connection) => { const { query: processedQuery, bindings } = processSQLQueryIR( diff --git a/packages/runtime/tsconfig.json b/packages/runtime/tsconfig.json new file mode 100644 index 00000000..95f2e757 --- /dev/null +++ b/packages/runtime/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./lib/", + "rootDir": "./src/", + }, + "exclude": ["lib"], + "include": ["./src"] +} diff --git a/packages/wire/.npmignore b/packages/wire/.npmignore deleted file mode 100644 index b50b4c42..00000000 --- a/packages/wire/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -src/**/* -lib/**/*.test.* -tsconfig.json -*.tgz \ No newline at end of file diff --git a/packages/wire/README.md b/packages/wire/README.md index 1627c4c8..abacc60e 100644 --- a/packages/wire/README.md +++ b/packages/wire/README.md @@ -1,4 +1,4 @@ ### PgTyped Wire -This package is part of the pgtyped project. +This package implements most of the Postgres protocol for pgTyped internal use. Refer to root [README](https://github.com/adelsz/pgtyped) for details. diff --git a/packages/wire/jest.config.ts b/packages/wire/jest.config.ts new file mode 100644 index 00000000..bb75cce2 --- /dev/null +++ b/packages/wire/jest.config.ts @@ -0,0 +1,24 @@ +import type { Config } from 'jest'; + +const config: Config = { + snapshotFormat: { + escapeString: true, + printBasicPrototype: true, + }, + roots: ['src'], + moduleNameMapper: { + '^(\\.{1,2}/.*)\\.js$': '$1', + }, + transform: { + '^.+\\.tsx?$': [ + 'ts-jest', + { + useESM: true, + }, + ], + }, + preset: 'ts-jest/presets/default-esm', + testRegex: '\\.test\\.tsx?$', +}; + +export default config; diff --git a/packages/wire/package.json b/packages/wire/package.json index 57cd506f..1bb05b88 100644 --- a/packages/wire/package.json +++ b/packages/wire/package.json @@ -1,6 +1,13 @@ { "name": "@pgtyped/wire", "version": "1.1.0", + "type": "module", + "exports": { + ".": { + "import": "./lib/index.js", + "types": "./lib/index.d.ts" + } + }, "main": "lib/index.js", "types": "lib/index.d.ts", "license": "MIT", @@ -12,24 +19,14 @@ "publishConfig": { "access": "public" }, + "files": [ + "lib" + ], "scripts": { - "test": "jest", - "build": "tsc --declaration", + "test": "NODE_OPTIONS='--experimental-vm-modules' jest", + "build": "tsc", "check": "tsc --noEmit", - "watch": "tsc --declaration --watch --preserveWatchOutput" - }, - "jest": { - "roots": [ - "src" - ], - "testRegex": "\\.test\\.tsx?$", - "transform": { - "^.+\\.tsx?$": "ts-jest" - }, - "snapshotFormat": { - "escapeString": true, - "printBasicPrototype": true - } + "watch": "tsc --watch --preserveWatchOutput" }, "dependencies": { "debug": "^4.1.1" diff --git a/packages/wire/src/helpers.test.ts b/packages/wire/src/helpers.test.ts index 252eedce..22611327 100644 --- a/packages/wire/src/helpers.test.ts +++ b/packages/wire/src/helpers.test.ts @@ -6,7 +6,7 @@ import { int32, sumSize, notNullTerminatedString, -} from '../src/helpers'; +} from '../src/helpers.js'; test('cString works', () => { const str = 'a'; diff --git a/packages/wire/src/index.ts b/packages/wire/src/index.ts index ea483091..cee33aa6 100644 --- a/packages/wire/src/index.ts +++ b/packages/wire/src/index.ts @@ -1,3 +1,5 @@ -export { AsyncQueue } from './queue'; +export { AsyncQueue } from './queue.js'; -export { messages, PreparedObjectType } from './messages'; +export { messages, PreparedObjectType } from './messages.js'; + +export { cString } from './helpers.js'; diff --git a/packages/wire/src/messages.ts b/packages/wire/src/messages.ts index b6497fbf..58d899ae 100644 --- a/packages/wire/src/messages.ts +++ b/packages/wire/src/messages.ts @@ -10,7 +10,7 @@ import { int16, int32, notNullTerminatedString, -} from './helpers'; +} from './helpers.js'; export interface IClientMessage { name: string; diff --git a/packages/wire/src/protocol.test.ts b/packages/wire/src/protocol.test.ts index 6db06ca8..f947fea6 100644 --- a/packages/wire/src/protocol.test.ts +++ b/packages/wire/src/protocol.test.ts @@ -1,10 +1,10 @@ -import { messages } from '../src/messages'; +import { messages } from '../src/messages.js'; import { buildMessage, parseMessage, parseMultiple, parseOneOf, -} from '../src/protocol'; +} from '../src/protocol.js'; test('buildMessage for StartupMessage works', () => { const base = buildMessage(messages.startupMessage, { diff --git a/packages/wire/src/protocol.ts b/packages/wire/src/protocol.ts index 914e0488..3cf7d6cc 100644 --- a/packages/wire/src/protocol.ts +++ b/packages/wire/src/protocol.ts @@ -9,12 +9,12 @@ import { int32, sumSize, notNullTerminatedString, -} from './helpers'; +} from './helpers.js'; import { IClientMessage, IServerMessage, messages as pgMessages, -} from './messages'; +} from './messages.js'; export const parseSimpleType = ( type: any, diff --git a/packages/wire/src/queue.ts b/packages/wire/src/queue.ts index 2959e977..a53193f7 100644 --- a/packages/wire/src/queue.ts +++ b/packages/wire/src/queue.ts @@ -7,9 +7,9 @@ import { parseMultiple, parseOneOf, ParseResult, -} from './protocol'; +} from './protocol.js'; -import { IClientMessage, IServerMessage, messages } from './messages'; +import { IClientMessage, IServerMessage, messages } from './messages.js'; import debugBase from 'debug'; const debug = debugBase('pg-wire:socket'); diff --git a/packages/wire/tsconfig.json b/packages/wire/tsconfig.json index d48ff986..95f2e757 100644 --- a/packages/wire/tsconfig.json +++ b/packages/wire/tsconfig.json @@ -1,8 +1,8 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "./lib/" /* Redirect output structure to the directory. */, - "rootDir": "./src/" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + "outDir": "./lib/", + "rootDir": "./src/", }, "exclude": ["lib"], "include": ["./src"] diff --git a/tsconfig.json b/tsconfig.json index ad59da3c..ec9f1711 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,12 +2,12 @@ "compilerOptions": { /* Basic Options */ "target": "ES6", - "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */, + "module": "ES2020" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */, // "lib": [], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ - // "declaration": true, /* Generates corresponding '.d.ts' file. */ + "declaration": true, /* Generates corresponding '.d.ts' file. */ // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ "sourceMap": true /* Generates corresponding '.map' file. */, // "outFile": "./", /* Concatenate and emit output to single file. */ @@ -37,7 +37,7 @@ // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ /* Module Resolution Options */ - // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */