@toonstore/torm 0.2.0 β†’ 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/README.md CHANGED
@@ -1,17 +1,32 @@
1
1
  # @toonstore/torm
2
2
 
3
- > ToonStore ORM Client for Node.js & TypeScript
3
+ > ToonStoreDB ORM Client for Node.js & TypeScript
4
4
 
5
- A Mongoose-style ORM client for ToonStore, providing type-safe models, validation, and query building.
5
+ A Mongoose-style ORM client for ToonStoreDB, providing type-safe models, validation, and query building.
6
+
7
+ > **What is ToonStoreDB?** ToonStoreDB is a blazingly fast embedded database with a built-in caching layer. This SDK lets you work with ToonStoreDB using a familiar Mongoose-like API.
8
+
9
+ ## 🎯 Quick Summary
10
+
11
+ **What is this?** A TypeScript/JavaScript ORM library (like Mongoose for MongoDB or Drizzle for PostgreSQL) that lets you easily work with ToonStoreDB.
12
+
13
+ **What do I need?**
14
+ - βœ… ToonStoreDB server running (the database)
15
+ - βœ… This npm package (`@toonstore/torm`)
16
+ - βœ… Node.js/TypeScript project
17
+
18
+ **What is TORM Studio?** An optional visual management tool (like phpMyAdmin or MongoDB Compass) for managing your ToonStoreDB data - NOT required for the SDK to work.
6
19
 
7
20
  ## ✨ Features
8
21
 
9
- - βœ… **Type-Safe** - Full TypeScript support
10
- - βœ… **Validation** - Built-in validators (email, URL, min/max, patterns)
11
- - βœ… **Query Builder** - Fluent API for filtering and sorting
12
- - βœ… **Schema Definition** - Define your data models
13
- - βœ… **Async/Await** - Promise-based API
14
- - βœ… **Direct Redis Connection** - No server required, connects directly to Redis/ToonStore
22
+ - βœ… **Type-Safe** - Full TypeScript support with generics
23
+ - βœ… **Direct Database Connection** - Connects directly to ToonStoreDB
24
+ - βœ… **Mongoose-Like API** - Familiar API for easy adoption
25
+ - βœ… **Schema Validation** - Built-in validators (email, URL, min/max, patterns, custom)
26
+ - βœ… **Query Builder** - Fluent API for filtering, sorting, and pagination
27
+ - βœ… **Async/Await** - Modern promise-based API
28
+ - βœ… **Auto-Generated IDs** - Automatic document ID generation with timestamps
29
+ - βœ… **Zero Configuration** - Works out of the box with sensible defaults
15
30
 
16
31
  ## πŸ“¦ Installation
17
32
 
@@ -19,39 +34,52 @@ A Mongoose-style ORM client for ToonStore, providing type-safe models, validatio
19
34
  npm install @toonstore/torm
20
35
  # or
21
36
  yarn add @toonstore/torm
37
+ # or
38
+ pnpm add @toonstore/torm
22
39
  ```
23
40
 
24
41
  ## πŸš€ Quick Start
25
42
 
26
43
  ### Prerequisites
27
44
 
28
- Make sure Redis is running:
45
+ **ToonStoreDB must be running:**
46
+
29
47
  ```bash
30
- redis-server
48
+ # Start ToonStoreDB
49
+ ./toonstoredb
31
50
  # Default: localhost:6379
51
+
52
+ # Or using Docker
53
+ docker run -d -p 6379:6379 toonstoredb/toonstoredb:latest
54
+
55
+ # Or install from releases
56
+ # Download from: https://github.com/toonstore/toonstoredb/releases
32
57
  ```
33
58
 
59
+ > **Note:** ToonStoreDB is a high-performance database with Redis-compatible protocol. The SDK connects directly to your ToonStoreDB instance. No additional servers or middleware needed.
60
+
34
61
  ### Basic Usage
35
62
 
36
63
  ```typescript
37
64
  import { TormClient } from '@toonstore/torm';
38
65
 
39
- // 1. Create client (connects directly to Redis)
66
+ // 1. Connect to ToonStoreDB
40
67
  const torm = new TormClient({
41
68
  host: 'localhost',
42
69
  port: 6379,
43
70
  // Or use connection URL:
44
- // url: 'redis://localhost:6379'
71
+ // url: 'toonstoredb://localhost:6379'
45
72
  });
46
73
 
47
- // 2. Define model with schema
74
+ // 2. Define your model interface
48
75
  interface User {
49
- id: string;
50
76
  name: string;
51
77
  email: string;
52
78
  age: number;
79
+ website?: string;
53
80
  }
54
81
 
82
+ // 3. Create model with validation schema
55
83
  const User = torm.model<User>('User', {
56
84
  name: {
57
85
  type: 'string',
@@ -70,35 +98,118 @@ const User = torm.model<User>('User', {
70
98
  min: 13,
71
99
  max: 120,
72
100
  },
101
+ website: {
102
+ type: 'string',
103
+ url: true,
104
+ },
73
105
  });
74
106
 
75
- // 3. Create document
107
+ // 4. Create document (ID auto-generated)
76
108
  const user = await User.create({
77
- id: 'user:1',
78
109
  name: 'Alice',
79
110
  email: 'alice@example.com',
80
111
  age: 30,
112
+ website: 'https://alice.dev',
81
113
  });
114
+ console.log(user._id); // Auto-generated: "1736076000000-abc123xyz"
82
115
 
83
- // 4. Find documents
116
+ // 5. Find documents
84
117
  const allUsers = await User.find();
85
- const specificUser = await User.findById('user:1');
118
+ const specificUser = await User.findById(user._id);
119
+ const foundUser = await User.findOne({ email: 'alice@example.com' });
86
120
 
87
- // 5. Query with filters
121
+ // 6. Query with filters
88
122
  const adults = await User.query()
89
- .filter('age', 'gte', 18)
123
+ .where('age', 'gte', 18)
90
124
  .sort('name', 'asc')
91
125
  .limit(10)
92
126
  .exec();
93
127
 
94
- // 6. Update document
95
- await User.update('user:1', { age: 31 });
128
+ // 7. Update document
129
+ const updated = await User.update(user._id, { age: 31 });
130
+
131
+ // 8. Delete document
132
+ await User.delete(user._id);
96
133
 
97
- // 7. Delete document
98
- await User.delete('user:1');
134
+ // 9. Delete many documents
135
+ await User.deleteMany({ age: { $lt: 18 } });
99
136
 
100
- // 8. Count documents
137
+ // 10. Count documents
101
138
  const count = await User.count();
139
+
140
+ // 11. Disconnect when done
141
+ await torm.disconnect();
142
+ ```
143
+
144
+ ## πŸ› οΈ CLI Commands
145
+
146
+ TORM includes a powerful CLI for database management and development workflows:
147
+
148
+ ### TORM Studio
149
+
150
+ Launch the visual database manager (bundled with the SDK):
151
+
152
+ ```bash
153
+ # Start TORM Studio
154
+ npx torm studio
155
+ ```
156
+
157
+ **First Run:** If no `torm.config.ts` exists, it will be auto-generated. Edit it with your database credentials, then run `npx torm studio` again.
158
+
159
+ **Access:** http://localhost:4983
160
+
161
+ **Configuration:**
162
+ Create or edit `torm.config.ts` in your project root:
163
+ ```typescript
164
+ export default {
165
+ dbCredentials: {
166
+ host: 'localhost', // or cloud host
167
+ port: 6379,
168
+ // For cloud/auth:
169
+ // password: 'your-password',
170
+ // url: 'redis://user:pass@host:port',
171
+ },
172
+ studio: {
173
+ port: 4983, // default
174
+ },
175
+ };
176
+ ```
177
+
178
+ **Features:**
179
+ - πŸ“Š Visual database browser - browse collections and documents
180
+ - ✏️ Create, read, update, delete records with UI
181
+ - πŸ” Search and filter data
182
+ - πŸ“ˆ Real-time database statistics
183
+ - 🎨 Modern dark-themed interface
184
+ - βœ… No separate installation - fully bundled with npm package!
185
+ - 🌐 Works with local or cloud-hosted ToonStoreDB
186
+
187
+ **Custom Port:**
188
+ ```bash
189
+ npx torm studio --port 8080
190
+ ```
191
+
192
+ ### Migrations (Coming Soon)
193
+
194
+ ```bash
195
+ # Generate migration from schema changes
196
+ npx torm generate
197
+
198
+ # Run pending migrations
199
+ npx torm migrate
200
+
201
+ # Check migration status
202
+ npx torm migrate:status
203
+ ```
204
+
205
+ ### Type Generation (Coming Soon)
206
+
207
+ ```bash
208
+ # Generate TypeScript types from your schema
209
+ npx torm generate
210
+
211
+ # Watch mode for development
212
+ npx torm generate --watch
102
213
  ```
103
214
 
104
215
  ## πŸ“– API Documentation
@@ -112,35 +223,45 @@ const torm = new TormClient(options?: TormClientOptions);
112
223
  ```
113
224
 
114
225
  **Options:**
115
- - `host` (string) - Redis host (default: `localhost`)
116
- - `port` (number) - Redis port (default: `6379`)
117
- - `url` (string) - Redis connection URL (e.g., `redis://localhost:6379`)
118
- - All standard `ioredis` options are supported
226
+ - `host` (string) - ToonStoreDB host (default: `localhost`)
227
+ - `port` (number) - ToonStoreDB port (default: `6379`)
228
+ - `url` (string) - ToonStoreDB connection URL (e.g., `toonstoredb://localhost:6379`)
229
+ - All standard connection options are supported
119
230
 
120
231
  #### Methods
121
232
 
122
233
  - `model<T>(name, schema?, options?)` - Create a model
123
- - `health()` - Check Redis connection health
124
- - `disconnect()` - Close Redis connection
125
- - `isConnected()` - Check if connected to Redis
234
+ - `health()` - Check database connection health
235
+ - `disconnect()` - Close database connection
236
+ - `isConnected()` - Check if connected to database
237
+ - `getClient()` - Get underlying database client instance
126
238
 
127
239
  ### Model
128
240
 
241
+ All documents automatically include:
242
+ - `_id` - Auto-generated unique ID
243
+ - `_createdAt` - ISO timestamp of creation
244
+ - `_updatedAt` - ISO timestamp of last update
245
+
129
246
  #### CRUD Operations
130
247
 
131
248
  ```typescript
132
- // Create
249
+ // Create (ID auto-generated)
133
250
  const doc = await Model.create(data);
251
+ // Returns: { ...data, _id, _createdAt, _updatedAt }
134
252
 
135
253
  // Read
136
254
  const all = await Model.find();
137
255
  const one = await Model.findById(id);
256
+ const match = await Model.findOne({ email: 'user@example.com' });
138
257
 
139
258
  // Update
140
259
  const updated = await Model.update(id, data);
141
260
 
142
261
  // Delete
143
262
  const deleted = await Model.delete(id);
263
+ await Model.deleteMany(); // Delete all
264
+ await Model.deleteMany({ status: 'inactive' }); // Delete matching
144
265
 
145
266
  // Count
146
267
  const count = await Model.count();
@@ -150,16 +271,16 @@ const count = await Model.count();
150
271
 
151
272
  ```typescript
152
273
  const results = await Model.query()
153
- .filter(field, operator, value) // Add filter
154
- .where(field, value) // Shorthand for .filter(field, 'eq', value)
155
- .sort(field, order) // Sort results
274
+ .where(field, operator, value) // Add filter
275
+ .equals(field, value) // Shorthand for .where(field, 'eq', value)
276
+ .sort(field, order) // Sort results ('asc' | 'desc')
156
277
  .limit(n) // Limit results
157
- .skip(n) // Skip results
278
+ .skip(n) // Skip results (pagination)
158
279
  .exec(); // Execute query
159
280
 
160
281
  // Count with filters
161
282
  const count = await Model.query()
162
- .filter('status', 'eq', 'active')
283
+ .where('status', 'eq', 'active')
163
284
  .count();
164
285
  ```
165
286
 
@@ -219,16 +340,26 @@ age: { type: 'number', min: 0, max: 120 }
219
340
  // Pattern matching
220
341
  phone: { type: 'string', pattern: /^\d{10}$/ }
221
342
 
222
- // Custom validation
343
+ // Custom validation (sync or async)
223
344
  username: {
224
345
  type: 'string',
225
346
  validate: (value) => /^[a-z0-9_]+$/.test(value),
226
347
  }
348
+
349
+ // Async custom validation
350
+ email: {
351
+ type: 'string',
352
+ validate: async (value) => {
353
+ // Check if email is already taken
354
+ const existing = await User.findOne({ email: value });
355
+ return !existing;
356
+ },
357
+ }
227
358
  ```
228
359
 
229
360
  ## πŸ“ Examples
230
361
 
231
- ### Example 1: User Management
362
+ ### Example 1: User Management System
232
363
 
233
364
  ```typescript
234
365
  import { TormClient } from '@toonstore/torm';
@@ -236,10 +367,10 @@ import { TormClient } from '@toonstore/torm';
236
367
  const torm = new TormClient();
237
368
 
238
369
  interface User {
239
- id: string;
240
370
  username: string;
241
371
  email: string;
242
372
  age: number;
373
+ role: 'admin' | 'user';
243
374
  }
244
375
 
245
376
  const User = torm.model<User>('User', {
@@ -258,33 +389,43 @@ const User = torm.model<User>('User', {
258
389
  type: 'number',
259
390
  min: 18,
260
391
  },
392
+ role: {
393
+ type: 'string',
394
+ required: true,
395
+ },
261
396
  });
262
397
 
263
398
  // Create users
264
- await User.create({
265
- id: 'user:1',
399
+ const alice = await User.create({
266
400
  username: 'alice',
267
401
  email: 'alice@example.com',
268
402
  age: 30,
403
+ role: 'admin',
269
404
  });
270
405
 
271
- // Find adults
272
- const adults = await User.query()
273
- .filter('age', 'gte', 18)
406
+ // Find by role
407
+ const admins = await User.query()
408
+ .where('role', 'eq', 'admin')
274
409
  .sort('username', 'asc')
275
410
  .exec();
411
+
412
+ // Find adults sorted by age
413
+ const adults = await User.query()
414
+ .where('age', 'gte', 18)
415
+ .sort('age', 'desc')
416
+ .exec();
276
417
  ```
277
418
 
278
- ### Example 2: Blog Posts
419
+ ### Example 2: Blog Posts with Tags
279
420
 
280
421
  ```typescript
281
422
  interface Post {
282
- id: string;
283
423
  title: string;
284
424
  content: string;
285
- author_id: string;
425
+ authorId: string;
286
426
  published: boolean;
287
427
  tags: string[];
428
+ views: number;
288
429
  }
289
430
 
290
431
  const Post = torm.model<Post>('Post', {
@@ -299,7 +440,7 @@ const Post = torm.model<Post>('Post', {
299
440
  required: true,
300
441
  minLength: 10,
301
442
  },
302
- author_id: {
443
+ authorId: {
303
444
  type: 'string',
304
445
  required: true,
305
446
  },
@@ -309,41 +450,48 @@ const Post = torm.model<Post>('Post', {
309
450
  tags: {
310
451
  type: 'array',
311
452
  },
453
+ views: {
454
+ type: 'number',
455
+ min: 0,
456
+ },
312
457
  });
313
458
 
314
459
  // Create post
315
- await Post.create({
316
- id: 'post:1',
460
+ const post = await Post.create({
317
461
  title: 'Getting Started with TORM',
318
- content: 'TORM is an amazing ORM for ToonStore...',
319
- author_id: 'user:1',
462
+ content: 'TORM is an amazing ORM for ToonStoreDB with type-safe models and validation...',
463
+ authorId: alice._id,
320
464
  published: true,
321
- tags: ['orm', 'database', 'toonstore'],
465
+ tags: ['orm', 'database', 'toonstore', 'redis'],
466
+ views: 0,
322
467
  });
323
468
 
324
469
  // Find published posts
325
- const published = await Post.query()
326
- .filter('published', 'eq', true)
327
- .sort('created_at', 'desc')
470
+ const publishedPosts = await Post.query()
471
+ .where('published', 'eq', true)
472
+ .sort('_createdAt', 'desc')
328
473
  .limit(10)
329
474
  .exec();
330
475
 
331
476
  // Find posts by author
332
- const authorPosts = await Post.query()
333
- .filter('author_id', 'eq', 'user:1')
477
+ const alicePosts = await Post.query()
478
+ .where('authorId', 'eq', alice._id)
334
479
  .exec();
480
+
481
+ // Update view count
482
+ await Post.update(post._id, { views: post.views + 1 });
335
483
  ```
336
484
 
337
- ### Example 3: E-Commerce Products
485
+ ### Example 3: E-Commerce Product Catalog
338
486
 
339
487
  ```typescript
340
488
  interface Product {
341
- id: string;
342
489
  name: string;
343
490
  price: number;
344
491
  stock: number;
345
492
  sku: string;
346
493
  category: string;
494
+ description?: string;
347
495
  }
348
496
 
349
497
  const Product = torm.model<Product>('Product', {
@@ -368,31 +516,82 @@ const Product = torm.model<Product>('Product', {
368
516
  },
369
517
  });
370
518
 
371
- // Create product
372
- await Product.create({
373
- id: 'product:1',
374
- name: 'Laptop',
375
- price: 999.99,
376
- stock: 50,
519
+ // Create products
520
+ const laptop = await Product.create({
521
+ name: 'Gaming Laptop',
522
+ price: 1299.99,
523
+ stock: 15,
377
524
  sku: 'LAP-12345',
378
525
  category: 'electronics',
526
+ description: 'High-performance gaming laptop with RTX 4070',
379
527
  });
380
528
 
381
529
  // Find products in stock
382
530
  const inStock = await Product.query()
383
- .filter('stock', 'gt', 0)
531
+ .where('stock', 'gt', 0)
384
532
  .sort('price', 'asc')
385
533
  .exec();
386
534
 
535
+ // Find by category with pagination
536
+ const electronics = await Product.query()
537
+ .where('category', 'eq', 'electronics')
538
+ .sort('name', 'asc')
539
+ .skip(0)
540
+ .limit(20)
541
+ .exec();
542
+
387
543
  // Find expensive products
388
- const expensive = await Product.query()
389
- .filter('price', 'gte', 1000)
544
+ const premium = await Product.query()
545
+ .where('price', 'gte', 1000)
546
+ .sort('price', 'desc')
547
+ .exec();
548
+
549
+ // Low stock alert
550
+ const lowStock = await Product.query()
551
+ .where('stock', 'lt', 10)
390
552
  .exec();
391
553
  ```
392
554
 
555
+ ## πŸ”„ Migration from v0.1.x
556
+
557
+ Version 0.2.0 introduces breaking changes:
558
+
559
+ ### What Changed
560
+ - **No more HTTP server required** - SDK now connects directly to ToonStoreDB
561
+ - **Auto-generated IDs** - No need to provide `id` field, use `_id` instead
562
+ - **New connection options** - Use `host`, `port`, or `url` for ToonStoreDB connection
563
+
564
+ ### Migration Steps
565
+
566
+ ```typescript
567
+ // v0.1.x (OLD - required TORM server via HTTP)
568
+ const torm = new TormClient({
569
+ baseURL: 'http://localhost:3001',
570
+ });
571
+
572
+ const user = await User.create({
573
+ id: 'user:1',
574
+ name: 'Alice',
575
+ });
576
+
577
+ // v0.2.x (NEW - direct ToonStoreDB connection)
578
+ const torm = new TormClient({
579
+ host: 'localhost',
580
+ port: 6379,
581
+ });
582
+
583
+ const user = await User.create({
584
+ name: 'Alice', // No id needed
585
+ });
586
+ console.log(user._id); // Auto-generated
587
+ ```
588
+
393
589
  ## πŸ§ͺ Running Examples
394
590
 
395
591
  ```bash
592
+ # Make sure ToonStoreDB is running
593
+ ./toonstoredb
594
+
396
595
  # Install dependencies
397
596
  npm install
398
597
 
@@ -403,7 +602,7 @@ npm run build
403
602
  npm run example
404
603
  ```
405
604
 
406
- ## πŸ› οΈ Development
605
+ ## πŸ—οΈ Development
407
606
 
408
607
  ```bash
409
608
  # Install dependencies
@@ -412,15 +611,93 @@ npm install
412
611
  # Build TypeScript
413
612
  npm run build
414
613
 
415
- # Watch mode (auto-rebuild)
614
+ # Watch mode (auto-rebuild on changes)
416
615
  npm run dev
616
+
617
+ # Run tests
618
+ npm test
619
+ ```
620
+
621
+ ## 🌟 Why TORM?
622
+
623
+ - **Standalone SDK** - No TORM server needed, just ToonStoreDB
624
+ - **Type Safety** - Full TypeScript support with generics
625
+ - **Familiar API** - If you know Mongoose, you know TORM
626
+ - **High Performance** - Leverages ToonStoreDB's blazing fast speed (5.28M ops/sec)
627
+ - **Validation Built-in** - Comprehensive validation without extra libraries
628
+ - **Modern Async/Await** - Clean, readable promise-based code
629
+
630
+ ## 🏒 Architecture
631
+
417
632
  ```
633
+ Your Node.js App β†’ @toonstore/torm SDK β†’ ToonStoreDB
634
+ ```
635
+
636
+ **What you need to run:**
637
+ - βœ… ToonStoreDB server (the database)
638
+ - βœ… Your Node.js app with this SDK
639
+
640
+ **What you DON'T need:**
641
+ - ❌ TORM Server (that's only for TORM Studio UI - a separate optional visual management tool)
642
+ - ❌ Any HTTP server or API layer
643
+ - ❌ Redis installation (ToonStoreDB is the database, it just uses Redis-compatible protocol internally)
644
+
645
+ ## πŸ—ΊοΈ Roadmap
646
+
647
+ **SDK Features:**
648
+ - [ ] Relationships (references between models)
649
+ - [ ] Hooks (pre/post save, update, delete)
650
+ - [ ] Indexes and search optimization
651
+ - [ ] Transactions support
652
+ - [ ] Aggregation pipelines
653
+ - [ ] Virtual fields
654
+ - [ ] Plugins system
655
+
656
+ **CLI Tools:**
657
+ - [x] TORM Studio (bundled Node.js server) βœ…
658
+ - [ ] Schema migrations (`torm generate`, `torm migrate`)
659
+ - [ ] Type generation from schemas
660
+ - [ ] Database seeding
661
+ - [ ] Schema validation and linting
662
+
663
+ **Studio Enhancements:**
664
+ - [ ] Custom domain (local.torm.studio via DNS) - no hosts file needed
665
+ - [ ] Advanced query builder UI
666
+ - [ ] Export/import data
667
+ - [ ] Real-time collaboration
668
+ - [ ] Schema visualization
669
+
670
+ **Migration System (Planned):**
671
+ ```bash
672
+ # Generate migration from model changes
673
+ torm generate --name add_users_table
674
+
675
+ # Run migrations
676
+ torm migrate
677
+
678
+ # Rollback
679
+ torm migrate:rollback
680
+
681
+ # Check status
682
+ torm migrate:status
683
+ ```
684
+
685
+ ## 🀝 Contributing
686
+
687
+ Contributions are welcome! Please feel free to submit a Pull Request.
418
688
 
419
689
  ## πŸ“„ License
420
690
 
421
691
  MIT
422
692
 
423
- ## πŸ™ Credits
693
+ ## πŸ”— Links
694
+
695
+ - [ToonStoreDB](https://github.com/toonstore/toonstoredb) - The blazingly fast database
696
+ - [TORM](https://github.com/toonstore/torm) - Multi-language ORM with Studio
697
+ - [TOON Format](https://github.com/toon-format/toon) - The data format specification
698
+ - [NPM Package](https://www.npmjs.com/package/@toonstore/torm)
699
+ - [TORM Studio Guide](https://github.com/toonstore/torm/blob/main/docs/STUDIO.md)
700
+
701
+ ## πŸ’¬ Support
424
702
 
425
- - Inspired by [Mongoose](https://mongoosejs.com/)
426
- - Built for [ToonStore](https://github.com/toon-format/toon)
703
+ For questions and support, please open an issue on GitHub.
package/dist/cli.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * TORM CLI
4
+ * Command-line interface for ToonStoreDB ORM
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;GAGG"}