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.
- package/README.md +122 -39
- package/dist/cjs/adapters/cockroachdb.d.ts +39 -0
- package/dist/cjs/adapters/index.d.ts +110 -0
- package/dist/cjs/adapters/yugabytedb.d.ts +51 -0
- package/dist/cjs/cli/config.d.ts +181 -0
- package/dist/cjs/cli/config.js +32 -6
- package/dist/cjs/cli/destructive.d.ts +38 -0
- package/dist/cjs/cli/index.d.ts +359 -0
- package/dist/cjs/cli/index.js +228 -56
- package/dist/cjs/cli/loader.d.ts +61 -0
- package/dist/cjs/cli/mcp.d.ts +42 -0
- package/dist/cjs/cli/migrate.d.ts +356 -0
- package/dist/cjs/cli/migrate.js +131 -40
- package/dist/cjs/cli/observe-ui.d.ts +1 -0
- package/dist/cjs/cli/observe-ui.js +14 -5
- package/dist/cjs/cli/observe.d.ts +25 -0
- package/dist/cjs/cli/observe.js +49 -12
- package/dist/cjs/cli/pii-tags.d.ts +53 -0
- package/dist/cjs/cli/prisma-report.d.ts +33 -0
- package/dist/cjs/cli/prisma-report.js +73 -0
- package/dist/cjs/cli/prisma-resolve.d.ts +106 -0
- package/dist/cjs/cli/prisma-resolve.js +1 -0
- package/dist/cjs/cli/prisma-schema.d.ts +176 -0
- package/dist/cjs/cli/prisma-schema.js +82 -4
- package/dist/cjs/cli/rate-limit.d.ts +32 -0
- package/dist/cjs/cli/rate-limit.js +45 -0
- package/dist/cjs/cli/studio-demo.d.ts +43 -0
- package/dist/cjs/cli/studio-ui.generated.d.ts +1 -0
- package/dist/cjs/cli/studio.d.ts +207 -0
- package/dist/cjs/cli/studio.js +136 -71
- package/dist/cjs/cli/ui.d.ts +73 -0
- package/dist/cjs/cli/ui.js +51 -9
- package/dist/cjs/client.d.ts +837 -0
- package/dist/cjs/client.js +3 -0
- package/dist/cjs/dialect.d.ts +516 -0
- package/dist/cjs/dialect.js +37 -12
- package/dist/cjs/errors.d.ts +370 -0
- package/dist/cjs/generate.d.ts +137 -0
- package/dist/cjs/generate.js +39 -6
- package/dist/cjs/index-advisor.d.ts +153 -0
- package/dist/cjs/index-stats.d.ts +384 -0
- package/dist/cjs/index.d.ts +55 -0
- package/dist/cjs/index.js +7 -2
- package/dist/cjs/introspect.d.ts +269 -0
- package/dist/cjs/mssql.d.ts +232 -0
- package/dist/cjs/mssql.js +6 -0
- package/dist/cjs/mysql.d.ts +173 -0
- package/dist/cjs/mysql.js +16 -0
- package/dist/cjs/nested-write.d.ts +96 -0
- package/dist/cjs/nested-write.js +414 -24
- package/dist/cjs/observe.d.ts +115 -0
- package/dist/cjs/optional-peer-import.d.cts +72 -0
- package/dist/cjs/pipeline-submittable.d.ts +93 -0
- package/dist/cjs/pipeline.d.ts +71 -0
- package/dist/cjs/powdb-introspect.d.ts +84 -0
- package/dist/cjs/powdb.d.ts +931 -0
- package/dist/cjs/powdb.js +106 -21
- package/dist/cjs/powql.d.ts +592 -0
- package/dist/cjs/powql.js +42 -6
- package/dist/cjs/prisma-compat.d.ts +283 -0
- package/dist/cjs/prisma-compat.js +167 -9
- package/dist/cjs/query/aggregates.d.ts +92 -0
- package/dist/cjs/query/aggregates.js +7 -3
- package/dist/cjs/query/batched-loader.d.ts +193 -0
- package/dist/cjs/query/builder.d.ts +849 -0
- package/dist/cjs/query/builder.js +571 -65
- package/dist/cjs/query/compound-unique.d.ts +51 -0
- package/dist/cjs/query/deferred.d.ts +223 -0
- package/dist/cjs/query/filters.d.ts +201 -0
- package/dist/cjs/query/index.d.ts +14 -0
- package/dist/cjs/query/index.js +6 -1
- package/dist/cjs/query/relations.d.ts +609 -0
- package/dist/cjs/query/relations.js +693 -46
- package/dist/cjs/query/types.d.ts +1300 -0
- package/dist/cjs/query/utils.d.ts +209 -0
- package/dist/cjs/query/utils.js +208 -1
- package/dist/cjs/query/warn-registry.d.ts +68 -0
- package/dist/cjs/query/warn-registry.js +9 -0
- package/dist/cjs/query/where-compile.d.ts +139 -0
- package/dist/cjs/query/where.d.ts +548 -0
- package/dist/cjs/query/where.js +58 -22
- package/dist/cjs/query/writes.d.ts +172 -0
- package/dist/cjs/query/writes.js +105 -12
- package/dist/cjs/realtime.d.ts +70 -0
- package/dist/cjs/schema-builder.d.ts +354 -0
- package/dist/cjs/schema-metadata.d.ts +83 -0
- package/dist/cjs/schema-sql.d.ts +217 -0
- package/dist/cjs/schema-sql.js +23 -5
- package/dist/cjs/schema.d.ts +356 -0
- package/dist/cjs/schema.js +125 -0
- package/dist/cjs/seed.d.ts +15 -0
- package/dist/cjs/serverless.d.ts +142 -0
- package/dist/cjs/sqlite.d.ts +143 -0
- package/dist/cjs/sqlite.js +4 -0
- package/dist/cjs/typed-sql.d.ts +102 -0
- package/dist/cli/config.d.ts +18 -4
- package/dist/cli/config.js +31 -6
- package/dist/cli/index.d.ts +123 -0
- package/dist/cli/index.js +223 -58
- package/dist/cli/migrate.d.ts +59 -10
- package/dist/cli/migrate.js +128 -41
- package/dist/cli/observe-ui.d.ts +1 -1
- package/dist/cli/observe-ui.js +14 -5
- package/dist/cli/observe.d.ts +7 -1
- package/dist/cli/observe.js +48 -12
- package/dist/cli/prisma-report.d.ts +14 -0
- package/dist/cli/prisma-report.js +72 -0
- package/dist/cli/prisma-resolve.d.ts +6 -0
- package/dist/cli/prisma-resolve.js +1 -0
- package/dist/cli/prisma-schema.d.ts +62 -2
- package/dist/cli/prisma-schema.js +81 -4
- package/dist/cli/rate-limit.d.ts +32 -0
- package/dist/cli/rate-limit.js +40 -0
- package/dist/cli/studio.d.ts +5 -5
- package/dist/cli/studio.js +135 -70
- package/dist/cli/ui.d.ts +1 -1
- package/dist/cli/ui.js +51 -9
- package/dist/client.d.ts +40 -0
- package/dist/client.js +3 -0
- package/dist/dialect.d.ts +17 -1
- package/dist/dialect.js +37 -12
- package/dist/generate.js +40 -7
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/mssql.js +6 -0
- package/dist/mysql.js +16 -0
- package/dist/nested-write.d.ts +2 -0
- package/dist/nested-write.js +415 -25
- package/dist/powdb.d.ts +4 -2
- package/dist/powdb.js +106 -21
- package/dist/powql.d.ts +5 -0
- package/dist/powql.js +42 -6
- package/dist/prisma-compat.d.ts +2 -0
- package/dist/prisma-compat.js +166 -8
- package/dist/query/aggregates.js +7 -3
- package/dist/query/builder.d.ts +292 -21
- package/dist/query/builder.js +570 -64
- package/dist/query/deferred.d.ts +39 -0
- package/dist/query/index.d.ts +1 -1
- package/dist/query/index.js +1 -1
- package/dist/query/relations.d.ts +173 -5
- package/dist/query/relations.js +688 -47
- package/dist/query/types.d.ts +123 -39
- package/dist/query/utils.d.ts +116 -0
- package/dist/query/utils.js +198 -0
- package/dist/query/warn-registry.d.ts +9 -0
- package/dist/query/warn-registry.js +9 -0
- package/dist/query/where.d.ts +38 -1
- package/dist/query/where.js +58 -23
- package/dist/query/writes.d.ts +42 -1
- package/dist/query/writes.js +104 -13
- package/dist/schema-sql.d.ts +14 -0
- package/dist/schema-sql.js +23 -5
- package/dist/schema.d.ts +38 -0
- package/dist/schema.js +123 -0
- package/dist/sqlite.js +4 -0
- package/package.json +77 -28
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* turbine-orm/serverless — edge / serverless driver integration
|
|
3
|
+
*
|
|
4
|
+
* Turbine runs on any Postgres driver that speaks the node-postgres API.
|
|
5
|
+
* This module exposes a thin factory (`turbineHttp`) that binds an external
|
|
6
|
+
* pg-compatible pool to a schema, so you can use Turbine on Vercel Edge,
|
|
7
|
+
* Cloudflare Workers, Deno Deploy, Netlify Edge, or any other environment
|
|
8
|
+
* where a direct TCP connection is unavailable.
|
|
9
|
+
*
|
|
10
|
+
* ## Supported drivers
|
|
11
|
+
*
|
|
12
|
+
* Any driver whose `Pool` satisfies `PgCompatPool` will work. The ones
|
|
13
|
+
* below are verified:
|
|
14
|
+
*
|
|
15
|
+
* - **Neon** (`@neondatabase/serverless`) — HTTP and WebSocket transports
|
|
16
|
+
* - **Vercel Postgres** (`@vercel/postgres`) — wraps Neon
|
|
17
|
+
* - **Cloudflare Hyperdrive** — exposes a pg-compatible driver
|
|
18
|
+
* - **Supabase** — use the regular `pg` package; Supabase is Postgres-native
|
|
19
|
+
*
|
|
20
|
+
* Turbine does NOT bundle any of these — install whichever you need and
|
|
21
|
+
* pass its pool directly.
|
|
22
|
+
*
|
|
23
|
+
* ## Limitations over HTTP
|
|
24
|
+
*
|
|
25
|
+
* - **Streaming cursors** (`findManyStream`, `findManyCursor`) require
|
|
26
|
+
* server-side `DECLARE CURSOR`, which most HTTP drivers do not support.
|
|
27
|
+
* If you call these on an HTTP pool the underlying driver will error.
|
|
28
|
+
* - **LISTEN/NOTIFY** is not available over HTTP.
|
|
29
|
+
* - **Transactions** are supported but each transaction holds an HTTP
|
|
30
|
+
* connection for its duration — keep them short.
|
|
31
|
+
*
|
|
32
|
+
* ## Example — Neon on Vercel Edge
|
|
33
|
+
*
|
|
34
|
+
* ```ts
|
|
35
|
+
* // app/api/users/route.ts
|
|
36
|
+
* import { Pool } from '@neondatabase/serverless';
|
|
37
|
+
* import { turbineHttp } from 'turbine-orm/serverless';
|
|
38
|
+
* import { SCHEMA } from '../../generated/turbine/metadata';
|
|
39
|
+
*
|
|
40
|
+
* export const runtime = 'edge';
|
|
41
|
+
*
|
|
42
|
+
* const pool = new Pool({ connectionString: process.env.DATABASE_URL });
|
|
43
|
+
* const db = turbineHttp(pool, SCHEMA);
|
|
44
|
+
*
|
|
45
|
+
* export async function GET() {
|
|
46
|
+
* const users = await db.table('users').findMany({ limit: 10 });
|
|
47
|
+
* return Response.json(users);
|
|
48
|
+
* }
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* ## Example — Supabase (direct Postgres, no HTTP proxy needed)
|
|
52
|
+
*
|
|
53
|
+
* ```ts
|
|
54
|
+
* import { TurbineClient } from 'turbine-orm';
|
|
55
|
+
* import { SCHEMA } from './generated/turbine/metadata.js';
|
|
56
|
+
*
|
|
57
|
+
* const db = new TurbineClient({
|
|
58
|
+
* connectionString: process.env.SUPABASE_DB_URL,
|
|
59
|
+
* ssl: { rejectUnauthorized: false },
|
|
60
|
+
* }, SCHEMA);
|
|
61
|
+
* ```
|
|
62
|
+
*
|
|
63
|
+
* ## Example — Cloudflare Workers
|
|
64
|
+
*
|
|
65
|
+
* ```ts
|
|
66
|
+
* // Use the Neon HTTP driver which works in Workers runtime
|
|
67
|
+
* import { Pool } from '@neondatabase/serverless';
|
|
68
|
+
* import { turbineHttp } from 'turbine-orm/serverless';
|
|
69
|
+
* import { SCHEMA } from './generated/turbine/metadata';
|
|
70
|
+
*
|
|
71
|
+
* export default {
|
|
72
|
+
* async fetch(req: Request, env: Env) {
|
|
73
|
+
* const pool = new Pool({ connectionString: env.DATABASE_URL });
|
|
74
|
+
* const db = turbineHttp(pool, SCHEMA);
|
|
75
|
+
* const users = await db.table('users').findMany({ limit: 10 });
|
|
76
|
+
* return Response.json(users);
|
|
77
|
+
* }
|
|
78
|
+
* };
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
import { type PgCompatPool, TurbineClient, type TurbineConfig } from './client.js';
|
|
82
|
+
import type { SchemaMetadata } from './schema.js';
|
|
83
|
+
export type { PgCompatPool, PgCompatPoolClient, PgCompatQueryResult } from './client.js';
|
|
84
|
+
/**
|
|
85
|
+
* Options for `turbineHttp()`. Mirrors the fields of `TurbineConfig`
|
|
86
|
+
* that are relevant for externally-managed pools.
|
|
87
|
+
*/
|
|
88
|
+
export interface TurbineHttpOptions extends Pick<TurbineConfig, 'logging' | 'defaultLimit' | 'warnOnUnlimited'> {
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Create a TurbineClient bound to an external pg-compatible pool.
|
|
92
|
+
*
|
|
93
|
+
* Use this for serverless/edge environments where Turbine should NOT
|
|
94
|
+
* manage its own `pg.Pool`. The caller retains ownership of the pool's
|
|
95
|
+
* lifecycle — `db.disconnect()` is a no-op.
|
|
96
|
+
*
|
|
97
|
+
* ## Typed table accessors
|
|
98
|
+
*
|
|
99
|
+
* By default `turbineHttp` returns the base {@link TurbineClient}, so you
|
|
100
|
+
* reach tables through `db.table('users')`. To get the *generated*, fully
|
|
101
|
+
* typed accessors (`db.users.findMany()`) — identical to what the TCP-path
|
|
102
|
+
* `turbine()` factory gives you — pass your generated client type as the
|
|
103
|
+
* `TClient` type argument. The runtime object is the same; the generated
|
|
104
|
+
* subclass only adds `declare readonly` accessor typings, and the base
|
|
105
|
+
* constructor already creates those accessors at runtime for every table in
|
|
106
|
+
* the schema, so the assertion is sound (not a lie about the shape).
|
|
107
|
+
*
|
|
108
|
+
* This closes the "identical typed code across transports" gap: the edge
|
|
109
|
+
* client is now as typed as the direct one, with no `as` casts at the call
|
|
110
|
+
* site.
|
|
111
|
+
*
|
|
112
|
+
* @typeParam TClient - The generated `TurbineClient` subclass (from
|
|
113
|
+
* `./generated/turbine`). Defaults to the base client for back-compat.
|
|
114
|
+
* @param pool - Any pg-compatible pool (Neon, Vercel Postgres, etc.)
|
|
115
|
+
* @param schema - Introspected or hand-written schema metadata
|
|
116
|
+
* @param options - Optional logging / defaultLimit / warnOnUnlimited
|
|
117
|
+
* @returns A TurbineClient instance (typed as `TClient`)
|
|
118
|
+
*
|
|
119
|
+
* @example Untyped (back-compat) — reach tables via `db.table(...)`
|
|
120
|
+
* ```ts
|
|
121
|
+
* import { Pool } from '@neondatabase/serverless';
|
|
122
|
+
* import { turbineHttp } from 'turbine-orm/serverless';
|
|
123
|
+
* import { SCHEMA } from './generated/turbine/metadata.js';
|
|
124
|
+
*
|
|
125
|
+
* const pool = new Pool({ connectionString: process.env.DATABASE_URL });
|
|
126
|
+
* const db = turbineHttp(pool, SCHEMA);
|
|
127
|
+
* const users = await db.table('users').findMany({ limit: 10 });
|
|
128
|
+
* ```
|
|
129
|
+
*
|
|
130
|
+
* @example Typed — generated accessors, identical to the TCP client
|
|
131
|
+
* ```ts
|
|
132
|
+
* import { Pool } from '@neondatabase/serverless';
|
|
133
|
+
* import { turbineHttp } from 'turbine-orm/serverless';
|
|
134
|
+
* import type { TurbineClient } from './generated/turbine';
|
|
135
|
+
* import { SCHEMA } from './generated/turbine/metadata.js';
|
|
136
|
+
*
|
|
137
|
+
* const pool = new Pool({ connectionString: process.env.DATABASE_URL });
|
|
138
|
+
* const db = turbineHttp<TurbineClient>(pool, SCHEMA);
|
|
139
|
+
* const users = await db.users.findMany({ limit: 10 }); // fully typed, no cast
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
export declare function turbineHttp<TClient extends TurbineClient = TurbineClient>(pool: PgCompatPool, schema: SchemaMetadata, options?: TurbineHttpOptions): TClient;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* turbine-orm/sqlite — zero-dependency SQLite engine
|
|
3
|
+
*
|
|
4
|
+
* Binds Turbine to SQLite via Node's built-in `node:sqlite` driver
|
|
5
|
+
* (`DatabaseSync`), so SQLite is a **zero new dependency** engine: the root
|
|
6
|
+
* package's runtime dependency stays exactly `pg`. This is the in-process
|
|
7
|
+
* test / edge / "try it in 10 seconds" engine — `:memory:` databases run
|
|
8
|
+
* entirely in-process with no service container.
|
|
9
|
+
*
|
|
10
|
+
* ## Driver
|
|
11
|
+
*
|
|
12
|
+
* - **Primary:** `node:sqlite` `DatabaseSync` (Node ≥ 22.5, experimental). Emits
|
|
13
|
+
* an `ExperimentalWarning` — harmless. No native build, no extra dependency.
|
|
14
|
+
* - **Fallback:** `better-sqlite3` for Node < 22.5. Not bundled and not required;
|
|
15
|
+
* wrap a `better-sqlite3` handle in the same `PgCompatPool` shape if needed.
|
|
16
|
+
*
|
|
17
|
+
* ## Capabilities & limits (vs PostgreSQL)
|
|
18
|
+
*
|
|
19
|
+
* - `RETURNING` + `ON CONFLICT … DO UPDATE` (SQLite ≥ 3.35) → create / upsert /
|
|
20
|
+
* update / delete return real rows in a single statement (`resultStrategy =
|
|
21
|
+
* 'returning'`, same as Postgres).
|
|
22
|
+
* - **Single-writer:** one connection / one write transaction at a time;
|
|
23
|
+
* concurrent writers get `SQLITE_BUSY` (treated as retryable). `journal_mode =
|
|
24
|
+
* WAL` is enabled for file databases to allow concurrent readers.
|
|
25
|
+
* - **Unsupported (throw `UnsupportedFeatureError`):** pgvector distance ops,
|
|
26
|
+
* LISTEN/NOTIFY (`$listen` / `$notify`), RLS `sessionContext`. Advisory-lock
|
|
27
|
+
* migration locking is unavailable — SQLite is single-writer, so migrations
|
|
28
|
+
* serialize naturally.
|
|
29
|
+
* - **Type affinity caveats:** SQLite has no native `BOOLEAN` (0/1 integers) or
|
|
30
|
+
* `DATE` (TEXT/INTEGER). Booleans bind as 1/0; `Date` values bind as ISO-8601
|
|
31
|
+
* text; columns declared `TIMESTAMP`/`DATETIME`/`DATE` are coerced back to
|
|
32
|
+
* `Date`. Integers wider than `Number.MAX_SAFE_INTEGER` come back as strings
|
|
33
|
+
* (the same safe-int policy Turbine uses for Postgres `int8`).
|
|
34
|
+
* - **Case-insensitive matching** uses `COLLATE NOCASE`, which is **ASCII-only**
|
|
35
|
+
* (no Unicode case folding).
|
|
36
|
+
*
|
|
37
|
+
* ## Example — `:memory:` database
|
|
38
|
+
*
|
|
39
|
+
* ```ts
|
|
40
|
+
* import { turbineSqlite } from 'turbine-orm/sqlite';
|
|
41
|
+
* import { SCHEMA } from './generated/turbine/metadata.js';
|
|
42
|
+
*
|
|
43
|
+
* const db = turbineSqlite(':memory:', SCHEMA);
|
|
44
|
+
* const users = await db.users.findMany({ with: { posts: true }, limit: 10 });
|
|
45
|
+
* await db.disconnect();
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
import type { DatabaseSync } from 'node:sqlite';
|
|
49
|
+
import { type PgCompatPool, type PgCompatPoolClient, TurbineClient, type TurbineConfig } from './client.js';
|
|
50
|
+
import { type Dialect, type IntrospectOptions } from './dialect.js';
|
|
51
|
+
import { type SchemaMetadata, type TableMetadata } from './schema.js';
|
|
52
|
+
/** pg-style query argument: a SQL string or a `{ text, values }` config object. */
|
|
53
|
+
type QueryArg = string | {
|
|
54
|
+
name?: string;
|
|
55
|
+
text: string;
|
|
56
|
+
values?: unknown[];
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* A `PgCompatPool` backed by a single `node:sqlite` `DatabaseSync` connection.
|
|
60
|
+
* SQLite is single-connection by nature (a `:memory:` database is per-handle),
|
|
61
|
+
* so `connect()` hands back a client over the **same** handle — transactions
|
|
62
|
+
* (`BEGIN`/`COMMIT`/`ROLLBACK`, `SAVEPOINT` nesting) just run on it. Queries are
|
|
63
|
+
* serialized; this is the documented single-writer model.
|
|
64
|
+
*/
|
|
65
|
+
export declare class SqlitePool implements PgCompatPool {
|
|
66
|
+
/** The underlying `node:sqlite` handle — exposed as an escape hatch (seed/DDL). */
|
|
67
|
+
readonly db: DatabaseSync;
|
|
68
|
+
private closed;
|
|
69
|
+
constructor(db: DatabaseSync);
|
|
70
|
+
query(text: QueryArg, values?: unknown[]): Promise<any>;
|
|
71
|
+
connect(): Promise<PgCompatPoolClient>;
|
|
72
|
+
end(): Promise<void>;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Map a SQLite declared column type (type affinity) to a TypeScript type.
|
|
76
|
+
* SQLite is dynamically typed; we read the declared `PRAGMA table_info` type.
|
|
77
|
+
*/
|
|
78
|
+
export declare function sqliteTypeToTs(declaredType: string, nullable: boolean): string;
|
|
79
|
+
/**
|
|
80
|
+
* SQLite implementation of the {@link Dialect} contract. Standardizes on `"…"`
|
|
81
|
+
* identifier quoting and positional `?` placeholders, uses `json_object` /
|
|
82
|
+
* `json_group_array` for the single-query nested-relation engine (with the
|
|
83
|
+
* critical `json(...)` subresult wrap so nested objects are real JSON, not
|
|
84
|
+
* SQLite's strings-of-strings double-encoding), keeps `RETURNING` + `ON CONFLICT`
|
|
85
|
+
* (SQLite ≥ 3.35), and disables the Postgres-only capabilities (vector,
|
|
86
|
+
* LISTEN/NOTIFY, RLS, advisory locks).
|
|
87
|
+
*/
|
|
88
|
+
export declare const sqliteDialect: Dialect;
|
|
89
|
+
/**
|
|
90
|
+
* Read a live SQLite database (an open `DatabaseSync` handle) into the same
|
|
91
|
+
* {@link SchemaMetadata} shape the Postgres catalog introspector produces.
|
|
92
|
+
* Exposed directly so callers (and tests) can introspect an in-process
|
|
93
|
+
* `:memory:` database without round-tripping through a file path.
|
|
94
|
+
*/
|
|
95
|
+
export declare function introspectSqliteDatabase(db: DatabaseSync, options?: {
|
|
96
|
+
include?: string[];
|
|
97
|
+
exclude?: string[];
|
|
98
|
+
}): {
|
|
99
|
+
tables: Record<string, TableMetadata>;
|
|
100
|
+
enums: {};
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Open the SQLite database named by `options.connectionString` (a file path or
|
|
104
|
+
* `':memory:'`), introspect it, and close it. Wraps
|
|
105
|
+
* {@link introspectSqliteDatabase} for the {@link DialectIntrospector} seam used
|
|
106
|
+
* by `introspect()` / `npx turbine generate`.
|
|
107
|
+
*
|
|
108
|
+
* Note: introspecting `':memory:'` opens a *fresh, empty* database (memory DBs
|
|
109
|
+
* are per-handle), so codegen should target a real file.
|
|
110
|
+
*/
|
|
111
|
+
export declare function introspectSqlite(options: IntrospectOptions): Promise<SchemaMetadata>;
|
|
112
|
+
/** Options for {@link turbineSqlite}. Mirrors the relevant {@link TurbineConfig} fields. */
|
|
113
|
+
export interface TurbineSqliteOptions extends Pick<TurbineConfig, 'logging' | 'defaultLimit' | 'warnOnUnlimited'> {
|
|
114
|
+
/**
|
|
115
|
+
* Enable WAL journal mode for file databases (better read concurrency).
|
|
116
|
+
* Ignored for `':memory:'`. Default: `true`.
|
|
117
|
+
*/
|
|
118
|
+
wal?: boolean;
|
|
119
|
+
/** `PRAGMA busy_timeout` in ms — how long a writer waits on `SQLITE_BUSY`. Default: 5000. */
|
|
120
|
+
busyTimeoutMs?: number;
|
|
121
|
+
/** Enable `PRAGMA foreign_keys` enforcement. Default: `true`. */
|
|
122
|
+
foreignKeys?: boolean;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Create a {@link TurbineClient} bound to SQLite via `node:sqlite`.
|
|
126
|
+
*
|
|
127
|
+
* Pass a file path, `':memory:'`, or an already-open `DatabaseSync` handle (so
|
|
128
|
+
* you can seed / introspect it first and reuse the same connection). The
|
|
129
|
+
* returned client uses {@link sqliteDialect} and disables prepared-statement
|
|
130
|
+
* names (SQLite caches plans internally).
|
|
131
|
+
*
|
|
132
|
+
* @param target A SQLite file path, `':memory:'`, or an open `DatabaseSync`.
|
|
133
|
+
* @param schema Introspected or hand-written {@link SchemaMetadata}.
|
|
134
|
+
* @param options Optional pragmas + logging / defaultLimit / warnOnUnlimited.
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* ```ts
|
|
138
|
+
* import { turbineSqlite } from 'turbine-orm/sqlite';
|
|
139
|
+
* const db = turbineSqlite(':memory:', SCHEMA);
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
export declare function turbineSqlite(target: string | DatabaseSync, schema: SchemaMetadata, options?: TurbineSqliteOptions): TurbineClient;
|
|
143
|
+
export {};
|
package/dist/cjs/sqlite.js
CHANGED
|
@@ -462,6 +462,10 @@ exports.sqliteDialect = {
|
|
|
462
462
|
buildUpsertStatement(input) {
|
|
463
463
|
return (`INSERT INTO ${input.table} (${input.insertColumns.join(', ')}) VALUES (${input.valuePlaceholders.join(', ')})` +
|
|
464
464
|
` ON CONFLICT (${input.conflictColumns.join(', ')}) DO UPDATE SET ${input.updateSetClauses.join(', ')}` +
|
|
465
|
+
// SQLite's upsert takes the same trailing conflict-UPDATE predicate as
|
|
466
|
+
// Postgres, so `supportsUpsertUpdateWhere` (inherited true) is honest and
|
|
467
|
+
// global filters restrict the UPDATE branch here too.
|
|
468
|
+
(input.updateWhere ? ` WHERE ${input.updateWhere}` : '') +
|
|
465
469
|
this.buildReturningClause(input.returning));
|
|
466
470
|
},
|
|
467
471
|
buildInsensitiveLike(column, paramRef) {
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* turbine-orm — Typed raw SQL (Turbine's answer to Prisma's TypedSQL)
|
|
3
|
+
*
|
|
4
|
+
* `client.raw()` returns untyped rows. This module adds a *typed* escape hatch:
|
|
5
|
+
* a generic tagged template where the caller supplies the row shape, and the
|
|
6
|
+
* builder yields a typed result that can be awaited as an array of rows, or
|
|
7
|
+
* narrowed to a single row (`.one()`) or a single scalar value (`.scalar()`).
|
|
8
|
+
*
|
|
9
|
+
* Design goals & guarantees:
|
|
10
|
+
*
|
|
11
|
+
* 1. **Compile-time only types.** `T` is supplied by the caller and never
|
|
12
|
+
* validated at runtime — exactly like Prisma's TypedSQL and the existing
|
|
13
|
+
* `raw<T>()`. Postgres still returns whatever the SQL selects; the generic
|
|
14
|
+
* is a convenience for autocomplete and downstream type-checking.
|
|
15
|
+
*
|
|
16
|
+
* 2. **Mandatory parameterization.** Only the *static* string segments of the
|
|
17
|
+
* template literal ever reach the SQL text. Every interpolated `${value}`
|
|
18
|
+
* becomes a `$N` placeholder and is passed in the params array — it is
|
|
19
|
+
* impossible to string-concatenate a value into the query through this API.
|
|
20
|
+
* This is the whole point of the tagged-template shape: the literal segments
|
|
21
|
+
* are frozen by the compiler (`TemplateStringsArray`), and the only way to
|
|
22
|
+
* get a runtime value into the query is via `${...}`, which we bind.
|
|
23
|
+
*
|
|
24
|
+
* 3. **Rows are returned as-is (no snake→camel mapping).** This matches the
|
|
25
|
+
* existing `client.raw()` behavior: a typed raw query is a literal escape
|
|
26
|
+
* hatch, so the result columns are whatever your `SELECT` names them. Alias
|
|
27
|
+
* columns in SQL (`SELECT created_at AS "createdAt"`) if you want camelCase.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* // Awaited directly -> rows
|
|
32
|
+
* const rows = await db.sql<{ id: number; name: string }>`
|
|
33
|
+
* SELECT id, name FROM users WHERE org_id = ${orgId}
|
|
34
|
+
* `;
|
|
35
|
+
* // ^? { id: number; name: string }[]
|
|
36
|
+
*
|
|
37
|
+
* // .one() -> single row or null
|
|
38
|
+
* const user = await db.sql<{ id: number; name: string }>`
|
|
39
|
+
* SELECT id, name FROM users WHERE id = ${userId}
|
|
40
|
+
* `.one();
|
|
41
|
+
* // ^? { id: number; name: string } | null
|
|
42
|
+
*
|
|
43
|
+
* // .scalar() -> first column of first row, or null
|
|
44
|
+
* const total = await db.sql<{ count: number }>`
|
|
45
|
+
* SELECT COUNT(*)::int AS count FROM users WHERE org_id = ${orgId}
|
|
46
|
+
* `.scalar();
|
|
47
|
+
* // ^? number | null
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
import type { PgCompatPool } from './client.js';
|
|
51
|
+
import { type Dialect } from './dialect.js';
|
|
52
|
+
/**
|
|
53
|
+
* Build a `(sql, params)` pair from a tagged-template invocation.
|
|
54
|
+
*
|
|
55
|
+
* Each interpolated value is replaced by a positional placeholder (the active
|
|
56
|
+
* dialect's `paramPlaceholder`, `$N` for PostgreSQL) and pushed to the params
|
|
57
|
+
* array in order. The static string segments are the only thing concatenated
|
|
58
|
+
* into the SQL text. This is the single point that guarantees parameterization
|
|
59
|
+
* for the entire typed-SQL surface.
|
|
60
|
+
*
|
|
61
|
+
* Exported for unit testing the parameterization invariant without a database.
|
|
62
|
+
*/
|
|
63
|
+
export declare function buildTypedSql(strings: TemplateStringsArray, values: readonly unknown[], dialect?: Pick<Dialect, 'paramPlaceholder'>): {
|
|
64
|
+
sql: string;
|
|
65
|
+
params: unknown[];
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* A pending typed raw SQL query. Implements the thenable contract, so it can be
|
|
69
|
+
* `await`ed directly to get `T[]`, or refined via `.one()` / `.scalar()` first.
|
|
70
|
+
*
|
|
71
|
+
* The query is executed lazily and exactly once per terminal call (`then`,
|
|
72
|
+
* `one`, `scalar`). Each terminal method runs the query independently — this is
|
|
73
|
+
* an escape hatch, not a cached query object, so don't call two terminals on
|
|
74
|
+
* the same builder expecting a single round-trip; build a fresh template each
|
|
75
|
+
* time (the common pattern is `await db.sql\`...\`` inline).
|
|
76
|
+
*/
|
|
77
|
+
export declare class TypedSqlQuery<T extends Record<string, unknown>> implements PromiseLike<T[]> {
|
|
78
|
+
private readonly pool;
|
|
79
|
+
private readonly sql;
|
|
80
|
+
private readonly params;
|
|
81
|
+
private readonly logging;
|
|
82
|
+
constructor(pool: PgCompatPool, sql: string, params: unknown[], logging: boolean);
|
|
83
|
+
/** Execute and return all rows. Internal; powers `then`, `one`, and `scalar`. */
|
|
84
|
+
private run;
|
|
85
|
+
/**
|
|
86
|
+
* PromiseLike implementation: `await db.sql<T>\`...\`` resolves to `T[]`.
|
|
87
|
+
*/
|
|
88
|
+
then<TResult1 = T[], TResult2 = never>(onfulfilled?: ((value: T[]) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
|
|
89
|
+
/**
|
|
90
|
+
* Execute and return the first row, or `null` if the query returns no rows.
|
|
91
|
+
* Use for queries you expect to match at most one row.
|
|
92
|
+
*/
|
|
93
|
+
one(): Promise<T | null>;
|
|
94
|
+
/**
|
|
95
|
+
* Execute and return the first column of the first row, or `null` if there
|
|
96
|
+
* are no rows. Useful for `SELECT COUNT(*)`, `SELECT EXISTS(...)`, etc.
|
|
97
|
+
*
|
|
98
|
+
* The generic `V` defaults to the value type of `T`'s first property, but you
|
|
99
|
+
* can override it: `db.sql<{ count: number }>\`...\`.scalar<number>()`.
|
|
100
|
+
*/
|
|
101
|
+
scalar<V = T[keyof T]>(): Promise<V | null>;
|
|
102
|
+
}
|
package/dist/cli/config.d.ts
CHANGED
|
@@ -34,10 +34,17 @@ export interface TurbineCliConfig {
|
|
|
34
34
|
legacyToManyUniques?: boolean;
|
|
35
35
|
/** Directory for migration files (default: ./turbine/migrations) */
|
|
36
36
|
migrationsDir?: string;
|
|
37
|
-
/**
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
/**
|
|
38
|
+
* Path to the seed file (canonical key). With no value, discovery falls back
|
|
39
|
+
* to seed.ts, seed.js, seed.sql, then the same three under `turbine/`.
|
|
40
|
+
*/
|
|
40
41
|
seedFile?: string;
|
|
42
|
+
/**
|
|
43
|
+
* Path to the seed file. Back-compat alias for {@link TurbineCliConfig.seedFile}:
|
|
44
|
+
* older `turbine init` runs scaffolded this spelling. `seedFile` wins when both
|
|
45
|
+
* are set.
|
|
46
|
+
*/
|
|
47
|
+
seed?: string;
|
|
41
48
|
/** Schema builder file path (for push command) */
|
|
42
49
|
schemaFile?: string;
|
|
43
50
|
/**
|
|
@@ -66,6 +73,12 @@ export type TurbineConfig = TurbineCliConfig;
|
|
|
66
73
|
* silently matches zero tables. Used by `turbine generate` to fail loudly.
|
|
67
74
|
*/
|
|
68
75
|
export declare function looksLikeSchemaFilePath(schema: string): boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Where `turbine init` scaffolds the seed file, and the `seedFile` value it
|
|
78
|
+
* writes into the generated config. Kept next to the schema file so a new
|
|
79
|
+
* project's Turbine files live in one directory.
|
|
80
|
+
*/
|
|
81
|
+
export declare const DEFAULT_INIT_SEED_FILE = "./turbine/seed.ts";
|
|
69
82
|
/** A config-file load attempt that failed, kept so the CLI can surface it. */
|
|
70
83
|
export interface ConfigLoadError {
|
|
71
84
|
/** The config file whose import threw (e.g. `turbine.config.ts`). */
|
|
@@ -161,7 +174,8 @@ export interface CliOverrides {
|
|
|
161
174
|
export declare function resolveConfig(fileConfig: TurbineCliConfig, overrides: CliOverrides): ResolvedConfig;
|
|
162
175
|
/**
|
|
163
176
|
* Resolve the seed file path. An explicit config value wins even if the file
|
|
164
|
-
* does not exist yet; otherwise
|
|
177
|
+
* does not exist yet; otherwise {@link DEFAULT_SEED_CANDIDATES} is tried in
|
|
178
|
+
* order (root-level first, then the `turbine/` location `init` scaffolds).
|
|
165
179
|
*/
|
|
166
180
|
export declare function resolveSeedFile(config: Pick<TurbineCliConfig, 'seed' | 'seedFile'>, cwd?: string): string | null;
|
|
167
181
|
export declare function configTemplate(connectionString?: string): string;
|
package/dist/cli/config.js
CHANGED
|
@@ -24,7 +24,28 @@ export function looksLikeSchemaFilePath(schema) {
|
|
|
24
24
|
// Config file names, in priority order
|
|
25
25
|
// ---------------------------------------------------------------------------
|
|
26
26
|
const CONFIG_FILES = ['turbine.config.ts', 'turbine.config.mts', 'turbine.config.js', 'turbine.config.mjs'];
|
|
27
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Config-less fallback locations for the seed file, in priority order.
|
|
29
|
+
*
|
|
30
|
+
* Root-level candidates stay FIRST so no project that already relies on
|
|
31
|
+
* `./seed.ts` changes behavior. The `turbine/` candidates are appended so a
|
|
32
|
+
* project that drops the `seedFile` key can still auto-discover the file
|
|
33
|
+
* `turbine init` scaffolds (see {@link DEFAULT_INIT_SEED_FILE}).
|
|
34
|
+
*/
|
|
35
|
+
const DEFAULT_SEED_CANDIDATES = [
|
|
36
|
+
'seed.ts',
|
|
37
|
+
'seed.js',
|
|
38
|
+
'seed.sql',
|
|
39
|
+
'turbine/seed.ts',
|
|
40
|
+
'turbine/seed.js',
|
|
41
|
+
'turbine/seed.sql',
|
|
42
|
+
];
|
|
43
|
+
/**
|
|
44
|
+
* Where `turbine init` scaffolds the seed file, and the `seedFile` value it
|
|
45
|
+
* writes into the generated config. Kept next to the schema file so a new
|
|
46
|
+
* project's Turbine files live in one directory.
|
|
47
|
+
*/
|
|
48
|
+
export const DEFAULT_INIT_SEED_FILE = './turbine/seed.ts';
|
|
28
49
|
function isPlainObject(value) {
|
|
29
50
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
30
51
|
}
|
|
@@ -139,7 +160,9 @@ export function resolveConfig(fileConfig, overrides) {
|
|
|
139
160
|
include: overrides.include ?? fileConfig.include ?? [],
|
|
140
161
|
exclude: overrides.exclude ?? fileConfig.exclude ?? [],
|
|
141
162
|
migrationsDir: fileConfig.migrationsDir ?? './turbine/migrations',
|
|
142
|
-
seedFile
|
|
163
|
+
// `seedFile` is canonical (what the docs and `turbine init` use); `seed` is a
|
|
164
|
+
// back-compat alias kept working for configs scaffolded before 0.50.
|
|
165
|
+
seedFile: fileConfig.seedFile ?? fileConfig.seed,
|
|
143
166
|
schemaFile: fileConfig.schemaFile ?? './turbine/schema.ts',
|
|
144
167
|
importExtension: overrides.importExtension ?? fileConfig.importExtension ?? 'auto',
|
|
145
168
|
keepColumnNames: overrides.keepColumnNames ?? fileConfig.keepColumnNames ?? false,
|
|
@@ -148,10 +171,12 @@ export function resolveConfig(fileConfig, overrides) {
|
|
|
148
171
|
}
|
|
149
172
|
/**
|
|
150
173
|
* Resolve the seed file path. An explicit config value wins even if the file
|
|
151
|
-
* does not exist yet; otherwise
|
|
174
|
+
* does not exist yet; otherwise {@link DEFAULT_SEED_CANDIDATES} is tried in
|
|
175
|
+
* order (root-level first, then the `turbine/` location `init` scaffolds).
|
|
152
176
|
*/
|
|
153
177
|
export function resolveSeedFile(config, cwd = process.cwd()) {
|
|
154
|
-
|
|
178
|
+
// Canonical `seedFile` first, then the back-compat `seed` alias (see resolveConfig).
|
|
179
|
+
const explicit = config.seedFile ?? config.seed;
|
|
155
180
|
if (explicit)
|
|
156
181
|
return resolve(cwd, explicit);
|
|
157
182
|
for (const candidate of DEFAULT_SEED_CANDIDATES) {
|
|
@@ -189,8 +214,8 @@ ${urlLine}
|
|
|
189
214
|
/** Directory for SQL migration files */
|
|
190
215
|
migrationsDir: './turbine/migrations',
|
|
191
216
|
|
|
192
|
-
/** Path to seed file (defaults: ./seed.ts, ./seed.js, ./seed.sql) */
|
|
193
|
-
|
|
217
|
+
/** Path to seed file (defaults: ./seed.ts, ./seed.js, ./seed.sql, ./turbine/seed.ts) */
|
|
218
|
+
seedFile: '${DEFAULT_INIT_SEED_FILE}',
|
|
194
219
|
|
|
195
220
|
/** Path to schema builder file (for turbine push) */
|
|
196
221
|
schemaFile: './turbine/schema.ts',
|
package/dist/cli/index.d.ts
CHANGED
|
@@ -24,6 +24,8 @@
|
|
|
24
24
|
* npx turbine init --url postgres://...
|
|
25
25
|
* npx turbine migrate create add_users_table
|
|
26
26
|
*/
|
|
27
|
+
import type { CliOverrides, ConfigLoadError, ResolvedConfig, TurbineCliConfig } from './config.js';
|
|
28
|
+
import { type PrismaSchemaAst, type ResolvedPrismaDatasourceUrl } from './prisma-schema.js';
|
|
27
29
|
export interface CliArgs {
|
|
28
30
|
command: string;
|
|
29
31
|
subcommand?: string;
|
|
@@ -96,6 +98,43 @@ export interface CliArgs {
|
|
|
96
98
|
noDb?: boolean;
|
|
97
99
|
}
|
|
98
100
|
export declare function parseArgs(argv?: string[]): CliArgs;
|
|
101
|
+
/**
|
|
102
|
+
* Does this invocation need a `turbine.config.*` file?
|
|
103
|
+
*
|
|
104
|
+
* Everything does, with one deliberate exception: `turbine studio --demo` boots
|
|
105
|
+
* a seeded in-memory database, needs no `DATABASE_URL` and no config file, and
|
|
106
|
+
* is the very next command the quickstart suggests after `turbine init`.
|
|
107
|
+
* Resolving the config anyway means a freshly scaffolded directory (a
|
|
108
|
+
* `turbine.config.ts` with `tsx` not installed yet) dies with "Cannot load
|
|
109
|
+
* TypeScript file" before demo mode ever starts.
|
|
110
|
+
*
|
|
111
|
+
* @internal exported for tests.
|
|
112
|
+
*/
|
|
113
|
+
export declare function usesProjectConfig(args: Pick<CliArgs, 'command' | 'demo'>): boolean;
|
|
114
|
+
/**
|
|
115
|
+
* Outcome of {@link bootstrapCliConfig}.
|
|
116
|
+
*
|
|
117
|
+
* @internal exported for tests.
|
|
118
|
+
*/
|
|
119
|
+
export interface CliConfigBootstrap {
|
|
120
|
+
/** Merged config: CLI flags > env vars > config file > defaults. */
|
|
121
|
+
config: ResolvedConfig;
|
|
122
|
+
/** The raw config-file contents (`{}` when none was loaded). */
|
|
123
|
+
fileConfig: TurbineCliConfig;
|
|
124
|
+
/** Set when a config file existed but failed to import. */
|
|
125
|
+
loadError?: ConfigLoadError;
|
|
126
|
+
/** True when config resolution was deliberately skipped (see {@link usesProjectConfig}). */
|
|
127
|
+
skipped: boolean;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Resolve the effective CLI config: register the tsx loader when the config file
|
|
131
|
+
* is TypeScript, import it, then merge it with env vars and CLI flags. Exits with
|
|
132
|
+
* the actionable "Cannot load TypeScript file" error when a `.ts` config cannot
|
|
133
|
+
* be loaded. Config-free invocations short-circuit without touching the disk.
|
|
134
|
+
*
|
|
135
|
+
* @internal exported for tests.
|
|
136
|
+
*/
|
|
137
|
+
export declare function bootstrapCliConfig(args: Pick<CliArgs, 'command' | 'demo'>, overrides: CliOverrides): Promise<CliConfigBootstrap>;
|
|
99
138
|
/** Where a resolved `DATABASE_URL` came from, after the `.env` load. */
|
|
100
139
|
export type DotEnvProvenance = 'shell' | 'dotenv' | 'none';
|
|
101
140
|
/** Structured outcome of {@link loadDotEnvForCli}. */
|
|
@@ -158,6 +197,30 @@ export declare function dotEnvUrlConflictWarning(input: {
|
|
|
158
197
|
fileConfigUrl: string | undefined;
|
|
159
198
|
overrideUrl: string | undefined;
|
|
160
199
|
}): string | null;
|
|
200
|
+
/** Package managers we can name an exact install command for. */
|
|
201
|
+
export type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun';
|
|
202
|
+
/**
|
|
203
|
+
* Detect the consumer's package manager from its lockfile, defaulting to npm.
|
|
204
|
+
* Used only to print an exact, copy-pasteable install command.
|
|
205
|
+
*
|
|
206
|
+
* @internal exported for tests.
|
|
207
|
+
*/
|
|
208
|
+
export declare function detectPackageManager(cwd?: string): PackageManager;
|
|
209
|
+
/**
|
|
210
|
+
* The exact "add tsx as a dev dependency" command for a package manager.
|
|
211
|
+
*
|
|
212
|
+
* @internal exported for tests.
|
|
213
|
+
*/
|
|
214
|
+
export declare function tsxInstallCommand(pm: PackageManager): string;
|
|
215
|
+
/**
|
|
216
|
+
* The heads-up `turbine init` prints when it has just scaffolded TypeScript
|
|
217
|
+
* files and `tsx` is not resolvable: without it the CLI cannot load them, and
|
|
218
|
+
* the very next command the user runs dies on "Cannot load TypeScript file".
|
|
219
|
+
* Pure (returns the lines, prints nothing) so it can be asserted in tests.
|
|
220
|
+
*
|
|
221
|
+
* @internal exported for tests.
|
|
222
|
+
*/
|
|
223
|
+
export declare function tsxRequiredNotice(tsFiles: string[], installCommand: string): string[];
|
|
161
224
|
/**
|
|
162
225
|
* Read the consumer's `package.json` `"type"` field. Returns `'module'` for an
|
|
163
226
|
* ESM project, `'commonjs'` for an explicit or absent (defaulted) CommonJS
|
|
@@ -212,6 +275,66 @@ export interface InitPlanFlags {
|
|
|
212
275
|
* skipped when there is no URL or the database is unreachable.
|
|
213
276
|
*/
|
|
214
277
|
export declare function planInitSteps(state: InitPlanState, flags: InitPlanFlags): InitPlanStep[];
|
|
278
|
+
/**
|
|
279
|
+
* The one-line connection heads-up `turbine init` opens with.
|
|
280
|
+
*
|
|
281
|
+
* @internal exported for tests.
|
|
282
|
+
*/
|
|
283
|
+
export interface InitEnvNotice {
|
|
284
|
+
kind: 'success' | 'info';
|
|
285
|
+
message: string;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Decide which connection notice `turbine init` prints. Pure so the whole
|
|
289
|
+
* decision matrix is testable.
|
|
290
|
+
*
|
|
291
|
+
* "No DATABASE_URL found in environment" is reserved for the case where NO
|
|
292
|
+
* source supplied one: printing it while happily using `--url` (or a config
|
|
293
|
+
* `url`) reads like a failure the user then goes looking for.
|
|
294
|
+
*
|
|
295
|
+
* @internal exported for tests.
|
|
296
|
+
*/
|
|
297
|
+
export declare function initEnvNotice(input: {
|
|
298
|
+
envUrl: string | undefined;
|
|
299
|
+
hasEnvFile: boolean;
|
|
300
|
+
hasEnvLocal: boolean;
|
|
301
|
+
canAutoLoadEnv: boolean;
|
|
302
|
+
flagUrl: string | undefined;
|
|
303
|
+
configUrl: string | undefined;
|
|
304
|
+
}): InitEnvNotice;
|
|
305
|
+
/**
|
|
306
|
+
* `turbine migrate-from-prisma --schema prisma/schema.prisma` parses a Prisma
|
|
307
|
+
* schema, resolve its models/fields/relations/compound-uniques against the live
|
|
308
|
+
* database (unless `--no-db`), and emit (a) a Markdown resolution report and
|
|
309
|
+
* (b) a typed `prisma-map.ts` name map next to the generated client.
|
|
310
|
+
*
|
|
311
|
+
* NOTE: within THIS command `--schema` names the Prisma schema FILE (not the
|
|
312
|
+
* Postgres namespace, which the rest of the CLI's `--schema` means). The
|
|
313
|
+
* Postgres namespace is `public` here; multi-schema (`@@schema`) is unsupported
|
|
314
|
+
* in v1 and listed as a parser note in the report.
|
|
315
|
+
*/
|
|
316
|
+
/** Outcome of {@link resolveMigrateFromPrismaUrl}. */
|
|
317
|
+
export interface MigrateFromPrismaUrl {
|
|
318
|
+
/** The connection string to use, or undefined when none could be found. */
|
|
319
|
+
url?: string;
|
|
320
|
+
/** Where it came from: the normal CLI resolution, or the Prisma datasource. */
|
|
321
|
+
source: 'config' | 'datasource' | 'none';
|
|
322
|
+
/** Datasource detail, set only when `source` is `'datasource'`. */
|
|
323
|
+
datasource?: ResolvedPrismaDatasourceUrl;
|
|
324
|
+
/** Datasource `env(...)` variable names that were declared but unset. */
|
|
325
|
+
missingVariables: string[];
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Pick the connection string for `migrate-from-prisma`.
|
|
329
|
+
*
|
|
330
|
+
* `configUrl` is what {@link resolveConfig} already produced (`--url`, then
|
|
331
|
+
* `DATABASE_URL`, then `turbine.config.ts`) and always wins: an explicit flag
|
|
332
|
+
* must never be overridden by a value declared in someone else's schema file.
|
|
333
|
+
* Only when that is empty do we fall back to the `datasource` block, which
|
|
334
|
+
* removes the flag a project with a non-standard variable name would otherwise
|
|
335
|
+
* pass on every run.
|
|
336
|
+
*/
|
|
337
|
+
export declare function resolveMigrateFromPrismaUrl(configUrl: string | undefined, ast: Pick<PrismaSchemaAst, 'datasources'>, env: Record<string, string | undefined>): MigrateFromPrismaUrl;
|
|
215
338
|
export declare function buildMigrateDeployOptions(args: CliArgs): {
|
|
216
339
|
allowDrift: boolean;
|
|
217
340
|
allowDestructive: true;
|