@typed-sql/postgres 1.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,17 @@
1
+ # @typed-sql/postgres
2
+
3
+ ## 1.0.0-beta.0
4
+
5
+ ### Major Changes
6
+
7
+ - Release the first public typed-sql beta: exact TypeScript 7 row inference from static PostgreSQL and
8
+ MySQL, versioned schema introspection, application-owned drivers, config-driven grammar plugins,
9
+ CLI verification, editor language-server integration, versioned diagnostics, bounded parsing, and
10
+ real-database plus packed-tarball verification.
11
+
12
+ ### Patch Changes
13
+
14
+ - Updated dependencies
15
+ - @typed-sql/ast@1.0.0-beta.0
16
+ - @typed-sql/core@1.0.0-beta.0
17
+ - @typed-sql/schema@1.0.0-beta.0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 typed-sql contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,75 @@
1
+ # @typed-sql/postgres
2
+
3
+ PostgreSQL grammar, catalog introspection, exact result inference, type policy, runtime codecs, and
4
+ an optional application-owned `pg` adapter for [typed-sql](https://github.com/Lojhan/typed-sql).
5
+
6
+ ```sh
7
+ pnpm add @typed-sql/core@next @typed-sql/postgres@next pg
8
+ pnpm add -D @typed-sql/cli@next typescript@7.0.2
9
+ ```
10
+
11
+ `pg` is intentionally not a dependency or peer dependency of this package. Your application chooses
12
+ its driver version, pool configuration, and lifecycle; the adapter loads it only when you import
13
+ `@typed-sql/postgres/pg`.
14
+
15
+ ## Configure and generate
16
+
17
+ ```ts
18
+ import { defineConfig } from "@typed-sql/core";
19
+ import { postgres, typePolicy } from "@typed-sql/postgres";
20
+ import { pg } from "@typed-sql/postgres/pg";
21
+
22
+ export default defineConfig({
23
+ dialect: postgres({ typePolicy }),
24
+ schema: {
25
+ file: "generated/db/schema.json",
26
+ provider: pg({
27
+ connectionString: () => process.env.DATABASE_URL!,
28
+ schemas: ["public"],
29
+ typePolicy,
30
+ }),
31
+ },
32
+ outDir: "generated/db",
33
+ projects: ["tsconfig.json"],
34
+ typePolicy,
35
+ });
36
+ ```
37
+
38
+ ```sh
39
+ pnpm exec typed-sql generate
40
+ ```
41
+
42
+ ## Query and execute
43
+
44
+ ```ts
45
+ import { sql, typePolicy } from "@typed-sql/postgres";
46
+ import { createPgDatabase } from "@typed-sql/postgres/pg";
47
+
48
+ const query = sql`
49
+ SELECT account.id, account.email, account.status, project.budget
50
+ FROM users AS account
51
+ LEFT JOIN projects AS project ON project.owner_id = account.id
52
+ ORDER BY account.id
53
+ `;
54
+
55
+ const database = await createPgDatabase({
56
+ connectionString: process.env.DATABASE_URL!,
57
+ typePolicy,
58
+ });
59
+
60
+ const rows = await database.execute(query);
61
+ // readonly {
62
+ // id: bigint;
63
+ // email: string;
64
+ // status: "active" | "suspended";
65
+ // budget: string | null;
66
+ // }[]
67
+ ```
68
+
69
+ The default lossless policy maps PostgreSQL `bigint` to `bigint`, `numeric` to `string`, temporal
70
+ types to `Date`, JSON to `unknown`, enums to literal unions, arrays recursively, and `bytea` to
71
+ `Uint8Array`. Per-query parsers do not mutate `pg` globals.
72
+
73
+ See the complete [PostgreSQL support matrix](https://github.com/Lojhan/typed-sql/blob/main/docs/POSTGRESQL_SUPPORT.md).
74
+
75
+ MIT © typed-sql contributors
@@ -0,0 +1,19 @@
1
+ import { type DialectPlugin } from "@typed-sql/core";
2
+ import { type SchemaSnapshot } from "@typed-sql/schema";
3
+ import { type PostgresTypePolicy } from "./type-policy.js";
4
+ export declare const POSTGRES_DIALECT_VERSION = "1.0.0";
5
+ export type PostgresSchemaSnapshot = SchemaSnapshot & {
6
+ readonly dialect: "postgres";
7
+ };
8
+ export interface PostgresDialectOptions {
9
+ readonly typePolicy?: PostgresTypePolicy;
10
+ }
11
+ export declare function postgres(options?: PostgresDialectOptions): DialectPlugin<PostgresSchemaSnapshot, PostgresTypePolicy>;
12
+ export { parseSchemaSnapshot, } from "@typed-sql/schema";
13
+ export { sql } from "@typed-sql/core";
14
+ export { introspectPostgres, loadPostgresDriver, PostgresSchemaProvider, postgresCatalogQueries } from "./provider.js";
15
+ export { defaultPostgresTypePolicy, defaultPostgresTypePolicy as typePolicy, isKnownPostgresType, mapPostgresType } from "./type-policy.js";
16
+ export type { PostgresTypePolicy } from "./type-policy.js";
17
+ export type { SchemaSnapshot } from "@typed-sql/schema";
18
+ export type { PostgresDriverImporter, PostgresDriverModule, PostgresIntrospectionClient, PostgresIntrospectionPool, PostgresQueryable, PostgresQueryResult, PostgresSchemaProviderOptions, } from "./provider.js";
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAE/E,OAAO,EAEL,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAA6B,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtF,eAAO,MAAM,wBAAwB,UAAU,CAAC;AAEhD,MAAM,MAAM,sBAAsB,GAAG,cAAc,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAA;CAAE,CAAC;AACvF,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,UAAU,CAAC,EAAE,kBAAkB,CAAC;CAC1C;AAUD,wBAAgB,QAAQ,CAAC,OAAO,GAAE,sBAA2B,GAAG,aAAa,CAAC,sBAAsB,EAAE,kBAAkB,CAAC,CAyBxH;AAED,OAAO,EACL,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AACtC,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AACvH,OAAO,EAAE,yBAAyB,EAAE,yBAAyB,IAAI,UAAU,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC5I,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,YAAY,EACV,sBAAsB,EACtB,oBAAoB,EACpB,2BAA2B,EAC3B,yBAAyB,EACzB,iBAAiB,EACjB,mBAAmB,EACnB,6BAA6B,GAC9B,MAAM,eAAe,CAAC"}
@@ -0,0 +1,47 @@
1
+ import { DIALECT_CONTRACT_VERSION } from "@typed-sql/core";
2
+ import { parseStatement, SqlParseError } from "@typed-sql/ast";
3
+ import { parseSchemaSnapshot, } from "@typed-sql/schema";
4
+ import { resolveStatement } from "./resolver.js";
5
+ import { defaultPostgresTypePolicy } from "./type-policy.js";
6
+ export const POSTGRES_DIALECT_VERSION = "1.0.0";
7
+ function validatePostgresSnapshot(value) {
8
+ const snapshot = parseSchemaSnapshot(value);
9
+ if (snapshot.dialect !== "postgres") {
10
+ throw new TypeError(`@typed-sql/postgres cannot use a ${snapshot.dialect} schema snapshot`);
11
+ }
12
+ return snapshot;
13
+ }
14
+ export function postgres(options = {}) {
15
+ const defaultTypePolicy = options.typePolicy ?? defaultPostgresTypePolicy;
16
+ return Object.freeze({
17
+ contractVersion: DIALECT_CONTRACT_VERSION,
18
+ id: "postgres",
19
+ grammarVersion: POSTGRES_DIALECT_VERSION,
20
+ sqlModule: "@typed-sql/postgres",
21
+ defaultTypePolicy,
22
+ placeholder(index) {
23
+ if (!Number.isInteger(index) || index < 1)
24
+ throw new RangeError("PostgreSQL parameter indexes start at 1");
25
+ return `$${index}`;
26
+ },
27
+ analyze(sql, snapshot, policy = defaultTypePolicy) {
28
+ try {
29
+ return resolveStatement(parseStatement(sql), snapshot, { typePolicy: policy });
30
+ }
31
+ catch (error) {
32
+ if (!(error instanceof SqlParseError))
33
+ throw error;
34
+ return {
35
+ columns: [],
36
+ diagnostics: [{ code: error.code, message: error.message, severity: "error", range: error.range }],
37
+ };
38
+ }
39
+ },
40
+ validateSnapshot: validatePostgresSnapshot,
41
+ });
42
+ }
43
+ export { parseSchemaSnapshot, } from "@typed-sql/schema";
44
+ export { sql } from "@typed-sql/core";
45
+ export { introspectPostgres, loadPostgresDriver, PostgresSchemaProvider, postgresCatalogQueries } from "./provider.js";
46
+ export { defaultPostgresTypePolicy, defaultPostgresTypePolicy as typePolicy, isKnownPostgresType, mapPostgresType } from "./type-policy.js";
47
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAsB,MAAM,iBAAiB,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EACL,mBAAmB,GAEpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,yBAAyB,EAA2B,MAAM,kBAAkB,CAAC;AAEtF,MAAM,CAAC,MAAM,wBAAwB,GAAG,OAAO,CAAC;AAOhD,SAAS,wBAAwB,CAAC,KAAc;IAC9C,MAAM,QAAQ,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;IAC5C,IAAI,QAAQ,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;QACpC,MAAM,IAAI,SAAS,CAAC,oCAAoC,QAAQ,CAAC,OAAO,kBAAkB,CAAC,CAAC;IAC9F,CAAC;IACD,OAAO,QAAkC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,OAAO,GAA2B,EAAE;IAC3D,MAAM,iBAAiB,GAAG,OAAO,CAAC,UAAU,IAAI,yBAAyB,CAAC;IAC1E,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,eAAe,EAAE,wBAAwB;QACzC,EAAE,EAAE,UAAU;QACd,cAAc,EAAE,wBAAwB;QACxC,SAAS,EAAE,qBAAqB;QAChC,iBAAiB;QACjB,WAAW,CAAC,KAAa;YACvB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC;gBAAE,MAAM,IAAI,UAAU,CAAC,yCAAyC,CAAC,CAAC;YAC3G,OAAO,IAAI,KAAK,EAAE,CAAC;QACrB,CAAC;QACD,OAAO,CAAC,GAAW,EAAE,QAAgC,EAAE,MAAM,GAAG,iBAAiB;YAC/E,IAAI,CAAC;gBACH,OAAO,gBAAgB,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC;YACjF,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,CAAC,KAAK,YAAY,aAAa,CAAC;oBAAE,MAAM,KAAK,CAAC;gBACnD,OAAO;oBACL,OAAO,EAAE,EAAE;oBACX,WAAW,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAgB,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC;iBAC5G,CAAC;YACJ,CAAC;QACH,CAAC;QACD,gBAAgB,EAAE,wBAAwB;KAC3C,CAAC,CAAC;AACL,CAAC;AAED,OAAO,EACL,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AACtC,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AACvH,OAAO,EAAE,yBAAyB,EAAE,yBAAyB,IAAI,UAAU,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,23 @@
1
+ import type { Pool as PgPool, PoolConfig } from "pg";
2
+ import { type PostgresSchemaSnapshot, type PostgresTypePolicy } from "./index.js";
3
+ import { type PostgresQueryable } from "./provider.js";
4
+ import { type PostgresDatabase, type PostgresPoolLike } from "./runtime.js";
5
+ export interface PgOptions {
6
+ readonly connectionString: string | (() => string | Promise<string>);
7
+ readonly poolConfig?: Omit<PoolConfig, "connectionString" | "types">;
8
+ readonly typePolicy?: PostgresTypePolicy;
9
+ readonly decimal?: (value: string) => unknown;
10
+ }
11
+ export interface PgSchemaProviderOptions {
12
+ readonly connectionString?: string | (() => string | Promise<string>);
13
+ readonly client?: PostgresQueryable;
14
+ readonly schemas?: readonly string[];
15
+ readonly typePolicy?: PostgresTypePolicy;
16
+ }
17
+ export declare function loadPgDriver(importer?: () => Promise<typeof import("pg")>): Promise<typeof import("pg")>;
18
+ export declare function adaptPgPool(pool: PgPool): PostgresPoolLike;
19
+ export declare function createPgDatabase(options: PgOptions): Promise<PostgresDatabase>;
20
+ export declare function pg(options: PgSchemaProviderOptions): {
21
+ introspect(): Promise<PostgresSchemaSnapshot>;
22
+ };
23
+ //# sourceMappingURL=pg.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pg.d.ts","sourceRoot":"","sources":["../../../../src/pg.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,IAAI,MAAM,EAAc,UAAU,EAAe,MAAM,IAAI,CAAC;AAC9E,OAAO,EAAE,KAAK,sBAAsB,EAAE,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAClF,OAAO,EAA0B,KAAK,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAC/E,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EAGtB,MAAM,cAAc,CAAC;AAEtB,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IACrE,QAAQ,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,UAAU,EAAE,kBAAkB,GAAG,OAAO,CAAC,CAAC;IACrE,QAAQ,CAAC,UAAU,CAAC,EAAE,kBAAkB,CAAC;IACzC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;CAC/C;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IACtE,QAAQ,CAAC,MAAM,CAAC,EAAE,iBAAiB,CAAC;IACpC,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,UAAU,CAAC,EAAE,kBAAkB,CAAC;CAC1C;AAED,wBAAsB,YAAY,CAChC,QAAQ,GAAE,MAAM,OAAO,CAAC,cAAc,IAAI,CAAC,CAAsB,GAChE,OAAO,CAAC,cAAc,IAAI,CAAC,CAAC,CAS9B;AAgBD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,CAoB1D;AAED,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,SAAS,GAAG,OAAO,CAAC,gBAAgB,CAAC,CASpF;AAED,wBAAgB,EAAE,CAAC,OAAO,EAAE,uBAAuB,GAAG;IAAE,UAAU,IAAI,OAAO,CAAC,sBAAsB,CAAC,CAAA;CAAE,CAetG"}
@@ -0,0 +1,76 @@
1
+ import {} from "./index.js";
2
+ import { PostgresSchemaProvider } from "./provider.js";
3
+ import { createPostgresDatabase, } from "./runtime.js";
4
+ export async function loadPgDriver(importer = () => import("pg")) {
5
+ try {
6
+ return await importer();
7
+ }
8
+ catch (error) {
9
+ if (error instanceof Error && "code" in error && error.code === "ERR_MODULE_NOT_FOUND") {
10
+ throw new Error("@typed-sql/postgres/pg requires the application-owned pg driver. Install it with: pnpm add pg", { cause: error });
11
+ }
12
+ throw error;
13
+ }
14
+ }
15
+ async function connectionString(value) {
16
+ const resolved = typeof value === "function" ? await value() : value;
17
+ if (resolved.length === 0)
18
+ throw new TypeError("PostgreSQL connectionString must not be empty");
19
+ return resolved;
20
+ }
21
+ function queryConfig(config) {
22
+ return {
23
+ text: config.text,
24
+ ...(config.values === undefined ? {} : { values: [...config.values] }),
25
+ ...(config.types === undefined ? {} : { types: config.types }),
26
+ };
27
+ }
28
+ export function adaptPgPool(pool) {
29
+ const wrapClient = (client) => ({
30
+ async query(config) {
31
+ const result = typeof config === "string"
32
+ ? await client.query(config)
33
+ : await client.query(queryConfig(config));
34
+ return { rows: result.rows };
35
+ },
36
+ release() { client.release(); },
37
+ });
38
+ return {
39
+ async query(config) {
40
+ const result = typeof config === "string"
41
+ ? await pool.query(config)
42
+ : await pool.query(queryConfig(config));
43
+ return { rows: result.rows };
44
+ },
45
+ async connect() { return wrapClient(await pool.connect()); },
46
+ async end() { await pool.end(); },
47
+ };
48
+ }
49
+ export async function createPgDatabase(options) {
50
+ const { Pool } = await loadPgDriver();
51
+ const pool = new Pool({ ...options.poolConfig, connectionString: await connectionString(options.connectionString) });
52
+ return createPostgresDatabase({
53
+ pool: adaptPgPool(pool),
54
+ ownsPool: true,
55
+ ...(options.typePolicy === undefined ? {} : { typePolicy: options.typePolicy }),
56
+ ...(options.decimal === undefined ? {} : { decimal: options.decimal }),
57
+ });
58
+ }
59
+ export function pg(options) {
60
+ return {
61
+ async introspect() {
62
+ if (options.connectionString === undefined && options.client === undefined) {
63
+ throw new TypeError("pg schema provider requires connectionString or client");
64
+ }
65
+ const provider = new PostgresSchemaProvider({
66
+ ...(options.client === undefined ? {} : { client: options.client }),
67
+ ...(options.schemas === undefined ? {} : { includeSchemas: options.schemas }),
68
+ ...(options.typePolicy === undefined ? {} : { typePolicy: options.typePolicy }),
69
+ });
70
+ if (options.client !== undefined)
71
+ return await provider.introspect({});
72
+ return await provider.introspect({ url: await connectionString(options.connectionString) });
73
+ },
74
+ };
75
+ }
76
+ //# sourceMappingURL=pg.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pg.js","sourceRoot":"","sources":["../../../../src/pg.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,100 @@
1
+ import type { SchemaInput, SchemaProvider, SchemaSnapshot } from "@typed-sql/schema";
2
+ import { type PostgresTypePolicy } from "./type-policy.js";
3
+ export interface PostgresQueryResult<Row> {
4
+ readonly rows: readonly Row[];
5
+ }
6
+ export interface PostgresQueryable {
7
+ query<Row extends Record<string, unknown>>(text: string, values?: readonly unknown[]): Promise<PostgresQueryResult<Row>>;
8
+ }
9
+ export interface PostgresIntrospectionClient extends PostgresQueryable {
10
+ release(): void;
11
+ }
12
+ export interface PostgresIntrospectionPool {
13
+ connect(): Promise<PostgresIntrospectionClient>;
14
+ end(): Promise<void>;
15
+ }
16
+ export interface PostgresDriverModule {
17
+ readonly Pool: new (config: {
18
+ readonly connectionString: string;
19
+ }) => PostgresIntrospectionPool;
20
+ }
21
+ export type PostgresDriverImporter = () => Promise<PostgresDriverModule>;
22
+ export interface PostgresSchemaProviderOptions {
23
+ readonly client?: PostgresQueryable;
24
+ readonly pool?: PostgresIntrospectionPool;
25
+ readonly includeSchemas?: readonly string[];
26
+ readonly typePolicy?: PostgresTypePolicy;
27
+ }
28
+ export declare const postgresCatalogQueries: {
29
+ readonly version: "SELECT current_setting('server_version') AS server_version";
30
+ readonly columns: `
31
+ SELECT
32
+ n.nspname AS schema_name,
33
+ c.relname AS table_name,
34
+ a.attname AS column_name,
35
+ format_type(a.atttypid, a.atttypmod) AS database_type,
36
+ a.attnotnull AS not_null,
37
+ (t.typcategory = 'A') AS is_array,
38
+ pg_get_expr(ad.adbin, ad.adrelid) AS default_expression
39
+ FROM pg_catalog.pg_attribute AS a
40
+ JOIN pg_catalog.pg_class AS c ON c.oid = a.attrelid
41
+ JOIN pg_catalog.pg_namespace AS n ON n.oid = c.relnamespace
42
+ JOIN pg_catalog.pg_type AS t ON t.oid = a.atttypid
43
+ LEFT JOIN pg_catalog.pg_attrdef AS ad ON ad.adrelid = a.attrelid AND ad.adnum = a.attnum
44
+ WHERE a.attnum > 0
45
+ AND NOT a.attisdropped
46
+ AND c.relkind IN ('r', 'p', 'v', 'm', 'f')
47
+ AND n.nspname NOT IN ('pg_catalog', 'information_schema')
48
+ AND n.nspname NOT LIKE 'pg_toast%'
49
+ AND ($1::text[] IS NULL OR n.nspname = ANY($1::text[]))
50
+ ORDER BY n.nspname, c.relname, a.attnum
51
+ `;
52
+ readonly enums: `
53
+ SELECT n.nspname AS schema_name, t.typname AS type_name, e.enumlabel AS enum_label
54
+ FROM pg_catalog.pg_type AS t
55
+ JOIN pg_catalog.pg_namespace AS n ON n.oid = t.typnamespace
56
+ JOIN pg_catalog.pg_enum AS e ON e.enumtypid = t.oid
57
+ WHERE n.nspname NOT IN ('pg_catalog', 'information_schema')
58
+ AND ($1::text[] IS NULL OR n.nspname = ANY($1::text[]))
59
+ ORDER BY n.nspname, t.typname, e.enumsortorder
60
+ `;
61
+ readonly domains: `
62
+ SELECT
63
+ n.nspname AS schema_name,
64
+ t.typname AS domain_name,
65
+ format_type(t.typbasetype, t.typtypmod) AS database_type,
66
+ t.typnotnull AS not_null
67
+ FROM pg_catalog.pg_type AS t
68
+ JOIN pg_catalog.pg_namespace AS n ON n.oid = t.typnamespace
69
+ WHERE t.typtype = 'd'
70
+ AND n.nspname NOT IN ('pg_catalog', 'information_schema')
71
+ AND ($1::text[] IS NULL OR n.nspname = ANY($1::text[]))
72
+ ORDER BY n.nspname, t.typname
73
+ `;
74
+ readonly functions: `
75
+ SELECT
76
+ n.nspname AS schema_name,
77
+ p.proname AS function_name,
78
+ ARRAY(
79
+ SELECT format_type(argument_oid, NULL)
80
+ FROM unnest(p.proargtypes::oid[]) WITH ORDINALITY AS arguments(argument_oid, position)
81
+ ORDER BY position
82
+ ) AS argument_types,
83
+ format_type(p.prorettype, NULL) AS database_return_type,
84
+ p.proretset AS set_returning
85
+ FROM pg_catalog.pg_proc AS p
86
+ JOIN pg_catalog.pg_namespace AS n ON n.oid = p.pronamespace
87
+ WHERE p.prokind = 'f'
88
+ AND n.nspname NOT IN ('pg_catalog', 'information_schema')
89
+ AND ($1::text[] IS NULL OR n.nspname = ANY($1::text[]))
90
+ ORDER BY n.nspname, p.proname, p.oid
91
+ `;
92
+ };
93
+ export declare function loadPostgresDriver(importer?: PostgresDriverImporter): Promise<PostgresDriverModule>;
94
+ export declare class PostgresSchemaProvider implements SchemaProvider {
95
+ #private;
96
+ constructor(options?: PostgresSchemaProviderOptions);
97
+ introspect(input: SchemaInput): Promise<SchemaSnapshot>;
98
+ }
99
+ export declare function introspectPostgres(input: SchemaInput, options?: PostgresSchemaProviderOptions): Promise<SchemaSnapshot>;
100
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../../src/provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAIV,WAAW,EACX,cAAc,EACd,cAAc,EAEf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAA8C,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEvG,MAAM,WAAW,mBAAmB,CAAC,GAAG;IACtC,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,GAAG,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC;CAC1H;AAED,MAAM,WAAW,2BAA4B,SAAQ,iBAAiB;IACpE,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,yBAAyB;IACxC,OAAO,IAAI,OAAO,CAAC,2BAA2B,CAAC,CAAC;IAChD,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,KAAK,MAAM,EAAE;QAAE,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAA;KAAE,KAAK,yBAAyB,CAAC;CACjG;AAED,MAAM,MAAM,sBAAsB,GAAG,MAAM,OAAO,CAAC,oBAAoB,CAAC,CAAC;AAEzE,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,MAAM,CAAC,EAAE,iBAAiB,CAAC;IACpC,QAAQ,CAAC,IAAI,CAAC,EAAE,yBAAyB,CAAC;IAC1C,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,QAAQ,CAAC,UAAU,CAAC,EAAE,kBAAkB,CAAC;CAC1C;AAqCD,eAAO,MAAM,sBAAsB;aACjC,OAAO,EAAE,4DAA4D;aACrE,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;GAqBR;aACD,KAAK,EAAE;;;;;;;;GAQN;aACD,OAAO,EAAE;;;;;;;;;;;;GAYR;aACD,SAAS,EAAE;;;;;;;;;;;;;;;;;GAiBV;CACO,CAAC;AAWX,wBAAsB,kBAAkB,CACtC,QAAQ,GAAE,sBAA0F,GACnG,OAAO,CAAC,oBAAoB,CAAC,CAS/B;AA8BD,qBAAa,sBAAuB,YAAW,cAAc;;IAG3D,YAAY,OAAO,GAAE,6BAAkC,EAEtD;IAEK,UAAU,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,cAAc,CAAC,CAwE5D;CACF;AAED,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,GAAE,6BAAkC,GAAG,OAAO,CAAC,cAAc,CAAC,CAEjI"}
@@ -0,0 +1,197 @@
1
+ import { defaultPostgresTypePolicy, mapPostgresType } from "./type-policy.js";
2
+ export const postgresCatalogQueries = {
3
+ version: "SELECT current_setting('server_version') AS server_version",
4
+ columns: `
5
+ SELECT
6
+ n.nspname AS schema_name,
7
+ c.relname AS table_name,
8
+ a.attname AS column_name,
9
+ format_type(a.atttypid, a.atttypmod) AS database_type,
10
+ a.attnotnull AS not_null,
11
+ (t.typcategory = 'A') AS is_array,
12
+ pg_get_expr(ad.adbin, ad.adrelid) AS default_expression
13
+ FROM pg_catalog.pg_attribute AS a
14
+ JOIN pg_catalog.pg_class AS c ON c.oid = a.attrelid
15
+ JOIN pg_catalog.pg_namespace AS n ON n.oid = c.relnamespace
16
+ JOIN pg_catalog.pg_type AS t ON t.oid = a.atttypid
17
+ LEFT JOIN pg_catalog.pg_attrdef AS ad ON ad.adrelid = a.attrelid AND ad.adnum = a.attnum
18
+ WHERE a.attnum > 0
19
+ AND NOT a.attisdropped
20
+ AND c.relkind IN ('r', 'p', 'v', 'm', 'f')
21
+ AND n.nspname NOT IN ('pg_catalog', 'information_schema')
22
+ AND n.nspname NOT LIKE 'pg_toast%'
23
+ AND ($1::text[] IS NULL OR n.nspname = ANY($1::text[]))
24
+ ORDER BY n.nspname, c.relname, a.attnum
25
+ `,
26
+ enums: `
27
+ SELECT n.nspname AS schema_name, t.typname AS type_name, e.enumlabel AS enum_label
28
+ FROM pg_catalog.pg_type AS t
29
+ JOIN pg_catalog.pg_namespace AS n ON n.oid = t.typnamespace
30
+ JOIN pg_catalog.pg_enum AS e ON e.enumtypid = t.oid
31
+ WHERE n.nspname NOT IN ('pg_catalog', 'information_schema')
32
+ AND ($1::text[] IS NULL OR n.nspname = ANY($1::text[]))
33
+ ORDER BY n.nspname, t.typname, e.enumsortorder
34
+ `,
35
+ domains: `
36
+ SELECT
37
+ n.nspname AS schema_name,
38
+ t.typname AS domain_name,
39
+ format_type(t.typbasetype, t.typtypmod) AS database_type,
40
+ t.typnotnull AS not_null
41
+ FROM pg_catalog.pg_type AS t
42
+ JOIN pg_catalog.pg_namespace AS n ON n.oid = t.typnamespace
43
+ WHERE t.typtype = 'd'
44
+ AND n.nspname NOT IN ('pg_catalog', 'information_schema')
45
+ AND ($1::text[] IS NULL OR n.nspname = ANY($1::text[]))
46
+ ORDER BY n.nspname, t.typname
47
+ `,
48
+ functions: `
49
+ SELECT
50
+ n.nspname AS schema_name,
51
+ p.proname AS function_name,
52
+ ARRAY(
53
+ SELECT format_type(argument_oid, NULL)
54
+ FROM unnest(p.proargtypes::oid[]) WITH ORDINALITY AS arguments(argument_oid, position)
55
+ ORDER BY position
56
+ ) AS argument_types,
57
+ format_type(p.prorettype, NULL) AS database_return_type,
58
+ p.proretset AS set_returning
59
+ FROM pg_catalog.pg_proc AS p
60
+ JOIN pg_catalog.pg_namespace AS n ON n.oid = p.pronamespace
61
+ WHERE p.prokind = 'f'
62
+ AND n.nspname NOT IN ('pg_catalog', 'information_schema')
63
+ AND ($1::text[] IS NULL OR n.nspname = ANY($1::text[]))
64
+ ORDER BY n.nspname, p.proname, p.oid
65
+ `,
66
+ };
67
+ function qualifiedKey(schema, name) {
68
+ return schema === "public" ? name : `${schema}.${name}`;
69
+ }
70
+ function redactError(error, connectionString) {
71
+ const message = error instanceof Error ? error.message : String(error);
72
+ return new Error(message.replaceAll(connectionString, "[REDACTED_DATABASE_URL]"));
73
+ }
74
+ export async function loadPostgresDriver(importer = async () => await import("pg")) {
75
+ try {
76
+ return await importer();
77
+ }
78
+ catch (error) {
79
+ if (error instanceof Error && "code" in error && error.code === "ERR_MODULE_NOT_FOUND") {
80
+ throw new Error("PostgreSQL introspection requires the application-owned pg driver. Install it with: pnpm add pg", { cause: error });
81
+ }
82
+ throw error;
83
+ }
84
+ }
85
+ async function withConnection(input, options, fn) {
86
+ if (options.client !== undefined)
87
+ return fn(options.client);
88
+ if (input.url === undefined)
89
+ throw new TypeError("PostgreSQL introspection requires SchemaInput.url");
90
+ const pool = options.pool ?? new (await loadPostgresDriver()).Pool({ connectionString: input.url });
91
+ const client = await pool.connect().catch(async (error) => {
92
+ await pool.end();
93
+ throw redactError(error, input.url);
94
+ });
95
+ const queryable = {
96
+ async query(text, values) {
97
+ const result = await client.query(text, values === undefined ? [] : [...values]);
98
+ return { rows: result.rows };
99
+ },
100
+ };
101
+ try {
102
+ await client.query("BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ READ ONLY");
103
+ const result = await fn(queryable);
104
+ await client.query("COMMIT");
105
+ return result;
106
+ }
107
+ catch (error) {
108
+ try {
109
+ await client.query("ROLLBACK");
110
+ }
111
+ catch { /* Preserve the introspection error. */ }
112
+ throw redactError(error, input.url);
113
+ }
114
+ finally {
115
+ client.release();
116
+ await pool.end();
117
+ }
118
+ }
119
+ export class PostgresSchemaProvider {
120
+ #options;
121
+ constructor(options = {}) {
122
+ this.#options = options;
123
+ }
124
+ async introspect(input) {
125
+ return withConnection(input, this.#options, async (client) => {
126
+ const schemaFilter = this.#options.includeSchemas === undefined ? null : [...this.#options.includeSchemas];
127
+ const values = [schemaFilter];
128
+ const [versionResult, enumResult, domainResult, columnResult, functionResult] = await Promise.all([
129
+ client.query(postgresCatalogQueries.version),
130
+ client.query(postgresCatalogQueries.enums, values),
131
+ client.query(postgresCatalogQueries.domains, values),
132
+ client.query(postgresCatalogQueries.columns, values),
133
+ client.query(postgresCatalogQueries.functions, values),
134
+ ]);
135
+ const enums = {};
136
+ for (const row of enumResult.rows)
137
+ (enums[qualifiedKey(row.schema_name, row.type_name)] ??= []).push(row.enum_label);
138
+ const policy = this.#options.typePolicy ?? defaultPostgresTypePolicy;
139
+ const domains = {};
140
+ for (const row of domainResult.rows) {
141
+ const key = qualifiedKey(row.schema_name, row.domain_name);
142
+ domains[key] = {
143
+ name: row.domain_name,
144
+ databaseType: row.database_type,
145
+ tsType: mapPostgresType(row.database_type, policy),
146
+ nullable: !row.not_null,
147
+ };
148
+ }
149
+ const partialSchema = { formatVersion: 1, dialect: "postgres", tables: {}, enums, domains };
150
+ const tables = {};
151
+ for (const row of columnResult.rows) {
152
+ const tableKey = qualifiedKey(row.schema_name, row.table_name);
153
+ const existing = tables[tableKey];
154
+ const columns = existing === undefined ? {} : { ...existing.columns };
155
+ const domain = domains[row.database_type];
156
+ columns[row.column_name] = {
157
+ name: row.column_name,
158
+ databaseType: row.database_type,
159
+ tsType: mapPostgresType(row.database_type, policy, partialSchema),
160
+ nullable: !row.not_null && (domain?.nullable ?? true),
161
+ ...(row.is_array ? { array: true } : {}),
162
+ ...(row.default_expression === null ? {} : { defaultExpression: row.default_expression }),
163
+ };
164
+ tables[tableKey] = { schema: row.schema_name, name: row.table_name, columns };
165
+ }
166
+ const schemaForFunctions = { ...partialSchema, tables };
167
+ const functions = {};
168
+ for (const row of functionResult.rows) {
169
+ const name = qualifiedKey(row.schema_name, row.function_name);
170
+ const key = `${name}(${row.argument_types.join(",")})`;
171
+ functions[key] = {
172
+ name: row.function_name,
173
+ schema: row.schema_name,
174
+ argumentTypes: row.argument_types,
175
+ databaseReturnType: row.database_return_type,
176
+ returnType: mapPostgresType(row.database_return_type, policy, schemaForFunctions),
177
+ nullable: true,
178
+ ...(row.set_returning ? { setReturning: true } : {}),
179
+ };
180
+ }
181
+ const version = versionResult.rows[0]?.server_version;
182
+ return {
183
+ formatVersion: 1,
184
+ dialect: "postgres",
185
+ ...(version === undefined ? {} : { version }),
186
+ tables,
187
+ ...(Object.keys(enums).length === 0 ? {} : { enums }),
188
+ ...(Object.keys(domains).length === 0 ? {} : { domains }),
189
+ ...(Object.keys(functions).length === 0 ? {} : { functions }),
190
+ };
191
+ });
192
+ }
193
+ }
194
+ export async function introspectPostgres(input, options = {}) {
195
+ return new PostgresSchemaProvider(options).introspect(input);
196
+ }
197
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../../../src/provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { SelectStatement, SourceRange, SqlDiagnostic, Statement } from "@typed-sql/ast";
2
+ import type { SchemaSnapshot } from "@typed-sql/schema";
3
+ import { type PostgresTypePolicy } from "./type-policy.js";
4
+ interface ResolvedType {
5
+ readonly tsType: string;
6
+ readonly nullable: boolean;
7
+ readonly databaseType?: string;
8
+ }
9
+ export interface ResolvedColumn extends ResolvedType {
10
+ readonly name: string;
11
+ readonly range: SourceRange;
12
+ }
13
+ export interface ResolvedQuery {
14
+ readonly columns: readonly ResolvedColumn[];
15
+ readonly diagnostics: readonly SqlDiagnostic[];
16
+ readonly resultKind: "rows" | "command";
17
+ }
18
+ export interface ResolveOptions {
19
+ readonly typePolicy?: PostgresTypePolicy;
20
+ readonly strictExpressions?: boolean;
21
+ }
22
+ export declare function resolveStatement(statement: Statement, schema: SchemaSnapshot, options?: ResolveOptions): ResolvedQuery;
23
+ export declare function resolveSelect(statement: SelectStatement, schema: SchemaSnapshot, options?: ResolveOptions): ResolvedQuery;
24
+ export declare function rowTypeLiteral(columns: readonly ResolvedColumn[]): string;
25
+ export {};
26
+ //# sourceMappingURL=resolver.d.ts.map