turbine-orm 0.19.2 → 0.22.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/README.md +99 -18
- package/dist/adapters/cockroachdb.js +4 -9
- package/dist/cjs/adapters/cockroachdb.js +4 -9
- package/dist/cjs/cli/index.js +6 -3
- package/dist/cjs/cli/observe-ui.js +12 -2
- package/dist/cjs/cli/observe.js +6 -7
- package/dist/cjs/cli/studio.js +6 -7
- package/dist/cjs/client.js +44 -22
- package/dist/cjs/dialect.js +116 -0
- package/dist/cjs/errors.js +19 -1
- package/dist/cjs/generate.js +4 -0
- package/dist/cjs/index.js +3 -2
- package/dist/cjs/introspect.js +20 -0
- package/dist/cjs/mssql.js +1338 -0
- package/dist/cjs/mysql.js +1052 -0
- package/dist/cjs/powdb.js +851 -0
- package/dist/cjs/powql.js +903 -0
- package/dist/cjs/query/builder.js +293 -73
- package/dist/cjs/sqlite.js +849 -0
- package/dist/cjs/typed-sql.js +9 -7
- package/dist/cli/index.js +6 -3
- package/dist/cli/observe-ui.d.ts +1 -1
- package/dist/cli/observe-ui.js +12 -2
- package/dist/cli/observe.js +7 -8
- package/dist/cli/studio.js +7 -8
- package/dist/cli/ui.d.ts +1 -1
- package/dist/client.d.ts +23 -1
- package/dist/client.js +45 -23
- package/dist/dialect.d.ts +258 -1
- package/dist/dialect.js +83 -0
- package/dist/errors.d.ts +12 -0
- package/dist/errors.js +17 -0
- package/dist/generate.js +4 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/introspect.d.ts +18 -0
- package/dist/introspect.js +19 -0
- package/dist/mssql.d.ts +233 -0
- package/dist/mssql.js +1298 -0
- package/dist/mysql.d.ts +174 -0
- package/dist/mysql.js +1012 -0
- package/dist/powdb.d.ts +338 -0
- package/dist/powdb.js +802 -0
- package/dist/powql.d.ts +153 -0
- package/dist/powql.js +900 -0
- package/dist/query/builder.d.ts +105 -0
- package/dist/query/builder.js +294 -74
- package/dist/query/index.d.ts +1 -1
- package/dist/sqlite.d.ts +144 -0
- package/dist/sqlite.js +842 -0
- package/dist/typed-sql.d.ts +7 -5
- package/dist/typed-sql.js +9 -7
- package/package.json +45 -1
package/dist/mysql.d.ts
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* turbine-orm/mysql — MySQL 8 engine (driver-injected, optional peer)
|
|
3
|
+
*
|
|
4
|
+
* Binds Turbine to MySQL 8 via the `mysql2` driver. `mysql2` is **not** a root
|
|
5
|
+
* dependency — it is an **optional peer**: `npm i turbine-orm` pulls nothing
|
|
6
|
+
* extra, and only consumers who `import 'turbine-orm/mysql'` install `mysql2`
|
|
7
|
+
* themselves. The factory loads it through a dynamic `import('mysql2/promise')`
|
|
8
|
+
* so importing this module never crashes when `mysql2` is absent for a consumer
|
|
9
|
+
* who does not use it. Turbine's root runtime dependency stays exactly `pg`.
|
|
10
|
+
*
|
|
11
|
+
* ## The two hard MySQL realities this engine solves
|
|
12
|
+
*
|
|
13
|
+
* 1. **No `RETURNING`.** `INSERT`/`UPDATE`/`DELETE` cannot return the affected
|
|
14
|
+
* rows. `mysqlDialect.resultStrategy = 'reselect'`: the executor runs the
|
|
15
|
+
* write, then issues a follow-up `SELECT` by primary key (using mysql2's
|
|
16
|
+
* `insertId` for auto-increment PKs) / by the `where` predicate, so
|
|
17
|
+
* `create`/`update`/`upsert`/`delete` still return real rows. This is the
|
|
18
|
+
* first shipped engine to exercise the Phase-0 `reselect` path.
|
|
19
|
+
* 2. **Positional `?` is broken for this builder.** Turbine pushes params in
|
|
20
|
+
* 1-indexed generation order but EMITS them in a different SQL-text position
|
|
21
|
+
* (e.g. a `with`-relation `LIMIT` lands in the SELECT list, ahead of the
|
|
22
|
+
* outer `WHERE`). Postgres reconciles this via numbered `$N`; positional `?`
|
|
23
|
+
* silently mis-binds. So `mysqlDialect` uses **mysql2 named placeholders**
|
|
24
|
+
* (`:p1`, `:p2`, …) and the driver shim binds via a `{ p1, p2, … }` object —
|
|
25
|
+
* exactly mirroring `$N` semantics regardless of text order. (See
|
|
26
|
+
* `turbine-orm/sqlite` for the same fix.)
|
|
27
|
+
*
|
|
28
|
+
* ## Capabilities & limits (vs PostgreSQL)
|
|
29
|
+
*
|
|
30
|
+
* - **Single query nested relations preserved** via MySQL 8 `JSON_OBJECT` /
|
|
31
|
+
* `JSON_ARRAYAGG` with `COALESCE(…, JSON_ARRAY())`. `JSON_ARRAYAGG` has no
|
|
32
|
+
* inline `ORDER BY` argument, so every ordered to-many relation is forced
|
|
33
|
+
* through the inner-subquery rewrite (`aggSupportsInlineOrderBy = false`).
|
|
34
|
+
* Nested subresults are `CAST(… AS JSON)`-wrapped so MySQL embeds them as real
|
|
35
|
+
* nested JSON instead of double-encoding a scalar subquery result as a string.
|
|
36
|
+
* - **`createMany` returns an empty array** (count-not-rows). MySQL has no
|
|
37
|
+
* `RETURNING` and the bulk-insert `insertId` is only the first generated id, so
|
|
38
|
+
* re-selecting N rows reliably is unsafe. The rows ARE inserted; re-query if you
|
|
39
|
+
* need them back. (Plan §4 documented divergence.)
|
|
40
|
+
* - **Unsupported (throw `UnsupportedFeatureError`):** pgvector distance ops,
|
|
41
|
+
* LISTEN/NOTIFY (`$listen`/`$notify`), RLS `sessionContext` (no GUCs).
|
|
42
|
+
* - **Advisory-lock migration locking** is available in principle via
|
|
43
|
+
* `GET_LOCK`/`RELEASE_LOCK` (`supportsAdvisoryLock = true`); the migrate CLI is
|
|
44
|
+
* still PostgreSQL-only, so this flag documents intent for a future adapter.
|
|
45
|
+
* - **Case-insensitive matching** uses `LOWER(col) LIKE LOWER(ref)` — note this
|
|
46
|
+
* can defeat indexes unless a functional/generated index exists.
|
|
47
|
+
* - **bignum:** mysql2 is configured `supportBigNumbers:true, bigNumberStrings:false`
|
|
48
|
+
* — the same safe-int policy Turbine uses for Postgres `int8` (number when it
|
|
49
|
+
* fits, decimal string otherwise). `DECIMAL` comes back as a string; `TINYINT(1)`
|
|
50
|
+
* binds booleans as 1/0. No global parser state is mutated.
|
|
51
|
+
* - **Version:** MySQL **8.0+** required (5.7 lacks `JSON_ARRAYAGG`); MariaDB is
|
|
52
|
+
* unsupported. The factory probes `SELECT VERSION()` and fails fast otherwise.
|
|
53
|
+
*
|
|
54
|
+
* ## Example
|
|
55
|
+
*
|
|
56
|
+
* ```ts
|
|
57
|
+
* import { turbineMysql } from 'turbine-orm/mysql';
|
|
58
|
+
* import { SCHEMA } from './generated/turbine/metadata.js';
|
|
59
|
+
*
|
|
60
|
+
* const db = await turbineMysql('mysql://user:pass@localhost:3306/app', SCHEMA);
|
|
61
|
+
* const users = await db.users.findMany({ with: { posts: true }, limit: 10 });
|
|
62
|
+
* await db.disconnect();
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
import { type PgCompatPool, type PgCompatPoolClient, TurbineClient, type TurbineConfig } from './client.js';
|
|
66
|
+
import { type Dialect, type IntrospectOptions } from './dialect.js';
|
|
67
|
+
import { type SchemaMetadata } from './schema.js';
|
|
68
|
+
/** mysql2's `[result, fields]` tuple. `result` is rows (SELECT) or a header (write). */
|
|
69
|
+
type Mysql2Result = [unknown, unknown];
|
|
70
|
+
interface Mysql2Queryable {
|
|
71
|
+
query(sql: string, values?: unknown): Promise<Mysql2Result>;
|
|
72
|
+
execute(sql: string, values?: unknown): Promise<Mysql2Result>;
|
|
73
|
+
}
|
|
74
|
+
interface Mysql2Connection extends Mysql2Queryable {
|
|
75
|
+
release(): void;
|
|
76
|
+
}
|
|
77
|
+
interface Mysql2Pool extends Mysql2Queryable {
|
|
78
|
+
getConnection(): Promise<Mysql2Connection>;
|
|
79
|
+
end(): Promise<void>;
|
|
80
|
+
on?(event: string, listener: (...args: any[]) => void): unknown;
|
|
81
|
+
}
|
|
82
|
+
/** pg-style query argument: a SQL string or a `{ text, values }` config object. */
|
|
83
|
+
type QueryArg = string | {
|
|
84
|
+
name?: string;
|
|
85
|
+
text: string;
|
|
86
|
+
values?: unknown[];
|
|
87
|
+
};
|
|
88
|
+
/**
|
|
89
|
+
* A {@link PgCompatPool} backed by a `mysql2` pool. Non-transaction queries run
|
|
90
|
+
* on the pool directly (any connection); `connect()` checks out a dedicated
|
|
91
|
+
* connection so a transaction's `START TRANSACTION` / `COMMIT` / `ROLLBACK` /
|
|
92
|
+
* `SAVEPOINT` nesting all run on the same physical connection.
|
|
93
|
+
*/
|
|
94
|
+
export declare class MysqlPool implements PgCompatPool {
|
|
95
|
+
/** The underlying mysql2 pool — exposed as an escape hatch (seed / DDL / advanced ops). */
|
|
96
|
+
readonly pool: Mysql2Pool;
|
|
97
|
+
private closed;
|
|
98
|
+
constructor(pool: Mysql2Pool);
|
|
99
|
+
query(text: QueryArg, values?: unknown[]): Promise<any>;
|
|
100
|
+
connect(): Promise<PgCompatPoolClient>;
|
|
101
|
+
end(): Promise<void>;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Map a MySQL column type to a TypeScript type. `dialectType` is the
|
|
105
|
+
* `information_schema.COLUMNS.DATA_TYPE` (e.g. `bigint`, `varchar`, `datetime`);
|
|
106
|
+
* `columnType` is the full `COLUMN_TYPE` (e.g. `tinyint(1)`, `enum('a','b')`)
|
|
107
|
+
* used to detect `TINYINT(1)` booleans.
|
|
108
|
+
*/
|
|
109
|
+
export declare function mysqlTypeToTs(dialectType: string, nullable: boolean, columnType?: string): string;
|
|
110
|
+
/**
|
|
111
|
+
* MySQL 8 implementation of the {@link Dialect} contract. Backtick identifier
|
|
112
|
+
* quoting, named `:pN` placeholders (NOT positional `?` — see the module
|
|
113
|
+
* docstring), `JSON_OBJECT` / `JSON_ARRAYAGG` for the single-query nested
|
|
114
|
+
* relation engine (`CAST(… AS JSON)`-wrapped nested subresults), no `RETURNING`
|
|
115
|
+
* (`resultStrategy = 'reselect'`), `INSERT … ON DUPLICATE KEY UPDATE` upserts,
|
|
116
|
+
* and the Postgres-only capabilities disabled (vector / LISTEN-NOTIFY / RLS).
|
|
117
|
+
*/
|
|
118
|
+
export declare const mysqlDialect: Dialect;
|
|
119
|
+
/** Async executor that returns plain row objects for a parameterized query. */
|
|
120
|
+
export type MysqlRowExecutor = (sql: string, params: unknown[]) => Promise<Record<string, unknown>[]>;
|
|
121
|
+
/**
|
|
122
|
+
* Introspect a MySQL database into the same {@link SchemaMetadata} shape the
|
|
123
|
+
* Postgres catalog introspector produces, using a caller-supplied query
|
|
124
|
+
* executor (so tests can dogfood an already-open mysql2 pool/connection).
|
|
125
|
+
*
|
|
126
|
+
* @param exec Runs a parameterized (`:p1`, `:p2`, …) query and returns rows.
|
|
127
|
+
* @param schema The MySQL database (schema) name to introspect.
|
|
128
|
+
* @param options Optional include / exclude table-name filters.
|
|
129
|
+
*/
|
|
130
|
+
export declare function introspectMysqlWith(exec: MysqlRowExecutor, schema: string, options?: {
|
|
131
|
+
include?: string[];
|
|
132
|
+
exclude?: string[];
|
|
133
|
+
}): Promise<SchemaMetadata>;
|
|
134
|
+
/**
|
|
135
|
+
* Open a short-lived mysql2 connection from `options.connectionString`,
|
|
136
|
+
* introspect the database (schema = `options.schema` or the connection's current
|
|
137
|
+
* database), and close it. Wraps {@link introspectMysqlWith} for the
|
|
138
|
+
* {@link DialectIntrospector} seam used by `introspect()` / `npx turbine generate`.
|
|
139
|
+
*/
|
|
140
|
+
export declare function introspectMysql(options: IntrospectOptions): Promise<SchemaMetadata>;
|
|
141
|
+
interface MysqlConnectionConfig {
|
|
142
|
+
host?: string;
|
|
143
|
+
port?: number;
|
|
144
|
+
user?: string;
|
|
145
|
+
password?: string;
|
|
146
|
+
database?: string;
|
|
147
|
+
}
|
|
148
|
+
/** Options for {@link turbineMysql}. Mirrors the relevant {@link TurbineConfig} fields. */
|
|
149
|
+
export interface TurbineMysqlOptions extends Pick<TurbineConfig, 'logging' | 'defaultLimit' | 'warnOnUnlimited'> {
|
|
150
|
+
/** Maximum number of pooled connections (when Turbine builds the pool). Default: 10. */
|
|
151
|
+
connectionLimit?: number;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Create a {@link TurbineClient} bound to MySQL 8 via `mysql2`.
|
|
155
|
+
*
|
|
156
|
+
* Pass one of:
|
|
157
|
+
* - a connection string (`'mysql://user:pass@host:3306/db'`),
|
|
158
|
+
* - a mysql2 connection config object (`{ host, user, password, database }`), or
|
|
159
|
+
* - an existing mysql2 pool / {@link MysqlPool} (injection — you own its lifecycle,
|
|
160
|
+
* `disconnect()` is a no-op, advanced config like SSL lives here).
|
|
161
|
+
*
|
|
162
|
+
* When Turbine builds the pool (string/config), it pins the correct mysql2 flags
|
|
163
|
+
* (named placeholders, bignum, UTC dates, JSON-as-string), probes `SELECT VERSION()`
|
|
164
|
+
* to reject MySQL < 8.0 / MariaDB, and `disconnect()` closes the pool it created.
|
|
165
|
+
*
|
|
166
|
+
* @example
|
|
167
|
+
* ```ts
|
|
168
|
+
* import { turbineMysql } from 'turbine-orm/mysql';
|
|
169
|
+
* const db = await turbineMysql('mysql://root:root@localhost:3306/app', SCHEMA);
|
|
170
|
+
* ```
|
|
171
|
+
*/
|
|
172
|
+
export declare function turbineMysql(target: string | MysqlConnectionConfig | Mysql2Pool | MysqlPool, schema: SchemaMetadata, options?: TurbineMysqlOptions): Promise<TurbineClient>;
|
|
173
|
+
export {};
|
|
174
|
+
//# sourceMappingURL=mysql.d.ts.map
|