@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
|
@@ -24,16 +24,16 @@ Orchestrate atomic operations across multiple repositories.
|
|
|
24
24
|
### Basic Transaction
|
|
25
25
|
|
|
26
26
|
```typescript
|
|
27
|
-
const tx = await
|
|
27
|
+
const tx = await repository.beginTransaction();
|
|
28
28
|
|
|
29
29
|
try {
|
|
30
30
|
// All operations use the same transaction
|
|
31
|
-
const user = await
|
|
31
|
+
const user = await userRepository.create({
|
|
32
32
|
data: { name: 'Alice', email: 'alice@example.com' },
|
|
33
33
|
options: { transaction: tx }
|
|
34
34
|
});
|
|
35
35
|
|
|
36
|
-
const profile = await
|
|
36
|
+
const profile = await profileRepository.create({
|
|
37
37
|
data: { userId: user.data.id, bio: 'Hello!' },
|
|
38
38
|
options: { transaction: tx }
|
|
39
39
|
});
|
|
@@ -54,7 +54,7 @@ try {
|
|
|
54
54
|
Control how transactions interact with concurrent operations:
|
|
55
55
|
|
|
56
56
|
```typescript
|
|
57
|
-
const tx = await
|
|
57
|
+
const tx = await repository.beginTransaction({
|
|
58
58
|
isolationLevel: 'SERIALIZABLE'
|
|
59
59
|
});
|
|
60
60
|
```
|
|
@@ -69,25 +69,25 @@ const tx = await repo.beginTransaction({
|
|
|
69
69
|
|
|
70
70
|
```typescript
|
|
71
71
|
async function transferFunds(fromId: string, toId: string, amount: number) {
|
|
72
|
-
const tx = await
|
|
72
|
+
const tx = await accountRepository.beginTransaction();
|
|
73
73
|
|
|
74
74
|
try {
|
|
75
75
|
// Debit source account
|
|
76
|
-
await
|
|
76
|
+
await accountRepository.updateById({
|
|
77
77
|
id: fromId,
|
|
78
78
|
data: { balance: sql`balance - ${amount}` },
|
|
79
79
|
options: { transaction: tx }
|
|
80
80
|
});
|
|
81
81
|
|
|
82
82
|
// Credit destination account
|
|
83
|
-
await
|
|
83
|
+
await accountRepository.updateById({
|
|
84
84
|
id: toId,
|
|
85
85
|
data: { balance: sql`balance + ${amount}` },
|
|
86
86
|
options: { transaction: tx }
|
|
87
87
|
});
|
|
88
88
|
|
|
89
89
|
// Record the transfer
|
|
90
|
-
await
|
|
90
|
+
await transferRepository.create({
|
|
91
91
|
data: { fromId, toId, amount, status: 'completed' },
|
|
92
92
|
options: { transaction: tx }
|
|
93
93
|
});
|
|
@@ -110,11 +110,11 @@ Acquire pessimistic locks on selected rows within a transaction using PostgreSQL
|
|
|
110
110
|
Pass `lock` in options alongside a `transaction`:
|
|
111
111
|
|
|
112
112
|
```typescript
|
|
113
|
-
const tx = await
|
|
113
|
+
const tx = await repository.beginTransaction();
|
|
114
114
|
|
|
115
115
|
try {
|
|
116
|
-
// Lock the row
|
|
117
|
-
const item = await
|
|
116
|
+
// Lock the row - other transactions will wait
|
|
117
|
+
const item = await repository.findOne({
|
|
118
118
|
filter: { where: { id: '123' } },
|
|
119
119
|
options: {
|
|
120
120
|
transaction: tx,
|
|
@@ -122,8 +122,8 @@ try {
|
|
|
122
122
|
},
|
|
123
123
|
});
|
|
124
124
|
|
|
125
|
-
// Safe to modify
|
|
126
|
-
await
|
|
125
|
+
// Safe to modify - no concurrent changes possible
|
|
126
|
+
await repository.updateById({
|
|
127
127
|
id: '123',
|
|
128
128
|
data: { quantity: item.quantity - 1 },
|
|
129
129
|
options: { transaction: tx },
|
|
@@ -163,7 +163,7 @@ Control what happens when rows are already locked:
|
|
|
163
163
|
|
|
164
164
|
```typescript
|
|
165
165
|
// Skip locked rows (queue-style worker pattern)
|
|
166
|
-
const items = await
|
|
166
|
+
const items = await repository.find({
|
|
167
167
|
filter: { where: { status: 'pending' }, limit: 10 },
|
|
168
168
|
options: {
|
|
169
169
|
transaction: tx,
|
|
@@ -172,7 +172,7 @@ const items = await repo.find({
|
|
|
172
172
|
});
|
|
173
173
|
|
|
174
174
|
// Fail immediately instead of waiting
|
|
175
|
-
const item = await
|
|
175
|
+
const item = await repository.findOne({
|
|
176
176
|
filter: { where: { id: '123' } },
|
|
177
177
|
options: {
|
|
178
178
|
transaction: tx,
|
|
@@ -193,14 +193,14 @@ const item = await repo.findOne({
|
|
|
193
193
|
> Row-level locking requires a **transaction** and is **incompatible with `include`/`fields`** in the filter (these use the Drizzle Query API which does not support `.for()`).
|
|
194
194
|
|
|
195
195
|
```typescript
|
|
196
|
-
// Error
|
|
197
|
-
await
|
|
196
|
+
// Error - no transaction
|
|
197
|
+
await repository.findOne({
|
|
198
198
|
filter: { where: { id: '123' } },
|
|
199
199
|
options: { lock: { strength: 'update' } },
|
|
200
200
|
});
|
|
201
201
|
|
|
202
|
-
// Error
|
|
203
|
-
await
|
|
202
|
+
// Error - include uses Query API
|
|
203
|
+
await repository.findOne({
|
|
204
204
|
filter: { where: { id: '123' }, include: [{ relation: 'posts' }] },
|
|
205
205
|
options: { transaction: tx, lock: { strength: 'update' } },
|
|
206
206
|
});
|
|
@@ -235,12 +235,12 @@ Hidden properties are excluded at the **SQL level** for maximum security:
|
|
|
235
235
|
|
|
236
236
|
```typescript
|
|
237
237
|
// Read operations exclude hidden properties
|
|
238
|
-
const user = await
|
|
238
|
+
const user = await userRepository.findById({ id: '123' });
|
|
239
239
|
// Result: { id: '123', email: 'john@example.com', name: 'John' }
|
|
240
240
|
// Note: password, secret, apiKey are NOT included
|
|
241
241
|
|
|
242
242
|
// Write operations exclude hidden from RETURNING clause
|
|
243
|
-
const created = await
|
|
243
|
+
const created = await userRepository.create({
|
|
244
244
|
data: { email: 'new@example.com', password: 'hashed_secret' }
|
|
245
245
|
});
|
|
246
246
|
// Result: { count: 1, data: { id: '456', email: 'new@example.com' } }
|
|
@@ -253,7 +253,7 @@ You **can** filter by hidden properties - you just can't see them in results:
|
|
|
253
253
|
|
|
254
254
|
```typescript
|
|
255
255
|
// This works! Finds user but password not in result
|
|
256
|
-
const user = await
|
|
256
|
+
const user = await userRepository.findOne({
|
|
257
257
|
filter: { where: { password: 'hashed_value' } }
|
|
258
258
|
});
|
|
259
259
|
```
|
|
@@ -263,7 +263,7 @@ const user = await userRepo.findOne({
|
|
|
263
263
|
Hidden properties are also excluded from included relations:
|
|
264
264
|
|
|
265
265
|
```typescript
|
|
266
|
-
const post = await
|
|
266
|
+
const post = await postRepository.findOne({
|
|
267
267
|
filter: {
|
|
268
268
|
include: [{ relation: 'author' }]
|
|
269
269
|
}
|
|
@@ -277,7 +277,7 @@ When you need hidden fields (e.g., for authentication), bypass the repository:
|
|
|
277
277
|
|
|
278
278
|
```typescript
|
|
279
279
|
// Direct connector access - includes all fields
|
|
280
|
-
const connector =
|
|
280
|
+
const connector = userRepository.getConnector();
|
|
281
281
|
const [fullUser] = await connector
|
|
282
282
|
.select()
|
|
283
283
|
.from(User.schema)
|
|
@@ -294,7 +294,7 @@ The repository automatically uses Drizzle's Core API (faster) for simple queries
|
|
|
294
294
|
|
|
295
295
|
```typescript
|
|
296
296
|
// Automatically optimized - uses Core API
|
|
297
|
-
const users = await
|
|
297
|
+
const users = await repository.find({
|
|
298
298
|
filter: {
|
|
299
299
|
where: { status: 'active' },
|
|
300
300
|
limit: 10,
|
|
@@ -304,7 +304,7 @@ const users = await repo.find({
|
|
|
304
304
|
// Uses: db.select().from(table).where(...).orderBy(...).limit(10)
|
|
305
305
|
|
|
306
306
|
// Uses Query API (has relations)
|
|
307
|
-
const usersWithPosts = await
|
|
307
|
+
const usersWithPosts = await repository.find({
|
|
308
308
|
filter: {
|
|
309
309
|
where: { status: 'active' },
|
|
310
310
|
include: [{ relation: 'posts' }]
|
|
@@ -325,7 +325,7 @@ Prevent memory exhaustion on large tables:
|
|
|
325
325
|
|
|
326
326
|
```typescript
|
|
327
327
|
// Good - bounded result set
|
|
328
|
-
await
|
|
328
|
+
await repository.find({
|
|
329
329
|
filter: {
|
|
330
330
|
where: { status: 'active' },
|
|
331
331
|
limit: 100
|
|
@@ -333,20 +333,20 @@ await repo.find({
|
|
|
333
333
|
});
|
|
334
334
|
|
|
335
335
|
// Dangerous - could return millions of rows
|
|
336
|
-
await
|
|
336
|
+
await repository.find({
|
|
337
337
|
filter: { where: { status: 'active' } }
|
|
338
338
|
});
|
|
339
339
|
```
|
|
340
340
|
|
|
341
341
|
> [!NOTE]
|
|
342
|
-
>
|
|
342
|
+
> `find()` always applies a default limit of `10` when no `limit` is set in the filter. Pass an explicit `limit` in the filter to override this default.
|
|
343
343
|
|
|
344
344
|
### Pagination with Data Range
|
|
345
345
|
|
|
346
346
|
Use `shouldQueryRange` to get both data and total count in a single call:
|
|
347
347
|
|
|
348
348
|
```typescript
|
|
349
|
-
const result = await
|
|
349
|
+
const result = await userRepository.find({
|
|
350
350
|
filter: {
|
|
351
351
|
where: { status: 'active' },
|
|
352
352
|
limit: 20,
|
|
@@ -361,7 +361,7 @@ const result = await userRepo.find({
|
|
|
361
361
|
// Example: { data: [...20 users], range: { start: 40, end: 59, total: 150 } }
|
|
362
362
|
```
|
|
363
363
|
|
|
364
|
-
This runs `find` and `count` in parallel via `Promise.all` for optimal performance.
|
|
364
|
+
This runs `find` and `count` in parallel via `Promise.all` for optimal performance. Inside a transaction the two queries run sequentially instead - a transaction connector wraps a single client, so parallel queries on it are not safe.
|
|
365
365
|
|
|
366
366
|
### WeakMap Cache
|
|
367
367
|
|
|
@@ -382,14 +382,14 @@ Repository methods infer return types based on `shouldReturn`:
|
|
|
382
382
|
|
|
383
383
|
```typescript
|
|
384
384
|
// shouldReturn: false - TypeScript knows data is null
|
|
385
|
-
const result1 = await
|
|
385
|
+
const result1 = await repository.create({
|
|
386
386
|
data: { name: 'John' },
|
|
387
387
|
options: { shouldReturn: false }
|
|
388
388
|
});
|
|
389
389
|
// Type: Promise<{ count: number; data: undefined | null }>
|
|
390
390
|
|
|
391
391
|
// shouldReturn: true (default) - TypeScript knows data is the entity
|
|
392
|
-
const result2 = await
|
|
392
|
+
const result2 = await repository.create({
|
|
393
393
|
data: { name: 'John' },
|
|
394
394
|
options: { shouldReturn: true }
|
|
395
395
|
});
|
|
@@ -397,7 +397,7 @@ const result2 = await repo.create({
|
|
|
397
397
|
console.log(result2.data.name); // 'John' - fully typed!
|
|
398
398
|
|
|
399
399
|
// Array operations
|
|
400
|
-
const results = await
|
|
400
|
+
const results = await repository.createAll({
|
|
401
401
|
data: [{ name: 'John' }, { name: 'Jane' }],
|
|
402
402
|
options: { shouldReturn: true }
|
|
403
403
|
});
|
|
@@ -415,7 +415,7 @@ type UserWithPosts = User & {
|
|
|
415
415
|
};
|
|
416
416
|
|
|
417
417
|
// Use generic override
|
|
418
|
-
const user = await
|
|
418
|
+
const user = await userRepository.findOne<UserWithPosts>({
|
|
419
419
|
filter: {
|
|
420
420
|
where: { id: '123' },
|
|
421
421
|
include: [{ relation: 'posts' }]
|
|
@@ -443,7 +443,7 @@ Enable logging for specific operations:
|
|
|
443
443
|
|
|
444
444
|
```typescript
|
|
445
445
|
// Enable debug logging
|
|
446
|
-
await
|
|
446
|
+
await repository.create({
|
|
447
447
|
data: { name: 'John', email: 'john@example.com' },
|
|
448
448
|
options: {
|
|
449
449
|
log: { use: true, level: 'debug' }
|
|
@@ -452,7 +452,7 @@ await repo.create({
|
|
|
452
452
|
// Output: [_create] Executing with opts: { data: [...], options: {...} }
|
|
453
453
|
|
|
454
454
|
// Available levels: 'debug', 'info', 'warn', 'error'
|
|
455
|
-
await
|
|
455
|
+
await repository.updateById({
|
|
456
456
|
id: '123',
|
|
457
457
|
data: { name: 'Jane' },
|
|
458
458
|
options: { log: { use: true, level: 'info' } }
|
|
@@ -482,10 +482,10 @@ Prevents accidental mass updates/deletes:
|
|
|
482
482
|
|
|
483
483
|
```typescript
|
|
484
484
|
// Throws error - empty where without force
|
|
485
|
-
await
|
|
485
|
+
await repository.deleteAll({ where: {} });
|
|
486
486
|
|
|
487
487
|
// Explicit force flag - logs warning, proceeds
|
|
488
|
-
await
|
|
488
|
+
await repository.deleteAll({
|
|
489
489
|
where: {},
|
|
490
490
|
options: { force: true }
|
|
491
491
|
});
|
|
@@ -516,7 +516,7 @@ For advanced queries not supported by the repository API:
|
|
|
516
516
|
|
|
517
517
|
```typescript
|
|
518
518
|
// Get the Drizzle connector
|
|
519
|
-
const connector =
|
|
519
|
+
const connector = repository.getConnector();
|
|
520
520
|
|
|
521
521
|
// Raw Drizzle query
|
|
522
522
|
const results = await connector
|
|
@@ -537,7 +537,8 @@ const results = await connector
|
|
|
537
537
|
|
|
538
538
|
| Class | Scope | Description |
|
|
539
539
|
|-------|-------|-------------|
|
|
540
|
-
| `AbstractRepository` | N/A |
|
|
540
|
+
| `AbstractRepository` | N/A | Engine-neutral abstract base (`src/base`), defines all method signatures, lazy `dataSource`/`entity` resolution. No mixin composition - plain `BaseHelper` subclass. |
|
|
541
|
+
| `PostgresBaseRepository` | N/A | PostgreSQL connector base. Adds `FilterBuilder`, hidden-column exclusion (`getHiddenProperties`/`getVisibleProperties`), default-filter application (`getDefaultFilter`/`applyDefaultFilter`) - the behavior formerly provided by the now-removed `FieldsVisibilityMixin`/`DefaultFilterMixin` (see [Repository Mixins](./mixins.md)). |
|
|
541
542
|
| `ReadableRepository` | `READ_ONLY` | Read-only operations (`find`, `findOne`, `findById`, `count`, `existsWith`). Write operations throw errors. |
|
|
542
543
|
| `PersistableRepository` | `READ_WRITE` | Adds write operations (`create`, `update`, `delete`) with `UpdateBuilder` |
|
|
543
544
|
| `DefaultCRUDRepository` | `READ_WRITE` | Extends `PersistableRepository` with no additional logic - **recommended default** |
|
|
@@ -569,13 +570,13 @@ When models have a `defaultFilter` configured, you can bypass it for admin/maint
|
|
|
569
570
|
|
|
570
571
|
```typescript
|
|
571
572
|
// Normal query - default filter applies
|
|
572
|
-
await
|
|
573
|
+
await repository.find({
|
|
573
574
|
filter: { where: { status: 'active' } }
|
|
574
575
|
});
|
|
575
576
|
// WHERE isDeleted = false AND status = 'active' (if model has soft-delete default)
|
|
576
577
|
|
|
577
578
|
// Admin query - bypass default filter
|
|
578
|
-
await
|
|
579
|
+
await repository.find({
|
|
579
580
|
filter: { where: { status: 'active' } },
|
|
580
581
|
options: { shouldSkipDefaultFilter: true }
|
|
581
582
|
});
|
|
@@ -586,20 +587,20 @@ await repo.find({
|
|
|
586
587
|
|
|
587
588
|
```typescript
|
|
588
589
|
// Read operations
|
|
589
|
-
await
|
|
590
|
-
await
|
|
591
|
-
await
|
|
590
|
+
await repository.find({ filter, options: { shouldSkipDefaultFilter: true } });
|
|
591
|
+
await repository.findOne({ filter, options: { shouldSkipDefaultFilter: true } });
|
|
592
|
+
await repository.count({ where, options: { shouldSkipDefaultFilter: true } });
|
|
592
593
|
|
|
593
594
|
// Write operations
|
|
594
|
-
await
|
|
595
|
-
await
|
|
595
|
+
await repository.updateAll({ where, data, options: { shouldSkipDefaultFilter: true } });
|
|
596
|
+
await repository.deleteAll({ where, options: { shouldSkipDefaultFilter: true, force: true } });
|
|
596
597
|
```
|
|
597
598
|
|
|
598
599
|
**Combined with transactions:**
|
|
599
600
|
|
|
600
601
|
```typescript
|
|
601
|
-
const tx = await
|
|
602
|
-
await
|
|
602
|
+
const tx = await repository.beginTransaction();
|
|
603
|
+
await repository.updateAll({
|
|
603
604
|
where: { status: 'archived' },
|
|
604
605
|
data: { isDeleted: true },
|
|
605
606
|
options: {
|
|
@@ -626,7 +627,7 @@ Use dot notation keys to target nested properties:
|
|
|
626
627
|
// Assume 'metadata' is a JSONB column
|
|
627
628
|
// Current value: { theme: 'light', notifications: { email: true } }
|
|
628
629
|
|
|
629
|
-
await
|
|
630
|
+
await repository.updateById({
|
|
630
631
|
id: '123',
|
|
631
632
|
data: {
|
|
632
633
|
// Update only the theme, preserving other fields
|
|
@@ -651,7 +652,7 @@ await repo.updateById({
|
|
|
651
652
|
#### Deeply Nested Updates
|
|
652
653
|
|
|
653
654
|
```typescript
|
|
654
|
-
await
|
|
655
|
+
await repository.updateById({
|
|
655
656
|
id: '123',
|
|
656
657
|
data: {
|
|
657
658
|
'metadata.settings.display.fontSize': 16,
|
|
@@ -663,7 +664,7 @@ await repo.updateById({
|
|
|
663
664
|
#### Array Element Updates
|
|
664
665
|
|
|
665
666
|
```typescript
|
|
666
|
-
await
|
|
667
|
+
await repository.updateById({
|
|
667
668
|
id: '123',
|
|
668
669
|
data: {
|
|
669
670
|
// Set the first address as primary
|
|
@@ -677,7 +678,7 @@ await repo.updateById({
|
|
|
677
678
|
You can mix regular column updates with JSON path updates:
|
|
678
679
|
|
|
679
680
|
```typescript
|
|
680
|
-
await
|
|
681
|
+
await repository.updateById({
|
|
681
682
|
id: '123',
|
|
682
683
|
data: {
|
|
683
684
|
status: 'active', // Regular column
|
|
@@ -722,7 +723,7 @@ Write operations additionally support:
|
|
|
722
723
|
|
|
723
724
|
| Feature | Code |
|
|
724
725
|
|---------|------|
|
|
725
|
-
| Start transaction | `const tx = await
|
|
726
|
+
| Start transaction | `const tx = await repository.beginTransaction()` |
|
|
726
727
|
| Use transaction | `options: { transaction: tx }` |
|
|
727
728
|
| Commit | `await tx.commit()` |
|
|
728
729
|
| Rollback | `await tx.rollback()` |
|
|
@@ -733,7 +734,7 @@ Write operations additionally support:
|
|
|
733
734
|
| Force delete all | `options: { force: true }` |
|
|
734
735
|
| Skip returning data | `options: { shouldReturn: false }` |
|
|
735
736
|
| Get data + count | `options: { shouldQueryRange: true }` |
|
|
736
|
-
| Access connector | `
|
|
737
|
+
| Access connector | `repository.getConnector()` |
|
|
737
738
|
|
|
738
739
|
|
|
739
740
|
## Next Steps
|
|
@@ -741,7 +742,7 @@ Write operations additionally support:
|
|
|
741
742
|
- [Overview](./index.md) - Repository basics
|
|
742
743
|
- [Filter System](../filter-system/) - Query operators
|
|
743
744
|
- [Default Filter](../filter-system/default-filter.md) - Automatic filter configuration
|
|
744
|
-
- [Repository Mixins](./mixins.md) -
|
|
745
|
+
- [Repository Mixins (Removed)](./mixins.md) - Where mixin behavior lives now
|
|
745
746
|
- [Relations & Includes](./relations.md) - Eager loading
|
|
746
747
|
- [Soft-Deletable Repository](./soft-deletable.md) - Soft delete operations
|
|
747
748
|
- [JSON Path Filtering](../filter-system/json-filtering) - JSONB queries
|
|
@@ -755,7 +756,7 @@ Write operations additionally support:
|
|
|
755
756
|
- [DataSources](/guides/core-concepts/persistent/datasources) - Database connections
|
|
756
757
|
|
|
757
758
|
- **Related Topics:**
|
|
758
|
-
- [Repository Mixins](./mixins) -
|
|
759
|
+
- [Repository Mixins (Removed)](./mixins) - Where mixin behavior lives now
|
|
759
760
|
- [Relations & Includes](./relations) - Loading related data
|
|
760
761
|
- [Filter System](/references/base/filter-system/) - Query operators
|
|
761
762
|
|