turbine-orm 0.3.1 → 0.5.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 +51 -2
- package/dist/cjs/cli/config.js +161 -0
- package/dist/cjs/cli/index.js +977 -0
- package/dist/cjs/cli/migrate.js +421 -0
- package/dist/cjs/cli/ui.js +237 -0
- package/dist/cjs/client.js +449 -0
- package/dist/cjs/generate.js +301 -0
- package/dist/cjs/index.js +75 -0
- package/dist/cjs/introspect.js +289 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/pipeline.js +71 -0
- package/dist/cjs/query.js +1558 -0
- package/dist/cjs/schema-builder.js +169 -0
- package/dist/cjs/schema-sql.js +371 -0
- package/dist/cjs/schema.js +137 -0
- package/dist/cjs/serverless.js +199 -0
- package/dist/cli/index.js +14 -6
- package/dist/cli/migrate.d.ts +29 -5
- package/dist/cli/migrate.js +58 -35
- package/dist/client.d.ts +13 -2
- package/dist/client.js +26 -13
- package/dist/generate.js +7 -1
- package/dist/query.d.ts +54 -2
- package/dist/query.js +126 -35
- package/dist/schema-sql.js +30 -14
- package/package.json +14 -9
- package/dist/cli/config.d.ts.map +0 -1
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/migrate.d.ts.map +0 -1
- package/dist/cli/ui.d.ts.map +0 -1
- package/dist/client.d.ts.map +0 -1
- package/dist/generate.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/introspect.d.ts.map +0 -1
- package/dist/pipeline.d.ts.map +0 -1
- package/dist/query.d.ts.map +0 -1
- package/dist/schema-builder.d.ts.map +0 -1
- package/dist/schema-sql.d.ts.map +0 -1
- package/dist/schema.d.ts.map +0 -1
- package/dist/serverless.d.ts.map +0 -1
- package/dist/types.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -46,6 +46,16 @@ npx turbine init --url postgres://user:pass@localhost:5432/mydb
|
|
|
46
46
|
npx turbine generate
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
+
Works with both ESM and CommonJS:
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
// ESM
|
|
53
|
+
import { turbine } from './generated/turbine';
|
|
54
|
+
|
|
55
|
+
// CommonJS
|
|
56
|
+
const { turbine } = require('./generated/turbine');
|
|
57
|
+
```
|
|
58
|
+
|
|
49
59
|
This introspects your database and generates a fully-typed client at `./generated/turbine/`.
|
|
50
60
|
|
|
51
61
|
```typescript
|
|
@@ -167,6 +177,36 @@ const stats = await db.raw<{ day: Date; count: number }>`
|
|
|
167
177
|
`;
|
|
168
178
|
```
|
|
169
179
|
|
|
180
|
+
### Case-insensitive search
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
const users = await db.users.findMany({
|
|
184
|
+
where: {
|
|
185
|
+
email: { contains: 'alice', mode: 'insensitive' },
|
|
186
|
+
},
|
|
187
|
+
});
|
|
188
|
+
// Generates: WHERE email ILIKE '%alice%'
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Query timeout
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
const users = await db.users.findMany({
|
|
195
|
+
where: { orgId: 1 },
|
|
196
|
+
timeout: 5000, // 5 second timeout
|
|
197
|
+
});
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Default limit
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
// Set a default limit for all queries on a model
|
|
204
|
+
const db = turbine({
|
|
205
|
+
connectionString: process.env.DATABASE_URL,
|
|
206
|
+
defaultLimit: 100,
|
|
207
|
+
});
|
|
208
|
+
```
|
|
209
|
+
|
|
170
210
|
### Middleware
|
|
171
211
|
|
|
172
212
|
```typescript
|
|
@@ -239,9 +279,17 @@ npx turbine generate # Regenerate typed client
|
|
|
239
279
|
### Migration workflow
|
|
240
280
|
|
|
241
281
|
```bash
|
|
282
|
+
# Create a new migration
|
|
242
283
|
npx turbine migrate create add_users_table
|
|
243
|
-
#
|
|
284
|
+
# -> Creates turbine/migrations/001_add_users_table.sql with UP/DOWN sections
|
|
285
|
+
|
|
286
|
+
# Apply all pending migrations
|
|
244
287
|
npx turbine migrate up
|
|
288
|
+
|
|
289
|
+
# Rollback the last applied migration
|
|
290
|
+
npx turbine migrate down
|
|
291
|
+
|
|
292
|
+
# Check migration status (applied vs pending)
|
|
245
293
|
npx turbine migrate status
|
|
246
294
|
```
|
|
247
295
|
|
|
@@ -287,8 +335,9 @@ This resolves the entire 3-level object graph in one database round-trip. Prisma
|
|
|
287
335
|
|
|
288
336
|
## Requirements
|
|
289
337
|
|
|
290
|
-
- Node.js >=
|
|
338
|
+
- Node.js >= 18.0.0
|
|
291
339
|
- PostgreSQL >= 14
|
|
340
|
+
- Works with both ESM (`import`) and CommonJS (`require`)
|
|
292
341
|
|
|
293
342
|
## License
|
|
294
343
|
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* turbine-orm CLI — Configuration file support
|
|
4
|
+
*
|
|
5
|
+
* Loads turbine.config.ts (or .js/.mjs) via dynamic import.
|
|
6
|
+
* Falls back to CLI args and environment variables.
|
|
7
|
+
*/
|
|
8
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
15
|
+
}) : (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
o[k2] = m[k];
|
|
18
|
+
}));
|
|
19
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
20
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
21
|
+
}) : function(o, v) {
|
|
22
|
+
o["default"] = v;
|
|
23
|
+
});
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.loadConfig = loadConfig;
|
|
43
|
+
exports.findConfigFile = findConfigFile;
|
|
44
|
+
exports.resolveConfig = resolveConfig;
|
|
45
|
+
exports.configTemplate = configTemplate;
|
|
46
|
+
const node_fs_1 = require("node:fs");
|
|
47
|
+
const node_path_1 = require("node:path");
|
|
48
|
+
const node_url_1 = require("node:url");
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
// Config file names, in priority order
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
const CONFIG_FILES = [
|
|
53
|
+
'turbine.config.ts',
|
|
54
|
+
'turbine.config.mts',
|
|
55
|
+
'turbine.config.js',
|
|
56
|
+
'turbine.config.mjs',
|
|
57
|
+
];
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
// Load config
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
/**
|
|
62
|
+
* Attempt to load a turbine config file from the current directory.
|
|
63
|
+
* Returns the config if found, or an empty object.
|
|
64
|
+
*/
|
|
65
|
+
async function loadConfig(cwd) {
|
|
66
|
+
const dir = cwd ?? process.cwd();
|
|
67
|
+
for (const filename of CONFIG_FILES) {
|
|
68
|
+
const filePath = (0, node_path_1.join)(dir, filename);
|
|
69
|
+
if (!(0, node_fs_1.existsSync)(filePath))
|
|
70
|
+
continue;
|
|
71
|
+
try {
|
|
72
|
+
const absPath = (0, node_path_1.resolve)(filePath);
|
|
73
|
+
const fileUrl = (0, node_url_1.pathToFileURL)(absPath).href;
|
|
74
|
+
// For .ts files, we need to rely on Node's --experimental-strip-types
|
|
75
|
+
// or the tsx loader. Dynamic import handles .js/.mjs natively.
|
|
76
|
+
const mod = await Promise.resolve(`${fileUrl}`).then(s => __importStar(require(s)));
|
|
77
|
+
const config = mod.default ?? mod;
|
|
78
|
+
return config;
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
// If importing a .ts file fails, try the next one
|
|
82
|
+
if (filename.endsWith('.ts') || filename.endsWith('.mts')) {
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
throw new Error(`Failed to load config from ${filename}: ${err instanceof Error ? err.message : String(err)}`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return {};
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Find the config file path (for display purposes).
|
|
92
|
+
* Returns null if no config file is found.
|
|
93
|
+
*/
|
|
94
|
+
function findConfigFile(cwd) {
|
|
95
|
+
const dir = cwd ?? process.cwd();
|
|
96
|
+
for (const filename of CONFIG_FILES) {
|
|
97
|
+
const filePath = (0, node_path_1.join)(dir, filename);
|
|
98
|
+
if ((0, node_fs_1.existsSync)(filePath))
|
|
99
|
+
return filePath;
|
|
100
|
+
}
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Merge config file values with CLI overrides and env vars.
|
|
105
|
+
* Priority: CLI flags > env vars > config file > defaults.
|
|
106
|
+
*/
|
|
107
|
+
function resolveConfig(fileConfig, overrides) {
|
|
108
|
+
return {
|
|
109
|
+
url: overrides.url ??
|
|
110
|
+
process.env['DATABASE_URL'] ??
|
|
111
|
+
fileConfig.url ??
|
|
112
|
+
'',
|
|
113
|
+
out: overrides.out ?? fileConfig.out ?? './generated/turbine',
|
|
114
|
+
schema: overrides.schema ?? fileConfig.schema ?? 'public',
|
|
115
|
+
include: overrides.include ?? fileConfig.include ?? [],
|
|
116
|
+
exclude: overrides.exclude ?? fileConfig.exclude ?? [],
|
|
117
|
+
migrationsDir: fileConfig.migrationsDir ?? './turbine/migrations',
|
|
118
|
+
seedFile: fileConfig.seedFile ?? './turbine/seed.ts',
|
|
119
|
+
schemaFile: fileConfig.schemaFile ?? './turbine/schema.ts',
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
// ---------------------------------------------------------------------------
|
|
123
|
+
// Config file template (for `turbine init`)
|
|
124
|
+
// ---------------------------------------------------------------------------
|
|
125
|
+
function configTemplate(connectionString) {
|
|
126
|
+
const url = connectionString ?? 'process.env.DATABASE_URL';
|
|
127
|
+
const urlLine = connectionString
|
|
128
|
+
? ` url: '${connectionString}',`
|
|
129
|
+
: ` url: process.env.DATABASE_URL,`;
|
|
130
|
+
return `import type { TurbineCliConfig } from 'turbine-orm/cli';
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Turbine configuration
|
|
134
|
+
* @see https://batadata.com/docs/turbine/config
|
|
135
|
+
*/
|
|
136
|
+
const config: TurbineCliConfig = {
|
|
137
|
+
/** Postgres connection string */
|
|
138
|
+
${urlLine}
|
|
139
|
+
|
|
140
|
+
/** Output directory for generated types + client */
|
|
141
|
+
out: './generated/turbine',
|
|
142
|
+
|
|
143
|
+
/** Postgres schema to introspect (default: public) */
|
|
144
|
+
schema: 'public',
|
|
145
|
+
|
|
146
|
+
/** Tables to exclude from generation */
|
|
147
|
+
// exclude: ['_migrations', '_sessions'],
|
|
148
|
+
|
|
149
|
+
/** Directory for SQL migration files */
|
|
150
|
+
migrationsDir: './turbine/migrations',
|
|
151
|
+
|
|
152
|
+
/** Path to seed file */
|
|
153
|
+
seedFile: './turbine/seed.ts',
|
|
154
|
+
|
|
155
|
+
/** Path to schema builder file (for turbine push) */
|
|
156
|
+
schemaFile: './turbine/schema.ts',
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
export default config;
|
|
160
|
+
`;
|
|
161
|
+
}
|