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.
- package/LICENSE +21 -0
- package/README.md +295 -0
- package/dist/cli/config.d.ts +58 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.js +123 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/index.d.ts +23 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +935 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/migrate.d.ts +94 -0
- package/dist/cli/migrate.d.ts.map +1 -0
- package/dist/cli/migrate.js +383 -0
- package/dist/cli/migrate.js.map +1 -0
- package/dist/cli/ui.d.ts +74 -0
- package/dist/cli/ui.d.ts.map +1 -0
- package/dist/cli/ui.js +220 -0
- package/dist/cli/ui.js.map +1 -0
- package/dist/client.d.ts +212 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +423 -0
- package/dist/client.js.map +1 -0
- package/dist/generate.d.ts +24 -0
- package/dist/generate.d.ts.map +1 -0
- package/dist/generate.js +289 -0
- package/dist/generate.js.map +1 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +53 -0
- package/dist/index.js.map +1 -0
- package/dist/introspect.d.ts +22 -0
- package/dist/introspect.d.ts.map +1 -0
- package/dist/introspect.js +284 -0
- package/dist/introspect.js.map +1 -0
- package/dist/pipeline.d.ts +44 -0
- package/dist/pipeline.d.ts.map +1 -0
- package/dist/pipeline.js +69 -0
- package/dist/pipeline.js.map +1 -0
- package/dist/query.d.ts +342 -0
- package/dist/query.d.ts.map +1 -0
- package/dist/query.js +1396 -0
- package/dist/query.js.map +1 -0
- package/dist/schema-builder.d.ts +127 -0
- package/dist/schema-builder.d.ts.map +1 -0
- package/dist/schema-builder.js +164 -0
- package/dist/schema-builder.js.map +1 -0
- package/dist/schema-sql.d.ts +71 -0
- package/dist/schema-sql.d.ts.map +1 -0
- package/dist/schema-sql.js +347 -0
- package/dist/schema-sql.js.map +1 -0
- package/dist/schema.d.ts +90 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +129 -0
- package/dist/schema.js.map +1 -0
- package/dist/serverless.d.ts +162 -0
- package/dist/serverless.d.ts.map +1 -0
- package/dist/serverless.js +195 -0
- package/dist/serverless.js.map +1 -0
- package/dist/types.d.ts +93 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +126 -0
- package/dist/types.js.map +1 -0
- package/package.json +74 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @batadata/turbine/serverless — HTTP-based query driver for edge functions
|
|
3
|
+
*
|
|
4
|
+
* Use this driver when you cannot establish a direct TCP connection to Postgres
|
|
5
|
+
* (e.g., Vercel Edge Functions, Cloudflare Workers, Deno Deploy).
|
|
6
|
+
*
|
|
7
|
+
* It sends queries as JSON over HTTP to a Turbine query endpoint, which executes
|
|
8
|
+
* them against the actual database and returns typed results.
|
|
9
|
+
*
|
|
10
|
+
* NOTE: This is a scaffold. The server-side query endpoint does not exist yet.
|
|
11
|
+
* The HTTP protocol and response format are defined here and will be implemented
|
|
12
|
+
* on the server side in a future release.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* import { createServerlessClient } from '@batadata/turbine/serverless';
|
|
17
|
+
*
|
|
18
|
+
* const db = createServerlessClient({
|
|
19
|
+
* endpoint: 'https://your-turbine-proxy.fly.dev/query',
|
|
20
|
+
* authToken: process.env.TURBINE_AUTH_TOKEN!,
|
|
21
|
+
* });
|
|
22
|
+
*
|
|
23
|
+
* const result = await db.query('SELECT * FROM users WHERE id = $1', [1]);
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
/** Configuration for the serverless HTTP driver */
|
|
27
|
+
export interface ServerlessConfig {
|
|
28
|
+
/** URL of the Turbine query endpoint (e.g. https://proxy.example.com/query) */
|
|
29
|
+
endpoint: string;
|
|
30
|
+
/** Authentication token for the endpoint */
|
|
31
|
+
authToken: string;
|
|
32
|
+
/** Request timeout in milliseconds (default: 10000) */
|
|
33
|
+
timeout?: number;
|
|
34
|
+
/** Custom fetch implementation (defaults to global fetch) */
|
|
35
|
+
fetch?: typeof globalThis.fetch;
|
|
36
|
+
/** Custom headers to include with every request */
|
|
37
|
+
headers?: Record<string, string>;
|
|
38
|
+
}
|
|
39
|
+
/** A single SQL query to execute */
|
|
40
|
+
export interface QueryRequest {
|
|
41
|
+
/** SQL query string with $1, $2, ... parameter placeholders */
|
|
42
|
+
sql: string;
|
|
43
|
+
/** Parameter values */
|
|
44
|
+
params?: unknown[];
|
|
45
|
+
/** Hint for the server about expected result shape */
|
|
46
|
+
mode?: 'rows' | 'one' | 'count' | 'void';
|
|
47
|
+
}
|
|
48
|
+
/** Batch of queries to execute in a single round-trip */
|
|
49
|
+
export interface BatchRequest {
|
|
50
|
+
queries: QueryRequest[];
|
|
51
|
+
/** Whether to wrap the batch in a transaction */
|
|
52
|
+
transaction?: boolean;
|
|
53
|
+
}
|
|
54
|
+
/** Response from the query endpoint for a single query */
|
|
55
|
+
export interface QueryResponse<T = Record<string, unknown>> {
|
|
56
|
+
/** Returned rows */
|
|
57
|
+
rows: T[];
|
|
58
|
+
/** Number of rows affected (for INSERT/UPDATE/DELETE) */
|
|
59
|
+
rowCount: number;
|
|
60
|
+
/** Column metadata */
|
|
61
|
+
fields?: Array<{
|
|
62
|
+
name: string;
|
|
63
|
+
dataTypeID: number;
|
|
64
|
+
}>;
|
|
65
|
+
/** Server-side execution time in milliseconds */
|
|
66
|
+
durationMs?: number;
|
|
67
|
+
}
|
|
68
|
+
/** Response from the query endpoint for a batch */
|
|
69
|
+
export interface BatchResponse {
|
|
70
|
+
results: QueryResponse[];
|
|
71
|
+
/** Total server-side execution time in milliseconds */
|
|
72
|
+
totalDurationMs?: number;
|
|
73
|
+
}
|
|
74
|
+
/** Error response from the query endpoint */
|
|
75
|
+
export interface QueryError {
|
|
76
|
+
error: string;
|
|
77
|
+
code?: string;
|
|
78
|
+
detail?: string;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* HTTP-based Postgres query client for serverless/edge environments.
|
|
82
|
+
*
|
|
83
|
+
* Sends SQL queries as JSON POST requests to a Turbine query endpoint.
|
|
84
|
+
* Does not require a direct TCP connection to Postgres.
|
|
85
|
+
*/
|
|
86
|
+
export declare class ServerlessClient {
|
|
87
|
+
private readonly config;
|
|
88
|
+
private readonly fetchFn;
|
|
89
|
+
constructor(config: ServerlessConfig);
|
|
90
|
+
/**
|
|
91
|
+
* Execute a single SQL query.
|
|
92
|
+
*
|
|
93
|
+
* @param sql - SQL string with $1, $2, ... placeholders
|
|
94
|
+
* @param params - Parameter values
|
|
95
|
+
* @returns Query result with typed rows
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* ```ts
|
|
99
|
+
* const result = await client.query<{ id: number; name: string }>(
|
|
100
|
+
* 'SELECT id, name FROM users WHERE org_id = $1',
|
|
101
|
+
* [42]
|
|
102
|
+
* );
|
|
103
|
+
* console.log(result.rows);
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
query<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<QueryResponse<T>>;
|
|
107
|
+
/**
|
|
108
|
+
* Execute a single SQL query and return the first row, or null.
|
|
109
|
+
*/
|
|
110
|
+
queryOne<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<T | null>;
|
|
111
|
+
/**
|
|
112
|
+
* Execute a batch of queries in a single HTTP request.
|
|
113
|
+
* Optionally wraps them in a transaction.
|
|
114
|
+
*
|
|
115
|
+
* @param queries - Array of queries to execute
|
|
116
|
+
* @param options - Batch options
|
|
117
|
+
* @returns Array of results, one per query
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* ```ts
|
|
121
|
+
* const results = await client.batch([
|
|
122
|
+
* { sql: 'SELECT * FROM users WHERE id = $1', params: [1] },
|
|
123
|
+
* { sql: 'SELECT COUNT(*) FROM posts WHERE user_id = $1', params: [1] },
|
|
124
|
+
* ], { transaction: true });
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
127
|
+
batch(queries: QueryRequest[], options?: {
|
|
128
|
+
transaction?: boolean;
|
|
129
|
+
}): Promise<BatchResponse>;
|
|
130
|
+
/**
|
|
131
|
+
* Tagged template helper for SQL queries.
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* ```ts
|
|
135
|
+
* const users = await client.sql<{ id: number; name: string }>`
|
|
136
|
+
* SELECT id, name FROM users WHERE org_id = ${orgId}
|
|
137
|
+
* `;
|
|
138
|
+
* ```
|
|
139
|
+
*/
|
|
140
|
+
sql<T = Record<string, unknown>>(strings: TemplateStringsArray, ...values: unknown[]): Promise<T[]>;
|
|
141
|
+
private post;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Create a serverless Turbine client for edge/serverless environments.
|
|
145
|
+
*
|
|
146
|
+
* @param config - Endpoint URL and auth token
|
|
147
|
+
* @returns A ServerlessClient instance
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* ```ts
|
|
151
|
+
* import { createServerlessClient } from '@batadata/turbine/serverless';
|
|
152
|
+
*
|
|
153
|
+
* const db = createServerlessClient({
|
|
154
|
+
* endpoint: process.env.TURBINE_ENDPOINT!,
|
|
155
|
+
* authToken: process.env.TURBINE_AUTH_TOKEN!,
|
|
156
|
+
* });
|
|
157
|
+
*
|
|
158
|
+
* const users = await db.sql`SELECT * FROM users LIMIT 10`;
|
|
159
|
+
* ```
|
|
160
|
+
*/
|
|
161
|
+
export declare function createServerlessClient(config: ServerlessConfig): ServerlessClient;
|
|
162
|
+
//# sourceMappingURL=serverless.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serverless.d.ts","sourceRoot":"","sources":["../src/serverless.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @batadata/turbine/serverless — HTTP-based query driver for edge functions
|
|
3
|
+
*
|
|
4
|
+
* Use this driver when you cannot establish a direct TCP connection to Postgres
|
|
5
|
+
* (e.g., Vercel Edge Functions, Cloudflare Workers, Deno Deploy).
|
|
6
|
+
*
|
|
7
|
+
* It sends queries as JSON over HTTP to a Turbine query endpoint, which executes
|
|
8
|
+
* them against the actual database and returns typed results.
|
|
9
|
+
*
|
|
10
|
+
* NOTE: This is a scaffold. The server-side query endpoint does not exist yet.
|
|
11
|
+
* The HTTP protocol and response format are defined here and will be implemented
|
|
12
|
+
* on the server side in a future release.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* import { createServerlessClient } from '@batadata/turbine/serverless';
|
|
17
|
+
*
|
|
18
|
+
* const db = createServerlessClient({
|
|
19
|
+
* endpoint: 'https://your-turbine-proxy.fly.dev/query',
|
|
20
|
+
* authToken: process.env.TURBINE_AUTH_TOKEN!,
|
|
21
|
+
* });
|
|
22
|
+
*
|
|
23
|
+
* const result = await db.query('SELECT * FROM users WHERE id = $1', [1]);
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
// Serverless client
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
/**
|
|
30
|
+
* HTTP-based Postgres query client for serverless/edge environments.
|
|
31
|
+
*
|
|
32
|
+
* Sends SQL queries as JSON POST requests to a Turbine query endpoint.
|
|
33
|
+
* Does not require a direct TCP connection to Postgres.
|
|
34
|
+
*/
|
|
35
|
+
export class ServerlessClient {
|
|
36
|
+
config;
|
|
37
|
+
fetchFn;
|
|
38
|
+
constructor(config) {
|
|
39
|
+
if (!config.endpoint) {
|
|
40
|
+
throw new Error('[turbine/serverless] endpoint is required');
|
|
41
|
+
}
|
|
42
|
+
if (!config.authToken) {
|
|
43
|
+
throw new Error('[turbine/serverless] authToken is required');
|
|
44
|
+
}
|
|
45
|
+
this.config = {
|
|
46
|
+
...config,
|
|
47
|
+
timeout: config.timeout ?? 10_000,
|
|
48
|
+
};
|
|
49
|
+
this.fetchFn = config.fetch ?? globalThis.fetch;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Execute a single SQL query.
|
|
53
|
+
*
|
|
54
|
+
* @param sql - SQL string with $1, $2, ... placeholders
|
|
55
|
+
* @param params - Parameter values
|
|
56
|
+
* @returns Query result with typed rows
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* const result = await client.query<{ id: number; name: string }>(
|
|
61
|
+
* 'SELECT id, name FROM users WHERE org_id = $1',
|
|
62
|
+
* [42]
|
|
63
|
+
* );
|
|
64
|
+
* console.log(result.rows);
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
async query(sql, params) {
|
|
68
|
+
const request = { sql, params, mode: 'rows' };
|
|
69
|
+
const response = await this.post('/query', request);
|
|
70
|
+
return response;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Execute a single SQL query and return the first row, or null.
|
|
74
|
+
*/
|
|
75
|
+
async queryOne(sql, params) {
|
|
76
|
+
const request = { sql, params, mode: 'one' };
|
|
77
|
+
const response = await this.post('/query', request);
|
|
78
|
+
return response.rows[0] ?? null;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Execute a batch of queries in a single HTTP request.
|
|
82
|
+
* Optionally wraps them in a transaction.
|
|
83
|
+
*
|
|
84
|
+
* @param queries - Array of queries to execute
|
|
85
|
+
* @param options - Batch options
|
|
86
|
+
* @returns Array of results, one per query
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```ts
|
|
90
|
+
* const results = await client.batch([
|
|
91
|
+
* { sql: 'SELECT * FROM users WHERE id = $1', params: [1] },
|
|
92
|
+
* { sql: 'SELECT COUNT(*) FROM posts WHERE user_id = $1', params: [1] },
|
|
93
|
+
* ], { transaction: true });
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
async batch(queries, options) {
|
|
97
|
+
const request = {
|
|
98
|
+
queries,
|
|
99
|
+
transaction: options?.transaction ?? false,
|
|
100
|
+
};
|
|
101
|
+
return this.post('/batch', request);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Tagged template helper for SQL queries.
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ```ts
|
|
108
|
+
* const users = await client.sql<{ id: number; name: string }>`
|
|
109
|
+
* SELECT id, name FROM users WHERE org_id = ${orgId}
|
|
110
|
+
* `;
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
async sql(strings, ...values) {
|
|
114
|
+
let sqlStr = '';
|
|
115
|
+
strings.forEach((str, i) => {
|
|
116
|
+
sqlStr += str;
|
|
117
|
+
if (i < values.length) {
|
|
118
|
+
sqlStr += `$${i + 1}`;
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
const result = await this.query(sqlStr, values);
|
|
122
|
+
return result.rows;
|
|
123
|
+
}
|
|
124
|
+
// -------------------------------------------------------------------------
|
|
125
|
+
// Internal HTTP transport
|
|
126
|
+
// -------------------------------------------------------------------------
|
|
127
|
+
async post(path, body) {
|
|
128
|
+
const url = this.config.endpoint.replace(/\/$/, '') + path;
|
|
129
|
+
const controller = new AbortController();
|
|
130
|
+
const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
|
|
131
|
+
try {
|
|
132
|
+
const response = await this.fetchFn(url, {
|
|
133
|
+
method: 'POST',
|
|
134
|
+
headers: {
|
|
135
|
+
'Content-Type': 'application/json',
|
|
136
|
+
'Authorization': `Bearer ${this.config.authToken}`,
|
|
137
|
+
'User-Agent': '@batadata/turbine-serverless',
|
|
138
|
+
...this.config.headers,
|
|
139
|
+
},
|
|
140
|
+
body: JSON.stringify(body),
|
|
141
|
+
signal: controller.signal,
|
|
142
|
+
});
|
|
143
|
+
if (!response.ok) {
|
|
144
|
+
const errorBody = await response.text();
|
|
145
|
+
let parsed;
|
|
146
|
+
try {
|
|
147
|
+
parsed = JSON.parse(errorBody);
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
// Not JSON
|
|
151
|
+
}
|
|
152
|
+
const message = parsed?.error ?? `HTTP ${response.status}: ${errorBody.slice(0, 200)}`;
|
|
153
|
+
const err = new Error(`[turbine/serverless] ${message}`);
|
|
154
|
+
err['status'] = response.status;
|
|
155
|
+
err['code'] = parsed?.code;
|
|
156
|
+
throw err;
|
|
157
|
+
}
|
|
158
|
+
return (await response.json());
|
|
159
|
+
}
|
|
160
|
+
catch (err) {
|
|
161
|
+
if (err instanceof DOMException && err.name === 'AbortError') {
|
|
162
|
+
throw new Error(`[turbine/serverless] Request timed out after ${this.config.timeout}ms`);
|
|
163
|
+
}
|
|
164
|
+
throw err;
|
|
165
|
+
}
|
|
166
|
+
finally {
|
|
167
|
+
clearTimeout(timeoutId);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// ---------------------------------------------------------------------------
|
|
172
|
+
// Factory function
|
|
173
|
+
// ---------------------------------------------------------------------------
|
|
174
|
+
/**
|
|
175
|
+
* Create a serverless Turbine client for edge/serverless environments.
|
|
176
|
+
*
|
|
177
|
+
* @param config - Endpoint URL and auth token
|
|
178
|
+
* @returns A ServerlessClient instance
|
|
179
|
+
*
|
|
180
|
+
* @example
|
|
181
|
+
* ```ts
|
|
182
|
+
* import { createServerlessClient } from '@batadata/turbine/serverless';
|
|
183
|
+
*
|
|
184
|
+
* const db = createServerlessClient({
|
|
185
|
+
* endpoint: process.env.TURBINE_ENDPOINT!,
|
|
186
|
+
* authToken: process.env.TURBINE_AUTH_TOKEN!,
|
|
187
|
+
* });
|
|
188
|
+
*
|
|
189
|
+
* const users = await db.sql`SELECT * FROM users LIMIT 10`;
|
|
190
|
+
* ```
|
|
191
|
+
*/
|
|
192
|
+
export function createServerlessClient(config) {
|
|
193
|
+
return new ServerlessClient(config);
|
|
194
|
+
}
|
|
195
|
+
//# sourceMappingURL=serverless.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serverless.js","sourceRoot":"","sources":["../src/serverless.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @batadata/turbine — Generated entity types
|
|
3
|
+
*
|
|
4
|
+
* These types mirror the Postgres schema and would normally be auto-generated
|
|
5
|
+
* by `npx turbine generate` from your database schema or Rust entity definitions.
|
|
6
|
+
*
|
|
7
|
+
* Schema: turbine/sql/schema.sql
|
|
8
|
+
*/
|
|
9
|
+
export interface Organization {
|
|
10
|
+
id: number;
|
|
11
|
+
name: string;
|
|
12
|
+
slug: string;
|
|
13
|
+
plan: string;
|
|
14
|
+
createdAt: Date;
|
|
15
|
+
}
|
|
16
|
+
export interface User {
|
|
17
|
+
id: number;
|
|
18
|
+
orgId: number;
|
|
19
|
+
email: string;
|
|
20
|
+
name: string;
|
|
21
|
+
role: string;
|
|
22
|
+
avatarUrl: string | null;
|
|
23
|
+
lastLoginAt: Date | null;
|
|
24
|
+
createdAt: Date;
|
|
25
|
+
}
|
|
26
|
+
export interface Post {
|
|
27
|
+
id: number;
|
|
28
|
+
userId: number;
|
|
29
|
+
orgId: number;
|
|
30
|
+
title: string;
|
|
31
|
+
content: string;
|
|
32
|
+
published: boolean;
|
|
33
|
+
viewCount: number;
|
|
34
|
+
createdAt: Date;
|
|
35
|
+
updatedAt: Date;
|
|
36
|
+
}
|
|
37
|
+
export interface Comment {
|
|
38
|
+
id: number;
|
|
39
|
+
postId: number;
|
|
40
|
+
userId: number;
|
|
41
|
+
body: string;
|
|
42
|
+
createdAt: Date;
|
|
43
|
+
}
|
|
44
|
+
export type OrganizationCreate = Omit<Organization, 'id' | 'createdAt'>;
|
|
45
|
+
export type OrganizationUpdate = Partial<Omit<Organization, 'id' | 'createdAt'>>;
|
|
46
|
+
export type UserCreate = Omit<User, 'id' | 'createdAt'>;
|
|
47
|
+
export type UserUpdate = Partial<Omit<User, 'id' | 'createdAt'>>;
|
|
48
|
+
export type PostCreate = Omit<Post, 'id' | 'createdAt' | 'updatedAt' | 'viewCount'>;
|
|
49
|
+
export type PostUpdate = Partial<Omit<Post, 'id' | 'createdAt' | 'updatedAt'>>;
|
|
50
|
+
export type CommentCreate = Omit<Comment, 'id' | 'createdAt'>;
|
|
51
|
+
export type CommentUpdate = Partial<Omit<Comment, 'id' | 'createdAt'>>;
|
|
52
|
+
/** User with their posts loaded */
|
|
53
|
+
export interface UserWithPosts extends User {
|
|
54
|
+
posts: Post[];
|
|
55
|
+
}
|
|
56
|
+
/** User with posts and each post's comments */
|
|
57
|
+
export interface UserWithPostsAndComments extends User {
|
|
58
|
+
posts: (Post & {
|
|
59
|
+
comments: Comment[];
|
|
60
|
+
})[];
|
|
61
|
+
}
|
|
62
|
+
/** Post with its comments loaded */
|
|
63
|
+
export interface PostWithComments extends Post {
|
|
64
|
+
comments: Comment[];
|
|
65
|
+
}
|
|
66
|
+
/** Organization with all nested relations (full tree) */
|
|
67
|
+
export interface OrgWithEverything extends Organization {
|
|
68
|
+
users: (User & {
|
|
69
|
+
posts: (Post & {
|
|
70
|
+
comments: Comment[];
|
|
71
|
+
})[];
|
|
72
|
+
})[];
|
|
73
|
+
}
|
|
74
|
+
/** Organization with users loaded */
|
|
75
|
+
export interface OrgWithUsers extends Organization {
|
|
76
|
+
users: User[];
|
|
77
|
+
}
|
|
78
|
+
/** Maps camelCase field names to snake_case column names */
|
|
79
|
+
export declare const COLUMN_MAP: Record<string, Record<string, string>>;
|
|
80
|
+
/** Reverse map: snake_case column -> camelCase field */
|
|
81
|
+
export declare function snakeToCamel(s: string): string;
|
|
82
|
+
/** Forward map: camelCase field -> snake_case column */
|
|
83
|
+
export declare function camelToSnake(s: string): string;
|
|
84
|
+
export interface RelationDef {
|
|
85
|
+
type: 'hasMany' | 'hasOne' | 'belongsTo';
|
|
86
|
+
from: string;
|
|
87
|
+
to: string;
|
|
88
|
+
foreignKey: string;
|
|
89
|
+
referenceKey: string;
|
|
90
|
+
}
|
|
91
|
+
export declare const RELATIONS: Record<string, Record<string, RelationDef>>;
|
|
92
|
+
export declare const DATE_COLUMNS: Record<string, Set<string>>;
|
|
93
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,IAAI,CAAC;CACjB;AAMD,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,YAAY,EAAE,IAAI,GAAG,WAAW,CAAC,CAAC;AACxE,MAAM,MAAM,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC;AAEjF,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,WAAW,CAAC,CAAC;AACxD,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC;AAEjE,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,WAAW,GAAG,WAAW,GAAG,WAAW,CAAC,CAAC;AACpF,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,WAAW,GAAG,WAAW,CAAC,CAAC,CAAC;AAE/E,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,EAAE,IAAI,GAAG,WAAW,CAAC,CAAC;AAC9D,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC;AAMvE,mCAAmC;AACnC,MAAM,WAAW,aAAc,SAAQ,IAAI;IACzC,KAAK,EAAE,IAAI,EAAE,CAAC;CACf;AAED,+CAA+C;AAC/C,MAAM,WAAW,wBAAyB,SAAQ,IAAI;IACpD,KAAK,EAAE,CAAC,IAAI,GAAG;QAAE,QAAQ,EAAE,OAAO,EAAE,CAAA;KAAE,CAAC,EAAE,CAAC;CAC3C;AAED,oCAAoC;AACpC,MAAM,WAAW,gBAAiB,SAAQ,IAAI;IAC5C,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAED,yDAAyD;AACzD,MAAM,WAAW,iBAAkB,SAAQ,YAAY;IACrD,KAAK,EAAE,CAAC,IAAI,GAAG;QAAE,KAAK,EAAE,CAAC,IAAI,GAAG;YAAE,QAAQ,EAAE,OAAO,EAAE,CAAA;SAAE,CAAC,EAAE,CAAA;KAAE,CAAC,EAAE,CAAC;CACjE;AAED,qCAAqC;AACrC,MAAM,WAAW,YAAa,SAAQ,YAAY;IAChD,KAAK,EAAE,IAAI,EAAE,CAAC;CACf;AAMD,4DAA4D;AAC5D,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAoCpD,CAAC;AAEX,wDAAwD;AACxD,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,wDAAwD;AACxD,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE9C;AAMD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,SAAS,GAAG,QAAQ,GAAG,WAAW,CAAC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CA0DxD,CAAC;AAMX,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAKpD,CAAC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @batadata/turbine — Generated entity types
|
|
3
|
+
*
|
|
4
|
+
* These types mirror the Postgres schema and would normally be auto-generated
|
|
5
|
+
* by `npx turbine generate` from your database schema or Rust entity definitions.
|
|
6
|
+
*
|
|
7
|
+
* Schema: turbine/sql/schema.sql
|
|
8
|
+
*/
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// Column-name mappings (camelCase <-> snake_case)
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
/** Maps camelCase field names to snake_case column names */
|
|
13
|
+
export const COLUMN_MAP = {
|
|
14
|
+
organizations: {
|
|
15
|
+
id: 'id',
|
|
16
|
+
name: 'name',
|
|
17
|
+
slug: 'slug',
|
|
18
|
+
plan: 'plan',
|
|
19
|
+
createdAt: 'created_at',
|
|
20
|
+
},
|
|
21
|
+
users: {
|
|
22
|
+
id: 'id',
|
|
23
|
+
orgId: 'org_id',
|
|
24
|
+
email: 'email',
|
|
25
|
+
name: 'name',
|
|
26
|
+
role: 'role',
|
|
27
|
+
avatarUrl: 'avatar_url',
|
|
28
|
+
lastLoginAt: 'last_login_at',
|
|
29
|
+
createdAt: 'created_at',
|
|
30
|
+
},
|
|
31
|
+
posts: {
|
|
32
|
+
id: 'id',
|
|
33
|
+
userId: 'user_id',
|
|
34
|
+
orgId: 'org_id',
|
|
35
|
+
title: 'title',
|
|
36
|
+
content: 'content',
|
|
37
|
+
published: 'published',
|
|
38
|
+
viewCount: 'view_count',
|
|
39
|
+
createdAt: 'created_at',
|
|
40
|
+
updatedAt: 'updated_at',
|
|
41
|
+
},
|
|
42
|
+
comments: {
|
|
43
|
+
id: 'id',
|
|
44
|
+
postId: 'post_id',
|
|
45
|
+
userId: 'user_id',
|
|
46
|
+
body: 'body',
|
|
47
|
+
createdAt: 'created_at',
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
/** Reverse map: snake_case column -> camelCase field */
|
|
51
|
+
export function snakeToCamel(s) {
|
|
52
|
+
return s.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
|
|
53
|
+
}
|
|
54
|
+
/** Forward map: camelCase field -> snake_case column */
|
|
55
|
+
export function camelToSnake(s) {
|
|
56
|
+
return s.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`);
|
|
57
|
+
}
|
|
58
|
+
export const RELATIONS = {
|
|
59
|
+
organizations: {
|
|
60
|
+
users: {
|
|
61
|
+
type: 'hasMany',
|
|
62
|
+
from: 'organizations',
|
|
63
|
+
to: 'users',
|
|
64
|
+
foreignKey: 'org_id',
|
|
65
|
+
referenceKey: 'id',
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
users: {
|
|
69
|
+
organization: {
|
|
70
|
+
type: 'belongsTo',
|
|
71
|
+
from: 'users',
|
|
72
|
+
to: 'organizations',
|
|
73
|
+
foreignKey: 'org_id',
|
|
74
|
+
referenceKey: 'id',
|
|
75
|
+
},
|
|
76
|
+
posts: {
|
|
77
|
+
type: 'hasMany',
|
|
78
|
+
from: 'users',
|
|
79
|
+
to: 'posts',
|
|
80
|
+
foreignKey: 'user_id',
|
|
81
|
+
referenceKey: 'id',
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
posts: {
|
|
85
|
+
user: {
|
|
86
|
+
type: 'belongsTo',
|
|
87
|
+
from: 'posts',
|
|
88
|
+
to: 'users',
|
|
89
|
+
foreignKey: 'user_id',
|
|
90
|
+
referenceKey: 'id',
|
|
91
|
+
},
|
|
92
|
+
comments: {
|
|
93
|
+
type: 'hasMany',
|
|
94
|
+
from: 'posts',
|
|
95
|
+
to: 'comments',
|
|
96
|
+
foreignKey: 'post_id',
|
|
97
|
+
referenceKey: 'id',
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
comments: {
|
|
101
|
+
post: {
|
|
102
|
+
type: 'belongsTo',
|
|
103
|
+
from: 'comments',
|
|
104
|
+
to: 'posts',
|
|
105
|
+
foreignKey: 'post_id',
|
|
106
|
+
referenceKey: 'id',
|
|
107
|
+
},
|
|
108
|
+
user: {
|
|
109
|
+
type: 'belongsTo',
|
|
110
|
+
from: 'comments',
|
|
111
|
+
to: 'users',
|
|
112
|
+
foreignKey: 'user_id',
|
|
113
|
+
referenceKey: 'id',
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
// ---------------------------------------------------------------------------
|
|
118
|
+
// Timestamp columns that need Date parsing
|
|
119
|
+
// ---------------------------------------------------------------------------
|
|
120
|
+
export const DATE_COLUMNS = {
|
|
121
|
+
organizations: new Set(['created_at']),
|
|
122
|
+
users: new Set(['last_login_at', 'created_at']),
|
|
123
|
+
posts: new Set(['created_at', 'updated_at']),
|
|
124
|
+
comments: new Set(['created_at']),
|
|
125
|
+
};
|
|
126
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "turbine-orm",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "TypeScript ORM with json_agg nested queries — 2-3x faster than Prisma, 1.5x faster than Drizzle",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"import": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts"
|
|
10
|
+
},
|
|
11
|
+
"./cli": {
|
|
12
|
+
"import": "./dist/cli/config.js",
|
|
13
|
+
"types": "./dist/cli/config.d.ts"
|
|
14
|
+
},
|
|
15
|
+
"./serverless": {
|
|
16
|
+
"import": "./dist/serverless.js",
|
|
17
|
+
"types": "./dist/serverless.d.ts"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"main": "./dist/index.js",
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"bin": {
|
|
23
|
+
"turbine": "./dist/cli/index.js"
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist",
|
|
27
|
+
"!dist/test",
|
|
28
|
+
"LICENSE",
|
|
29
|
+
"README.md"
|
|
30
|
+
],
|
|
31
|
+
"sideEffects": false,
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "tsc",
|
|
34
|
+
"dev": "tsc --watch",
|
|
35
|
+
"typecheck": "tsc --noEmit",
|
|
36
|
+
"generate": "tsx src/cli/index.ts generate",
|
|
37
|
+
"status": "tsx src/cli/index.ts status",
|
|
38
|
+
"examples": "tsx src/examples.ts",
|
|
39
|
+
"test": "node --test --experimental-strip-types src/test/*.test.ts"
|
|
40
|
+
},
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=22.0.0"
|
|
43
|
+
},
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"pg": "^8.13.1"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@types/pg": "^8.11.11",
|
|
49
|
+
"@types/node": "^22.10.0",
|
|
50
|
+
"typescript": "^5.7.0",
|
|
51
|
+
"tsx": "^4.19.0"
|
|
52
|
+
},
|
|
53
|
+
"keywords": [
|
|
54
|
+
"orm",
|
|
55
|
+
"postgres",
|
|
56
|
+
"postgresql",
|
|
57
|
+
"typescript",
|
|
58
|
+
"json-agg",
|
|
59
|
+
"query-builder",
|
|
60
|
+
"database",
|
|
61
|
+
"sql",
|
|
62
|
+
"turbine",
|
|
63
|
+
"batadata",
|
|
64
|
+
"nested-queries"
|
|
65
|
+
],
|
|
66
|
+
"author": "ZVN DEV <dev@zvndev.com>",
|
|
67
|
+
"license": "MIT",
|
|
68
|
+
"homepage": "https://turbine.batadata.com",
|
|
69
|
+
"repository": {
|
|
70
|
+
"type": "git",
|
|
71
|
+
"url": "https://github.com/zvndev/nexus-postgres",
|
|
72
|
+
"directory": "turbine/turbine-ts"
|
|
73
|
+
}
|
|
74
|
+
}
|