@semics-tech/mongolite 1.1.0 → 1.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/README.md +54 -3
- package/dist/adapters/node-sqlite.d.ts +4 -0
- package/dist/adapters/node-sqlite.js +80 -35
- package/dist/adapters/node-sqlite.js.map +1 -1
- package/dist/bin/mongolite-debug.d.ts +6 -1
- package/dist/bin/mongolite-debug.js +6 -113
- package/dist/bin/mongolite-debug.js.map +1 -1
- package/dist/bin/mongolite.d.ts +13 -0
- package/dist/bin/mongolite.js +172 -0
- package/dist/bin/mongolite.js.map +1 -0
- package/dist/cjs/adapters/node-sqlite.js +84 -35
- package/dist/cjs/bin/mongolite-debug.js +6 -149
- package/dist/cjs/bin/mongolite.js +207 -0
- package/dist/cjs/cli/discover.js +156 -0
- package/dist/cjs/cli/explorer.js +929 -0
- package/dist/cjs/cli/filter-builder.js +276 -0
- package/dist/cjs/cli/format.js +161 -0
- package/dist/cjs/cli/schema.js +211 -0
- package/dist/cjs/cli/ui.js +431 -0
- package/dist/cjs/collection.js +53 -14
- package/dist/cjs/cursors/findCursor.js +108 -19
- package/dist/cjs/db.js +87 -40
- package/dist/cjs/utils/connection-registry.js +122 -0
- package/dist/cli/discover.d.ts +40 -0
- package/dist/cli/discover.js +146 -0
- package/dist/cli/discover.js.map +1 -0
- package/dist/cli/explorer.d.ts +59 -0
- package/dist/cli/explorer.js +923 -0
- package/dist/cli/explorer.js.map +1 -0
- package/dist/cli/filter-builder.d.ts +52 -0
- package/dist/cli/filter-builder.js +268 -0
- package/dist/cli/filter-builder.js.map +1 -0
- package/dist/cli/format.d.ts +29 -0
- package/dist/cli/format.js +153 -0
- package/dist/cli/format.js.map +1 -0
- package/dist/cli/schema.d.ts +58 -0
- package/dist/cli/schema.js +205 -0
- package/dist/cli/schema.js.map +1 -0
- package/dist/cli/ui.d.ts +71 -0
- package/dist/cli/ui.js +379 -0
- package/dist/cli/ui.js.map +1 -0
- package/dist/collection.d.ts +25 -0
- package/dist/collection.js +53 -14
- package/dist/collection.js.map +1 -1
- package/dist/cursors/findCursor.d.ts +70 -0
- package/dist/cursors/findCursor.js +108 -19
- package/dist/cursors/findCursor.js.map +1 -1
- package/dist/db.d.ts +23 -0
- package/dist/db.js +85 -39
- package/dist/db.js.map +1 -1
- package/dist/utils/connection-registry.d.ts +74 -0
- package/dist/utils/connection-registry.js +117 -0
- package/dist/utils/connection-registry.js.map +1 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -18,12 +18,13 @@ A MongoDB-like client backed by SQLite. Use a familiar MongoDB API with the simp
|
|
|
18
18
|
- **MongoDB-compatible API** — `insertOne`, `findOne`, `updateOne`, `deleteOne`, `find`, `aggregate`, and more
|
|
19
19
|
- **SQLite persistence** — single file, zero configuration, works offline
|
|
20
20
|
- **Automatic `_id` generation** — UUID assigned on insert if not provided
|
|
21
|
-
- **WAL mode** — Write-Ahead Logging for better concurrent read access
|
|
21
|
+
- **WAL mode** — Write-Ahead Logging for better concurrent read access, on by default
|
|
22
|
+
- **Shared connections** — opt into one pooled connection per file per process
|
|
22
23
|
- **Rich query operators** — `$eq`, `$gt`, `$in`, `$and`, `$or`, `$elemMatch`, `$regex`, and more
|
|
23
24
|
- **Update operators** — `$set`, `$inc`, `$push`, `$pull`, `$addToSet`, `$mul`, and more
|
|
24
25
|
- **Indexing** — create, list, and drop indexes including unique and compound indexes
|
|
25
26
|
- **Change streams** — real-time change tracking via `collection.watch()`
|
|
26
|
-
- **JSON safety** — validates documents before insert and
|
|
27
|
+
- **JSON safety** — validates documents before insert, and a corrupted row can't break queries for the rest of the collection
|
|
27
28
|
- **TypeScript** — fully typed with strict mode
|
|
28
29
|
|
|
29
30
|
## Installation
|
|
@@ -68,6 +69,18 @@ async function main() {
|
|
|
68
69
|
main();
|
|
69
70
|
```
|
|
70
71
|
|
|
72
|
+
## Explore a database from the terminal
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
npx mongolite
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Picks up the SQLite files around you, lists the collections it finds inside,
|
|
79
|
+
and builds queries out of plain-English choices — "age is at least 30",
|
|
80
|
+
"skills contains SQL" — using fields inferred from your actual documents. It
|
|
81
|
+
prints the MongoDB filter it built alongside the results, and raw filters and
|
|
82
|
+
raw SQL are a menu item away when you want them. See [the CLI docs](./docs/CLI.md).
|
|
83
|
+
|
|
71
84
|
## How does it compare?
|
|
72
85
|
|
|
73
86
|
| | MongoLite | lowdb | better-sqlite3 (raw) | NeDB | PouchDB | MongoDB |
|
|
@@ -88,7 +101,8 @@ MongoLite's niche: the MongoDB query API you already know, running anywhere SQLi
|
|
|
88
101
|
| [API Reference](./docs/API.md) | Full API docs: methods, query operators, update operators |
|
|
89
102
|
| [Change Streams](./docs/CHANGE_STREAMS.md) | Real-time change tracking with `collection.watch()` |
|
|
90
103
|
| [JSON Safety](./docs/JSON_SAFETY.md) | Document validation and corrupted data recovery |
|
|
91
|
-
| [
|
|
104
|
+
| [CLI](./docs/CLI.md) | `npx mongolite` — guided explorer for browsing and querying a database |
|
|
105
|
+
| [Query Debugger](./docs/DEBUGGER.md) | The older command-driven REPL (`npx mongolite --repl`) |
|
|
92
106
|
| [Benchmarks](./docs/BENCHMARKS.md) | Performance benchmarks and storage characteristics |
|
|
93
107
|
| [Cloudflare Durable Objects](./docs/CLOUDFLARE.md) | Using MongoLite inside a Cloudflare Durable Object |
|
|
94
108
|
|
|
@@ -106,6 +120,43 @@ await users.insertOne({ name: 'Alice', age: 30 });
|
|
|
106
120
|
await client.close();
|
|
107
121
|
```
|
|
108
122
|
|
|
123
|
+
### Connection options
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
const client = new MongoLite({
|
|
127
|
+
filePath: './myapp.sqlite',
|
|
128
|
+
WAL: true, // Write-Ahead Logging. Default: true
|
|
129
|
+
busyTimeout: 5000, // ms to wait for a lock before SQLITE_BUSY. Default: 5000
|
|
130
|
+
shared: true, // reuse one connection per file in this process. Default: false
|
|
131
|
+
readOnly: false,
|
|
132
|
+
verbose: false,
|
|
133
|
+
});
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
#### Sharing one connection across a process
|
|
137
|
+
|
|
138
|
+
Applications often end up with several clients pointing at the same database file
|
|
139
|
+
— a module-level client, a background job, a request handler — each opening its
|
|
140
|
+
own connection, and each then hand-rolling an instance cache to avoid the
|
|
141
|
+
resulting lock contention. `shared: true` moves that into the library:
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
// Both resolve to the same file, so they share a single SQLite connection.
|
|
145
|
+
const a = new MongoLite({ filePath: './app.sqlite', shared: true });
|
|
146
|
+
const b = new MongoLite({ filePath: './app.sqlite', shared: true });
|
|
147
|
+
|
|
148
|
+
await a.close(); // b keeps working — the handle is reference counted
|
|
149
|
+
await b.close(); // last holder out actually closes it
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Connections are only shared when the resolved path *and* every setting that
|
|
153
|
+
changes the handle's behaviour match. `:memory:` databases are never shared,
|
|
154
|
+
since two `:memory:` opens are two unrelated databases.
|
|
155
|
+
|
|
156
|
+
This dedupes connections **within a process only**. Separate processes each get
|
|
157
|
+
their own, so cross-process contention is handled by WAL mode and `busyTimeout`
|
|
158
|
+
instead.
|
|
159
|
+
|
|
109
160
|
### In-memory (tests / ephemeral)
|
|
110
161
|
|
|
111
162
|
```typescript
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { DatabaseSync } from 'node:sqlite';
|
|
2
2
|
import type { IDatabaseAdapter, MongoLiteOptions } from '../db.js';
|
|
3
|
+
/** Exposed for tests and diagnostics. */
|
|
4
|
+
export declare function sharedConnectionCount(): number;
|
|
3
5
|
/**
|
|
4
6
|
* Database adapter backed by Node.js's built-in `node:sqlite` module — no native
|
|
5
7
|
* addon, no prebuilt binary, no `node-gyp`. Requires Node.js 22.5.0+ (the module
|
|
@@ -33,6 +35,8 @@ export declare class NodeSqliteAdapter implements IDatabaseAdapter {
|
|
|
33
35
|
private readonly verbose;
|
|
34
36
|
private readonly readOnly;
|
|
35
37
|
private readonly WAL;
|
|
38
|
+
private readonly busyTimeout;
|
|
39
|
+
private readonly shareKey;
|
|
36
40
|
private openPromise;
|
|
37
41
|
/**
|
|
38
42
|
* @param dbPathOrOptions Path to the SQLite database file (use `':memory:'`
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import { DatabaseSync } from 'node:sqlite';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { ConnectionRegistry, DEFAULT_BUSY_TIMEOUT_MS, buildConnectionKey, isShareablePath, } from '../utils/connection-registry.js';
|
|
4
|
+
/** Shared `node:sqlite` handles for this process, keyed by connection identity. */
|
|
5
|
+
const sharedConnections = new ConnectionRegistry();
|
|
6
|
+
/** Exposed for tests and diagnostics. */
|
|
7
|
+
export function sharedConnectionCount() {
|
|
8
|
+
return sharedConnections.size;
|
|
9
|
+
}
|
|
2
10
|
/**
|
|
3
11
|
* Database adapter backed by Node.js's built-in `node:sqlite` module — no native
|
|
4
12
|
* addon, no prebuilt binary, no `node-gyp`. Requires Node.js 22.5.0+ (the module
|
|
@@ -35,18 +43,34 @@ export class NodeSqliteAdapter {
|
|
|
35
43
|
constructor(dbPathOrOptions) {
|
|
36
44
|
this.db = null;
|
|
37
45
|
this.openPromise = null;
|
|
46
|
+
let shared;
|
|
38
47
|
if (typeof dbPathOrOptions === 'string') {
|
|
39
48
|
this.filePath = dbPathOrOptions;
|
|
40
49
|
this.verbose = false;
|
|
41
50
|
this.readOnly = false;
|
|
42
|
-
this.WAL =
|
|
51
|
+
this.WAL = true;
|
|
52
|
+
this.busyTimeout = DEFAULT_BUSY_TIMEOUT_MS;
|
|
53
|
+
shared = false;
|
|
43
54
|
}
|
|
44
55
|
else {
|
|
45
56
|
this.filePath = dbPathOrOptions.filePath;
|
|
46
57
|
this.verbose = dbPathOrOptions.verbose || false;
|
|
47
58
|
this.readOnly = dbPathOrOptions.readOnly || false;
|
|
48
|
-
this.WAL = dbPathOrOptions.WAL
|
|
49
|
-
|
|
59
|
+
this.WAL = dbPathOrOptions.WAL ?? true;
|
|
60
|
+
this.busyTimeout = dbPathOrOptions.busyTimeout ?? DEFAULT_BUSY_TIMEOUT_MS;
|
|
61
|
+
shared = dbPathOrOptions.shared ?? false;
|
|
62
|
+
}
|
|
63
|
+
this.shareKey =
|
|
64
|
+
shared && isShareablePath(this.filePath)
|
|
65
|
+
? buildConnectionKey({
|
|
66
|
+
backend: 'node:sqlite',
|
|
67
|
+
filePath: path.resolve(this.filePath),
|
|
68
|
+
readOnly: this.readOnly,
|
|
69
|
+
WAL: this.WAL,
|
|
70
|
+
busyTimeout: this.busyTimeout,
|
|
71
|
+
verbose: this.verbose,
|
|
72
|
+
})
|
|
73
|
+
: null;
|
|
50
74
|
}
|
|
51
75
|
/**
|
|
52
76
|
* Opens the database connection if it's not already open.
|
|
@@ -60,39 +84,52 @@ export class NodeSqliteAdapter {
|
|
|
60
84
|
}
|
|
61
85
|
this.openPromise = new Promise((resolve, reject) => {
|
|
62
86
|
try {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
// not validated for catastrophic backtracking (ReDoS) could block the event loop.
|
|
70
|
-
// Avoid using untrusted/unvalidated patterns with $regex in security-sensitive contexts.
|
|
71
|
-
this.db.function('regexp', { deterministic: true }, (pattern, value) => {
|
|
72
|
-
if (typeof pattern !== 'string' || value === null || value === undefined)
|
|
73
|
-
return 0;
|
|
74
|
-
try {
|
|
75
|
-
return new RegExp(pattern).test(String(value)) ? 1 : 0;
|
|
76
|
-
}
|
|
77
|
-
catch {
|
|
78
|
-
return 0;
|
|
87
|
+
// Only runs on a genuinely new connection — when sharing, an existing
|
|
88
|
+
// handle already has its pragmas and UDFs applied.
|
|
89
|
+
const openConnection = () => {
|
|
90
|
+
const db = new DatabaseSync(this.filePath, { readOnly: this.readOnly });
|
|
91
|
+
if (this.WAL && !this.readOnly) {
|
|
92
|
+
db.exec('PRAGMA journal_mode = WAL');
|
|
79
93
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
return 0;
|
|
85
|
-
try {
|
|
86
|
-
const f = typeof flags === 'string' ? flags : '';
|
|
87
|
-
return new RegExp(pattern, f).test(String(value)) ? 1 : 0;
|
|
94
|
+
// Wait rather than immediately throwing SQLITE_BUSY when another
|
|
95
|
+
// connection (often another process) holds a lock.
|
|
96
|
+
if (this.busyTimeout > 0) {
|
|
97
|
+
db.exec(`PRAGMA busy_timeout = ${this.busyTimeout}`);
|
|
88
98
|
}
|
|
89
|
-
|
|
90
|
-
|
|
99
|
+
// Register regexp UDF for $regex operator support.
|
|
100
|
+
// WARNING: Patterns are compiled via JavaScript RegExp. User-supplied patterns that are
|
|
101
|
+
// not validated for catastrophic backtracking (ReDoS) could block the event loop.
|
|
102
|
+
// Avoid using untrusted/unvalidated patterns with $regex in security-sensitive contexts.
|
|
103
|
+
db.function('regexp', { deterministic: true }, (pattern, value) => {
|
|
104
|
+
if (typeof pattern !== 'string' || value === null || value === undefined)
|
|
105
|
+
return 0;
|
|
106
|
+
try {
|
|
107
|
+
return new RegExp(pattern).test(String(value)) ? 1 : 0;
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
return 0;
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
// Register regexp_flags UDF for $regex with $options support
|
|
114
|
+
db.function('regexp_flags', { deterministic: true }, (pattern, flags, value) => {
|
|
115
|
+
if (typeof pattern !== 'string' || value === null || value === undefined)
|
|
116
|
+
return 0;
|
|
117
|
+
try {
|
|
118
|
+
const f = typeof flags === 'string' ? flags : '';
|
|
119
|
+
return new RegExp(pattern, f).test(String(value)) ? 1 : 0;
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
return 0;
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
if (this.verbose) {
|
|
126
|
+
console.log(`SQLite database opened (node:sqlite): ${this.filePath}`);
|
|
91
127
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
128
|
+
return db;
|
|
129
|
+
};
|
|
130
|
+
this.db = this.shareKey
|
|
131
|
+
? sharedConnections.acquire(this.shareKey, openConnection)
|
|
132
|
+
: openConnection();
|
|
96
133
|
resolve();
|
|
97
134
|
}
|
|
98
135
|
catch (err) {
|
|
@@ -166,9 +203,17 @@ export class NodeSqliteAdapter {
|
|
|
166
203
|
}
|
|
167
204
|
if (this.db) {
|
|
168
205
|
try {
|
|
169
|
-
|
|
206
|
+
// When shared, only the last holder actually closes the handle.
|
|
207
|
+
const isLastHolder = this.shareKey
|
|
208
|
+
? sharedConnections.release(this.shareKey, this.db)
|
|
209
|
+
: true;
|
|
210
|
+
if (isLastHolder) {
|
|
211
|
+
this.db.close();
|
|
212
|
+
}
|
|
170
213
|
if (this.verbose) {
|
|
171
|
-
console.log(
|
|
214
|
+
console.log(isLastHolder
|
|
215
|
+
? `SQLite database closed (node:sqlite): ${this.filePath}`
|
|
216
|
+
: `SQLite database released (still in use): ${this.filePath}`);
|
|
172
217
|
}
|
|
173
218
|
}
|
|
174
219
|
catch (err) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-sqlite.js","sourceRoot":"","sources":["../../src/adapters/node-sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"node-sqlite.js","sourceRoot":"","sources":["../../src/adapters/node-sqlite.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,2 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* `mongolite-debug` is kept as an alias of `mongolite` so existing scripts and
|
|
4
|
+
* muscle memory keep working. It runs the same guided explorer; pass `--repl`
|
|
5
|
+
* for the original command-driven debugger (`.use`, `.find`, `.sql`, …).
|
|
6
|
+
*/
|
|
7
|
+
import './mongolite.js';
|
|
@@ -1,115 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
for (let i = 0; i < args.length; i++) {
|
|
9
|
-
const arg = args[i];
|
|
10
|
-
if (arg === '--verbose' || arg === '-v') {
|
|
11
|
-
options.verbose = true;
|
|
12
|
-
}
|
|
13
|
-
else if (arg === '--collection' || arg === '-c') {
|
|
14
|
-
options.collection = args[++i];
|
|
15
|
-
}
|
|
16
|
-
else if (arg === '--database' || arg === '-d') {
|
|
17
|
-
options.database = args[++i];
|
|
18
|
-
}
|
|
19
|
-
else if (arg === '--help' || arg === '-h') {
|
|
20
|
-
options.help = true;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
return options;
|
|
24
|
-
}
|
|
25
|
-
function showHelp() {
|
|
26
|
-
console.log('MongoLite Query Debugger');
|
|
27
|
-
console.log('');
|
|
28
|
-
console.log('Interactive debugging tool for MongoLite queries.');
|
|
29
|
-
console.log('');
|
|
30
|
-
console.log('Usage: npx mongolite-debug [options]');
|
|
31
|
-
console.log('');
|
|
32
|
-
console.log('Options:');
|
|
33
|
-
console.log(' -d, --database <path> Database file path (default: ./mongolite.db)');
|
|
34
|
-
console.log(' -c, --collection <name> Initial collection to use');
|
|
35
|
-
console.log(' -v, --verbose Enable verbose output');
|
|
36
|
-
console.log(' -h, --help Show this help');
|
|
37
|
-
console.log('');
|
|
38
|
-
console.log('Interactive Commands:');
|
|
39
|
-
console.log(' .help Show available commands');
|
|
40
|
-
console.log(' .collections List all collections');
|
|
41
|
-
console.log(' .use <collection> Select a collection to work with');
|
|
42
|
-
console.log(' .find <filter> Convert find filter to SQL and execute');
|
|
43
|
-
console.log(' .sql <query> Execute raw SQL query');
|
|
44
|
-
console.log(' .last Show last generated SQL');
|
|
45
|
-
console.log(' .sample [count] Show sample documents from current collection');
|
|
46
|
-
console.log(' .exit Exit the debugger');
|
|
47
|
-
console.log('');
|
|
48
|
-
console.log('Examples:');
|
|
49
|
-
console.log(' npx mongolite-debug -d ./myapp.db -c users');
|
|
50
|
-
console.log(' npx mongolite-debug --verbose');
|
|
51
|
-
console.log('');
|
|
52
|
-
console.log(' # Inside the debugger:');
|
|
53
|
-
console.log(' .use users');
|
|
54
|
-
console.log(' .find {"age": {"$gt": 25}}');
|
|
55
|
-
console.log(' .sql SELECT * FROM users WHERE json_extract(data, "$.age") > 25');
|
|
56
|
-
console.log('');
|
|
57
|
-
}
|
|
58
|
-
async function main() {
|
|
59
|
-
const options = parseArgs();
|
|
60
|
-
if (options.help) {
|
|
61
|
-
showHelp();
|
|
62
|
-
process.exit(0);
|
|
63
|
-
}
|
|
64
|
-
// Set default database path if not provided
|
|
65
|
-
if (!options.database) {
|
|
66
|
-
// Look for common database files in the current directory
|
|
67
|
-
const cwd = process.cwd();
|
|
68
|
-
const commonNames = [
|
|
69
|
-
'mongolite.db',
|
|
70
|
-
'mongolite.sqlite',
|
|
71
|
-
'database.db',
|
|
72
|
-
'database.sqlite',
|
|
73
|
-
'app.db',
|
|
74
|
-
'app.sqlite',
|
|
75
|
-
];
|
|
76
|
-
// Check if any common database files exist
|
|
77
|
-
const { existsSync } = await import('fs');
|
|
78
|
-
let foundDb = false;
|
|
79
|
-
for (const name of commonNames) {
|
|
80
|
-
const dbPath = path.join(cwd, name);
|
|
81
|
-
if (existsSync(dbPath)) {
|
|
82
|
-
options.database = dbPath;
|
|
83
|
-
foundDb = true;
|
|
84
|
-
break;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
if (!foundDb) {
|
|
88
|
-
options.database = path.join(cwd, 'mongolite.db');
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
console.log('🔍 MongoLite Query Debugger (npx version)');
|
|
92
|
-
console.log(`📁 Database: ${options.database}`);
|
|
93
|
-
if (options.collection) {
|
|
94
|
-
console.log(`📋 Initial collection: ${options.collection}`);
|
|
95
|
-
}
|
|
96
|
-
console.log('');
|
|
97
|
-
try {
|
|
98
|
-
const queryDebugger = new QueryDebugger(options);
|
|
99
|
-
await queryDebugger.start();
|
|
100
|
-
}
|
|
101
|
-
catch (error) {
|
|
102
|
-
console.error('Fatal error:', error instanceof Error ? error.message : error);
|
|
103
|
-
if (error instanceof Error && error.message.includes('SQLITE_CANTOPEN')) {
|
|
104
|
-
console.error('');
|
|
105
|
-
console.error('💡 Tip: Make sure the database file exists or specify a different path with -d');
|
|
106
|
-
console.error(' Example: npx mongolite-debug -d ./path/to/your/database.db');
|
|
107
|
-
}
|
|
108
|
-
process.exit(1);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
main().catch((error) => {
|
|
112
|
-
console.error('Unexpected error:', error);
|
|
113
|
-
process.exit(1);
|
|
114
|
-
});
|
|
2
|
+
/**
|
|
3
|
+
* `mongolite-debug` is kept as an alias of `mongolite` so existing scripts and
|
|
4
|
+
* muscle memory keep working. It runs the same guided explorer; pass `--repl`
|
|
5
|
+
* for the original command-driven debugger (`.use`, `.find`, `.sql`, …).
|
|
6
|
+
*/
|
|
7
|
+
import './mongolite.js';
|
|
115
8
|
//# sourceMappingURL=mongolite-debug.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mongolite-debug.js","sourceRoot":"","sources":["../../src/bin/mongolite-debug.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"mongolite-debug.js","sourceRoot":"","sources":["../../src/bin/mongolite-debug.ts"],"names":[],"mappings":";AACA;;;;GAIG;AACH,OAAO,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
interface CliOptions {
|
|
3
|
+
database?: string;
|
|
4
|
+
collection?: string;
|
|
5
|
+
verbose: boolean;
|
|
6
|
+
help: boolean;
|
|
7
|
+
version: boolean;
|
|
8
|
+
repl: boolean;
|
|
9
|
+
sampleSize?: number;
|
|
10
|
+
pageSize?: number;
|
|
11
|
+
}
|
|
12
|
+
export declare function parseArgs(argv: string[]): CliOptions;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* `mongolite` — the guided explorer for MongoLite databases.
|
|
4
|
+
*
|
|
5
|
+
* Running it with no arguments is the intended path: it finds your database
|
|
6
|
+
* files, lists the collections it finds inside, and walks you through a query.
|
|
7
|
+
* Flags are shortcuts for people who already know where they are going, and
|
|
8
|
+
* `--repl` drops into the older command-driven debugger.
|
|
9
|
+
*/
|
|
10
|
+
import { Explorer } from '../cli/explorer.js';
|
|
11
|
+
import { QueryDebugger } from '../debugger/query-debugger.js';
|
|
12
|
+
import { closePrompts, style } from '../cli/ui.js';
|
|
13
|
+
export function parseArgs(argv) {
|
|
14
|
+
const options = { verbose: false, help: false, version: false, repl: false };
|
|
15
|
+
const positional = [];
|
|
16
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
17
|
+
const arg = argv[index];
|
|
18
|
+
switch (arg) {
|
|
19
|
+
case '--database':
|
|
20
|
+
case '-d':
|
|
21
|
+
options.database = argv[++index];
|
|
22
|
+
break;
|
|
23
|
+
case '--collection':
|
|
24
|
+
case '-c':
|
|
25
|
+
options.collection = argv[++index];
|
|
26
|
+
break;
|
|
27
|
+
case '--verbose':
|
|
28
|
+
case '-v':
|
|
29
|
+
options.verbose = true;
|
|
30
|
+
break;
|
|
31
|
+
case '--repl':
|
|
32
|
+
case '--expert':
|
|
33
|
+
options.repl = true;
|
|
34
|
+
break;
|
|
35
|
+
case '--sample':
|
|
36
|
+
options.sampleSize = Number(argv[++index]);
|
|
37
|
+
break;
|
|
38
|
+
case '--page-size':
|
|
39
|
+
options.pageSize = Number(argv[++index]);
|
|
40
|
+
break;
|
|
41
|
+
case '--help':
|
|
42
|
+
case '-h':
|
|
43
|
+
options.help = true;
|
|
44
|
+
break;
|
|
45
|
+
case '--version':
|
|
46
|
+
case '-V':
|
|
47
|
+
options.version = true;
|
|
48
|
+
break;
|
|
49
|
+
default:
|
|
50
|
+
if (arg.startsWith('-')) {
|
|
51
|
+
throw new Error(`Unknown option: ${arg}`);
|
|
52
|
+
}
|
|
53
|
+
positional.push(arg);
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// `mongolite ./app.db users` is the shape people try first, so support it.
|
|
58
|
+
if (!options.database && positional[0])
|
|
59
|
+
options.database = positional[0];
|
|
60
|
+
if (!options.collection && positional[1])
|
|
61
|
+
options.collection = positional[1];
|
|
62
|
+
return options;
|
|
63
|
+
}
|
|
64
|
+
function showHelp() {
|
|
65
|
+
const lines = [
|
|
66
|
+
`${style.bold('mongolite')} — explore a MongoLite (SQLite-backed) database`,
|
|
67
|
+
'',
|
|
68
|
+
style.bold('Usage'),
|
|
69
|
+
' npx mongolite Start the guided explorer',
|
|
70
|
+
' npx mongolite ./app.db Open a specific database',
|
|
71
|
+
' npx mongolite ./app.db users Open a specific collection',
|
|
72
|
+
'',
|
|
73
|
+
style.bold('Options'),
|
|
74
|
+
' -d, --database <path> Database file to open (otherwise you get a list to pick from)',
|
|
75
|
+
' -c, --collection <name> Collection to start in',
|
|
76
|
+
' --sample <n> Documents to sample when inferring fields (default 200)',
|
|
77
|
+
' --page-size <n> Results shown per page (default 20)',
|
|
78
|
+
' --repl Use the older command-driven debugger instead',
|
|
79
|
+
' -v, --verbose Log the SQL being built',
|
|
80
|
+
' -h, --help Show this help',
|
|
81
|
+
' -V, --version Show the version',
|
|
82
|
+
'',
|
|
83
|
+
style.bold('In the explorer'),
|
|
84
|
+
' ↑/↓ move · type to filter the list · enter to choose · esc to go back · Ctrl+C to quit',
|
|
85
|
+
'',
|
|
86
|
+
'No MongoDB knowledge is needed: pick a field, pick a condition in plain English,',
|
|
87
|
+
'and the filter it builds is printed so you can learn the syntax as you go.',
|
|
88
|
+
'If you already know it, "Write a MongoDB filter yourself" and "Run raw SQL" are',
|
|
89
|
+
'under Advanced.',
|
|
90
|
+
'',
|
|
91
|
+
];
|
|
92
|
+
process.stdout.write(`${lines.join('\n')}\n`);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Find the package version by walking up from the running script.
|
|
96
|
+
* Deliberately avoids `import.meta` and `__dirname` so the same source compiles
|
|
97
|
+
* for both the ESM and CommonJS builds.
|
|
98
|
+
*/
|
|
99
|
+
async function showVersion() {
|
|
100
|
+
const { readFileSync, existsSync } = await import('node:fs');
|
|
101
|
+
const { dirname, join, parse } = await import('node:path');
|
|
102
|
+
let dir = dirname(process.argv[1] ?? process.cwd());
|
|
103
|
+
const { root } = parse(dir);
|
|
104
|
+
while (dir && dir !== root) {
|
|
105
|
+
const candidate = join(dir, 'package.json');
|
|
106
|
+
if (existsSync(candidate)) {
|
|
107
|
+
try {
|
|
108
|
+
const pkg = JSON.parse(readFileSync(candidate, 'utf8'));
|
|
109
|
+
if (pkg.version) {
|
|
110
|
+
process.stdout.write(`${pkg.version}\n`);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
// Unreadable package.json - keep walking up.
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
dir = dirname(dir);
|
|
119
|
+
}
|
|
120
|
+
process.stdout.write('unknown\n');
|
|
121
|
+
}
|
|
122
|
+
async function main() {
|
|
123
|
+
let options;
|
|
124
|
+
try {
|
|
125
|
+
options = parseArgs(process.argv.slice(2));
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
|
|
129
|
+
process.stderr.write('Run with --help to see the available options.\n');
|
|
130
|
+
process.exit(1);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
if (options.help) {
|
|
134
|
+
showHelp();
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
if (options.version) {
|
|
138
|
+
await showVersion();
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
if (options.repl) {
|
|
142
|
+
const queryDebugger = new QueryDebugger({
|
|
143
|
+
database: options.database,
|
|
144
|
+
collection: options.collection,
|
|
145
|
+
verbose: options.verbose,
|
|
146
|
+
});
|
|
147
|
+
await queryDebugger.start();
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
const explorer = new Explorer({
|
|
151
|
+
database: options.database,
|
|
152
|
+
collection: options.collection,
|
|
153
|
+
verbose: options.verbose,
|
|
154
|
+
sampleSize: Number.isFinite(options.sampleSize) ? options.sampleSize : undefined,
|
|
155
|
+
pageSize: Number.isFinite(options.pageSize) ? options.pageSize : undefined,
|
|
156
|
+
});
|
|
157
|
+
await explorer.run();
|
|
158
|
+
}
|
|
159
|
+
main()
|
|
160
|
+
.then(() => {
|
|
161
|
+
closePrompts();
|
|
162
|
+
process.exit(0);
|
|
163
|
+
})
|
|
164
|
+
.catch((error) => {
|
|
165
|
+
const text = error instanceof Error ? error.message : String(error);
|
|
166
|
+
process.stderr.write(`\n✖ ${text}\n`);
|
|
167
|
+
if (text.includes('SQLITE_CANTOPEN') || text.includes('unable to open')) {
|
|
168
|
+
process.stderr.write(' The file may not exist, or may not be readable.\n');
|
|
169
|
+
}
|
|
170
|
+
process.exit(1);
|
|
171
|
+
});
|
|
172
|
+
//# sourceMappingURL=mongolite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mongolite.js","sourceRoot":"","sources":["../../src/bin/mongolite.ts"],"names":[],"mappings":";AACA;;;;;;;GAOG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAanD,MAAM,UAAU,SAAS,CAAC,IAAc;IACtC,MAAM,OAAO,GAAe,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IACzF,MAAM,UAAU,GAAa,EAAE,CAAC;IAEhC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACpD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QACxB,QAAQ,GAAG,EAAE,CAAC;YACZ,KAAK,YAAY,CAAC;YAClB,KAAK,IAAI;gBACP,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;gBACjC,MAAM;YACR,KAAK,cAAc,CAAC;YACpB,KAAK,IAAI;gBACP,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;gBACnC,MAAM;YACR,KAAK,WAAW,CAAC;YACjB,KAAK,IAAI;gBACP,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;gBACvB,MAAM;YACR,KAAK,QAAQ,CAAC;YACd,KAAK,UAAU;gBACb,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;gBACpB,MAAM;YACR,KAAK,UAAU;gBACb,OAAO,CAAC,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;gBAC3C,MAAM;YACR,KAAK,aAAa;gBAChB,OAAO,CAAC,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;gBACzC,MAAM;YACR,KAAK,QAAQ,CAAC;YACd,KAAK,IAAI;gBACP,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;gBACpB,MAAM;YACR,KAAK,WAAW,CAAC;YACjB,KAAK,IAAI;gBACP,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;gBACvB,MAAM;YACR;gBACE,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;oBACxB,MAAM,IAAI,KAAK,CAAC,mBAAmB,GAAG,EAAE,CAAC,CAAC;gBAC5C,CAAC;gBACD,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACrB,MAAM;QACV,CAAC;IACH,CAAC;IAED,2EAA2E;IAC3E,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,UAAU,CAAC,CAAC,CAAC;QAAE,OAAO,CAAC,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;IACzE,IAAI,CAAC,OAAO,CAAC,UAAU,IAAI,UAAU,CAAC,CAAC,CAAC;QAAE,OAAO,CAAC,UAAU,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;IAE7E,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,QAAQ;IACf,MAAM,KAAK,GAAG;QACZ,GAAG,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,iDAAiD;QAC3E,EAAE;QACF,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC;QACnB,gEAAgE;QAChE,+DAA+D;QAC/D,iEAAiE;QACjE,EAAE;QACF,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;QACrB,yFAAyF;QACzF,kDAAkD;QAClD,mFAAmF;QACnF,+DAA+D;QAC/D,yEAAyE;QACzE,mDAAmD;QACnD,0CAA0C;QAC1C,4CAA4C;QAC5C,EAAE;QACF,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC;QAC7B,0FAA0F;QAC1F,EAAE;QACF,kFAAkF;QAClF,4EAA4E;QAC5E,iFAAiF;QACjF,iBAAiB;QACjB,EAAE;KACH,CAAC;IACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAChD,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,WAAW;IACxB,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;IAC7D,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;IAE3D,IAAI,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACpD,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;IAE5B,OAAO,GAAG,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;QAC5C,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAAyB,CAAC;gBAChF,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;oBAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;oBACzC,OAAO;gBACT,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,6CAA6C;YAC/C,CAAC;QACH,CAAC;QACD,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;AACpC,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,IAAI,OAAmB,CAAC;IACxB,IAAI,CAAC;QACH,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACpF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACxE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChB,OAAO;IACT,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,QAAQ,EAAE,CAAC;QACX,OAAO;IACT,CAAC;IACD,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,WAAW,EAAE,CAAC;QACpB,OAAO;IACT,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,MAAM,aAAa,GAAG,IAAI,aAAa,CAAC;YACtC,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,OAAO,EAAE,OAAO,CAAC,OAAO;SACzB,CAAC,CAAC;QACH,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC;QAC5B,OAAO;IACT,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC;QAC5B,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS;QAChF,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;KAC3E,CAAC,CAAC;IAEH,MAAM,QAAQ,CAAC,GAAG,EAAE,CAAC;AACvB,CAAC;AAED,IAAI,EAAE;KACH,IAAI,CAAC,GAAG,EAAE;IACT,YAAY,EAAE,CAAC;IACf,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC;KACD,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IACxB,MAAM,IAAI,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACpE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC;IACtC,IAAI,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACxE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC;IAC9E,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|