@veloxts/orm 0.4.0 → 0.4.2

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.
Files changed (2) hide show
  1. package/README.md +19 -534
  2. package/package.json +2 -2
package/README.md CHANGED
@@ -1,567 +1,52 @@
1
1
  # @veloxts/orm
2
2
 
3
- > **Alpha Release** - This framework is in early development. APIs may change between versions. Not recommended for production use yet.
3
+ **Pre-Alpha Notice:** This framework is in early development (v0.4.x). APIs are subject to change. Not recommended for production use.
4
4
 
5
- Prisma wrapper with enhanced developer experience for the VeloxTS framework.
5
+ ## What is this?
6
6
 
7
- ## Installation
7
+ Prisma ORM integration package for the VeloxTS Framework, providing enhanced developer experience for database operations.
8
8
 
9
- ```bash
10
- npm install @veloxts/orm @prisma/client
11
- # or
12
- pnpm add @veloxts/orm @prisma/client
13
- ```
9
+ ## Part of @veloxts/velox
14
10
 
15
- Note: `@prisma/client` is a peer dependency. You'll also need the `prisma` CLI as a dev dependency:
11
+ This package is part of the VeloxTS Framework. For the complete framework experience, install:
16
12
 
17
13
  ```bash
18
- npm install -D prisma
19
- # or
20
- pnpm add -D prisma
14
+ npm install @veloxts/velox
21
15
  ```
22
16
 
23
- ## Quick Start
17
+ Visit [@veloxts/velox](https://www.npmjs.com/package/@veloxts/velox) for the complete framework documentation.
24
18
 
25
- ### 1. Initialize Prisma
19
+ ## Standalone Installation
26
20
 
27
21
  ```bash
28
- npx prisma init
22
+ npm install @veloxts/orm @prisma/client
29
23
  ```
30
24
 
31
- This creates a `prisma` directory with a `schema.prisma` file.
32
-
33
- ### 2. Define Your Schema
25
+ Note: `@prisma/client` is a peer dependency. You'll also need the `prisma` CLI as a dev dependency.
34
26
 
35
- Edit `prisma/schema.prisma`:
27
+ ## Documentation
36
28
 
37
- ```prisma
38
- datasource db {
39
- provider = "postgresql"
40
- url = env("DATABASE_URL")
41
- }
29
+ For detailed documentation, usage examples, and API reference, see [GUIDE.md](./GUIDE.md).
42
30
 
43
- generator client {
44
- provider = "prisma-client-js"
45
- }
46
-
47
- model User {
48
- id String @id @default(uuid())
49
- name String
50
- email String @unique
51
- createdAt DateTime @default(now())
52
- updatedAt DateTime @updatedAt
53
- }
54
- ```
55
-
56
- ### 3. Generate Prisma Client
57
-
58
- ```bash
59
- npx prisma generate
60
- ```
61
-
62
- ### 4. Integrate with VeloxTS
31
+ ## Quick Example
63
32
 
64
33
  ```typescript
65
- import { createVeloxApp } from '@veloxts/core';
34
+ import { veloxApp } from '@veloxts/core';
66
35
  import { createDatabasePlugin } from '@veloxts/orm';
67
36
  import { PrismaClient } from '@prisma/client';
68
37
 
69
- // Create Prisma client
70
38
  const prisma = new PrismaClient();
39
+ const app = await veloxApp({ port: 3210 });
71
40
 
72
- // Create VeloxTS app
73
- const app = await createVeloxApp({
74
- port: 3210,
75
- logger: true,
76
- });
77
-
78
- // Register database plugin
79
41
  await app.register(createDatabasePlugin({ client: prisma }));
80
-
81
- // Start server
82
42
  await app.start();
83
- console.log(`Server running on ${app.address}`);
84
- ```
85
-
86
- ## Core API
87
-
88
- ### `createDatabasePlugin(config)`
89
-
90
- Creates a VeloxTS plugin that integrates Prisma with automatic lifecycle management.
91
-
92
- **Configuration:**
93
-
94
- ```typescript
95
- interface OrmPluginConfig {
96
- client: PrismaClient; // Your Prisma client instance
97
- connect?: boolean; // Auto-connect on startup (default: true)
98
- disconnect?: boolean; // Auto-disconnect on shutdown (default: true)
99
- }
100
- ```
101
-
102
- **Example:**
103
-
104
- ```typescript
105
- import { createDatabasePlugin } from '@veloxts/orm';
106
- import { PrismaClient } from '@prisma/client';
107
-
108
- const prisma = new PrismaClient({
109
- log: ['query', 'error', 'warn'],
110
- });
111
-
112
- const dbPlugin = createDatabasePlugin({
113
- client: prisma,
114
- connect: true, // Connect when app starts
115
- disconnect: true, // Disconnect on graceful shutdown
116
- });
117
-
118
- await app.register(dbPlugin);
119
- ```
120
-
121
- ### Context Extension
122
-
123
- The database plugin extends the VeloxTS context with a `db` property:
124
-
125
- ```typescript
126
- // Type definition is automatically available
127
- declare module '@veloxts/core' {
128
- interface BaseContext {
129
- db: PrismaClient;
130
- }
131
- }
132
-
133
- // Use in procedures
134
- export const userProcedures = defineProcedures('users', {
135
- getUser: procedure()
136
- .input(z.object({ id: z.string().uuid() }))
137
- .output(UserSchema)
138
- .query(async ({ input, ctx }) => {
139
- // ctx.db is fully typed as PrismaClient
140
- const user = await ctx.db.user.findUnique({
141
- where: { id: input.id },
142
- });
143
-
144
- if (!user) {
145
- throw new NotFoundError('User', input.id);
146
- }
147
-
148
- return user;
149
- }),
150
- });
151
- ```
152
-
153
- ## Database Queries
154
-
155
- The `ctx.db` object provides full access to Prisma's query API:
156
-
157
- ### Finding Records
158
-
159
- ```typescript
160
- // Find unique record
161
- const user = await ctx.db.user.findUnique({
162
- where: { id: userId },
163
- });
164
-
165
- // Find unique or throw
166
- const user = await ctx.db.user.findUniqueOrThrow({
167
- where: { id: userId },
168
- });
169
-
170
- // Find first matching record
171
- const user = await ctx.db.user.findFirst({
172
- where: { email: 'alice@example.com' },
173
- });
174
-
175
- // Find many with filters
176
- const users = await ctx.db.user.findMany({
177
- where: {
178
- email: { contains: '@example.com' },
179
- createdAt: { gte: new Date('2025-01-01') },
180
- },
181
- orderBy: { createdAt: 'desc' },
182
- take: 10,
183
- skip: 0,
184
- });
185
- ```
186
-
187
- ### Creating Records
188
-
189
- ```typescript
190
- // Create single record
191
- const user = await ctx.db.user.create({
192
- data: {
193
- name: 'Alice',
194
- email: 'alice@example.com',
195
- },
196
- });
197
-
198
- // Create with relations
199
- const post = await ctx.db.post.create({
200
- data: {
201
- title: 'Hello World',
202
- content: 'My first post',
203
- author: {
204
- connect: { id: userId },
205
- },
206
- },
207
- include: { author: true }, // Include related data
208
- });
209
- ```
210
-
211
- ### Updating Records
212
-
213
- ```typescript
214
- // Update single record
215
- const user = await ctx.db.user.update({
216
- where: { id: userId },
217
- data: { name: 'Alice Smith' },
218
- });
219
-
220
- // Update many
221
- const result = await ctx.db.user.updateMany({
222
- where: { email: { contains: '@old-domain.com' } },
223
- data: { email: 'migrated@new-domain.com' },
224
- });
225
- console.log(`Updated ${result.count} users`);
226
-
227
- // Upsert (update or create)
228
- const user = await ctx.db.user.upsert({
229
- where: { email: 'alice@example.com' },
230
- update: { name: 'Alice Updated' },
231
- create: {
232
- name: 'Alice',
233
- email: 'alice@example.com',
234
- },
235
- });
236
- ```
237
-
238
- ### Deleting Records
239
-
240
- ```typescript
241
- // Delete single record
242
- const user = await ctx.db.user.delete({
243
- where: { id: userId },
244
- });
245
-
246
- // Delete many
247
- const result = await ctx.db.user.deleteMany({
248
- where: { createdAt: { lt: new Date('2024-01-01') } },
249
- });
250
- console.log(`Deleted ${result.count} users`);
251
- ```
252
-
253
- ### Aggregations and Counting
254
-
255
- ```typescript
256
- // Count records
257
- const count = await ctx.db.user.count({
258
- where: { email: { contains: '@example.com' } },
259
- });
260
-
261
- // Aggregate
262
- const stats = await ctx.db.post.aggregate({
263
- _count: true,
264
- _avg: { views: true },
265
- _sum: { views: true },
266
- where: { published: true },
267
- });
268
- ```
269
-
270
- ### Transactions
271
-
272
- ```typescript
273
- // Transaction with array of operations
274
- const [user, post] = await ctx.db.$transaction([
275
- ctx.db.user.create({ data: { name: 'Alice', email: 'alice@example.com' } }),
276
- ctx.db.post.create({ data: { title: 'Hello', content: 'World' } }),
277
- ]);
278
-
279
- // Interactive transaction
280
- const result = await ctx.db.$transaction(async (tx) => {
281
- const user = await tx.user.create({
282
- data: { name: 'Bob', email: 'bob@example.com' },
283
- });
284
-
285
- const post = await tx.post.create({
286
- data: {
287
- title: 'Bob\'s Post',
288
- content: 'Hello from Bob',
289
- authorId: user.id,
290
- },
291
- });
292
-
293
- return { user, post };
294
- });
295
- ```
296
-
297
- ## Database Migrations
298
-
299
- VeloxTS provides CLI commands for managing database migrations via Prisma:
300
-
301
- ### Development Workflow
302
-
303
- ```bash
304
- # Create migration after schema changes
305
- npx prisma migrate dev --name add_user_table
306
-
307
- # Apply migrations
308
- velox migrate
309
-
310
- # Force push schema (dev only, skips migrations)
311
- velox migrate --force
312
-
313
- # Reset database (WARNING: deletes all data)
314
- npx prisma migrate reset
315
- ```
316
-
317
- ### Production Workflow
318
-
319
- ```bash
320
- # Deploy pending migrations
321
- velox migrate --deploy
322
-
323
- # Or use Prisma directly
324
- npx prisma migrate deploy
325
- ```
326
-
327
- ## Manual Connection Management
328
-
329
- For advanced use cases, you can manually manage connections:
330
-
331
- ```typescript
332
- import { createDatabase } from '@veloxts/orm';
333
- import { PrismaClient } from '@prisma/client';
334
-
335
- const db = createDatabase({
336
- client: new PrismaClient(),
337
- });
338
-
339
- // Manually connect
340
- await db.connect();
341
- console.log('Connected:', db.isConnected);
342
-
343
- // Use the client
344
- const users = await db.client.user.findMany();
345
-
346
- // Check connection status
347
- const status = db.getStatus();
348
- console.log(status);
349
- // {
350
- // state: 'connected',
351
- // connectedAt: Date,
352
- // disconnectedAt: null,
353
- // errorCount: 0,
354
- // lastError: null
355
- // }
356
-
357
- // Manually disconnect
358
- await db.disconnect();
359
- ```
360
-
361
- ## Practical Examples
362
-
363
- ### CRUD Procedures
364
-
365
- Complete example of CRUD operations:
366
-
367
- ```typescript
368
- import { defineProcedures, procedure } from '@veloxts/router';
369
- import { z, paginationInputSchema } from '@veloxts/validation';
370
- import { NotFoundError } from '@veloxts/core';
371
-
372
- const UserSchema = z.object({
373
- id: z.string().uuid(),
374
- name: z.string(),
375
- email: z.string().email(),
376
- createdAt: z.string().datetime(),
377
- updatedAt: z.string().datetime(),
378
- });
379
-
380
- export const userProcedures = defineProcedures('users', {
381
- // GET /users/:id
382
- getUser: procedure()
383
- .input(z.object({ id: z.string().uuid() }))
384
- .output(UserSchema)
385
- .query(async ({ input, ctx }) => {
386
- const user = await ctx.db.user.findUnique({
387
- where: { id: input.id },
388
- });
389
-
390
- if (!user) {
391
- throw new NotFoundError('User', input.id);
392
- }
393
-
394
- return user;
395
- }),
396
-
397
- // GET /users
398
- listUsers: procedure()
399
- .input(paginationInputSchema)
400
- .output(z.object({
401
- data: z.array(UserSchema),
402
- meta: z.object({
403
- page: z.number(),
404
- limit: z.number(),
405
- total: z.number(),
406
- }),
407
- }))
408
- .query(async ({ input, ctx }) => {
409
- const skip = (input.page - 1) * input.limit;
410
-
411
- const [data, total] = await Promise.all([
412
- ctx.db.user.findMany({
413
- skip,
414
- take: input.limit,
415
- orderBy: { createdAt: 'desc' },
416
- }),
417
- ctx.db.user.count(),
418
- ]);
419
-
420
- return {
421
- data,
422
- meta: { page: input.page, limit: input.limit, total },
423
- };
424
- }),
425
-
426
- // POST /users
427
- createUser: procedure()
428
- .input(z.object({
429
- name: z.string().min(1),
430
- email: z.string().email(),
431
- }))
432
- .output(UserSchema)
433
- .mutation(async ({ input, ctx }) => {
434
- return ctx.db.user.create({ data: input });
435
- }),
436
-
437
- // PUT /users/:id (deferred to v1.1+)
438
- // DELETE /users/:id (deferred to v1.1+)
439
- });
440
43
  ```
441
44
 
442
- ### Relationships
443
-
444
- Working with related data:
445
-
446
- ```typescript
447
- // Schema with relations
448
- model User {
449
- id String @id @default(uuid())
450
- name String
451
- posts Post[]
452
- }
453
-
454
- model Post {
455
- id String @id @default(uuid())
456
- title String
457
- authorId String
458
- author User @relation(fields: [authorId], references: [id])
459
- }
460
-
461
- // Query with relations
462
- const userProcedures = defineProcedures('users', {
463
- getUserWithPosts: procedure()
464
- .input(z.object({ id: z.string().uuid() }))
465
- .query(async ({ input, ctx }) => {
466
- return ctx.db.user.findUnique({
467
- where: { id: input.id },
468
- include: {
469
- posts: {
470
- orderBy: { createdAt: 'desc' },
471
- take: 10,
472
- },
473
- },
474
- });
475
- }),
476
- });
477
- ```
478
-
479
- ## Configuration Best Practices
480
-
481
- ### Environment Variables
482
-
483
- Store connection strings in `.env`:
484
-
485
- ```env
486
- DATABASE_URL="postgresql://user:password@localhost:5432/mydb?schema=public"
487
- ```
488
-
489
- ### Production Setup
490
-
491
- ```typescript
492
- const prisma = new PrismaClient({
493
- log: process.env.NODE_ENV === 'development'
494
- ? ['query', 'error', 'warn']
495
- : ['error'],
496
- errorFormat: 'minimal',
497
- });
498
-
499
- const dbPlugin = createDatabasePlugin({
500
- client: prisma,
501
- connect: true,
502
- disconnect: true,
503
- });
504
- ```
505
-
506
- ### Connection Pooling
507
-
508
- Prisma handles connection pooling automatically. Configure in `schema.prisma`:
509
-
510
- ```prisma
511
- datasource db {
512
- provider = "postgresql"
513
- url = env("DATABASE_URL")
514
- // Connection pool settings via URL parameters:
515
- // ?connection_limit=10&pool_timeout=20
516
- }
517
- ```
518
-
519
- ## Error Handling
520
-
521
- The ORM plugin integrates with VeloxTS's error handling:
522
-
523
- ```typescript
524
- import { NotFoundError, VeloxError } from '@veloxts/core';
525
-
526
- try {
527
- const user = await ctx.db.user.findUniqueOrThrow({
528
- where: { id: userId },
529
- });
530
- } catch (error) {
531
- if (error.code === 'P2025') {
532
- // Prisma "Record not found" error
533
- throw new NotFoundError('User', userId);
534
- }
535
- throw new VeloxError('Database error', 500);
536
- }
537
- ```
538
-
539
- ## MVP Limitations
540
-
541
- The current v0.1.0 release focuses on core functionality:
542
-
543
- **Included:**
544
- - Prisma client integration
545
- - Context extension (`ctx.db`)
546
- - Connection lifecycle management
547
- - Basic migration commands
548
-
549
- **Deferred to v1.1+:**
550
- - Database seeding utilities
551
- - Migration rollback via CLI
552
- - Query logging middleware
553
- - Advanced connection pooling configuration
554
-
555
- ## Related Packages
556
-
557
- - [@veloxts/core](/packages/core) - Core framework with context system
558
- - [@veloxts/router](/packages/router) - Procedure definitions using database queries
559
- - [@veloxts/validation](/packages/validation) - Schema validation for inputs/outputs
560
- - [@veloxts/cli](/packages/cli) - CLI with `velox migrate` command
561
-
562
- ## TypeScript Support
45
+ ## Learn More
563
46
 
564
- All exports are fully typed with comprehensive JSDoc documentation. The package includes type definitions and declaration maps for excellent IDE support.
47
+ - [Full Documentation](./GUIDE.md)
48
+ - [VeloxTS Framework](https://www.npmjs.com/package/@veloxts/velox)
49
+ - [GitHub Repository](https://github.com/veloxts/velox-ts-framework)
565
50
 
566
51
  ## License
567
52
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@veloxts/orm",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "description": "Prisma wrapper with enhanced DX for VeloxTS framework",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -13,7 +13,7 @@
13
13
  },
14
14
  "dependencies": {
15
15
  "fastify": "5.6.2",
16
- "@veloxts/core": "0.4.0"
16
+ "@veloxts/core": "0.4.2"
17
17
  },
18
18
  "devDependencies": {
19
19
  "@vitest/coverage-v8": "4.0.15",