spindb 0.15.2 → 0.17.3
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 +176 -81
- package/bin/cli.js +46 -10
- package/cli/commands/backup.ts +4 -1
- package/cli/commands/backups.ts +17 -23
- package/cli/commands/config.ts +1 -3
- package/cli/commands/connect.ts +16 -2
- package/cli/commands/create.ts +18 -9
- package/cli/commands/deps.ts +1 -3
- package/cli/commands/doctor.ts +29 -16
- package/cli/commands/edit.ts +4 -12
- package/cli/commands/engines.ts +730 -52
- package/cli/commands/list.ts +1 -3
- package/cli/commands/menu/backup-handlers.ts +36 -39
- package/cli/commands/menu/container-handlers.ts +6 -10
- package/cli/commands/menu/engine-handlers.ts +71 -639
- package/cli/commands/menu/shared.ts +2 -6
- package/cli/commands/menu/shell-handlers.ts +63 -16
- package/cli/commands/menu/sql-handlers.ts +10 -7
- package/cli/commands/run.ts +7 -2
- package/cli/commands/start.ts +10 -7
- package/cli/commands/stop.ts +9 -4
- package/cli/constants.ts +2 -1
- package/cli/helpers.ts +358 -357
- package/cli/ui/prompts.ts +8 -16
- package/cli/ui/spinner.ts +3 -9
- package/cli/utils/file-follower.ts +1 -3
- package/config/backup-formats.ts +42 -27
- package/config/engine-defaults.ts +25 -15
- package/config/engines-registry.ts +93 -0
- package/config/engines.json +109 -0
- package/config/engines.schema.json +117 -0
- package/config/os-dependencies.ts +72 -30
- package/config/paths.ts +7 -21
- package/core/backup-restore.ts +16 -32
- package/core/binary-manager.ts +165 -19
- package/core/config-manager.ts +187 -14
- package/core/dependency-manager.ts +13 -46
- package/core/error-handler.ts +1 -3
- package/core/homebrew-version-manager.ts +22 -22
- package/core/hostdb-client.ts +173 -0
- package/core/hostdb-metadata.ts +325 -0
- package/core/platform-service.ts +16 -72
- package/core/process-manager.ts +3 -1
- package/core/spawn-utils.ts +120 -0
- package/core/start-with-retry.ts +1 -3
- package/core/transaction-manager.ts +2 -6
- package/core/update-manager.ts +5 -15
- package/core/version-utils.ts +77 -0
- package/engines/base-engine.ts +29 -42
- package/engines/index.ts +6 -9
- package/engines/mariadb/backup.ts +8 -10
- package/engines/mariadb/binary-manager.ts +58 -138
- package/engines/mariadb/binary-urls.ts +3 -12
- package/engines/mariadb/hostdb-releases.ts +95 -180
- package/engines/mariadb/index.ts +24 -17
- package/engines/mariadb/restore.ts +10 -8
- package/engines/mariadb/version-maps.ts +21 -15
- package/engines/mariadb/version-validator.ts +12 -24
- package/engines/mongodb/backup.ts +2 -6
- package/engines/mongodb/binary-manager.ts +435 -0
- package/engines/mongodb/binary-urls.ts +71 -0
- package/engines/mongodb/cli-utils.ts +78 -0
- package/engines/mongodb/hostdb-releases.ts +182 -0
- package/engines/mongodb/index.ts +217 -152
- package/engines/mongodb/restore.ts +8 -16
- package/engines/mongodb/version-maps.ts +89 -0
- package/engines/mongodb/version-validator.ts +2 -6
- package/engines/mysql/backup.ts +13 -11
- package/engines/mysql/binary-detection.ts +116 -108
- package/engines/mysql/binary-manager.ts +395 -0
- package/engines/mysql/binary-urls.ts +122 -0
- package/engines/mysql/hostdb-releases.ts +199 -0
- package/engines/mysql/index.ts +356 -507
- package/engines/mysql/restore.ts +47 -13
- package/engines/mysql/version-maps.ts +88 -0
- package/engines/mysql/version-validator.ts +2 -6
- package/engines/postgresql/backup.ts +1 -3
- package/engines/postgresql/binary-manager.ts +63 -36
- package/engines/postgresql/binary-urls.ts +4 -15
- package/engines/postgresql/hostdb-releases.ts +101 -170
- package/engines/postgresql/index.ts +45 -70
- package/engines/postgresql/remote-version.ts +1 -3
- package/engines/postgresql/restore.ts +4 -12
- package/engines/postgresql/version-maps.ts +31 -8
- package/engines/postgresql/version-validator.ts +1 -3
- package/engines/redis/backup.ts +131 -100
- package/engines/redis/binary-manager.ts +471 -0
- package/engines/redis/binary-urls.ts +140 -0
- package/engines/redis/cli-utils.ts +44 -0
- package/engines/redis/hostdb-releases.ts +177 -0
- package/engines/redis/index.ts +285 -197
- package/engines/redis/restore.ts +54 -23
- package/engines/redis/version-maps.ts +80 -0
- package/engines/redis/version-validator.ts +1 -3
- package/engines/sqlite/binary-manager.ts +431 -0
- package/engines/sqlite/binary-urls.ts +120 -0
- package/engines/sqlite/index.ts +165 -64
- package/engines/sqlite/registry.ts +9 -27
- package/engines/sqlite/version-maps.ts +63 -0
- package/engines/valkey/backup.ts +389 -0
- package/engines/valkey/binary-manager.ts +473 -0
- package/engines/valkey/binary-urls.ts +143 -0
- package/engines/valkey/cli-utils.ts +44 -0
- package/engines/valkey/hostdb-releases.ts +182 -0
- package/engines/valkey/index.ts +1022 -0
- package/engines/valkey/restore.ts +415 -0
- package/engines/valkey/version-maps.ts +80 -0
- package/engines/valkey/version-validator.ts +131 -0
- package/package.json +11 -2
- package/types/index.ts +103 -21
- package/engines/mongodb/binary-detection.ts +0 -314
- package/engines/redis/binary-detection.ts +0 -442
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
**The first npm CLI for running local databases without Docker.**
|
|
9
9
|
|
|
10
|
-
Spin up PostgreSQL, MySQL, MariaDB, SQLite, MongoDB, and
|
|
10
|
+
Spin up PostgreSQL, MySQL, MariaDB, SQLite, MongoDB, Redis, and Valkey instances for local development. No Docker daemon, no container networking, no volume mounts. Just databases running on localhost, ready in seconds.
|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|
|
@@ -136,7 +136,7 @@ You'll get an interactive menu with arrow-key navigation:
|
|
|
136
136
|
|
|
137
137
|
| | |
|
|
138
138
|
|---|---|
|
|
139
|
-
| Versions |
|
|
139
|
+
| Versions | 15, 16, 17, 18 |
|
|
140
140
|
| Default port | 5432 |
|
|
141
141
|
| Default user | `postgres` |
|
|
142
142
|
| Binary source | [hostdb](https://github.com/robertjbass/hostdb) (macOS/Linux), [EDB](https://www.enterprisedb.com/) (Windows) |
|
|
@@ -177,43 +177,39 @@ MariaDB is MySQL-compatible, so most MySQL tools and clients work seamlessly. If
|
|
|
177
177
|
|
|
178
178
|
| | |
|
|
179
179
|
|---|---|
|
|
180
|
-
| Versions |
|
|
180
|
+
| Versions | 8.0, 8.4, 9 |
|
|
181
181
|
| Default port | 3306 |
|
|
182
182
|
| Default user | `root` |
|
|
183
|
-
| Binary source |
|
|
183
|
+
| Binary source | [hostdb](https://github.com/robertjbass/hostdb) |
|
|
184
184
|
|
|
185
|
-
|
|
185
|
+
SpinDB downloads MySQL server binaries automatically from [hostdb](https://github.com/robertjbass/hostdb) on GitHub Releases—just like PostgreSQL and MariaDB. This provides multi-version support and works across all platforms.
|
|
186
186
|
|
|
187
187
|
```bash
|
|
188
|
-
#
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
# Ubuntu/Debian
|
|
192
|
-
sudo apt install mysql-server
|
|
193
|
-
|
|
194
|
-
# Windows (Chocolatey)
|
|
195
|
-
choco install mysql
|
|
188
|
+
# Create a MySQL container
|
|
189
|
+
spindb create mydb --engine mysql
|
|
196
190
|
|
|
197
|
-
#
|
|
198
|
-
|
|
191
|
+
# Create with specific version
|
|
192
|
+
spindb create mydb --engine mysql --version 8.0
|
|
199
193
|
|
|
200
|
-
# Check
|
|
194
|
+
# Check what's available
|
|
201
195
|
spindb deps check --engine mysql
|
|
202
196
|
```
|
|
203
197
|
|
|
204
|
-
**
|
|
198
|
+
**Client tools included:** MySQL binaries include `mysql`, `mysqldump`, and `mysqladmin` for all operations. No system installation required.
|
|
205
199
|
|
|
206
200
|
#### SQLite
|
|
207
201
|
|
|
208
202
|
| | |
|
|
209
203
|
|---|---|
|
|
210
|
-
| Version | 3
|
|
204
|
+
| Version | 3 |
|
|
211
205
|
| Default port | N/A (file-based) |
|
|
212
206
|
| Data location | Project directory (CWD) |
|
|
213
|
-
| Binary source |
|
|
207
|
+
| Binary source | [hostdb](https://github.com/robertjbass/hostdb) |
|
|
214
208
|
|
|
215
209
|
SQLite is a file-based database—no server process, no ports. Databases are stored in your project directory by default, not `~/.spindb/`. SpinDB tracks registered SQLite databases in a registry file.
|
|
216
210
|
|
|
211
|
+
**Tools included:** SQLite binaries include `sqlite3`, `sqldiff`, `sqlite3_analyzer`, and `sqlite3_rsync`. No system installation required.
|
|
212
|
+
|
|
217
213
|
```bash
|
|
218
214
|
# Create in current directory
|
|
219
215
|
spindb create mydb --engine sqlite
|
|
@@ -234,25 +230,21 @@ spindb connect mydb --litecli
|
|
|
234
230
|
|
|
235
231
|
| | |
|
|
236
232
|
|---|---|
|
|
237
|
-
| Versions |
|
|
233
|
+
| Versions | 7.0, 8.0, 8.2 |
|
|
238
234
|
| Default port | 27017 |
|
|
239
235
|
| Default user | None (no auth by default) |
|
|
240
|
-
| Binary source |
|
|
236
|
+
| Binary source | [hostdb](https://github.com/robertjbass/hostdb) |
|
|
241
237
|
|
|
242
|
-
|
|
238
|
+
SpinDB downloads MongoDB server binaries automatically from [hostdb](https://github.com/robertjbass/hostdb) on GitHub Releases—just like PostgreSQL, MariaDB, and MySQL. This provides multi-version support on all platforms.
|
|
243
239
|
|
|
244
240
|
```bash
|
|
245
|
-
#
|
|
246
|
-
|
|
247
|
-
brew install mongodb-community mongosh mongodb-database-tools
|
|
241
|
+
# Create a MongoDB container (downloads binaries automatically)
|
|
242
|
+
spindb create mydb --engine mongodb
|
|
248
243
|
|
|
249
|
-
#
|
|
250
|
-
|
|
244
|
+
# Create with specific version
|
|
245
|
+
spindb create mydb --engine mongodb --version 8.0
|
|
251
246
|
|
|
252
|
-
#
|
|
253
|
-
choco install mongodb mongodb-shell mongodb-database-tools
|
|
254
|
-
|
|
255
|
-
# Check if SpinDB can find MongoDB
|
|
247
|
+
# Check what's available
|
|
256
248
|
spindb deps check --engine mongodb
|
|
257
249
|
```
|
|
258
250
|
|
|
@@ -273,24 +265,21 @@ spindb run mydb --file ./scripts/seed.js
|
|
|
273
265
|
|
|
274
266
|
| | |
|
|
275
267
|
|---|---|
|
|
276
|
-
| Versions |
|
|
268
|
+
| Versions | 7, 8 |
|
|
277
269
|
| Default port | 6379 |
|
|
278
270
|
| Default user | None (no auth by default) |
|
|
279
|
-
| Binary source |
|
|
271
|
+
| Binary source | [hostdb](https://github.com/robertjbass/hostdb) |
|
|
280
272
|
|
|
281
|
-
|
|
273
|
+
SpinDB downloads Redis server binaries automatically from [hostdb](https://github.com/robertjbass/hostdb) on GitHub Releases—just like PostgreSQL, MariaDB, MySQL, and MongoDB. This provides multi-version support on all platforms.
|
|
282
274
|
|
|
283
275
|
```bash
|
|
284
|
-
#
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
# Ubuntu/Debian
|
|
288
|
-
sudo apt install redis-server redis-tools
|
|
276
|
+
# Create a Redis container (downloads binaries automatically)
|
|
277
|
+
spindb create mydb --engine redis
|
|
289
278
|
|
|
290
|
-
#
|
|
291
|
-
|
|
279
|
+
# Create with specific version
|
|
280
|
+
spindb create mydb --engine redis --version 8
|
|
292
281
|
|
|
293
|
-
# Check
|
|
282
|
+
# Check what's available
|
|
294
283
|
spindb deps check --engine redis
|
|
295
284
|
```
|
|
296
285
|
|
|
@@ -312,6 +301,97 @@ spindb connect myredis --iredis
|
|
|
312
301
|
|
|
313
302
|
**Note:** Redis doesn't support remote dump/restore. Creating containers from remote Redis connection strings is not supported. Use `backup` and `restore` commands for data migration.
|
|
314
303
|
|
|
304
|
+
#### Valkey
|
|
305
|
+
|
|
306
|
+
| | |
|
|
307
|
+
|---|---|
|
|
308
|
+
| Versions | 8, 9 |
|
|
309
|
+
| Default port | 6379 |
|
|
310
|
+
| Default user | None (no auth by default) |
|
|
311
|
+
| Binary source | [hostdb](https://github.com/robertjbass/hostdb) |
|
|
312
|
+
|
|
313
|
+
Valkey is a Redis fork created after Redis changed its license (RSALv2/SSPLv1). It's fully API-compatible with Redis, making it a drop-in replacement with permissive BSD-3 licensing.
|
|
314
|
+
|
|
315
|
+
SpinDB downloads Valkey server binaries automatically from [hostdb](https://github.com/robertjbass/hostdb) on GitHub Releases. This provides multi-version support on all platforms.
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
# Create a Valkey container (downloads binaries automatically)
|
|
319
|
+
spindb create mydb --engine valkey
|
|
320
|
+
|
|
321
|
+
# Create with specific version
|
|
322
|
+
spindb create mydb --engine valkey --version 9
|
|
323
|
+
|
|
324
|
+
# Check what's available
|
|
325
|
+
spindb deps check --engine valkey
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
Valkey uses the same commands as Redis:
|
|
329
|
+
|
|
330
|
+
```bash
|
|
331
|
+
# Set a key
|
|
332
|
+
spindb run myvalkey -c "SET mykey myvalue"
|
|
333
|
+
|
|
334
|
+
# Get a key
|
|
335
|
+
spindb run myvalkey -c "GET mykey"
|
|
336
|
+
|
|
337
|
+
# Run a command file
|
|
338
|
+
spindb run myvalkey --file ./scripts/seed.valkey
|
|
339
|
+
|
|
340
|
+
# Use iredis for enhanced shell experience (Redis-protocol compatible)
|
|
341
|
+
spindb connect myvalkey --iredis
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
**Note:** Valkey uses `redis://` connection scheme for client compatibility since it's wire-compatible with Redis.
|
|
345
|
+
|
|
346
|
+
### hostdb Platform Coverage
|
|
347
|
+
|
|
348
|
+
SpinDB downloads database binaries from [hostdb](https://github.com/robertjbass/hostdb), a repository of pre-built database binaries for all major platforms. The following table shows current platform support and integration status:
|
|
349
|
+
|
|
350
|
+
| Icon | Meaning |
|
|
351
|
+
|:----:|---------|
|
|
352
|
+
| ✅ | Integrated with SpinDB |
|
|
353
|
+
| 🟦 | Pending SpinDB integration (hostdb ready) |
|
|
354
|
+
| 🟪 | Planned for hostdb (pending/in-progress) |
|
|
355
|
+
|
|
356
|
+
| Database | macOS ARM64 | macOS Intel | Linux x64 | Linux ARM64 | Windows x64 |
|
|
357
|
+
|----------|:-----------:|:-----------:|:---------:|:-----------:|:-----------:|
|
|
358
|
+
| **Integrated** |||||
|
|
359
|
+
| PostgreSQL | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
360
|
+
| MySQL | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
361
|
+
| MariaDB | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
362
|
+
| SQLite | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
363
|
+
| MongoDB* | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
364
|
+
| Redis* | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
365
|
+
| Valkey | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
366
|
+
| **Planned for hostdb** |||||
|
|
367
|
+
| CockroachDB | 🟪 | 🟪 | 🟪 | 🟪 | 🟪 |
|
|
368
|
+
| TimescaleDB | 🟪 | 🟪 | 🟪 | 🟪 | 🟪 |
|
|
369
|
+
| DuckDB | 🟪 | 🟪 | 🟪 | 🟪 | 🟪 |
|
|
370
|
+
| Meilisearch | 🟪 | 🟪 | 🟪 | 🟪 | 🟪 |
|
|
371
|
+
| OpenSearch | 🟪 | 🟪 | 🟪 | 🟪 | 🟪 |
|
|
372
|
+
| QuestDB | 🟪 | 🟪 | 🟪 | 🟪 | 🟪 |
|
|
373
|
+
| FerretDB | 🟪 | 🟪 | 🟪 | 🟪 | 🟪 |
|
|
374
|
+
| TiDB | 🟪 | 🟪 | 🟪 | 🟪 | 🟪 |
|
|
375
|
+
| ArangoDB | 🟪 | 🟪 | 🟪 | 🟪 | 🟪 |
|
|
376
|
+
| Qdrant | 🟪 | 🟪 | 🟪 | 🟪 | 🟪 |
|
|
377
|
+
| Apache Cassandra | 🟪 | 🟪 | 🟪 | 🟪 | 🟪 |
|
|
378
|
+
| ClickHouse | 🟪 | 🟪 | 🟪 | 🟪 | 🟪 |
|
|
379
|
+
| InfluxDB | 🟪 | 🟪 | 🟪 | 🟪 | 🟪 |
|
|
380
|
+
| CouchDB | 🟪 | 🟪 | 🟪 | 🟪 | 🟪 |
|
|
381
|
+
| KeyDB | 🟪 | 🟪 | 🟪 | 🟪 | 🟪 |
|
|
382
|
+
| libSQL | 🟪 | 🟪 | 🟪 | 🟪 | 🟪 |
|
|
383
|
+
| FoundationDB | 🟪 | 🟪 | 🟪 | 🟪 | 🟪 |
|
|
384
|
+
| RocksDB | 🟪 | 🟪 | 🟪 | 🟪 | 🟪 |
|
|
385
|
+
|
|
386
|
+
**Notes:**
|
|
387
|
+
- **\*** Licensing considerations for commercial use — consider Valkey (Redis) or FerretDB (MongoDB) as alternatives
|
|
388
|
+
- **PostgreSQL** uses [EDB](https://www.enterprisedb.com/) binaries on Windows instead of hostdb
|
|
389
|
+
- **Valkey** is a Redis-compatible drop-in replacement with permissive licensing
|
|
390
|
+
- **CockroachDB** is planned for both hostdb and SpinDB (see [roadmap](TODO.md))
|
|
391
|
+
- All databases under "Planned for hostdb" have permissive open-source licenses (Apache 2.0, MIT, or BSD)
|
|
392
|
+
|
|
393
|
+
For the latest platform support, see the [hostdb databases.json](https://github.com/robertjbass/hostdb/blob/main/databases.json).
|
|
394
|
+
|
|
315
395
|
---
|
|
316
396
|
|
|
317
397
|
## Commands
|
|
@@ -349,8 +429,8 @@ spindb create mydb --from "postgresql://user:pass@host:5432/production"
|
|
|
349
429
|
|
|
350
430
|
| Option | Description |
|
|
351
431
|
|--------|-------------|
|
|
352
|
-
| `--engine`, `-e` | Database engine (`postgresql`, `mariadb`, `mysql`, `sqlite`, `mongodb`, `redis`) |
|
|
353
|
-
| `--db-version` | Engine version (e.g., 17 for PostgreSQL, 11.8 for MariaDB, 8 for Redis) |
|
|
432
|
+
| `--engine`, `-e` | Database engine (`postgresql`, `mariadb`, `mysql`, `sqlite`, `mongodb`, `redis`, `valkey`) |
|
|
433
|
+
| `--db-version` | Engine version (e.g., 17 for PostgreSQL, 11.8 for MariaDB, 8 for Redis, 9 for Valkey) |
|
|
354
434
|
| `--port`, `-p` | Port number (not applicable for SQLite) |
|
|
355
435
|
| `--database`, `-d` | Primary database name (Redis uses 0-15) |
|
|
356
436
|
| `--path` | File path for SQLite databases |
|
|
@@ -468,6 +548,7 @@ Format by engine:
|
|
|
468
548
|
- SQLite: `.sql` (plain SQL) / `.sqlite` (binary copy)
|
|
469
549
|
- MongoDB: `.bson` (BSON dump) / `.archive` (compressed archive)
|
|
470
550
|
- Redis: `.redis` (text commands) / `.rdb` (RDB snapshot)
|
|
551
|
+
- Valkey: `.valkey` (text commands) / `.rdb` (RDB snapshot)
|
|
471
552
|
|
|
472
553
|
<details>
|
|
473
554
|
<summary>All options</summary>
|
|
@@ -622,6 +703,26 @@ Each engine has specific backup formats and restore behaviors:
|
|
|
622
703
|
|
|
623
704
|
</details>
|
|
624
705
|
|
|
706
|
+
<details>
|
|
707
|
+
<summary>Valkey</summary>
|
|
708
|
+
|
|
709
|
+
| Format | Extension | Tool | Notes |
|
|
710
|
+
|--------|-----------|------|-------|
|
|
711
|
+
| RDB | `.rdb` | BGSAVE | Binary snapshot, requires restart |
|
|
712
|
+
| Text | `.valkey` | Custom | Human-readable Redis-compatible commands |
|
|
713
|
+
|
|
714
|
+
**Text format detection:** Files are detected as Valkey text commands if they contain valid Redis commands (SET, HSET, DEL, etc.), regardless of file extension.
|
|
715
|
+
|
|
716
|
+
**Restore behavior:** Same as Redis (Valkey is Redis-compatible).
|
|
717
|
+
- **RDB (`.rdb`):** Requires stopping Valkey, copies file to data directory, restart loads data
|
|
718
|
+
- **Text (`.valkey`):** Pipes commands to running Valkey instance. Prompts for:
|
|
719
|
+
- **Replace all:** Runs `FLUSHDB` first (clean slate)
|
|
720
|
+
- **Merge:** Adds/updates keys, keeps existing keys not in backup
|
|
721
|
+
|
|
722
|
+
**Note:** Valkey uses numbered databases (0-15) that always exist. "Create new database" is not applicable.
|
|
723
|
+
|
|
724
|
+
</details>
|
|
725
|
+
|
|
625
726
|
### Container Management
|
|
626
727
|
|
|
627
728
|
#### `list` - List all containers
|
|
@@ -672,6 +773,10 @@ spindb logs mydb --editor # Open in $EDITOR
|
|
|
672
773
|
|
|
673
774
|
```bash
|
|
674
775
|
spindb engines # List installed engines
|
|
776
|
+
spindb engines list --json # JSON output
|
|
777
|
+
spindb engines supported # List all supported engines
|
|
778
|
+
spindb engines supported --json # Full engine config as JSON
|
|
779
|
+
spindb engines supported --all # Include pending/planned engines
|
|
675
780
|
spindb engines delete postgresql 16 # Delete a version (frees ~45MB)
|
|
676
781
|
```
|
|
677
782
|
|
|
@@ -682,13 +787,25 @@ ENGINE VERSION SOURCE SIZE
|
|
|
682
787
|
────────────────────────────────────────────────────────
|
|
683
788
|
🐘 postgresql 18.1 darwin-arm64 46.0 MB
|
|
684
789
|
🐘 postgresql 17.7 darwin-arm64 45.2 MB
|
|
685
|
-
🐬 mysql
|
|
686
|
-
🪶 sqlite 3.
|
|
790
|
+
🐬 mysql 9.0.1 darwin-arm64 150.0 MB
|
|
791
|
+
🪶 sqlite 3.51.2 darwin-arm64 5.0 MB
|
|
687
792
|
────────────────────────────────────────────────────────
|
|
688
793
|
|
|
689
794
|
PostgreSQL: 2 version(s), 90.0 MB
|
|
690
|
-
MySQL:
|
|
691
|
-
SQLite:
|
|
795
|
+
MySQL: 1 version(s), 150.0 MB
|
|
796
|
+
SQLite: 1 version(s), 5.0 MB
|
|
797
|
+
```
|
|
798
|
+
|
|
799
|
+
`spindb engines supported` output:
|
|
800
|
+
|
|
801
|
+
```
|
|
802
|
+
🐘 postgresql
|
|
803
|
+
🐬 mysql
|
|
804
|
+
🦭 mariadb
|
|
805
|
+
🪶 sqlite
|
|
806
|
+
🍃 mongodb
|
|
807
|
+
🔴 redis
|
|
808
|
+
🔷 valkey
|
|
692
809
|
```
|
|
693
810
|
|
|
694
811
|
#### `deps` - Manage client tools
|
|
@@ -773,6 +890,7 @@ SpinDB supports enhanced database shells that provide features like auto-complet
|
|
|
773
890
|
| SQLite | `sqlite3` | `litecli` | `usql` |
|
|
774
891
|
| MongoDB | `mongosh` | - | `usql` |
|
|
775
892
|
| Redis | `redis-cli` | `iredis` | - |
|
|
893
|
+
| Valkey | `valkey-cli` | `iredis` | - |
|
|
776
894
|
|
|
777
895
|
**pgcli / mycli** provide:
|
|
778
896
|
- Intelligent auto-completion (tables, columns, keywords)
|
|
@@ -879,42 +997,27 @@ This means Redis may lose up to ~60 seconds of writes on an unexpected crash. Fo
|
|
|
879
997
|
### Binary Sources
|
|
880
998
|
|
|
881
999
|
**PostgreSQL:** Server binaries are downloaded automatically:
|
|
882
|
-
- **
|
|
883
|
-
|
|
884
|
-
**MariaDB:** Server binaries are downloaded automatically from [hostdb](https://github.com/robertjbass/hostdb) on GitHub Releases for all platforms.
|
|
1000
|
+
- **macOS/Linux:** From [hostdb](https://github.com/robertjbass/hostdb) on GitHub Releases
|
|
1001
|
+
- **Windows:** From [EnterpriseDB (EDB)](https://www.enterprisedb.com/download-postgresql-binaries)
|
|
885
1002
|
|
|
886
|
-
**MySQL
|
|
1003
|
+
**MariaDB, MySQL, MongoDB, Redis, Valkey:** Server binaries are downloaded automatically from [hostdb](https://github.com/robertjbass/hostdb) on GitHub Releases for all platforms.
|
|
887
1004
|
|
|
888
|
-
### Why Precompiled Binaries
|
|
1005
|
+
### Why Precompiled Binaries?
|
|
889
1006
|
|
|
890
|
-
|
|
1007
|
+
The [hostdb](https://github.com/robertjbass/hostdb) project provides pre-compiled, portable database binaries:
|
|
891
1008
|
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
- Cross-platform (macOS Intel/ARM, Linux x64/ARM, Windows)
|
|
1009
|
+
- Cross-platform (macOS Intel/ARM, Linux x64/ARM, Windows x64)
|
|
895
1010
|
- Hosted on GitHub Releases (highly reliable CDN)
|
|
896
|
-
- ~45-
|
|
1011
|
+
- ~45-200 MB per version depending on engine
|
|
897
1012
|
- Actively maintained with new database releases
|
|
898
1013
|
|
|
899
|
-
This makes multi-version support trivial: need PostgreSQL 14 for a legacy project and 18 for a new one? Need
|
|
900
|
-
|
|
901
|
-
**No equivalent exists for MySQL, MongoDB, or Redis (yet).** None of these databases have a comparable embedded binary distribution:
|
|
902
|
-
|
|
903
|
-
- **MySQL:** Oracle distributes MySQL as large installers with system dependencies, not embeddable binaries.
|
|
904
|
-
- **MongoDB:** Server binaries are several hundred MB and aren't designed for portable distribution.
|
|
905
|
-
- **Redis:** While Redis is small (~6-12 MB), there's no official portable distribution. Community Windows ports exist, but macOS/Linux rely on system packages.
|
|
906
|
-
|
|
907
|
-
For these databases, system packages (Homebrew, apt, choco) are the most reliable option. They handle dependencies, platform quirks, and security updates. SpinDB simply orchestrates what's already installed.
|
|
908
|
-
|
|
909
|
-
**Does this limit multi-version support?** Yes, for MySQL/MongoDB/Redis you get whatever version your package manager provides. In practice, this is rarely a problem—developers seldom need multiple versions of these databases simultaneously. As hostdb expands to support more databases, SpinDB will adopt them for multi-version support.
|
|
1014
|
+
This makes multi-version support trivial: need PostgreSQL 14 for a legacy project and 18 for a new one? Need MongoDB 7.0 and 8.0? Redis 7 and 8? SpinDB downloads them all, and they run side-by-side without conflicts.
|
|
910
1015
|
|
|
911
1016
|
---
|
|
912
1017
|
|
|
913
1018
|
## Limitations
|
|
914
1019
|
|
|
915
|
-
- **Client tools required** - `mysql`, `mongosh`, and `redis-cli` must be installed separately for some operations (connecting, backups, restores) for system-installed engines
|
|
916
1020
|
- **Local only** - Databases bind to `127.0.0.1`; remote connections planned for v1.1
|
|
917
|
-
- **Single version for MySQL/MongoDB/Redis** - Unlike PostgreSQL and MariaDB, MySQL, MongoDB, and Redis use system installations, so you're limited to one version per machine (see [Why Precompiled Binaries for PostgreSQL and MariaDB?](#why-precompiled-binaries-for-postgresql-and-mariadb-but-system-installs-for-others))
|
|
918
1021
|
- **Redis remote dump not supported** - Redis doesn't support creating containers from remote connection strings. Use backup/restore for data migration.
|
|
919
1022
|
|
|
920
1023
|
---
|
|
@@ -938,6 +1041,7 @@ See [TODO.md](TODO.md) for the full roadmap.
|
|
|
938
1041
|
|
|
939
1042
|
### Future Infrastructure
|
|
940
1043
|
- **hostdb npm package**: Available database versions will be published as an npm package from [hostdb](https://github.com/robertjbass/hostdb) and imported into SpinDB, eliminating the need to manually sync version-maps.ts with releases.json
|
|
1044
|
+
- **pnpm 10 upgrade**: Currently pinned to pnpm 9.x (`packageManager` in package.json and Docker). Consider upgrading to pnpm 10.x when stable—requires updating package.json, Dockerfile, regenerating pnpm-lock.yaml, and testing for lockfile format changes
|
|
941
1045
|
|
|
942
1046
|
### Possible Future Engines
|
|
943
1047
|
|
|
@@ -947,7 +1051,6 @@ These engines are under consideration but not yet on the roadmap. Community inte
|
|
|
947
1051
|
|--------|------|-------|
|
|
948
1052
|
| **DuckDB** | Embedded analytical | File-based like SQLite, popular for data/analytics work |
|
|
949
1053
|
| **libSQL** | Embedded relational | SQLite fork by Turso with replication and edge support |
|
|
950
|
-
| **Valkey** | Key-value store | Redis fork (post-license change), growing adoption |
|
|
951
1054
|
| **Meilisearch** | Search engine | Developer-friendly search, good binary distribution |
|
|
952
1055
|
| **Elasticsearch/OpenSearch** | Search engine | Full-text search, common in web applications |
|
|
953
1056
|
| **Neo4j** | Graph database | Most popular graph database |
|
|
@@ -1011,15 +1114,7 @@ See [ENGINES.md](ENGINES.md) for detailed engine documentation (backup formats,
|
|
|
1011
1114
|
|
|
1012
1115
|
SpinDB wouldn't be possible without:
|
|
1013
1116
|
|
|
1014
|
-
- **[
|
|
1015
|
-
|
|
1016
|
-
---
|
|
1017
|
-
|
|
1018
|
-
## Related Work
|
|
1019
|
-
|
|
1020
|
-
We're actively contributing to the broader embedded database ecosystem:
|
|
1021
|
-
|
|
1022
|
-
- **[hostdb](https://github.com/robertjbass/hostdb)** - A companion project providing downloadable database binaries (Redis, MySQL/MariaDB, etc.) as GitHub releases. This will enable SpinDB to offer multi-version support for additional engines beyond PostgreSQL.
|
|
1117
|
+
- **[hostdb](https://github.com/robertjbass/hostdb)** - Pre-compiled database binaries (PostgreSQL, MySQL, MariaDB, MongoDB, Redis, Valkey, SQLite) that make Docker-free local databases possible. Hosted on GitHub Releases for reliable, fast downloads.
|
|
1023
1118
|
|
|
1024
1119
|
---
|
|
1025
1120
|
|
package/bin/cli.js
CHANGED
|
@@ -1,24 +1,60 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { fileURLToPath } from 'node:url'
|
|
3
|
+
import { fileURLToPath, pathToFileURL } from 'node:url'
|
|
4
4
|
import { dirname, join } from 'node:path'
|
|
5
5
|
import { spawn } from 'node:child_process'
|
|
6
|
+
import { existsSync } from 'node:fs'
|
|
7
|
+
import { createRequire } from 'node:module'
|
|
6
8
|
|
|
7
9
|
// Get the directory of this file
|
|
8
10
|
const __filename = fileURLToPath(import.meta.url)
|
|
9
11
|
const __dirname = dirname(__filename)
|
|
10
12
|
|
|
11
|
-
// Path to the main TypeScript entry point
|
|
12
|
-
const
|
|
13
|
+
// Path to the main TypeScript entry point and package root
|
|
14
|
+
const packageRoot = join(__dirname, '..')
|
|
15
|
+
const mainScript = join(packageRoot, 'cli', 'bin.ts')
|
|
13
16
|
|
|
14
|
-
// Use
|
|
15
|
-
|
|
17
|
+
// Use Node.js with tsx as ESM loader
|
|
18
|
+
// This approach works reliably on all platforms because:
|
|
19
|
+
// 1. We use process.execPath (always the current Node.js executable)
|
|
20
|
+
// 2. We use --import with tsx's ESM loader module
|
|
21
|
+
// 3. Arguments pass through without shell interpretation (shell: false)
|
|
22
|
+
// 4. Works on Windows without needing to spawn .cmd files
|
|
16
23
|
|
|
17
|
-
//
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
24
|
+
// Find tsx ESM loader using Node's module resolution
|
|
25
|
+
// This works with npm, pnpm, yarn regardless of hoisting/symlink structure
|
|
26
|
+
let tsxLoader = null
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
const require = createRequire(import.meta.url)
|
|
30
|
+
const tsxDir = dirname(require.resolve('tsx/package.json'))
|
|
31
|
+
const loaderPaths = [
|
|
32
|
+
join(tsxDir, 'dist', 'esm', 'index.mjs'),
|
|
33
|
+
join(tsxDir, 'dist', 'loader.mjs'),
|
|
34
|
+
]
|
|
35
|
+
tsxLoader = loaderPaths.find((p) => existsSync(p))
|
|
36
|
+
} catch {
|
|
37
|
+
// tsx not found via module resolution
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (!tsxLoader) {
|
|
41
|
+
console.error('Error: tsx loader not found.')
|
|
42
|
+
console.error('\nTry running: pnpm install')
|
|
43
|
+
process.exit(1)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Convert to file URL for --import (required on Windows)
|
|
47
|
+
const tsxLoaderUrl = pathToFileURL(tsxLoader).href
|
|
48
|
+
|
|
49
|
+
const child = spawn(
|
|
50
|
+
process.execPath,
|
|
51
|
+
['--import', tsxLoaderUrl, mainScript, ...process.argv.slice(2)],
|
|
52
|
+
{
|
|
53
|
+
stdio: 'inherit',
|
|
54
|
+
shell: false,
|
|
55
|
+
cwd: packageRoot,
|
|
56
|
+
},
|
|
57
|
+
)
|
|
22
58
|
|
|
23
59
|
// Forward exit code
|
|
24
60
|
child.on('exit', (code) => {
|
package/cli/commands/backup.ts
CHANGED
|
@@ -252,7 +252,10 @@ export const backupCommand = new Command('backup')
|
|
|
252
252
|
console.log(uiSuccess('Backup complete'))
|
|
253
253
|
console.log()
|
|
254
254
|
console.log(chalk.gray(' Saved to:'), chalk.cyan(result.path))
|
|
255
|
-
console.log(
|
|
255
|
+
console.log(
|
|
256
|
+
chalk.gray(' Size:'),
|
|
257
|
+
chalk.white(formatBytes(result.size)),
|
|
258
|
+
)
|
|
256
259
|
console.log(chalk.gray(' Format:'), chalk.white(result.format))
|
|
257
260
|
console.log()
|
|
258
261
|
}
|
package/cli/commands/backups.ts
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import { Command } from 'commander'
|
|
9
9
|
import { readdirSync, statSync } from 'fs'
|
|
10
10
|
import { join, extname } from 'path'
|
|
11
|
+
import { homedir } from 'os'
|
|
11
12
|
import chalk from 'chalk'
|
|
12
13
|
import { formatBytes } from '../ui/theme'
|
|
13
14
|
|
|
@@ -20,10 +21,11 @@ type BackupInfo = {
|
|
|
20
21
|
format: string
|
|
21
22
|
}
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
// Detect engine and format from file extension
|
|
25
|
+
function detectBackupType(filename: string): {
|
|
26
|
+
engine: string | null
|
|
27
|
+
format: string
|
|
28
|
+
} {
|
|
27
29
|
const ext = extname(filename).toLowerCase()
|
|
28
30
|
|
|
29
31
|
// Check for double extensions like .sql.gz
|
|
@@ -54,9 +56,7 @@ function detectBackupType(filename: string): { engine: string | null; format: st
|
|
|
54
56
|
}
|
|
55
57
|
}
|
|
56
58
|
|
|
57
|
-
|
|
58
|
-
* Check if a file looks like a backup file
|
|
59
|
-
*/
|
|
59
|
+
// Check if a file looks like a backup file
|
|
60
60
|
function isBackupFile(filename: string): boolean {
|
|
61
61
|
const backupExtensions = [
|
|
62
62
|
'.sql',
|
|
@@ -77,9 +77,7 @@ function isBackupFile(filename: string): boolean {
|
|
|
77
77
|
return backupExtensions.includes(ext)
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
|
|
81
|
-
* Scan directory for backup files
|
|
82
|
-
*/
|
|
80
|
+
// Scan directory for backup files
|
|
83
81
|
function findBackups(directory: string): BackupInfo[] {
|
|
84
82
|
const backups: BackupInfo[] = []
|
|
85
83
|
|
|
@@ -118,9 +116,7 @@ function findBackups(directory: string): BackupInfo[] {
|
|
|
118
116
|
return backups
|
|
119
117
|
}
|
|
120
118
|
|
|
121
|
-
|
|
122
|
-
* Format a relative time string
|
|
123
|
-
*/
|
|
119
|
+
// Format a relative time string
|
|
124
120
|
function formatRelativeTime(date: Date): string {
|
|
125
121
|
const now = new Date()
|
|
126
122
|
const diffMs = now.getTime() - date.getTime()
|
|
@@ -136,9 +132,7 @@ function formatRelativeTime(date: Date): string {
|
|
|
136
132
|
return date.toLocaleDateString()
|
|
137
133
|
}
|
|
138
134
|
|
|
139
|
-
|
|
140
|
-
* Get engine icon
|
|
141
|
-
*/
|
|
135
|
+
// Get engine icon
|
|
142
136
|
function getEngineIcon(engine: string | null): string {
|
|
143
137
|
switch (engine) {
|
|
144
138
|
case 'postgresql':
|
|
@@ -174,11 +168,7 @@ export const backupsCommand = new Command('backups')
|
|
|
174
168
|
const searchDirs = [directory || process.cwd()]
|
|
175
169
|
|
|
176
170
|
if (options.all) {
|
|
177
|
-
const homeBackups = join(
|
|
178
|
-
process.env.HOME || '',
|
|
179
|
-
'.spindb',
|
|
180
|
-
'backups',
|
|
181
|
-
)
|
|
171
|
+
const homeBackups = join(homedir(), '.spindb', 'backups')
|
|
182
172
|
searchDirs.push(homeBackups)
|
|
183
173
|
}
|
|
184
174
|
|
|
@@ -219,7 +209,9 @@ export const backupsCommand = new Command('backups')
|
|
|
219
209
|
console.log(chalk.gray(' No backup files found'))
|
|
220
210
|
console.log()
|
|
221
211
|
console.log(chalk.gray(' Backup files are identified by extensions:'))
|
|
222
|
-
console.log(
|
|
212
|
+
console.log(
|
|
213
|
+
chalk.gray(' .sql, .dump, .sqlite, .archive, .rdb, .sql.gz'),
|
|
214
|
+
)
|
|
223
215
|
console.log()
|
|
224
216
|
return
|
|
225
217
|
}
|
|
@@ -248,7 +240,9 @@ export const backupsCommand = new Command('backups')
|
|
|
248
240
|
const time = formatRelativeTime(backup.modified).padStart(10)
|
|
249
241
|
const format = chalk.gray(backup.format)
|
|
250
242
|
|
|
251
|
-
console.log(
|
|
243
|
+
console.log(
|
|
244
|
+
` ${icon} ${chalk.cyan(filename)} ${chalk.white(size)} ${chalk.gray(time)} ${format}`,
|
|
245
|
+
)
|
|
252
246
|
}
|
|
253
247
|
|
|
254
248
|
console.log()
|
package/cli/commands/config.ts
CHANGED
|
@@ -13,9 +13,7 @@ import { uiError, uiSuccess, header, uiInfo } from '../ui/theme'
|
|
|
13
13
|
import { createSpinner } from '../ui/spinner'
|
|
14
14
|
import type { BinaryTool } from '../../types'
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
* Helper to display a tool's config
|
|
18
|
-
*/
|
|
16
|
+
// Helper to display a tool's config
|
|
19
17
|
function displayToolConfig(
|
|
20
18
|
tool: BinaryTool,
|
|
21
19
|
binaryConfig: { path: string; version?: string; source: string } | undefined,
|
package/cli/commands/connect.ts
CHANGED
|
@@ -467,7 +467,14 @@ export const connectCommand = new Command('connect')
|
|
|
467
467
|
clientArgs = [config.database]
|
|
468
468
|
} else if (useIredis) {
|
|
469
469
|
clientCmd = 'iredis'
|
|
470
|
-
clientArgs = [
|
|
470
|
+
clientArgs = [
|
|
471
|
+
'-h',
|
|
472
|
+
'127.0.0.1',
|
|
473
|
+
'-p',
|
|
474
|
+
String(config.port),
|
|
475
|
+
'-n',
|
|
476
|
+
database,
|
|
477
|
+
]
|
|
471
478
|
} else if (usePgcli) {
|
|
472
479
|
clientCmd = 'pgcli'
|
|
473
480
|
clientArgs = [connectionString]
|
|
@@ -490,7 +497,14 @@ export const connectCommand = new Command('connect')
|
|
|
490
497
|
clientArgs = [config.database]
|
|
491
498
|
} else if (engineName === Engine.Redis) {
|
|
492
499
|
clientCmd = 'redis-cli'
|
|
493
|
-
clientArgs = [
|
|
500
|
+
clientArgs = [
|
|
501
|
+
'-h',
|
|
502
|
+
'127.0.0.1',
|
|
503
|
+
'-p',
|
|
504
|
+
String(config.port),
|
|
505
|
+
'-n',
|
|
506
|
+
database,
|
|
507
|
+
]
|
|
494
508
|
} else if (engineName === 'mysql') {
|
|
495
509
|
clientCmd = 'mysql'
|
|
496
510
|
clientArgs = [
|