@bunnykit/orm 0.1.0 → 0.1.1
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 +18 -2
- package/dist/bin/bunny.js +132 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Bunny
|
|
2
2
|
|
|
3
|
+
> **Bun-only package.** Install with:
|
|
4
|
+
>
|
|
5
|
+
> ```bash
|
|
6
|
+
> bun add @bunnykit/orm
|
|
7
|
+
> ```
|
|
8
|
+
>
|
|
9
|
+
> npm, yarn, pnpm, and Node.js runtime usage are not supported.
|
|
10
|
+
|
|
3
11
|
An **Eloquent-inspired ORM** built specifically for [Bun](https://bun.sh)'s native `bun:sql` client. Supports **SQLite**, **MySQL**, and **PostgreSQL** with full TypeScript typing, a chainable query builder, schema migrations, model observers, and polymorphic relations.
|
|
4
12
|
|
|
5
13
|
---
|
|
@@ -24,8 +32,6 @@ An **Eloquent-inspired ORM** built specifically for [Bun](https://bun.sh)'s nati
|
|
|
24
32
|
bun add @bunnykit/orm
|
|
25
33
|
```
|
|
26
34
|
|
|
27
|
-
> **Note:** This package is Bun-only. Install and run it with Bun >= 1.1; npm, yarn, pnpm, and Node.js runtime usage are not supported.
|
|
28
|
-
|
|
29
35
|
---
|
|
30
36
|
|
|
31
37
|
## Configuration
|
|
@@ -137,6 +143,16 @@ await user.save();
|
|
|
137
143
|
await user.delete();
|
|
138
144
|
```
|
|
139
145
|
|
|
146
|
+
### REPL
|
|
147
|
+
|
|
148
|
+
Start an interactive Bunny session with the ORM already loaded:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
bunny repl
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
The REPL exposes `Model`, `Schema`, `Connection`, and `db`. If no project config is present, it starts against an in-memory SQLite database so you can still experiment immediately.
|
|
155
|
+
|
|
140
156
|
---
|
|
141
157
|
|
|
142
158
|
## Schema Builder
|
package/dist/bin/bunny.js
CHANGED
|
@@ -4,8 +4,125 @@ import { Migrator } from "../src/migration/Migrator.js";
|
|
|
4
4
|
import { MigrationCreator } from "../src/migration/MigrationCreator.js";
|
|
5
5
|
import { TypeGenerator } from "../src/typegen/TypeGenerator.js";
|
|
6
6
|
import { existsSync } from "fs";
|
|
7
|
+
import { mkdir, writeFile, rm } from "fs/promises";
|
|
7
8
|
import { join } from "path";
|
|
8
|
-
|
|
9
|
+
import { tmpdir } from "os";
|
|
10
|
+
async function createReplBootstrap(config) {
|
|
11
|
+
const dir = join(tmpdir(), "bunny-repl");
|
|
12
|
+
await mkdir(dir, { recursive: true });
|
|
13
|
+
const bootstrapPath = join(dir, `bootstrap-${Date.now()}-${Math.random().toString(36).slice(2)}.ts`);
|
|
14
|
+
const source = `
|
|
15
|
+
import {
|
|
16
|
+
BelongsTo,
|
|
17
|
+
BelongsToMany,
|
|
18
|
+
Blueprint,
|
|
19
|
+
Builder,
|
|
20
|
+
Connection,
|
|
21
|
+
Grammar,
|
|
22
|
+
HasMany,
|
|
23
|
+
HasManyThrough,
|
|
24
|
+
HasOne,
|
|
25
|
+
HasOneThrough,
|
|
26
|
+
Migration,
|
|
27
|
+
MigrationCreator,
|
|
28
|
+
Migrator,
|
|
29
|
+
MorphMany,
|
|
30
|
+
MorphMap,
|
|
31
|
+
MorphOne,
|
|
32
|
+
MorphTo,
|
|
33
|
+
MorphToMany,
|
|
34
|
+
MySqlGrammar,
|
|
35
|
+
ObserverRegistry,
|
|
36
|
+
PostgresGrammar,
|
|
37
|
+
Schema,
|
|
38
|
+
SQLiteGrammar,
|
|
39
|
+
TypeGenerator,
|
|
40
|
+
TypeMapper,
|
|
41
|
+
Model
|
|
42
|
+
} from "@bunnykit/orm";
|
|
43
|
+
|
|
44
|
+
const connection = new Connection(${JSON.stringify(config.connection)});
|
|
45
|
+
Model.setConnection(connection);
|
|
46
|
+
Schema.setConnection(connection);
|
|
47
|
+
|
|
48
|
+
Object.assign(globalThis, {
|
|
49
|
+
Connection,
|
|
50
|
+
Builder,
|
|
51
|
+
Blueprint,
|
|
52
|
+
Grammar,
|
|
53
|
+
SQLiteGrammar,
|
|
54
|
+
MySqlGrammar,
|
|
55
|
+
PostgresGrammar,
|
|
56
|
+
Model,
|
|
57
|
+
HasMany,
|
|
58
|
+
BelongsTo,
|
|
59
|
+
HasOne,
|
|
60
|
+
HasManyThrough,
|
|
61
|
+
HasOneThrough,
|
|
62
|
+
BelongsToMany,
|
|
63
|
+
MorphMap,
|
|
64
|
+
MorphTo,
|
|
65
|
+
MorphOne,
|
|
66
|
+
MorphMany,
|
|
67
|
+
MorphToMany,
|
|
68
|
+
ObserverRegistry,
|
|
69
|
+
Migration,
|
|
70
|
+
Migrator,
|
|
71
|
+
MigrationCreator,
|
|
72
|
+
TypeGenerator,
|
|
73
|
+
TypeMapper,
|
|
74
|
+
Schema,
|
|
75
|
+
db: connection,
|
|
76
|
+
connection,
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
console.log('Bunny REPL ready. Use Model, Schema, db, and your own imports.');
|
|
80
|
+
`;
|
|
81
|
+
await writeFile(bootstrapPath, source, "utf-8");
|
|
82
|
+
return bootstrapPath;
|
|
83
|
+
}
|
|
84
|
+
async function runRepl(config, replArgs) {
|
|
85
|
+
const bootstrapPath = await createReplBootstrap(config);
|
|
86
|
+
const proc = Bun.spawn(["bun", "repl", ...replArgs], {
|
|
87
|
+
terminal: {
|
|
88
|
+
cols: process.stdout.columns || 80,
|
|
89
|
+
rows: process.stdout.rows || 24,
|
|
90
|
+
data(_terminal, data) {
|
|
91
|
+
process.stdout.write(data);
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
const stdin = process.stdin;
|
|
96
|
+
const terminal = proc.terminal;
|
|
97
|
+
const restoreRawMode = stdin.isTTY && typeof stdin.setRawMode === "function";
|
|
98
|
+
if (restoreRawMode) {
|
|
99
|
+
stdin.setRawMode(true);
|
|
100
|
+
}
|
|
101
|
+
stdin.resume();
|
|
102
|
+
const onData = (chunk) => {
|
|
103
|
+
terminal.write(chunk);
|
|
104
|
+
};
|
|
105
|
+
stdin.on("data", onData);
|
|
106
|
+
const cleanup = async () => {
|
|
107
|
+
stdin.off("data", onData);
|
|
108
|
+
if (restoreRawMode) {
|
|
109
|
+
stdin.setRawMode(false);
|
|
110
|
+
}
|
|
111
|
+
terminal.close();
|
|
112
|
+
await rm(bootstrapPath, { force: true });
|
|
113
|
+
};
|
|
114
|
+
process.once("SIGINT", () => {
|
|
115
|
+
terminal.close();
|
|
116
|
+
});
|
|
117
|
+
process.once("SIGTERM", () => {
|
|
118
|
+
terminal.close();
|
|
119
|
+
});
|
|
120
|
+
terminal.write(`.load ${bootstrapPath}\n`);
|
|
121
|
+
const exitCode = await proc.exited;
|
|
122
|
+
await cleanup();
|
|
123
|
+
return exitCode;
|
|
124
|
+
}
|
|
125
|
+
async function loadConfig(allowFallback = false) {
|
|
9
126
|
const configPath = join(process.cwd(), "bunny.config.ts");
|
|
10
127
|
if (existsSync(configPath)) {
|
|
11
128
|
const mod = await import(configPath);
|
|
@@ -39,6 +156,12 @@ async function loadConfig() {
|
|
|
39
156
|
migrationsPath: process.env.MIGRATIONS_PATH || "./database/migrations",
|
|
40
157
|
};
|
|
41
158
|
}
|
|
159
|
+
if (allowFallback) {
|
|
160
|
+
return {
|
|
161
|
+
connection: { url: "sqlite://:memory:" },
|
|
162
|
+
migrationsPath: process.env.MIGRATIONS_PATH || "./database/migrations",
|
|
163
|
+
};
|
|
164
|
+
}
|
|
42
165
|
throw new Error("No database configuration found. Create bunny.config.ts or set DATABASE_URL / DB_CONNECTION environment variables.");
|
|
43
166
|
}
|
|
44
167
|
async function main() {
|
|
@@ -73,6 +196,12 @@ async function main() {
|
|
|
73
196
|
console.log(`Generated model type declarations in ${outDir}`);
|
|
74
197
|
return;
|
|
75
198
|
}
|
|
199
|
+
if (command === "repl") {
|
|
200
|
+
const config = await loadConfig(true);
|
|
201
|
+
const replArgs = args.slice(1);
|
|
202
|
+
const exitCode = await runRepl(config, replArgs);
|
|
203
|
+
process.exit(exitCode);
|
|
204
|
+
}
|
|
76
205
|
const config = await loadConfig();
|
|
77
206
|
const connection = new Connection(config.connection);
|
|
78
207
|
const migrator = new Migrator(connection, config.migrationsPath, config.typesOutDir, {
|
|
@@ -100,6 +229,8 @@ async function main() {
|
|
|
100
229
|
console.log(" bun run bunny migrate:rollback Rollback the last batch");
|
|
101
230
|
console.log(" bun run bunny migrate:status Show migration status");
|
|
102
231
|
console.log(" bun run bunny types:generate [dir] Generate model type declarations from DB schema");
|
|
232
|
+
console.log(" bun run bunny repl Start a Bunny REPL with Model, Schema, and db loaded");
|
|
233
|
+
console.log(" Falls back to in-memory SQLite when no config is present");
|
|
103
234
|
}
|
|
104
235
|
}
|
|
105
236
|
main().catch((err) => {
|
package/package.json
CHANGED