@vibeorm/runtime 1.0.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 +74 -0
- package/package.json +47 -0
- package/src/adapter.ts +114 -0
- package/src/client.ts +2055 -0
- package/src/errors.ts +39 -0
- package/src/id-generators.ts +151 -0
- package/src/index.ts +36 -0
- package/src/lateral-join-builder.ts +759 -0
- package/src/query-builder.ts +1417 -0
- package/src/relation-loader.ts +489 -0
- package/src/types.ts +290 -0
- package/src/where-builder.ts +737 -0
package/README.md
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# @vibeorm/runtime
|
|
2
|
+
|
|
3
|
+
Driver-agnostic query engine and client runtime for VibeORM. This package contains the SQL query builder, WHERE clause compiler, relation loading strategies, and client factory. It does **not** include any database driver — use an adapter package to connect to PostgreSQL.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bun add @vibeorm/runtime
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
You also need an adapter:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
bun add @vibeorm/adapter-bun # for bun:sql
|
|
15
|
+
# or
|
|
16
|
+
bun add @vibeorm/adapter-pg pg # for node-postgres
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
This package is consumed by the generated client. You typically don't import from it directly — the generated `index.ts` calls `createClient()` internally.
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
// The generated client wires everything together:
|
|
25
|
+
import { VibeClient } from "./generated/vibeorm/index.ts";
|
|
26
|
+
|
|
27
|
+
const db = VibeClient({
|
|
28
|
+
relationStrategy: "query",
|
|
29
|
+
log: false,
|
|
30
|
+
});
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## API
|
|
34
|
+
|
|
35
|
+
### `createClient({ options, modelMeta, schemas? })`
|
|
36
|
+
|
|
37
|
+
Creates a VibeORM client instance. Called by generated code — takes model metadata, optional Zod schemas, and client options.
|
|
38
|
+
|
|
39
|
+
### `toSqlExecutor({ adapter })`
|
|
40
|
+
|
|
41
|
+
Bridges a `DatabaseAdapter` to a `SqlExecutor` for use with the migrate package.
|
|
42
|
+
|
|
43
|
+
### `VibeValidationError`
|
|
44
|
+
|
|
45
|
+
Custom error class thrown when Zod validation fails on input or output data.
|
|
46
|
+
|
|
47
|
+
### `DatabaseAdapter` interface
|
|
48
|
+
|
|
49
|
+
The contract that adapter packages implement:
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
type DatabaseAdapter = {
|
|
53
|
+
execute(params: { text: string; values: unknown[] }): Promise<Record<string, unknown>[]>;
|
|
54
|
+
executeRaw(params: { text: string; values: unknown[] }): Promise<QueryResult>;
|
|
55
|
+
transaction<T>(params: { fn: (adapter: DatabaseAdapter) => Promise<T> }): Promise<T>;
|
|
56
|
+
connect(): Promise<void>;
|
|
57
|
+
disconnect(): Promise<void>;
|
|
58
|
+
};
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Relation Loading Strategies
|
|
62
|
+
|
|
63
|
+
| Strategy | Method | Best for |
|
|
64
|
+
|----------|--------|----------|
|
|
65
|
+
| `"query"` | Parent query + batched `WHERE IN` queries | Deep/nested includes |
|
|
66
|
+
| `"join"` | `LEFT JOIN LATERAL` + JSON aggregation | Flat includes, fewer round-trips |
|
|
67
|
+
|
|
68
|
+
### Exported Types
|
|
69
|
+
|
|
70
|
+
`DatabaseAdapter`, `QueryResult`, `SqlExecutor`, `VibeClientOptions`, `ModelMeta`, `ModelMetaMap`, `ModelSchemas`, `ValidationSchema`, `QueryProfile`, `RelationProfile`, `ScalarFieldMeta`, `RelationFieldMeta`, `SqlQuery`, `Operation`.
|
|
71
|
+
|
|
72
|
+
## License
|
|
73
|
+
|
|
74
|
+
[MIT](../../LICENSE)
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vibeorm/runtime",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Driver-agnostic query engine and client runtime for VibeORM",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"orm",
|
|
8
|
+
"runtime",
|
|
9
|
+
"query-builder",
|
|
10
|
+
"bun",
|
|
11
|
+
"typescript",
|
|
12
|
+
"postgresql"
|
|
13
|
+
],
|
|
14
|
+
"type": "module",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"default": "./src/index.ts",
|
|
18
|
+
"types": "./src/index.ts"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"src"
|
|
23
|
+
],
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "https://github.com/vibeorm/vibeorm.git",
|
|
27
|
+
"directory": "packages/runtime"
|
|
28
|
+
},
|
|
29
|
+
"homepage": "https://github.com/vibeorm/vibeorm/tree/master/packages/runtime",
|
|
30
|
+
"bugs": {
|
|
31
|
+
"url": "https://github.com/vibeorm/vibeorm/issues"
|
|
32
|
+
},
|
|
33
|
+
"engines": {
|
|
34
|
+
"bun": ">=1.1.0"
|
|
35
|
+
},
|
|
36
|
+
"peerDependencies": {
|
|
37
|
+
"zod": ">=4"
|
|
38
|
+
},
|
|
39
|
+
"peerDependenciesMeta": {
|
|
40
|
+
"zod": {
|
|
41
|
+
"optional": true
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"publishConfig": {
|
|
45
|
+
"access": "public"
|
|
46
|
+
}
|
|
47
|
+
}
|
package/src/adapter.ts
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database adapter interface for VibeORM.
|
|
3
|
+
*
|
|
4
|
+
* Each adapter implementation (bun:sql, pg, etc.) provides a concrete
|
|
5
|
+
* implementation of this interface. The runtime is completely driver-agnostic
|
|
6
|
+
* and interacts with the database exclusively through this contract.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
// ─── Core Adapter Interface ───────────────────────────────────────
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The primary interface that every database adapter must implement.
|
|
13
|
+
* Adapters own connection management, query execution, statement caching,
|
|
14
|
+
* transactions, and driver-specific parameter formatting.
|
|
15
|
+
*/
|
|
16
|
+
export type DatabaseAdapter = {
|
|
17
|
+
/**
|
|
18
|
+
* Execute a parameterized query and return rows.
|
|
19
|
+
* The adapter owns statement caching and driver-specific optimizations.
|
|
20
|
+
*
|
|
21
|
+
* For bun:sql this means synthetic tagged template caching.
|
|
22
|
+
* For pg this means named prepared statement caching.
|
|
23
|
+
*/
|
|
24
|
+
execute(params: { text: string; values: unknown[] }): Promise<Record<string, unknown>[]>;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Execute a raw/unsafe query without prepared statement caching.
|
|
28
|
+
* Used for `$queryRawUnsafe`, `$executeRawUnsafe`, and dynamic DDL.
|
|
29
|
+
*
|
|
30
|
+
* Returns both rows and affected row count (for INSERT/UPDATE/DELETE).
|
|
31
|
+
*/
|
|
32
|
+
executeUnsafe(params: {
|
|
33
|
+
text: string;
|
|
34
|
+
values?: unknown[];
|
|
35
|
+
}): Promise<QueryResult>;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Run a function inside a database transaction.
|
|
39
|
+
* The callback receives a transactional adapter with the same interface.
|
|
40
|
+
* If the callback throws, the transaction is automatically rolled back.
|
|
41
|
+
*/
|
|
42
|
+
transaction<T>(fn: (txAdapter: DatabaseAdapter) => Promise<T>): Promise<T>;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Eagerly warm up the connection pool.
|
|
46
|
+
* Forces at least one TCP handshake + auth so subsequent queries start instantly.
|
|
47
|
+
*/
|
|
48
|
+
connect(): Promise<void>;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Gracefully close all connections in the pool.
|
|
52
|
+
*/
|
|
53
|
+
disconnect(): Promise<void>;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Convert a JS array to the driver's preferred format for `= ANY($N)` queries.
|
|
57
|
+
*
|
|
58
|
+
* - **bun:sql**: Returns a PG array literal string `"{val1,val2,val3}"` because
|
|
59
|
+
* bun:sql's extended query protocol sends values as strings.
|
|
60
|
+
* - **pg**: Returns the raw JS array (pg driver handles native array serialization).
|
|
61
|
+
*/
|
|
62
|
+
formatArrayParam(values: unknown[]): unknown;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// ─── Query Result ─────────────────────────────────────────────────
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Result from an unsafe query execution.
|
|
69
|
+
* Contains both the rows returned and the number of affected rows
|
|
70
|
+
* (parsed from the PostgreSQL CommandComplete tag).
|
|
71
|
+
*/
|
|
72
|
+
export type QueryResult = {
|
|
73
|
+
rows: Record<string, unknown>[];
|
|
74
|
+
affectedRows: number;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
// ─── SQL Executor (Migration Compatibility) ───────────────────────
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Minimal SQL execution interface compatible with `@vibeorm/migrate`.
|
|
81
|
+
* Adapters expose this via a helper function so migrations can run
|
|
82
|
+
* without knowing which adapter is in use.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```ts
|
|
86
|
+
* import { bunAdapter } from "@vibeorm/adapter-bun";
|
|
87
|
+
* import { toSqlExecutor } from "@vibeorm/runtime";
|
|
88
|
+
*
|
|
89
|
+
* const adapter = bunAdapter({ url: "postgres://..." });
|
|
90
|
+
* const executor = toSqlExecutor({ adapter });
|
|
91
|
+
* await applyMigration({ executor, migrationName: "init", sql, checksum });
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
export type SqlExecutor = (params: {
|
|
95
|
+
text: string;
|
|
96
|
+
values?: unknown[];
|
|
97
|
+
}) => Promise<Record<string, unknown>[]>;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Create an SqlExecutor from a DatabaseAdapter.
|
|
101
|
+
* Bridges the adapter pattern with the migrate package's SqlExecutor interface.
|
|
102
|
+
*/
|
|
103
|
+
export function toSqlExecutor(params: {
|
|
104
|
+
adapter: DatabaseAdapter;
|
|
105
|
+
}): SqlExecutor {
|
|
106
|
+
const { adapter } = params;
|
|
107
|
+
return async (queryParams) => {
|
|
108
|
+
const result = await adapter.executeUnsafe({
|
|
109
|
+
text: queryParams.text,
|
|
110
|
+
values: queryParams.values,
|
|
111
|
+
});
|
|
112
|
+
return result.rows;
|
|
113
|
+
};
|
|
114
|
+
}
|