@erwininteractive/mvc 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +175 -2
- package/dist/cli.js +2 -1
- package/dist/generators/initApp.d.ts +1 -0
- package/dist/generators/initApp.js +17 -0
- package/package.json +1 -1
- package/templates/ci/test.yml +49 -0
package/README.md
CHANGED
|
@@ -110,9 +110,55 @@ app.get("/api/users", (req, res) => {
|
|
|
110
110
|
|
|
111
111
|
---
|
|
112
112
|
|
|
113
|
+
## Resources
|
|
114
|
+
|
|
115
|
+
Generate a complete resource (model + controller + views) with one command:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
npx erwinmvc generate resource Post
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
This creates:
|
|
122
|
+
- `prisma/schema.prisma` - Adds the Post model
|
|
123
|
+
- `src/controllers/PostController.ts` - Full CRUD controller with form handling
|
|
124
|
+
- `src/views/posts/index.ejs` - List view
|
|
125
|
+
- `src/views/posts/show.ejs` - Detail view
|
|
126
|
+
- `src/views/posts/create.ejs` - Create form
|
|
127
|
+
- `src/views/posts/edit.ejs` - Edit form
|
|
128
|
+
|
|
129
|
+
### Resource Routes
|
|
130
|
+
|
|
131
|
+
| Action | HTTP Method | URL | Description |
|
|
132
|
+
|-----------|-------------|------------------|------------------|
|
|
133
|
+
| `index` | GET | /posts | List all |
|
|
134
|
+
| `create` | GET | /posts/create | Show create form |
|
|
135
|
+
| `store` | POST | /posts | Create new |
|
|
136
|
+
| `show` | GET | /posts/:id | Show one |
|
|
137
|
+
| `edit` | GET | /posts/:id/edit | Show edit form |
|
|
138
|
+
| `update` | PUT | /posts/:id | Update |
|
|
139
|
+
| `destroy` | DELETE | /posts/:id | Delete |
|
|
140
|
+
|
|
141
|
+
### Wiring Up Routes
|
|
142
|
+
|
|
143
|
+
Add to `src/server.ts`:
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
import * as PostController from "./controllers/PostController";
|
|
147
|
+
|
|
148
|
+
app.get("/posts", PostController.index);
|
|
149
|
+
app.get("/posts/create", PostController.create);
|
|
150
|
+
app.post("/posts", PostController.store);
|
|
151
|
+
app.get("/posts/:id", PostController.show);
|
|
152
|
+
app.get("/posts/:id/edit", PostController.edit);
|
|
153
|
+
app.put("/posts/:id", PostController.update);
|
|
154
|
+
app.delete("/posts/:id", PostController.destroy);
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
113
159
|
## Controllers
|
|
114
160
|
|
|
115
|
-
Generate a controller
|
|
161
|
+
Generate just a controller (without model/views):
|
|
116
162
|
|
|
117
163
|
```bash
|
|
118
164
|
npx erwinmvc generate controller Product
|
|
@@ -239,6 +285,7 @@ app.get("/protected", authenticate, (req, res) => {
|
|
|
239
285
|
| Command | Description |
|
|
240
286
|
|---------|-------------|
|
|
241
287
|
| `npx @erwininteractive/mvc init <dir>` | Create a new app |
|
|
288
|
+
| `npx erwinmvc generate resource <name>` | Generate model + controller + views |
|
|
242
289
|
| `npx erwinmvc generate controller <name>` | Generate a CRUD controller |
|
|
243
290
|
| `npx erwinmvc generate model <name>` | Generate a database model |
|
|
244
291
|
|
|
@@ -248,8 +295,19 @@ app.get("/protected", authenticate, (req, res) => {
|
|
|
248
295
|
|--------|-------------|
|
|
249
296
|
| `--skip-install` | Skip running npm install |
|
|
250
297
|
| `--with-database` | Include Prisma database setup |
|
|
298
|
+
| `--with-ci` | Include GitHub Actions CI workflow |
|
|
251
299
|
|
|
252
|
-
###
|
|
300
|
+
### Resource Options
|
|
301
|
+
|
|
302
|
+
| Option | Description |
|
|
303
|
+
|--------|-------------|
|
|
304
|
+
| `--skip-model` | Skip generating Prisma model |
|
|
305
|
+
| `--skip-controller` | Skip generating controller |
|
|
306
|
+
| `--skip-views` | Skip generating views |
|
|
307
|
+
| `--skip-migrate` | Skip running Prisma migrate |
|
|
308
|
+
| `--api-only` | Generate API-only controller (no views) |
|
|
309
|
+
|
|
310
|
+
### Other Generate Options
|
|
253
311
|
|
|
254
312
|
| Option | Description |
|
|
255
313
|
|--------|-------------|
|
|
@@ -299,6 +357,121 @@ public/images/logo.png → /images/logo.png
|
|
|
299
357
|
|
|
300
358
|
---
|
|
301
359
|
|
|
360
|
+
## CI/CD (Optional)
|
|
361
|
+
|
|
362
|
+
Add GitHub Actions CI to your project for automated testing:
|
|
363
|
+
|
|
364
|
+
```bash
|
|
365
|
+
npx @erwininteractive/mvc init myapp --with-ci
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
Or add CI to an existing project by creating `.github/workflows/test.yml`:
|
|
369
|
+
|
|
370
|
+
```yaml
|
|
371
|
+
name: Test
|
|
372
|
+
|
|
373
|
+
on:
|
|
374
|
+
push:
|
|
375
|
+
branches: [main]
|
|
376
|
+
pull_request:
|
|
377
|
+
branches: [main]
|
|
378
|
+
|
|
379
|
+
jobs:
|
|
380
|
+
test:
|
|
381
|
+
runs-on: ubuntu-latest
|
|
382
|
+
|
|
383
|
+
steps:
|
|
384
|
+
- name: Checkout
|
|
385
|
+
uses: actions/checkout@v4
|
|
386
|
+
|
|
387
|
+
- name: Setup Node.js
|
|
388
|
+
uses: actions/setup-node@v4
|
|
389
|
+
with:
|
|
390
|
+
node-version: "20"
|
|
391
|
+
cache: "npm"
|
|
392
|
+
|
|
393
|
+
- name: Install dependencies
|
|
394
|
+
run: npm ci
|
|
395
|
+
|
|
396
|
+
- name: Run tests
|
|
397
|
+
run: npm test
|
|
398
|
+
|
|
399
|
+
- name: Build
|
|
400
|
+
run: npm run build
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
### Adding Database Tests
|
|
404
|
+
|
|
405
|
+
If your app uses a database, add PostgreSQL as a service:
|
|
406
|
+
|
|
407
|
+
```yaml
|
|
408
|
+
jobs:
|
|
409
|
+
test:
|
|
410
|
+
runs-on: ubuntu-latest
|
|
411
|
+
|
|
412
|
+
services:
|
|
413
|
+
postgres:
|
|
414
|
+
image: postgres:16
|
|
415
|
+
env:
|
|
416
|
+
POSTGRES_USER: postgres
|
|
417
|
+
POSTGRES_PASSWORD: postgres
|
|
418
|
+
POSTGRES_DB: test
|
|
419
|
+
ports:
|
|
420
|
+
- 5432:5432
|
|
421
|
+
options: >-
|
|
422
|
+
--health-cmd pg_isready
|
|
423
|
+
--health-interval 10s
|
|
424
|
+
--health-timeout 5s
|
|
425
|
+
--health-retries 5
|
|
426
|
+
|
|
427
|
+
steps:
|
|
428
|
+
- name: Checkout
|
|
429
|
+
uses: actions/checkout@v4
|
|
430
|
+
|
|
431
|
+
- name: Setup Node.js
|
|
432
|
+
uses: actions/setup-node@v4
|
|
433
|
+
with:
|
|
434
|
+
node-version: "20"
|
|
435
|
+
cache: "npm"
|
|
436
|
+
|
|
437
|
+
- name: Install dependencies
|
|
438
|
+
run: npm ci
|
|
439
|
+
|
|
440
|
+
- name: Run migrations
|
|
441
|
+
run: npx prisma migrate deploy
|
|
442
|
+
env:
|
|
443
|
+
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/test
|
|
444
|
+
|
|
445
|
+
- name: Run tests
|
|
446
|
+
run: npm test
|
|
447
|
+
env:
|
|
448
|
+
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/test
|
|
449
|
+
|
|
450
|
+
- name: Build
|
|
451
|
+
run: npm run build
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
### Secrets
|
|
455
|
+
|
|
456
|
+
For production deployments, add these secrets in your GitHub repository settings:
|
|
457
|
+
|
|
458
|
+
| Secret | Description |
|
|
459
|
+
|--------|-------------|
|
|
460
|
+
| `DATABASE_URL` | Production database connection string |
|
|
461
|
+
| `REDIS_URL` | Production Redis connection string |
|
|
462
|
+
| `JWT_SECRET` | Secret key for JWT signing |
|
|
463
|
+
| `SESSION_SECRET` | Secret key for session encryption |
|
|
464
|
+
|
|
465
|
+
Access secrets in your workflow:
|
|
466
|
+
|
|
467
|
+
```yaml
|
|
468
|
+
env:
|
|
469
|
+
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
|
470
|
+
JWT_SECRET: ${{ secrets.JWT_SECRET }}
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
---
|
|
474
|
+
|
|
302
475
|
## Environment Variables
|
|
303
476
|
|
|
304
477
|
All optional. Create `.env` from `.env.example`:
|
package/dist/cli.js
CHANGED
|
@@ -10,13 +10,14 @@ const program = new commander_1.Command();
|
|
|
10
10
|
program
|
|
11
11
|
.name("erwinmvc")
|
|
12
12
|
.description("CLI for @erwininteractive/mvc framework")
|
|
13
|
-
.version("0.
|
|
13
|
+
.version("0.2.0");
|
|
14
14
|
// Init command - scaffold a new application
|
|
15
15
|
program
|
|
16
16
|
.command("init <dir>")
|
|
17
17
|
.description("Scaffold a new MVC application")
|
|
18
18
|
.option("--skip-install", "Skip npm install")
|
|
19
19
|
.option("--with-database", "Include database/Prisma setup")
|
|
20
|
+
.option("--with-ci", "Include GitHub Actions CI workflow")
|
|
20
21
|
.action(async (dir, options) => {
|
|
21
22
|
try {
|
|
22
23
|
await (0, initApp_1.initApp)(dir, options);
|
|
@@ -68,6 +68,10 @@ async function initApp(dir, options = {}) {
|
|
|
68
68
|
if (options.withDatabase) {
|
|
69
69
|
setupDatabase(targetDir);
|
|
70
70
|
}
|
|
71
|
+
// Setup CI if requested
|
|
72
|
+
if (options.withCi) {
|
|
73
|
+
setupCi(targetDir);
|
|
74
|
+
}
|
|
71
75
|
console.log(`
|
|
72
76
|
Next steps:
|
|
73
77
|
cd ${dir}
|
|
@@ -81,6 +85,19 @@ To add database support later:
|
|
|
81
85
|
npx prisma migrate dev --name init
|
|
82
86
|
` : ""}`);
|
|
83
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* Setup GitHub Actions CI workflow.
|
|
90
|
+
*/
|
|
91
|
+
function setupCi(targetDir) {
|
|
92
|
+
const workflowDir = path_1.default.join(targetDir, ".github", "workflows");
|
|
93
|
+
fs_1.default.mkdirSync(workflowDir, { recursive: true });
|
|
94
|
+
const ciTemplateDir = path_1.default.join((0, paths_1.getTemplatesDir)(), "ci");
|
|
95
|
+
const testWorkflow = path_1.default.join(ciTemplateDir, "test.yml");
|
|
96
|
+
if (fs_1.default.existsSync(testWorkflow)) {
|
|
97
|
+
fs_1.default.copyFileSync(testWorkflow, path_1.default.join(workflowDir, "test.yml"));
|
|
98
|
+
console.log("GitHub Actions CI workflow added.");
|
|
99
|
+
}
|
|
100
|
+
}
|
|
84
101
|
/**
|
|
85
102
|
* Setup Prisma database support.
|
|
86
103
|
*/
|
package/package.json
CHANGED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
name: Test
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
# Uncomment to add PostgreSQL for database tests
|
|
14
|
+
# services:
|
|
15
|
+
# postgres:
|
|
16
|
+
# image: postgres:16
|
|
17
|
+
# env:
|
|
18
|
+
# POSTGRES_USER: postgres
|
|
19
|
+
# POSTGRES_PASSWORD: postgres
|
|
20
|
+
# POSTGRES_DB: test
|
|
21
|
+
# ports:
|
|
22
|
+
# - 5432:5432
|
|
23
|
+
# options: >-
|
|
24
|
+
# --health-cmd pg_isready
|
|
25
|
+
# --health-interval 10s
|
|
26
|
+
# --health-timeout 5s
|
|
27
|
+
# --health-retries 5
|
|
28
|
+
|
|
29
|
+
steps:
|
|
30
|
+
- name: Checkout
|
|
31
|
+
uses: actions/checkout@v4
|
|
32
|
+
|
|
33
|
+
- name: Setup Node.js
|
|
34
|
+
uses: actions/setup-node@v4
|
|
35
|
+
with:
|
|
36
|
+
node-version: "20"
|
|
37
|
+
cache: "npm"
|
|
38
|
+
|
|
39
|
+
- name: Install dependencies
|
|
40
|
+
run: npm ci
|
|
41
|
+
|
|
42
|
+
- name: Run tests
|
|
43
|
+
run: npm test
|
|
44
|
+
# Uncomment for database tests
|
|
45
|
+
# env:
|
|
46
|
+
# DATABASE_URL: postgresql://postgres:postgres@localhost:5432/test
|
|
47
|
+
|
|
48
|
+
- name: Build
|
|
49
|
+
run: npm run build
|