@venizia/ignis-docs 0.0.1-5 → 0.0.1-6
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/package.json +5 -4
- package/wiki/public/logo.svg +1 -0
- package/wiki/references/base/models.md +319 -1
- package/wiki/references/components/index.md +3 -1
- package/wiki/references/components/static-asset.md +1289 -0
- package/wiki/references/helpers/storage.md +538 -11
- package/wiki/references/utilities/index.md +1 -1
- package/wiki/references/utilities/request.md +150 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@venizia/ignis-docs",
|
|
3
|
-
"version": "0.0.1-
|
|
3
|
+
"version": "0.0.1-6",
|
|
4
4
|
"description": "Documentation and MCP Server for Ignis Framework",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ignis",
|
|
@@ -54,7 +54,8 @@
|
|
|
54
54
|
"README.md",
|
|
55
55
|
"LICENSE.md",
|
|
56
56
|
"mcp-server/dist",
|
|
57
|
-
"wiki"
|
|
57
|
+
"wiki",
|
|
58
|
+
"!**/*.tsbuildinfo"
|
|
58
59
|
],
|
|
59
60
|
"publishConfig": {
|
|
60
61
|
"access": "public"
|
|
@@ -94,7 +95,7 @@
|
|
|
94
95
|
"bugs": {
|
|
95
96
|
"url": "https://github.com/VENIZIA-AI/ignis/issues"
|
|
96
97
|
},
|
|
97
|
-
"homepage": "https://github.
|
|
98
|
+
"homepage": "https://venizia-ai.github.io/ignis",
|
|
98
99
|
"license": "MIT",
|
|
99
100
|
"dependencies": {
|
|
100
101
|
"@mastra/core": "^0.24.6",
|
|
@@ -110,7 +111,7 @@
|
|
|
110
111
|
"@braintree/sanitize-url": "^7.1.1",
|
|
111
112
|
"@types/bun": "^1.3.4",
|
|
112
113
|
"@types/glob": "^8.1.0",
|
|
113
|
-
"@venizia/dev-configs": "^0.0.1-
|
|
114
|
+
"@venizia/dev-configs": "^0.0.1-4",
|
|
114
115
|
"eslint": "^9.36.0",
|
|
115
116
|
"glob": "^10.4.2",
|
|
116
117
|
"prettier": "^3.6.2",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 92.27 122.88" style="enable-background:new 0 0 92.27 122.88" xml:space="preserve"><style type="text/css">.st0{fill-rule:evenodd;clip-rule:evenodd;fill:#EC6F59;} .st1{fill-rule:evenodd;clip-rule:evenodd;fill:#FAD15C;}</style><g><path class="st0" d="M18.61,54.89C15.7,28.8,30.94,10.45,59.52,0C42.02,22.71,74.44,47.31,76.23,70.89 c4.19-7.15,6.57-16.69,7.04-29.45c21.43,33.62,3.66,88.57-43.5,80.67c-4.33-0.72-8.5-2.09-12.3-4.13C10.27,108.8,0,88.79,0,69.68 C0,57.5,5.21,46.63,11.95,37.99C12.85,46.45,14.77,52.76,18.61,54.89L18.61,54.89z"/><path class="st1" d="M33.87,92.58c-4.86-12.55-4.19-32.82,9.42-39.93c0.1,23.3,23.05,26.27,18.8,51.14 c3.92-4.44,5.9-11.54,6.25-17.15c6.22,14.24,1.34,25.63-7.53,31.43c-26.97,17.64-50.19-18.12-34.75-37.72 C26.53,84.73,31.89,91.49,33.87,92.58L33.87,92.58z"/></g></svg>
|
|
@@ -79,7 +79,7 @@ Enrichers are helper functions located in `packages/core/src/base/models/enriche
|
|
|
79
79
|
| Enricher Function | Purpose |
|
|
80
80
|
| :--- | :--- |
|
|
81
81
|
| **`generateIdColumnDefs`** | Adds a primary key `id` column (string UUID or numeric serial). |
|
|
82
|
-
| **`generateTzColumnDefs`** | Adds `createdAt` and `
|
|
82
|
+
| **`generateTzColumnDefs`** | Adds `createdAt`, `modifiedAt`, and `deletedAt` timestamp columns with timezone support. |
|
|
83
83
|
| **`generateUserAuditColumnDefs`** | Adds `createdBy` and `modifiedBy` columns to track user audit information. |
|
|
84
84
|
| **`generateDataTypeColumnDefs`** | Adds generic data type columns (`dataType`, `nValue`, `tValue`, `bValue`, `jValue`, `boValue`) for flexible data storage. |
|
|
85
85
|
| **`generatePrincipalColumnDefs`** | Adds polymorphic fields for associating with different principal types. |
|
|
@@ -102,3 +102,321 @@ export const myTable = pgTable('MyTable', {
|
|
|
102
102
|
name: text('name').notNull(),
|
|
103
103
|
});
|
|
104
104
|
```
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Detailed Enricher Reference
|
|
109
|
+
|
|
110
|
+
### `generateTzColumnDefs`
|
|
111
|
+
|
|
112
|
+
Adds timestamp columns for tracking entity creation, modification, and soft deletion.
|
|
113
|
+
|
|
114
|
+
**File:** `packages/core/src/base/models/enrichers/tz.enricher.ts`
|
|
115
|
+
|
|
116
|
+
#### Signature
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
generateTzColumnDefs(opts?: TTzEnricherOptions): TTzEnricherResult
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
#### Options (`TTzEnricherOptions`)
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
type TTzEnricherOptions = {
|
|
126
|
+
created?: { columnName: string; withTimezone: boolean };
|
|
127
|
+
modified?: { enable: boolean; columnName: string; withTimezone: boolean };
|
|
128
|
+
deleted?: { enable: boolean; columnName: string; withTimezone: boolean };
|
|
129
|
+
};
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**Default values:**
|
|
133
|
+
- `created`: `{ columnName: 'created_at', withTimezone: true }`
|
|
134
|
+
- `modified`: `{ enable: true, columnName: 'modified_at', withTimezone: true }`
|
|
135
|
+
- `deleted`: `{ enable: false }` (disabled by default)
|
|
136
|
+
|
|
137
|
+
#### Generated Columns
|
|
138
|
+
|
|
139
|
+
| Column | Type | Constraints | Default | Description |
|
|
140
|
+
|--------|------|-------------|---------|-------------|
|
|
141
|
+
| `createdAt` | `timestamp` | `NOT NULL` | `now()` | When the record was created (always included) |
|
|
142
|
+
| `modifiedAt` | `timestamp` | `NOT NULL` | `now()` | When the record was last modified (optional, enabled by default) |
|
|
143
|
+
| `deletedAt` | `timestamp` | nullable | `null` | When the record was soft-deleted (optional, **disabled by default**) |
|
|
144
|
+
|
|
145
|
+
#### Usage Examples
|
|
146
|
+
|
|
147
|
+
**Basic usage (default columns):**
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
import { pgTable, text } from 'drizzle-orm/pg-core';
|
|
151
|
+
import { generateTzColumnDefs } from '@venizia/ignis';
|
|
152
|
+
|
|
153
|
+
export const myTable = pgTable('MyTable', {
|
|
154
|
+
...generateTzColumnDefs(),
|
|
155
|
+
name: text('name').notNull(),
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// Generates: createdAt, modifiedAt (deletedAt is disabled by default)
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
**Enable soft delete:**
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
export const myTable = pgTable('MyTable', {
|
|
165
|
+
...generateTzColumnDefs({
|
|
166
|
+
deleted: { enable: true, columnName: 'deleted_at', withTimezone: true },
|
|
167
|
+
}),
|
|
168
|
+
name: text('name').notNull(),
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
// Generates: createdAt, modifiedAt, deletedAt
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
**Custom column names:**
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
export const myTable = pgTable('MyTable', {
|
|
178
|
+
...generateTzColumnDefs({
|
|
179
|
+
created: { columnName: 'created_date', withTimezone: true },
|
|
180
|
+
modified: { enable: true, columnName: 'updated_date', withTimezone: true },
|
|
181
|
+
deleted: { enable: true, columnName: 'removed_date', withTimezone: true },
|
|
182
|
+
}),
|
|
183
|
+
name: text('name').notNull(),
|
|
184
|
+
});
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**Without timezone:**
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
export const myTable = pgTable('MyTable', {
|
|
191
|
+
...generateTzColumnDefs({
|
|
192
|
+
created: { columnName: 'created_at', withTimezone: false },
|
|
193
|
+
modified: { enable: true, columnName: 'modified_at', withTimezone: false },
|
|
194
|
+
deleted: { enable: true, columnName: 'deleted_at', withTimezone: false },
|
|
195
|
+
}),
|
|
196
|
+
name: text('name').notNull(),
|
|
197
|
+
});
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
**Minimal setup (only createdAt):**
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
export const myTable = pgTable('MyTable', {
|
|
206
|
+
...generateTzColumnDefs({
|
|
207
|
+
modified: { enable: false },
|
|
208
|
+
deleted: { enable: false },
|
|
209
|
+
}),
|
|
210
|
+
name: text('name').notNull(),
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
// Generates: createdAt only
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
#### Soft Delete Pattern
|
|
217
|
+
|
|
218
|
+
The `deletedAt` column enables the soft delete pattern, where records are marked as deleted rather than physically removed from the database.
|
|
219
|
+
|
|
220
|
+
**Example soft delete query:**
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
import { eq, isNull } from 'drizzle-orm';
|
|
224
|
+
|
|
225
|
+
// Soft delete: set deletedAt timestamp
|
|
226
|
+
await db.update(myTable)
|
|
227
|
+
.set({ deletedAt: new Date() })
|
|
228
|
+
.where(eq(myTable.id, id));
|
|
229
|
+
|
|
230
|
+
// Query only active (non-deleted) records
|
|
231
|
+
const activeRecords = await db.select()
|
|
232
|
+
.from(myTable)
|
|
233
|
+
.where(isNull(myTable.deletedAt));
|
|
234
|
+
|
|
235
|
+
// Query deleted records
|
|
236
|
+
const deletedRecords = await db.select()
|
|
237
|
+
.from(myTable)
|
|
238
|
+
.where(isNotNull(myTable.deletedAt));
|
|
239
|
+
|
|
240
|
+
// Restore a soft-deleted record
|
|
241
|
+
await db.update(myTable)
|
|
242
|
+
.set({ deletedAt: null })
|
|
243
|
+
.where(eq(myTable.id, id));
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
#### Type Inference
|
|
247
|
+
|
|
248
|
+
The enricher provides proper TypeScript type inference:
|
|
249
|
+
|
|
250
|
+
```typescript
|
|
251
|
+
type TTzEnricherResult<ColumnDefinitions extends TColumnDefinitions = TColumnDefinitions> = {
|
|
252
|
+
createdAt: PgTimestampBuilderInitial<string> & NotNull & HasDefault;
|
|
253
|
+
modifiedAt?: PgTimestampBuilderInitial<string> & NotNull & HasDefault;
|
|
254
|
+
deletedAt?: PgTimestampBuilderInitial<string>;
|
|
255
|
+
};
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## Schema Utilities
|
|
261
|
+
|
|
262
|
+
### `snakeToCamel`
|
|
263
|
+
|
|
264
|
+
Converts a Zod schema from snake_case to camelCase, transforming both the schema shape and runtime data.
|
|
265
|
+
|
|
266
|
+
**File:** `packages/core/src/base/models/common/types.ts`
|
|
267
|
+
|
|
268
|
+
#### Signature
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
snakeToCamel<T extends z.ZodRawShape>(shape: T): z.ZodEffects<...>
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
#### Purpose
|
|
275
|
+
|
|
276
|
+
This utility is useful when working with databases that use snake_case column names but you want to work with camelCase in your TypeScript code. It creates a Zod schema that:
|
|
277
|
+
|
|
278
|
+
1. Accepts snake_case input (validates against original schema)
|
|
279
|
+
2. Transforms the data to camelCase at runtime
|
|
280
|
+
3. Validates the transformed data against a camelCase schema
|
|
281
|
+
|
|
282
|
+
#### Usage Example
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
import { z } from 'zod';
|
|
286
|
+
import { snakeToCamel } from '@venizia/ignis';
|
|
287
|
+
|
|
288
|
+
// Define schema with snake_case fields
|
|
289
|
+
const userSnakeSchema = {
|
|
290
|
+
user_id: z.number(),
|
|
291
|
+
first_name: z.string(),
|
|
292
|
+
last_name: z.string(),
|
|
293
|
+
created_at: z.date(),
|
|
294
|
+
is_active: z.boolean(),
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
// Convert to camelCase schema
|
|
298
|
+
const userCamelSchema = snakeToCamel(userSnakeSchema);
|
|
299
|
+
|
|
300
|
+
// Input data from database (snake_case)
|
|
301
|
+
const dbData = {
|
|
302
|
+
user_id: 123,
|
|
303
|
+
first_name: 'John',
|
|
304
|
+
last_name: 'Doe',
|
|
305
|
+
created_at: new Date(),
|
|
306
|
+
is_active: true,
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
// Parse and transform to camelCase
|
|
310
|
+
const result = userCamelSchema.parse(dbData);
|
|
311
|
+
|
|
312
|
+
// Result is automatically camelCase:
|
|
313
|
+
console.log(result);
|
|
314
|
+
// {
|
|
315
|
+
// userId: 123,
|
|
316
|
+
// firstName: 'John',
|
|
317
|
+
// lastName: 'Doe',
|
|
318
|
+
// createdAt: Date,
|
|
319
|
+
// isActive: true
|
|
320
|
+
// }
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
#### Real-world Example
|
|
324
|
+
|
|
325
|
+
**Use case:** API endpoint that accepts snake_case but works with camelCase internally
|
|
326
|
+
|
|
327
|
+
```typescript
|
|
328
|
+
import { BaseController, controller, snakeToCamel } from '@venizia/ignis';
|
|
329
|
+
import { z } from '@hono/zod-openapi';
|
|
330
|
+
|
|
331
|
+
const createUserSchema = snakeToCamel({
|
|
332
|
+
first_name: z.string().min(1),
|
|
333
|
+
last_name: z.string().min(1),
|
|
334
|
+
email_address: z.string().email(),
|
|
335
|
+
phone_number: z.string().optional(),
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
@controller({ path: '/users' })
|
|
339
|
+
export class UserController extends BaseController {
|
|
340
|
+
override binding() {
|
|
341
|
+
this.bindRoute({
|
|
342
|
+
configs: {
|
|
343
|
+
path: '/',
|
|
344
|
+
method: 'post',
|
|
345
|
+
request: {
|
|
346
|
+
body: {
|
|
347
|
+
content: {
|
|
348
|
+
'application/json': { schema: createUserSchema },
|
|
349
|
+
},
|
|
350
|
+
},
|
|
351
|
+
},
|
|
352
|
+
},
|
|
353
|
+
}).to({
|
|
354
|
+
handler: async (ctx) => {
|
|
355
|
+
// Request body is automatically camelCase
|
|
356
|
+
const data = ctx.req.valid('json');
|
|
357
|
+
|
|
358
|
+
// data = {
|
|
359
|
+
// firstName: string,
|
|
360
|
+
// lastName: string,
|
|
361
|
+
// emailAddress: string,
|
|
362
|
+
// phoneNumber?: string
|
|
363
|
+
// }
|
|
364
|
+
|
|
365
|
+
// Work with camelCase data
|
|
366
|
+
console.log(data.firstName); // ✅ TypeScript knows this exists
|
|
367
|
+
console.log(data.first_name); // ❌ TypeScript error
|
|
368
|
+
|
|
369
|
+
return ctx.json({ success: true });
|
|
370
|
+
},
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
#### Type Transformation
|
|
377
|
+
|
|
378
|
+
The utility includes sophisticated TypeScript type transformation:
|
|
379
|
+
|
|
380
|
+
```typescript
|
|
381
|
+
type TSnakeToCamelCase<S extends string> =
|
|
382
|
+
S extends `${infer T}_${infer U}`
|
|
383
|
+
? `${T}${Capitalize<TSnakeToCamelCase<U>>}`
|
|
384
|
+
: S;
|
|
385
|
+
|
|
386
|
+
type TCamelCaseKeys<T extends z.ZodRawShape> = {
|
|
387
|
+
[K in keyof T as K extends string ? TSnakeToCamelCase<K> : K]:
|
|
388
|
+
T[K] extends z.ZodType<infer U> ? z.ZodType<U> : T[K];
|
|
389
|
+
};
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
This ensures full type safety: TypeScript will know that `first_name` becomes `firstName`, `created_at` becomes `createdAt`, etc.
|
|
393
|
+
|
|
394
|
+
#### Validation
|
|
395
|
+
|
|
396
|
+
The schema validates twice for safety:
|
|
397
|
+
|
|
398
|
+
1. **First validation:** Checks that input matches snake_case schema
|
|
399
|
+
2. **Transformation:** Converts keys from snake_case to camelCase
|
|
400
|
+
3. **Second validation:** Validates transformed data against camelCase schema
|
|
401
|
+
|
|
402
|
+
```typescript
|
|
403
|
+
// If validation fails at any step, you get clear error messages
|
|
404
|
+
const invalidData = {
|
|
405
|
+
user_id: 'not-a-number', // ❌ Fails first validation
|
|
406
|
+
first_name: 'John',
|
|
407
|
+
last_name: 'Doe',
|
|
408
|
+
};
|
|
409
|
+
|
|
410
|
+
try {
|
|
411
|
+
userCamelSchema.parse(invalidData);
|
|
412
|
+
} catch (error) {
|
|
413
|
+
// ZodError with clear message about user_id expecting number
|
|
414
|
+
}
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
#### Notes
|
|
418
|
+
|
|
419
|
+
- Built on top of `keysToCamel()` and `toCamel()` utilities from `@venizia/ignis-helpers`
|
|
420
|
+
- Recursively handles nested objects
|
|
421
|
+
- Preserves array structures
|
|
422
|
+
- Works seamlessly with Zod's other features (refinements, transforms, etc.)
|
|
@@ -8,8 +8,10 @@ Reusable, pluggable modules that encapsulate specific features in Ignis applicat
|
|
|
8
8
|
|-----------|---------|--------------|
|
|
9
9
|
| [Authentication](./authentication.md) | JWT-based auth | Token generation, protected routes, user payload |
|
|
10
10
|
| [Health Check](./health-check.md) | Monitoring endpoint | `/health` endpoint, ping/pong functionality |
|
|
11
|
-
| [
|
|
11
|
+
| [Request Tracker](./request-tracker.md) | Request logging | Request ID generation, timing, structured logging |
|
|
12
12
|
| [Socket.IO](./socket-io.md) | Real-time communication | WebSocket support, Redis adapter, event-based |
|
|
13
|
+
| [Static Asset](./static-asset.md) | File management | Upload/download files, MinIO & local filesystem support |
|
|
14
|
+
| [Swagger](./swagger.md) | API documentation | OpenAPI generation, Swagger UI, Scalar UI |
|
|
13
15
|
|
|
14
16
|
## Creating a Component
|
|
15
17
|
|