@typesql/pg 0.0.3 → 0.1.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 +32 -0
- package/README.md +41 -23
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +5 -0
- package/dist/bin.js.map +1 -0
- package/dist/client.d.ts +7 -29
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +44 -73
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +15 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -9
- package/dist/index.js.map +1 -1
- package/dist/introspect/cli.d.ts +24 -0
- package/dist/introspect/cli.d.ts.map +1 -0
- package/dist/introspect/cli.js +121 -0
- package/dist/introspect/cli.js.map +1 -0
- package/dist/introspect/emit.d.ts +30 -0
- package/dist/introspect/emit.d.ts.map +1 -0
- package/dist/introspect/emit.js +144 -0
- package/dist/introspect/emit.js.map +1 -0
- package/dist/introspect/index.d.ts +5 -0
- package/dist/introspect/index.d.ts.map +1 -0
- package/dist/introspect/index.js +5 -0
- package/dist/introspect/index.js.map +1 -0
- package/dist/introspect/introspect.d.ts +67 -0
- package/dist/introspect/introspect.d.ts.map +1 -0
- package/dist/introspect/introspect.js +109 -0
- package/dist/introspect/introspect.js.map +1 -0
- package/dist/introspect/nullability.d.ts +60 -0
- package/dist/introspect/nullability.d.ts.map +1 -0
- package/dist/introspect/nullability.js +354 -0
- package/dist/introspect/nullability.js.map +1 -0
- package/dist/type-map.d.ts +42 -14
- package/dist/type-map.d.ts.map +1 -1
- package/package.json +10 -3
- package/src/bin.ts +5 -0
- package/src/client.ts +45 -77
- package/src/index.ts +14 -14
- package/src/introspect/cli.ts +138 -0
- package/src/introspect/emit.ts +168 -0
- package/src/introspect/index.ts +12 -0
- package/src/introspect/introspect.ts +221 -0
- package/src/introspect/nullability.ts +356 -0
- package/src/type-map.ts +42 -14
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
# @typesql/pg
|
|
2
2
|
|
|
3
|
+
## 0.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Queries run from the `sql` bound to your client: `createSql<DB>(client)` then `sql("…").execute()` (or `executeTakeFirst`, `executeTakeFirstOrThrow`, `executeCount`), and `sql.transaction(async (tx) => …)` for transactions, nested with savepoints; the `query`, `one`, `maybeOne`, `many`, `execute`, `transaction` and `RowCountError` exports of `@typesql/pg` and `@typesql/postgres`, `query` and `execute` of `@typesql/kysely`, and `queryRaw` and `executeRaw` of `@typesql/prisma` are removed.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- The README links to the type map tables on the new node-postgres and postgres.js adapter pages of the docs.
|
|
12
|
+
|
|
13
|
+
- Updated dependencies:
|
|
14
|
+
- @typesql/core@0.1.0
|
|
15
|
+
|
|
16
|
+
## 0.0.4
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- 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>()`.
|
|
21
|
+
|
|
22
|
+
- 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.
|
|
23
|
+
|
|
24
|
+
- `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.
|
|
25
|
+
|
|
26
|
+
- 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.
|
|
27
|
+
|
|
28
|
+
- 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.
|
|
29
|
+
|
|
30
|
+
- `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.
|
|
31
|
+
|
|
32
|
+
- Updated dependencies:
|
|
33
|
+
- @typesql/core@0.0.4
|
|
34
|
+
|
|
3
35
|
## 0.0.3
|
|
4
36
|
|
|
5
37
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[node-postgres](https://node-postgres.com) (`pg` 8.x) adapter for
|
|
4
4
|
[`@typesql/core`](https://www.npmjs.com/package/@typesql/core): a `createSql` bound to the type
|
|
5
|
-
map of `pg`'s default parsers,
|
|
5
|
+
map of `pg`'s default parsers, whose queries run on your pool and return rows typed from the SQL.
|
|
6
6
|
|
|
7
7
|
```sh
|
|
8
8
|
pnpm add @typesql/core @typesql/pg pg
|
|
@@ -12,21 +12,20 @@ pnpm add @typesql/core @typesql/pg pg
|
|
|
12
12
|
|
|
13
13
|
```ts
|
|
14
14
|
import { Pool } from "pg";
|
|
15
|
-
import { createSql
|
|
15
|
+
import { createSql } from "@typesql/pg";
|
|
16
16
|
import type { DB } from "./schema";
|
|
17
17
|
|
|
18
18
|
const pool = new Pool();
|
|
19
|
-
const sql = createSql<DB>();
|
|
19
|
+
const sql = createSql<DB>(pool);
|
|
20
20
|
|
|
21
|
-
const users = await
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
const changed = await execute(pool, sql("UPDATE users SET display_name = NULL")); // row count
|
|
21
|
+
const users = await sql("SELECT id, email FROM users").execute(); // { id: number; email: string }[]
|
|
22
|
+
const maybe = await sql("SELECT id FROM users WHERE email = $1", "x").executeTakeFirst(); // row | undefined
|
|
23
|
+
const user = await sql("SELECT id, email FROM users WHERE id = $1", 7).executeTakeFirstOrThrow(); // row, or NoResultError
|
|
24
|
+
const changed = await sql("UPDATE users SET display_name = NULL").executeCount(); // row count
|
|
26
25
|
|
|
27
|
-
const id = await transaction(
|
|
28
|
-
const { id } = await
|
|
29
|
-
await
|
|
26
|
+
const id = await sql.transaction(async (tx) => {
|
|
27
|
+
const { id } = await tx("INSERT INTO users (email) VALUES ($1) RETURNING id", "a@b.c").executeTakeFirstOrThrow();
|
|
28
|
+
await tx("INSERT INTO posts (author_id, title) VALUES ($1, $2)", id, "Hello").execute();
|
|
30
29
|
return id;
|
|
31
30
|
});
|
|
32
31
|
```
|
|
@@ -35,19 +34,34 @@ const id = await transaction(pool, async (client) => {
|
|
|
35
34
|
|
|
36
35
|
| Export | |
|
|
37
36
|
|---|---|
|
|
38
|
-
| `createSql<DB>()` | core's `createSql<DB, PgTypeMap>()` |
|
|
39
|
-
| `
|
|
40
|
-
| `
|
|
41
|
-
| `
|
|
42
|
-
| `many(client, q)` | `Promise<[Row, ...Row[]]>`; `RowCountError` on zero rows |
|
|
43
|
-
| `execute(client, q)` | `Promise<number>`, the affected row count |
|
|
44
|
-
| `transaction(pool, fn)` | `BEGIN`, `fn(client)`, `COMMIT`; `ROLLBACK` and rethrow on error |
|
|
37
|
+
| `createSql<DB>(client, options?)` | core's `createSql<DB, PgTypeMap>()` with the queries running on `client` (a `Pool`, `Client` or `PoolClient`); `{ rowKeys: "camelCase" }` camelCases the row keys |
|
|
38
|
+
| `q.execute()`, `q.executeTakeFirst()`, `q.executeTakeFirstOrThrow()`, `q.executeCount()` | `Promise<Row[]>`, `Promise<Row \| undefined>`, `Promise<Row>` (`NoResultError` on 0 rows), `Promise<number>` (`rowCount`) |
|
|
39
|
+
| `sql.transaction(fn)` | on a `Pool`: checks out a client, `BEGIN`, `fn(tx)`, `COMMIT`, releases it; `ROLLBACK` and rethrow on error. On a `Client` or `PoolClient`: the same on that connection. `tx` is `sql` bound to the transaction; `tx.transaction(fn)` uses a savepoint |
|
|
40
|
+
| `executor(client)` | an `Executor` for `q.execute(executor)` and core's `createSql(executor)` (reports `rowCount`) |
|
|
45
41
|
| `migrate(pool, m)` | runs `m.statements` (e.g. from core's `migrations()`) in one transaction |
|
|
46
|
-
| `
|
|
47
|
-
| `
|
|
42
|
+
| `PgSql<DB, Keys>` | the type `createSql` returns |
|
|
43
|
+
| `PgTypeMap`, `PgParamTypeMap`, `PgInterval` | the type map (rows), what parameters also accept, and the `postgres-interval` object type |
|
|
44
|
+
| `NoResultError`, `PgQueryable`, `PgPoolLike`, `PgTransactionClient`, `PgResult`, `MigrationSource` | errors and parameter types |
|
|
48
45
|
|
|
49
|
-
`client` is anything with `query(text, values)
|
|
50
|
-
|
|
46
|
+
`client` is anything with `query(text, values)`. The parameters are structural, so fakes work
|
|
47
|
+
in tests. If the `ROLLBACK` of a pool transaction fails, the client is released with the error
|
|
48
|
+
so the pool discards the connection.
|
|
49
|
+
|
|
50
|
+
## `typesql introspect`
|
|
51
|
+
|
|
52
|
+
Generates the schema from a live database: tables, views, materialized views and enums, with
|
|
53
|
+
the exact Postgres type of every column (domains as their base type), nullability, defaults,
|
|
54
|
+
identity and generated columns, other schemas nested, and TypeScript types for JSON columns
|
|
55
|
+
from a config file.
|
|
56
|
+
|
|
57
|
+
```sh
|
|
58
|
+
pnpm exec typesql introspect --url postgres://localhost/app --out src/db/schema.ts
|
|
59
|
+
pnpm exec typesql introspect --schema public,auth --config typesql.config.ts
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
The same is available from code as `introspect(client)` and `generateSource(db)` in
|
|
63
|
+
`@typesql/pg/introspect`. See the
|
|
64
|
+
[Introspection guide](https://github.com/ismailkarsli/typesql/blob/main/packages/docs/guide/introspect.md).
|
|
51
65
|
|
|
52
66
|
## `PgTypeMap`
|
|
53
67
|
|
|
@@ -66,4 +80,8 @@ What `pg`'s default parsers return:
|
|
|
66
80
|
| text-like and other types | `string` |
|
|
67
81
|
|
|
68
82
|
Arrays map element-wise. The full table, including the array types `pg` leaves as raw text, is
|
|
69
|
-
|
|
83
|
+
on the [node-postgres adapter page](https://github.com/ismailkarsli/typesql/blob/main/packages/docs/adapters/pg.md).
|
|
84
|
+
|
|
85
|
+
Parameters accept the row type and what `pg` serializes for the type (`PgParamTypeMap`):
|
|
86
|
+
`number | bigint | string` for `int8`, `numeric` and `money`, `Date | string` for dates and
|
|
87
|
+
timestamps, `string` for `interval`, `Uint8Array` for `bytea`.
|
package/dist/bin.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":""}
|
package/dist/bin.js
ADDED
package/dist/bin.js.map
ADDED
|
@@ -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,5 +1,5 @@
|
|
|
1
|
-
import type
|
|
2
|
-
/** The subset of a `pg` query result the
|
|
1
|
+
import { type Executor, type SqlDriver } from "@typesql/core";
|
|
2
|
+
/** The subset of a `pg` query result the adapter relies on. */
|
|
3
3
|
export interface PgResult {
|
|
4
4
|
readonly rows: unknown[];
|
|
5
5
|
readonly rowCount: number | null;
|
|
@@ -19,34 +19,13 @@ export interface PgTransactionClient extends PgQueryable {
|
|
|
19
19
|
export interface PgPoolLike<C extends PgTransactionClient = PgTransactionClient> {
|
|
20
20
|
connect(): Promise<C>;
|
|
21
21
|
}
|
|
22
|
-
/** Thrown by `one`, `maybeOne` and `many` when the row count does not match. */
|
|
23
|
-
export declare class RowCountError extends Error {
|
|
24
|
-
readonly code: "NO_ROWS" | "TOO_MANY_ROWS";
|
|
25
|
-
readonly expected: string;
|
|
26
|
-
readonly actual: number;
|
|
27
|
-
readonly text: string;
|
|
28
|
-
readonly name = "RowCountError";
|
|
29
|
-
constructor(code: "NO_ROWS" | "TOO_MANY_ROWS", expected: string, actual: number, text: string);
|
|
30
|
-
}
|
|
31
|
-
type AnyQuery = Query<unknown, readonly unknown[]>;
|
|
32
|
-
/** An `Executor` for core's `q.execute()`: runs queries on `client` and resolves to the rows. */
|
|
33
|
-
export declare function executor(client: PgQueryable): Executor;
|
|
34
|
-
/** Run a query and return all rows, typed from the query. */
|
|
35
|
-
export declare function query<Q extends AnyQuery>(client: PgQueryable, q: Q): Promise<RowType<Q>[]>;
|
|
36
|
-
/** Exactly one row, otherwise throws `RowCountError`. */
|
|
37
|
-
export declare function one<Q extends AnyQuery>(client: PgQueryable, q: Q): Promise<RowType<Q>>;
|
|
38
|
-
/** Zero or one row (`null` for zero); throws `RowCountError` on more than one. */
|
|
39
|
-
export declare function maybeOne<Q extends AnyQuery>(client: PgQueryable, q: Q): Promise<RowType<Q> | null>;
|
|
40
|
-
/** At least one row, otherwise throws `RowCountError`. */
|
|
41
|
-
export declare function many<Q extends AnyQuery>(client: PgQueryable, q: Q): Promise<[RowType<Q>, ...RowType<Q>[]]>;
|
|
42
|
-
/** Run a statement for its side effect and return the affected row count (`rowCount ?? 0`). */
|
|
43
|
-
export declare function execute(client: PgQueryable, q: AnyQuery): Promise<number>;
|
|
44
22
|
/**
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
* discards the connection instead of reusing it.
|
|
23
|
+
* An `Executor` for core's `q.execute()`: runs queries on `client` and resolves to
|
|
24
|
+
* `{ rows, rowCount }` (pg's `rowCount`, so `q.executeCount()` works).
|
|
48
25
|
*/
|
|
49
|
-
export declare function
|
|
26
|
+
export declare function executor(client: PgQueryable): Executor;
|
|
27
|
+
/** How `createSql(client)` runs queries and transactions. */
|
|
28
|
+
export declare const driver: SqlDriver<PgQueryable>;
|
|
50
29
|
/** Anything carrying an ordered list of DDL statements, e.g. a `migrations()` builder from core. */
|
|
51
30
|
export interface MigrationSource {
|
|
52
31
|
readonly statements: readonly string[];
|
|
@@ -57,5 +36,4 @@ export interface MigrationSource {
|
|
|
57
36
|
* with `$$`-quoted function bodies work.
|
|
58
37
|
*/
|
|
59
38
|
export declare function migrate<C extends PgTransactionClient>(pool: PgPoolLike<C>, m: MigrationSource): Promise<void>;
|
|
60
|
-
export {};
|
|
61
39
|
//# sourceMappingURL=client.d.ts.map
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AAE9E,+DAA+D;AAC/D,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;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,QAAQ,CAMtD;AA6CD,6DAA6D;AAC7D,eAAO,MAAM,MAAM,EAAE,SAAS,CAAC,WAAW,CAA6B,CAAC;AAExE,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,94 +1,65 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
text;
|
|
7
|
-
name = "RowCountError";
|
|
8
|
-
constructor(code, expected, actual, text) {
|
|
9
|
-
super(`Expected ${expected} row(s) but the query returned ${actual}`);
|
|
10
|
-
this.code = code;
|
|
11
|
-
this.expected = expected;
|
|
12
|
-
this.actual = actual;
|
|
13
|
-
this.text = text;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
function run(client, q) {
|
|
17
|
-
// `pg` requires a mutable array (`QueryConfigValues<I>` matches `Array<U>` only).
|
|
18
|
-
return client.query(q.text, Array.from(q.values));
|
|
19
|
-
}
|
|
20
|
-
/** An `Executor` for core's `q.execute()`: runs queries on `client` and resolves to the rows. */
|
|
1
|
+
import { runTransaction } from "@typesql/core";
|
|
2
|
+
/**
|
|
3
|
+
* An `Executor` for core's `q.execute()`: runs queries on `client` and resolves to
|
|
4
|
+
* `{ rows, rowCount }` (pg's `rowCount`, so `q.executeCount()` works).
|
|
5
|
+
*/
|
|
21
6
|
export function executor(client) {
|
|
22
|
-
return async (text, values) =>
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
return result.rows;
|
|
7
|
+
return async (text, values) => {
|
|
8
|
+
// `pg` requires a mutable array (`QueryConfigValues<I>` matches `Array<U>` only).
|
|
9
|
+
const { rows, rowCount } = await client.query(text, Array.from(values));
|
|
10
|
+
return { rows, rowCount };
|
|
11
|
+
};
|
|
28
12
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
if (rows.length !== 1) {
|
|
33
|
-
throw new RowCountError(rows.length === 0 ? "NO_ROWS" : "TOO_MANY_ROWS", "exactly 1", rows.length, q.text);
|
|
34
|
-
}
|
|
35
|
-
return rows[0];
|
|
13
|
+
function isPool(client) {
|
|
14
|
+
// `pg.Client` has `connect()` too (it opens the socket), and `processID`; a `PoolClient` has `release()`.
|
|
15
|
+
return typeof client.connect === "function" && !("release" in client) && !("processID" in client);
|
|
36
16
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const rows = await query(client, q);
|
|
40
|
-
if (rows.length > 1)
|
|
41
|
-
throw new RowCountError("TOO_MANY_ROWS", "at most 1", rows.length, q.text);
|
|
42
|
-
return rows.length === 0 ? null : rows[0];
|
|
43
|
-
}
|
|
44
|
-
/** At least one row, otherwise throws `RowCountError`. */
|
|
45
|
-
export async function many(client, q) {
|
|
46
|
-
const rows = await query(client, q);
|
|
47
|
-
if (rows.length === 0)
|
|
48
|
-
throw new RowCountError("NO_ROWS", "at least 1", 0, q.text);
|
|
49
|
-
return rows;
|
|
50
|
-
}
|
|
51
|
-
/** Run a statement for its side effect and return the affected row count (`rowCount ?? 0`). */
|
|
52
|
-
export async function execute(client, q) {
|
|
53
|
-
const result = await run(client, q);
|
|
54
|
-
return result.rowCount ?? 0;
|
|
17
|
+
function isConnection(client) {
|
|
18
|
+
return "release" in client || "processID" in client;
|
|
55
19
|
}
|
|
20
|
+
const on = (c) => (statement) => c.query(statement);
|
|
56
21
|
/**
|
|
57
|
-
* Check out a client, run `fn`
|
|
58
|
-
*
|
|
59
|
-
* discards the connection instead of reusing it.
|
|
22
|
+
* Check out a client, run `fn` with it between `BEGIN` and `COMMIT`, and release it, with the
|
|
23
|
+
* error when `ROLLBACK` fails so the pool discards the connection instead of reusing it.
|
|
60
24
|
*/
|
|
61
|
-
|
|
62
|
-
const
|
|
25
|
+
async function inPoolTransaction(pool, fn) {
|
|
26
|
+
const conn = await pool.connect();
|
|
63
27
|
let releaseWith;
|
|
64
28
|
try {
|
|
65
|
-
await
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
catch (err) {
|
|
72
|
-
try {
|
|
73
|
-
await client.query("ROLLBACK");
|
|
74
|
-
}
|
|
75
|
-
catch (rollbackErr) {
|
|
76
|
-
releaseWith = rollbackErr instanceof Error ? rollbackErr : new Error(String(rollbackErr));
|
|
77
|
-
}
|
|
78
|
-
throw err;
|
|
79
|
-
}
|
|
29
|
+
return await runTransaction(on(conn), () => fn(conn), {
|
|
30
|
+
onRollbackError: (err) => {
|
|
31
|
+
releaseWith = err instanceof Error ? err : new Error(String(err));
|
|
32
|
+
},
|
|
33
|
+
});
|
|
80
34
|
}
|
|
81
35
|
finally {
|
|
82
|
-
|
|
36
|
+
conn.release(releaseWith);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Run `fn` inside a transaction: on a pool, on a client checked out of it; on a `Client` or
|
|
41
|
+
* `PoolClient`, on that connection. With `depth > 0` the client is already in a transaction,
|
|
42
|
+
* and `fn` runs in a savepoint.
|
|
43
|
+
*/
|
|
44
|
+
function transaction(client, depth, fn) {
|
|
45
|
+
if (depth > 0)
|
|
46
|
+
return runTransaction(on(client), () => fn(client), { savepoint: `typesql_${depth}` });
|
|
47
|
+
if (isPool(client))
|
|
48
|
+
return inPoolTransaction(client, fn);
|
|
49
|
+
if (!isConnection(client)) {
|
|
50
|
+
return Promise.reject(new Error("typesql: sql.transaction() needs a pg Pool, Client or PoolClient, so that BEGIN and COMMIT reach one connection"));
|
|
83
51
|
}
|
|
52
|
+
return runTransaction(on(client), () => fn(client));
|
|
84
53
|
}
|
|
54
|
+
/** How `createSql(client)` runs queries and transactions. */
|
|
55
|
+
export const driver = { executor, transaction };
|
|
85
56
|
/**
|
|
86
57
|
* Run a migration's statements in order on one connection, inside a single transaction
|
|
87
58
|
* (all or nothing). Statements are sent as simple queries without parameters, so scripts
|
|
88
59
|
* with `$$`-quoted function bodies work.
|
|
89
60
|
*/
|
|
90
61
|
export async function migrate(pool, m) {
|
|
91
|
-
await
|
|
62
|
+
await inPoolTransaction(pool, async (client) => {
|
|
92
63
|
for (const statement of m.statements)
|
|
93
64
|
await client.query(statement);
|
|
94
65
|
});
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,21 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type RowKeys, type TransactionalSql } from "@typesql/core";
|
|
2
2
|
import { type PgQueryable } from "./client.js";
|
|
3
3
|
import type { PgTypeMap } from "./type-map.js";
|
|
4
|
-
export { NoResultError, type Executor } from "@typesql/core";
|
|
5
|
-
export type { PgInterval, PgTypeMap } from "./type-map.js";
|
|
6
|
-
export {
|
|
4
|
+
export { NoResultError, type Executor, type TransactionalSql } from "@typesql/core";
|
|
5
|
+
export type { PgInterval, PgParamTypeMap, PgTypeMap } from "./type-map.js";
|
|
6
|
+
export { executor, migrate, type MigrationSource, type PgQueryable, type PgResult, type PgTransactionClient, type PgPoolLike, } from "./client.js";
|
|
7
|
+
/** What `createSql<DB>(client)` returns: core's `Sql` under `PgTypeMap`, with `transaction(fn)`. */
|
|
8
|
+
export type PgSql<DB, Keys extends RowKeys = "preserve"> = TransactionalSql<DB, PgTypeMap, Keys>;
|
|
7
9
|
/**
|
|
8
10
|
* `createSql<DB>()` from core, pre-bound to `PgTypeMap` (`count(*)` is `string`, `int8` is `string`, dates are `Date`).
|
|
9
|
-
*
|
|
11
|
+
* The queries' `execute*` methods run on `client` (a `Pool`, `Client` or `PoolClient`), and
|
|
12
|
+
* `sql.transaction(fn)` runs `fn` with a `sql` bound to one transaction.
|
|
13
|
+
* `{ rowKeys: "camelCase" }` camelCases the rows' keys, in the types and at runtime.
|
|
10
14
|
*/
|
|
11
|
-
export declare function createSql<DB>(client
|
|
15
|
+
export declare function createSql<DB>(client: PgQueryable | undefined, options: {
|
|
16
|
+
readonly rowKeys: "camelCase";
|
|
17
|
+
}): PgSql<DB, "camelCase">;
|
|
18
|
+
export declare function createSql<DB>(client?: PgQueryable, options?: {
|
|
19
|
+
readonly rowKeys?: "preserve";
|
|
20
|
+
}): PgSql<DB>;
|
|
12
21
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,OAAO,EAAmB,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAC7G,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE/C,OAAO,EAAE,aAAa,EAAE,KAAK,QAAQ,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACpF,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,EACL,QAAQ,EACR,OAAO,EACP,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,KAAK,mBAAmB,EACxB,KAAK,UAAU,GAChB,MAAM,aAAa,CAAC;AAErB,oGAAoG;AACpG,MAAM,MAAM,KAAK,CAAC,EAAE,EAAE,IAAI,SAAS,OAAO,GAAG,UAAU,IAAI,gBAAgB,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;AAEjG;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,GAAG,SAAS,EAAE,OAAO,EAAE;IAAE,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;CAAE,GAAG,KAAK,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;AACnI,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,UAAU,CAAA;CAAE,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { createTransactionalSql } from "@typesql/core";
|
|
2
|
+
import { driver } from "./client.js";
|
|
3
3
|
export { NoResultError } from "@typesql/core";
|
|
4
|
-
export {
|
|
5
|
-
|
|
6
|
-
|
|
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));
|
|
4
|
+
export { executor, migrate, } from "./client.js";
|
|
5
|
+
export function createSql(client, options) {
|
|
6
|
+
return createTransactionalSql(client, driver, 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,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAwD,MAAM,eAAe,CAAC;AAC7G,OAAO,EAAE,MAAM,EAAoB,MAAM,aAAa,CAAC;AAGvD,OAAO,EAAE,aAAa,EAAwC,MAAM,eAAe,CAAC;AAEpF,OAAO,EACL,QAAQ,EACR,OAAO,GAMR,MAAM,aAAa,CAAC;AAarB,MAAM,UAAU,SAAS,CAAK,MAAoB,EAAE,OAAoB;IACtE,OAAO,sBAAsB,CAA6B,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;AACrF,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"}
|