turbine-orm 0.49.0 → 0.50.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.
Files changed (157) hide show
  1. package/README.md +122 -39
  2. package/dist/cjs/adapters/cockroachdb.d.ts +39 -0
  3. package/dist/cjs/adapters/index.d.ts +110 -0
  4. package/dist/cjs/adapters/yugabytedb.d.ts +51 -0
  5. package/dist/cjs/cli/config.d.ts +181 -0
  6. package/dist/cjs/cli/config.js +32 -6
  7. package/dist/cjs/cli/destructive.d.ts +38 -0
  8. package/dist/cjs/cli/index.d.ts +359 -0
  9. package/dist/cjs/cli/index.js +228 -56
  10. package/dist/cjs/cli/loader.d.ts +61 -0
  11. package/dist/cjs/cli/mcp.d.ts +42 -0
  12. package/dist/cjs/cli/migrate.d.ts +356 -0
  13. package/dist/cjs/cli/migrate.js +131 -40
  14. package/dist/cjs/cli/observe-ui.d.ts +1 -0
  15. package/dist/cjs/cli/observe-ui.js +14 -5
  16. package/dist/cjs/cli/observe.d.ts +25 -0
  17. package/dist/cjs/cli/observe.js +49 -12
  18. package/dist/cjs/cli/pii-tags.d.ts +53 -0
  19. package/dist/cjs/cli/prisma-report.d.ts +33 -0
  20. package/dist/cjs/cli/prisma-report.js +73 -0
  21. package/dist/cjs/cli/prisma-resolve.d.ts +106 -0
  22. package/dist/cjs/cli/prisma-resolve.js +1 -0
  23. package/dist/cjs/cli/prisma-schema.d.ts +176 -0
  24. package/dist/cjs/cli/prisma-schema.js +82 -4
  25. package/dist/cjs/cli/rate-limit.d.ts +32 -0
  26. package/dist/cjs/cli/rate-limit.js +45 -0
  27. package/dist/cjs/cli/studio-demo.d.ts +43 -0
  28. package/dist/cjs/cli/studio-ui.generated.d.ts +1 -0
  29. package/dist/cjs/cli/studio.d.ts +207 -0
  30. package/dist/cjs/cli/studio.js +136 -71
  31. package/dist/cjs/cli/ui.d.ts +73 -0
  32. package/dist/cjs/cli/ui.js +51 -9
  33. package/dist/cjs/client.d.ts +837 -0
  34. package/dist/cjs/client.js +3 -0
  35. package/dist/cjs/dialect.d.ts +516 -0
  36. package/dist/cjs/dialect.js +37 -12
  37. package/dist/cjs/errors.d.ts +370 -0
  38. package/dist/cjs/generate.d.ts +137 -0
  39. package/dist/cjs/generate.js +39 -6
  40. package/dist/cjs/index-advisor.d.ts +153 -0
  41. package/dist/cjs/index-stats.d.ts +384 -0
  42. package/dist/cjs/index.d.ts +55 -0
  43. package/dist/cjs/index.js +7 -2
  44. package/dist/cjs/introspect.d.ts +269 -0
  45. package/dist/cjs/mssql.d.ts +232 -0
  46. package/dist/cjs/mssql.js +6 -0
  47. package/dist/cjs/mysql.d.ts +173 -0
  48. package/dist/cjs/mysql.js +16 -0
  49. package/dist/cjs/nested-write.d.ts +96 -0
  50. package/dist/cjs/nested-write.js +414 -24
  51. package/dist/cjs/observe.d.ts +115 -0
  52. package/dist/cjs/optional-peer-import.d.cts +72 -0
  53. package/dist/cjs/pipeline-submittable.d.ts +93 -0
  54. package/dist/cjs/pipeline.d.ts +71 -0
  55. package/dist/cjs/powdb-introspect.d.ts +84 -0
  56. package/dist/cjs/powdb.d.ts +931 -0
  57. package/dist/cjs/powdb.js +106 -21
  58. package/dist/cjs/powql.d.ts +592 -0
  59. package/dist/cjs/powql.js +42 -6
  60. package/dist/cjs/prisma-compat.d.ts +283 -0
  61. package/dist/cjs/prisma-compat.js +167 -9
  62. package/dist/cjs/query/aggregates.d.ts +92 -0
  63. package/dist/cjs/query/aggregates.js +7 -3
  64. package/dist/cjs/query/batched-loader.d.ts +193 -0
  65. package/dist/cjs/query/builder.d.ts +849 -0
  66. package/dist/cjs/query/builder.js +571 -65
  67. package/dist/cjs/query/compound-unique.d.ts +51 -0
  68. package/dist/cjs/query/deferred.d.ts +223 -0
  69. package/dist/cjs/query/filters.d.ts +201 -0
  70. package/dist/cjs/query/index.d.ts +14 -0
  71. package/dist/cjs/query/index.js +6 -1
  72. package/dist/cjs/query/relations.d.ts +609 -0
  73. package/dist/cjs/query/relations.js +693 -46
  74. package/dist/cjs/query/types.d.ts +1300 -0
  75. package/dist/cjs/query/utils.d.ts +209 -0
  76. package/dist/cjs/query/utils.js +208 -1
  77. package/dist/cjs/query/warn-registry.d.ts +68 -0
  78. package/dist/cjs/query/warn-registry.js +9 -0
  79. package/dist/cjs/query/where-compile.d.ts +139 -0
  80. package/dist/cjs/query/where.d.ts +548 -0
  81. package/dist/cjs/query/where.js +58 -22
  82. package/dist/cjs/query/writes.d.ts +172 -0
  83. package/dist/cjs/query/writes.js +105 -12
  84. package/dist/cjs/realtime.d.ts +70 -0
  85. package/dist/cjs/schema-builder.d.ts +354 -0
  86. package/dist/cjs/schema-metadata.d.ts +83 -0
  87. package/dist/cjs/schema-sql.d.ts +217 -0
  88. package/dist/cjs/schema-sql.js +23 -5
  89. package/dist/cjs/schema.d.ts +356 -0
  90. package/dist/cjs/schema.js +125 -0
  91. package/dist/cjs/seed.d.ts +15 -0
  92. package/dist/cjs/serverless.d.ts +142 -0
  93. package/dist/cjs/sqlite.d.ts +143 -0
  94. package/dist/cjs/sqlite.js +4 -0
  95. package/dist/cjs/typed-sql.d.ts +102 -0
  96. package/dist/cli/config.d.ts +18 -4
  97. package/dist/cli/config.js +31 -6
  98. package/dist/cli/index.d.ts +123 -0
  99. package/dist/cli/index.js +223 -58
  100. package/dist/cli/migrate.d.ts +59 -10
  101. package/dist/cli/migrate.js +128 -41
  102. package/dist/cli/observe-ui.d.ts +1 -1
  103. package/dist/cli/observe-ui.js +14 -5
  104. package/dist/cli/observe.d.ts +7 -1
  105. package/dist/cli/observe.js +48 -12
  106. package/dist/cli/prisma-report.d.ts +14 -0
  107. package/dist/cli/prisma-report.js +72 -0
  108. package/dist/cli/prisma-resolve.d.ts +6 -0
  109. package/dist/cli/prisma-resolve.js +1 -0
  110. package/dist/cli/prisma-schema.d.ts +62 -2
  111. package/dist/cli/prisma-schema.js +81 -4
  112. package/dist/cli/rate-limit.d.ts +32 -0
  113. package/dist/cli/rate-limit.js +40 -0
  114. package/dist/cli/studio.d.ts +5 -5
  115. package/dist/cli/studio.js +135 -70
  116. package/dist/cli/ui.d.ts +1 -1
  117. package/dist/cli/ui.js +51 -9
  118. package/dist/client.d.ts +40 -0
  119. package/dist/client.js +3 -0
  120. package/dist/dialect.d.ts +17 -1
  121. package/dist/dialect.js +37 -12
  122. package/dist/generate.js +40 -7
  123. package/dist/index.d.ts +1 -1
  124. package/dist/index.js +1 -1
  125. package/dist/mssql.js +6 -0
  126. package/dist/mysql.js +16 -0
  127. package/dist/nested-write.d.ts +2 -0
  128. package/dist/nested-write.js +415 -25
  129. package/dist/powdb.d.ts +4 -2
  130. package/dist/powdb.js +106 -21
  131. package/dist/powql.d.ts +5 -0
  132. package/dist/powql.js +42 -6
  133. package/dist/prisma-compat.d.ts +2 -0
  134. package/dist/prisma-compat.js +166 -8
  135. package/dist/query/aggregates.js +7 -3
  136. package/dist/query/builder.d.ts +292 -21
  137. package/dist/query/builder.js +570 -64
  138. package/dist/query/deferred.d.ts +39 -0
  139. package/dist/query/index.d.ts +1 -1
  140. package/dist/query/index.js +1 -1
  141. package/dist/query/relations.d.ts +173 -5
  142. package/dist/query/relations.js +688 -47
  143. package/dist/query/types.d.ts +123 -39
  144. package/dist/query/utils.d.ts +116 -0
  145. package/dist/query/utils.js +198 -0
  146. package/dist/query/warn-registry.d.ts +9 -0
  147. package/dist/query/warn-registry.js +9 -0
  148. package/dist/query/where.d.ts +38 -1
  149. package/dist/query/where.js +58 -23
  150. package/dist/query/writes.d.ts +42 -1
  151. package/dist/query/writes.js +104 -13
  152. package/dist/schema-sql.d.ts +14 -0
  153. package/dist/schema-sql.js +23 -5
  154. package/dist/schema.d.ts +38 -0
  155. package/dist/schema.js +123 -0
  156. package/dist/sqlite.js +4 -0
  157. package/package.json +77 -28
@@ -0,0 +1,72 @@
1
+ /**
2
+ * True dynamic `import()` for the optional peer dependencies (`mysql2`,
3
+ * `mssql`, `@zvndev/powdb-client`, `@zvndev/powdb-embedded`) — safe in BOTH
4
+ * build outputs, including for peers that are ESM-only.
5
+ *
6
+ * THE PROBLEM THIS FILE SOLVES (the `@zvndev/powdb-client` ≥ 0.9 CJS break):
7
+ * the engine subpaths load their optional peers with dynamic `import()` so the
8
+ * peers stay out of the static graph. The ESM build (`tsconfig.json`, module
9
+ * NodeNext) emits that `import()` verbatim. The CJS build (`tsconfig.cjs.json`,
10
+ * module CommonJS) however TRANSPILES `import()` into
11
+ * `Promise.resolve().then(() => require(...))` — and `require()` of an
12
+ * ESM-only package (no `require` export condition, e.g. powdb-client ≥ 0.9)
13
+ * throws `ERR_PACKAGE_PATH_NOT_EXPORTED`, breaking every CJS consumer.
14
+ *
15
+ * TypeScript offers no way to preserve `import()` under `module: CommonJS`,
16
+ * and the CJS pass cannot switch to `module: NodeNext` (the root package.json
17
+ * says `"type": "module"`, so NodeNext would classify every `.ts` source as
18
+ * ESM and emit ESM into dist/cjs). A `.cts` file is the escape hatch: it is
19
+ * CommonJS-format by extension regardless of package `type`, so under the ESM
20
+ * pass (NodeNext) it compiles to `dist/optional-peer-import.cjs` — a CommonJS
21
+ * file whose `import()` SURVIVES transpilation (NodeNext preserves dynamic
22
+ * import in CJS files precisely because it is the only way CJS can load ESM).
23
+ *
24
+ * That gives the published package two copies of this module:
25
+ * - `dist/optional-peer-import.cjs` (ESM pass, NodeNext) — real `import()`
26
+ * - `dist/cjs/optional-peer-import.cjs` (CJS pass, CommonJS) — lowered to `require()`
27
+ *
28
+ * The lowered copy works fine for CJS-loadable peers (`mysql2`, `mssql`, older
29
+ * powdb peers). When it hits an ESM-only peer, the `require()` fails with a
30
+ * recognizable code and this function falls back to delegating the load to the
31
+ * sibling NodeNext copy one directory up (`../optional-peer-import.cjs`) —
32
+ * which is a plain CommonJS file (loadable by `require()` on every supported
33
+ * Node) whose real `import()` then loads the ESM peer. The ESM-pass copy has
34
+ * no such sibling; its lazy `require` throws and the original error surfaces,
35
+ * so the fallback can never recurse.
36
+ *
37
+ * Keep this module dependency-free and side-effect-free: it must be loadable
38
+ * from both module systems on every supported Node (≥ 20) without pulling in
39
+ * anything else.
40
+ */
41
+ /**
42
+ * Dynamically import an optional peer dependency. In the ESM build this is a
43
+ * plain `import()`. In the CJS build the first attempt is a transpiled
44
+ * `require()`; if the peer turns out to be ESM-only, the load is retried
45
+ * through the ESM-build sibling copy of this file, whose `import()` survived
46
+ * transpilation (see the module doc comment).
47
+ *
48
+ * @param specifier bare package specifier (e.g. `'@zvndev/powdb-client'`).
49
+ * @param allowEsmFallback internal recursion guard — the delegated call passes
50
+ * `false` so a failure in the sibling copy can never bounce back.
51
+ */
52
+ declare function importOptionalPeer(specifier: string, allowEsmFallback?: boolean): Promise<unknown>;
53
+ /**
54
+ * Merged namespace so callers can reach {@link peerPackageVersion} off the same
55
+ * default import (`importOptionalPeer.peerPackageVersion(...)`). Lives in this
56
+ * `.cts` file for the same reason the dynamic import does: a `.cts` compiles to
57
+ * CommonJS in BOTH build passes, so `require` / `require.resolve` are natively
58
+ * available and `import.meta` is never emitted (which would break the CJS build
59
+ * and crash CJS consumers, see `resolveEmbeddedVersion` in powdb.ts).
60
+ */
61
+ declare namespace importOptionalPeer {
62
+ /**
63
+ * Resolve an optional peer's declared `package.json` version WITHOUT loading
64
+ * the package itself (so an ESM-only peer never trips `require`). `require` is
65
+ * anchored on THIS module's location (inside the published `dist/`), so bare
66
+ * resolution walks up `node_modules` and finds the peer exactly where
67
+ * `import.meta.url` used to point, but it compiles under `module: CommonJS`
68
+ * too. Returns `null` when the peer / its package.json cannot be resolved.
69
+ */
70
+ function peerPackageVersion(specifier: string): string | null;
71
+ }
72
+ export = importOptionalPeer;
@@ -0,0 +1,93 @@
1
+ /**
2
+ * turbine-orm — Real Postgres pipeline protocol implementation
3
+ *
4
+ * Uses the pg extended-query protocol wire methods (parse/bind/describe/execute/sync)
5
+ * exposed on pg.Client's Connection object to send multiple queries in a single
6
+ * TCP flush. This achieves true 1-RTT pipeline execution instead of the sequential
7
+ * await-per-query approach.
8
+ *
9
+ * The approach (listener-swap):
10
+ * 1. Detach the pg.Client's event listeners from the Connection
11
+ * 2. Attach our own state-machine listeners
12
+ * 3. Cork the TCP stream, push all protocol messages, uncork (one TCP write)
13
+ * 4. Drive a state machine over backend response events
14
+ * 5. Restore original listeners and release the client
15
+ *
16
+ * This is the same pattern used by pg-cursor and pg-query-stream, but extended
17
+ * to handle N queries in a single pipeline.
18
+ */
19
+ import type { EventEmitter } from 'node:events';
20
+ import type { DeferredQuery } from './query/index.js';
21
+ /** The pg Connection object — an EventEmitter with wire-protocol methods */
22
+ export interface PgConnection extends EventEmitter {
23
+ stream: {
24
+ cork?: () => void;
25
+ uncork?: () => void;
26
+ writable?: boolean;
27
+ destroy?: (err?: Error) => void;
28
+ write?: (...args: unknown[]) => boolean;
29
+ };
30
+ parse(query: {
31
+ text: string;
32
+ name?: string;
33
+ types?: number[];
34
+ }): void;
35
+ bind(config: {
36
+ portal?: string;
37
+ statement?: string;
38
+ values?: unknown[];
39
+ binary?: boolean;
40
+ valueMapper?: (val: unknown, index: number) => unknown;
41
+ }): void;
42
+ describe(msg: {
43
+ type: 'S' | 'P';
44
+ name?: string;
45
+ }): void;
46
+ execute(config: {
47
+ portal?: string;
48
+ rows?: number;
49
+ }): void;
50
+ sync(): void;
51
+ }
52
+ /** A pg PoolClient with the internal fields we need */
53
+ export interface PgPoolClient {
54
+ connection: PgConnection;
55
+ /** pg.Client sets this to control query queue draining */
56
+ readyForQuery: boolean;
57
+ /** Type parser overrides (if the client has custom type parsers) */
58
+ _types?: unknown;
59
+ release(err?: Error | boolean): void;
60
+ }
61
+ export interface PipelineRunOptions {
62
+ /**
63
+ * Whether to wrap the pipeline in BEGIN/COMMIT (default: true).
64
+ * When true, all queries execute atomically. On error, ROLLBACK is sent.
65
+ * When false, each query gets its own Sync message for error isolation.
66
+ */
67
+ transactional?: boolean;
68
+ /** Timeout in milliseconds. If exceeded, the connection is destroyed. */
69
+ timeout?: number;
70
+ }
71
+ /**
72
+ * Execute multiple queries using the Postgres extended-query pipeline protocol.
73
+ *
74
+ * All protocol messages are buffered into a single TCP write via cork/uncork.
75
+ * The backend processes them in order and sends back results which our state
76
+ * machine collects.
77
+ *
78
+ * @param client - A pg PoolClient with an accessible Connection
79
+ * @param queries - Array of DeferredQuery descriptors
80
+ * @param options - Pipeline options (transactional, timeout)
81
+ * @returns Array of transformed results in the same order as queries
82
+ */
83
+ export declare function runPipelined<T extends readonly DeferredQuery<unknown>[]>(client: PgPoolClient, queries: T, options?: PipelineRunOptions): Promise<unknown[]>;
84
+ /**
85
+ * Check whether a pool client supports the extended-query pipeline protocol.
86
+ *
87
+ * Returns true if the client has a Connection object with the required wire
88
+ * protocol methods (parse, bind, describe, execute, sync) and is an EventEmitter.
89
+ *
90
+ * Returns false for HTTP-based drivers (Neon HTTP, Vercel Postgres), mock pools,
91
+ * and any pool that doesn't expose pg internals.
92
+ */
93
+ export declare function supportsExtendedPipeline(poolClient: unknown): poolClient is PgPoolClient;
@@ -0,0 +1,71 @@
1
+ /**
2
+ * turbine-orm — Pipeline execution
3
+ *
4
+ * Pipelines batch multiple independent queries into a single database round-trip.
5
+ * Instead of N sequential awaits (N round-trips), you get 1 round-trip for all N queries.
6
+ *
7
+ * How it works:
8
+ * 1. Each query method (findUnique, count, etc.) can produce a DeferredQuery descriptor
9
+ * containing the SQL, params, and a transform function.
10
+ * 2. pipeline() collects these descriptors, checks whether the underlying pool client
11
+ * supports the extended-query pipeline protocol, and either:
12
+ * (a) executes them via real Postgres pipeline protocol (one TCP flush), or
13
+ * (b) falls back to sequential execution on a single connection.
14
+ *
15
+ * Real pipeline mode uses `src/pipeline-submittable.ts` which drives the pg Connection's
16
+ * wire-protocol methods (parse/bind/describe/execute/sync) directly with listener-swap.
17
+ *
18
+ * Sequential fallback covers HTTP-based drivers (Neon HTTP, Vercel Postgres, Cloudflare
19
+ * Hyperdrive), mock pools in tests, and any pool that doesn't expose pg internals.
20
+ */
21
+ import type pg from 'pg';
22
+ import type { DeferredQuery } from './query/index.js';
23
+ export interface PipelineOptions {
24
+ /**
25
+ * Whether to wrap the pipeline in a transaction (default: true).
26
+ *
27
+ * - `true` (default): All queries execute atomically within BEGIN/COMMIT.
28
+ * If any query fails, the entire batch is rolled back.
29
+ *
30
+ * - `false`: Each query is independent. A failure in one query does NOT
31
+ * affect others. On partial failure, a `PipelineError` is thrown with
32
+ * per-query results in `.results`.
33
+ */
34
+ transactional?: boolean;
35
+ /** Timeout in milliseconds. If exceeded, the connection is destroyed. */
36
+ timeout?: number;
37
+ }
38
+ /**
39
+ * Execute multiple deferred queries in a single batch.
40
+ *
41
+ * On pg.Pool-backed connections with the standard TCP driver, this uses the
42
+ * real Postgres extended-query pipeline protocol for true 1-RTT execution.
43
+ * On HTTP-based drivers (Neon HTTP, Vercel Postgres, etc.) or mock pools,
44
+ * it falls back to sequential execution on a single connection.
45
+ *
46
+ * @example
47
+ * ```ts
48
+ * const [user, count, posts] = await executePipeline(pool, [
49
+ * db.users.buildFindUnique({ where: { id: 1 } }),
50
+ * db.posts.buildCount({ where: { orgId: 1 } }),
51
+ * db.posts.buildFindMany({ where: { userId: 1 }, limit: 10 }),
52
+ * ]);
53
+ * ```
54
+ */
55
+ export declare function executePipeline<T extends readonly DeferredQuery<unknown>[]>(pool: pg.Pool, queries: T, options?: PipelineOptions): Promise<PipelineResults<T>>;
56
+ /**
57
+ * Check whether a pool supports the real pipeline protocol.
58
+ * Call this to determine at runtime whether pipelines will use the fast path
59
+ * or fall back to sequential execution.
60
+ *
61
+ * Note: This acquires and immediately releases a connection to inspect it.
62
+ */
63
+ export declare function pipelineSupported(pool: pg.Pool): Promise<boolean>;
64
+ /**
65
+ * Extract the result types from a tuple of DeferredQuery objects.
66
+ * If you pass [DeferredQuery<User>, DeferredQuery<number>, DeferredQuery<Post[]>],
67
+ * you get back [User, number, Post[]].
68
+ */
69
+ export type PipelineResults<T extends readonly DeferredQuery<unknown>[]> = {
70
+ [K in keyof T]: T[K] extends DeferredQuery<infer R> ? R : never;
71
+ };
@@ -0,0 +1,84 @@
1
+ /**
2
+ * turbine-orm/powdb — `describe`-based introspection.
3
+ *
4
+ * PowDB exposes its catalog through two ordinary rows-returning statements
5
+ * (keywords since engine 0.10):
6
+ * - `schema` → one row per type: `{ name, columns }` (columns = a count).
7
+ * - `describe <T>` / `schema <T>` → one row per column:
8
+ * `{ column, type, nullable, index }` where `type` is a PowQL type name
9
+ * (`str`/`int`/`float`/`bool`/`json`/`datetime`/`uuid`/`bytes`), `nullable`
10
+ * is `"true"`/`"false"`, and `index` is `"unique"` / `"index"` / `""`.
11
+ *
12
+ * {@link introspectPowdbDatabase} turns those into the same {@link SchemaMetadata}
13
+ * shape the SQL introspectors produce, so a code-first PowDB database can be
14
+ * introspected for bootstrap/verification. It is transport-agnostic: the caller
15
+ * supplies an `exec(powql)` that returns row objects **keyed by column name**.
16
+ * - Embedded / owned pool: `exec = async (q) => ({ rows: await db.raw([q]) })`
17
+ * using a live `turbinePowDB` client's `raw` tagged template.
18
+ * - Networked: the raw `@zvndev/powdb-client` returns POSITIONAL rows
19
+ * (`{ columns: string[], rows: string[][] }`), so zip them into records.
20
+ * A bare `(await client.query(q)).rows` would hand this function `string[][]`
21
+ * whose `.name` cell is `undefined` and every table would silently drop out:
22
+ * ```ts
23
+ * const exec = async (q) => {
24
+ * const r = await client.query(q);
25
+ * return { rows: r.rows.map((row) => Object.fromEntries(r.columns.map((c, i) => [c, row[i]]))) };
26
+ * };
27
+ * ```
28
+ * (A mis-shaped exec is now caught: if `schema` returns rows but none carry
29
+ * a `name`, {@link introspectPowdbDatabase} throws instead of returning an
30
+ * empty schema.)
31
+ *
32
+ * IMPORTANT LIMITATIONS (all documented, none silent):
33
+ * - Relations are ALWAYS `{}`: PowDB has no declared foreign keys, so
34
+ * `describe` cannot report them. The recommended flow for relation-aware
35
+ * metadata is code-first `defineSchema` + `schemaDefToMetadata`; use
36
+ * introspection to bootstrap or verify column shape.
37
+ * - Primary key is a HEURISTIC (`describe` has no PK concept): PowDB marks a
38
+ * PK column as `required unique`, so the first non-nullable `unique` column
39
+ * is chosen (a column named `id` wins ties). A table with no such column
40
+ * yields `primaryKey: []` and a warning; single-row ops on it fail loudly.
41
+ * - `isGenerated` is always `false`: `describe` does not expose PowDB's `auto`
42
+ * modifier, so an introspected int PK is treated as client-supplied unless
43
+ * the caller hand-edits the metadata.
44
+ * - Doc-field expression indexes are INVISIBLE to `describe`, so they never
45
+ * round-trip; only plain `unique`/`index` columns appear in `indexes`.
46
+ * - `datetime` / `uuid` / `bytes` columns map to read-oriented TS types
47
+ * (`Date` / `string` / `Uint8Array`). Turbine never emits those PowQL types
48
+ * on write, so writing to such a column may not round-trip.
49
+ *
50
+ * v1 is a PROGRAMMATIC API (exported from `turbine-orm/powdb`); the CLI's
51
+ * `turbine generate` still defaults to Postgres. Routing a `powdb://` URL
52
+ * through the CLI would additionally need: a `powdbDialect.introspector`
53
+ * wired to a networked `exec`, and `cli/config.ts` teaching the generate
54
+ * funnel to construct a PowDB client instead of a `pg` client for `powdb://`.
55
+ */
56
+ import { type PowdbCapabilities } from './powdb.js';
57
+ import type { SchemaMetadata } from './schema.js';
58
+ /** A minimal rows-returning executor over a PowDB connection (embedded or networked). */
59
+ export type PowdbExec = (powql: string) => Promise<{
60
+ rows: Record<string, unknown>[];
61
+ }>;
62
+ /** Options controlling which tables {@link introspectPowdbDatabase} reads. */
63
+ export interface PowdbIntrospectOptions {
64
+ /** Only introspect these table names (snake_case, as PowDB reports them). */
65
+ include?: string[];
66
+ /** Skip these table names. */
67
+ exclude?: string[];
68
+ /**
69
+ * Bound connection capabilities. When supplied AND `introspection` (engine
70
+ * >= 0.10) is false, this throws a version-hinting {@link UnsupportedFeatureError}
71
+ * (E017) up front instead of letting a pre-0.10 engine reject the `schema` /
72
+ * `describe` keywords with an opaque parse error. Omit it (the bare-exec path)
73
+ * to run ungated; the pool paths that know the version pass it through.
74
+ */
75
+ capabilities?: PowdbCapabilities;
76
+ }
77
+ /**
78
+ * Read a live PowDB database into {@link SchemaMetadata} via `schema` +
79
+ * `describe <T>` statements run through the supplied {@link PowdbExec}.
80
+ *
81
+ * @param exec Rows-returning executor (embedded `db.raw` or networked `client.query`).
82
+ * @param options `include`/`exclude` table filters.
83
+ */
84
+ export declare function introspectPowdbDatabase(exec: PowdbExec, options?: PowdbIntrospectOptions): Promise<SchemaMetadata>;