@venizia/ignis-docs 0.0.8 → 0.2.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 +7 -7
- package/content/best-practices/api-usage-examples.md +15 -12
- package/content/best-practices/architectural-patterns.md +70 -78
- package/content/best-practices/architecture-decisions.md +91 -60
- package/content/best-practices/code-style-standards/advanced-patterns.md +56 -44
- package/content/best-practices/code-style-standards/constants-configuration.md +11 -11
- package/content/best-practices/code-style-standards/control-flow.md +5 -2
- package/content/best-practices/code-style-standards/documentation.md +13 -13
- package/content/best-practices/code-style-standards/function-patterns.md +9 -10
- package/content/best-practices/code-style-standards/index.md +1 -1
- package/content/best-practices/code-style-standards/naming-conventions.md +10 -8
- package/content/best-practices/code-style-standards/route-definitions.md +30 -12
- package/content/best-practices/code-style-standards/tooling.md +8 -5
- package/content/best-practices/code-style-standards/type-safety.md +13 -12
- package/content/best-practices/common-pitfalls.md +56 -37
- package/content/best-practices/contribution-workflow.md +13 -14
- package/content/best-practices/data-modeling.md +46 -22
- package/content/best-practices/deployment-strategies.md +28 -27
- package/content/best-practices/error-handling.md +48 -24
- package/content/best-practices/index.md +5 -5
- package/content/best-practices/performance-optimization.md +40 -31
- package/content/best-practices/security-guidelines.md +52 -23
- package/content/best-practices/testing-strategies.md +65 -51
- package/content/best-practices/troubleshooting-tips.md +24 -24
- package/content/extensions/components/{swagger.md → api-reference.md} +40 -31
- package/content/extensions/components/authentication/api.md +19 -19
- package/content/extensions/components/authentication/errors.md +7 -7
- package/content/extensions/components/authentication/index.md +10 -8
- package/content/extensions/components/authentication/usage.md +101 -6
- package/content/extensions/components/authorization/api.md +45 -25
- package/content/extensions/components/authorization/errors.md +6 -6
- package/content/extensions/components/authorization/index.md +11 -10
- package/content/extensions/components/authorization/usage.md +21 -21
- package/content/extensions/components/health-check.md +1 -1
- package/content/extensions/components/index.md +5 -5
- package/content/extensions/components/mail/errors.md +15 -15
- package/content/extensions/components/mail/index.md +1 -2
- package/content/extensions/components/mail/usage.md +1 -1
- package/content/extensions/components/request-tracker.md +1 -1
- package/content/extensions/components/socket-io/api.md +9 -9
- package/content/extensions/components/socket-io/errors.md +5 -5
- package/content/extensions/components/socket-io/index.md +8 -8
- package/content/extensions/components/socket-io/usage.md +1 -1
- package/content/extensions/components/static-asset/api.md +17 -4
- package/content/extensions/components/static-asset/errors.md +4 -4
- package/content/extensions/components/static-asset/index.md +26 -28
- package/content/extensions/components/static-asset/usage.md +13 -12
- package/content/extensions/components/template/index.md +2 -2
- package/content/extensions/components/template/setup-page.md +1 -1
- package/content/extensions/components/websocket/api.md +3 -3
- package/content/extensions/components/websocket/errors.md +5 -5
- package/content/extensions/components/websocket/index.md +5 -5
- package/content/extensions/components/websocket/usage.md +3 -3
- package/content/extensions/helpers/cron/index.md +2 -2
- package/content/extensions/helpers/crypto/index.md +1 -1
- package/content/extensions/helpers/env/index.md +27 -12
- package/content/extensions/helpers/error/index.md +81 -25
- package/content/extensions/helpers/index.md +2 -3
- package/content/extensions/helpers/inversion/index.md +15 -7
- package/content/extensions/helpers/kafka/compile-binary.md +92 -0
- package/content/extensions/helpers/kafka/examples.md +1 -1
- package/content/extensions/helpers/kafka/index.md +3 -0
- package/content/extensions/helpers/logger/index.md +32 -2
- package/content/extensions/helpers/network/index.md +6 -0
- package/content/extensions/helpers/queue/index.md +14 -17
- package/content/extensions/helpers/redis/index.md +548 -323
- package/content/extensions/helpers/socket-io/index.md +14 -10
- package/content/extensions/helpers/storage/api.md +44 -8
- package/content/extensions/helpers/storage/index.md +43 -7
- package/content/extensions/helpers/template/index.md +6 -3
- package/content/extensions/helpers/types/index.md +11 -8
- package/content/extensions/helpers/websocket/api.md +9 -9
- package/content/extensions/helpers/websocket/index.md +7 -7
- package/content/extensions/helpers/worker-thread/index.md +2 -2
- package/content/extensions/index.md +3 -4
- package/content/extensions/src-details/mcp-server.md +18 -24
- package/content/guides/core-concepts/application/bootstrapping.md +11 -14
- package/content/guides/core-concepts/application/index.md +3 -3
- package/content/guides/core-concepts/components.md +19 -10
- package/content/guides/core-concepts/dependency-injection.md +6 -3
- package/content/guides/core-concepts/grpc-controllers.md +6 -5
- package/content/guides/core-concepts/persistent/datasources.md +42 -43
- package/content/guides/core-concepts/persistent/index.md +16 -7
- package/content/guides/core-concepts/persistent/models.md +24 -20
- package/content/guides/core-concepts/persistent/postgres-drivers.md +201 -0
- package/content/guides/core-concepts/persistent/repositories.md +40 -23
- package/content/guides/core-concepts/persistent/search-meilisearch.md +185 -0
- package/content/guides/core-concepts/persistent/search-typesense.md +431 -0
- package/content/guides/core-concepts/persistent/transactions.md +61 -25
- package/content/guides/core-concepts/rest-controllers.md +12 -9
- package/content/guides/core-concepts/services.md +330 -60
- package/content/guides/get-started/5-minute-quickstart.md +15 -15
- package/content/guides/get-started/philosophy.md +36 -36
- package/content/guides/get-started/setup.md +3 -3
- package/content/guides/index.md +3 -3
- package/content/guides/migrations/redis-helpers-migration.md +177 -0
- package/content/guides/migrations/scoped-rbac-migration.md +17 -17
- package/content/guides/migrations/unified-connectors-migration.md +113 -0
- package/content/guides/reference/glossary.md +19 -12
- package/content/guides/reference/mcp-docs-server.md +22 -18
- package/content/guides/tutorials/building-a-crud-api.md +37 -44
- package/content/guides/tutorials/complete-installation.md +17 -17
- package/content/guides/tutorials/ecommerce-api.md +163 -124
- package/content/guides/tutorials/realtime-chat.md +181 -135
- package/content/guides/tutorials/testing.md +65 -523
- package/content/index.md +2 -180
- package/content/public/apple-touch-icon.png +0 -0
- package/content/public/og-image.png +0 -0
- package/content/public/site.webmanifest +11 -0
- package/content/references/base/application.md +4 -5
- package/content/references/base/bootstrapping.md +18 -5
- package/content/references/base/components.md +149 -120
- package/content/references/base/connectors.md +178 -0
- package/content/references/base/controllers.md +41 -30
- package/content/references/base/datasources.md +163 -92
- package/content/references/base/dependency-injection.md +34 -22
- package/content/references/base/filter-system/application-usage.md +17 -14
- package/content/references/base/filter-system/array-operators.md +7 -2
- package/content/references/base/filter-system/comparison-operators.md +3 -0
- package/content/references/base/filter-system/default-filter.md +89 -71
- package/content/references/base/filter-system/fields-order-pagination.md +22 -22
- package/content/references/base/filter-system/index.md +6 -3
- package/content/references/base/filter-system/json-filtering.md +20 -1
- package/content/references/base/filter-system/list-operators.md +1 -1
- package/content/references/base/filter-system/logical-operators.md +33 -1
- package/content/references/base/filter-system/null-operators.md +30 -1
- package/content/references/base/filter-system/quick-reference.md +23 -4
- package/content/references/base/filter-system/tips.md +5 -5
- package/content/references/base/filter-system/use-cases.md +12 -12
- package/content/references/base/grpc-controllers.md +13 -13
- package/content/references/base/index.md +24 -12
- package/content/references/base/middlewares.md +265 -327
- package/content/references/base/models.md +63 -49
- package/content/references/base/providers.md +136 -130
- package/content/references/base/repositories/advanced.md +59 -58
- package/content/references/base/repositories/index.md +115 -91
- package/content/references/base/repositories/mixins.md +55 -291
- package/content/references/base/repositories/relations.md +54 -64
- package/content/references/base/repositories/soft-deletable.md +31 -30
- package/content/references/base/services.md +296 -93
- package/content/references/configuration/environment-variables.md +49 -31
- package/content/references/configuration/index.md +6 -6
- package/content/references/index.md +17 -12
- package/content/references/quick-reference.md +65 -106
- package/content/references/utilities/crypto.md +65 -23
- package/content/references/utilities/index.md +3 -3
- package/content/references/utilities/jsx.md +6 -4
- package/content/references/utilities/module.md +68 -20
- package/content/references/utilities/parse.md +4 -14
- package/content/references/utilities/promise.md +9 -7
- package/content/references/utilities/schema.md +5 -3
- package/dist/mcp-server/common/guards.d.ts +8 -0
- package/dist/mcp-server/common/guards.d.ts.map +1 -0
- package/dist/mcp-server/common/guards.js +14 -0
- package/dist/mcp-server/common/guards.js.map +1 -0
- package/dist/mcp-server/common/index.d.ts +1 -0
- package/dist/mcp-server/common/index.d.ts.map +1 -1
- package/dist/mcp-server/common/index.js +1 -0
- package/dist/mcp-server/common/index.js.map +1 -1
- package/dist/mcp-server/helpers/docs.helper.d.ts.map +1 -1
- package/dist/mcp-server/helpers/docs.helper.js +4 -2
- package/dist/mcp-server/helpers/docs.helper.js.map +1 -1
- package/dist/mcp-server/helpers/github.helper.js +1 -1
- package/dist/mcp-server/index.js +7 -2
- package/dist/mcp-server/index.js.map +1 -1
- package/dist/mcp-server/tools/base.tool.d.ts +6 -2
- package/dist/mcp-server/tools/base.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/base.tool.js.map +1 -1
- package/dist/mcp-server/tools/docs/search-documents.tool.d.ts +1 -1
- package/dist/mcp-server/tools/github/list-project-files.tool.d.ts +1 -1
- package/dist/mcp-server/tools/github/search-code.tool.d.ts +1 -1
- package/dist/mcp-server/tools/github/search-code.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/github/search-code.tool.js +4 -1
- package/dist/mcp-server/tools/github/search-code.tool.js.map +1 -1
- package/dist/mcp-server/tools/github/verify-dependencies.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/github/verify-dependencies.tool.js +3 -1
- package/dist/mcp-server/tools/github/verify-dependencies.tool.js.map +1 -1
- package/package.json +9 -9
- package/content/extensions/helpers/testing/index.md +0 -510
- package/content/references/base/middleware.md +0 -347
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
# Repositories Overview
|
|
2
2
|
|
|
3
|
-
Repositories are the data access layer in
|
|
3
|
+
Repositories are the data access layer in IGNIS - they provide type-safe CRUD operations for your database entities.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
> [!IMPORTANT] Base vs. Connectors
|
|
6
|
+
> `AbstractRepository` (`packages/core/src/base/repositories/core/abstract.ts`) is the engine-neutral root shared by both connectors - it declares the CRUD contract but has no Drizzle, SQL, or mixin composition. The concrete classes documented on this page (`ReadableRepository`, `PersistableRepository`, `DefaultCRUDRepository`, `SoftDeletableRepository`) belong to the **PostgreSQL connector**, built on `PostgresBaseRepository`. Typesense has its own parallel tier - see [Connectors](/references/base/connectors) and [Search & Typesense](/guides/core-concepts/persistent/search-typesense).
|
|
7
|
+
|
|
8
|
+
**Files:** `packages/core/src/base/repositories/core/abstract.ts` (neutral) and `packages/core/src/connectors/postgres/repositories/core/*.ts` (PostgreSQL)
|
|
6
9
|
|
|
7
10
|
|
|
8
11
|
## Quick Start
|
|
@@ -25,7 +28,7 @@ export class TodoRepository extends DefaultCRUDRepository<typeof Todo.schema> {
|
|
|
25
28
|
|
|
26
29
|
| Class | Capabilities | Use Case |
|
|
27
30
|
|-------|--------------|----------|
|
|
28
|
-
| **AbstractRepository** |
|
|
31
|
+
| **AbstractRepository** | Engine-neutral base class with lazy dataSource/entity resolution and @model settings getters | Extend for custom repositories |
|
|
29
32
|
| **ReadableRepository** | Read-only operations (write methods throw errors) | Views, external tables, read-only access |
|
|
30
33
|
| **PersistableRepository** | Read + Write operations | Full CRUD access |
|
|
31
34
|
| **DefaultCRUDRepository** | Extends PersistableRepository (no additions) | Standard data tables (recommended) |
|
|
@@ -37,19 +40,22 @@ export class TodoRepository extends DefaultCRUDRepository<typeof Todo.schema> {
|
|
|
37
40
|
|
|
38
41
|
```
|
|
39
42
|
BaseHelper
|
|
40
|
-
|
|
41
|
-
+ DefaultFilterMixin
|
|
42
|
-
= AbstractRepository (abstract base, declares all CRUD signatures)
|
|
43
|
+
= AbstractRepository (engine-neutral abstract base, declares all CRUD signatures, src/base)
|
|
43
44
|
|
|
|
44
|
-
+--
|
|
45
|
+
+-- PostgresBaseRepository (PostgreSQL connector; hidden-fields + default-filter logic, no mixins)
|
|
45
46
|
|
|
|
46
|
-
+--
|
|
47
|
+
+-- ReadableRepository (implements read ops; write ops throw errors)
|
|
47
48
|
|
|
|
48
|
-
+--
|
|
49
|
+
+-- PersistableRepository (implements write + delete ops, READ_WRITE scope)
|
|
49
50
|
|
|
|
50
|
-
+--
|
|
51
|
+
+-- DefaultCRUDRepository (empty subclass, recommended entry point)
|
|
52
|
+
|
|
|
53
|
+
+-- SoftDeletableRepository (overrides delete with soft-delete)
|
|
51
54
|
```
|
|
52
55
|
|
|
56
|
+
> [!NOTE]
|
|
57
|
+
> Prior to the connectors restructure, `AbstractRepository` composed `FieldsVisibilityMixin`/`DefaultFilterMixin` directly onto `BaseHelper`. Those mixins have been **removed** - see [Repository Mixins](./mixins) - and the equivalent behavior lives in `AbstractRepository`'s settings getters and `PostgresBaseRepository` instead.
|
|
58
|
+
|
|
53
59
|
### Type Parameters
|
|
54
60
|
|
|
55
61
|
All repository classes share the same four type parameters:
|
|
@@ -59,7 +65,7 @@ class DefaultCRUDRepository<
|
|
|
59
65
|
EntitySchema extends TTableSchemaWithId = TTableSchemaWithId,
|
|
60
66
|
DataObject extends TTableObject<EntitySchema> = TTableObject<EntitySchema>,
|
|
61
67
|
PersistObject extends TTableInsert<EntitySchema> = TTableInsert<EntitySchema>,
|
|
62
|
-
ExtraOptions extends IExtraOptions =
|
|
68
|
+
ExtraOptions extends IExtraOptions = IDatabaseExtraOptions,
|
|
63
69
|
>
|
|
64
70
|
```
|
|
65
71
|
|
|
@@ -68,7 +74,7 @@ class DefaultCRUDRepository<
|
|
|
68
74
|
| `EntitySchema` | The Drizzle `pgTable` schema type (e.g., `typeof User.schema`) |
|
|
69
75
|
| `DataObject` | The inferred SELECT type from the schema |
|
|
70
76
|
| `PersistObject` | The inferred INSERT type from the schema |
|
|
71
|
-
| `ExtraOptions` | Extra options for operations (defaults to `IExtraOptions`) |
|
|
77
|
+
| `ExtraOptions` | Extra options for operations (defaults to `IDatabaseExtraOptions`, which narrows `IExtraOptions.transaction` to `IDatabaseTransaction`) |
|
|
72
78
|
|
|
73
79
|
|
|
74
80
|
## Available Methods
|
|
@@ -76,24 +82,24 @@ class DefaultCRUDRepository<
|
|
|
76
82
|
### Read Operations
|
|
77
83
|
| Method | Description | Example |
|
|
78
84
|
|--------|-------------|---------|
|
|
79
|
-
| `find(opts)` | Find multiple records | `
|
|
80
|
-
| `find(opts)` with range | Find with pagination range | `
|
|
81
|
-
| `findOne(opts)` | Find single record | `
|
|
82
|
-
| `findById(opts)` | Find by primary key | `
|
|
83
|
-
| `count(opts)` | Count matching records | `
|
|
84
|
-
| `existsWith(opts)` | Check if exists | `
|
|
85
|
+
| `find(opts)` | Find multiple records | `repository.find({ filter: { where: { status: 'active' } } })` |
|
|
86
|
+
| `find(opts)` with range | Find with pagination range | `repository.find({ filter, options: { shouldQueryRange: true } })` |
|
|
87
|
+
| `findOne(opts)` | Find single record | `repository.findOne({ filter: { where: { email } } })` |
|
|
88
|
+
| `findById(opts)` | Find by primary key | `repository.findById({ id: '123' })` |
|
|
89
|
+
| `count(opts)` | Count matching records | `repository.count({ where: { status: 'active' } })` |
|
|
90
|
+
| `existsWith(opts)` | Check if exists | `repository.existsWith({ where: { email } })` |
|
|
85
91
|
|
|
86
92
|
### Write Operations
|
|
87
93
|
| Method | Description | Example |
|
|
88
94
|
|--------|-------------|---------|
|
|
89
|
-
| `create(opts)` | Create single record | `
|
|
90
|
-
| `createAll(opts)` | Create multiple records | `
|
|
91
|
-
| `updateById(opts)` | Update by primary key | `
|
|
92
|
-
| `updateAll(opts)` | Update matching records | `
|
|
93
|
-
| `updateBy(opts)` | Alias for `updateAll` | `
|
|
94
|
-
| `deleteById(opts)` | Delete by primary key | `
|
|
95
|
-
| `deleteAll(opts)` | Delete matching records | `
|
|
96
|
-
| `deleteBy(opts)` | Alias for `deleteAll` | `
|
|
95
|
+
| `create(opts)` | Create single record | `repository.create({ data: { title: 'New' } })` |
|
|
96
|
+
| `createAll(opts)` | Create multiple records | `repository.createAll({ data: [{ title: 'A' }, { title: 'B' }] })` |
|
|
97
|
+
| `updateById(opts)` | Update by primary key | `repository.updateById({ id: '123', data: { title: 'Updated' } })` |
|
|
98
|
+
| `updateAll(opts)` | Update matching records | `repository.updateAll({ data: { status: 'published' }, where: { status: 'draft' } })` |
|
|
99
|
+
| `updateBy(opts)` | Alias for `updateAll` | `repository.updateBy({ data: { status: 'published' }, where: { status: 'draft' } })` |
|
|
100
|
+
| `deleteById(opts)` | Delete by primary key | `repository.deleteById({ id: '123' })` |
|
|
101
|
+
| `deleteAll(opts)` | Delete matching records | `repository.deleteAll({ where: { status: 'archived' } })` |
|
|
102
|
+
| `deleteBy(opts)` | Alias for `deleteAll` | `repository.deleteBy({ where: { status: 'archived' } })` |
|
|
97
103
|
|
|
98
104
|
|
|
99
105
|
## Method Signatures
|
|
@@ -230,7 +236,7 @@ All repository operations accept an `options` parameter with these fields:
|
|
|
230
236
|
|
|
231
237
|
```typescript
|
|
232
238
|
interface IExtraOptions {
|
|
233
|
-
/** Transaction context
|
|
239
|
+
/** Transaction context - switches the underlying Drizzle connector. */
|
|
234
240
|
transaction?: ITransaction;
|
|
235
241
|
|
|
236
242
|
/** Operation logging configuration. */
|
|
@@ -238,9 +244,15 @@ interface IExtraOptions {
|
|
|
238
244
|
|
|
239
245
|
/** If true, bypass the default filter configured in model settings (e.g., soft delete). */
|
|
240
246
|
shouldSkipDefaultFilter?: boolean;
|
|
247
|
+
|
|
248
|
+
/** Row-level locking (requires transaction, incompatible with Query API). */
|
|
249
|
+
lock?: TLockOptions;
|
|
241
250
|
}
|
|
242
251
|
```
|
|
243
252
|
|
|
253
|
+
> [!NOTE]
|
|
254
|
+
> Postgres narrows this via `IDatabaseExtraOptions` (`connectors/postgres/repositories/common`), which overrides `transaction` to `IDatabaseTransaction` so `options.transaction.connector` needs no cast.
|
|
255
|
+
|
|
244
256
|
Additional fields are available as intersections on specific methods:
|
|
245
257
|
|
|
246
258
|
| Field | Type | Methods | Description |
|
|
@@ -263,16 +275,21 @@ type TDataRange = {
|
|
|
263
275
|
```
|
|
264
276
|
|
|
265
277
|
|
|
266
|
-
## AbstractRepository Properties
|
|
278
|
+
## AbstractRepository / PostgresBaseRepository Properties
|
|
267
279
|
|
|
268
280
|
### dataSource
|
|
269
281
|
|
|
270
282
|
Getter/setter for the repository's datasource. Throws if accessed before being set (either via constructor or `@repository` auto-injection).
|
|
271
283
|
|
|
272
284
|
```typescript
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
285
|
+
// AbstractRepository (engine-neutral, src/base)
|
|
286
|
+
get dataSource(): AbstractDataSource;
|
|
287
|
+
set dataSource(value: AbstractDataSource);
|
|
288
|
+
setDataSource(opts: { dataSource: AbstractDataSource }): void;
|
|
289
|
+
|
|
290
|
+
// PostgresBaseRepository narrows the return type
|
|
291
|
+
get dataSource(): IPostgresDataSource;
|
|
292
|
+
set dataSource(value: IPostgresDataSource);
|
|
276
293
|
```
|
|
277
294
|
|
|
278
295
|
### entity
|
|
@@ -280,12 +297,19 @@ setDataSource(opts: { dataSource: IDataSource }): void;
|
|
|
280
297
|
Lazy-resolved from `@repository` metadata on first access. Can also be set explicitly via constructor `entityClass` option.
|
|
281
298
|
|
|
282
299
|
```typescript
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
300
|
+
// AbstractRepository
|
|
301
|
+
get entity(): AbstractEntity;
|
|
302
|
+
set entity(value: AbstractEntity);
|
|
303
|
+
getEntity(): AbstractEntity;
|
|
304
|
+
|
|
305
|
+
// PostgresBaseRepository narrows the return type
|
|
306
|
+
get entity(): BasePostgresEntity<EntitySchema>;
|
|
307
|
+
set entity(value: BasePostgresEntity<EntitySchema>);
|
|
286
308
|
getEntitySchema(): EntitySchema;
|
|
287
309
|
```
|
|
288
310
|
|
|
311
|
+
`BaseEntity` is a compatibility alias re-exported for `BasePostgresEntity` - prefer `BasePostgresEntity` in new code.
|
|
312
|
+
|
|
289
313
|
### operationScope
|
|
290
314
|
|
|
291
315
|
Returns the repository's operation scope: `'READ_ONLY'`, `'WRITE_ONLY'`, or `'READ_WRITE'`.
|
|
@@ -297,21 +321,21 @@ get operationScope(): TRepositoryOperationScope;
|
|
|
297
321
|
- `ReadableRepository` defaults to `READ_ONLY`
|
|
298
322
|
- `PersistableRepository` and `DefaultCRUDRepository` default to `READ_WRITE`
|
|
299
323
|
|
|
300
|
-
### filterBuilder
|
|
324
|
+
### filterBuilder (PostgresBaseRepository+)
|
|
301
325
|
|
|
302
|
-
Access to the `FilterBuilder` instance used for converting filter objects to Drizzle SQL.
|
|
326
|
+
Access to the `FilterBuilder` instance used for converting filter objects to Drizzle SQL. Not present on the engine-neutral `AbstractRepository`.
|
|
303
327
|
|
|
304
328
|
```typescript
|
|
305
329
|
get filterBuilder(): FilterBuilder;
|
|
306
330
|
```
|
|
307
331
|
|
|
308
|
-
### connector
|
|
332
|
+
### connector (PostgresBaseRepository+)
|
|
309
333
|
|
|
310
|
-
Shortcut for `this.dataSource.connector`.
|
|
334
|
+
Shortcut for `this.dataSource.connector`. Not present on the engine-neutral `AbstractRepository`.
|
|
311
335
|
|
|
312
336
|
```typescript
|
|
313
|
-
get connector():
|
|
314
|
-
getConnector():
|
|
337
|
+
get connector(): IPostgresDataSource['connector'];
|
|
338
|
+
getConnector(): IPostgresDataSource['connector'];
|
|
315
339
|
```
|
|
316
340
|
|
|
317
341
|
### updateBuilder (PersistableRepository+)
|
|
@@ -325,21 +349,21 @@ get updateBuilder(): UpdateBuilder;
|
|
|
325
349
|
|
|
326
350
|
## Key Methods
|
|
327
351
|
|
|
328
|
-
### beginTransaction
|
|
352
|
+
### beginTransaction (PostgresBaseRepository+)
|
|
329
353
|
|
|
330
|
-
|
|
354
|
+
Delegates to the repository's datasource. Not present on the engine-neutral `AbstractRepository` - each connector adds it with its own transaction type (or omits it, like typesense).
|
|
331
355
|
|
|
332
356
|
```typescript
|
|
333
|
-
|
|
357
|
+
beginTransaction(opts?: IDatabaseTransactionOptions): Promise<IDatabaseTransaction>;
|
|
334
358
|
```
|
|
335
359
|
|
|
336
360
|
Usage:
|
|
337
361
|
|
|
338
362
|
```typescript
|
|
339
|
-
const tx = await
|
|
363
|
+
const tx = await repository.beginTransaction();
|
|
340
364
|
try {
|
|
341
|
-
await
|
|
342
|
-
await
|
|
365
|
+
await repository.create({ data: { name: 'John' }, options: { transaction: tx } });
|
|
366
|
+
await repository.updateById({ id: '456', data: { count: 1 }, options: { transaction: tx } });
|
|
343
367
|
await tx.commit();
|
|
344
368
|
} catch (e) {
|
|
345
369
|
await tx.rollback();
|
|
@@ -379,10 +403,10 @@ The selection is automatic based on filter complexity:
|
|
|
379
403
|
|
|
380
404
|
```typescript
|
|
381
405
|
// Uses Core API (no include, no fields)
|
|
382
|
-
await
|
|
406
|
+
await repository.find({ filter: { where: { status: 'active' }, limit: 10 } });
|
|
383
407
|
|
|
384
408
|
// Uses Query API (has include)
|
|
385
|
-
await
|
|
409
|
+
await repository.find({
|
|
386
410
|
filter: {
|
|
387
411
|
where: { status: 'active' },
|
|
388
412
|
include: [{ relation: 'posts' }],
|
|
@@ -390,7 +414,7 @@ await repo.find({
|
|
|
390
414
|
});
|
|
391
415
|
|
|
392
416
|
// Uses Query API (has fields)
|
|
393
|
-
await
|
|
417
|
+
await repository.find({
|
|
394
418
|
filter: {
|
|
395
419
|
fields: { id: true, name: true },
|
|
396
420
|
where: { status: 'active' },
|
|
@@ -405,37 +429,37 @@ await repo.find({
|
|
|
405
429
|
|
|
406
430
|
```typescript
|
|
407
431
|
constructor(
|
|
408
|
-
|
|
432
|
+
dataSource?: AbstractDataSource,
|
|
409
433
|
opts?: {
|
|
410
434
|
scope?: string;
|
|
411
|
-
entityClass?: TClass<
|
|
435
|
+
entityClass?: TClass<AbstractEntity>;
|
|
412
436
|
operationScope?: TRepositoryOperationScope;
|
|
413
437
|
},
|
|
414
438
|
)
|
|
415
439
|
```
|
|
416
440
|
|
|
417
|
-
- `
|
|
441
|
+
- `dataSource` -- DataSource instance (optional; auto-injected by `@repository` decorator)
|
|
418
442
|
- `opts.scope` -- Logger scope name (defaults to class name)
|
|
419
443
|
- `opts.entityClass` -- Entity class to instantiate (optional; lazy-resolved from `@repository` metadata)
|
|
420
444
|
- `opts.operationScope` -- Defaults to `READ_ONLY`
|
|
421
445
|
|
|
422
|
-
### ReadableRepository
|
|
446
|
+
### ReadableRepository (PostgreSQL)
|
|
423
447
|
|
|
424
448
|
```typescript
|
|
425
449
|
constructor(
|
|
426
|
-
ds?:
|
|
427
|
-
opts?: { entityClass?: TClass<
|
|
450
|
+
ds?: IPostgresDataSource,
|
|
451
|
+
opts?: { entityClass?: TClass<BasePostgresEntity<EntitySchema>> },
|
|
428
452
|
)
|
|
429
453
|
```
|
|
430
454
|
|
|
431
455
|
Forces `operationScope` to `READ_ONLY`.
|
|
432
456
|
|
|
433
|
-
### PersistableRepository
|
|
457
|
+
### PersistableRepository (PostgreSQL)
|
|
434
458
|
|
|
435
459
|
```typescript
|
|
436
460
|
constructor(
|
|
437
|
-
ds?:
|
|
438
|
-
opts?: { entityClass?: TClass<
|
|
461
|
+
ds?: IPostgresDataSource,
|
|
462
|
+
opts?: { entityClass?: TClass<BasePostgresEntity<EntitySchema>> },
|
|
439
463
|
)
|
|
440
464
|
```
|
|
441
465
|
|
|
@@ -451,7 +475,7 @@ Complete reference for querying data - operators, JSON filtering, array operator
|
|
|
451
475
|
|
|
452
476
|
```typescript
|
|
453
477
|
// Preview
|
|
454
|
-
await
|
|
478
|
+
await repository.find({
|
|
455
479
|
filter: {
|
|
456
480
|
where: {
|
|
457
481
|
status: 'active',
|
|
@@ -470,7 +494,7 @@ Fetch related data using `include` for eager loading and nested queries.
|
|
|
470
494
|
|
|
471
495
|
```typescript
|
|
472
496
|
// Preview
|
|
473
|
-
await
|
|
497
|
+
await repository.find({
|
|
474
498
|
filter: {
|
|
475
499
|
include: [{
|
|
476
500
|
relation: 'posts',
|
|
@@ -489,11 +513,11 @@ Soft-delete and restore operations using `deletedAt` timestamps instead of physi
|
|
|
489
513
|
export class CategoryRepository extends SoftDeletableRepository<typeof Category.schema> {}
|
|
490
514
|
|
|
491
515
|
// Soft delete (sets deletedAt)
|
|
492
|
-
await
|
|
516
|
+
await repository.deleteById({ id: '123' });
|
|
493
517
|
// Restore
|
|
494
|
-
await
|
|
518
|
+
await repository.restoreById({ id: '123' });
|
|
495
519
|
// Hard delete (physical removal)
|
|
496
|
-
await
|
|
520
|
+
await repository.deleteById({ id: '123', options: { shouldHardDelete: true } });
|
|
497
521
|
```
|
|
498
522
|
|
|
499
523
|
### [Advanced Features](./advanced.md)
|
|
@@ -501,17 +525,17 @@ Transactions, hidden properties, default filter bypass, performance optimization
|
|
|
501
525
|
|
|
502
526
|
```typescript
|
|
503
527
|
// Preview
|
|
504
|
-
const tx = await
|
|
528
|
+
const tx = await repository.beginTransaction();
|
|
505
529
|
try {
|
|
506
|
-
await
|
|
530
|
+
await repository.create({ data, options: { transaction: tx } });
|
|
507
531
|
await tx.commit();
|
|
508
532
|
} catch (e) {
|
|
509
533
|
await tx.rollback();
|
|
510
534
|
}
|
|
511
535
|
```
|
|
512
536
|
|
|
513
|
-
### [Repository Mixins](./mixins.md)
|
|
514
|
-
|
|
537
|
+
### [Repository Mixins (Removed)](./mixins.md)
|
|
538
|
+
Tombstone for the removed `DefaultFilterMixin` and `FieldsVisibilityMixin` - where the equivalent behavior lives now.
|
|
515
539
|
|
|
516
540
|
|
|
517
541
|
## @repository Decorator
|
|
@@ -593,12 +617,12 @@ Prevents accidental mass updates/deletes (in `PersistableRepository` and above):
|
|
|
593
617
|
|
|
594
618
|
```typescript
|
|
595
619
|
// Throws error - empty where without force flag
|
|
596
|
-
await
|
|
597
|
-
await
|
|
620
|
+
await repository.deleteAll({ where: {} });
|
|
621
|
+
await repository.updateAll({ data: { status: 'archived' }, where: {} });
|
|
598
622
|
|
|
599
623
|
// Explicitly allow with force flag (logs warning)
|
|
600
|
-
await
|
|
601
|
-
await
|
|
624
|
+
await repository.deleteAll({ where: {}, options: { force: true } });
|
|
625
|
+
await repository.updateAll({ data: { status: 'archived' }, where: {}, options: { force: true } });
|
|
602
626
|
```
|
|
603
627
|
|
|
604
628
|
| Scenario | `force: false` (default) | `force: true` |
|
|
@@ -608,7 +632,7 @@ await repo.updateAll({ data: { status: 'archived' }, where: {}, options: { force
|
|
|
608
632
|
|
|
609
633
|
### ReadableRepository Write Protection
|
|
610
634
|
|
|
611
|
-
All write methods (`create`, `createAll`, `updateById`, `updateAll`, `deleteById`, `deleteAll`) throw errors on `ReadableRepository`, enforcing the read-only scope at runtime.
|
|
635
|
+
All write methods (`create`, `createAll`, `updateById`, `updateAll`, `deleteById`, `deleteAll`) throw errors on `ReadableRepository`, enforcing the read-only scope at runtime. The thrown error carries `messageCode: 'core.repository.operation_not_allowed'` (`RepositoryErrorCodes.OPERATION_NOT_ALLOWED`).
|
|
612
636
|
|
|
613
637
|
|
|
614
638
|
## TFilter Reference
|
|
@@ -634,24 +658,24 @@ type TFilter<T = any> = {
|
|
|
634
658
|
|
|
635
659
|
| Want to... | Code |
|
|
636
660
|
|------------|------|
|
|
637
|
-
| Find all active | `
|
|
638
|
-
| Find with range info | `
|
|
639
|
-
| Find by ID | `
|
|
640
|
-
| Find with relations | `
|
|
641
|
-
| Create one | `
|
|
642
|
-
| Create without returning data | `
|
|
643
|
-
| Create many | `
|
|
644
|
-
| Update by ID | `
|
|
645
|
-
| Update by condition | `
|
|
646
|
-
| Delete by ID | `
|
|
647
|
-
| Delete by condition | `
|
|
648
|
-
| Soft delete | `
|
|
649
|
-
| Restore soft-deleted | `
|
|
650
|
-
| Hard delete (bypass soft) | `
|
|
651
|
-
| Count matching | `
|
|
652
|
-
| Check exists | `
|
|
653
|
-
| Skip default filter | `
|
|
654
|
-
| Use transaction | `
|
|
661
|
+
| Find all active | `repository.find({ filter: { where: { status: 'active' } } })` |
|
|
662
|
+
| Find with range info | `repository.find({ filter, options: { shouldQueryRange: true } })` |
|
|
663
|
+
| Find by ID | `repository.findById({ id: '123' })` |
|
|
664
|
+
| Find with relations | `repository.find({ filter: { include: [{ relation: 'posts' }] } })` |
|
|
665
|
+
| Create one | `repository.create({ data: { name: 'John' } })` |
|
|
666
|
+
| Create without returning data | `repository.create({ data: { name: 'John' }, options: { shouldReturn: false } })` |
|
|
667
|
+
| Create many | `repository.createAll({ data: [{ name: 'A' }, { name: 'B' }] })` |
|
|
668
|
+
| Update by ID | `repository.updateById({ id: '123', data: { name: 'Jane' } })` |
|
|
669
|
+
| Update by condition | `repository.updateAll({ data: { status: 'published' }, where: { status: 'draft' } })` |
|
|
670
|
+
| Delete by ID | `repository.deleteById({ id: '123' })` |
|
|
671
|
+
| Delete by condition | `repository.deleteBy({ where: { status: 'archived' } })` |
|
|
672
|
+
| Soft delete | `repository.deleteById({ id: '123' })` (with `SoftDeletableRepository`) |
|
|
673
|
+
| Restore soft-deleted | `repository.restoreById({ id: '123' })` (with `SoftDeletableRepository`) |
|
|
674
|
+
| Hard delete (bypass soft) | `repository.deleteById({ id: '123', options: { shouldHardDelete: true } })` |
|
|
675
|
+
| Count matching | `repository.count({ where: { status: 'active' } })` |
|
|
676
|
+
| Check exists | `repository.existsWith({ where: { email: 'test@example.com' } })` |
|
|
677
|
+
| Skip default filter | `repository.find({ filter, options: { shouldSkipDefaultFilter: true } })` |
|
|
678
|
+
| Use transaction | `repository.create({ data, options: { transaction: tx } })` |
|
|
655
679
|
|
|
656
680
|
|
|
657
681
|
## Next Steps
|
|
@@ -673,7 +697,7 @@ type TFilter<T = any> = {
|
|
|
673
697
|
- **Repository Topics:**
|
|
674
698
|
- [Relations & Includes](./relations) - Loading related data
|
|
675
699
|
- [Advanced Features](./advanced) - JSON updates, transactions, performance tuning
|
|
676
|
-
- [Repository Mixins](./mixins) -
|
|
700
|
+
- [Repository Mixins (Removed)](./mixins) - Where mixin behavior lives now
|
|
677
701
|
|
|
678
702
|
- **Filtering:**
|
|
679
703
|
- [Filter System Overview](/references/base/filter-system/) - Complete filtering guide
|