@venizia/ignis-docs 0.0.1-1 → 0.0.1-10
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/LICENSE.md +102 -0
- package/README.md +459 -0
- package/dist/mcp-server/common/config.d.ts +64 -0
- package/dist/mcp-server/common/config.d.ts.map +1 -0
- package/dist/mcp-server/common/config.js +82 -0
- package/dist/mcp-server/common/config.js.map +1 -0
- package/dist/mcp-server/common/index.d.ts +3 -0
- package/dist/mcp-server/common/index.d.ts.map +1 -0
- package/dist/mcp-server/common/index.js.map +1 -0
- package/dist/mcp-server/common/paths.d.ts.map +1 -0
- package/{mcp-server/dist → dist/mcp-server}/common/paths.js +13 -11
- package/dist/mcp-server/common/paths.js.map +1 -0
- package/{mcp-server/dist → dist/mcp-server}/helpers/docs.helper.d.ts +5 -5
- package/dist/mcp-server/helpers/docs.helper.d.ts.map +1 -0
- package/{mcp-server/dist → dist/mcp-server}/helpers/docs.helper.js +38 -34
- package/dist/mcp-server/helpers/docs.helper.js.map +1 -0
- package/dist/mcp-server/helpers/github.helper.d.ts +37 -0
- package/dist/mcp-server/helpers/github.helper.d.ts.map +1 -0
- package/dist/mcp-server/helpers/github.helper.js +100 -0
- package/dist/mcp-server/helpers/github.helper.js.map +1 -0
- package/dist/mcp-server/helpers/index.d.ts +4 -0
- package/dist/mcp-server/helpers/index.d.ts.map +1 -0
- package/{mcp-server/dist → dist/mcp-server}/helpers/index.js +1 -0
- package/dist/mcp-server/helpers/index.js.map +1 -0
- package/dist/mcp-server/helpers/logger.helper.d.ts.map +1 -0
- package/dist/mcp-server/helpers/logger.helper.js.map +1 -0
- package/{mcp-server/dist → dist/mcp-server}/index.d.ts.map +1 -1
- package/dist/mcp-server/index.js +90 -0
- package/dist/mcp-server/index.js.map +1 -0
- package/{mcp-server/dist → dist/mcp-server}/tools/base.tool.d.ts +8 -12
- package/dist/mcp-server/tools/base.tool.d.ts.map +1 -0
- package/{mcp-server/dist → dist/mcp-server}/tools/base.tool.js +3 -5
- package/dist/mcp-server/tools/base.tool.js.map +1 -0
- package/{mcp-server/dist/tools/get-doc-content.tool.d.ts → dist/mcp-server/tools/docs/get-document-content.tool.d.ts} +13 -17
- package/dist/mcp-server/tools/docs/get-document-content.tool.d.ts.map +1 -0
- package/{mcp-server/dist/tools/get-doc-content.tool.js → dist/mcp-server/tools/docs/get-document-content.tool.js} +20 -22
- package/dist/mcp-server/tools/docs/get-document-content.tool.js.map +1 -0
- package/{mcp-server/dist/tools/get-doc-metadata.tool.d.ts → dist/mcp-server/tools/docs/get-document-metadata.tool.d.ts} +21 -25
- package/dist/mcp-server/tools/docs/get-document-metadata.tool.d.ts.map +1 -0
- package/{mcp-server/dist/tools/get-doc-metadata.tool.js → dist/mcp-server/tools/docs/get-document-metadata.tool.js} +35 -27
- package/dist/mcp-server/tools/docs/get-document-metadata.tool.js.map +1 -0
- package/dist/mcp-server/tools/docs/get-package-overview.tool.d.ts +50 -0
- package/dist/mcp-server/tools/docs/get-package-overview.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/docs/get-package-overview.tool.js +221 -0
- package/dist/mcp-server/tools/docs/get-package-overview.tool.js.map +1 -0
- package/dist/mcp-server/tools/docs/index.d.ts +7 -0
- package/dist/mcp-server/tools/docs/index.d.ts.map +1 -0
- package/dist/mcp-server/tools/docs/index.js +23 -0
- package/dist/mcp-server/tools/docs/index.js.map +1 -0
- package/{mcp-server/dist/tools → dist/mcp-server/tools/docs}/list-categories.tool.d.ts +3 -3
- package/dist/mcp-server/tools/docs/list-categories.tool.d.ts.map +1 -0
- package/{mcp-server/dist/tools → dist/mcp-server/tools/docs}/list-categories.tool.js +10 -9
- package/dist/mcp-server/tools/docs/list-categories.tool.js.map +1 -0
- package/{mcp-server/dist/tools/list-docs.tool.d.ts → dist/mcp-server/tools/docs/list-documents.tool.d.ts} +5 -5
- package/dist/mcp-server/tools/docs/list-documents.tool.d.ts.map +1 -0
- package/{mcp-server/dist/tools/list-docs.tool.js → dist/mcp-server/tools/docs/list-documents.tool.js} +15 -14
- package/dist/mcp-server/tools/docs/list-documents.tool.js.map +1 -0
- package/{mcp-server/dist/tools/search-docs.tool.d.ts → dist/mcp-server/tools/docs/search-documents.tool.d.ts} +23 -19
- package/dist/mcp-server/tools/docs/search-documents.tool.d.ts.map +1 -0
- package/{mcp-server/dist/tools/search-docs.tool.js → dist/mcp-server/tools/docs/search-documents.tool.js} +29 -25
- package/dist/mcp-server/tools/docs/search-documents.tool.js.map +1 -0
- package/dist/mcp-server/tools/github/index.d.ts +5 -0
- package/dist/mcp-server/tools/github/index.d.ts.map +1 -0
- package/dist/mcp-server/tools/github/index.js +21 -0
- package/dist/mcp-server/tools/github/index.js.map +1 -0
- package/dist/mcp-server/tools/github/list-project-files.tool.d.ts +28 -0
- package/dist/mcp-server/tools/github/list-project-files.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/github/list-project-files.tool.js +98 -0
- package/dist/mcp-server/tools/github/list-project-files.tool.js.map +1 -0
- package/dist/mcp-server/tools/github/search-code.tool.d.ts +42 -0
- package/dist/mcp-server/tools/github/search-code.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/github/search-code.tool.js +194 -0
- package/dist/mcp-server/tools/github/search-code.tool.js.map +1 -0
- package/dist/mcp-server/tools/github/verify-dependencies.tool.d.ts +55 -0
- package/dist/mcp-server/tools/github/verify-dependencies.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/github/verify-dependencies.tool.js +167 -0
- package/dist/mcp-server/tools/github/verify-dependencies.tool.js.map +1 -0
- package/dist/mcp-server/tools/github/view-source-file.tool.d.ts +26 -0
- package/dist/mcp-server/tools/github/view-source-file.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/github/view-source-file.tool.js +91 -0
- package/dist/mcp-server/tools/github/view-source-file.tool.js.map +1 -0
- package/dist/mcp-server/tools/index.d.ts +4 -0
- package/dist/mcp-server/tools/index.d.ts.map +1 -0
- package/dist/mcp-server/tools/index.js +22 -0
- package/dist/mcp-server/tools/index.js.map +1 -0
- package/package.json +46 -23
- package/wiki/changelogs/2025-12-16-initial-architecture.md +145 -0
- package/wiki/changelogs/2025-12-16-model-repo-datasource-refactor.md +300 -0
- package/wiki/changelogs/2025-12-17-refactor.md +90 -0
- package/wiki/changelogs/2025-12-18-performance-optimizations.md +130 -0
- package/wiki/changelogs/2025-12-18-repository-validation-security.md +249 -0
- package/wiki/changelogs/index.md +33 -0
- package/wiki/changelogs/planned-transaction-support.md +216 -0
- package/wiki/changelogs/template.md +123 -0
- package/wiki/get-started/5-minute-quickstart.md +1 -1
- package/wiki/get-started/best-practices/api-usage-examples.md +54 -8
- package/wiki/get-started/best-practices/architectural-patterns.md +43 -2
- package/wiki/get-started/best-practices/code-style-standards.md +41 -0
- package/wiki/get-started/best-practices/common-pitfalls.md +5 -3
- package/wiki/get-started/best-practices/contribution-workflow.md +40 -6
- package/wiki/get-started/best-practices/data-modeling.md +177 -0
- package/wiki/get-started/best-practices/security-guidelines.md +3 -1
- package/wiki/get-started/building-a-crud-api.md +63 -78
- package/wiki/get-started/core-concepts/components.md +4 -2
- package/wiki/get-started/core-concepts/controllers.md +14 -14
- package/wiki/get-started/core-concepts/dependency-injection.md +13 -1
- package/wiki/get-started/core-concepts/persistent.md +383 -431
- package/wiki/get-started/core-concepts/services.md +21 -27
- package/wiki/get-started/mcp-docs-server.md +130 -32
- package/wiki/get-started/philosophy.md +198 -25
- package/wiki/get-started/quickstart.md +1 -1
- package/wiki/public/logo.svg +1 -0
- package/wiki/references/base/application.md +5 -5
- package/wiki/references/base/components.md +1 -1
- package/wiki/references/base/controllers.md +43 -17
- package/wiki/references/base/datasources.md +195 -33
- package/wiki/references/base/dependency-injection.md +8 -7
- package/wiki/references/base/models.md +713 -25
- package/wiki/references/base/repositories.md +475 -22
- package/wiki/references/base/services.md +2 -2
- package/wiki/references/components/authentication.md +228 -10
- package/wiki/references/components/health-check.md +1 -1
- package/wiki/references/components/index.md +4 -2
- package/wiki/references/components/static-asset.md +1289 -0
- package/wiki/references/components/swagger.md +1 -1
- package/wiki/references/helpers/error.md +2 -2
- package/wiki/references/helpers/inversion.md +29 -14
- package/wiki/references/helpers/storage.md +538 -11
- package/wiki/references/src-details/core.md +21 -6
- package/wiki/references/src-details/docs.md +19 -9
- package/wiki/references/src-details/inversion.md +4 -4
- package/wiki/references/src-details/mcp-server.md +185 -234
- package/wiki/references/utilities/index.md +1 -1
- package/wiki/references/utilities/request.md +162 -3
- package/mcp-server/dist/common/config.d.ts +0 -27
- package/mcp-server/dist/common/config.d.ts.map +0 -1
- package/mcp-server/dist/common/config.js +0 -27
- package/mcp-server/dist/common/config.js.map +0 -1
- package/mcp-server/dist/common/index.d.ts +0 -3
- package/mcp-server/dist/common/index.d.ts.map +0 -1
- package/mcp-server/dist/common/index.js.map +0 -1
- package/mcp-server/dist/common/paths.d.ts.map +0 -1
- package/mcp-server/dist/common/paths.js.map +0 -1
- package/mcp-server/dist/helpers/docs.helper.d.ts.map +0 -1
- package/mcp-server/dist/helpers/docs.helper.js.map +0 -1
- package/mcp-server/dist/helpers/index.d.ts +0 -3
- package/mcp-server/dist/helpers/index.d.ts.map +0 -1
- package/mcp-server/dist/helpers/index.js.map +0 -1
- package/mcp-server/dist/helpers/logger.helper.d.ts.map +0 -1
- package/mcp-server/dist/helpers/logger.helper.js.map +0 -1
- package/mcp-server/dist/index.js +0 -62
- package/mcp-server/dist/index.js.map +0 -1
- package/mcp-server/dist/tools/base.tool.d.ts.map +0 -1
- package/mcp-server/dist/tools/base.tool.js.map +0 -1
- package/mcp-server/dist/tools/get-doc-content.tool.d.ts.map +0 -1
- package/mcp-server/dist/tools/get-doc-content.tool.js.map +0 -1
- package/mcp-server/dist/tools/get-doc-metadata.tool.d.ts.map +0 -1
- package/mcp-server/dist/tools/get-doc-metadata.tool.js.map +0 -1
- package/mcp-server/dist/tools/index.d.ts +0 -8
- package/mcp-server/dist/tools/index.d.ts.map +0 -1
- package/mcp-server/dist/tools/index.js +0 -18
- package/mcp-server/dist/tools/index.js.map +0 -1
- package/mcp-server/dist/tools/list-categories.tool.d.ts.map +0 -1
- package/mcp-server/dist/tools/list-categories.tool.js.map +0 -1
- package/mcp-server/dist/tools/list-docs.tool.d.ts.map +0 -1
- package/mcp-server/dist/tools/list-docs.tool.js.map +0 -1
- package/mcp-server/dist/tools/search-docs.tool.d.ts.map +0 -1
- package/mcp-server/dist/tools/search-docs.tool.js.map +0 -1
- /package/{mcp-server/dist → dist/mcp-server}/common/index.js +0 -0
- /package/{mcp-server/dist → dist/mcp-server}/common/paths.d.ts +0 -0
- /package/{mcp-server/dist → dist/mcp-server}/helpers/logger.helper.d.ts +0 -0
- /package/{mcp-server/dist → dist/mcp-server}/helpers/logger.helper.js +0 -0
- /package/{mcp-server/dist → dist/mcp-server}/index.d.ts +0 -0
|
@@ -134,12 +134,10 @@ export type TTodo = TTableObject<TTodoSchema>;
|
|
|
134
134
|
|
|
135
135
|
// 4. Create the Entity class, decorated with @model
|
|
136
136
|
@model({ type: 'entity' })
|
|
137
|
-
export class Todo extends BaseEntity<
|
|
138
|
-
static
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
super({ name: Todo.TABLE_NAME, schema: todoTable });
|
|
142
|
-
}
|
|
137
|
+
export class Todo extends BaseEntity<typeof Todo.schema> {
|
|
138
|
+
static override schema = todoTable;
|
|
139
|
+
static override relations = () => todoRelations.definitions;
|
|
140
|
+
static override TABLE_NAME = 'Todo';
|
|
143
141
|
}
|
|
144
142
|
```
|
|
145
143
|
|
|
@@ -203,7 +201,6 @@ Create `src/datasources/postgres.datasource.ts`:
|
|
|
203
201
|
|
|
204
202
|
```typescript
|
|
205
203
|
// src/datasources/postgres.datasource.ts
|
|
206
|
-
import { Todo, todoRelations, todoTable } from '@/models/todo.model';
|
|
207
204
|
import {
|
|
208
205
|
BaseDataSource,
|
|
209
206
|
datasource,
|
|
@@ -214,61 +211,61 @@ import { drizzle } from 'drizzle-orm/node-postgres';
|
|
|
214
211
|
import { Pool } from 'pg';
|
|
215
212
|
|
|
216
213
|
interface IDSConfigs {
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
database?: string;
|
|
223
|
-
};
|
|
214
|
+
host: string;
|
|
215
|
+
port: number;
|
|
216
|
+
database: string;
|
|
217
|
+
user: string;
|
|
218
|
+
password: string;
|
|
224
219
|
}
|
|
225
220
|
|
|
226
|
-
|
|
221
|
+
/**
|
|
222
|
+
* PostgresDataSource with auto-discovery support.
|
|
223
|
+
*
|
|
224
|
+
* How it works:
|
|
225
|
+
* 1. @repository decorator binds model to datasource
|
|
226
|
+
* 2. When configure() is called, getSchema() auto-discovers all bound models
|
|
227
|
+
* 3. Drizzle is initialized with the auto-discovered schema
|
|
228
|
+
*/
|
|
229
|
+
@datasource({ driver: 'node-postgres' })
|
|
227
230
|
export class PostgresDataSource extends BaseDataSource<TNodePostgresConnector, IDSConfigs> {
|
|
228
231
|
constructor() {
|
|
229
232
|
super({
|
|
230
233
|
name: PostgresDataSource.name,
|
|
231
|
-
|
|
234
|
+
// Driver is read from @datasource decorator - no need to pass here!
|
|
232
235
|
config: {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
database: process.env.APP_ENV_POSTGRES_DATABASE,
|
|
239
|
-
},
|
|
236
|
+
host: process.env.APP_ENV_POSTGRES_HOST ?? 'localhost',
|
|
237
|
+
port: +(process.env.APP_ENV_POSTGRES_PORT ?? 5432),
|
|
238
|
+
database: process.env.APP_ENV_POSTGRES_DATABASE ?? 'todo_db',
|
|
239
|
+
user: process.env.APP_ENV_POSTGRES_USERNAME ?? 'postgres',
|
|
240
|
+
password: process.env.APP_ENV_POSTGRES_PASSWORD ?? '',
|
|
240
241
|
},
|
|
241
|
-
//
|
|
242
|
-
schema: Object.assign(
|
|
243
|
-
{},
|
|
244
|
-
{ [Todo.TABLE_NAME]: todoTable },
|
|
245
|
-
todoRelations.relations,
|
|
246
|
-
),
|
|
242
|
+
// NO schema property - auto-discovered from @repository bindings!
|
|
247
243
|
});
|
|
248
244
|
}
|
|
249
245
|
|
|
250
246
|
override configure(): ValueOrPromise<void> {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
247
|
+
// getSchema() auto-discovers models from @repository bindings
|
|
248
|
+
const schema = this.getSchema();
|
|
249
|
+
|
|
250
|
+
// Log discovered schema for debugging
|
|
251
|
+
const schemaKeys = Object.keys(schema);
|
|
252
|
+
this.logger.debug(
|
|
253
|
+
'[configure] Auto-discovered schema | Schema + Relations (%s): %o',
|
|
254
|
+
schemaKeys.length,
|
|
255
|
+
schemaKeys,
|
|
256
|
+
);
|
|
257
|
+
|
|
258
|
+
const client = new Pool(this.settings);
|
|
259
|
+
this.connector = drizzle({ client, schema });
|
|
264
260
|
}
|
|
265
261
|
}
|
|
266
262
|
```
|
|
267
263
|
|
|
268
264
|
**Key Points:**
|
|
269
|
-
-
|
|
265
|
+
- Schema is auto-discovered from `@repository` decorators - no manual registration needed
|
|
266
|
+
- Uses `getSchema()` for lazy schema resolution (resolves when all models are loaded)
|
|
270
267
|
- Uses environment variables for connection config
|
|
271
|
-
- Implements connection lifecycle methods
|
|
268
|
+
- Implements connection lifecycle methods (`connect()`, `disconnect()`)
|
|
272
269
|
|
|
273
270
|
> **Deep Dive:** See [DataSources Reference](../references/base/datasources.md) for advanced configuration and multiple database support.
|
|
274
271
|
|
|
@@ -280,26 +277,15 @@ Create `src/repositories/todo.repository.ts`:
|
|
|
280
277
|
|
|
281
278
|
```typescript
|
|
282
279
|
// src/repositories/todo.repository.ts
|
|
283
|
-
import { Todo
|
|
284
|
-
import {
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
@repository
|
|
292
|
-
export class TodoRepository extends DefaultCRUDRepository<TTodoSchema> {
|
|
293
|
-
constructor(
|
|
294
|
-
@inject({ key: 'datasources.PostgresDataSource' })
|
|
295
|
-
dataSource: IDataSource,
|
|
296
|
-
) {
|
|
297
|
-
super({
|
|
298
|
-
dataSource,
|
|
299
|
-
entityClass: Todo,
|
|
300
|
-
relations: todoRelations.definitions,
|
|
301
|
-
});
|
|
302
|
-
}
|
|
280
|
+
import { Todo } from '@/models/todo.model';
|
|
281
|
+
import { PostgresDataSource } from '@/datasources/postgres.datasource';
|
|
282
|
+
import { DefaultCRUDRepository, repository } from '@venizia/ignis';
|
|
283
|
+
|
|
284
|
+
// Both 'model' and 'dataSource' are required for schema auto-discovery
|
|
285
|
+
@repository({ model: Todo, dataSource: PostgresDataSource })
|
|
286
|
+
export class TodoRepository extends DefaultCRUDRepository<typeof Todo.schema> {
|
|
287
|
+
// No constructor needed! DataSource and relations are auto-resolved
|
|
288
|
+
// from the @repository decorator and entity's static properties
|
|
303
289
|
}
|
|
304
290
|
```
|
|
305
291
|
|
|
@@ -358,15 +344,15 @@ export class TodoController extends _Controller {
|
|
|
358
344
|
**Auto-generated Endpoints:**
|
|
359
345
|
| Method | Path | Description |
|
|
360
346
|
|--------|------|-------------|
|
|
361
|
-
| GET | `/todos` | List all todos |
|
|
362
|
-
| GET | `/todos/:id` | Get todo by ID |
|
|
363
|
-
| GET | `/todos/find-one` | Find one todo by filter |
|
|
364
|
-
| GET | `/todos/count` | Count todos |
|
|
365
|
-
| POST | `/todos` | Create todo |
|
|
366
|
-
| PATCH | `/todos/:id` | Update todo by ID |
|
|
367
|
-
| PATCH | `/todos` | Update multiple todos |
|
|
368
|
-
| DELETE | `/todos/:id` | Delete todo by ID |
|
|
369
|
-
| DELETE | `/todos` | Delete multiple todos |
|
|
347
|
+
| GET | `/todos` | List all todos (find) |
|
|
348
|
+
| GET | `/todos/:id` | Get todo by ID (findById) |
|
|
349
|
+
| GET | `/todos/find-one` | Find one todo by filter (findOne) |
|
|
350
|
+
| GET | `/todos/count` | Count todos (count) |
|
|
351
|
+
| POST | `/todos` | Create todo (create) |
|
|
352
|
+
| PATCH | `/todos/:id` | Update todo by ID (updateById) |
|
|
353
|
+
| PATCH | `/todos` | Update multiple todos by filter (updateBy) |
|
|
354
|
+
| DELETE | `/todos/:id` | Delete todo by ID (deleteById) |
|
|
355
|
+
| DELETE | `/todos` | Delete multiple todos by filter (deleteBy) |
|
|
370
356
|
|
|
371
357
|
> **Deep Dive:** See [ControllerFactory Reference](../references/base/controllers.md#controllerfactory) for customization options.
|
|
372
358
|
|
|
@@ -639,8 +625,7 @@ Now that you've built the Todo API, try building a **User** feature on your own!
|
|
|
639
625
|
|
|
640
626
|
**Challenge checklist:**
|
|
641
627
|
- [ ] Create `src/models/user.model.ts`
|
|
642
|
-
- [ ]
|
|
643
|
-
- [ ] Create `src/repositories/user.repository.ts`
|
|
628
|
+
- [ ] Create `src/repositories/user.repository.ts` (this auto-registers User with PostgresDataSource)
|
|
644
629
|
- [ ] Create `src/controllers/user.controller.ts`
|
|
645
630
|
- [ ] Register repository and controller in `application.ts`
|
|
646
631
|
- [ ] Run migration: `bun run migrate:dev`
|
|
@@ -660,7 +645,7 @@ For complex validation or business rules, create a Service layer:
|
|
|
660
645
|
|
|
661
646
|
```typescript
|
|
662
647
|
// src/services/todo.service.ts
|
|
663
|
-
import { BaseService, inject } from '@venizia/ignis';
|
|
648
|
+
import { BaseService, inject, getError } from '@venizia/ignis';
|
|
664
649
|
import { TodoRepository } from '@/repositories/todo.repository';
|
|
665
650
|
|
|
666
651
|
export class TodoService extends BaseService {
|
|
@@ -674,7 +659,7 @@ export class TodoService extends BaseService {
|
|
|
674
659
|
async createTodo(data: any) {
|
|
675
660
|
// Business logic validation
|
|
676
661
|
if (data.title.length < 3) {
|
|
677
|
-
throw
|
|
662
|
+
throw getError({ message: 'Title too short' });
|
|
678
663
|
}
|
|
679
664
|
|
|
680
665
|
// Check for duplicates
|
|
@@ -682,7 +667,7 @@ export class TodoService extends BaseService {
|
|
|
682
667
|
filter: { where: { title: data.title } },
|
|
683
668
|
});
|
|
684
669
|
if (existing) {
|
|
685
|
-
throw
|
|
670
|
+
throw getError({ message: 'Todo already exists' });
|
|
686
671
|
}
|
|
687
672
|
|
|
688
673
|
return this.todoRepository.create({ data });
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Components
|
|
2
2
|
|
|
3
|
-
Components are reusable, pluggable modules that encapsulate features
|
|
3
|
+
Components are reusable, pluggable modules that encapsulate a group of related features. A component acts as a powerful container for various resources—including providers, services, controllers, repositories, and even entire mini-applications—making it easy to share and integrate complex functionality across projects.
|
|
4
4
|
|
|
5
5
|
> **Deep Dive:** See [Components Reference](../../references/base/components.md) for technical details.
|
|
6
6
|
|
|
@@ -8,9 +8,11 @@ Components are reusable, pluggable modules that encapsulate features like authen
|
|
|
8
8
|
|
|
9
9
|
A component is a class that extends `BaseComponent` and is responsible for:
|
|
10
10
|
|
|
11
|
-
- **Binding Dependencies**: Registering services, controllers, providers, or other resources with the application's dependency injection container.
|
|
11
|
+
- **Binding Dependencies**: Registering services, controllers, repositories, providers, or other resources with the application's dependency injection container.
|
|
12
12
|
- **Configuring Features**: Setting up middlewares, initializing services, or performing any other setup required for the feature to work.
|
|
13
13
|
|
|
14
|
+
A single component can bundle everything needed for a specific domain—for example, an "AuthComponent" might include multiple services for token management, repositories for user data, and controllers for login/signup endpoints, essentially functioning as a plug-and-play mini-application.
|
|
15
|
+
|
|
14
16
|
`Ignis` comes with several built-in components, which you can explore in the [**Components Reference**](../../references/components/) section:
|
|
15
17
|
|
|
16
18
|
- **`AuthenticateComponent`**: Sets up JWT-based authentication.
|
|
@@ -9,7 +9,7 @@ Controllers handle HTTP requests and return responses - they're your API endpoin
|
|
|
9
9
|
Extend `BaseController` and use decorators to define routes:
|
|
10
10
|
|
|
11
11
|
```typescript
|
|
12
|
-
import { BaseController, controller, get, jsonResponse, z } from '@venizia/ignis';
|
|
12
|
+
import { BaseController, controller, get, jsonResponse, z, HTTP } from '@venizia/ignis';
|
|
13
13
|
import { Context } from 'hono';
|
|
14
14
|
|
|
15
15
|
@controller({ path: '/users' })
|
|
@@ -29,7 +29,7 @@ export class UserController extends BaseController {
|
|
|
29
29
|
},
|
|
30
30
|
})
|
|
31
31
|
getAllUsers(c: Context) {
|
|
32
|
-
return c.json([{ id: '1', name: 'John Doe' }]);
|
|
32
|
+
return c.json([{ id: '1', name: 'John Doe' }], HTTP.ResultCodes.RS_2.Ok);
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
```
|
|
@@ -177,7 +177,7 @@ const GetUsersRoute = {
|
|
|
177
177
|
this.defineRoute({
|
|
178
178
|
configs: GetUsersRoute,
|
|
179
179
|
handler: (c: TRouteContext<typeof GetUsersRoute>) => { // Return type is automatically inferred
|
|
180
|
-
return c.json([{ id: 1, name: 'John Doe' }]);
|
|
180
|
+
return c.json([{ id: 1, name: 'John Doe' }], HTTP.ResultCodes.RS_2.Ok);
|
|
181
181
|
},
|
|
182
182
|
});
|
|
183
183
|
```
|
|
@@ -187,7 +187,7 @@ this.defineRoute({
|
|
|
187
187
|
This method offers a fluent API for defining routes, similar to `defineRoute`, but structured for chaining. It also benefits from `TRouteContext` for type safety.
|
|
188
188
|
|
|
189
189
|
```typescript
|
|
190
|
-
import { jsonResponse, z, TRouteContext } from '@venizia/ignis';
|
|
190
|
+
import { jsonResponse, z, TRouteContext, HTTP } from '@venizia/ignis';
|
|
191
191
|
|
|
192
192
|
// ... inside the binding() method
|
|
193
193
|
|
|
@@ -205,7 +205,7 @@ this.bindRoute({
|
|
|
205
205
|
}).to({
|
|
206
206
|
handler: (c: TRouteContext<typeof GetUserByIdRoute>) => { // Return type is automatically inferred
|
|
207
207
|
const { id } = c.req.param();
|
|
208
|
-
return c.json({ id: id, name: 'John Doe' });
|
|
208
|
+
return c.json({ id: id, name: 'John Doe' }, HTTP.ResultCodes.RS_2.Ok);
|
|
209
209
|
},
|
|
210
210
|
});
|
|
211
211
|
```
|
|
@@ -255,17 +255,17 @@ export class ConfigurationController extends _Controller {
|
|
|
255
255
|
```
|
|
256
256
|
The `ControllerFactory.defineCrudController` method automatically sets up the following routes based on your entity schema:
|
|
257
257
|
|
|
258
|
-
| Name | Method | Path | Description |
|
|
258
|
+
| Route Name | Method | Path | Description |
|
|
259
259
|
| :--- | :--- | :--- | :--- |
|
|
260
260
|
| `count` | `GET` | `/count` | Get the number of records matching a filter. |
|
|
261
261
|
| `find` | `GET` | `/` | Retrieve all records matching a filter. |
|
|
262
262
|
| `findById` | `GET` | `/:id` | Retrieve a single record by its ID. |
|
|
263
263
|
| `findOne` | `GET` | `/find-one` | Retrieve a single record matching a filter. |
|
|
264
264
|
| `create` | `POST` | `/` | Create a new record. |
|
|
265
|
-
| `updateById` | `PATCH` | `/:id` | Update a record by its ID. |
|
|
266
|
-
| `
|
|
267
|
-
| `deleteById` | `DELETE` | `/:id` | Delete a record by its ID. |
|
|
268
|
-
| `
|
|
265
|
+
| `updateById` | `PATCH` | `/:id` | Update a single record by its ID. |
|
|
266
|
+
| `updateBy` | `PATCH` | `/` | Update multiple records matching a `where` filter. |
|
|
267
|
+
| `deleteById` | `DELETE` | `/:id` | Delete a single record by its ID. |
|
|
268
|
+
| `deleteBy` | `DELETE` | `/` | Delete multiple records matching a `where` filter. |
|
|
269
269
|
|
|
270
270
|
:::info Customization
|
|
271
271
|
The `ControllerFactory` is highly customizable. You can override the Zod schemas for any of the generated routes to add, remove, or modify fields for request validation and response shapes. You can also configure other behaviors, like making delete operations return the deleted records.
|
|
@@ -368,7 +368,7 @@ When you define Zod schemas in your route's `request` configuration (whether wit
|
|
|
368
368
|
|
|
369
369
|
```typescript
|
|
370
370
|
import { z } from '@hono/zod-openapi';
|
|
371
|
-
import { jsonContent, put } from '@venizia/ignis';
|
|
371
|
+
import { jsonContent, put, HTTP } from '@venizia/ignis';
|
|
372
372
|
|
|
373
373
|
// ... inside a controller class
|
|
374
374
|
|
|
@@ -397,7 +397,7 @@ updateUser(c: Context) {
|
|
|
397
397
|
console.log('Notification is enabled.');
|
|
398
398
|
}
|
|
399
399
|
|
|
400
|
-
return c.json({ success: true, id, ...userUpdateData });
|
|
400
|
+
return c.json({ success: true, id, ...userUpdateData }, HTTP.ResultCodes.RS_2.Ok);
|
|
401
401
|
}
|
|
402
402
|
```
|
|
403
403
|
|
|
@@ -405,7 +405,7 @@ Using `c.req.valid()` is the recommended way to access request data as it ensure
|
|
|
405
405
|
|
|
406
406
|
```typescript
|
|
407
407
|
import { z } from '@hono/zod-openapi';
|
|
408
|
-
import { jsonContent, put, TRouteContext } from '@venizia/ignis';
|
|
408
|
+
import { jsonContent, put, TRouteContext, HTTP } from '@venizia/ignis';
|
|
409
409
|
|
|
410
410
|
// ... inside a controller class
|
|
411
411
|
|
|
@@ -434,7 +434,7 @@ updateUser(c: TRouteContext<typeof updateUserConfig>) {
|
|
|
434
434
|
console.log('Notification is enabled.');
|
|
435
435
|
}
|
|
436
436
|
|
|
437
|
-
return c.json({ success: true, id, ...userUpdateData });
|
|
437
|
+
return c.json({ success: true, id, ...userUpdateData }, HTTP.ResultCodes.RS_2.Ok);
|
|
438
438
|
}
|
|
439
439
|
```
|
|
440
440
|
|
|
@@ -50,7 +50,7 @@ Before a dependency can be injected, it must be **bound** to the container. This
|
|
|
50
50
|
|
|
51
51
|
The `Application` class provides helper methods for common resource types. These automatically create a binding with a conventional key.
|
|
52
52
|
|
|
53
|
-
| Method |
|
|
53
|
+
| Method | Default Key |
|
|
54
54
|
| :--- | :--- |
|
|
55
55
|
| `app.service(UserService)` | `services.UserService` |
|
|
56
56
|
| `app.repository(UserRepository)` | `repositories.UserRepository` |
|
|
@@ -58,6 +58,18 @@ The `Application` class provides helper methods for common resource types. These
|
|
|
58
58
|
| `app.controller(UserController)` | `controllers.UserController` |
|
|
59
59
|
| `app.component(MyComponent)` | `components.MyComponent` |
|
|
60
60
|
|
|
61
|
+
All these methods accept an optional second parameter to customize the binding key:
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
// Default binding (key: 'controllers.UserController')
|
|
65
|
+
app.controller(UserController);
|
|
66
|
+
|
|
67
|
+
// Custom binding key
|
|
68
|
+
app.controller(UserController, {
|
|
69
|
+
binding: { namespace: 'controllers', key: 'CustomUserController' }
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
61
73
|
### Custom Bindings
|
|
62
74
|
|
|
63
75
|
For other values or more complex setups, use the `bind` method directly.
|