@venizia/ignis-docs 0.0.7-2 → 0.0.8-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.
Files changed (161) hide show
  1. package/dist/mcp-server/common/paths.d.ts +4 -2
  2. package/dist/mcp-server/common/paths.d.ts.map +1 -1
  3. package/dist/mcp-server/common/paths.js +8 -6
  4. package/dist/mcp-server/common/paths.js.map +1 -1
  5. package/dist/mcp-server/tools/docs/get-document-content.tool.d.ts +1 -1
  6. package/dist/mcp-server/tools/docs/get-document-content.tool.d.ts.map +1 -1
  7. package/dist/mcp-server/tools/docs/get-document-content.tool.js +7 -7
  8. package/dist/mcp-server/tools/docs/get-document-metadata.tool.js +3 -3
  9. package/dist/mcp-server/tools/docs/get-package-overview.tool.d.ts +1 -1
  10. package/dist/mcp-server/tools/docs/get-package-overview.tool.js +1 -1
  11. package/package.json +1 -1
  12. package/wiki/best-practices/api-usage-examples.md +9 -9
  13. package/wiki/best-practices/architectural-patterns.md +19 -3
  14. package/wiki/best-practices/architecture-decisions.md +6 -6
  15. package/wiki/best-practices/code-style-standards/advanced-patterns.md +1 -1
  16. package/wiki/best-practices/code-style-standards/control-flow.md +1 -1
  17. package/wiki/best-practices/code-style-standards/function-patterns.md +2 -2
  18. package/wiki/best-practices/code-style-standards/index.md +2 -2
  19. package/wiki/best-practices/code-style-standards/naming-conventions.md +1 -1
  20. package/wiki/best-practices/code-style-standards/route-definitions.md +4 -4
  21. package/wiki/best-practices/data-modeling.md +1 -1
  22. package/wiki/best-practices/deployment-strategies.md +1 -1
  23. package/wiki/best-practices/error-handling.md +2 -2
  24. package/wiki/best-practices/performance-optimization.md +3 -3
  25. package/wiki/best-practices/security-guidelines.md +2 -2
  26. package/wiki/best-practices/troubleshooting-tips.md +1 -1
  27. package/wiki/{references → extensions}/components/authentication/api.md +12 -20
  28. package/wiki/{references → extensions}/components/authentication/errors.md +1 -1
  29. package/wiki/{references → extensions}/components/authentication/index.md +5 -8
  30. package/wiki/{references → extensions}/components/authentication/usage.md +20 -36
  31. package/wiki/{references → extensions}/components/authorization/api.md +62 -13
  32. package/wiki/{references → extensions}/components/authorization/errors.md +12 -7
  33. package/wiki/{references → extensions}/components/authorization/index.md +93 -6
  34. package/wiki/{references → extensions}/components/authorization/usage.md +42 -4
  35. package/wiki/{references → extensions}/components/health-check.md +5 -4
  36. package/wiki/{references → extensions}/components/index.md +2 -0
  37. package/wiki/{references → extensions}/components/mail/index.md +1 -1
  38. package/wiki/{references → extensions}/components/request-tracker.md +1 -1
  39. package/wiki/{references → extensions}/components/socket-io/api.md +2 -2
  40. package/wiki/{references → extensions}/components/socket-io/errors.md +2 -0
  41. package/wiki/{references → extensions}/components/socket-io/index.md +24 -20
  42. package/wiki/{references → extensions}/components/socket-io/usage.md +2 -2
  43. package/wiki/{references → extensions}/components/static-asset/api.md +14 -15
  44. package/wiki/{references → extensions}/components/static-asset/errors.md +3 -1
  45. package/wiki/{references → extensions}/components/static-asset/index.md +158 -89
  46. package/wiki/{references → extensions}/components/static-asset/usage.md +8 -5
  47. package/wiki/{references → extensions}/components/swagger.md +3 -3
  48. package/wiki/{references → extensions}/components/template/index.md +4 -4
  49. package/wiki/{references → extensions}/components/template/setup-page.md +1 -1
  50. package/wiki/{references → extensions}/components/template/single-page.md +1 -1
  51. package/wiki/{references → extensions}/components/websocket/api.md +7 -6
  52. package/wiki/{references → extensions}/components/websocket/errors.md +17 -3
  53. package/wiki/{references → extensions}/components/websocket/index.md +17 -11
  54. package/wiki/{references → extensions}/components/websocket/usage.md +2 -2
  55. package/wiki/{references → extensions}/helpers/crypto/index.md +1 -1
  56. package/wiki/{references → extensions}/helpers/env/index.md +9 -5
  57. package/wiki/{references → extensions}/helpers/error/index.md +2 -7
  58. package/wiki/{references → extensions}/helpers/index.md +18 -6
  59. package/wiki/{references → extensions}/helpers/kafka/admin.md +33 -16
  60. package/wiki/extensions/helpers/kafka/consumer.md +384 -0
  61. package/wiki/extensions/helpers/kafka/examples.md +361 -0
  62. package/wiki/extensions/helpers/kafka/index.md +639 -0
  63. package/wiki/{references → extensions}/helpers/kafka/producer.md +100 -96
  64. package/wiki/extensions/helpers/kafka/schema-registry.md +214 -0
  65. package/wiki/{references → extensions}/helpers/logger/index.md +2 -2
  66. package/wiki/{references → extensions}/helpers/queue/index.md +400 -4
  67. package/wiki/{references → extensions}/helpers/storage/api.md +170 -10
  68. package/wiki/{references → extensions}/helpers/storage/index.md +44 -8
  69. package/wiki/{references → extensions}/helpers/template/index.md +1 -1
  70. package/wiki/{references → extensions}/helpers/testing/index.md +4 -4
  71. package/wiki/{references → extensions}/helpers/types/index.md +63 -16
  72. package/wiki/{references → extensions}/helpers/websocket/index.md +1 -1
  73. package/wiki/extensions/index.md +48 -0
  74. package/wiki/guides/core-concepts/application/bootstrapping.md +55 -37
  75. package/wiki/guides/core-concepts/application/index.md +95 -35
  76. package/wiki/guides/core-concepts/components-guide.md +23 -19
  77. package/wiki/guides/core-concepts/components.md +34 -10
  78. package/wiki/guides/core-concepts/dependency-injection.md +99 -34
  79. package/wiki/guides/core-concepts/grpc-controllers.md +295 -0
  80. package/wiki/guides/core-concepts/persistent/datasources.md +27 -8
  81. package/wiki/guides/core-concepts/persistent/models.md +43 -1
  82. package/wiki/guides/core-concepts/persistent/repositories.md +75 -8
  83. package/wiki/guides/core-concepts/persistent/transactions.md +38 -8
  84. package/wiki/guides/core-concepts/{controllers.md → rest-controllers.md} +30 -33
  85. package/wiki/guides/core-concepts/services.md +19 -5
  86. package/wiki/guides/get-started/5-minute-quickstart.md +6 -7
  87. package/wiki/guides/get-started/philosophy.md +1 -1
  88. package/wiki/guides/index.md +2 -2
  89. package/wiki/guides/reference/glossary.md +7 -7
  90. package/wiki/guides/reference/mcp-docs-server.md +1 -1
  91. package/wiki/guides/tutorials/building-a-crud-api.md +2 -2
  92. package/wiki/guides/tutorials/complete-installation.md +17 -14
  93. package/wiki/guides/tutorials/ecommerce-api.md +18 -18
  94. package/wiki/guides/tutorials/realtime-chat.md +8 -8
  95. package/wiki/guides/tutorials/testing.md +2 -2
  96. package/wiki/index.md +4 -3
  97. package/wiki/references/base/application.md +341 -21
  98. package/wiki/references/base/bootstrapping.md +43 -13
  99. package/wiki/references/base/components.md +259 -8
  100. package/wiki/references/base/controllers.md +556 -253
  101. package/wiki/references/base/datasources.md +159 -79
  102. package/wiki/references/base/dependency-injection.md +299 -48
  103. package/wiki/references/base/filter-system/application-usage.md +18 -2
  104. package/wiki/references/base/filter-system/array-operators.md +14 -6
  105. package/wiki/references/base/filter-system/comparison-operators.md +9 -3
  106. package/wiki/references/base/filter-system/default-filter.md +28 -3
  107. package/wiki/references/base/filter-system/fields-order-pagination.md +17 -13
  108. package/wiki/references/base/filter-system/index.md +169 -11
  109. package/wiki/references/base/filter-system/json-filtering.md +51 -18
  110. package/wiki/references/base/filter-system/list-operators.md +4 -3
  111. package/wiki/references/base/filter-system/logical-operators.md +7 -2
  112. package/wiki/references/base/filter-system/null-operators.md +50 -0
  113. package/wiki/references/base/filter-system/quick-reference.md +82 -243
  114. package/wiki/references/base/filter-system/range-operators.md +7 -1
  115. package/wiki/references/base/filter-system/tips.md +34 -7
  116. package/wiki/references/base/filter-system/use-cases.md +6 -5
  117. package/wiki/references/base/grpc-controllers.md +984 -0
  118. package/wiki/references/base/index.md +32 -24
  119. package/wiki/references/base/middleware.md +347 -0
  120. package/wiki/references/base/models.md +390 -46
  121. package/wiki/references/base/providers.md +14 -14
  122. package/wiki/references/base/repositories/advanced.md +84 -69
  123. package/wiki/references/base/repositories/index.md +447 -12
  124. package/wiki/references/base/repositories/mixins.md +103 -98
  125. package/wiki/references/base/repositories/relations.md +129 -45
  126. package/wiki/references/base/repositories/soft-deletable.md +104 -23
  127. package/wiki/references/base/services.md +94 -14
  128. package/wiki/references/index.md +12 -10
  129. package/wiki/references/quick-reference.md +98 -65
  130. package/wiki/references/utilities/crypto.md +21 -4
  131. package/wiki/references/utilities/date.md +25 -7
  132. package/wiki/references/utilities/index.md +26 -24
  133. package/wiki/references/utilities/jsx.md +54 -54
  134. package/wiki/references/utilities/module.md +8 -6
  135. package/wiki/references/utilities/parse.md +16 -9
  136. package/wiki/references/utilities/performance.md +22 -7
  137. package/wiki/references/utilities/promise.md +19 -16
  138. package/wiki/references/utilities/request.md +48 -26
  139. package/wiki/references/utilities/schema.md +69 -6
  140. package/wiki/references/utilities/statuses.md +131 -140
  141. package/wiki/references/helpers/kafka/consumer.md +0 -473
  142. package/wiki/references/helpers/kafka/examples.md +0 -234
  143. package/wiki/references/helpers/kafka/index.md +0 -482
  144. /package/wiki/{references → extensions}/components/mail/api.md +0 -0
  145. /package/wiki/{references → extensions}/components/mail/errors.md +0 -0
  146. /package/wiki/{references → extensions}/components/mail/usage.md +0 -0
  147. /package/wiki/{references → extensions}/components/template/api-page.md +0 -0
  148. /package/wiki/{references → extensions}/components/template/errors-page.md +0 -0
  149. /package/wiki/{references → extensions}/components/template/usage-page.md +0 -0
  150. /package/wiki/{references → extensions}/helpers/cron/index.md +0 -0
  151. /package/wiki/{references → extensions}/helpers/inversion/index.md +0 -0
  152. /package/wiki/{references → extensions}/helpers/network/api.md +0 -0
  153. /package/wiki/{references → extensions}/helpers/network/index.md +0 -0
  154. /package/wiki/{references → extensions}/helpers/redis/index.md +0 -0
  155. /package/wiki/{references → extensions}/helpers/socket-io/api.md +0 -0
  156. /package/wiki/{references → extensions}/helpers/socket-io/index.md +0 -0
  157. /package/wiki/{references → extensions}/helpers/template/single-page.md +0 -0
  158. /package/wiki/{references → extensions}/helpers/uid/index.md +0 -0
  159. /package/wiki/{references → extensions}/helpers/websocket/api.md +0 -0
  160. /package/wiki/{references → extensions}/helpers/worker-thread/index.md +0 -0
  161. /package/wiki/{references → extensions}/src-details/mcp-server.md +0 -0
@@ -2,7 +2,7 @@
2
2
  title: Providers Reference
3
3
  description: Technical reference for the Provider pattern in IGNIS
4
4
  difficulty: advanced
5
- lastUpdated: 2026-01-03
5
+ lastUpdated: 2026-03-15
6
6
  ---
7
7
 
8
8
  # Providers Reference
@@ -461,38 +461,38 @@ export class MailQueueExecutorProvider extends BaseProvider<TGetMailQueueExecuto
461
461
 
462
462
  ### Example 3: Middleware Provider
463
463
 
464
- Providers can also produce middleware:
464
+ Providers can also produce middleware. `RequestSpyMiddleware` is a real-world example that implements `IProvider<MiddlewareHandler>` directly (extending `BaseHelper`, not `BaseProvider`):
465
465
 
466
466
  ```typescript
467
- import { RequestSpyMiddleware } from '@venizia/ignis';
468
-
469
- // RequestSpyMiddleware is a provider that produces Hono middleware
470
- @injectable()
467
+ // From packages/core/src/base/middlewares/request-spy.middleware.ts
471
468
  export class RequestSpyMiddleware extends BaseHelper implements IProvider<MiddlewareHandler> {
472
469
  static readonly REQUEST_ID_KEY = 'requestId';
473
470
 
474
471
  constructor() {
475
- super({ scope: RequestSpyMiddleware.name });
472
+ super({ scope: 'SpyMW' });
476
473
  }
477
474
 
475
+ /** Returns a Hono middleware that logs request details and duration. */
478
476
  value() {
479
477
  return createMiddleware(async (context, next) => {
478
+ const t = performance.now();
480
479
  const requestId = context.get(RequestSpyMiddleware.REQUEST_ID_KEY);
480
+ const method = context.req.method;
481
+ const path = context.req.path ?? '/';
481
482
 
482
- this.logger.info('[spy][%s] START | path: %s', requestId, context.req.path);
483
+ this.logger.info('[%s][=>] %s %s', requestId, method, path);
483
484
 
484
485
  await next();
485
486
 
486
- this.logger.info('[spy][%s] DONE | path: %s', requestId, context.req.path);
487
+ const duration = (performance.now() - t).toFixed(2);
488
+ this.logger.info('[%s][<=] %s %s | Took: %s (ms)', requestId, method, path, duration);
487
489
  });
488
490
  }
489
491
  }
490
-
491
- // Usage
492
- const requestSpy = new RequestSpyMiddleware();
493
- app.use(requestSpy.value());
494
492
  ```
495
493
 
494
+ Note that `RequestSpyMiddleware.value()` does not accept a `container` parameter -- the `IProvider<T>` interface defines `value(container: Container): T`, but implementations may ignore the parameter when they don't need container access. In practice, `RequestSpyMiddleware` is registered via `RequestTrackerComponent`, which binds it as a provider in the DI container and resolves it automatically.
495
+
496
496
 
497
497
  ## Common Patterns
498
498
 
@@ -708,7 +708,7 @@ export class ConfigProvider extends BaseProvider<Config> {
708
708
  - **Related References:**
709
709
  - [Services](./services.md) - Business logic layer
710
710
  - [Dependency Injection](./dependency-injection.md) - DI container and injection
711
- - [Middlewares](./middlewares.md) - Middleware providers
711
+ - [Middleware](./middleware.md) - Built-in middlewares (includes `RequestSpyMiddleware` provider)
712
712
 
713
713
  - **Guides:**
714
714
  - [Dependency Injection Guide](/guides/core-concepts/dependency-injection.md)
@@ -207,7 +207,7 @@ const usersWithPosts = await repo.find({
207
207
 
208
208
  | Filter Options | API Used | Performance |
209
209
  |----------------|----------|-------------|
210
- | `where`, `limit`, `order`, `offset` only | Core API | ~15-20% faster |
210
+ | `where`, `limit`, `order`, `offset`/`skip` only | Core API | ~15-20% faster |
211
211
  | Has `include` (relations) | Query API | Standard |
212
212
  | Has `fields` selection | Query API | Standard |
213
213
 
@@ -216,7 +216,7 @@ const usersWithPosts = await repo.find({
216
216
  Prevent memory exhaustion on large tables:
217
217
 
218
218
  ```typescript
219
- // Good - bounded result set
219
+ // Good - bounded result set
220
220
  await repo.find({
221
221
  filter: {
222
222
  where: { status: 'active' },
@@ -230,42 +230,39 @@ await repo.find({
230
230
  });
231
231
  ```
232
232
 
233
- ### Pagination Pattern
233
+ > [!NOTE]
234
+ > The default limit is `10` when using the `FilterSchema` Zod validation (via `LimitSchema`). However, when calling repository methods directly without schema validation, no default limit is applied.
235
+
236
+ ### Pagination with Data Range
237
+
238
+ Use `shouldQueryRange` to get both data and total count in a single call:
234
239
 
235
240
  ```typescript
236
- async function getPaginatedUsers(page: number, pageSize: number = 20) {
237
- const [users, total] = await Promise.all([
238
- userRepo.find({
239
- filter: {
240
- where: { status: 'active' },
241
- limit: pageSize,
242
- skip: (page - 1) * pageSize,
243
- order: ['createdAt DESC']
244
- }
245
- }),
246
- userRepo.count({ where: { status: 'active' } })
247
- ]);
248
-
249
- return {
250
- data: users,
251
- pagination: {
252
- page,
253
- pageSize,
254
- total,
255
- totalPages: Math.ceil(total / pageSize)
256
- }
257
- };
258
- }
241
+ const result = await userRepo.find({
242
+ filter: {
243
+ where: { status: 'active' },
244
+ limit: 20,
245
+ skip: 40,
246
+ order: ['createdAt DESC']
247
+ },
248
+ options: { shouldQueryRange: true }
249
+ });
250
+
251
+ // Result type: { data: User[], range: { start: number, end: number, total: number } }
252
+ // range follows HTTP Content-Range standard (inclusive end index)
253
+ // Example: { data: [...20 users], range: { start: 40, end: 59, total: 150 } }
259
254
  ```
260
255
 
256
+ This runs `find` and `count` in parallel via `Promise.all` for optimal performance.
257
+
261
258
  ### WeakMap Cache
262
259
 
263
260
  The filter builder caches table column metadata, avoiding repeated reflection:
264
261
 
265
262
  ```typescript
266
263
  // Internal optimization - automatic
267
- // First query: getTableColumns(schema) cached
268
- // Subsequent queries: retrieved from WeakMap
264
+ // First query: getTableColumns(schema) -> cached in WeakMap
265
+ // Subsequent queries: retrieved from WeakMap cache
269
266
  ```
270
267
 
271
268
 
@@ -281,8 +278,7 @@ const result1 = await repo.create({
281
278
  data: { name: 'John' },
282
279
  options: { shouldReturn: false }
283
280
  });
284
- // Type: Promise<{ count: number; data: null }>
285
- console.log(result1.data); // null
281
+ // Type: Promise<{ count: number; data: undefined | null }>
286
282
 
287
283
  // shouldReturn: true (default) - TypeScript knows data is the entity
288
284
  const result2 = await repo.create({
@@ -327,7 +323,7 @@ if (user) {
327
323
  **Supported Methods:**
328
324
  - `find<R>()`, `findOne<R>()`, `findById<R>()`
329
325
  - `create<R>()`, `createAll<R>()`
330
- - `updateById<R>()`, `updateAll<R>()`
326
+ - `updateById<R>()`, `updateAll<R>()`, `updateBy<R>()`
331
327
  - `deleteById<R>()`, `deleteAll<R>()`, `deleteBy<R>()`
332
328
 
333
329
 
@@ -355,7 +351,7 @@ await repo.updateById({
355
351
  });
356
352
  ```
357
353
 
358
- **Available on:** `create`, `createAll`, `updateById`, `updateAll`, `deleteById`, `deleteAll`, `deleteBy`
354
+ **Available on:** `create`, `createAll`, `updateById`, `updateAll`, `updateBy`, `deleteById`, `deleteAll`, `deleteBy` (all write operations that go through `_create`, `_update`, or `_delete` internal methods)
359
355
 
360
356
  ### Query Interface Validation
361
357
 
@@ -377,10 +373,10 @@ The repository validates schema registration on startup:
377
373
  Prevents accidental mass updates/deletes:
378
374
 
379
375
  ```typescript
380
- // Throws error - empty where without force
376
+ // Throws error - empty where without force
381
377
  await repo.deleteAll({ where: {} });
382
378
 
383
- // Explicit force flag - logs warning, proceeds
379
+ // Explicit force flag - logs warning, proceeds
384
380
  await repo.deleteAll({
385
381
  where: {},
386
382
  options: { force: true }
@@ -393,29 +389,16 @@ await repo.deleteAll({
393
389
  | Empty `where` | Throws error | Logs warning, proceeds |
394
390
  | Valid `where` | Executes normally | Executes normally |
395
391
 
396
- ### Constructor Type Validation
392
+ > [!NOTE]
393
+ > This protection applies to `updateAll`, `updateBy`, `deleteAll`, and `deleteBy`. The `updateById` and `deleteById` methods always have a non-empty where (`{ id }`) so they are not affected.
397
394
 
398
- The `@repository` decorator validates constructor parameters:
395
+ ### Transaction Safety
399
396
 
400
- ```typescript
401
- // ❌ Error: First parameter must extend AbstractDataSource
402
- @repository({ model: User, dataSource: PostgresDataSource })
403
- export class UserRepository extends DefaultCRUDRepository<typeof User.schema> {
404
- constructor(dataSource: any) { // 'any' not allowed!
405
- super(dataSource);
406
- }
407
- }
397
+ The `resolveConnector` method validates transaction state before use:
408
398
 
409
- // ✅ Correct: Concrete DataSource type
410
- @repository({ model: User, dataSource: PostgresDataSource })
411
- export class UserRepository extends DefaultCRUDRepository<typeof User.schema> {
412
- constructor(
413
- @inject({ key: 'datasources.PostgresDataSource' })
414
- dataSource: PostgresDataSource,
415
- ) {
416
- super(dataSource);
417
- }
418
- }
399
+ ```typescript
400
+ // If a transaction has already been committed or rolled back:
401
+ // Error: [UserRepository][resolveConnector] Transaction is no longer active
419
402
  ```
420
403
 
421
404
 
@@ -444,12 +427,13 @@ const results = await connector
444
427
 
445
428
  ## Repository Class Hierarchy
446
429
 
447
- | Class | Description |
448
- |-------|-------------|
449
- | `AbstractRepository` | Base class, defines method signatures |
450
- | `ReadableRepository` | Read-only operations (find, findOne, count) |
451
- | `PersistableRepository` | Adds write operations (create, update, delete) |
452
- | `DefaultCRUDRepository` | Full CRUD - **use this one** |
430
+ | Class | Scope | Description |
431
+ |-------|-------|-------------|
432
+ | `AbstractRepository` | N/A | Abstract base class, defines all method signatures, combines `FieldsVisibilityMixin` + `DefaultFilterMixin` |
433
+ | `ReadableRepository` | `READ_ONLY` | Read-only operations (`find`, `findOne`, `findById`, `count`, `existsWith`). Write operations throw errors. |
434
+ | `PersistableRepository` | `READ_WRITE` | Adds write operations (`create`, `update`, `delete`) with `UpdateBuilder` |
435
+ | `DefaultCRUDRepository` | `READ_WRITE` | Extends `PersistableRepository` with no additional logic - **recommended default** |
436
+ | `SoftDeletableRepository` | `READ_WRITE` | Extends `DefaultCRUDRepository` with soft delete + restore operations |
453
437
 
454
438
  ### Creating a Read-Only Repository
455
439
 
@@ -461,6 +445,15 @@ export class AuditLogRepository extends ReadableRepository<typeof AuditLog.schem
461
445
  }
462
446
  ```
463
447
 
448
+ ### Alias Methods
449
+
450
+ `AbstractRepository` provides two alias methods for convenience:
451
+
452
+ - `updateBy(opts)` - Alias for `updateAll(opts)`. Delegates directly.
453
+ - `deleteBy(opts)` - Alias for `deleteAll(opts)`. Delegates directly.
454
+
455
+ Both accept the same parameters (`where`, `data`/`options`) and support `shouldReturn` and `force` options.
456
+
464
457
 
465
458
  ## Default Filter Bypass
466
459
 
@@ -515,7 +508,7 @@ await tx.commit();
515
508
 
516
509
  ## Nested JSON Updates
517
510
 
518
- Repositories support updating specific fields within `json` or `jsonb` columns without overwriting the entire object. This is achieved using **JSON Path Notation** in the update data.
511
+ Repositories support updating specific fields within `json` or `jsonb` columns without overwriting the entire object. This is achieved using **JSON Path Notation** in the update data via the `UpdateBuilder`.
519
512
 
520
513
  ### Basic Usage
521
514
 
@@ -540,9 +533,10 @@ await repo.updateById({
540
533
 
541
534
  - **Deep Nesting:** Update properties at any depth (e.g., `settings.display.font.size`).
542
535
  - **Array Access:** Update array elements by index (e.g., `tags[0]`).
543
- - **Auto-Creation:** Creates missing intermediate keys automatically.
544
- - **Type Safety:** Validates that the target column is a JSON type.
545
- - **Multiple Updates:** Chain multiple updates to the same or different columns.
536
+ - **Auto-Creation:** Creates missing intermediate keys automatically (`jsonb_set` with `create_missing = true`).
537
+ - **Type Safety:** Validates that the target column is a JSON/JSONB type.
538
+ - **Multiple Updates:** Multiple updates to the same column are chained as nested `jsonb_set` calls.
539
+ - **Mixed Updates:** Combine regular column updates with JSON path updates in a single call.
546
540
 
547
541
  ### Examples
548
542
 
@@ -580,7 +574,7 @@ await repo.updateById({
580
574
  data: {
581
575
  status: 'active', // Regular column
582
576
  'metadata.lastLogin': now, // JSON path
583
- 'preferences.lang': 'en' // Another JSON path
577
+ 'preferences.lang': 'en' // Another JSON path
584
578
  }
585
579
  });
586
580
  ```
@@ -588,14 +582,33 @@ await repo.updateById({
588
582
  ### Security & Validation
589
583
 
590
584
  The framework validates JSON paths to prevent SQL injection:
591
- - **Allowed Characters:** Alphanumeric, underscores `_`, hyphens `-`, and brackets `[]`.
592
- - **Validation:** Invalid paths (e.g., containing SQL commands or special characters) throw an error before reaching the database.
593
- - **Values:** Values are safely serialized and parameterized.
585
+ - **Allowed Characters:** Path components must match `/^[a-zA-Z_][a-zA-Z0-9_-]*$|^\d+$/` (identifiers, kebab-case, or array indices).
586
+ - **Column Type Validation:** Only `json` and `jsonb` columns are allowed. Other column types throw an error.
587
+ - **Values:** Values are serialized to JSONB literals with proper escaping.
594
588
 
595
589
  > [!NOTE]
596
590
  > This feature uses PostgreSQL's `jsonb_set` function. It is only available for columns defined as `json` or `jsonb`.
597
591
 
598
592
 
593
+ ## ExtraOptions Reference
594
+
595
+ All repository operations accept an `options` parameter with these fields:
596
+
597
+ | Option | Type | Default | Description |
598
+ |--------|------|---------|-------------|
599
+ | `transaction` | `ITransaction` | - | Transaction context for the operation |
600
+ | `log` | `{ use: boolean; level?: TLogLevel }` | - | Enable operation logging |
601
+ | `shouldSkipDefaultFilter` | `boolean` | `false` | Bypass the default filter from model settings |
602
+
603
+ Write operations additionally support:
604
+
605
+ | Option | Type | Default | Description |
606
+ |--------|------|---------|-------------|
607
+ | `shouldReturn` | `boolean` | `true` | Return the created/updated/deleted data |
608
+ | `force` | `boolean` | `false` | Allow empty `where` condition on bulk operations |
609
+ | `shouldQueryRange` | `boolean` | `false` | Return `{ data, range }` with total count (find only) |
610
+
611
+
599
612
  ## Quick Reference
600
613
 
601
614
  | Feature | Code |
@@ -608,6 +621,7 @@ The framework validates JSON paths to prevent SQL injection:
608
621
  | Enable logging | `options: { log: { use: true, level: 'debug' } }` |
609
622
  | Force delete all | `options: { force: true }` |
610
623
  | Skip returning data | `options: { shouldReturn: false }` |
624
+ | Get data + count | `options: { shouldQueryRange: true }` |
611
625
  | Access connector | `repo.getConnector()` |
612
626
 
613
627
 
@@ -618,6 +632,7 @@ The framework validates JSON paths to prevent SQL injection:
618
632
  - [Default Filter](../filter-system/default-filter.md) - Automatic filter configuration
619
633
  - [Repository Mixins](./mixins.md) - Composable features
620
634
  - [Relations & Includes](./relations.md) - Eager loading
635
+ - [Soft-Deletable Repository](./soft-deletable.md) - Soft delete operations
621
636
  - [JSON Path Filtering](../filter-system/json-filtering) - JSONB queries
622
637
  - [Array Operators](../filter-system/array-operators) - PostgreSQL arrays
623
638
 
@@ -629,7 +644,7 @@ The framework validates JSON paths to prevent SQL injection:
629
644
  - [DataSources](/guides/core-concepts/persistent/datasources) - Database connections
630
645
 
631
646
  - **Related Topics:**
632
- - [Repository Mixins](./mixins) - Soft delete and auditing
647
+ - [Repository Mixins](./mixins) - Composable mixin features
633
648
  - [Relations & Includes](./relations) - Loading related data
634
649
  - [Filter System](/references/base/filter-system/) - Query operators
635
650