@currentjs/gen 0.1.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/CHANGELOG.md +7 -0
- package/LICENSE +56 -0
- package/README.md +686 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +143 -0
- package/dist/commands/commit.d.ts +1 -0
- package/dist/commands/commit.js +153 -0
- package/dist/commands/createApp.d.ts +1 -0
- package/dist/commands/createApp.js +64 -0
- package/dist/commands/createModule.d.ts +1 -0
- package/dist/commands/createModule.js +121 -0
- package/dist/commands/diff.d.ts +1 -0
- package/dist/commands/diff.js +164 -0
- package/dist/commands/generateAll.d.ts +4 -0
- package/dist/commands/generateAll.js +305 -0
- package/dist/commands/infer.d.ts +1 -0
- package/dist/commands/infer.js +179 -0
- package/dist/generators/controllerGenerator.d.ts +20 -0
- package/dist/generators/controllerGenerator.js +280 -0
- package/dist/generators/domainModelGenerator.d.ts +33 -0
- package/dist/generators/domainModelGenerator.js +175 -0
- package/dist/generators/serviceGenerator.d.ts +39 -0
- package/dist/generators/serviceGenerator.js +379 -0
- package/dist/generators/storeGenerator.d.ts +31 -0
- package/dist/generators/storeGenerator.js +191 -0
- package/dist/generators/templateGenerator.d.ts +11 -0
- package/dist/generators/templateGenerator.js +143 -0
- package/dist/generators/templates/appTemplates.d.ts +27 -0
- package/dist/generators/templates/appTemplates.js +1621 -0
- package/dist/generators/templates/controllerTemplates.d.ts +43 -0
- package/dist/generators/templates/controllerTemplates.js +82 -0
- package/dist/generators/templates/index.d.ts +5 -0
- package/dist/generators/templates/index.js +21 -0
- package/dist/generators/templates/serviceTemplates.d.ts +15 -0
- package/dist/generators/templates/serviceTemplates.js +54 -0
- package/dist/generators/templates/storeTemplates.d.ts +9 -0
- package/dist/generators/templates/storeTemplates.js +260 -0
- package/dist/generators/templates/validationTemplates.d.ts +25 -0
- package/dist/generators/templates/validationTemplates.js +66 -0
- package/dist/generators/templates/viewTemplates.d.ts +16 -0
- package/dist/generators/templates/viewTemplates.js +359 -0
- package/dist/generators/validationGenerator.d.ts +24 -0
- package/dist/generators/validationGenerator.js +199 -0
- package/dist/utils/cliUtils.d.ts +6 -0
- package/dist/utils/cliUtils.js +71 -0
- package/dist/utils/colors.d.ts +26 -0
- package/dist/utils/colors.js +80 -0
- package/dist/utils/commitUtils.d.ts +46 -0
- package/dist/utils/commitUtils.js +377 -0
- package/dist/utils/constants.d.ts +52 -0
- package/dist/utils/constants.js +64 -0
- package/dist/utils/generationRegistry.d.ts +25 -0
- package/dist/utils/generationRegistry.js +192 -0
- package/howto.md +556 -0
- package/package.json +44 -0
package/README.md
ADDED
|
@@ -0,0 +1,686 @@
|
|
|
1
|
+
# @currentjs/gen 🚀
|
|
2
|
+
|
|
3
|
+
> *"Because writing boilerplate code is like doing laundry - necessary, tedious, and something a machine should definitely handle for you."*
|
|
4
|
+
|
|
5
|
+
A CLI code generator that transforms YAML specifications into fully functional TypeScript applications following clean architecture principles. Think of it as the overly enthusiastic intern who actually enjoys writing controllers, services, and domain models all day long.
|
|
6
|
+
|
|
7
|
+
## Installation 📦
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g @currentjs/gen
|
|
11
|
+
# or use without installing
|
|
12
|
+
npx @currentjs/gen
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick Start 🏃♂️
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Show help
|
|
19
|
+
currentjs --help
|
|
20
|
+
|
|
21
|
+
# Create a new app in the current directory
|
|
22
|
+
currentjs create app
|
|
23
|
+
|
|
24
|
+
# Create a new app inside a folder
|
|
25
|
+
currentjs create app my-app
|
|
26
|
+
|
|
27
|
+
# Create a module folder under src/modules
|
|
28
|
+
currentjs create module Blog
|
|
29
|
+
|
|
30
|
+
# Generate everything from app.yaml
|
|
31
|
+
currentjs generate
|
|
32
|
+
|
|
33
|
+
# Generate specific module
|
|
34
|
+
currentjs generate Blog --yaml app.yaml
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## What Does This Actually Do? 🤔
|
|
38
|
+
|
|
39
|
+
This generator takes your YAML specifications and creates:
|
|
40
|
+
|
|
41
|
+
- **🏗️ Complete app structure** with TypeScript, configs, and dependencies
|
|
42
|
+
- **📋 Domain entities** from your model definitions
|
|
43
|
+
- **🔄 Service layer** with business logic and validation
|
|
44
|
+
- **🎭 Controllers** for both API endpoints and web pages
|
|
45
|
+
- **💾 Data stores** with database provider integration
|
|
46
|
+
- **🎨 HTML templates** using @currentjs/templating
|
|
47
|
+
- **📊 Change tracking** so you can modify generated code safely
|
|
48
|
+
|
|
49
|
+
## Commands Reference 🛠️
|
|
50
|
+
|
|
51
|
+
> See the [HOW TO](howto.md) reference
|
|
52
|
+
|
|
53
|
+
### App & Module Creation
|
|
54
|
+
```bash
|
|
55
|
+
currentjs create app [name] # Create new application
|
|
56
|
+
currentjs create module <name> # Create new module in existing app
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Code Generation
|
|
60
|
+
```bash
|
|
61
|
+
currentjs generate [module] # Generate code from YAML specs
|
|
62
|
+
--yaml app.yaml # Specify config file (default: ./app.yaml)
|
|
63
|
+
--force # Overwrite files without prompting
|
|
64
|
+
--skip # Skip conflicts, never overwrite
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Advanced Change Management 🔄
|
|
68
|
+
|
|
69
|
+
The generator includes a sophisticated change tracking system that **revolutionizes how you work with generated code**:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
currentjs diff [module] # Show differences between generated and current code
|
|
73
|
+
currentjs commit [files...] # Commit your changes to version tracking
|
|
74
|
+
currentjs infer --file Entity.ts # Generate YAML model from existing TypeScript
|
|
75
|
+
--write # Write back to module YAML file
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
#### 🚀 **The Revolutionary Approach: Version Control Without Generated Code**
|
|
79
|
+
|
|
80
|
+
Here's the game-changer: **You don't need to commit generated source code to your repository at all!**
|
|
81
|
+
|
|
82
|
+
Instead, you only need to track:
|
|
83
|
+
- **Your YAML files** (the source of truth)
|
|
84
|
+
- **`registry.json`** (change tracking metadata)
|
|
85
|
+
- **Your custom modifications** (stored as reusable "patches")
|
|
86
|
+
|
|
87
|
+
**Traditional Approach** ❌
|
|
88
|
+
```
|
|
89
|
+
git/
|
|
90
|
+
├── src/modules/Blog/Blog.yaml # Source specification
|
|
91
|
+
├── src/modules/Blog/domain/entities/Post.ts # Generated + modified
|
|
92
|
+
├── src/modules/Blog/services/PostService.ts # Generated + modified
|
|
93
|
+
└── ... (hundreds of generated files with custom changes)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**CurrentJS Approach** ✅
|
|
97
|
+
```
|
|
98
|
+
git/
|
|
99
|
+
├── src/modules/Blog/Blog.yaml # Source specification
|
|
100
|
+
├── registry.json # Change tracking metadata
|
|
101
|
+
└── .currentjs/commits/ # Your custom modifications as patches
|
|
102
|
+
├── commit-2024-01-15.json
|
|
103
|
+
└── commit-2024-01-20.json
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
#### 🔧 **How It Works (Like Git for Generated Code)**
|
|
107
|
+
|
|
108
|
+
**1. Initial Generation**
|
|
109
|
+
```bash
|
|
110
|
+
currentjs generate
|
|
111
|
+
# Creates all files and tracks their hashes in registry.json
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**2. Make Your Custom Changes**
|
|
115
|
+
```typescript
|
|
116
|
+
// Edit generated service to add custom logic
|
|
117
|
+
export class PostService extends GeneratedPostService {
|
|
118
|
+
async publishPost(id: number): Promise<void> {
|
|
119
|
+
// Your custom business logic here
|
|
120
|
+
const post = await this.getById(id);
|
|
121
|
+
post.publishedAt = new Date();
|
|
122
|
+
await this.update(id, post);
|
|
123
|
+
await this.sendNotificationEmail(post);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
**3. Commit Your Changes**
|
|
129
|
+
```bash
|
|
130
|
+
currentjs commit src/modules/Blog/services/PostService.ts
|
|
131
|
+
# Saves your modifications as reusable "hunks" (like git patches)
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**4. Regenerate Safely**
|
|
135
|
+
```bash
|
|
136
|
+
# Change your YAML specification
|
|
137
|
+
currentjs generate --force
|
|
138
|
+
# Your custom changes are automatically reapplied to the new generated code!
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
#### 📊 **Change Tracking in Action**
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
# See what's different from generated baseline
|
|
145
|
+
currentjs diff Blog
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Sample Output:**
|
|
149
|
+
```diff
|
|
150
|
+
[modified] src/modules/Blog/services/PostService.ts
|
|
151
|
+
|
|
152
|
+
@@ -15,0 +16,8 @@
|
|
153
|
+
+
|
|
154
|
+
+ async publishPost(id: number): Promise<void> {
|
|
155
|
+
+ const post = await this.getById(id);
|
|
156
|
+
+ post.publishedAt = new Date();
|
|
157
|
+
+ await this.update(id, post);
|
|
158
|
+
+ await this.sendNotificationEmail(post);
|
|
159
|
+
+ }
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
#### 🎯 **registry.json Explained**
|
|
163
|
+
|
|
164
|
+
The registry tracks the "fingerprint" of each generated file:
|
|
165
|
+
|
|
166
|
+
```json
|
|
167
|
+
{
|
|
168
|
+
"src/modules/Blog/services/PostService.ts": {
|
|
169
|
+
"hash": "a1b2c3d4...", // Hash of the generated baseline
|
|
170
|
+
"updatedAt": "2024-01-15T10:30:00.000Z",
|
|
171
|
+
"diffFormat": "hunks-v1", // Change tracking format
|
|
172
|
+
"diffBaseHash": "a1b2c3d4...", // Hash of baseline this diff applies to
|
|
173
|
+
"diffHunks": [ // Your custom changes as patches
|
|
174
|
+
{
|
|
175
|
+
"oldStart": 15,
|
|
176
|
+
"newStart": 16,
|
|
177
|
+
"oldLines": 0,
|
|
178
|
+
"newLines": 8,
|
|
179
|
+
"oldContent": [],
|
|
180
|
+
"newContent": [
|
|
181
|
+
" async publishPost(id: number): Promise<void> {",
|
|
182
|
+
" const post = await this.getById(id);",
|
|
183
|
+
" // ... your custom logic"
|
|
184
|
+
]
|
|
185
|
+
}
|
|
186
|
+
]
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
#### 🌟 **Workflow Benefits**
|
|
192
|
+
|
|
193
|
+
**For Solo Development:**
|
|
194
|
+
- Cleaner repositories (no generated code noise)
|
|
195
|
+
- Fearless regeneration (your changes are always preserved)
|
|
196
|
+
- Clear separation between specifications and implementations
|
|
197
|
+
|
|
198
|
+
**For Team Development:**
|
|
199
|
+
- Merge conflicts only happen in YAML files (much simpler)
|
|
200
|
+
- Team members can have different generated code locally
|
|
201
|
+
- Changes to business logic are tracked separately from schema changes
|
|
202
|
+
- New team members just run `currentjs generate` to get up and running
|
|
203
|
+
|
|
204
|
+
**For CI/CD:**
|
|
205
|
+
```bash
|
|
206
|
+
# In your deployment pipeline
|
|
207
|
+
git clone your-repo
|
|
208
|
+
currentjs generate # Recreates all source code from YAML + patches
|
|
209
|
+
npm run build
|
|
210
|
+
npm run deploy
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
#### 🔄 **Advanced Workflows**
|
|
214
|
+
|
|
215
|
+
**Evolving Your Schema:**
|
|
216
|
+
```bash
|
|
217
|
+
# 1. Modify your YAML files
|
|
218
|
+
vim src/modules/Blog/Blog.yaml
|
|
219
|
+
|
|
220
|
+
# 2. See what would change
|
|
221
|
+
currentjs diff Blog
|
|
222
|
+
|
|
223
|
+
# 3. Regenerate with preserved customizations
|
|
224
|
+
currentjs generate --force
|
|
225
|
+
|
|
226
|
+
# 4. Commit any new customizations
|
|
227
|
+
currentjs commit
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
**Sharing Customizations:**
|
|
231
|
+
```bash
|
|
232
|
+
# Export your modifications
|
|
233
|
+
git add registry.json .currentjs/
|
|
234
|
+
git commit -m "Add custom publish functionality"
|
|
235
|
+
git push
|
|
236
|
+
|
|
237
|
+
# Teammates get your changes
|
|
238
|
+
git pull
|
|
239
|
+
currentjs generate # Their code automatically includes your customizations
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
**Branching Strategy:**
|
|
243
|
+
```bash
|
|
244
|
+
# Feature branch: only track YAML changes
|
|
245
|
+
git checkout -b feature/add-comments
|
|
246
|
+
# Edit Blog.yaml to add Comment model
|
|
247
|
+
currentjs generate
|
|
248
|
+
currentjs commit # Save any customizations
|
|
249
|
+
git add src/modules/Blog/Blog.yaml registry.json
|
|
250
|
+
git commit -m "Add comment system"
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
This change management system solves the age-old problem of "generated code vs. version control" by treating your customizations as first-class citizens while keeping your repository clean and merge-friendly!
|
|
254
|
+
|
|
255
|
+
#### 📝 **Recommended .gitignore Setup**
|
|
256
|
+
|
|
257
|
+
For the cleanest repository experience, add this to your `.gitignore`:
|
|
258
|
+
|
|
259
|
+
```gitignore
|
|
260
|
+
# Generated source code (will be recreated from YAML + registry)
|
|
261
|
+
src/modules/*/domain/entities/*.ts
|
|
262
|
+
src/modules/*/application/services/*.ts
|
|
263
|
+
src/modules/*/application/validation/*.ts
|
|
264
|
+
src/modules/*/infrastructure/controllers/*.ts
|
|
265
|
+
src/modules/*/infrastructure/stores/*.ts
|
|
266
|
+
src/modules/*/infrastructure/interfaces/*.ts
|
|
267
|
+
src/modules/*/views/*.html
|
|
268
|
+
|
|
269
|
+
# Keep these in version control
|
|
270
|
+
!*.yaml
|
|
271
|
+
!registry.json
|
|
272
|
+
!.currentjs/
|
|
273
|
+
|
|
274
|
+
# Standard Node.js ignores
|
|
275
|
+
node_modules/
|
|
276
|
+
build/
|
|
277
|
+
dist/
|
|
278
|
+
*.log
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
With this setup, your repository stays focused on what matters: your specifications and customizations, not generated boilerplate!
|
|
282
|
+
|
|
283
|
+
## Example: Building a Blog System 📝
|
|
284
|
+
|
|
285
|
+
Here's how you'd create a complete blog system:
|
|
286
|
+
|
|
287
|
+
### 1. Create the app and module
|
|
288
|
+
```bash
|
|
289
|
+
currentjs create app my-blog
|
|
290
|
+
cd my-blog
|
|
291
|
+
currentjs create module Blog
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### 2. Define your data model
|
|
295
|
+
```yaml
|
|
296
|
+
# src/modules/Blog/Blog.yaml
|
|
297
|
+
models:
|
|
298
|
+
- name: Post
|
|
299
|
+
fields:
|
|
300
|
+
- name: title
|
|
301
|
+
type: string
|
|
302
|
+
required: true
|
|
303
|
+
- name: content
|
|
304
|
+
type: string
|
|
305
|
+
required: true
|
|
306
|
+
- name: authorEmail
|
|
307
|
+
type: string
|
|
308
|
+
required: true
|
|
309
|
+
- name: publishedAt
|
|
310
|
+
type: datetime
|
|
311
|
+
required: false
|
|
312
|
+
# this part is already generated for you!
|
|
313
|
+
api:
|
|
314
|
+
prefix: /api/posts
|
|
315
|
+
endpoints:
|
|
316
|
+
- method: GET
|
|
317
|
+
path: /
|
|
318
|
+
action: list
|
|
319
|
+
- method: POST
|
|
320
|
+
path: /
|
|
321
|
+
action: create
|
|
322
|
+
- method: GET
|
|
323
|
+
path: /:id
|
|
324
|
+
action: get
|
|
325
|
+
- method: PUT
|
|
326
|
+
path: /:id
|
|
327
|
+
action: update
|
|
328
|
+
- method: DELETE
|
|
329
|
+
path: /:id
|
|
330
|
+
action: delete
|
|
331
|
+
|
|
332
|
+
routes:
|
|
333
|
+
prefix: /posts
|
|
334
|
+
strategy: [back, toast]
|
|
335
|
+
endpoints:
|
|
336
|
+
- path: /
|
|
337
|
+
action: list
|
|
338
|
+
view: postList
|
|
339
|
+
- path: /:id
|
|
340
|
+
action: get
|
|
341
|
+
view: postDetail
|
|
342
|
+
- path: /create
|
|
343
|
+
action: empty
|
|
344
|
+
view: postCreate
|
|
345
|
+
- path: /:id/edit
|
|
346
|
+
action: get
|
|
347
|
+
view: postUpdate
|
|
348
|
+
|
|
349
|
+
actions:
|
|
350
|
+
list:
|
|
351
|
+
handlers: [default:list]
|
|
352
|
+
get:
|
|
353
|
+
handlers: [default:getById]
|
|
354
|
+
create:
|
|
355
|
+
handlers: [default:create]
|
|
356
|
+
update:
|
|
357
|
+
handlers: [default:update]
|
|
358
|
+
delete:
|
|
359
|
+
handlers: [default:delete]
|
|
360
|
+
|
|
361
|
+
permissions: []
|
|
362
|
+
```
|
|
363
|
+
> **Note**: All CRUD routes and configurations are automatically generated when you run `currentjs create module Blog`. The only thing is left for you is your data model.
|
|
364
|
+
|
|
365
|
+
### 3. Generate everything
|
|
366
|
+
```bash
|
|
367
|
+
currentjs generate
|
|
368
|
+
npm run build
|
|
369
|
+
npm start
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
**Boom!** 💥 You now have a complete blog system with:
|
|
373
|
+
- REST API endpoints at `/api/posts/*`
|
|
374
|
+
- Web interface at `/posts/*`
|
|
375
|
+
- Full CRUD operations
|
|
376
|
+
- HTML templates for all views
|
|
377
|
+
- Database integration ready to go
|
|
378
|
+
|
|
379
|
+
## Generated Project Structure 🏗️
|
|
380
|
+
|
|
381
|
+
```
|
|
382
|
+
my-app/
|
|
383
|
+
├── package.json # Dependencies (router, templating, providers)
|
|
384
|
+
├── tsconfig.json # TypeScript configuration
|
|
385
|
+
├── app.yaml # Main application config
|
|
386
|
+
├── src/
|
|
387
|
+
│ ├── app.ts # Main application entry point
|
|
388
|
+
│ ├── common/ # Shared utilities and templates
|
|
389
|
+
│ │ ├── services/ # Common services
|
|
390
|
+
│ │ └── ui/
|
|
391
|
+
│ │ └── templates/
|
|
392
|
+
│ │ ├── main_view.html # Main layout template
|
|
393
|
+
│ │ └── error.html # Error page template
|
|
394
|
+
│ └── modules/ # Your business modules
|
|
395
|
+
│ └── YourModule/
|
|
396
|
+
│ ├── YourModule.yaml # Module specification
|
|
397
|
+
│ ├── domain/
|
|
398
|
+
│ │ └── entities/ # Domain models
|
|
399
|
+
│ ├── application/
|
|
400
|
+
│ │ ├── services/ # Business logic
|
|
401
|
+
│ │ └── validation/ # Input validation
|
|
402
|
+
│ ├── infrastructure/
|
|
403
|
+
│ │ ├── controllers/ # HTTP endpoints
|
|
404
|
+
│ │ └── stores/ # Data access
|
|
405
|
+
│ └── views/ # HTML templates
|
|
406
|
+
├── build/ # Compiled JavaScript
|
|
407
|
+
└── web/ # Static assets, served as is
|
|
408
|
+
├── app.js # Frontend JavaScript
|
|
409
|
+
└── translations.json # i18n support
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
## YAML Configuration Reference 📋
|
|
413
|
+
|
|
414
|
+
Understanding the key configuration sections in your module YAML files:
|
|
415
|
+
|
|
416
|
+
### Strategy Settings 🎯
|
|
417
|
+
|
|
418
|
+
The `strategy` array controls what happens after successful form submissions in your web interface:
|
|
419
|
+
|
|
420
|
+
```yaml
|
|
421
|
+
routes:
|
|
422
|
+
prefix: /posts
|
|
423
|
+
strategy: [back, toast] # Multiple strategies can be combined
|
|
424
|
+
endpoints:
|
|
425
|
+
# ... your routes
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
**Available Strategies:**
|
|
429
|
+
- **`toast`** - Shows a success notification popup (most common)
|
|
430
|
+
- **`back`** - Navigates back to the previous page using browser history
|
|
431
|
+
- **`message`** - Displays a success message in a specific element on the page
|
|
432
|
+
- **`modal`** - Shows a success message in a modal dialog
|
|
433
|
+
- **`redirect`** - Redirects to a specific URL after success
|
|
434
|
+
- **`refresh`** - Refreshes the current page
|
|
435
|
+
|
|
436
|
+
**Examples:**
|
|
437
|
+
```yaml
|
|
438
|
+
# Show toast and go back
|
|
439
|
+
strategy: [toast, back]
|
|
440
|
+
|
|
441
|
+
# Just show a toast notification
|
|
442
|
+
strategy: [toast]
|
|
443
|
+
|
|
444
|
+
# Show message in a specific element
|
|
445
|
+
strategy: [message]
|
|
446
|
+
|
|
447
|
+
# Multiple feedback mechanisms
|
|
448
|
+
strategy: [toast, modal, back]
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
The strategy is automatically applied to all form submissions in your generated templates (create, update forms).
|
|
452
|
+
|
|
453
|
+
### Actions & Handlers 🔧
|
|
454
|
+
|
|
455
|
+
The `actions` section maps logical business operations to their implementations:
|
|
456
|
+
|
|
457
|
+
```yaml
|
|
458
|
+
actions:
|
|
459
|
+
list:
|
|
460
|
+
handlers: [default:list] # Built-in CRUD handler
|
|
461
|
+
get:
|
|
462
|
+
handlers: [default:getById] # Built-in get by ID
|
|
463
|
+
create:
|
|
464
|
+
handlers: [default:create] # Built-in create
|
|
465
|
+
update:
|
|
466
|
+
handlers: [default:update] # Built-in update
|
|
467
|
+
delete:
|
|
468
|
+
handlers: [default:delete] # Built-in delete
|
|
469
|
+
customAction:
|
|
470
|
+
handlers: [service:myMethod] # Custom service method
|
|
471
|
+
complexAction:
|
|
472
|
+
handlers: [ # Multiple handlers (executed in order)
|
|
473
|
+
default:getById,
|
|
474
|
+
service:validateData,
|
|
475
|
+
default:update
|
|
476
|
+
]
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
**Built-in Handlers (`default:`):**
|
|
480
|
+
- **`default:list`** - Returns all entities with optional filtering/pagination
|
|
481
|
+
- **`default:getById`** - Fetches a single entity by ID
|
|
482
|
+
- **`default:create`** - Creates a new entity with validation
|
|
483
|
+
- **`default:update`** - Updates an existing entity by ID
|
|
484
|
+
- **`default:delete`** - Soft or hard deletes an entity by ID
|
|
485
|
+
|
|
486
|
+
**Custom Handlers (`service:`):**
|
|
487
|
+
- **`service:methodName`** - Calls a custom method on your service class
|
|
488
|
+
- Useful for complex business logic beyond basic CRUD
|
|
489
|
+
- Methods are automatically generated with proper type signatures
|
|
490
|
+
|
|
491
|
+
**Handler Chaining:**
|
|
492
|
+
You can chain multiple handlers to create complex workflows:
|
|
493
|
+
```yaml
|
|
494
|
+
actions:
|
|
495
|
+
publish:
|
|
496
|
+
handlers: [
|
|
497
|
+
default:getById, # First, fetch the entity
|
|
498
|
+
service:validateForPublish, # Then, run custom validation
|
|
499
|
+
service:updatePublishStatus, # Finally, update status
|
|
500
|
+
service:sendNotification # And send notifications
|
|
501
|
+
]
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
### Permissions & Security 🔐
|
|
505
|
+
|
|
506
|
+
The `permissions` array controls role-based access to your actions:
|
|
507
|
+
|
|
508
|
+
```yaml
|
|
509
|
+
permissions:
|
|
510
|
+
- action: create
|
|
511
|
+
roles: [admin, editor] # Only admins and editors can create
|
|
512
|
+
- action: delete
|
|
513
|
+
roles: [admin] # Only admins can delete
|
|
514
|
+
- action: list
|
|
515
|
+
roles: [all] # Everyone can list (including anonymous)
|
|
516
|
+
- action: update
|
|
517
|
+
roles: [admin, editor, owner] # Multiple roles allowed
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
**Special Roles:**
|
|
521
|
+
- **`all`** - Any user, including anonymous (no authentication required)
|
|
522
|
+
- **`authenticated`** - Any logged-in user
|
|
523
|
+
- **`owner`** - The user who owns/created the entity (automatic ownership check)
|
|
524
|
+
- **`admin`**, **`editor`**, **`user`** - Custom roles from your authentication system
|
|
525
|
+
|
|
526
|
+
**How It Works:**
|
|
527
|
+
```typescript
|
|
528
|
+
// Generated service methods automatically include permission checks
|
|
529
|
+
async create(data: CreatePostDto, user?: AuthenticatedUser): Promise<Post> {
|
|
530
|
+
// Auto-generated permission check
|
|
531
|
+
if (!user || !['admin', 'editor'].includes(user.role)) {
|
|
532
|
+
throw new Error('Insufficient permissions');
|
|
533
|
+
}
|
|
534
|
+
// ... rest of create logic
|
|
535
|
+
}
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
**No Permissions = Open Access:**
|
|
539
|
+
```yaml
|
|
540
|
+
permissions: [] # No restrictions - all actions available to everyone
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
**Ownership-Based Permissions:**
|
|
544
|
+
```yaml
|
|
545
|
+
permissions:
|
|
546
|
+
- action: update
|
|
547
|
+
roles: [owner, admin] # Users can update their own posts, admins can update any
|
|
548
|
+
- action: delete
|
|
549
|
+
roles: [owner] # Only the creator can delete their post
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
### Complete Configuration Example 🚀
|
|
553
|
+
|
|
554
|
+
Here's a real-world blog module with all concepts combined:
|
|
555
|
+
|
|
556
|
+
```yaml
|
|
557
|
+
models:
|
|
558
|
+
- name: Post
|
|
559
|
+
fields:
|
|
560
|
+
- name: title
|
|
561
|
+
type: string
|
|
562
|
+
required: true
|
|
563
|
+
- name: content
|
|
564
|
+
type: string
|
|
565
|
+
required: true
|
|
566
|
+
- name: authorId
|
|
567
|
+
type: number
|
|
568
|
+
required: true
|
|
569
|
+
- name: publishedAt
|
|
570
|
+
type: datetime
|
|
571
|
+
required: false
|
|
572
|
+
- name: status
|
|
573
|
+
type: string
|
|
574
|
+
required: true
|
|
575
|
+
|
|
576
|
+
api:
|
|
577
|
+
prefix: /api/posts
|
|
578
|
+
endpoints:
|
|
579
|
+
- method: GET
|
|
580
|
+
path: /
|
|
581
|
+
action: list
|
|
582
|
+
- method: POST
|
|
583
|
+
path: /
|
|
584
|
+
action: create
|
|
585
|
+
- method: GET
|
|
586
|
+
path: /:id
|
|
587
|
+
action: get
|
|
588
|
+
- method: PUT
|
|
589
|
+
path: /:id
|
|
590
|
+
action: update
|
|
591
|
+
- method: DELETE
|
|
592
|
+
path: /:id
|
|
593
|
+
action: delete
|
|
594
|
+
- method: POST
|
|
595
|
+
path: /:id/publish
|
|
596
|
+
action: publish
|
|
597
|
+
|
|
598
|
+
routes:
|
|
599
|
+
prefix: /posts
|
|
600
|
+
strategy: [toast, back] # Show success message and navigate back
|
|
601
|
+
endpoints:
|
|
602
|
+
- path: /
|
|
603
|
+
action: list
|
|
604
|
+
view: postList
|
|
605
|
+
- path: /:id
|
|
606
|
+
action: get
|
|
607
|
+
view: postDetail
|
|
608
|
+
- path: /create
|
|
609
|
+
action: empty
|
|
610
|
+
view: postCreate
|
|
611
|
+
- path: /:id/edit
|
|
612
|
+
action: get
|
|
613
|
+
view: postUpdate
|
|
614
|
+
|
|
615
|
+
actions:
|
|
616
|
+
list:
|
|
617
|
+
handlers: [default:list]
|
|
618
|
+
get:
|
|
619
|
+
handlers: [default:getById]
|
|
620
|
+
create:
|
|
621
|
+
handlers: [
|
|
622
|
+
service:validateContent, # Custom validation
|
|
623
|
+
default:create, # Standard creation
|
|
624
|
+
service:sendCreationNotice # Custom notification
|
|
625
|
+
]
|
|
626
|
+
update:
|
|
627
|
+
handlers: [default:update]
|
|
628
|
+
delete:
|
|
629
|
+
handlers: [
|
|
630
|
+
service:checkCanDelete, # Custom business logic
|
|
631
|
+
default:delete
|
|
632
|
+
]
|
|
633
|
+
publish:
|
|
634
|
+
handlers: [
|
|
635
|
+
default:getById,
|
|
636
|
+
service:validateForPublish,
|
|
637
|
+
service:updatePublishStatus
|
|
638
|
+
]
|
|
639
|
+
|
|
640
|
+
permissions:
|
|
641
|
+
- action: list
|
|
642
|
+
roles: [all] # Anyone can view list
|
|
643
|
+
- action: get
|
|
644
|
+
roles: [all] # Anyone can view individual posts
|
|
645
|
+
- action: create
|
|
646
|
+
roles: [authenticated] # Must be logged in to create
|
|
647
|
+
- action: update
|
|
648
|
+
roles: [owner, admin] # Authors and admins can edit
|
|
649
|
+
- action: delete
|
|
650
|
+
roles: [admin] # Only admins can delete
|
|
651
|
+
- action: publish
|
|
652
|
+
roles: [owner, admin] # Authors and admins can publish
|
|
653
|
+
```
|
|
654
|
+
|
|
655
|
+
This configuration creates a sophisticated blog system with proper security, custom business logic, and user-friendly interface behaviors.
|
|
656
|
+
|
|
657
|
+
## Part of the Framework Ecosystem 🌍
|
|
658
|
+
|
|
659
|
+
This generator is the foundation of the `currentjs` framework:
|
|
660
|
+
- Works seamlessly with `@currentjs/router` for HTTP handling
|
|
661
|
+
- Integrates with `@currentjs/templating` for server-side rendering
|
|
662
|
+
- Uses `@currentjs/provider-*` packages for database access
|
|
663
|
+
- Follows clean architecture principles for maintainable code
|
|
664
|
+
|
|
665
|
+
## Notes
|
|
666
|
+
|
|
667
|
+
- `currentjs create app` scaffolds complete app structure with TypeScript configs and dependencies
|
|
668
|
+
- `currentjs generate` creates domain entities, services, controllers, stores, and templates
|
|
669
|
+
- Generated code follows clean architecture: domain/application/infrastructure layers
|
|
670
|
+
- Supports both API endpoints and web page routes in the same module
|
|
671
|
+
- Includes change tracking system for safely modifying generated code
|
|
672
|
+
|
|
673
|
+
## Authorship & Contribution
|
|
674
|
+
|
|
675
|
+
Vibecoded with `claude-4-sonnet` (mostly) by Konstantin Zavalny. Yes, it is a vibecoded solution, really.
|
|
676
|
+
|
|
677
|
+
Any contributions such as bugfixes, improvements, etc are very welcome.
|
|
678
|
+
|
|
679
|
+
## License
|
|
680
|
+
|
|
681
|
+
GNU Lesser General Public License (LGPL)
|
|
682
|
+
|
|
683
|
+
It simply means, that you:
|
|
684
|
+
- can create a proprietary application that uses this library without having to open source their entire application code (this is the "lesser" aspect of LGPL compared to GPL).
|
|
685
|
+
- can make any modifications, but must distribute those modifications under the LGPL (or a compatible license) and include the original copyright and license notice.
|
|
686
|
+
|
package/dist/cli.d.ts
ADDED