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/mssql.d.ts
ADDED
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* turbine-orm/mssql — Microsoft SQL Server engine (driver-injected, optional peer)
|
|
3
|
+
*
|
|
4
|
+
* Binds Turbine to SQL Server 2016+ via the `mssql` driver (which wraps
|
|
5
|
+
* `tedious`). `mssql` is **not** a root dependency — it is an **optional peer**:
|
|
6
|
+
* `npm i turbine-orm` pulls nothing extra, and only consumers who
|
|
7
|
+
* `import 'turbine-orm/mssql'` install `mssql` themselves. The factory loads it
|
|
8
|
+
* through a dynamic `import('mssql')` so importing this module never crashes when
|
|
9
|
+
* `mssql` is absent for a consumer who does not use it. Turbine's root runtime
|
|
10
|
+
* dependency stays exactly `pg`.
|
|
11
|
+
*
|
|
12
|
+
* ## The three hard SQL Server realities this engine solves
|
|
13
|
+
*
|
|
14
|
+
* 1. **No `RETURNING`.** `INSERT`/`UPDATE`/`DELETE` cannot trail a `RETURNING`
|
|
15
|
+
* clause; SQL Server returns affected rows via `OUTPUT INSERTED.*` /
|
|
16
|
+
* `OUTPUT DELETED.*` injected MID-statement (between the column list and
|
|
17
|
+
* `VALUES`, or between `SET …` and `WHERE …`). `mssqlDialect.resultStrategy =
|
|
18
|
+
* 'output'`: the statement returns its own rows in ONE round-trip (executed
|
|
19
|
+
* exactly like the PostgreSQL `'returning'` path). Upsert becomes a
|
|
20
|
+
* `MERGE … WHEN MATCHED … WHEN NOT MATCHED … OUTPUT INSERTED.* ;` (a MERGE
|
|
21
|
+
* must end with `;`). This is the first shipped engine to exercise the
|
|
22
|
+
* Phase-0 `'output'` result strategy.
|
|
23
|
+
* 2. **No `json_agg`.** SQL Server has no JSON aggregate function; the idiomatic
|
|
24
|
+
* single-query nested-relation path is `(SELECT child cols … FOR JSON PATH)`,
|
|
25
|
+
* whose object shape is expressed by the child SELECT's column ALIASES rather
|
|
26
|
+
* than an explicit `JSON_OBJECT(...)`. That does NOT map onto
|
|
27
|
+
* `buildJsonObject`/`buildJsonArrayAgg`, so `mssqlDialect` defines the
|
|
28
|
+
* additive `Dialect.buildRelationSubquery` override (the sanctioned Phase-3
|
|
29
|
+
* seam extension) and owns the whole correlated subquery. To-many wraps
|
|
30
|
+
* `ISNULL((… FOR JSON PATH), '[]')` (FOR JSON over zero rows is NULL, not
|
|
31
|
+
* `[]`); to-one adds `, WITHOUT_ARRAY_WRAPPER` and lets NULL be the no-row
|
|
32
|
+
* value. Nested relations are embedded with `JSON_QUERY(...)` so they stay
|
|
33
|
+
* real JSON instead of being escaped as a string. `INCLUDE_NULL_VALUES`
|
|
34
|
+
* keeps NULL columns present (matching PostgreSQL `json_build_object`).
|
|
35
|
+
* 3. **No `LIMIT`.** Paging is `ORDER BY … OFFSET n ROWS FETCH NEXT m ROWS ONLY`,
|
|
36
|
+
* which requires an ORDER BY — a stable `ORDER BY (SELECT NULL)` is injected
|
|
37
|
+
* when the query has none (`Dialect.buildLimitOffset`).
|
|
38
|
+
*
|
|
39
|
+
* ## Named `@pN` placeholders (no positional `?`)
|
|
40
|
+
*
|
|
41
|
+
* `mssqlDialect.paramPlaceholder = (i) => '@p' + i`. The driver shim binds via
|
|
42
|
+
* `request.input('p' + i, value)`, so binding is by NAME and independent of where
|
|
43
|
+
* each placeholder lands in the SQL text — exactly the guarantee PostgreSQL's
|
|
44
|
+
* numbered `$N` gives. (SQL Server is naturally named-param friendly, sidestepping
|
|
45
|
+
* the positional-`?` mis-bind bug the SQLite/MySQL phases hit.)
|
|
46
|
+
*
|
|
47
|
+
* ## Capabilities & limits (vs PostgreSQL)
|
|
48
|
+
*
|
|
49
|
+
* - **Single query nested relations preserved** via `FOR JSON PATH` (SQL Server
|
|
50
|
+
* 2016+). Ordered/limited to-many uses `ORDER BY … OFFSET/FETCH` inside the FOR
|
|
51
|
+
* JSON subquery (no inner-subquery rewrite needed — FOR JSON aggregates AFTER
|
|
52
|
+
* the row selection).
|
|
53
|
+
* - **Result strategy `'output'`:** create/update/delete/upsert return their rows
|
|
54
|
+
* from the same statement. `createMany` returns the inserted rows via
|
|
55
|
+
* `OUTPUT INSERTED.*` on the multi-row VALUES insert (≤ 1000 rows / 2100 params
|
|
56
|
+
* per statement — exceeding either throws a clear `ValidationError`; chunk
|
|
57
|
+
* yourself or use single `create`s).
|
|
58
|
+
* - **MERGE concurrency caveat:** `MERGE` is the upsert primitive; under high
|
|
59
|
+
* concurrency a `MERGE` can still race (it is NOT a substitute for a unique
|
|
60
|
+
* constraint). Keep the conflict target backed by a real `UNIQUE`/`PK` index,
|
|
61
|
+
* and rely on the typed `UniqueConstraintError` (2627/2601 → E008) for the
|
|
62
|
+
* loser of a race.
|
|
63
|
+
* - **Unsupported (throw `UnsupportedFeatureError`):** pgvector distance ops,
|
|
64
|
+
* LISTEN/NOTIFY (`$listen`/`$notify`), RLS `sessionContext` (sp_set_session_context
|
|
65
|
+
* exists but is connection-scoped, not transaction-local, so it is not wired —
|
|
66
|
+
* throws rather than silently leaking context across pooled connections).
|
|
67
|
+
* - **Advisory-lock migration locking** is available in principle via
|
|
68
|
+
* `sp_getapplock`/`sp_releaseapplock` (`supportsAdvisoryLock = true`); the
|
|
69
|
+
* migrate CLI is still PostgreSQL-only, so this flag documents intent for a
|
|
70
|
+
* future adapter.
|
|
71
|
+
* - **Case-insensitive matching** uses `LOWER(col) LIKE LOWER(ref)` — deterministic
|
|
72
|
+
* regardless of the column's collation (note this can defeat an index unless a
|
|
73
|
+
* computed/persisted `LOWER()` index exists).
|
|
74
|
+
* - **bignum:** the shim applies the same safe-int policy Turbine uses for Postgres
|
|
75
|
+
* `int8` (number when it fits in 2^53, decimal string otherwise) WITHOUT mutating
|
|
76
|
+
* any global driver state. `DECIMAL`/`NUMERIC`/`MONEY` come back as strings;
|
|
77
|
+
* `BIT` binds/returns booleans.
|
|
78
|
+
* - **`DISTINCT ON`** is PostgreSQL-only and is not translated — avoid `distinct`
|
|
79
|
+
* on SQL Server.
|
|
80
|
+
*
|
|
81
|
+
* ## Example
|
|
82
|
+
*
|
|
83
|
+
* ```ts
|
|
84
|
+
* import { turbineMssql } from 'turbine-orm/mssql';
|
|
85
|
+
* import { SCHEMA } from './generated/turbine/metadata.js';
|
|
86
|
+
*
|
|
87
|
+
* const db = await turbineMssql('mssql://sa:Passw0rd!@localhost:1433/app', SCHEMA);
|
|
88
|
+
* const users = await db.users.findMany({ with: { posts: true }, limit: 10 });
|
|
89
|
+
* await db.disconnect();
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
import { type PgCompatPool, type PgCompatPoolClient, TurbineClient, type TurbineConfig } from './client.js';
|
|
93
|
+
import { type Dialect, type IntrospectOptions } from './dialect.js';
|
|
94
|
+
import { type SchemaMetadata } from './schema.js';
|
|
95
|
+
interface MssqlRequest {
|
|
96
|
+
input(name: string, value: unknown): MssqlRequest;
|
|
97
|
+
query<R = Record<string, unknown>>(text: string): Promise<MssqlQueryResult<R>>;
|
|
98
|
+
batch<R = Record<string, unknown>>(text: string): Promise<MssqlQueryResult<R>>;
|
|
99
|
+
}
|
|
100
|
+
/** Per-column metadata `mssql` attaches to a recordset (`recordset.columns`). */
|
|
101
|
+
interface MssqlColumnMeta {
|
|
102
|
+
[name: string]: {
|
|
103
|
+
type?: {
|
|
104
|
+
name?: string;
|
|
105
|
+
declaration?: string;
|
|
106
|
+
};
|
|
107
|
+
} | undefined;
|
|
108
|
+
}
|
|
109
|
+
interface MssqlQueryResult<R = Record<string, unknown>> {
|
|
110
|
+
recordset?: R[] & {
|
|
111
|
+
columns?: MssqlColumnMeta;
|
|
112
|
+
};
|
|
113
|
+
recordsets?: R[][];
|
|
114
|
+
rowsAffected?: number[];
|
|
115
|
+
}
|
|
116
|
+
interface MssqlTransaction {
|
|
117
|
+
begin(isolationLevel?: number): Promise<unknown>;
|
|
118
|
+
commit(): Promise<unknown>;
|
|
119
|
+
rollback(): Promise<unknown>;
|
|
120
|
+
}
|
|
121
|
+
interface MssqlConnectionPool {
|
|
122
|
+
connect(): Promise<MssqlConnectionPool>;
|
|
123
|
+
request(): MssqlRequest;
|
|
124
|
+
close(): Promise<unknown>;
|
|
125
|
+
readonly connected?: boolean;
|
|
126
|
+
}
|
|
127
|
+
/** The subset of the `mssql` module namespace the shim constructs. */
|
|
128
|
+
interface MssqlModule {
|
|
129
|
+
connect(config: any): Promise<MssqlConnectionPool>;
|
|
130
|
+
ConnectionPool: new (config: any) => MssqlConnectionPool;
|
|
131
|
+
Request: new (parent: MssqlConnectionPool | MssqlTransaction) => MssqlRequest;
|
|
132
|
+
Transaction: new (pool: MssqlConnectionPool) => MssqlTransaction;
|
|
133
|
+
ISOLATION_LEVEL: Record<string, number>;
|
|
134
|
+
}
|
|
135
|
+
/** pg-style query argument: a SQL string or a `{ text, values }` config object. */
|
|
136
|
+
type QueryArg = string | {
|
|
137
|
+
name?: string;
|
|
138
|
+
text: string;
|
|
139
|
+
values?: unknown[];
|
|
140
|
+
};
|
|
141
|
+
/**
|
|
142
|
+
* A {@link PgCompatPool} backed by an `mssql` ConnectionPool. Non-transaction
|
|
143
|
+
* queries run on a fresh pooled `Request`; `connect()` returns a
|
|
144
|
+
* {@link MssqlTxClient} that drives a single transaction through the mssql
|
|
145
|
+
* `Transaction` API so `BEGIN`/`COMMIT`/`ROLLBACK`/savepoints all run on the same
|
|
146
|
+
* physical connection.
|
|
147
|
+
*/
|
|
148
|
+
export declare class MssqlPool implements PgCompatPool {
|
|
149
|
+
/** The underlying `mssql` ConnectionPool — exposed as an escape hatch (seed / DDL / advanced ops). */
|
|
150
|
+
readonly pool: MssqlConnectionPool;
|
|
151
|
+
private readonly sqlNS;
|
|
152
|
+
private closed;
|
|
153
|
+
constructor(pool: MssqlConnectionPool, sqlNS: MssqlModule);
|
|
154
|
+
query(text: QueryArg, values?: unknown[]): Promise<any>;
|
|
155
|
+
connect(): Promise<PgCompatPoolClient>;
|
|
156
|
+
end(): Promise<void>;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Map a SQL Server column type to a TypeScript type. `dialectType` is the
|
|
160
|
+
* `INFORMATION_SCHEMA.COLUMNS.DATA_TYPE` (lowercase, e.g. `bigint`, `nvarchar`,
|
|
161
|
+
* `datetime2`, `bit`, `uniqueidentifier`).
|
|
162
|
+
*/
|
|
163
|
+
export declare function mssqlTypeToTs(dialectType: string, nullable: boolean): string;
|
|
164
|
+
/**
|
|
165
|
+
* SQL Server 2016+ implementation of the {@link Dialect} contract. Bracket
|
|
166
|
+
* identifier quoting (`[…]`), named `@pN` placeholders, the `FOR JSON PATH`
|
|
167
|
+
* nested-relation override (no `json_agg`), no `RETURNING`
|
|
168
|
+
* (`resultStrategy = 'output'` via `OUTPUT INSERTED.*` / `MERGE`), `OFFSET/FETCH`
|
|
169
|
+
* paging, and the Postgres-only capabilities disabled (vector / LISTEN-NOTIFY /
|
|
170
|
+
* RLS).
|
|
171
|
+
*/
|
|
172
|
+
export declare const mssqlDialect: Dialect;
|
|
173
|
+
/** Async executor that returns plain row objects for a parameterized (`@pN`) query. */
|
|
174
|
+
export type MssqlRowExecutor = (sql: string, params: unknown[]) => Promise<Record<string, unknown>[]>;
|
|
175
|
+
/**
|
|
176
|
+
* Introspect a SQL Server database into the same {@link SchemaMetadata} shape the
|
|
177
|
+
* Postgres catalog introspector produces, using a caller-supplied query executor
|
|
178
|
+
* (so tests can dogfood an already-open `mssql` pool/connection). Reads
|
|
179
|
+
* `INFORMATION_SCHEMA.*` plus `sys.identity_columns` / `sys.foreign_keys` /
|
|
180
|
+
* `sys.indexes`.
|
|
181
|
+
*
|
|
182
|
+
* @param exec Runs a parameterized (`@p1`, `@p2`, …) query and returns rows.
|
|
183
|
+
* @param schema The SQL Server schema to introspect (default `dbo`).
|
|
184
|
+
*/
|
|
185
|
+
export declare function introspectMssqlWith(exec: MssqlRowExecutor, schema?: string, options?: {
|
|
186
|
+
include?: string[];
|
|
187
|
+
exclude?: string[];
|
|
188
|
+
}): Promise<SchemaMetadata>;
|
|
189
|
+
/**
|
|
190
|
+
* Open a short-lived `mssql` connection from `options.connectionString`, introspect
|
|
191
|
+
* the database (schema = `options.schema` or `dbo`), and close it. Wraps
|
|
192
|
+
* {@link introspectMssqlWith} for the {@link DialectIntrospector} seam used by
|
|
193
|
+
* `introspect()` / `npx turbine generate`.
|
|
194
|
+
*/
|
|
195
|
+
export declare function introspectMssql(options: IntrospectOptions): Promise<SchemaMetadata>;
|
|
196
|
+
interface MssqlConnectionConfig {
|
|
197
|
+
server?: string;
|
|
198
|
+
port?: number;
|
|
199
|
+
user?: string;
|
|
200
|
+
password?: string;
|
|
201
|
+
database?: string;
|
|
202
|
+
options?: {
|
|
203
|
+
encrypt?: boolean;
|
|
204
|
+
trustServerCertificate?: boolean;
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
/** Options for {@link turbineMssql}. Mirrors the relevant {@link TurbineConfig} fields. */
|
|
208
|
+
export interface TurbineMssqlOptions extends Pick<TurbineConfig, 'logging' | 'defaultLimit' | 'warnOnUnlimited'> {
|
|
209
|
+
/** SQL Server schema for introspection / DDL (default `dbo`). */
|
|
210
|
+
schema?: string;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Create a {@link TurbineClient} bound to SQL Server 2016+ via `mssql`.
|
|
214
|
+
*
|
|
215
|
+
* Pass one of:
|
|
216
|
+
* - a connection string (`'mssql://sa:pass@host:1433/db'`),
|
|
217
|
+
* - an `mssql` config object (`{ server, user, password, database, options }`),
|
|
218
|
+
* - an existing `MssqlPool` (injection — you own its lifecycle, `disconnect()` is
|
|
219
|
+
* a no-op).
|
|
220
|
+
*
|
|
221
|
+
* When Turbine builds the pool (string/config), it probes
|
|
222
|
+
* `SERVERPROPERTY('ProductMajorVersion')` to reject SQL Server < 2016, and
|
|
223
|
+
* `disconnect()` closes the pool it created.
|
|
224
|
+
*
|
|
225
|
+
* @example
|
|
226
|
+
* ```ts
|
|
227
|
+
* import { turbineMssql } from 'turbine-orm/mssql';
|
|
228
|
+
* const db = await turbineMssql('mssql://sa:Passw0rd!@localhost:1433/app', SCHEMA);
|
|
229
|
+
* ```
|
|
230
|
+
*/
|
|
231
|
+
export declare function turbineMssql(target: string | MssqlConnectionConfig | MssqlPool, schema: SchemaMetadata, options?: TurbineMssqlOptions): Promise<TurbineClient>;
|
|
232
|
+
export {};
|
|
233
|
+
//# sourceMappingURL=mssql.d.ts.map
|