@erwininteractive/mvc 0.1.3 → 0.1.4

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.
Files changed (3) hide show
  1. package/README.md +230 -78
  2. package/dist/cli.js +1 -1
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -5,91 +5,208 @@ A lightweight, full-featured MVC framework for Node.js 20+ built with TypeScript
5
5
  ## Features
6
6
 
7
7
  - **Express** - Fast, minimal web framework
8
- - **Prisma** - Modern database ORM with PostgreSQL
9
8
  - **EJS + Alpine.js** - Server-side templating with reactive client-side components
10
- - **Redis Sessions** - Scalable session management
9
+ - **Optional Database** - Add Prisma + PostgreSQL when you need it
10
+ - **Optional Redis Sessions** - Scalable session management
11
11
  - **JWT Authentication** - Secure token-based auth with bcrypt password hashing
12
12
  - **CLI Tools** - Scaffold apps and generate models/controllers
13
13
 
14
14
  ## Quick Start
15
15
 
16
- ### Create a New Application
17
-
18
16
  ```bash
19
17
  npx @erwininteractive/mvc init myapp
20
18
  cd myapp
21
- cp .env.example .env
22
- # Edit .env with your database configuration
23
- npx prisma migrate dev --name init
24
19
  npm run dev
25
20
  ```
26
21
 
27
- ### Generate a Model
22
+ Visit http://localhost:3000 - your app is running!
28
23
 
29
- ```bash
30
- npx erwinmvc generate model Post
24
+ ---
25
+
26
+ ## Getting Started
27
+
28
+ ### Step 1: Create a New Page
29
+
30
+ Create `src/views/about.ejs`:
31
+
32
+ ```html
33
+ <!doctype html>
34
+ <html>
35
+ <head>
36
+ <title><%= title %></title>
37
+ </head>
38
+ <body>
39
+ <h1><%= title %></h1>
40
+ <p>Welcome to my about page!</p>
41
+ </body>
42
+ </html>
31
43
  ```
32
44
 
33
- This creates a Prisma model and runs migrations.
45
+ ### Step 2: Add a Route
34
46
 
35
- ### Generate a Controller
47
+ Edit `src/server.ts`:
36
48
 
37
- ```bash
38
- npx erwinmvc generate controller Post
49
+ ```typescript
50
+ app.get("/about", (req, res) => {
51
+ res.render("about", { title: "About Us" });
52
+ });
39
53
  ```
40
54
 
41
- This creates a CRUD controller with routes:
42
- - `GET /posts` - List all posts
43
- - `GET /posts/:id` - Show a single post
44
- - `POST /posts` - Create a post
45
- - `PUT /posts/:id` - Update a post
46
- - `DELETE /posts/:id` - Delete a post
55
+ ### Step 3: View Your Page
47
56
 
48
- ## CLI Commands
57
+ Visit http://localhost:3000/about
49
58
 
50
- | Command | Description |
51
- |---------|-------------|
52
- | `erwinmvc init <dir>` | Scaffold a new MVC application |
53
- | `erwinmvc generate model <name>` | Generate a Prisma model |
54
- | `erwinmvc generate controller <name>` | Generate a CRUD controller |
59
+ ---
60
+
61
+ ## Creating Pages
55
62
 
56
- ### Options
63
+ ### EJS Templates
57
64
 
58
- **init:**
59
- - `--skip-install` - Skip running npm install
60
- - `--skip-prisma` - Skip Prisma client generation
65
+ Create `.ejs` files in `src/views/`. EJS lets you use JavaScript in HTML:
61
66
 
62
- **generate model:**
63
- - `--skip-migrate` - Skip running Prisma migrate
67
+ ```html
68
+ <!-- Output a variable (escaped) -->
69
+ <h1><%= title %></h1>
64
70
 
65
- **generate controller:**
66
- - `--no-views` - Skip generating EJS views
71
+ <!-- Output raw HTML -->
72
+ <%- htmlContent %>
67
73
 
68
- ## Framework API
74
+ <!-- JavaScript logic -->
75
+ <% if (user) { %>
76
+ <p>Welcome, <%= user.name %>!</p>
77
+ <% } %>
78
+
79
+ <!-- Loop through items -->
80
+ <ul>
81
+ <% items.forEach(item => { %>
82
+ <li><%= item.name %></li>
83
+ <% }); %>
84
+ </ul>
85
+
86
+ <!-- Include another template -->
87
+ <%- include('partials/header') %>
88
+ ```
69
89
 
70
- ### App Factory
90
+ ### Adding Routes
71
91
 
72
92
  ```typescript
73
- import { createMvcApp, startServer } from "@erwininteractive/mvc";
93
+ // Simple page
94
+ app.get("/contact", (req, res) => {
95
+ res.render("contact", { title: "Contact Us" });
96
+ });
74
97
 
75
- const { app, redisClient } = await createMvcApp({
76
- viewsPath: "src/views",
77
- publicPath: "public",
98
+ // Handle form submission
99
+ app.post("/contact", (req, res) => {
100
+ const { name, email, message } = req.body;
101
+ console.log(`Message from ${name}: ${message}`);
102
+ res.redirect("/contact?sent=true");
78
103
  });
79
104
 
80
- startServer(app);
105
+ // JSON API endpoint
106
+ app.get("/api/users", (req, res) => {
107
+ res.json([{ id: 1, name: "John" }]);
108
+ });
81
109
  ```
82
110
 
83
- ### Database
111
+ ---
112
+
113
+ ## Controllers
114
+
115
+ Generate a controller with the CLI:
116
+
117
+ ```bash
118
+ npx erwinmvc generate controller Product
119
+ ```
120
+
121
+ This creates `src/controllers/ProductController.ts` with CRUD actions:
122
+
123
+ | Action | HTTP Method | URL | Description |
124
+ |-----------|-------------|------------------|-------------|
125
+ | `index` | GET | /products | List all |
126
+ | `show` | GET | /products/:id | Show one |
127
+ | `store` | POST | /products | Create |
128
+ | `update` | PUT | /products/:id | Update |
129
+ | `destroy` | DELETE | /products/:id | Delete |
130
+
131
+ ### Using Controllers
132
+
133
+ ```typescript
134
+ import * as ProductController from "./controllers/ProductController";
135
+
136
+ app.get("/products", ProductController.index);
137
+ app.get("/products/:id", ProductController.show);
138
+ app.post("/products", ProductController.store);
139
+ app.put("/products/:id", ProductController.update);
140
+ app.delete("/products/:id", ProductController.destroy);
141
+ ```
142
+
143
+ ---
144
+
145
+ ## Database (Optional)
146
+
147
+ Your app works without a database. Add one when you need it.
148
+
149
+ ### Setup
150
+
151
+ ```bash
152
+ npm run db:setup
153
+ ```
154
+
155
+ Edit `.env` with your database URL:
156
+
157
+ ```
158
+ DATABASE_URL="postgresql://user:password@localhost:5432/mydb"
159
+ ```
160
+
161
+ Run migrations:
162
+
163
+ ```bash
164
+ npx prisma migrate dev --name init
165
+ ```
166
+
167
+ ### Generate Models
168
+
169
+ ```bash
170
+ npx erwinmvc generate model Post
171
+ ```
172
+
173
+ Edit `prisma/schema.prisma` to add fields:
174
+
175
+ ```prisma
176
+ model Post {
177
+ id Int @id @default(autoincrement())
178
+ title String
179
+ content String?
180
+ published Boolean @default(false)
181
+ createdAt DateTime @default(now())
182
+ updatedAt DateTime @updatedAt
183
+
184
+ @@map("posts")
185
+ }
186
+ ```
187
+
188
+ Run migrations again:
189
+
190
+ ```bash
191
+ npx prisma migrate dev --name add-post-fields
192
+ ```
193
+
194
+ ### Use in Code
84
195
 
85
196
  ```typescript
86
197
  import { getPrismaClient } from "@erwininteractive/mvc";
87
198
 
88
199
  const prisma = getPrismaClient();
89
- const users = await prisma.user.findMany();
200
+
201
+ app.get("/posts", async (req, res) => {
202
+ const posts = await prisma.post.findMany();
203
+ res.render("posts/index", { posts });
204
+ });
90
205
  ```
91
206
 
92
- ### Authentication
207
+ ---
208
+
209
+ ## Authentication
93
210
 
94
211
  ```typescript
95
212
  import {
@@ -115,59 +232,94 @@ app.get("/protected", authenticate, (req, res) => {
115
232
  });
116
233
  ```
117
234
 
118
- ### Routing
235
+ ---
119
236
 
120
- ```typescript
121
- import { registerControllers } from "@erwininteractive/mvc";
237
+ ## CLI Commands
122
238
 
123
- // Auto-register all *Controller.ts files
124
- await registerControllers(app, path.resolve("src/controllers"));
125
- ```
239
+ | Command | Description |
240
+ |---------|-------------|
241
+ | `npx @erwininteractive/mvc init <dir>` | Create a new app |
242
+ | `npx erwinmvc generate controller <name>` | Generate a CRUD controller |
243
+ | `npx erwinmvc generate model <name>` | Generate a database model |
126
244
 
127
- ## Environment Variables
245
+ ### Init Options
128
246
 
129
- Create a `.env` file with:
247
+ | Option | Description |
248
+ |--------|-------------|
249
+ | `--skip-install` | Skip running npm install |
250
+ | `--with-database` | Include Prisma database setup |
130
251
 
131
- ```env
132
- DATABASE_URL="postgresql://USER:PASSWORD@localhost:5432/yourdb?schema=public"
133
- REDIS_URL="redis://localhost:6379"
134
- JWT_SECRET="your-secret-key"
135
- SESSION_SECRET="your-session-secret"
136
- PORT=3000
137
- NODE_ENV=development
138
- ```
252
+ ### Generate Options
139
253
 
140
- ## Project Structure
254
+ | Option | Description |
255
+ |--------|-------------|
256
+ | `--skip-migrate` | Skip running Prisma migrate (model) |
257
+ | `--no-views` | Skip generating EJS views (controller) |
258
+
259
+ ---
141
260
 
142
- Generated applications follow this structure:
261
+ ## Project Structure
143
262
 
144
263
  ```
145
264
  myapp/
146
265
  ├── src/
147
- │ ├── controllers/ # Route controllers
148
- │ ├── middleware/ # Express middleware
149
- │ ├── views/ # EJS templates
150
- │ └── server.ts # Entry point
151
- ├── prisma/
152
- │ └── schema.prisma # Database schema
153
- ├── public/ # Static files
266
+ │ ├── server.ts # Main app - add routes here
267
+ │ ├── views/ # EJS templates
268
+ │ ├── controllers/ # Route handlers (optional)
269
+ │ └── middleware/ # Express middleware (optional)
270
+ ├── public/ # Static files (CSS, JS, images)
271
+ ├── prisma/ # Database (after db:setup)
272
+ │ └── schema.prisma
154
273
  ├── .env.example
274
+ ├── .gitignore
155
275
  ├── package.json
156
276
  └── tsconfig.json
157
277
  ```
158
278
 
159
- ## Controller Convention
279
+ ### Static Files
160
280
 
161
- Controllers export named functions that map to routes:
281
+ Files in `public/` are served at the root URL:
162
282
 
163
- ```typescript
164
- // src/controllers/PostController.ts
165
- export async function index(req, res) { /* GET /posts */ }
166
- export async function show(req, res) { /* GET /posts/:id */ }
167
- export async function store(req, res) { /* POST /posts */ }
168
- export async function update(req, res) { /* PUT /posts/:id */ }
169
- export async function destroy(req, res) { /* DELETE /posts/:id */ }
170
283
  ```
284
+ public/css/style.css → /css/style.css
285
+ public/images/logo.png → /images/logo.png
286
+ ```
287
+
288
+ ---
289
+
290
+ ## App Commands
291
+
292
+ | Command | Description |
293
+ |---------|-------------|
294
+ | `npm run dev` | Start development server (auto-reload) |
295
+ | `npm run build` | Build for production |
296
+ | `npm start` | Run production build |
297
+ | `npm run db:setup` | Install database dependencies |
298
+ | `npm run db:migrate` | Run database migrations |
299
+
300
+ ---
301
+
302
+ ## Environment Variables
303
+
304
+ All optional. Create `.env` from `.env.example`:
305
+
306
+ ```env
307
+ DATABASE_URL="postgresql://user:pass@localhost:5432/mydb" # For database
308
+ REDIS_URL="redis://localhost:6379" # For sessions
309
+ JWT_SECRET="your-secret-key" # For auth
310
+ SESSION_SECRET="your-session-secret" # For sessions
311
+ PORT=3000 # Server port
312
+ NODE_ENV=development # Environment
313
+ ```
314
+
315
+ ---
316
+
317
+ ## Learn More
318
+
319
+ - [Express.js Documentation](https://expressjs.com/)
320
+ - [EJS Documentation](https://ejs.co/)
321
+ - [Prisma Documentation](https://www.prisma.io/docs/)
322
+ - [Alpine.js Documentation](https://alpinejs.dev/)
171
323
 
172
324
  ## License
173
325
 
package/dist/cli.js CHANGED
@@ -9,7 +9,7 @@ const program = new commander_1.Command();
9
9
  program
10
10
  .name("erwinmvc")
11
11
  .description("CLI for @erwininteractive/mvc framework")
12
- .version("0.1.3");
12
+ .version("0.1.4");
13
13
  // Init command - scaffold a new application
14
14
  program
15
15
  .command("init <dir>")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@erwininteractive/mvc",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "A lightweight, full-featured MVC framework for Node.js with Express, Prisma, and EJS",
5
5
  "main": "dist/framework/index.js",
6
6
  "types": "dist/framework/index.d.ts",