opticore-feature-component 1.0.0 → 1.0.1
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 +214 -173
- package/dist/{core-ED52ORJA.js → core-GNR24GXE.js} +614 -238
- package/dist/index.cjs +647 -252
- package/dist/index.js +1 -1
- package/package.json +42 -40
package/README.md
CHANGED
|
@@ -1,112 +1,127 @@
|
|
|
1
1
|
# opticore-feature-component
|
|
2
2
|
|
|
3
|
-
OptiCore Feature
|
|
4
|
-
|
|
3
|
+
OptiCore Feature Component is a package that provides an interactive CLI to generate features in an **OptiCoreJs** project.
|
|
4
|
+
Three scaffolding modes are available: Simple Component, Clean Architecture step by step, and Full Clean Architecture.
|
|
5
5
|
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
7
7
|
[](https://www.npmjs.com/package/opticore-feature-component)
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
## Table
|
|
11
|
+
## Table of Contents
|
|
12
12
|
|
|
13
|
-
- [
|
|
13
|
+
- [Prerequisites](#prerequisites)
|
|
14
14
|
- [Installation](#installation)
|
|
15
|
-
- [
|
|
16
|
-
- [
|
|
15
|
+
- [Running the CLI](#running-the-cli)
|
|
16
|
+
- [Global Interactive Flow](#global-interactive-flow)
|
|
17
17
|
- [Option 1 — Simple Component](#option-1--simple-component)
|
|
18
18
|
- [Option 2 — CLEAN Architecture by step](#option-2--clean-architecture-by-step)
|
|
19
19
|
- [Option 3 — Full CLEAN Architecture component](#option-3--full-clean-architecture-component)
|
|
20
|
-
- [
|
|
21
|
-
- [
|
|
22
|
-
- [
|
|
20
|
+
- [Naming Rules](#naming-rules)
|
|
21
|
+
- [Automatic Router Registration](#automatic-router-registration)
|
|
22
|
+
- [Contributing](#contributing)
|
|
23
23
|
|
|
24
24
|
---
|
|
25
25
|
|
|
26
|
-
##
|
|
26
|
+
## Prerequisites
|
|
27
27
|
|
|
28
28
|
- **Node.js** ≥ 18
|
|
29
29
|
- **TypeScript** ≥ 5
|
|
30
|
-
-
|
|
30
|
+
- A project exposing the `src/features/` directory at the root (the CLI creates features there)
|
|
31
31
|
|
|
32
32
|
```
|
|
33
|
-
|
|
33
|
+
my-project > src > app > router > register.router.ts
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
The `register.router.ts` file is automatically updated when a feature router is created.
|
|
37
37
|
|
|
38
|
-
>
|
|
38
|
+
> If the `features` folder is missing when the server launches, the CLI displays an error and stops.
|
|
39
39
|
|
|
40
40
|
---
|
|
41
41
|
|
|
42
42
|
## Installation
|
|
43
43
|
|
|
44
|
-
###
|
|
44
|
+
### As a dev dependency (recommended)
|
|
45
45
|
|
|
46
46
|
```bash
|
|
47
47
|
npm install --save-dev opticore-feature-component
|
|
48
|
-
#
|
|
48
|
+
# or
|
|
49
49
|
yarn add -D opticore-feature-component
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
-
###
|
|
52
|
+
### Globally
|
|
53
53
|
|
|
54
54
|
```bash
|
|
55
55
|
npm install -g opticore-feature-component
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
-
###
|
|
58
|
+
### From source (monorepo)
|
|
59
59
|
|
|
60
60
|
```bash
|
|
61
|
-
#
|
|
61
|
+
# from the package root
|
|
62
62
|
npm install
|
|
63
63
|
npm run build
|
|
64
64
|
```
|
|
65
65
|
|
|
66
66
|
---
|
|
67
67
|
|
|
68
|
-
##
|
|
68
|
+
## Running the CLI
|
|
69
69
|
|
|
70
|
-
###
|
|
70
|
+
### With `npx` or `npm` (no global install)
|
|
71
71
|
|
|
72
72
|
```bash
|
|
73
|
-
npx
|
|
73
|
+
npx create-feature-module
|
|
74
74
|
```
|
|
75
75
|
```bash
|
|
76
|
-
npm exec
|
|
76
|
+
npm exec create-feature-module
|
|
77
77
|
```
|
|
78
78
|
|
|
79
|
-
### Via
|
|
79
|
+
### Via a `package.json` script (recommended)
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
Add a script to your project's `package.json`:
|
|
82
82
|
|
|
83
83
|
```json
|
|
84
84
|
{
|
|
85
85
|
"scripts": {
|
|
86
|
-
"feature": "
|
|
86
|
+
"feature": "create-feature-module"
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
```
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
Then run:
|
|
92
92
|
|
|
93
93
|
```bash
|
|
94
94
|
npm run feature
|
|
95
|
-
#
|
|
95
|
+
# or
|
|
96
96
|
yarn feature
|
|
97
97
|
```
|
|
98
98
|
|
|
99
|
-
###
|
|
99
|
+
### Global installation
|
|
100
100
|
|
|
101
101
|
```bash
|
|
102
|
-
|
|
102
|
+
create-feature-module
|
|
103
103
|
```
|
|
104
104
|
|
|
105
105
|
---
|
|
106
106
|
|
|
107
|
-
##
|
|
107
|
+
## Global Interactive Flow
|
|
108
108
|
|
|
109
|
-
|
|
109
|
+
When launched, the CLI displays the following banner before any prompt:
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
██████╗ ██████╗ ████████╗ ██╗ ██████╗ ██████╗ ██████╗ ███████╗ ██╗ ███████╗
|
|
113
|
+
██╔═══██╗ ██╔══██╗ ╚══██╔══╝ ██║ ██╔════╝ ██╔═══██╗ ██╔══██╗ ██╔════╝ ██║ ██╔════╝
|
|
114
|
+
██║ ██║ ██████╔╝ ██║ ██║ ██║ ██║ ██║ ██████╔╝ █████╗ ██║ ███████╗
|
|
115
|
+
██║ ██║ ██╔═══╝ ██║ ██║ ██║ ██║ ██║ ██╔══██╗ ██╔══╝ ██ ██║ ╚════██║
|
|
116
|
+
╚██████╔╝ ██║ ██║ ██║ ╚██████╗ ╚██████╔╝ ██║ ██║ ███████╗ ╚█████╔╝ ███████║
|
|
117
|
+
╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚══════╝ ╚════╝ ╚══════╝
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
OPTICORE F E A T U R E M O D U L E
|
|
121
|
+
Create · Structure · Scaffold · Generate · Organize
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Then follows a 3-step flow before presenting the scaffold options:
|
|
110
125
|
|
|
111
126
|
```
|
|
112
127
|
╭────────────────────────────────────────────────────╮
|
|
@@ -131,56 +146,73 @@ opticore-feature-component
|
|
|
131
146
|
└
|
|
132
147
|
```
|
|
133
148
|
|
|
134
|
-
|
|
149
|
+
**Step 1 — Creation Principle**
|
|
135
150
|
|
|
136
|
-
|
|
|
151
|
+
| Choice | Behavior |
|
|
137
152
|
|---|---|
|
|
138
|
-
| `OptiCoreJs CLEAN Module` |
|
|
139
|
-
| `Custom feature` |
|
|
153
|
+
| `OptiCoreJs CLEAN Module` | Enables automated scaffolding — continues to step 2 |
|
|
154
|
+
| `Custom feature` | Displays an information message and exits (manual creation) |
|
|
140
155
|
|
|
141
|
-
|
|
156
|
+
**Step 2 — Feature Name**
|
|
142
157
|
|
|
143
|
-
|
|
144
|
-
→ camelCase,
|
|
158
|
+
The name must follow the rule: `^[a-z][A-Za-z]+$`
|
|
159
|
+
→ camelCase, starts with a lowercase letter, minimum 2 characters.
|
|
145
160
|
|
|
146
161
|
```
|
|
147
162
|
✅ userProfile
|
|
148
163
|
✅ productOrder
|
|
149
164
|
✅ authToken
|
|
150
|
-
❌ UserProfile (
|
|
151
|
-
❌ user_profile (underscore
|
|
152
|
-
❌ user (1
|
|
165
|
+
❌ UserProfile (starts with uppercase)
|
|
166
|
+
❌ user_profile (underscore not allowed)
|
|
167
|
+
❌ user (only 1 character after the first letter)
|
|
153
168
|
```
|
|
154
169
|
|
|
155
|
-
|
|
170
|
+
**Step 3 — Component Type** → see the following sections.
|
|
156
171
|
|
|
157
|
-
>
|
|
158
|
-
> les répertoires éventuellement créés.
|
|
172
|
+
> Press **Ctrl+C** at any step to cancel the operation and remove any directories already created.
|
|
159
173
|
|
|
160
174
|
---
|
|
161
175
|
|
|
162
176
|
## Option 1 — Simple Component
|
|
163
177
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
###
|
|
167
|
-
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
│
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
178
|
+
Flat and pragmatic structure. Ideal for lightweight features without a domain layer.
|
|
179
|
+
|
|
180
|
+
### What is generated
|
|
181
|
+
|
|
182
|
+
```
|
|
183
|
+
╔═══════════════════════════════════════════════════════════════════════╗
|
|
184
|
+
║ SIMPLE COMPONENT — src/features/<featureName>/ ║
|
|
185
|
+
╠═══════════════════════════════════════════════════════════════════════╣
|
|
186
|
+
║ ║
|
|
187
|
+
║ ┌───────────────────────────────────────────────────────────────┐ ║
|
|
188
|
+
║ │ 🌐 ROUTES — HTTP entry point │ ║
|
|
189
|
+
║ │ routes/<featureName>.router.ts │ ║
|
|
190
|
+
║ │ routes/<featureName>.router.handler.ts │ ║
|
|
191
|
+
║ └────────────────────────────┬──────────────────────────────────┘ ║
|
|
192
|
+
║ │ handles HTTP requests ║
|
|
193
|
+
║ ┌────────────────────────────▼──────────────────────────────────┐ ║
|
|
194
|
+
║ │ 🎮 CONTROLLER — request / response orchestration │ ║
|
|
195
|
+
║ │ controllers/<featureName>.controller.ts │ ║
|
|
196
|
+
║ └────────────────────────────┬──────────────────────────────────┘ ║
|
|
197
|
+
║ │ delegates business logic ║
|
|
198
|
+
║ ┌────────────────────────────▼──────────────────────────────────┐ ║
|
|
199
|
+
║ │ ⚙️ SERVICE — business logic │ ║
|
|
200
|
+
║ │ services/<featureName>.service.ts │ ║
|
|
201
|
+
║ └────────────────────────────┬──────────────────────────────────┘ ║
|
|
202
|
+
║ │ reads & writes data ║
|
|
203
|
+
║ ┌────────────────────────────▼──────────────────────────────────┐ ║
|
|
204
|
+
║ │ 🗄️ REPOSITORY — data access │ ║
|
|
205
|
+
║ │ repositories/<featureName>.repository.ts │ ║
|
|
206
|
+
║ └────────────────────────────┬──────────────────────────────────┘ ║
|
|
207
|
+
║ │ shapes data ║
|
|
208
|
+
║ ┌────────────────────────────▼──────────────────────────────────┐ ║
|
|
209
|
+
║ │ 📦 MODEL — data shape │ ║
|
|
210
|
+
║ │ models/<featureName>.model.ts │ ║
|
|
211
|
+
║ └───────────────────────────────────────────────────────────────┘ ║
|
|
212
|
+
╚═══════════════════════════════════════════════════════════════════════╝
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Example — `order` feature
|
|
184
216
|
|
|
185
217
|
```
|
|
186
218
|
src/features/order/
|
|
@@ -197,7 +229,7 @@ src/features/order/
|
|
|
197
229
|
└── order.router.ts
|
|
198
230
|
```
|
|
199
231
|
|
|
200
|
-
|
|
232
|
+
The CLI asks whether you want methods in the controller:
|
|
201
233
|
|
|
202
234
|
```
|
|
203
235
|
◆ Do you want to add methods to the controller?
|
|
@@ -209,7 +241,7 @@ Le CLI demande si vous souhaitez des méthodes dans le controller :
|
|
|
209
241
|
└
|
|
210
242
|
```
|
|
211
243
|
|
|
212
|
-
###
|
|
244
|
+
### Generated content — `order.service.ts`
|
|
213
245
|
|
|
214
246
|
```typescript
|
|
215
247
|
import { OrderRepository } from "../repositories/order.repository";
|
|
@@ -249,7 +281,7 @@ export class OrderService {
|
|
|
249
281
|
}
|
|
250
282
|
```
|
|
251
283
|
|
|
252
|
-
###
|
|
284
|
+
### Generated content — `order.controller.ts` (methods `create, findAll`)
|
|
253
285
|
|
|
254
286
|
```typescript
|
|
255
287
|
import { Request, Response } from "express";
|
|
@@ -288,26 +320,26 @@ export class OrderController {
|
|
|
288
320
|
}
|
|
289
321
|
```
|
|
290
322
|
|
|
291
|
-
###
|
|
323
|
+
### Automatic HTTP method mapping
|
|
292
324
|
|
|
293
|
-
|
|
325
|
+
The CLI infers the HTTP verb and path from the method name:
|
|
294
326
|
|
|
295
|
-
|
|
|
327
|
+
| Method name (examples) | Verb | Path |
|
|
296
328
|
|---|---|---|
|
|
297
329
|
| `findAll`, `getAll` | `GET` | `/<featureName>` |
|
|
298
330
|
| `findById`, `getById`, `getOne` | `GET` | `/<featureName>/:id` |
|
|
299
331
|
| `create`, `add` | `POST` | `/<featureName>` |
|
|
300
332
|
| `update`, `edit` | `PUT` | `/<featureName>/:id` |
|
|
301
333
|
| `delete`, `remove` | `DELETE` | `/<featureName>/:id` |
|
|
302
|
-
|
|
|
334
|
+
| any other name | `GET` | `/<featureName>/<methodName>` |
|
|
303
335
|
|
|
304
336
|
---
|
|
305
337
|
|
|
306
338
|
## Option 2 — CLEAN Architecture by step
|
|
307
339
|
|
|
308
|
-
|
|
340
|
+
File-by-file interactive mode. The CLI proposes each component one at a time and only creates the ones you confirm. **All created files are empty** — no template is injected.
|
|
309
341
|
|
|
310
|
-
###
|
|
342
|
+
### Step-by-step flow
|
|
311
343
|
|
|
312
344
|
```
|
|
313
345
|
── Domain ──────────────────────────────────────────────────────
|
|
@@ -325,7 +357,6 @@ Mode interactif file-par-file. Le CLI propose chaque composant un à un et ne cr
|
|
|
325
357
|
│ ○ Yes ● No
|
|
326
358
|
└
|
|
327
359
|
|
|
328
|
-
── Application ─────────────────────────────────────────────────
|
|
329
360
|
|
|
330
361
|
◆ Repo Interface → payment.repository.interface.ts
|
|
331
362
|
│ ● Yes ○ No
|
|
@@ -350,7 +381,6 @@ Mode interactif file-par-file. Le CLI propose chaque composant un à un et ne cr
|
|
|
350
381
|
└
|
|
351
382
|
✅ Created: src/features/payment/application/use-cases/payment.usecase.ts
|
|
352
383
|
|
|
353
|
-
── Infrastructure ──────────────────────────────────────────────
|
|
354
384
|
|
|
355
385
|
◆ Repo Impl → payment.repository.ts
|
|
356
386
|
│ ● Yes ○ No
|
|
@@ -377,32 +407,44 @@ Mode interactif file-par-file. Le CLI propose chaque composant un à un et ne cr
|
|
|
377
407
|
🎉 Feature "payment" — 5 file(s) created step by step.
|
|
378
408
|
```
|
|
379
409
|
|
|
380
|
-
###
|
|
381
|
-
|
|
382
|
-
```
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
410
|
+
### Result for the example above
|
|
411
|
+
|
|
412
|
+
```
|
|
413
|
+
╔══════════════════════════════════════════════════════════════════════════╗
|
|
414
|
+
║ CLEAN by step — src/features/payment/ (partial selection) ║
|
|
415
|
+
╠══════════════════════════════════════════════════════════════════════════╣
|
|
416
|
+
║ ║
|
|
417
|
+
║ ╔════════════════════════════════════════════════════════════════════╗ ║
|
|
418
|
+
║ ║ 🟦 APPLICATION ║ ║
|
|
419
|
+
║ ║ ║ ║
|
|
420
|
+
║ ║ dtos/ ║ ║
|
|
421
|
+
║ ║ └── ✅ payment.dto.ts (empty) ║ ║
|
|
422
|
+
║ ║ ║ ║
|
|
423
|
+
║ ║ ports/repositories/ ║ ║
|
|
424
|
+
║ ║ └── ✅ payment.repository.interface.ts (empty) ║ ║
|
|
425
|
+
║ ║ ║ ║
|
|
426
|
+
║ ║ use-cases/ ║ ║
|
|
427
|
+
║ ║ └── ✅ payment.usecase.ts (empty) ║ ║
|
|
428
|
+
║ ╚════════════════════════════════════════════════════════════════════╝ ║
|
|
429
|
+
║ ║
|
|
430
|
+
║ ╔════════════════════════════════════════════════════════════════════╗ ║
|
|
431
|
+
║ ║ 🟠 INFRASTRUCTURE ║ ║
|
|
432
|
+
║ ║ ║ ║
|
|
433
|
+
║ ║ adapters/controllers/ ║ ║
|
|
434
|
+
║ ║ └── ✅ payment.controller.ts (empty) ║ ║
|
|
435
|
+
║ ║ ║ ║
|
|
436
|
+
║ ║ adapters/repositories/ ║ ║
|
|
437
|
+
║ ║ └── ✅ payment.repository.ts (empty) ║ ║
|
|
438
|
+
║ ╚════════════════════════════════════════════════════════════════════╝ ║
|
|
439
|
+
╚══════════════════════════════════════════════════════════════════════════╝
|
|
440
|
+
|
|
441
|
+
⚠ Directories are only created for confirmed files.
|
|
442
|
+
⚠ If no file is selected, nothing is written to disk.
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
### Available components
|
|
446
|
+
|
|
447
|
+
| Group | Label | File created | Directory |
|
|
406
448
|
|---|---|---|---|
|
|
407
449
|
| Domain | Entity | `<n>.entity.ts` | `domain/entities/` |
|
|
408
450
|
| Domain | Event | `<n>.event.ts` | `domain/events/` |
|
|
@@ -422,49 +464,48 @@ src/features/payment/
|
|
|
422
464
|
|
|
423
465
|
## Option 3 — Full CLEAN Architecture component
|
|
424
466
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
###
|
|
428
|
-
|
|
429
|
-
```
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
Seule question posée pendant la génération : les méthodes du controller.
|
|
467
|
+
Generates the entire Clean Architecture structure in a single command. Every file is pre-filled with a functional TypeScript template ready to be adapted.
|
|
468
|
+
|
|
469
|
+
### What is generated
|
|
470
|
+
|
|
471
|
+
```
|
|
472
|
+
╔══════════════════════════════════════════════════════════════════════════════╗
|
|
473
|
+
║ 🟠 INFRASTRUCTURE — wires everything together ║
|
|
474
|
+
║ adapters/controllers/<featureName>.controller.ts ║
|
|
475
|
+
║ adapters/repositories/<featureName>.repository.ts ║
|
|
476
|
+
║ adapters/presenters/<featureName>.presenter.ts ║
|
|
477
|
+
║ routes/<featureName>.router.handler.ts ║
|
|
478
|
+
║ routes/<featureName>.router.ts ║
|
|
479
|
+
║ ║
|
|
480
|
+
║ ╔══════════════════════════════════════════════════════════════════════╗ ║
|
|
481
|
+
║ ║ 🟦 APPLICATION — use cases & ports (interfaces) ║ ║
|
|
482
|
+
║ ║ ports/repositories/<featureName>.repository.interface.ts ║ ║
|
|
483
|
+
║ ║ ports/presenters/<featureName>.presenter.interface.ts ║ ║
|
|
484
|
+
║ ║ ports/services/<featureName>.service.ts ║ ║
|
|
485
|
+
║ ║ dtos/<featureName>.dto.ts ║ ║
|
|
486
|
+
║ ║ use-cases/<featureName>.usecase.ts ║ ║
|
|
487
|
+
║ ║ ║ ║
|
|
488
|
+
║ ║ ╔══════════════════════════════════════════════════════════════╗ ║ ║
|
|
489
|
+
║ ║ ║ 🟨 DOMAIN — pure business logic, no framework dependency ║ ║ ║
|
|
490
|
+
║ ║ ║ ║ ║ ║
|
|
491
|
+
║ ║ ║ ╔═══════════════════════════════════════════════════════╗ ║ ║ ║
|
|
492
|
+
║ ║ ║ ║ ⭐ ENTITIES (core — no external dependencies) ║ ║ ║ ║
|
|
493
|
+
║ ║ ║ ║ entities/<featureName>.entity.ts ║ ║ ║ ║
|
|
494
|
+
║ ║ ║ ╚═══════════════════════════════════════════════════════╝ ║ ║ ║
|
|
495
|
+
║ ║ ║ ║ ║ ║
|
|
496
|
+
║ ║ ║ events/<featureName>.event.ts ║ ║ ║
|
|
497
|
+
║ ║ ║ exceptions/<featureName>.exception.ts ║ ║ ║
|
|
498
|
+
║ ║ ╚══════════════════════════════════════════════════════════════╝ ║ ║
|
|
499
|
+
║ ╚══════════════════════════════════════════════════════════════════════╝ ║
|
|
500
|
+
╚══════════════════════════════════════════════════════════════════════════════╝
|
|
501
|
+
|
|
502
|
+
13 files · 12 directories — generated in a single interaction
|
|
503
|
+
← dependency direction: outer layers depend on inner layers, never the reverse
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
### Example — `invoice` feature
|
|
507
|
+
|
|
508
|
+
The only question asked during generation: the controller methods.
|
|
468
509
|
|
|
469
510
|
```
|
|
470
511
|
◆ Do you want to add methods to the controller?
|
|
@@ -493,7 +534,7 @@ Seule question posée pendant la génération : les méthodes du controller.
|
|
|
493
534
|
🎉 Feature "invoice" scaffolded with Clean Architecture!
|
|
494
535
|
```
|
|
495
536
|
|
|
496
|
-
###
|
|
537
|
+
### Generated content — `invoice.entity.ts`
|
|
497
538
|
|
|
498
539
|
```typescript
|
|
499
540
|
/**
|
|
@@ -539,7 +580,7 @@ export class InvoiceEntity {
|
|
|
539
580
|
}
|
|
540
581
|
```
|
|
541
582
|
|
|
542
|
-
###
|
|
583
|
+
### Generated content — `invoice.usecase.ts`
|
|
543
584
|
|
|
544
585
|
```typescript
|
|
545
586
|
import { IInvoiceRepository } from "../ports/repositories/invoice.repository.interface";
|
|
@@ -593,7 +634,7 @@ export class InvoiceUseCase {
|
|
|
593
634
|
}
|
|
594
635
|
```
|
|
595
636
|
|
|
596
|
-
###
|
|
637
|
+
### Generated content — `invoice.router.handler.ts` (methods `create, findAll, findById`)
|
|
597
638
|
|
|
598
639
|
```typescript
|
|
599
640
|
import { OpticoreRouting, ICustomContext, IMultipleRouteDefinition } from "opticore-router";
|
|
@@ -628,27 +669,27 @@ export const InvoiceHandlerRouter: () => IMultipleRouteDefinition = () => {
|
|
|
628
669
|
|
|
629
670
|
---
|
|
630
671
|
|
|
631
|
-
##
|
|
672
|
+
## Naming Rules
|
|
632
673
|
|
|
633
|
-
|
|
674
|
+
The feature name is subject to strict validation:
|
|
634
675
|
|
|
635
|
-
|
|
|
676
|
+
| Rule | Detail |
|
|
636
677
|
|---|---|
|
|
637
678
|
| Format | camelCase — `^[a-z][A-Za-z]+$` |
|
|
638
|
-
|
|
|
639
|
-
|
|
|
640
|
-
|
|
|
641
|
-
|
|
|
679
|
+
| First character | Must be lowercase |
|
|
680
|
+
| Minimum length | 2 characters |
|
|
681
|
+
| Allowed characters | Letters only (a-z, A-Z) |
|
|
682
|
+
| Forbidden characters | Digits, underscore, hyphen, spaces |
|
|
642
683
|
|
|
643
|
-
|
|
684
|
+
The CLI rejects the name if the feature already exists in `src/features/`.
|
|
644
685
|
|
|
645
686
|
---
|
|
646
687
|
|
|
647
|
-
##
|
|
688
|
+
## Automatic Router Registration
|
|
648
689
|
|
|
649
|
-
|
|
690
|
+
When generating **Simple Component** and **Full CLEAN Architecture**, the feature router is automatically registered in `src/app/router/register.router.ts`.
|
|
650
691
|
|
|
651
|
-
**
|
|
692
|
+
**Before**:
|
|
652
693
|
|
|
653
694
|
```typescript
|
|
654
695
|
export const registerRouter: () => TFeatureRoutes[] = (): TFeatureRoutes[] => {
|
|
@@ -658,7 +699,7 @@ export const registerRouter: () => TFeatureRoutes[] = (): TFeatureRoutes[] => {
|
|
|
658
699
|
}
|
|
659
700
|
```
|
|
660
701
|
|
|
661
|
-
**
|
|
702
|
+
**After** (`InvoiceRouter` added):
|
|
662
703
|
|
|
663
704
|
```typescript
|
|
664
705
|
import { InvoiceRouter } from "../../features/invoice/infrastructure/routes/invoice.router";
|
|
@@ -671,27 +712,27 @@ export const registerRouter: () => TFeatureRoutes[] = (): TFeatureRoutes[] => {
|
|
|
671
712
|
}
|
|
672
713
|
```
|
|
673
714
|
|
|
674
|
-
>
|
|
675
|
-
>
|
|
715
|
+
> If `register.router.ts` is not found, a warning is displayed but generation continues normally.
|
|
716
|
+
> In **CLEAN by step** mode, automatic registration is not performed because files are empty.
|
|
676
717
|
|
|
677
718
|
---
|
|
678
719
|
|
|
679
|
-
##
|
|
720
|
+
## Options Summary
|
|
680
721
|
|
|
681
|
-
| Option |
|
|
722
|
+
| Option | Files created | Content | Interaction |
|
|
682
723
|
|---|---|---|---|
|
|
683
|
-
| Simple Component | 6 |
|
|
684
|
-
| CLEAN by step | 0
|
|
685
|
-
| Full CLEAN Architecture | 13 |
|
|
724
|
+
| Simple Component | 6 | With template | Controller method names |
|
|
725
|
+
| CLEAN by step | 0 to 13 (your choice) | **Empty** | Confirmation for each file |
|
|
726
|
+
| Full CLEAN Architecture | 13 | With template | Controller method names |
|
|
686
727
|
|
|
687
728
|
---
|
|
688
729
|
|
|
689
|
-
##
|
|
730
|
+
## Contributing
|
|
690
731
|
|
|
691
|
-
`opticore-feature-component`
|
|
692
|
-
|
|
732
|
+
`opticore-feature-component` is open source.
|
|
733
|
+
To contribute: clone the repository and open a pull request.
|
|
693
734
|
|
|
694
|
-
- **Repository
|
|
695
|
-
- **Issues
|
|
735
|
+
- **Repository**: [github.com/guyzoum77/opticore-feature-cli](https://github.com/guyzoum77/opticore-feature-cli)
|
|
736
|
+
- **Issues**: [github.com/guyzoum77/opticore-feature-cli/issues](https://github.com/guyzoum77/opticore-feature-cli/issues)
|
|
696
737
|
|
|
697
|
-
**
|
|
738
|
+
**Author**: Guy-serge Kouacou — MIT License
|