@venizia/ignis-docs 0.0.7 → 0.0.8-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. package/dist/mcp-server/common/paths.d.ts +4 -2
  2. package/dist/mcp-server/common/paths.d.ts.map +1 -1
  3. package/dist/mcp-server/common/paths.js +8 -6
  4. package/dist/mcp-server/common/paths.js.map +1 -1
  5. package/dist/mcp-server/tools/docs/get-document-content.tool.d.ts +1 -1
  6. package/dist/mcp-server/tools/docs/get-document-content.tool.d.ts.map +1 -1
  7. package/dist/mcp-server/tools/docs/get-document-content.tool.js +7 -7
  8. package/dist/mcp-server/tools/docs/get-document-metadata.tool.js +3 -3
  9. package/dist/mcp-server/tools/docs/get-package-overview.tool.d.ts +1 -1
  10. package/dist/mcp-server/tools/docs/get-package-overview.tool.js +1 -1
  11. package/package.json +1 -1
  12. package/wiki/best-practices/api-usage-examples.md +9 -9
  13. package/wiki/best-practices/architectural-patterns.md +19 -3
  14. package/wiki/best-practices/architecture-decisions.md +6 -6
  15. package/wiki/best-practices/code-style-standards/advanced-patterns.md +1 -1
  16. package/wiki/best-practices/code-style-standards/control-flow.md +1 -1
  17. package/wiki/best-practices/code-style-standards/function-patterns.md +2 -2
  18. package/wiki/best-practices/code-style-standards/index.md +2 -2
  19. package/wiki/best-practices/code-style-standards/naming-conventions.md +1 -1
  20. package/wiki/best-practices/code-style-standards/route-definitions.md +4 -4
  21. package/wiki/best-practices/data-modeling.md +1 -1
  22. package/wiki/best-practices/deployment-strategies.md +1 -1
  23. package/wiki/best-practices/error-handling.md +2 -2
  24. package/wiki/best-practices/performance-optimization.md +3 -3
  25. package/wiki/best-practices/security-guidelines.md +2 -2
  26. package/wiki/best-practices/troubleshooting-tips.md +1 -1
  27. package/wiki/{references → extensions}/components/authentication/api.md +12 -20
  28. package/wiki/{references → extensions}/components/authentication/errors.md +1 -1
  29. package/wiki/{references → extensions}/components/authentication/index.md +5 -8
  30. package/wiki/{references → extensions}/components/authentication/usage.md +20 -36
  31. package/wiki/{references → extensions}/components/authorization/api.md +62 -13
  32. package/wiki/{references → extensions}/components/authorization/errors.md +12 -7
  33. package/wiki/{references → extensions}/components/authorization/index.md +93 -6
  34. package/wiki/{references → extensions}/components/authorization/usage.md +42 -4
  35. package/wiki/{references → extensions}/components/health-check.md +5 -4
  36. package/wiki/{references → extensions}/components/index.md +2 -0
  37. package/wiki/{references → extensions}/components/mail/index.md +1 -1
  38. package/wiki/{references → extensions}/components/request-tracker.md +1 -1
  39. package/wiki/{references → extensions}/components/socket-io/api.md +2 -2
  40. package/wiki/{references → extensions}/components/socket-io/errors.md +2 -0
  41. package/wiki/{references → extensions}/components/socket-io/index.md +24 -20
  42. package/wiki/{references → extensions}/components/socket-io/usage.md +2 -2
  43. package/wiki/{references → extensions}/components/static-asset/api.md +14 -15
  44. package/wiki/{references → extensions}/components/static-asset/errors.md +3 -1
  45. package/wiki/{references → extensions}/components/static-asset/index.md +158 -89
  46. package/wiki/{references → extensions}/components/static-asset/usage.md +8 -5
  47. package/wiki/{references → extensions}/components/swagger.md +3 -3
  48. package/wiki/{references → extensions}/components/template/index.md +4 -4
  49. package/wiki/{references → extensions}/components/template/setup-page.md +1 -1
  50. package/wiki/{references → extensions}/components/template/single-page.md +1 -1
  51. package/wiki/{references → extensions}/components/websocket/api.md +7 -6
  52. package/wiki/{references → extensions}/components/websocket/errors.md +17 -3
  53. package/wiki/{references → extensions}/components/websocket/index.md +17 -11
  54. package/wiki/{references → extensions}/components/websocket/usage.md +2 -2
  55. package/wiki/{references → extensions}/helpers/crypto/index.md +1 -1
  56. package/wiki/{references → extensions}/helpers/env/index.md +9 -5
  57. package/wiki/{references → extensions}/helpers/error/index.md +2 -7
  58. package/wiki/{references → extensions}/helpers/index.md +18 -6
  59. package/wiki/{references → extensions}/helpers/kafka/admin.md +13 -1
  60. package/wiki/{references → extensions}/helpers/kafka/consumer.md +28 -28
  61. package/wiki/{references → extensions}/helpers/kafka/examples.md +19 -19
  62. package/wiki/{references → extensions}/helpers/kafka/index.md +51 -48
  63. package/wiki/{references → extensions}/helpers/kafka/producer.md +18 -18
  64. package/wiki/{references → extensions}/helpers/kafka/schema-registry.md +25 -25
  65. package/wiki/{references → extensions}/helpers/logger/index.md +2 -2
  66. package/wiki/{references → extensions}/helpers/queue/index.md +400 -4
  67. package/wiki/{references → extensions}/helpers/storage/api.md +170 -10
  68. package/wiki/{references → extensions}/helpers/storage/index.md +44 -8
  69. package/wiki/{references → extensions}/helpers/template/index.md +1 -1
  70. package/wiki/{references → extensions}/helpers/testing/index.md +4 -4
  71. package/wiki/{references → extensions}/helpers/types/index.md +63 -16
  72. package/wiki/{references → extensions}/helpers/websocket/index.md +1 -1
  73. package/wiki/extensions/index.md +48 -0
  74. package/wiki/guides/core-concepts/application/bootstrapping.md +55 -37
  75. package/wiki/guides/core-concepts/application/index.md +95 -35
  76. package/wiki/guides/core-concepts/components-guide.md +23 -19
  77. package/wiki/guides/core-concepts/components.md +34 -10
  78. package/wiki/guides/core-concepts/dependency-injection.md +99 -34
  79. package/wiki/guides/core-concepts/grpc-controllers.md +295 -0
  80. package/wiki/guides/core-concepts/persistent/datasources.md +27 -8
  81. package/wiki/guides/core-concepts/persistent/models.md +43 -1
  82. package/wiki/guides/core-concepts/persistent/repositories.md +75 -8
  83. package/wiki/guides/core-concepts/persistent/transactions.md +38 -8
  84. package/wiki/guides/core-concepts/{controllers.md → rest-controllers.md} +30 -33
  85. package/wiki/guides/core-concepts/services.md +19 -5
  86. package/wiki/guides/get-started/5-minute-quickstart.md +6 -7
  87. package/wiki/guides/get-started/philosophy.md +1 -1
  88. package/wiki/guides/index.md +2 -2
  89. package/wiki/guides/reference/glossary.md +7 -7
  90. package/wiki/guides/reference/mcp-docs-server.md +1 -1
  91. package/wiki/guides/tutorials/building-a-crud-api.md +2 -2
  92. package/wiki/guides/tutorials/complete-installation.md +17 -14
  93. package/wiki/guides/tutorials/ecommerce-api.md +18 -18
  94. package/wiki/guides/tutorials/realtime-chat.md +8 -8
  95. package/wiki/guides/tutorials/testing.md +2 -2
  96. package/wiki/index.md +4 -3
  97. package/wiki/references/base/application.md +341 -21
  98. package/wiki/references/base/bootstrapping.md +43 -13
  99. package/wiki/references/base/components.md +259 -8
  100. package/wiki/references/base/controllers.md +556 -253
  101. package/wiki/references/base/datasources.md +159 -79
  102. package/wiki/references/base/dependency-injection.md +299 -48
  103. package/wiki/references/base/filter-system/application-usage.md +18 -2
  104. package/wiki/references/base/filter-system/array-operators.md +14 -6
  105. package/wiki/references/base/filter-system/comparison-operators.md +9 -3
  106. package/wiki/references/base/filter-system/default-filter.md +28 -3
  107. package/wiki/references/base/filter-system/fields-order-pagination.md +17 -13
  108. package/wiki/references/base/filter-system/index.md +169 -11
  109. package/wiki/references/base/filter-system/json-filtering.md +51 -18
  110. package/wiki/references/base/filter-system/list-operators.md +4 -3
  111. package/wiki/references/base/filter-system/logical-operators.md +7 -2
  112. package/wiki/references/base/filter-system/null-operators.md +50 -0
  113. package/wiki/references/base/filter-system/quick-reference.md +82 -243
  114. package/wiki/references/base/filter-system/range-operators.md +7 -1
  115. package/wiki/references/base/filter-system/tips.md +34 -7
  116. package/wiki/references/base/filter-system/use-cases.md +6 -5
  117. package/wiki/references/base/grpc-controllers.md +984 -0
  118. package/wiki/references/base/index.md +32 -24
  119. package/wiki/references/base/middleware.md +347 -0
  120. package/wiki/references/base/models.md +390 -46
  121. package/wiki/references/base/providers.md +14 -14
  122. package/wiki/references/base/repositories/advanced.md +84 -69
  123. package/wiki/references/base/repositories/index.md +447 -12
  124. package/wiki/references/base/repositories/mixins.md +103 -98
  125. package/wiki/references/base/repositories/relations.md +129 -45
  126. package/wiki/references/base/repositories/soft-deletable.md +104 -23
  127. package/wiki/references/base/services.md +94 -14
  128. package/wiki/references/index.md +12 -10
  129. package/wiki/references/quick-reference.md +98 -65
  130. package/wiki/references/utilities/crypto.md +21 -4
  131. package/wiki/references/utilities/date.md +25 -7
  132. package/wiki/references/utilities/index.md +26 -24
  133. package/wiki/references/utilities/jsx.md +54 -54
  134. package/wiki/references/utilities/module.md +8 -6
  135. package/wiki/references/utilities/parse.md +16 -9
  136. package/wiki/references/utilities/performance.md +22 -7
  137. package/wiki/references/utilities/promise.md +19 -16
  138. package/wiki/references/utilities/request.md +48 -26
  139. package/wiki/references/utilities/schema.md +69 -6
  140. package/wiki/references/utilities/statuses.md +131 -140
  141. /package/wiki/{references → extensions}/components/mail/api.md +0 -0
  142. /package/wiki/{references → extensions}/components/mail/errors.md +0 -0
  143. /package/wiki/{references → extensions}/components/mail/usage.md +0 -0
  144. /package/wiki/{references → extensions}/components/template/api-page.md +0 -0
  145. /package/wiki/{references → extensions}/components/template/errors-page.md +0 -0
  146. /package/wiki/{references → extensions}/components/template/usage-page.md +0 -0
  147. /package/wiki/{references → extensions}/helpers/cron/index.md +0 -0
  148. /package/wiki/{references → extensions}/helpers/inversion/index.md +0 -0
  149. /package/wiki/{references → extensions}/helpers/network/api.md +0 -0
  150. /package/wiki/{references → extensions}/helpers/network/index.md +0 -0
  151. /package/wiki/{references → extensions}/helpers/redis/index.md +0 -0
  152. /package/wiki/{references → extensions}/helpers/socket-io/api.md +0 -0
  153. /package/wiki/{references → extensions}/helpers/socket-io/index.md +0 -0
  154. /package/wiki/{references → extensions}/helpers/template/single-page.md +0 -0
  155. /package/wiki/{references → extensions}/helpers/uid/index.md +0 -0
  156. /package/wiki/{references → extensions}/helpers/websocket/api.md +0 -0
  157. /package/wiki/{references → extensions}/helpers/worker-thread/index.md +0 -0
  158. /package/wiki/{references → extensions}/src-details/mcp-server.md +0 -0
@@ -25,14 +25,51 @@ export class TodoRepository extends DefaultCRUDRepository<typeof Todo.schema> {
25
25
 
26
26
  | Class | Capabilities | Use Case |
27
27
  |-------|--------------|----------|
28
- | **AbstractRepository** | Base class with properties | Extend for custom repositories |
29
- | **ReadableRepository** | Read-only operations | Views, external tables |
30
- | **PersistableRepository** | Read + Write operations | Rarely used directly |
31
- | **DefaultCRUDRepository** | Full CRUD operations | Standard data tables |
28
+ | **AbstractRepository** | Base class with properties, mixins, lazy resolution | Extend for custom repositories |
29
+ | **ReadableRepository** | Read-only operations (write methods throw errors) | Views, external tables, read-only access |
30
+ | **PersistableRepository** | Read + Write operations | Full CRUD access |
31
+ | **DefaultCRUDRepository** | Extends PersistableRepository (no additions) | Standard data tables (recommended) |
32
32
  | **SoftDeletableRepository** | CRUD + soft delete + restore | Tables with `deletedAt` column |
33
33
 
34
34
  **Most common:** Extend `DefaultCRUDRepository` for standard tables, or `SoftDeletableRepository` for soft-delete patterns.
35
35
 
36
+ ### Hierarchy
37
+
38
+ ```
39
+ BaseHelper
40
+ + FieldsVisibilityMixin
41
+ + DefaultFilterMixin
42
+ = AbstractRepository (abstract base, declares all CRUD signatures)
43
+ |
44
+ +-- ReadableRepository (implements read ops; write ops throw errors)
45
+ |
46
+ +-- PersistableRepository (implements write + delete ops, READ_WRITE scope)
47
+ |
48
+ +-- DefaultCRUDRepository (empty subclass, recommended entry point)
49
+ |
50
+ +-- SoftDeletableRepository (overrides delete with soft-delete)
51
+ ```
52
+
53
+ ### Type Parameters
54
+
55
+ All repository classes share the same four type parameters:
56
+
57
+ ```typescript
58
+ class DefaultCRUDRepository<
59
+ EntitySchema extends TTableSchemaWithId = TTableSchemaWithId,
60
+ DataObject extends TTableObject<EntitySchema> = TTableObject<EntitySchema>,
61
+ PersistObject extends TTableInsert<EntitySchema> = TTableInsert<EntitySchema>,
62
+ ExtraOptions extends IExtraOptions = IExtraOptions,
63
+ >
64
+ ```
65
+
66
+ | Parameter | Description |
67
+ |-----------|-------------|
68
+ | `EntitySchema` | The Drizzle `pgTable` schema type (e.g., `typeof User.schema`) |
69
+ | `DataObject` | The inferred SELECT type from the schema |
70
+ | `PersistObject` | The inferred INSERT type from the schema |
71
+ | `ExtraOptions` | Extra options for operations (defaults to `IExtraOptions`) |
72
+
36
73
 
37
74
  ## Available Methods
38
75
 
@@ -52,10 +89,357 @@ export class TodoRepository extends DefaultCRUDRepository<typeof Todo.schema> {
52
89
  | `create(opts)` | Create single record | `repo.create({ data: { title: 'New' } })` |
53
90
  | `createAll(opts)` | Create multiple records | `repo.createAll({ data: [{ title: 'A' }, { title: 'B' }] })` |
54
91
  | `updateById(opts)` | Update by primary key | `repo.updateById({ id: '123', data: { title: 'Updated' } })` |
55
- | `updateAll(opts)` | Update matching records | `repo.updateAll({ where: { status: 'draft' }, data: { status: 'published' } })` |
92
+ | `updateAll(opts)` | Update matching records | `repo.updateAll({ data: { status: 'published' }, where: { status: 'draft' } })` |
93
+ | `updateBy(opts)` | Alias for `updateAll` | `repo.updateBy({ data: { status: 'published' }, where: { status: 'draft' } })` |
56
94
  | `deleteById(opts)` | Delete by primary key | `repo.deleteById({ id: '123' })` |
57
95
  | `deleteAll(opts)` | Delete matching records | `repo.deleteAll({ where: { status: 'archived' } })` |
58
- | `deleteBy(opts)` | Delete by where condition | `repo.deleteBy({ where: { status: 'archived' } })` |
96
+ | `deleteBy(opts)` | Alias for `deleteAll` | `repo.deleteBy({ where: { status: 'archived' } })` |
97
+
98
+
99
+ ## Method Signatures
100
+
101
+ ### Read Operations
102
+
103
+ ```typescript
104
+ // Count matching records
105
+ count(opts: {
106
+ where: TWhere<DataObject>;
107
+ options?: IExtraOptions;
108
+ }): Promise<{ count: number }>;
109
+
110
+ // Check if any record matches
111
+ existsWith(opts: {
112
+ where: TWhere<DataObject>;
113
+ options?: IExtraOptions;
114
+ }): Promise<boolean>;
115
+
116
+ // Find multiple records (returns array)
117
+ find<R = DataObject>(opts: {
118
+ filter: TFilter<DataObject>;
119
+ options?: IExtraOptions & { shouldQueryRange?: false };
120
+ }): Promise<R[]>;
121
+
122
+ // Find multiple records with range info (returns data + range)
123
+ find<R = DataObject>(opts: {
124
+ filter: TFilter<DataObject>;
125
+ options: IExtraOptions & { shouldQueryRange: true };
126
+ }): Promise<{ data: Array<R>; range: TDataRange }>;
127
+
128
+ // Find single record
129
+ findOne<R = DataObject>(opts: {
130
+ filter: TFilter<DataObject>;
131
+ options?: IExtraOptions;
132
+ }): Promise<R | null>;
133
+
134
+ // Find by primary key
135
+ findById<R = DataObject>(opts: {
136
+ id: IdType;
137
+ filter?: Omit<TFilter<DataObject>, 'where'>;
138
+ options?: IExtraOptions;
139
+ }): Promise<R | null>;
140
+ ```
141
+
142
+ ### Write Operations
143
+
144
+ ```typescript
145
+ // Create single record (returns created data by default)
146
+ create<R = DataObject>(opts: {
147
+ data: PersistObject;
148
+ options?: IExtraOptions & { shouldReturn?: true };
149
+ }): Promise<{ count: number; data: R }>;
150
+
151
+ // Create single record (skip returning data)
152
+ create(opts: {
153
+ data: PersistObject;
154
+ options: IExtraOptions & { shouldReturn: false };
155
+ }): Promise<{ count: number; data: undefined | null }>;
156
+
157
+ // Create multiple records (returns created data by default)
158
+ createAll<R = DataObject>(opts: {
159
+ data: Array<PersistObject>;
160
+ options?: IExtraOptions & { shouldReturn?: true };
161
+ }): Promise<{ count: number; data: Array<R> }>;
162
+
163
+ // Create multiple records (skip returning data)
164
+ createAll(opts: {
165
+ data: Array<PersistObject>;
166
+ options: IExtraOptions & { shouldReturn: false };
167
+ }): Promise<{ count: number; data: undefined | null }>;
168
+
169
+ // Update by primary key (returns updated data by default)
170
+ updateById<R = DataObject>(opts: {
171
+ id: IdType;
172
+ data: Partial<PersistObject>;
173
+ options?: IExtraOptions & { shouldReturn?: true };
174
+ }): Promise<{ count: number; data: R }>;
175
+
176
+ // Update by primary key (skip returning data)
177
+ updateById(opts: {
178
+ id: IdType;
179
+ data: Partial<PersistObject>;
180
+ options: IExtraOptions & { shouldReturn: false };
181
+ }): Promise<{ count: number; data: undefined | null }>;
182
+
183
+ // Update matching records (returns updated data by default)
184
+ updateAll<R = DataObject>(opts: {
185
+ data: Partial<PersistObject>;
186
+ where: TWhere<DataObject>;
187
+ options?: IExtraOptions & { shouldReturn?: true; force?: boolean };
188
+ }): Promise<{ count: number; data: Array<R> }>;
189
+
190
+ // Update matching records (skip returning data)
191
+ updateAll(opts: {
192
+ data: Partial<PersistObject>;
193
+ where: TWhere<DataObject>;
194
+ options: IExtraOptions & { shouldReturn: false; force?: boolean };
195
+ }): Promise<{ count: number; data: undefined | null }>;
196
+
197
+ // updateBy is an alias for updateAll (same signatures)
198
+
199
+ // Delete by primary key (returns deleted data by default)
200
+ deleteById<R = DataObject>(opts: {
201
+ id: IdType;
202
+ options?: IExtraOptions & { shouldReturn?: true };
203
+ }): Promise<{ count: number; data: R }>;
204
+
205
+ // Delete by primary key (skip returning data)
206
+ deleteById(opts: {
207
+ id: IdType;
208
+ options: IExtraOptions & { shouldReturn: false };
209
+ }): Promise<{ count: number; data: undefined | null }>;
210
+
211
+ // Delete matching records (returns deleted data by default)
212
+ deleteAll<R = DataObject>(opts: {
213
+ where: TWhere<DataObject>;
214
+ options?: IExtraOptions & { shouldReturn?: true; force?: boolean };
215
+ }): Promise<{ count: number; data: Array<R> }>;
216
+
217
+ // Delete matching records (skip returning data)
218
+ deleteAll(opts: {
219
+ where: TWhere<DataObject>;
220
+ options: IExtraOptions & { shouldReturn: false; force?: boolean };
221
+ }): Promise<{ count: number; data: undefined | null }>;
222
+
223
+ // deleteBy is an alias for deleteAll (same signatures)
224
+ ```
225
+
226
+
227
+ ## IExtraOptions
228
+
229
+ All repository operations accept an `options` parameter with these fields:
230
+
231
+ ```typescript
232
+ interface IExtraOptions {
233
+ /** Transaction context — switches the underlying Drizzle connector. */
234
+ transaction?: ITransaction;
235
+
236
+ /** Operation logging configuration. */
237
+ log?: { use: boolean; level?: TLogLevel };
238
+
239
+ /** If true, bypass the default filter configured in model settings (e.g., soft delete). */
240
+ shouldSkipDefaultFilter?: boolean;
241
+ }
242
+ ```
243
+
244
+ Additional fields are available as intersections on specific methods:
245
+
246
+ | Field | Type | Methods | Description |
247
+ |-------|------|---------|-------------|
248
+ | `shouldReturn` | `boolean` | `create`, `createAll`, `updateById`, `updateAll`, `deleteById`, `deleteAll` | If `false`, skip returning the data (only return count). Defaults to `true`. |
249
+ | `shouldQueryRange` | `boolean` | `find` | If `true`, returns `{ data, range: { start, end, total } }` instead of a plain array. |
250
+ | `force` | `boolean` | `updateAll`, `deleteAll`, `updateBy`, `deleteBy` | Required to allow empty `where` conditions. |
251
+
252
+
253
+ ## TDataRange
254
+
255
+ When `shouldQueryRange: true` is used, the range follows the HTTP Content-Range standard:
256
+
257
+ ```typescript
258
+ type TDataRange = {
259
+ start: number; // Inclusive start index (based on skip/offset)
260
+ end: number; // Inclusive end index
261
+ total: number; // Total matching records (ignoring limit)
262
+ };
263
+ ```
264
+
265
+
266
+ ## AbstractRepository Properties
267
+
268
+ ### dataSource
269
+
270
+ Getter/setter for the repository's datasource. Throws if accessed before being set (either via constructor or `@repository` auto-injection).
271
+
272
+ ```typescript
273
+ get dataSource(): IDataSource;
274
+ set dataSource(value: IDataSource);
275
+ setDataSource(opts: { dataSource: IDataSource }): void;
276
+ ```
277
+
278
+ ### entity
279
+
280
+ Lazy-resolved from `@repository` metadata on first access. Can also be set explicitly via constructor `entityClass` option.
281
+
282
+ ```typescript
283
+ get entity(): BaseEntity<EntitySchema>;
284
+ set entity(value: BaseEntity<EntitySchema>);
285
+ getEntity(): BaseEntity<EntitySchema>;
286
+ getEntitySchema(): EntitySchema;
287
+ ```
288
+
289
+ ### operationScope
290
+
291
+ Returns the repository's operation scope: `'READ_ONLY'`, `'WRITE_ONLY'`, or `'READ_WRITE'`.
292
+
293
+ ```typescript
294
+ get operationScope(): TRepositoryOperationScope;
295
+ ```
296
+
297
+ - `ReadableRepository` defaults to `READ_ONLY`
298
+ - `PersistableRepository` and `DefaultCRUDRepository` default to `READ_WRITE`
299
+
300
+ ### filterBuilder
301
+
302
+ Access to the `FilterBuilder` instance used for converting filter objects to Drizzle SQL.
303
+
304
+ ```typescript
305
+ get filterBuilder(): FilterBuilder;
306
+ ```
307
+
308
+ ### connector
309
+
310
+ Shortcut for `this.dataSource.connector`.
311
+
312
+ ```typescript
313
+ get connector(): IDataSource['connector'];
314
+ getConnector(): IDataSource['connector'];
315
+ ```
316
+
317
+ ### updateBuilder (PersistableRepository+)
318
+
319
+ Access to the `UpdateBuilder` instance used for transforming update data (including JSON path updates).
320
+
321
+ ```typescript
322
+ get updateBuilder(): UpdateBuilder;
323
+ ```
324
+
325
+
326
+ ## Key Methods
327
+
328
+ ### beginTransaction
329
+
330
+ Start a new database transaction through the repository's datasource:
331
+
332
+ ```typescript
333
+ await repo.beginTransaction(opts?: ITransactionOptions): Promise<ITransaction>;
334
+ ```
335
+
336
+ Usage:
337
+
338
+ ```typescript
339
+ const tx = await repo.beginTransaction();
340
+ try {
341
+ await repo.create({ data: { name: 'John' }, options: { transaction: tx } });
342
+ await repo.updateById({ id: '456', data: { count: 1 }, options: { transaction: tx } });
343
+ await tx.commit();
344
+ } catch (e) {
345
+ await tx.rollback();
346
+ }
347
+ ```
348
+
349
+ ### buildQuery
350
+
351
+ Converts a `TFilter` into Drizzle query options, automatically excluding hidden properties from `@model` settings:
352
+
353
+ ```typescript
354
+ buildQuery(opts: { filter: TFilter<DataObject> }): TDrizzleQueryOptions;
355
+ ```
356
+
357
+ The returned `TDrizzleQueryOptions` contains:
358
+
359
+ ```typescript
360
+ type TDrizzleQueryOptions = Partial<{
361
+ limit: number;
362
+ offset: number;
363
+ orderBy: SQL[];
364
+ where: SQL;
365
+ with: Record<string, true | TDrizzleQueryOptions>;
366
+ columns: Record<string, boolean>;
367
+ }>;
368
+ ```
369
+
370
+
371
+ ## Dual Query API
372
+
373
+ `ReadableRepository` automatically selects the optimal query strategy:
374
+
375
+ - **Core API** (Drizzle `select().from()`): ~15-20% faster for flat queries without relations or field selection
376
+ - **Query API** (Drizzle `connector.query[entity].findMany()`): Supports `include` for relations and `fields` for column selection
377
+
378
+ The selection is automatic based on filter complexity:
379
+
380
+ ```typescript
381
+ // Uses Core API (no include, no fields)
382
+ await repo.find({ filter: { where: { status: 'active' }, limit: 10 } });
383
+
384
+ // Uses Query API (has include)
385
+ await repo.find({
386
+ filter: {
387
+ where: { status: 'active' },
388
+ include: [{ relation: 'posts' }],
389
+ },
390
+ });
391
+
392
+ // Uses Query API (has fields)
393
+ await repo.find({
394
+ filter: {
395
+ fields: { id: true, name: true },
396
+ where: { status: 'active' },
397
+ },
398
+ });
399
+ ```
400
+
401
+
402
+ ## Constructor
403
+
404
+ ### AbstractRepository
405
+
406
+ ```typescript
407
+ constructor(
408
+ ds?: IDataSource,
409
+ opts?: {
410
+ scope?: string;
411
+ entityClass?: TClass<BaseEntity<EntitySchema>>;
412
+ operationScope?: TRepositoryOperationScope;
413
+ },
414
+ )
415
+ ```
416
+
417
+ - `ds` -- DataSource instance (optional; auto-injected by `@repository` decorator)
418
+ - `opts.scope` -- Logger scope name (defaults to class name)
419
+ - `opts.entityClass` -- Entity class to instantiate (optional; lazy-resolved from `@repository` metadata)
420
+ - `opts.operationScope` -- Defaults to `READ_ONLY`
421
+
422
+ ### ReadableRepository
423
+
424
+ ```typescript
425
+ constructor(
426
+ ds?: IDataSource,
427
+ opts?: { entityClass?: TClass<BaseEntity<EntitySchema>> },
428
+ )
429
+ ```
430
+
431
+ Forces `operationScope` to `READ_ONLY`.
432
+
433
+ ### PersistableRepository
434
+
435
+ ```typescript
436
+ constructor(
437
+ ds?: IDataSource,
438
+ opts?: { entityClass?: TClass<BaseEntity<EntitySchema>> },
439
+ )
440
+ ```
441
+
442
+ Forces `operationScope` to `READ_WRITE`. Also creates an `UpdateBuilder` instance.
59
443
 
60
444
 
61
445
  ## Documentation Sections
@@ -135,15 +519,29 @@ Composable mixins for repository features - `DefaultFilterMixin` and `FieldsVisi
135
519
  **Both `model` AND `dataSource` are required** for schema auto-discovery:
136
520
 
137
521
  ```typescript
138
- // WRONG - Missing dataSource
522
+ @repository({ model: Model, dataSource: DataSourceClass })
523
+ ```
524
+
525
+ The decorator accepts `IRepositoryMetadata`:
526
+
527
+ ```typescript
528
+ interface IRepositoryMetadata<Schema, Model, DataSource> {
529
+ model: TValueOrResolver<TClass<Model>>;
530
+ dataSource: string | TValueOrResolver<TClass<DataSource>>;
531
+ operationScope?: TRepositoryOperationScope; // 'READ_ONLY' | 'WRITE_ONLY' | 'READ_WRITE'
532
+ }
533
+ ```
534
+
535
+ ```typescript
536
+ // WRONG - Missing dataSource
139
537
  @repository({ model: User })
140
538
  export class UserRepository extends DefaultCRUDRepository<typeof User.schema> {}
141
539
 
142
- // WRONG - Missing model
540
+ // WRONG - Missing model
143
541
  @repository({ dataSource: PostgresDataSource })
144
542
  export class UserRepository extends DefaultCRUDRepository<typeof User.schema> {}
145
543
 
146
- // CORRECT
544
+ // CORRECT
147
545
  @repository({ model: User, dataSource: PostgresDataSource })
148
546
  export class UserRepository extends DefaultCRUDRepository<typeof User.schema> {}
149
547
  ```
@@ -179,19 +577,28 @@ export class UserRepository extends DefaultCRUDRepository<typeof User.schema> {
179
577
  }
180
578
  ```
181
579
 
580
+ ### Lazy Resolution
581
+
582
+ The `@repository` decorator enables two lazy resolution mechanisms:
583
+
584
+ 1. **Entity resolution**: The `entity` getter auto-resolves the model class from `@repository` metadata on first access, so you never need to pass `entityClass` manually.
585
+ 2. **DataSource resolution**: The DataSource is auto-injected at constructor param[0] unless an explicit `@inject` is present.
586
+
182
587
 
183
588
  ## Safety Features
184
589
 
185
590
  ### Empty Where Protection
186
591
 
187
- Prevents accidental mass updates/deletes:
592
+ Prevents accidental mass updates/deletes (in `PersistableRepository` and above):
188
593
 
189
594
  ```typescript
190
- // Throws error - empty where without force flag
595
+ // Throws error - empty where without force flag
191
596
  await repo.deleteAll({ where: {} });
597
+ await repo.updateAll({ data: { status: 'archived' }, where: {} });
192
598
 
193
- // Explicitly allow with force flag (logs warning)
599
+ // Explicitly allow with force flag (logs warning)
194
600
  await repo.deleteAll({ where: {}, options: { force: true } });
601
+ await repo.updateAll({ data: { status: 'archived' }, where: {}, options: { force: true } });
195
602
  ```
196
603
 
197
604
  | Scenario | `force: false` (default) | `force: true` |
@@ -199,6 +606,29 @@ await repo.deleteAll({ where: {}, options: { force: true } });
199
606
  | Empty `where` | Throws error | Logs warning, proceeds |
200
607
  | Valid `where` | Executes normally | Executes normally |
201
608
 
609
+ ### ReadableRepository Write Protection
610
+
611
+ All write methods (`create`, `createAll`, `updateById`, `updateAll`, `deleteById`, `deleteAll`) throw errors on `ReadableRepository`, enforcing the read-only scope at runtime.
612
+
613
+
614
+ ## TFilter Reference
615
+
616
+ ```typescript
617
+ type TFilter<T = any> = {
618
+ where?: TWhere<T>;
619
+ fields?: Partial<{ [K in keyof T]: boolean }> | Array<keyof T>;
620
+ include?: Array<{
621
+ relation: string;
622
+ scope?: TFilter;
623
+ shouldSkipDefaultFilter?: boolean;
624
+ }>;
625
+ order?: string[]; // e.g., ['createdAt DESC', 'name ASC']
626
+ limit?: number; // Defaults to 10
627
+ offset?: number;
628
+ skip?: number; // Alias for offset
629
+ };
630
+ ```
631
+
202
632
 
203
633
  ## Quick Reference
204
634
 
@@ -209,7 +639,10 @@ await repo.deleteAll({ where: {}, options: { force: true } });
209
639
  | Find by ID | `repo.findById({ id: '123' })` |
210
640
  | Find with relations | `repo.find({ filter: { include: [{ relation: 'posts' }] } })` |
211
641
  | Create one | `repo.create({ data: { name: 'John' } })` |
642
+ | Create without returning data | `repo.create({ data: { name: 'John' }, options: { shouldReturn: false } })` |
643
+ | Create many | `repo.createAll({ data: [{ name: 'A' }, { name: 'B' }] })` |
212
644
  | Update by ID | `repo.updateById({ id: '123', data: { name: 'Jane' } })` |
645
+ | Update by condition | `repo.updateAll({ data: { status: 'published' }, where: { status: 'draft' } })` |
213
646
  | Delete by ID | `repo.deleteById({ id: '123' })` |
214
647
  | Delete by condition | `repo.deleteBy({ where: { status: 'archived' } })` |
215
648
  | Soft delete | `repo.deleteById({ id: '123' })` (with `SoftDeletableRepository`) |
@@ -217,6 +650,8 @@ await repo.deleteAll({ where: {}, options: { force: true } });
217
650
  | Hard delete (bypass soft) | `repo.deleteById({ id: '123', options: { shouldHardDelete: true } })` |
218
651
  | Count matching | `repo.count({ where: { status: 'active' } })` |
219
652
  | Check exists | `repo.existsWith({ where: { email: 'test@example.com' } })` |
653
+ | Skip default filter | `repo.find({ filter, options: { shouldSkipDefaultFilter: true } })` |
654
+ | Use transaction | `repo.create({ data, options: { transaction: tx } })` |
220
655
 
221
656
 
222
657
  ## Next Steps