turbine-orm 0.3.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 (63) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +295 -0
  3. package/dist/cli/config.d.ts +58 -0
  4. package/dist/cli/config.d.ts.map +1 -0
  5. package/dist/cli/config.js +123 -0
  6. package/dist/cli/config.js.map +1 -0
  7. package/dist/cli/index.d.ts +23 -0
  8. package/dist/cli/index.d.ts.map +1 -0
  9. package/dist/cli/index.js +935 -0
  10. package/dist/cli/index.js.map +1 -0
  11. package/dist/cli/migrate.d.ts +94 -0
  12. package/dist/cli/migrate.d.ts.map +1 -0
  13. package/dist/cli/migrate.js +383 -0
  14. package/dist/cli/migrate.js.map +1 -0
  15. package/dist/cli/ui.d.ts +74 -0
  16. package/dist/cli/ui.d.ts.map +1 -0
  17. package/dist/cli/ui.js +220 -0
  18. package/dist/cli/ui.js.map +1 -0
  19. package/dist/client.d.ts +212 -0
  20. package/dist/client.d.ts.map +1 -0
  21. package/dist/client.js +423 -0
  22. package/dist/client.js.map +1 -0
  23. package/dist/generate.d.ts +24 -0
  24. package/dist/generate.d.ts.map +1 -0
  25. package/dist/generate.js +289 -0
  26. package/dist/generate.js.map +1 -0
  27. package/dist/index.d.ts +44 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +53 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/introspect.d.ts +22 -0
  32. package/dist/introspect.d.ts.map +1 -0
  33. package/dist/introspect.js +284 -0
  34. package/dist/introspect.js.map +1 -0
  35. package/dist/pipeline.d.ts +44 -0
  36. package/dist/pipeline.d.ts.map +1 -0
  37. package/dist/pipeline.js +69 -0
  38. package/dist/pipeline.js.map +1 -0
  39. package/dist/query.d.ts +342 -0
  40. package/dist/query.d.ts.map +1 -0
  41. package/dist/query.js +1396 -0
  42. package/dist/query.js.map +1 -0
  43. package/dist/schema-builder.d.ts +127 -0
  44. package/dist/schema-builder.d.ts.map +1 -0
  45. package/dist/schema-builder.js +164 -0
  46. package/dist/schema-builder.js.map +1 -0
  47. package/dist/schema-sql.d.ts +71 -0
  48. package/dist/schema-sql.d.ts.map +1 -0
  49. package/dist/schema-sql.js +347 -0
  50. package/dist/schema-sql.js.map +1 -0
  51. package/dist/schema.d.ts +90 -0
  52. package/dist/schema.d.ts.map +1 -0
  53. package/dist/schema.js +129 -0
  54. package/dist/schema.js.map +1 -0
  55. package/dist/serverless.d.ts +162 -0
  56. package/dist/serverless.d.ts.map +1 -0
  57. package/dist/serverless.js +195 -0
  58. package/dist/serverless.js.map +1 -0
  59. package/dist/types.d.ts +93 -0
  60. package/dist/types.d.ts.map +1 -0
  61. package/dist/types.js +126 -0
  62. package/dist/types.js.map +1 -0
  63. package/package.json +74 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ZVN DEV
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,295 @@
1
+ # @batadata/turbine
2
+
3
+ The performance-first Postgres ORM. Prisma-compatible API, 2-3x faster nested queries, zero runtime overhead beyond `pg`.
4
+
5
+ ```
6
+ npm install @batadata/turbine
7
+ ```
8
+
9
+ ## Why Turbine?
10
+
11
+ ORMs like Prisma fetch nested relations with N+1 queries -- one query per nesting level. Turbine uses Postgres `json_agg` to resolve the entire object graph in **a single SQL query**. The result is fewer round-trips, less connection overhead, and significantly lower latency.
12
+
13
+ **One query instead of N+1.** When you write `db.users.findMany({ with: { posts: { with: { comments: true } } } })`, Turbine generates a single SQL statement that returns fully-nested JSON. Prisma sends 3 separate queries. Drizzle uses LATERAL joins which are competitive, but Turbine still wins on median latency.
14
+
15
+ ## Benchmarks
16
+
17
+ Production results from Vercel Serverless hitting Neon Postgres (20 iterations, warm):
18
+
19
+ | Scenario | Turbine | Drizzle | Prisma |
20
+ |---|---|---|---|
21
+ | **Nested L3 (median)** | **5.3ms** | 6.5ms | 7.4ms |
22
+ | Nested L3 (min) | **4.4ms** | 5.7ms | 6.0ms |
23
+ | Nested L2 | **6.5ms** | 9.1ms | 10.2ms |
24
+ | Simple select | 5.6ms | 7.1ms | 3.9ms |
25
+
26
+ Local Docker results (50K iterations, HDR histograms):
27
+
28
+ | Scenario | Turbine | Drizzle | Prisma |
29
+ |---|---|---|---|
30
+ | **L2 nested p50** | **201us** | 523us | 835us |
31
+ | **L2 nested RPS (c=50)** | **24,041** | 6,360 | 3,784 |
32
+ | L2 nested memory | 109MB | 117MB | 233MB |
33
+
34
+ Turbine is 2.6x faster than Drizzle and 4.2x faster than Prisma on nested queries at p50. Throughput is 3.8x higher than Drizzle and 6.3x higher than Prisma.
35
+
36
+ ## Quick Start
37
+
38
+ ```bash
39
+ # 1. Install
40
+ npm install @batadata/turbine
41
+
42
+ # 2. Initialize project
43
+ npx turbine init --url postgres://user:pass@localhost:5432/mydb
44
+
45
+ # 3. Generate typed client from your database
46
+ npx turbine generate
47
+ ```
48
+
49
+ This introspects your database and generates a fully-typed client at `./generated/turbine/`.
50
+
51
+ ```typescript
52
+ import { turbine } from './generated/turbine';
53
+
54
+ const db = turbine({ connectionString: process.env.DATABASE_URL });
55
+
56
+ // Type-safe queries with autocompletion
57
+ const users = await db.users.findMany({
58
+ where: { role: 'admin' },
59
+ orderBy: { createdAt: 'desc' },
60
+ limit: 10,
61
+ });
62
+
63
+ await db.disconnect();
64
+ ```
65
+
66
+ ## Usage Examples
67
+
68
+ ### findMany with nested relations
69
+
70
+ ```typescript
71
+ // Single query -- returns users with their posts and each post's comments
72
+ const users = await db.users.findMany({
73
+ where: { orgId: 1 },
74
+ with: {
75
+ posts: {
76
+ with: { comments: true },
77
+ orderBy: { createdAt: 'desc' },
78
+ limit: 5,
79
+ },
80
+ },
81
+ });
82
+
83
+ // users[0].posts[0].comments -- fully typed, single round-trip
84
+ ```
85
+
86
+ ### findUnique
87
+
88
+ ```typescript
89
+ const user = await db.users.findUnique({
90
+ where: { id: 42 },
91
+ with: { posts: true },
92
+ });
93
+ // user.posts is Post[] -- resolved in the same query
94
+ ```
95
+
96
+ ### create
97
+
98
+ ```typescript
99
+ const newUser = await db.users.create({
100
+ data: {
101
+ email: 'alice@example.com',
102
+ name: 'Alice',
103
+ orgId: 1,
104
+ },
105
+ });
106
+ // Returns the full row with generated id, createdAt, etc.
107
+ ```
108
+
109
+ ### createMany (batch insert with UNNEST)
110
+
111
+ ```typescript
112
+ const users = await db.users.createMany({
113
+ data: [
114
+ { email: 'a@b.com', name: 'A', orgId: 1 },
115
+ { email: 'b@b.com', name: 'B', orgId: 1 },
116
+ { email: 'c@b.com', name: 'C', orgId: 1 },
117
+ ],
118
+ });
119
+ // Single INSERT with UNNEST -- not 3 separate inserts
120
+ ```
121
+
122
+ ### update / delete
123
+
124
+ ```typescript
125
+ const updated = await db.users.update({
126
+ where: { id: 42 },
127
+ data: { name: 'Alice Updated' },
128
+ });
129
+
130
+ const deleted = await db.users.delete({
131
+ where: { id: 42 },
132
+ });
133
+ ```
134
+
135
+ ### Transactions
136
+
137
+ ```typescript
138
+ await db.$transaction(async (tx) => {
139
+ const user = await tx.users.create({
140
+ data: { email: 'new@example.com', name: 'New', orgId: 1 },
141
+ });
142
+ await tx.posts.create({
143
+ data: { userId: user.id, orgId: 1, title: 'First Post', content: '...' },
144
+ });
145
+ });
146
+ // Fully typed -- tx.users and tx.posts have the same API as db.users and db.posts
147
+ ```
148
+
149
+ ### Pipeline (batch queries in one round-trip)
150
+
151
+ ```typescript
152
+ const [user, postCount, recentPosts] = await db.pipeline(
153
+ db.users.buildFindUnique({ where: { id: 1 } }),
154
+ db.posts.buildCount({ where: { orgId: 1 } }),
155
+ db.posts.buildFindMany({ where: { userId: 1 }, limit: 5 }),
156
+ );
157
+ // 3 queries, 1 database round-trip
158
+ ```
159
+
160
+ ### Raw SQL (tagged template)
161
+
162
+ ```typescript
163
+ const stats = await db.raw<{ day: Date; count: number }>`
164
+ SELECT DATE_TRUNC('day', created_at) AS day, COUNT(*)::int AS count
165
+ FROM posts WHERE org_id = ${orgId}
166
+ GROUP BY day ORDER BY day
167
+ `;
168
+ ```
169
+
170
+ ### Middleware
171
+
172
+ ```typescript
173
+ // Query timing
174
+ db.$use(async (params, next) => {
175
+ const start = Date.now();
176
+ const result = await next(params);
177
+ console.log(`${params.model}.${params.action} took ${Date.now() - start}ms`);
178
+ return result;
179
+ });
180
+
181
+ // Soft-delete filter
182
+ db.$use(async (params, next) => {
183
+ if (params.action === 'findMany' || params.action === 'findUnique') {
184
+ params.args.where = { ...params.args.where, deletedAt: null };
185
+ }
186
+ return next(params);
187
+ });
188
+ ```
189
+
190
+ ## CLI
191
+
192
+ ```
193
+ npx turbine <command> [options]
194
+
195
+ Commands:
196
+ init Initialize a Turbine project (creates config, dirs, templates)
197
+ generate | pull Introspect database and generate TypeScript types + client
198
+ push Apply schema-builder definitions to database
199
+ migrate create <name> Create a new SQL migration file
200
+ migrate up Apply pending migrations
201
+ migrate down Rollback last migration
202
+ migrate status Show applied/pending migrations
203
+ seed Run seed file
204
+ status Show database schema summary
205
+
206
+ Options:
207
+ --url, -u <url> Postgres connection string
208
+ --out, -o <dir> Output directory (default: ./generated/turbine)
209
+ --schema, -s <name> Postgres schema (default: public)
210
+ --dry-run Show SQL without executing
211
+ --verbose, -v Detailed output
212
+ ```
213
+
214
+ ### Schema-first workflow
215
+
216
+ Define your schema in TypeScript and push it to the database:
217
+
218
+ ```typescript
219
+ // turbine/schema.ts
220
+ import { defineSchema } from '@batadata/turbine';
221
+
222
+ export default defineSchema({
223
+ users: {
224
+ id: { type: 'serial', primaryKey: true },
225
+ email: { type: 'text', unique: true, notNull: true },
226
+ name: { type: 'text', notNull: true },
227
+ orgId: { type: 'bigint', notNull: true, references: 'organizations.id' },
228
+ createdAt: { type: 'timestamp', default: 'now()' },
229
+ },
230
+ });
231
+ ```
232
+
233
+ ```bash
234
+ npx turbine push --dry-run # Preview SQL
235
+ npx turbine push # Apply to database
236
+ npx turbine generate # Regenerate typed client
237
+ ```
238
+
239
+ ### Migration workflow
240
+
241
+ ```bash
242
+ npx turbine migrate create add_users_table
243
+ # Edit the generated .sql file with UP and DOWN sections
244
+ npx turbine migrate up
245
+ npx turbine migrate status
246
+ ```
247
+
248
+ ## Configuration
249
+
250
+ Create `turbine.config.ts` in your project root (or run `npx turbine init`):
251
+
252
+ ```typescript
253
+ import type { TurbineCliConfig } from '@batadata/turbine/cli';
254
+
255
+ const config: TurbineCliConfig = {
256
+ url: process.env.DATABASE_URL,
257
+ out: './generated/turbine',
258
+ schema: 'public',
259
+ migrationsDir: './turbine/migrations',
260
+ seedFile: './turbine/seed.ts',
261
+ schemaFile: './turbine/schema.ts',
262
+ };
263
+
264
+ export default config;
265
+ ```
266
+
267
+ Priority order: CLI flags > environment variables (`DATABASE_URL`) > config file > defaults.
268
+
269
+ ## How It Works
270
+
271
+ Turbine generates a single SQL query using Postgres `json_agg` + subqueries to fetch nested relations:
272
+
273
+ ```sql
274
+ -- db.users.findMany({ where: { orgId: 1 }, with: { posts: { with: { comments: true } } } })
275
+ SELECT u.*,
276
+ (SELECT COALESCE(json_agg(sub), '[]'::json) FROM (
277
+ SELECT p.*,
278
+ (SELECT COALESCE(json_agg(sub2), '[]'::json) FROM (
279
+ SELECT c.* FROM comments c WHERE c.post_id = p.id
280
+ ) sub2) AS comments
281
+ FROM posts p WHERE p.user_id = u.id
282
+ ) sub) AS posts
283
+ FROM users u WHERE u.org_id = 1
284
+ ```
285
+
286
+ This resolves the entire 3-level object graph in one database round-trip. Prisma would send 3 queries. The performance difference scales with nesting depth and network latency.
287
+
288
+ ## Requirements
289
+
290
+ - Node.js >= 22.0.0
291
+ - PostgreSQL >= 14
292
+
293
+ ## License
294
+
295
+ MIT
@@ -0,0 +1,58 @@
1
+ /**
2
+ * @batadata/turbine CLI — Configuration file support
3
+ *
4
+ * Loads turbine.config.ts (or .js/.mjs) via dynamic import.
5
+ * Falls back to CLI args and environment variables.
6
+ */
7
+ export interface TurbineCliConfig {
8
+ /** Postgres connection string */
9
+ url?: string;
10
+ /** Output directory for generated files (default: ./generated/turbine) */
11
+ out?: string;
12
+ /** Postgres schema to introspect (default: public) */
13
+ schema?: string;
14
+ /** Tables to include (empty = all) */
15
+ include?: string[];
16
+ /** Tables to exclude */
17
+ exclude?: string[];
18
+ /** Directory for migration files (default: ./turbine/migrations) */
19
+ migrationsDir?: string;
20
+ /** Path to seed file (default: ./turbine/seed.ts) */
21
+ seedFile?: string;
22
+ /** Schema builder file path (for push command) */
23
+ schemaFile?: string;
24
+ }
25
+ /**
26
+ * Attempt to load a turbine config file from the current directory.
27
+ * Returns the config if found, or an empty object.
28
+ */
29
+ export declare function loadConfig(cwd?: string): Promise<TurbineCliConfig>;
30
+ /**
31
+ * Find the config file path (for display purposes).
32
+ * Returns null if no config file is found.
33
+ */
34
+ export declare function findConfigFile(cwd?: string): string | null;
35
+ export interface ResolvedConfig {
36
+ url: string;
37
+ out: string;
38
+ schema: string;
39
+ include: string[];
40
+ exclude: string[];
41
+ migrationsDir: string;
42
+ seedFile: string;
43
+ schemaFile: string;
44
+ }
45
+ export interface CliOverrides {
46
+ url?: string;
47
+ out?: string;
48
+ schema?: string;
49
+ include?: string[];
50
+ exclude?: string[];
51
+ }
52
+ /**
53
+ * Merge config file values with CLI overrides and env vars.
54
+ * Priority: CLI flags > env vars > config file > defaults.
55
+ */
56
+ export declare function resolveConfig(fileConfig: TurbineCliConfig, overrides: CliOverrides): ResolvedConfig;
57
+ export declare function configTemplate(connectionString?: string): string;
58
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/cli/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,MAAM,WAAW,gBAAgB;IAC/B,iCAAiC;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0EAA0E;IAC1E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sCAAsC;IACtC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,wBAAwB;IACxB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,oEAAoE;IACpE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAiBD;;;GAGG;AACH,wBAAsB,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA6BxE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAO1D;AAMD,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,UAAU,EAAE,gBAAgB,EAC5B,SAAS,EAAE,YAAY,GACtB,cAAc,CAehB;AAMD,wBAAgB,cAAc,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM,CAqChE"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * @batadata/turbine CLI — Configuration file support
3
+ *
4
+ * Loads turbine.config.ts (or .js/.mjs) via dynamic import.
5
+ * Falls back to CLI args and environment variables.
6
+ */
7
+ import { existsSync } from 'node:fs';
8
+ import { resolve, join } from 'node:path';
9
+ import { pathToFileURL } from 'node:url';
10
+ // ---------------------------------------------------------------------------
11
+ // Config file names, in priority order
12
+ // ---------------------------------------------------------------------------
13
+ const CONFIG_FILES = [
14
+ 'turbine.config.ts',
15
+ 'turbine.config.mts',
16
+ 'turbine.config.js',
17
+ 'turbine.config.mjs',
18
+ ];
19
+ // ---------------------------------------------------------------------------
20
+ // Load config
21
+ // ---------------------------------------------------------------------------
22
+ /**
23
+ * Attempt to load a turbine config file from the current directory.
24
+ * Returns the config if found, or an empty object.
25
+ */
26
+ export async function loadConfig(cwd) {
27
+ const dir = cwd ?? process.cwd();
28
+ for (const filename of CONFIG_FILES) {
29
+ const filePath = join(dir, filename);
30
+ if (!existsSync(filePath))
31
+ continue;
32
+ try {
33
+ const absPath = resolve(filePath);
34
+ const fileUrl = pathToFileURL(absPath).href;
35
+ // For .ts files, we need to rely on Node's --experimental-strip-types
36
+ // or the tsx loader. Dynamic import handles .js/.mjs natively.
37
+ const mod = await import(fileUrl);
38
+ const config = mod.default ?? mod;
39
+ return config;
40
+ }
41
+ catch (err) {
42
+ // If importing a .ts file fails, try the next one
43
+ if (filename.endsWith('.ts') || filename.endsWith('.mts')) {
44
+ continue;
45
+ }
46
+ throw new Error(`Failed to load config from ${filename}: ${err instanceof Error ? err.message : String(err)}`);
47
+ }
48
+ }
49
+ return {};
50
+ }
51
+ /**
52
+ * Find the config file path (for display purposes).
53
+ * Returns null if no config file is found.
54
+ */
55
+ export function findConfigFile(cwd) {
56
+ const dir = cwd ?? process.cwd();
57
+ for (const filename of CONFIG_FILES) {
58
+ const filePath = join(dir, filename);
59
+ if (existsSync(filePath))
60
+ return filePath;
61
+ }
62
+ return null;
63
+ }
64
+ /**
65
+ * Merge config file values with CLI overrides and env vars.
66
+ * Priority: CLI flags > env vars > config file > defaults.
67
+ */
68
+ export function resolveConfig(fileConfig, overrides) {
69
+ return {
70
+ url: overrides.url ??
71
+ process.env['DATABASE_URL'] ??
72
+ fileConfig.url ??
73
+ '',
74
+ out: overrides.out ?? fileConfig.out ?? './generated/turbine',
75
+ schema: overrides.schema ?? fileConfig.schema ?? 'public',
76
+ include: overrides.include ?? fileConfig.include ?? [],
77
+ exclude: overrides.exclude ?? fileConfig.exclude ?? [],
78
+ migrationsDir: fileConfig.migrationsDir ?? './turbine/migrations',
79
+ seedFile: fileConfig.seedFile ?? './turbine/seed.ts',
80
+ schemaFile: fileConfig.schemaFile ?? './turbine/schema.ts',
81
+ };
82
+ }
83
+ // ---------------------------------------------------------------------------
84
+ // Config file template (for `turbine init`)
85
+ // ---------------------------------------------------------------------------
86
+ export function configTemplate(connectionString) {
87
+ const url = connectionString ?? 'process.env.DATABASE_URL';
88
+ const urlLine = connectionString
89
+ ? ` url: '${connectionString}',`
90
+ : ` url: process.env.DATABASE_URL,`;
91
+ return `import type { TurbineCliConfig } from '@batadata/turbine/cli';
92
+
93
+ /**
94
+ * Turbine configuration
95
+ * @see https://batadata.com/docs/turbine/config
96
+ */
97
+ const config: TurbineCliConfig = {
98
+ /** Postgres connection string */
99
+ ${urlLine}
100
+
101
+ /** Output directory for generated types + client */
102
+ out: './generated/turbine',
103
+
104
+ /** Postgres schema to introspect (default: public) */
105
+ schema: 'public',
106
+
107
+ /** Tables to exclude from generation */
108
+ // exclude: ['_migrations', '_sessions'],
109
+
110
+ /** Directory for SQL migration files */
111
+ migrationsDir: './turbine/migrations',
112
+
113
+ /** Path to seed file */
114
+ seedFile: './turbine/seed.ts',
115
+
116
+ /** Path to schema builder file (for turbine push) */
117
+ schemaFile: './turbine/schema.ts',
118
+ };
119
+
120
+ export default config;
121
+ `;
122
+ }
123
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/cli/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @batadata/turbine CLI
4
+ *
5
+ * Commands:
6
+ * turbine init — Initialize a Turbine project
7
+ * turbine generate | pull — Introspect database and generate TypeScript types
8
+ * turbine push — Apply schema-builder definitions to database
9
+ * turbine migrate create <name> — Create a new SQL migration file
10
+ * turbine migrate up — Apply pending migrations
11
+ * turbine migrate down — Rollback last migration
12
+ * turbine migrate status — Show migration status
13
+ * turbine seed — Run seed file
14
+ * turbine status — Show schema summary
15
+ * turbine studio — Launch web UI (coming soon)
16
+ *
17
+ * Usage:
18
+ * DATABASE_URL=postgres://... npx turbine generate
19
+ * npx turbine init --url postgres://...
20
+ * npx turbine migrate create add_users_table
21
+ */
22
+ export {};
23
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;GAmBG"}