@erwininteractive/mvc 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/README.md +174 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +61 -0
- package/dist/framework/App.d.ts +38 -0
- package/dist/framework/App.js +100 -0
- package/dist/framework/Auth.d.ts +27 -0
- package/dist/framework/Auth.js +67 -0
- package/dist/framework/Router.d.ts +29 -0
- package/dist/framework/Router.js +125 -0
- package/dist/framework/db.d.ts +13 -0
- package/dist/framework/db.js +41 -0
- package/dist/framework/index.d.ts +5 -0
- package/dist/framework/index.js +22 -0
- package/dist/generators/generateController.d.ts +7 -0
- package/dist/generators/generateController.js +110 -0
- package/dist/generators/generateModel.d.ts +7 -0
- package/dist/generators/generateModel.js +77 -0
- package/dist/generators/initApp.d.ts +8 -0
- package/dist/generators/initApp.js +113 -0
- package/dist/generators/paths.d.ts +17 -0
- package/dist/generators/paths.js +55 -0
- package/package.json +72 -0
- package/prisma/schema.prisma +19 -0
- package/templates/appScaffold/README.md +297 -0
- package/templates/appScaffold/package.json +23 -0
- package/templates/appScaffold/public/favicon.svg +16 -0
- package/templates/appScaffold/src/controllers/HomeController.ts +9 -0
- package/templates/appScaffold/src/middleware/auth.ts +8 -0
- package/templates/appScaffold/src/server.ts +24 -0
- package/templates/appScaffold/src/views/index.ejs +300 -0
- package/templates/appScaffold/tsconfig.json +16 -0
- package/templates/controller.ts.ejs +98 -0
- package/templates/model.prisma.ejs +7 -0
- package/templates/view.ejs.ejs +42 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "node",
|
|
6
|
+
"rootDir": "src",
|
|
7
|
+
"outDir": "dist",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"forceConsistentCasingInFileNames": true,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"resolveJsonModule": true
|
|
13
|
+
},
|
|
14
|
+
"include": ["src"],
|
|
15
|
+
"exclude": ["node_modules", "dist"]
|
|
16
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import type { Request, Response } from "express";
|
|
2
|
+
import { getPrismaClient } from "@erwininteractive/mvc";
|
|
3
|
+
|
|
4
|
+
const prisma = getPrismaClient();
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* GET /<%= resourcePath %>
|
|
8
|
+
* List all <%= lowerModelName %> records.
|
|
9
|
+
*/
|
|
10
|
+
export async function index(req: Request, res: Response): Promise<void> {
|
|
11
|
+
try {
|
|
12
|
+
const data = await prisma.<%= lowerModelName %>.findMany();
|
|
13
|
+
res.json(data);
|
|
14
|
+
} catch (error) {
|
|
15
|
+
res.status(500).json({ error: "Failed to fetch <%= lowerModelName %> records" });
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* GET /<%= resourcePath %>/:id
|
|
21
|
+
* Show a single <%= lowerModelName %> record.
|
|
22
|
+
*/
|
|
23
|
+
export async function show(req: Request, res: Response): Promise<void> {
|
|
24
|
+
try {
|
|
25
|
+
const id = Number(req.params.id);
|
|
26
|
+
if (isNaN(id)) {
|
|
27
|
+
res.status(400).json({ error: "Invalid ID" });
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const item = await prisma.<%= lowerModelName %>.findUnique({ where: { id } });
|
|
32
|
+
if (!item) {
|
|
33
|
+
res.status(404).json({ error: "<%= modelName %> not found" });
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
res.json(item);
|
|
38
|
+
} catch (error) {
|
|
39
|
+
res.status(500).json({ error: "Failed to fetch <%= lowerModelName %>" });
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* POST /<%= resourcePath %>
|
|
45
|
+
* Create a new <%= lowerModelName %> record.
|
|
46
|
+
*/
|
|
47
|
+
export async function store(req: Request, res: Response): Promise<void> {
|
|
48
|
+
try {
|
|
49
|
+
const data = req.body;
|
|
50
|
+
const item = await prisma.<%= lowerModelName %>.create({ data });
|
|
51
|
+
res.status(201).json(item);
|
|
52
|
+
} catch (error) {
|
|
53
|
+
res.status(500).json({ error: "Failed to create <%= lowerModelName %>" });
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* PUT /<%= resourcePath %>/:id
|
|
59
|
+
* Update a <%= lowerModelName %> record.
|
|
60
|
+
*/
|
|
61
|
+
export async function update(req: Request, res: Response): Promise<void> {
|
|
62
|
+
try {
|
|
63
|
+
const id = Number(req.params.id);
|
|
64
|
+
if (isNaN(id)) {
|
|
65
|
+
res.status(400).json({ error: "Invalid ID" });
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const data = req.body;
|
|
70
|
+
const item = await prisma.<%= lowerModelName %>.update({
|
|
71
|
+
where: { id },
|
|
72
|
+
data,
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
res.json(item);
|
|
76
|
+
} catch (error) {
|
|
77
|
+
res.status(500).json({ error: "Failed to update <%= lowerModelName %>" });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* DELETE /<%= resourcePath %>/:id
|
|
83
|
+
* Delete a <%= lowerModelName %> record.
|
|
84
|
+
*/
|
|
85
|
+
export async function destroy(req: Request, res: Response): Promise<void> {
|
|
86
|
+
try {
|
|
87
|
+
const id = Number(req.params.id);
|
|
88
|
+
if (isNaN(id)) {
|
|
89
|
+
res.status(400).json({ error: "Invalid ID" });
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
await prisma.<%= lowerModelName %>.delete({ where: { id } });
|
|
94
|
+
res.status(204).send();
|
|
95
|
+
} catch (error) {
|
|
96
|
+
res.status(500).json({ error: "Failed to delete <%= lowerModelName %>" });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title><%= title %></title>
|
|
7
|
+
<script src="https://unpkg.com/alpinejs" defer></script>
|
|
8
|
+
<style>
|
|
9
|
+
* { box-sizing: border-box; }
|
|
10
|
+
body {
|
|
11
|
+
font-family: system-ui, -apple-system, sans-serif;
|
|
12
|
+
line-height: 1.6;
|
|
13
|
+
max-width: 800px;
|
|
14
|
+
margin: 0 auto;
|
|
15
|
+
padding: 2rem;
|
|
16
|
+
background: #f5f5f5;
|
|
17
|
+
}
|
|
18
|
+
h1 { color: #333; }
|
|
19
|
+
.card {
|
|
20
|
+
background: white;
|
|
21
|
+
border-radius: 8px;
|
|
22
|
+
padding: 1.5rem;
|
|
23
|
+
margin: 1rem 0;
|
|
24
|
+
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
25
|
+
}
|
|
26
|
+
</style>
|
|
27
|
+
</head>
|
|
28
|
+
<body x-data="{ loading: false }">
|
|
29
|
+
<h1><%= title %></h1>
|
|
30
|
+
|
|
31
|
+
<div class="card">
|
|
32
|
+
<% if (viewType === 'index') { %>
|
|
33
|
+
<p>List of <%= modelName %> items will be displayed here.</p>
|
|
34
|
+
<div x-show="loading">Loading...</div>
|
|
35
|
+
<% } else if (viewType === 'show') { %>
|
|
36
|
+
<p><%= modelName %> details will be displayed here.</p>
|
|
37
|
+
<% } %>
|
|
38
|
+
</div>
|
|
39
|
+
|
|
40
|
+
<p><a href="/">Back to Home</a></p>
|
|
41
|
+
</body>
|
|
42
|
+
</html>
|