@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.
- package/dist/mcp-server/common/paths.d.ts +4 -2
- package/dist/mcp-server/common/paths.d.ts.map +1 -1
- package/dist/mcp-server/common/paths.js +8 -6
- package/dist/mcp-server/common/paths.js.map +1 -1
- package/dist/mcp-server/tools/docs/get-document-content.tool.d.ts +1 -1
- package/dist/mcp-server/tools/docs/get-document-content.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/docs/get-document-content.tool.js +7 -7
- package/dist/mcp-server/tools/docs/get-document-metadata.tool.js +3 -3
- package/dist/mcp-server/tools/docs/get-package-overview.tool.d.ts +1 -1
- package/dist/mcp-server/tools/docs/get-package-overview.tool.js +1 -1
- package/package.json +1 -1
- package/wiki/best-practices/api-usage-examples.md +9 -9
- package/wiki/best-practices/architectural-patterns.md +19 -3
- package/wiki/best-practices/architecture-decisions.md +6 -6
- package/wiki/best-practices/code-style-standards/advanced-patterns.md +1 -1
- package/wiki/best-practices/code-style-standards/control-flow.md +1 -1
- package/wiki/best-practices/code-style-standards/function-patterns.md +2 -2
- package/wiki/best-practices/code-style-standards/index.md +2 -2
- package/wiki/best-practices/code-style-standards/naming-conventions.md +1 -1
- package/wiki/best-practices/code-style-standards/route-definitions.md +4 -4
- package/wiki/best-practices/data-modeling.md +1 -1
- package/wiki/best-practices/deployment-strategies.md +1 -1
- package/wiki/best-practices/error-handling.md +2 -2
- package/wiki/best-practices/performance-optimization.md +3 -3
- package/wiki/best-practices/security-guidelines.md +2 -2
- package/wiki/best-practices/troubleshooting-tips.md +1 -1
- package/wiki/{references → extensions}/components/authentication/api.md +12 -20
- package/wiki/{references → extensions}/components/authentication/errors.md +1 -1
- package/wiki/{references → extensions}/components/authentication/index.md +5 -8
- package/wiki/{references → extensions}/components/authentication/usage.md +20 -36
- package/wiki/{references → extensions}/components/authorization/api.md +62 -13
- package/wiki/{references → extensions}/components/authorization/errors.md +12 -7
- package/wiki/{references → extensions}/components/authorization/index.md +93 -6
- package/wiki/{references → extensions}/components/authorization/usage.md +42 -4
- package/wiki/{references → extensions}/components/health-check.md +5 -4
- package/wiki/{references → extensions}/components/index.md +2 -0
- package/wiki/{references → extensions}/components/mail/index.md +1 -1
- package/wiki/{references → extensions}/components/request-tracker.md +1 -1
- package/wiki/{references → extensions}/components/socket-io/api.md +2 -2
- package/wiki/{references → extensions}/components/socket-io/errors.md +2 -0
- package/wiki/{references → extensions}/components/socket-io/index.md +24 -20
- package/wiki/{references → extensions}/components/socket-io/usage.md +2 -2
- package/wiki/{references → extensions}/components/static-asset/api.md +14 -15
- package/wiki/{references → extensions}/components/static-asset/errors.md +3 -1
- package/wiki/{references → extensions}/components/static-asset/index.md +158 -89
- package/wiki/{references → extensions}/components/static-asset/usage.md +8 -5
- package/wiki/{references → extensions}/components/swagger.md +3 -3
- package/wiki/{references → extensions}/components/template/index.md +4 -4
- package/wiki/{references → extensions}/components/template/setup-page.md +1 -1
- package/wiki/{references → extensions}/components/template/single-page.md +1 -1
- package/wiki/{references → extensions}/components/websocket/api.md +7 -6
- package/wiki/{references → extensions}/components/websocket/errors.md +17 -3
- package/wiki/{references → extensions}/components/websocket/index.md +17 -11
- package/wiki/{references → extensions}/components/websocket/usage.md +2 -2
- package/wiki/{references → extensions}/helpers/crypto/index.md +1 -1
- package/wiki/{references → extensions}/helpers/env/index.md +9 -5
- package/wiki/{references → extensions}/helpers/error/index.md +2 -7
- package/wiki/{references → extensions}/helpers/index.md +18 -6
- package/wiki/{references → extensions}/helpers/kafka/admin.md +33 -16
- package/wiki/extensions/helpers/kafka/consumer.md +384 -0
- package/wiki/extensions/helpers/kafka/examples.md +361 -0
- package/wiki/extensions/helpers/kafka/index.md +639 -0
- package/wiki/{references → extensions}/helpers/kafka/producer.md +100 -96
- package/wiki/extensions/helpers/kafka/schema-registry.md +214 -0
- package/wiki/{references → extensions}/helpers/logger/index.md +2 -2
- package/wiki/{references → extensions}/helpers/queue/index.md +400 -4
- package/wiki/{references → extensions}/helpers/storage/api.md +170 -10
- package/wiki/{references → extensions}/helpers/storage/index.md +44 -8
- package/wiki/{references → extensions}/helpers/template/index.md +1 -1
- package/wiki/{references → extensions}/helpers/testing/index.md +4 -4
- package/wiki/{references → extensions}/helpers/types/index.md +63 -16
- package/wiki/{references → extensions}/helpers/websocket/index.md +1 -1
- package/wiki/extensions/index.md +48 -0
- package/wiki/guides/core-concepts/application/bootstrapping.md +55 -37
- package/wiki/guides/core-concepts/application/index.md +95 -35
- package/wiki/guides/core-concepts/components-guide.md +23 -19
- package/wiki/guides/core-concepts/components.md +34 -10
- package/wiki/guides/core-concepts/dependency-injection.md +99 -34
- package/wiki/guides/core-concepts/grpc-controllers.md +295 -0
- package/wiki/guides/core-concepts/persistent/datasources.md +27 -8
- package/wiki/guides/core-concepts/persistent/models.md +43 -1
- package/wiki/guides/core-concepts/persistent/repositories.md +75 -8
- package/wiki/guides/core-concepts/persistent/transactions.md +38 -8
- package/wiki/guides/core-concepts/{controllers.md → rest-controllers.md} +30 -33
- package/wiki/guides/core-concepts/services.md +19 -5
- package/wiki/guides/get-started/5-minute-quickstart.md +6 -7
- package/wiki/guides/get-started/philosophy.md +1 -1
- package/wiki/guides/index.md +2 -2
- package/wiki/guides/reference/glossary.md +7 -7
- package/wiki/guides/reference/mcp-docs-server.md +1 -1
- package/wiki/guides/tutorials/building-a-crud-api.md +2 -2
- package/wiki/guides/tutorials/complete-installation.md +17 -14
- package/wiki/guides/tutorials/ecommerce-api.md +18 -18
- package/wiki/guides/tutorials/realtime-chat.md +8 -8
- package/wiki/guides/tutorials/testing.md +2 -2
- package/wiki/index.md +4 -3
- package/wiki/references/base/application.md +341 -21
- package/wiki/references/base/bootstrapping.md +43 -13
- package/wiki/references/base/components.md +259 -8
- package/wiki/references/base/controllers.md +556 -253
- package/wiki/references/base/datasources.md +159 -79
- package/wiki/references/base/dependency-injection.md +299 -48
- package/wiki/references/base/filter-system/application-usage.md +18 -2
- package/wiki/references/base/filter-system/array-operators.md +14 -6
- package/wiki/references/base/filter-system/comparison-operators.md +9 -3
- package/wiki/references/base/filter-system/default-filter.md +28 -3
- package/wiki/references/base/filter-system/fields-order-pagination.md +17 -13
- package/wiki/references/base/filter-system/index.md +169 -11
- package/wiki/references/base/filter-system/json-filtering.md +51 -18
- package/wiki/references/base/filter-system/list-operators.md +4 -3
- package/wiki/references/base/filter-system/logical-operators.md +7 -2
- package/wiki/references/base/filter-system/null-operators.md +50 -0
- package/wiki/references/base/filter-system/quick-reference.md +82 -243
- package/wiki/references/base/filter-system/range-operators.md +7 -1
- package/wiki/references/base/filter-system/tips.md +34 -7
- package/wiki/references/base/filter-system/use-cases.md +6 -5
- package/wiki/references/base/grpc-controllers.md +984 -0
- package/wiki/references/base/index.md +32 -24
- package/wiki/references/base/middleware.md +347 -0
- package/wiki/references/base/models.md +390 -46
- package/wiki/references/base/providers.md +14 -14
- package/wiki/references/base/repositories/advanced.md +84 -69
- package/wiki/references/base/repositories/index.md +447 -12
- package/wiki/references/base/repositories/mixins.md +103 -98
- package/wiki/references/base/repositories/relations.md +129 -45
- package/wiki/references/base/repositories/soft-deletable.md +104 -23
- package/wiki/references/base/services.md +94 -14
- package/wiki/references/index.md +12 -10
- package/wiki/references/quick-reference.md +98 -65
- package/wiki/references/utilities/crypto.md +21 -4
- package/wiki/references/utilities/date.md +25 -7
- package/wiki/references/utilities/index.md +26 -24
- package/wiki/references/utilities/jsx.md +54 -54
- package/wiki/references/utilities/module.md +8 -6
- package/wiki/references/utilities/parse.md +16 -9
- package/wiki/references/utilities/performance.md +22 -7
- package/wiki/references/utilities/promise.md +19 -16
- package/wiki/references/utilities/request.md +48 -26
- package/wiki/references/utilities/schema.md +69 -6
- package/wiki/references/utilities/statuses.md +131 -140
- package/wiki/references/helpers/kafka/consumer.md +0 -473
- package/wiki/references/helpers/kafka/examples.md +0 -234
- package/wiki/references/helpers/kafka/index.md +0 -482
- /package/wiki/{references → extensions}/components/mail/api.md +0 -0
- /package/wiki/{references → extensions}/components/mail/errors.md +0 -0
- /package/wiki/{references → extensions}/components/mail/usage.md +0 -0
- /package/wiki/{references → extensions}/components/template/api-page.md +0 -0
- /package/wiki/{references → extensions}/components/template/errors-page.md +0 -0
- /package/wiki/{references → extensions}/components/template/usage-page.md +0 -0
- /package/wiki/{references → extensions}/helpers/cron/index.md +0 -0
- /package/wiki/{references → extensions}/helpers/inversion/index.md +0 -0
- /package/wiki/{references → extensions}/helpers/network/api.md +0 -0
- /package/wiki/{references → extensions}/helpers/network/index.md +0 -0
- /package/wiki/{references → extensions}/helpers/redis/index.md +0 -0
- /package/wiki/{references → extensions}/helpers/socket-io/api.md +0 -0
- /package/wiki/{references → extensions}/helpers/socket-io/index.md +0 -0
- /package/wiki/{references → extensions}/helpers/template/single-page.md +0 -0
- /package/wiki/{references → extensions}/helpers/uid/index.md +0 -0
- /package/wiki/{references → extensions}/helpers/websocket/api.md +0 -0
- /package/wiki/{references → extensions}/helpers/worker-thread/index.md +0 -0
- /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-
|
|
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
|
-
|
|
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:
|
|
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('[
|
|
483
|
+
this.logger.info('[%s][=>] %s %s', requestId, method, path);
|
|
483
484
|
|
|
484
485
|
await next();
|
|
485
486
|
|
|
486
|
-
|
|
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
|
-
- [
|
|
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
|
-
//
|
|
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
|
-
|
|
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
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
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)
|
|
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
|
-
//
|
|
376
|
+
// Throws error - empty where without force
|
|
381
377
|
await repo.deleteAll({ where: {} });
|
|
382
378
|
|
|
383
|
-
//
|
|
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
|
-
|
|
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
|
-
|
|
395
|
+
### Transaction Safety
|
|
399
396
|
|
|
400
|
-
|
|
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
|
-
|
|
410
|
-
|
|
411
|
-
|
|
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` |
|
|
450
|
-
| `ReadableRepository` | Read-only operations (find
|
|
451
|
-
| `PersistableRepository` | Adds write operations (create
|
|
452
|
-
| `DefaultCRUDRepository` |
|
|
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:**
|
|
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'
|
|
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:**
|
|
592
|
-
- **Validation:**
|
|
593
|
-
- **Values:** Values are
|
|
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) -
|
|
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
|
|