@typesql/pg 0.0.2 → 0.0.4

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.
Files changed (46) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +23 -2
  3. package/dist/bin.d.ts +3 -0
  4. package/dist/bin.d.ts.map +1 -0
  5. package/dist/bin.js +5 -0
  6. package/dist/bin.js.map +1 -0
  7. package/dist/client.d.ts +5 -2
  8. package/dist/client.d.ts.map +1 -1
  9. package/dist/client.js +10 -3
  10. package/dist/client.js.map +1 -1
  11. package/dist/index.d.ts +8 -2
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +2 -6
  14. package/dist/index.js.map +1 -1
  15. package/dist/introspect/cli.d.ts +24 -0
  16. package/dist/introspect/cli.d.ts.map +1 -0
  17. package/dist/introspect/cli.js +121 -0
  18. package/dist/introspect/cli.js.map +1 -0
  19. package/dist/introspect/emit.d.ts +30 -0
  20. package/dist/introspect/emit.d.ts.map +1 -0
  21. package/dist/introspect/emit.js +144 -0
  22. package/dist/introspect/emit.js.map +1 -0
  23. package/dist/introspect/index.d.ts +5 -0
  24. package/dist/introspect/index.d.ts.map +1 -0
  25. package/dist/introspect/index.js +5 -0
  26. package/dist/introspect/index.js.map +1 -0
  27. package/dist/introspect/introspect.d.ts +67 -0
  28. package/dist/introspect/introspect.d.ts.map +1 -0
  29. package/dist/introspect/introspect.js +109 -0
  30. package/dist/introspect/introspect.js.map +1 -0
  31. package/dist/introspect/nullability.d.ts +60 -0
  32. package/dist/introspect/nullability.d.ts.map +1 -0
  33. package/dist/introspect/nullability.js +354 -0
  34. package/dist/introspect/nullability.js.map +1 -0
  35. package/dist/type-map.d.ts +42 -14
  36. package/dist/type-map.d.ts.map +1 -1
  37. package/package.json +10 -3
  38. package/src/bin.ts +5 -0
  39. package/src/client.ts +10 -4
  40. package/src/index.ts +7 -4
  41. package/src/introspect/cli.ts +138 -0
  42. package/src/introspect/emit.ts +168 -0
  43. package/src/introspect/index.ts +12 -0
  44. package/src/introspect/introspect.ts +221 -0
  45. package/src/introspect/nullability.ts +356 -0
  46. package/src/type-map.ts +42 -14
package/CHANGELOG.md ADDED
@@ -0,0 +1,27 @@
1
+ # @typesql/pg
2
+
3
+ ## 0.0.4
4
+
5
+ ### Patch Changes
6
+
7
+ - An opt-in `PgCatalog` slice types queries on `pg_stat_activity`, `pg_stat_database`, `pg_tables`, `pg_class`, `information_schema.columns` and other system catalogs: `createSql<DB & PgCatalog>()`.
8
+
9
+ - Queries have `executeCount()`, which resolves to the affected row count: an `Executor` may resolve to `{ rows, rowCount }` instead of the rows, as the `executor()` of `@typesql/pg`, `@typesql/postgres` and `@typesql/kysely` now do.
10
+
11
+ - `createSql(executor, { rowKeys: "camelCase" })` (and the adapters' `createSql(client, { rowKeys: "camelCase" })`) camelCases the top-level row keys the way Kysely's `CamelCasePlugin` does, in the row types and in the rows `execute*` and the `query`/`one`/`maybeOne`/`many` helpers return, leaving JSON values untouched.
12
+
13
+ - Rows with `interval` columns are plain object types, so a package that exports them no longer needs `@typesql/pg` as a dependency for declaration emit (TS2883); `PgInterval` stays exported.
14
+
15
+ - The type maps declare what parameters accept (`PgParamTypeMap`, `PostgresJsParamTypeMap`), so `int8`/`numeric` parameters take numbers and bigints and timestamp parameters take strings; postgres.js timestamp parameters also take epoch milliseconds.
16
+
17
+ - `typesql introspect` (a bin of `@typesql/pg`, also `@typesql/pg/introspect`) writes the schema of a live database: exact column types, domains as their base type, enums, arrays, views with nullability read from their definitions, other schemas nested, and `Json<T>` columns for the TypeScript types `columnTypes` gives json / jsonb columns.
18
+
19
+ - Updated dependencies:
20
+ - @typesql/core@0.0.4
21
+
22
+ ## 0.0.3
23
+
24
+ ### Patch Changes
25
+
26
+ - Updated dependencies:
27
+ - @typesql/core@0.0.3
package/README.md CHANGED
@@ -35,20 +35,37 @@ const id = await transaction(pool, async (client) => {
35
35
 
36
36
  | Export | |
37
37
  |---|---|
38
- | `createSql<DB>()` | core's `createSql<DB, PgTypeMap>()` |
38
+ | `createSql<DB>(pool?, options?)` | core's `createSql<DB, PgTypeMap>()`; `{ rowKeys: "camelCase" }` camelCases the row keys |
39
39
  | `query(client, q)` | `Promise<Row[]>` |
40
40
  | `one(client, q)` | `Promise<Row>`; `RowCountError` unless exactly one row |
41
41
  | `maybeOne(client, q)` | `Promise<Row \| null>`; `RowCountError` on more than one row |
42
42
  | `many(client, q)` | `Promise<[Row, ...Row[]]>`; `RowCountError` on zero rows |
43
43
  | `execute(client, q)` | `Promise<number>`, the affected row count |
44
+ | `executor(client)` | an `Executor` for `q.execute()` and `q.executeCount()` (reports `rowCount`); `createSql<DB>(pool)` binds one |
44
45
  | `transaction(pool, fn)` | `BEGIN`, `fn(client)`, `COMMIT`; `ROLLBACK` and rethrow on error |
45
46
  | `migrate(pool, m)` | runs `m.statements` (e.g. from core's `migrations()`) in one transaction |
46
- | `PgTypeMap`, `PgInterval` | the type map, and the `postgres-interval` object type |
47
+ | `PgTypeMap`, `PgParamTypeMap`, `PgInterval` | the type map (rows), what parameters also accept, and the `postgres-interval` object type |
47
48
  | `RowCountError`, `PgQueryable`, `PgPoolLike`, `PgTransactionClient`, `PgResult`, `MigrationSource` | errors and parameter types |
48
49
 
49
50
  `client` is anything with `query(text, values)`: a `Pool`, `Client` or `PoolClient`. The
50
51
  parameters are structural, so fakes work in tests.
51
52
 
53
+ ## `typesql introspect`
54
+
55
+ Generates the schema from a live database: tables, views, materialized views and enums, with
56
+ the exact Postgres type of every column (domains as their base type), nullability, defaults,
57
+ identity and generated columns, other schemas nested, and TypeScript types for JSON columns
58
+ from a config file.
59
+
60
+ ```sh
61
+ pnpm exec typesql introspect --url postgres://localhost/app --out src/db/schema.ts
62
+ pnpm exec typesql introspect --schema public,auth --config typesql.config.ts
63
+ ```
64
+
65
+ The same is available from code as `introspect(client)` and `generateSource(db)` in
66
+ `@typesql/pg/introspect`. See the
67
+ [Introspection guide](https://github.com/ismailkarsli/typesql/blob/main/packages/docs/guide/introspect.md).
68
+
52
69
  ## `PgTypeMap`
53
70
 
54
71
  What `pg`'s default parsers return:
@@ -67,3 +84,7 @@ What `pg`'s default parsers return:
67
84
 
68
85
  Arrays map element-wise. The full table, including the array types `pg` leaves as raw text, is
69
86
  in the [Adapters guide](https://github.com/ismailkarsli/typesql/blob/main/packages/docs/guide/adapters.md).
87
+
88
+ Parameters accept the row type and what `pg` serializes for the type (`PgParamTypeMap`):
89
+ `number | bigint | string` for `int8`, `numeric` and `money`, `Date | string` for dates and
90
+ timestamps, `string` for `interval`, `Uint8Array` for `bytea`.
package/dist/bin.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=bin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":""}
package/dist/bin.js ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ /** `typesql`: `typesql introspect` writes the typesql schema of a live database. */
3
+ import { main } from "./introspect/cli.js";
4
+ process.exitCode = await main(process.argv.slice(2));
5
+ //# sourceMappingURL=bin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,oFAAoF;AACpF,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAE3C,OAAO,CAAC,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC"}
package/dist/client.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Executor, Query, RowType } from "@typesql/core";
1
+ import { type Executor, type Query, type RowType } from "@typesql/core";
2
2
  /** The subset of a `pg` query result the helpers rely on. */
3
3
  export interface PgResult {
4
4
  readonly rows: unknown[];
@@ -29,7 +29,10 @@ export declare class RowCountError extends Error {
29
29
  constructor(code: "NO_ROWS" | "TOO_MANY_ROWS", expected: string, actual: number, text: string);
30
30
  }
31
31
  type AnyQuery = Query<unknown, readonly unknown[]>;
32
- /** An `Executor` for core's `q.execute()`: runs queries on `client` and resolves to the rows. */
32
+ /**
33
+ * An `Executor` for core's `q.execute()`: runs queries on `client` and resolves to
34
+ * `{ rows, rowCount }` (pg's `rowCount`, so `q.executeCount()` works).
35
+ */
33
36
  export declare function executor(client: PgQueryable): Executor;
34
37
  /** Run a query and return all rows, typed from the query. */
35
38
  export declare function query<Q extends AnyQuery>(client: PgQueryable, q: Q): Promise<RowType<Q>[]>;
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,QAAQ,EAAE,KAAK,KAAK,EAAE,KAAK,OAAO,EAAE,MAAM,eAAe,CAAC;AAEjF,6DAA6D;AAC7D,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;CAC5D;AAED,kFAAkF;AAClF,MAAM,WAAW,mBAAoB,SAAQ,WAAW;IACtD,OAAO,CAAC,GAAG,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,IAAI,CAAC;CACtC;AAED,6CAA6C;AAC7C,MAAM,WAAW,UAAU,CAAC,CAAC,SAAS,mBAAmB,GAAG,mBAAmB;IAC7E,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;CACvB;AAED,gFAAgF;AAChF,qBAAa,aAAc,SAAQ,KAAK;IAGpC,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,eAAe;IAC1C,QAAQ,CAAC,QAAQ,EAAE,MAAM;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM;IALvB,SAAkB,IAAI,mBAAmB;IACzC,YACW,IAAI,EAAE,SAAS,GAAG,eAAe,EACjC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EAGtB;CACF;AAED,KAAK,QAAQ,GAAG,KAAK,CAAC,OAAO,EAAE,SAAS,OAAO,EAAE,CAAC,CAAC;AAOnD;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,QAAQ,CAKtD;AAED,6DAA6D;AAC7D,wBAAsB,KAAK,CAAC,CAAC,SAAS,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAGhG;AAED,yDAAyD;AACzD,wBAAsB,GAAG,CAAC,CAAC,SAAS,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAM5F;AAED,kFAAkF;AAClF,wBAAsB,QAAQ,CAAC,CAAC,SAAS,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAIxG;AAED,0DAA0D;AAC1D,wBAAsB,IAAI,CAAC,CAAC,SAAS,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAIhH;AAED,+FAA+F;AAC/F,wBAAsB,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAG/E;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,CAAC,SAAS,mBAAmB,EAAE,CAAC,EAChE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,EACnB,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GAC5B,OAAO,CAAC,CAAC,CAAC,CAoBZ;AAED,oGAAoG;AACpG,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC;AAED;;;;GAIG;AACH,wBAAsB,OAAO,CAAC,CAAC,SAAS,mBAAmB,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAInH"}
package/dist/client.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { mapRows } from "@typesql/core";
1
2
  /** Thrown by `one`, `maybeOne` and `many` when the row count does not match. */
2
3
  export class RowCountError extends Error {
3
4
  code;
@@ -17,14 +18,20 @@ function run(client, q) {
17
18
  // `pg` requires a mutable array (`QueryConfigValues<I>` matches `Array<U>` only).
18
19
  return client.query(q.text, Array.from(q.values));
19
20
  }
20
- /** An `Executor` for core's `q.execute()`: runs queries on `client` and resolves to the rows. */
21
+ /**
22
+ * An `Executor` for core's `q.execute()`: runs queries on `client` and resolves to
23
+ * `{ rows, rowCount }` (pg's `rowCount`, so `q.executeCount()` works).
24
+ */
21
25
  export function executor(client) {
22
- return async (text, values) => (await client.query(text, Array.from(values))).rows;
26
+ return async (text, values) => {
27
+ const { rows, rowCount } = await client.query(text, Array.from(values));
28
+ return { rows, rowCount };
29
+ };
23
30
  }
24
31
  /** Run a query and return all rows, typed from the query. */
25
32
  export async function query(client, q) {
26
33
  const result = await run(client, q);
27
- return result.rows;
34
+ return mapRows(q, result.rows);
28
35
  }
29
36
  /** Exactly one row, otherwise throws `RowCountError`. */
30
37
  export async function one(client, q) {
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AA0BA,gFAAgF;AAChF,MAAM,OAAO,aAAc,SAAQ,KAAK;IAG3B,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,IAAI;IALG,IAAI,GAAG,eAAe,CAAC;IACzC,YACW,IAAiC,EACjC,QAAgB,EAChB,MAAc,EACd,IAAY;QAErB,KAAK,CAAC,YAAY,QAAQ,kCAAkC,MAAM,EAAE,CAAC,CAAC;oBAL7D,IAAI;wBACJ,QAAQ;sBACR,MAAM;oBACN,IAAI;IAGf,CAAC;CACF;AAID,SAAS,GAAG,CAAC,MAAmB,EAAE,CAAW;IAC3C,kFAAkF;IAClF,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AACpD,CAAC;AAED,iGAAiG;AACjG,MAAM,UAAU,QAAQ,CAAC,MAAmB;IAC1C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACrF,CAAC;AAED,6DAA6D;AAC7D,MAAM,CAAC,KAAK,UAAU,KAAK,CAAqB,MAAmB,EAAE,CAAI;IACvE,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACpC,OAAO,MAAM,CAAC,IAAoB,CAAC;AACrC,CAAC;AAED,yDAAyD;AACzD,MAAM,CAAC,KAAK,UAAU,GAAG,CAAqB,MAAmB,EAAE,CAAI;IACrE,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACpC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,aAAa,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,EAAE,WAAW,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IAC7G,CAAC;IACD,OAAO,IAAI,CAAC,CAAC,CAAe,CAAC;AAC/B,CAAC;AAED,kFAAkF;AAClF,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAqB,MAAmB,EAAE,CAAI;IAC1E,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACpC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,IAAI,aAAa,CAAC,eAAe,EAAE,WAAW,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IAChG,OAAO,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAE,IAAI,CAAC,CAAC,CAAgB,CAAC;AAC5D,CAAC;AAED,0DAA0D;AAC1D,MAAM,CAAC,KAAK,UAAU,IAAI,CAAqB,MAAmB,EAAE,CAAI;IACtE,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACpC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,aAAa,CAAC,SAAS,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IACnF,OAAO,IAAqC,CAAC;AAC/C,CAAC;AAED,+FAA+F;AAC/F,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,MAAmB,EAAE,CAAW;IAC5D,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACpC,OAAO,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC;AAC9B,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,IAAmB,EACnB,EAA6B;IAE7B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;IACpC,IAAI,WAA8B,CAAC;IACnC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC5B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC;YAChC,MAAM,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAC7B,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC;gBACH,MAAM,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YACjC,CAAC;YAAC,OAAO,WAAW,EAAE,CAAC;gBACrB,WAAW,GAAG,WAAW,YAAY,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;YAC5F,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC9B,CAAC;AACH,CAAC;AAOD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAgC,IAAmB,EAAE,CAAkB;IAClG,MAAM,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QACvC,KAAK,MAAM,SAAS,IAAI,CAAC,CAAC,UAAU;YAAE,MAAM,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -2,11 +2,17 @@ import { type Sql } from "@typesql/core";
2
2
  import { type PgQueryable } from "./client.js";
3
3
  import type { PgTypeMap } from "./type-map.js";
4
4
  export { NoResultError, type Executor } from "@typesql/core";
5
- export type { PgInterval, PgTypeMap } from "./type-map.js";
5
+ export type { PgInterval, PgParamTypeMap, PgTypeMap } from "./type-map.js";
6
6
  export { query, one, maybeOne, many, execute, executor, transaction, migrate, type MigrationSource, RowCountError, type PgQueryable, type PgResult, type PgTransactionClient, type PgPoolLike, } from "./client.js";
7
7
  /**
8
8
  * `createSql<DB>()` from core, pre-bound to `PgTypeMap` (`count(*)` is `string`, `int8` is `string`, dates are `Date`).
9
9
  * With a `client` (a `Pool`, `Client` or `PoolClient`), the queries' `execute*` methods run on it.
10
+ * `{ rowKeys: "camelCase" }` camelCases the rows' keys, in the types and at runtime.
10
11
  */
11
- export declare function createSql<DB>(client?: PgQueryable): Sql<DB, PgTypeMap>;
12
+ export declare function createSql<DB>(client: PgQueryable | undefined, options: {
13
+ readonly rowKeys: "camelCase";
14
+ }): Sql<DB, PgTypeMap, "camelCase">;
15
+ export declare function createSql<DB>(client?: PgQueryable, options?: {
16
+ readonly rowKeys?: "preserve";
17
+ }): Sql<DB, PgTypeMap>;
12
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,KAAK,GAAG,EAAE,MAAM,eAAe,CAAC;AACrE,OAAO,EAAY,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE/C,OAAO,EAAE,aAAa,EAAE,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC7D,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EACL,KAAK,EACL,GAAG,EACH,QAAQ,EACR,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,WAAW,EACX,OAAO,EACP,KAAK,eAAe,EACpB,aAAa,EACb,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,KAAK,mBAAmB,EACxB,KAAK,UAAU,GAChB,MAAM,aAAa,CAAC;AAErB;;;GAGG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,GAAG,CAAC,EAAE,EAAE,SAAS,CAAC,CAEtE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4C,KAAK,GAAG,EAAmB,MAAM,eAAe,CAAC;AACpG,OAAO,EAAY,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE/C,OAAO,EAAE,aAAa,EAAE,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC7D,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,EACL,KAAK,EACL,GAAG,EACH,QAAQ,EACR,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,WAAW,EACX,OAAO,EACP,KAAK,eAAe,EACpB,aAAa,EACb,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,KAAK,mBAAmB,EACxB,KAAK,UAAU,GAChB,MAAM,aAAa,CAAC;AAErB;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,GAAG,SAAS,EAAE,OAAO,EAAE;IAAE,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;CAAE,GAAG,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;AAC5I,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,UAAU,CAAA;CAAE,GAAG,GAAG,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC"}
package/dist/index.js CHANGED
@@ -2,11 +2,7 @@ import { createSql as createCoreSql } from "@typesql/core";
2
2
  import { executor } from "./client.js";
3
3
  export { NoResultError } from "@typesql/core";
4
4
  export { query, one, maybeOne, many, execute, executor, transaction, migrate, RowCountError, } from "./client.js";
5
- /**
6
- * `createSql<DB>()` from core, pre-bound to `PgTypeMap` (`count(*)` is `string`, `int8` is `string`, dates are `Date`).
7
- * With a `client` (a `Pool`, `Client` or `PoolClient`), the queries' `execute*` methods run on it.
8
- */
9
- export function createSql(client) {
10
- return createCoreSql(client && executor(client));
5
+ export function createSql(client, options) {
6
+ return createCoreSql(client && executor(client), options);
11
7
  }
12
8
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,IAAI,aAAa,EAAY,MAAM,eAAe,CAAC;AACrE,OAAO,EAAE,QAAQ,EAAoB,MAAM,aAAa,CAAC;AAGzD,OAAO,EAAE,aAAa,EAAiB,MAAM,eAAe,CAAC;AAE7D,OAAO,EACL,KAAK,EACL,GAAG,EACH,QAAQ,EACR,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,WAAW,EACX,OAAO,EAEP,aAAa,GAKd,MAAM,aAAa,CAAC;AAErB;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAK,MAAoB;IAChD,OAAO,aAAa,CAAgB,MAAM,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;AAClE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,IAAI,aAAa,EAA2C,MAAM,eAAe,CAAC;AACpG,OAAO,EAAE,QAAQ,EAAoB,MAAM,aAAa,CAAC;AAGzD,OAAO,EAAE,aAAa,EAAiB,MAAM,eAAe,CAAC;AAE7D,OAAO,EACL,KAAK,EACL,GAAG,EACH,QAAQ,EACR,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,WAAW,EACX,OAAO,EAEP,aAAa,GAKd,MAAM,aAAa,CAAC;AASrB,MAAM,UAAU,SAAS,CAAK,MAAoB,EAAE,OAAoB;IACtE,OAAO,aAAa,CAAgB,MAAM,IAAI,QAAQ,CAAC,MAAM,CAAC,EAAE,OAA4C,CAAC,CAAC;AAChH,CAAC"}
@@ -0,0 +1,24 @@
1
+ import type { PgQueryable } from "../client.js";
2
+ import { type GenerateOptions } from "./emit.js";
3
+ import { type IntrospectOptions } from "./introspect.js";
4
+ /** What a `--config` module exports as its default: CLI settings plus every generator option. */
5
+ export interface IntrospectConfig extends GenerateOptions, IntrospectOptions {
6
+ /** Connection string. Default: `--url`, then `$DATABASE_URL`. */
7
+ readonly url?: string;
8
+ /** Output file, relative to the working directory. Default: stdout. */
9
+ readonly out?: string;
10
+ }
11
+ interface Io {
12
+ readonly stdout: (s: string) => void;
13
+ readonly stderr: (s: string) => void;
14
+ readonly env: Readonly<Record<string, string | undefined>>;
15
+ readonly cwd: string;
16
+ /** Opens a client for a connection string; default: a `pg.Client`. */
17
+ readonly connect?: (url: string) => Promise<PgQueryable & {
18
+ end(): Promise<void>;
19
+ }>;
20
+ }
21
+ /** Runs the `typesql` CLI with `argv` (without `node` and the script). Returns the exit code. */
22
+ export declare function main(argv: readonly string[], io?: Io): Promise<number>;
23
+ export {};
24
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/introspect/cli.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAkB,KAAK,eAAe,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EAAc,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAErE,iGAAiG;AACjG,MAAM,WAAW,gBAAiB,SAAQ,eAAe,EAAE,iBAAiB;IAC1E,iEAAiE;IACjE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,uEAAuE;IACvE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;CACvB;AAmBD,UAAU,EAAE;IACV,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;IAC3D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,sEAAsE;IACtE,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,GAAG;QAAE,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,CAAC,CAAC;CACrF;AAqBD,iGAAiG;AACjG,wBAAsB,IAAI,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,EAAE,GAAE,EAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CA2EzF"}
@@ -0,0 +1,121 @@
1
+ import { mkdir, writeFile } from "node:fs/promises";
2
+ import { dirname, resolve } from "node:path";
3
+ import { pathToFileURL } from "node:url";
4
+ import { parseArgs } from "node:util";
5
+ import { generateSource } from "./emit.js";
6
+ import { introspect } from "./introspect.js";
7
+ const USAGE = `Usage: typesql introspect [options]
8
+
9
+ Reads a live Postgres database and writes its typesql schema (tables, views, enums).
10
+
11
+ Options:
12
+ --url <url> connection string (default: $DATABASE_URL)
13
+ --out <file> write the schema to <file> instead of stdout
14
+ --schema <name> schema to read; repeat or comma-separate (default: all but system schemas)
15
+ --exclude <pattern> relation to leave out (name or schema.name, * wildcard); repeat or comma-separate
16
+ --type-name <name> name of the schema interface (default: DB)
17
+ --import-from <mod> module the column helpers come from (default: @typesql/core)
18
+ --config <file> module whose default export holds these options and more
19
+ (columnTypes for JSON columns, imports, column(...) hook)
20
+ --no-comments omit JSDoc from comments, domains and generated columns
21
+ -h, --help show this help
22
+ `;
23
+ const defaultIo = () => ({
24
+ stdout: (s) => process.stdout.write(s),
25
+ stderr: (s) => process.stderr.write(s),
26
+ env: process.env,
27
+ cwd: process.cwd(),
28
+ });
29
+ async function pgConnect(url) {
30
+ let Client;
31
+ try {
32
+ ({ Client } = (await import("pg")).default);
33
+ }
34
+ catch {
35
+ throw new Error('typesql introspect needs the "pg" package: npm install pg');
36
+ }
37
+ const client = new Client({ connectionString: url });
38
+ await client.connect();
39
+ return client;
40
+ }
41
+ /** Runs the `typesql` CLI with `argv` (without `node` and the script). Returns the exit code. */
42
+ export async function main(argv, io = defaultIo()) {
43
+ let parsed;
44
+ try {
45
+ parsed = parseArgs({
46
+ args: [...argv],
47
+ allowPositionals: true,
48
+ options: {
49
+ url: { type: "string" },
50
+ out: { type: "string" },
51
+ schema: { type: "string", multiple: true },
52
+ exclude: { type: "string", multiple: true },
53
+ "type-name": { type: "string" },
54
+ "import-from": { type: "string" },
55
+ config: { type: "string" },
56
+ "no-comments": { type: "boolean" },
57
+ help: { type: "boolean", short: "h" },
58
+ },
59
+ });
60
+ }
61
+ catch (err) {
62
+ io.stderr(`${err.message}\n\n${USAGE}`);
63
+ return 2;
64
+ }
65
+ const { values, positionals } = parsed;
66
+ if (values.help || positionals.length === 0) {
67
+ (values.help ? io.stdout : io.stderr)(USAGE);
68
+ return values.help ? 0 : 2;
69
+ }
70
+ if (positionals[0] !== "introspect" || positionals.length > 1) {
71
+ io.stderr(`unknown command: ${positionals.join(" ")}\n\n${USAGE}`);
72
+ return 2;
73
+ }
74
+ try {
75
+ let config = {};
76
+ if (values.config) {
77
+ const mod = (await import(pathToFileURL(resolve(io.cwd, values.config)).href));
78
+ config = mod.default ?? {};
79
+ }
80
+ const url = values.url ?? config.url ?? io.env["DATABASE_URL"];
81
+ if (!url) {
82
+ io.stderr("typesql introspect: pass --url or set DATABASE_URL\n");
83
+ return 2;
84
+ }
85
+ const list = (v) => v?.flatMap((s) => s.split(",").map((x) => x.trim()).filter(Boolean));
86
+ const schemas = list(values.schema) ?? config.schemas;
87
+ const exclude = list(values.exclude) ?? config.exclude;
88
+ const options = {
89
+ ...config,
90
+ ...(schemas !== undefined && { schemas }),
91
+ ...(exclude !== undefined && { exclude }),
92
+ ...(values["type-name"] !== undefined && { typeName: values["type-name"] }),
93
+ ...(values["import-from"] !== undefined && { importFrom: values["import-from"] }),
94
+ ...(values["no-comments"] && { comments: false }),
95
+ };
96
+ const client = await (io.connect ?? pgConnect)(url);
97
+ let source;
98
+ try {
99
+ source = generateSource(await introspect(client, options), options);
100
+ }
101
+ finally {
102
+ await client.end();
103
+ }
104
+ const out = values.out ?? config.out;
105
+ if (out === undefined) {
106
+ io.stdout(source);
107
+ }
108
+ else {
109
+ const file = resolve(io.cwd, out);
110
+ await mkdir(dirname(file), { recursive: true });
111
+ await writeFile(file, source);
112
+ io.stderr(`typesql introspect: wrote ${out}\n`);
113
+ }
114
+ return 0;
115
+ }
116
+ catch (err) {
117
+ io.stderr(`typesql introspect: ${err.message}\n`);
118
+ return 1;
119
+ }
120
+ }
121
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/introspect/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,EAAE,cAAc,EAAwB,MAAM,WAAW,CAAC;AACjE,OAAO,EAAE,UAAU,EAA0B,MAAM,iBAAiB,CAAC;AAUrE,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;CAeb,CAAC;AAWF,MAAM,SAAS,GAAG,GAAO,EAAE,CAAC,CAAC;IAC3B,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACtC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACtC,GAAG,EAAE,OAAO,CAAC,GAAG;IAChB,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;CACnB,CAAC,CAAC;AAEH,KAAK,UAAU,SAAS,CAAC,GAAW;IAClC,IAAI,MAAkC,CAAC;IACvC,IAAI,CAAC;QACH,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;IAC/E,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAE,gBAAgB,EAAE,GAAG,EAAE,CAAC,CAAC;IACrD,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;IACvB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,iGAAiG;AACjG,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,IAAuB,EAAE,EAAE,GAAO,SAAS,EAAE;IACtE,IAAI,MAAM,CAAC;IACX,IAAI,CAAC;QACH,MAAM,GAAG,SAAS,CAAC;YACjB,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;YACf,gBAAgB,EAAE,IAAI;YACtB,OAAO,EAAE;gBACP,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBACvB,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBACvB,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC1C,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC3C,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBAC/B,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBACjC,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBAC1B,aAAa,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;gBAClC,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE;aACtC;SACF,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,EAAE,CAAC,MAAM,CAAC,GAAI,GAAa,CAAC,OAAO,OAAO,KAAK,EAAE,CAAC,CAAC;QACnD,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC;IACvC,IAAI,MAAM,CAAC,IAAI,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5C,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC;QAC7C,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7B,CAAC;IACD,IAAI,WAAW,CAAC,CAAC,CAAC,KAAK,YAAY,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9D,EAAE,CAAC,MAAM,CAAC,oBAAoB,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,KAAK,EAAE,CAAC,CAAC;QACnE,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,CAAC;QACH,IAAI,MAAM,GAAqB,EAAE,CAAC;QAClC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClB,MAAM,GAAG,GAAG,CAAC,MAAM,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAmC,CAAC;YACjH,MAAM,GAAG,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC;QAC7B,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAC/D,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,EAAE,CAAC,MAAM,CAAC,sDAAsD,CAAC,CAAC;YAClE,OAAO,CAAC,CAAC;QACX,CAAC;QACD,MAAM,IAAI,GAAG,CAAC,CAAuB,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;QAC/G,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC;QACtD,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC;QACvD,MAAM,OAAO,GAAqB;YAChC,GAAG,MAAM;YACT,GAAG,CAAC,OAAO,KAAK,SAAS,IAAI,EAAE,OAAO,EAAE,CAAC;YACzC,GAAG,CAAC,OAAO,KAAK,SAAS,IAAI,EAAE,OAAO,EAAE,CAAC;YACzC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,SAAS,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;YAC3E,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,SAAS,IAAI,EAAE,UAAU,EAAE,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC;YACjF,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;SAClD,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC,OAAO,IAAI,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC;QACpD,IAAI,MAAc,CAAC;QACnB,IAAI,CAAC;YACH,MAAM,GAAG,cAAc,CAAC,MAAM,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC;QACtE,CAAC;gBAAS,CAAC;YACT,MAAM,MAAM,CAAC,GAAG,EAAE,CAAC;QACrB,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,GAAG,CAAC;QACrC,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACtB,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACpB,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,GAAG,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YAClC,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAChD,MAAM,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAC9B,EAAE,CAAC,MAAM,CAAC,6BAA6B,GAAG,IAAI,CAAC,CAAC;QAClD,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,EAAE,CAAC,MAAM,CAAC,uBAAwB,GAAa,CAAC,OAAO,IAAI,CAAC,CAAC;QAC7D,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC"}
@@ -0,0 +1,30 @@
1
+ import type { IntrospectedColumn, IntrospectedDatabase, IntrospectedRelation } from "./introspect.js";
2
+ export interface GenerateOptions {
3
+ /** Name of the exported schema interface. Default `"DB"`. */
4
+ readonly typeName?: string;
5
+ /** Module the column helpers are imported from. Default `"@typesql/core"`. */
6
+ readonly importFrom?: string;
7
+ /** Extra lines after the helper import, e.g. `import type { HistoryItem } from "./json.js";`. */
8
+ readonly imports?: readonly string[];
9
+ /**
10
+ * TypeScript types of `json` / `jsonb` columns: a map keyed `"table.column"` (public) or
11
+ * `"schema.table.column"`, or a function returning the TS type source for a column (or
12
+ * `undefined`). Such a column is declared as `Json<T>`: still jsonb to the SQL, read as `T`,
13
+ * written with `sql.json(value)`. Other columns are an error (use `column` for those).
14
+ */
15
+ readonly columnTypes?: Readonly<Record<string, string>> | ((column: IntrospectedColumn, relation: IntrospectedRelation) => string | undefined);
16
+ /**
17
+ * Full control over one column: return the TypeScript source of its descriptor
18
+ * (`Col<"jsonb">`, a helper of your own, ...) or `undefined` to keep the default.
19
+ */
20
+ readonly column?: (column: IntrospectedColumn, relation: IntrospectedRelation) => string | undefined;
21
+ /** Emit table and column comments and notes as JSDoc. Default `true`. */
22
+ readonly comments?: boolean;
23
+ }
24
+ /**
25
+ * TypeScript source declaring the typesql schema of an introspected database: `public`
26
+ * relations at the top level, other schemas nested (`DB["auth"]["sessions"]`), views and
27
+ * materialized views as `View<…>`, enums under `$types`.
28
+ */
29
+ export declare function generateSource(db: IntrospectedDatabase, options?: GenerateOptions): string;
30
+ //# sourceMappingURL=emit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit.d.ts","sourceRoot":"","sources":["../../src/introspect/emit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEtG,MAAM,WAAW,eAAe;IAC9B,6DAA6D;IAC7D,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,8EAA8E;IAC9E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,iGAAiG;IACjG,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,CAAC,EACjB,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAChC,CAAC,CAAC,MAAM,EAAE,kBAAkB,EAAE,QAAQ,EAAE,oBAAoB,KAAK,MAAM,GAAG,SAAS,CAAC,CAAC;IACzF;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,kBAAkB,EAAE,QAAQ,EAAE,oBAAoB,KAAK,MAAM,GAAG,SAAS,CAAC;IACrG,yEAAyE;IACzE,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AA2BD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,oBAAoB,EAAE,OAAO,GAAE,eAAoB,GAAG,MAAM,CA8G9F"}
@@ -0,0 +1,144 @@
1
+ const IDENT = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
2
+ const key = (name) => (IDENT.test(name) ? name : JSON.stringify(name));
3
+ const str = (s) => JSON.stringify(s);
4
+ function doc(lines, indent) {
5
+ const text = lines.flatMap((l) => l.split("\n")).map((l) => l.replace(/\*\//g, "*\\/").trimEnd());
6
+ if (text.length === 0)
7
+ return "";
8
+ if (text.length === 1)
9
+ return `${indent}/** ${text[0]} */\n`;
10
+ return `${indent}/**\n${text.map((l) => `${indent} *${l ? ` ${l}` : ""}`).join("\n")}\n${indent} */\n`;
11
+ }
12
+ const helperFor = (nullable, hasDefault) => nullable ? (hasDefault ? "NullableGenerated" : "Nullable") : hasDefault ? "Generated" : "Col";
13
+ function columnNotes(c) {
14
+ const notes = [];
15
+ if (c.comment)
16
+ notes.push(c.comment);
17
+ if (c.domain)
18
+ notes.push(`Domain \`${c.domain}\`.`);
19
+ else if (c.declaredType === "citext")
20
+ notes.push("`citext`: typed as `text`.");
21
+ if (c.generated !== null)
22
+ notes.push(`\`GENERATED ALWAYS AS (${c.generated}) STORED\`: cannot be written.`);
23
+ if (c.identity === "always")
24
+ notes.push("`GENERATED ALWAYS AS IDENTITY`: written only with `OVERRIDING SYSTEM VALUE`.");
25
+ return notes;
26
+ }
27
+ /**
28
+ * TypeScript source declaring the typesql schema of an introspected database: `public`
29
+ * relations at the top level, other schemas nested (`DB["auth"]["sessions"]`), views and
30
+ * materialized views as `View<…>`, enums under `$types`.
31
+ */
32
+ export function generateSource(db, options = {}) {
33
+ const typeName = options.typeName ?? "DB";
34
+ const comments = options.comments ?? true;
35
+ const columnTypes = options.columnTypes ?? {};
36
+ const used = new Set();
37
+ const usedKeys = new Set();
38
+ /** The TS type `columnTypes` gives a column, if any. */
39
+ const customType = (rel, col) => {
40
+ const qualified = `${rel.schema}.${rel.name}.${col.name}`;
41
+ const short = `${rel.name}.${col.name}`;
42
+ let ts;
43
+ if (typeof columnTypes === "function")
44
+ ts = columnTypes(col, rel);
45
+ else {
46
+ const k = qualified in columnTypes ? qualified : rel.schema === "public" && short in columnTypes ? short : undefined;
47
+ if (k !== undefined) {
48
+ usedKeys.add(k);
49
+ ts = columnTypes[k];
50
+ }
51
+ }
52
+ if (ts !== undefined && col.type !== "json" && col.type !== "jsonb") {
53
+ throw new Error(`columnTypes: ${JSON.stringify(rel.schema === "public" ? short : qualified)} has type ${col.type}; columnTypes only types json / jsonb columns (use the column hook for others)`);
54
+ }
55
+ return ts;
56
+ };
57
+ /** `Json<T>`, `Json<T, { nullable: true }>`, `Json<T, {}, "json">`, … */
58
+ const jsonDescriptor = (col, ts) => {
59
+ const flags = [...(col.nullable ? ["nullable: true"] : []), ...(col.hasDefault ? ["hasDefault: true"] : [])];
60
+ const flagSource = flags.length > 0 ? `{ ${flags.join("; ")} }` : "{}";
61
+ used.add("Json");
62
+ if (col.type === "json")
63
+ return `Json<${ts}, ${flagSource}, "json">`;
64
+ return flags.length > 0 ? `Json<${ts}, ${flagSource}>` : `Json<${ts}>`;
65
+ };
66
+ const relation = (rel, indent) => {
67
+ const isView = rel.kind === "view" || rel.kind === "materialized view";
68
+ const cols = rel.columns.map((c) => {
69
+ let descriptor = options.column?.(c, rel);
70
+ if (descriptor === undefined) {
71
+ const custom = customType(rel, c);
72
+ if (custom !== undefined)
73
+ descriptor = jsonDescriptor(c, custom);
74
+ else {
75
+ const helper = helperFor(c.nullable, c.hasDefault);
76
+ used.add(helper);
77
+ descriptor = `${helper}<${str(c.type)}>`;
78
+ }
79
+ }
80
+ return `${comments ? doc(columnNotes(c), `${indent} `) : ""}${indent} ${key(c.name)}: ${descriptor};`;
81
+ });
82
+ const body = `{\n${cols.join("\n")}\n${indent}}`;
83
+ if (!isView)
84
+ return body;
85
+ used.add("View");
86
+ return `View<${body}>`;
87
+ };
88
+ const relDoc = (rel, indent) => {
89
+ if (!comments)
90
+ return "";
91
+ const kind = rel.kind === "table" ? [] : [`${rel.kind[0].toUpperCase()}${rel.kind.slice(1)}.`];
92
+ return doc([...(rel.comment ? [rel.comment] : []), ...kind], indent);
93
+ };
94
+ const topLevel = new Set(db.relations.filter((r) => r.schema === "public").map((r) => r.name));
95
+ const lines = [];
96
+ const namespaces = new Map();
97
+ for (const rel of db.relations) {
98
+ if (rel.schema === "public")
99
+ lines.push(`${relDoc(rel, " ")} ${key(rel.name)}: ${relation(rel, " ")};`);
100
+ else
101
+ namespaces.set(rel.schema, [...(namespaces.get(rel.schema) ?? []), rel]);
102
+ }
103
+ for (const [schema, rels] of namespaces) {
104
+ if (topLevel.has(schema)) {
105
+ throw new Error(`schema "${schema}" has the same name as the table "public.${schema}": typesql keeps public relations and schemas in one object`);
106
+ }
107
+ const body = rels.map((r) => `${relDoc(r, " ")} ${key(r.name)}: ${relation(r, " ")};`);
108
+ lines.push(` ${key(schema)}: {\n${body.join("\n")}\n };`);
109
+ }
110
+ if (db.enums.length > 0) {
111
+ // typesql's enum registry is flat (`Col<"mood">`, schema qualifiers are dropped), so enums
112
+ // of the same name in different schemas share an entry.
113
+ const byName = new Map();
114
+ for (const e of db.enums) {
115
+ const entry = byName.get(e.name) ?? { values: new Set(), schemas: [] };
116
+ for (const v of e.values)
117
+ entry.values.add(v);
118
+ entry.schemas.push(e.schema);
119
+ byName.set(e.name, entry);
120
+ }
121
+ const entries = [...byName].map(([name, { values, schemas }]) => {
122
+ const notes = comments && schemas.length > 1 ? doc([`Enums of the same name in ${schemas.map((s) => `\`${s}\``).join(", ")}.`], " ") : "";
123
+ return `${notes} ${key(name)}: ${[...values].map(str).join(" | ") || "never"};`;
124
+ });
125
+ lines.push(` $types: {\n${entries.join("\n")}\n };`);
126
+ }
127
+ const helpers = ["Col", "Generated", "Json", "Nullable", "NullableGenerated", "View"].filter((h) => used.has(h));
128
+ const out = [
129
+ `// Generated by \`typesql introspect\` (@typesql/pg) from PostgreSQL ${db.version.split(/[.\s]/)[0]}. Do not edit.`,
130
+ ...(helpers.length > 0 ? [`import type { ${helpers.join(", ")} } from ${str(options.importFrom ?? "@typesql/core")};`] : []),
131
+ ...(options.imports ?? []),
132
+ "",
133
+ `export interface ${key(typeName)} {`,
134
+ ...lines,
135
+ "}",
136
+ "",
137
+ ];
138
+ const unknownKeys = typeof columnTypes === "function" ? [] : Object.keys(columnTypes).filter((k) => !usedKeys.has(k));
139
+ if (unknownKeys.length > 0 && options.column === undefined) {
140
+ throw new Error(`columnTypes: no column ${unknownKeys.map((k) => JSON.stringify(k)).join(", ")} (keys are "table.column" for public tables, else "schema.table.column")`);
141
+ }
142
+ return out.join("\n");
143
+ }
144
+ //# sourceMappingURL=emit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit.js","sourceRoot":"","sources":["../../src/introspect/emit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { introspect, type IntrospectOptions, type IntrospectedDatabase, type IntrospectedRelation, type IntrospectedColumn, type IntrospectedEnum, type RelationKind, } from "./introspect.js";
2
+ export { generateSource, type GenerateOptions } from "./emit.js";
3
+ export { ViewNullability, parseNodeTree, type NullabilityOptions, type QueryFn } from "./nullability.js";
4
+ export { main, type IntrospectConfig } from "./cli.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/introspect/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,YAAY,GAClB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,cAAc,EAAE,KAAK,eAAe,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,KAAK,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACzG,OAAO,EAAE,IAAI,EAAE,KAAK,gBAAgB,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { introspect, } from "./introspect.js";
2
+ export { generateSource } from "./emit.js";
3
+ export { ViewNullability, parseNodeTree } from "./nullability.js";
4
+ export { main } from "./cli.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/introspect/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,GAOX,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,cAAc,EAAwB,MAAM,WAAW,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,aAAa,EAAyC,MAAM,kBAAkB,CAAC;AACzG,OAAO,EAAE,IAAI,EAAyB,MAAM,UAAU,CAAC"}