kaelum 1.4.1 → 1.4.3
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 +16 -8
- package/cli/templates/api/app.js +4 -5
- package/cli/templates/api/controllers/usersController.js +18 -49
- package/cli/templates/api/package.json +1 -1
- package/cli/templates/api/routes.js +22 -23
- package/cli/templates/web/app.js +1 -1
- package/cli/templates/web/controllers/pagesController.js +24 -0
- package/cli/templates/web/package.json +1 -1
- package/cli/templates/web/routes.js +24 -22
- package/cli/templates/web/views/index.html +3 -3
- package/core/addRoute.js +2 -19
- package/index.js +1 -2
- package/index.mjs +2 -0
- package/package.json +6 -3
- package/cli/templates/web/controllers/.gitkeep +0 -0
package/README.md
CHANGED
|
@@ -74,7 +74,7 @@ my-web-app/
|
|
|
74
74
|
├── views/ # HTML templates
|
|
75
75
|
│ └── index.html
|
|
76
76
|
├── controllers/ # Controller logic (MVC)
|
|
77
|
-
│ └── .
|
|
77
|
+
│ └── pagesController.js
|
|
78
78
|
├── middlewares/ # Custom middlewares
|
|
79
79
|
│ └── logger.js
|
|
80
80
|
├── routes.js # Route definitions (example uses Kaelum helpers)
|
|
@@ -99,12 +99,17 @@ my-api-app/
|
|
|
99
99
|
|
|
100
100
|
## 🧩 Core API
|
|
101
101
|
|
|
102
|
-
> Kaelum exposes a factory — use `require(
|
|
103
|
-
|
|
104
|
-
```js
|
|
105
|
-
|
|
106
|
-
const
|
|
107
|
-
|
|
102
|
+
> Kaelum exposes a factory — use `require` (CommonJS) or `import` (ESM) to get an app instance:
|
|
103
|
+
|
|
104
|
+
```js
|
|
105
|
+
// CommonJS
|
|
106
|
+
const kaelum = require("kaelum");
|
|
107
|
+
const app = kaelum();
|
|
108
|
+
|
|
109
|
+
// ESM
|
|
110
|
+
import kaelum from "kaelum";
|
|
111
|
+
const app = kaelum();
|
|
112
|
+
```
|
|
108
113
|
|
|
109
114
|
### `app.setConfig(options)`
|
|
110
115
|
|
|
@@ -147,7 +152,7 @@ app.addRoute("/home", {
|
|
|
147
152
|
post: (req, res) => res.send("Posted!"),
|
|
148
153
|
});
|
|
149
154
|
|
|
150
|
-
// apiRoute builds RESTy resources with nested subpaths:
|
|
155
|
+
// apiRoute builds RESTy resources with recursive nested subpaths:
|
|
151
156
|
app.apiRoute("users", {
|
|
152
157
|
get: listUsers,
|
|
153
158
|
post: createUser,
|
|
@@ -155,6 +160,9 @@ app.apiRoute("users", {
|
|
|
155
160
|
get: getUserById,
|
|
156
161
|
put: updateUser,
|
|
157
162
|
delete: deleteUser,
|
|
163
|
+
"/posts": {
|
|
164
|
+
get: getUserPosts // GET /users/:id/posts
|
|
165
|
+
}
|
|
158
166
|
},
|
|
159
167
|
});
|
|
160
168
|
```
|
package/cli/templates/api/app.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
// app.js - example API project generated by Kaelum (API template)
|
|
2
1
|
const kaelum = require("kaelum");
|
|
3
2
|
|
|
4
3
|
const app = kaelum();
|
|
5
4
|
|
|
6
5
|
// enable basic safety + logs via setConfig
|
|
7
6
|
app.setConfig({
|
|
8
|
-
cors: true,
|
|
9
|
-
helmet: true,
|
|
10
|
-
logs: true,
|
|
11
|
-
bodyParser: true,
|
|
7
|
+
cors: true, // Enable CORS for cross-origin requests
|
|
8
|
+
helmet: true, // Add security headers
|
|
9
|
+
logs: true, // Log requests to console (using morgan)
|
|
10
|
+
bodyParser: true, // Parse JSON and URL-encoded bodies (default true)
|
|
12
11
|
});
|
|
13
12
|
|
|
14
13
|
// mount routes
|
|
@@ -1,58 +1,27 @@
|
|
|
1
1
|
// controllers/usersController.js
|
|
2
|
-
// Simple in-memory
|
|
2
|
+
// Simple in-memory controller for Kaelum API demonstration
|
|
3
3
|
|
|
4
|
-
let _id = 1;
|
|
5
4
|
const users = [
|
|
6
|
-
{ id:
|
|
7
|
-
{ id:
|
|
5
|
+
{ id: 1, name: "Maria", role: "admin" },
|
|
6
|
+
{ id: 2, name: "Joao", role: "user" },
|
|
8
7
|
];
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
res.json({ data: users });
|
|
12
|
-
}
|
|
9
|
+
exports.list = (req, res) => res.json(users);
|
|
13
10
|
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
.json({ error: { message: "name and email required" } });
|
|
20
|
-
}
|
|
21
|
-
const user = { id: _id++, name: body.name, email: body.email };
|
|
22
|
-
users.push(user);
|
|
23
|
-
res.status(201).json({ data: user });
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function getUserById(req, res) {
|
|
27
|
-
const id = Number(req.params.id);
|
|
28
|
-
const u = users.find((x) => x.id === id);
|
|
29
|
-
if (!u) return res.status(404).json({ error: { message: "User not found" } });
|
|
30
|
-
res.json({ data: u });
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function updateUser(req, res) {
|
|
34
|
-
const id = Number(req.params.id);
|
|
35
|
-
const u = users.find((x) => x.id === id);
|
|
36
|
-
if (!u) return res.status(404).json({ error: { message: "User not found" } });
|
|
37
|
-
const body = req.body || {};
|
|
38
|
-
if (body.name) u.name = body.name;
|
|
39
|
-
if (body.email) u.email = body.email;
|
|
40
|
-
res.json({ data: u });
|
|
41
|
-
}
|
|
11
|
+
exports.create = (req, res) => {
|
|
12
|
+
const newUser = { id: users.length + 1, ...req.body };
|
|
13
|
+
users.push(newUser);
|
|
14
|
+
res.status(201).json({ success: true, user: newUser });
|
|
15
|
+
};
|
|
42
16
|
|
|
43
|
-
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
return res.status(404).json({ error: { message: "User not found" } });
|
|
48
|
-
const removed = users.splice(idx, 1)[0];
|
|
49
|
-
res.json({ data: removed });
|
|
50
|
-
}
|
|
17
|
+
exports.get = (req, res) => {
|
|
18
|
+
const user = users.find((u) => u.id == req.params.id);
|
|
19
|
+
return user ? res.json(user) : res.status(404).json({ error: "User not found" });
|
|
20
|
+
};
|
|
51
21
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
deleteUser,
|
|
22
|
+
exports.posts = (req, res) => {
|
|
23
|
+
res.json([
|
|
24
|
+
{ id: 101, title: "Kaelum Rocks", userId: req.params.id },
|
|
25
|
+
{ id: 102, title: "Recursive Routing", userId: req.params.id },
|
|
26
|
+
]);
|
|
58
27
|
};
|
|
@@ -1,34 +1,33 @@
|
|
|
1
|
-
// routes.js
|
|
2
|
-
const
|
|
3
|
-
getUsers,
|
|
4
|
-
createUser,
|
|
5
|
-
getUserById,
|
|
6
|
-
updateUser,
|
|
7
|
-
deleteUser,
|
|
8
|
-
} = require("./controllers/usersController");
|
|
9
|
-
|
|
1
|
+
// routes.js
|
|
2
|
+
const users = require("./controllers/usersController");
|
|
10
3
|
const auth = require("./middlewares/authMock");
|
|
11
4
|
|
|
12
|
-
module.exports =
|
|
13
|
-
// Global
|
|
14
|
-
// also demonstrate per-path middleware usage via setMiddleware(path, middleware)
|
|
5
|
+
module.exports = (app) => {
|
|
6
|
+
// Global middleware for /users path
|
|
15
7
|
app.setMiddleware("/users", (req, res, next) => {
|
|
16
|
-
//
|
|
17
|
-
|
|
18
|
-
if (["POST", "PUT", "DELETE"].includes(req.method)) {
|
|
19
|
-
return require("./middlewares/authMock")(req, res, next);
|
|
20
|
-
}
|
|
8
|
+
// Simple method check
|
|
9
|
+
if (req.method === "POST") return auth(req, res, next);
|
|
21
10
|
next();
|
|
22
11
|
});
|
|
23
12
|
|
|
24
|
-
//
|
|
13
|
+
// Recursive Nested Routing Example
|
|
25
14
|
app.apiRoute("users", {
|
|
26
|
-
get:
|
|
27
|
-
post:
|
|
15
|
+
get: users.list, // GET /users
|
|
16
|
+
post: users.create, // POST /users (protected by middleware above)
|
|
17
|
+
|
|
18
|
+
// Nested parameter: /users/:id
|
|
28
19
|
"/:id": {
|
|
29
|
-
get:
|
|
30
|
-
|
|
31
|
-
|
|
20
|
+
get: users.get, // GET /users/:id
|
|
21
|
+
|
|
22
|
+
// Nested resource: /users/:id/posts
|
|
23
|
+
"/posts": {
|
|
24
|
+
get: users.posts, // GET /users/:id/posts
|
|
25
|
+
},
|
|
32
26
|
},
|
|
33
27
|
});
|
|
28
|
+
|
|
29
|
+
// Metadata endpoint
|
|
30
|
+
app.addRoute("/meta", {
|
|
31
|
+
get: (req, res) => res.json({ version: "1.4.2", framework: "Kaelum" }),
|
|
32
|
+
});
|
|
34
33
|
};
|
package/cli/templates/web/app.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// app.js - example project generated by Kaelum (Web template)
|
|
2
1
|
const kaelum = require("kaelum");
|
|
3
2
|
|
|
4
3
|
const app = kaelum();
|
|
@@ -9,6 +8,7 @@ app.setConfig({
|
|
|
9
8
|
helmet: true,
|
|
10
9
|
static: "public", // will serve ./public
|
|
11
10
|
bodyParser: true, // default enabled — explicit for clarity
|
|
11
|
+
// views: { engine: 'ejs', path: './views' },
|
|
12
12
|
});
|
|
13
13
|
|
|
14
14
|
// Register routes (routes.js uses Kaelum helpers)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// controllers/pagesController.js
|
|
2
|
+
const path = require("path");
|
|
3
|
+
|
|
4
|
+
const view = (file) => path.join(process.cwd(), "views", file);
|
|
5
|
+
|
|
6
|
+
exports.home = (req, res) => {
|
|
7
|
+
res.sendFile(view("index.html"));
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
exports.about = (req, res) => {
|
|
11
|
+
res.send("<h1>About Kaelum</h1><p>A minimalist framework.</p>");
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
exports.team = (req, res) => {
|
|
15
|
+
res.send("<h1>Our Team</h1><p>Built by open source contributors.</p>");
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
exports.dashboard = (req, res) => {
|
|
19
|
+
res.send("<h1>Dashboard</h1><p>Welcome, " + (req.user || "User") + "</p>");
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
exports.settings = (req, res) => {
|
|
23
|
+
res.send("<h1>Settings</h1><p>Adjust your preferences here.</p>");
|
|
24
|
+
};
|
|
@@ -1,32 +1,34 @@
|
|
|
1
|
-
// routes.js
|
|
2
|
-
const
|
|
1
|
+
// routes.js
|
|
2
|
+
const pages = require("./controllers/pagesController");
|
|
3
|
+
const logger = require("./middlewares/logger");
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
5
|
+
// Mock auth middleware
|
|
6
|
+
const auth = (req, res, next) => {
|
|
7
|
+
// Simulate auth check
|
|
8
|
+
req.user = "Admin";
|
|
9
|
+
next();
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
module.exports = (app) => {
|
|
13
|
+
// Home
|
|
14
|
+
app.addRoute("/", pages.home);
|
|
12
15
|
|
|
13
|
-
//
|
|
16
|
+
// Nested Route Example: /about and /about/team
|
|
14
17
|
app.addRoute("/about", {
|
|
15
|
-
get:
|
|
16
|
-
|
|
18
|
+
get: pages.about,
|
|
19
|
+
"/team": {
|
|
20
|
+
get: pages.team,
|
|
17
21
|
},
|
|
18
22
|
});
|
|
19
23
|
|
|
20
|
-
//
|
|
21
|
-
|
|
22
|
-
const logger = require("./middlewares/logger");
|
|
23
|
-
app.setMiddleware("/protected", logger);
|
|
24
|
+
// Middleware Chain Example
|
|
25
|
+
const secureSection = [logger, auth];
|
|
24
26
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
// Dashboard with nested settings, protected by middleware chain
|
|
28
|
+
app.addRoute("/dashboard", {
|
|
29
|
+
get: [...secureSection, pages.dashboard],
|
|
30
|
+
"/settings": {
|
|
31
|
+
get: [...secureSection, pages.settings],
|
|
30
32
|
},
|
|
31
33
|
});
|
|
32
34
|
};
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
<div class="card">
|
|
27
27
|
<h3>Rotas</h3>
|
|
28
28
|
<p>
|
|
29
|
-
Veja as rotas: <code>/</code>, <code>/about</code>,
|
|
30
|
-
<code>/
|
|
29
|
+
Veja as rotas: <code>/</code>, <code>/about</code>, <code>/about/team</code>,
|
|
30
|
+
<code>/dashboard</code>, <code>/dashboard/settings</code>.
|
|
31
31
|
</p>
|
|
32
32
|
</div>
|
|
33
33
|
<div class="card">
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
</div>
|
|
38
38
|
|
|
39
39
|
<p class="small">
|
|
40
|
-
Gerado pela Kaelum CLI • Versão do template para Kaelum
|
|
40
|
+
Gerado pela Kaelum CLI • Versão do template para Kaelum v1.4.2
|
|
41
41
|
</p>
|
|
42
42
|
</section>
|
|
43
43
|
</main>
|
package/core/addRoute.js
CHANGED
|
@@ -114,26 +114,9 @@ function addRoute(app, basePath, handlers = {}) {
|
|
|
114
114
|
continue;
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
// If nested value is object ->
|
|
117
|
+
// If nested value is object -> RECURSE
|
|
118
118
|
if (isPlainObject(value)) {
|
|
119
|
-
|
|
120
|
-
const handlerFn = value[method];
|
|
121
|
-
const m = method.toLowerCase();
|
|
122
|
-
if (!supportedMethods.includes(m)) {
|
|
123
|
-
throw new Error(
|
|
124
|
-
`Unsupported HTTP method "${method}" for route "${subPath}"`
|
|
125
|
-
);
|
|
126
|
-
}
|
|
127
|
-
// allow single function or array for handlerFn
|
|
128
|
-
if (typeof handlerFn !== "function" && !Array.isArray(handlerFn)) {
|
|
129
|
-
throw new Error(
|
|
130
|
-
`Handler for ${method} ${subPath} must be a function or array of functions`
|
|
131
|
-
);
|
|
132
|
-
}
|
|
133
|
-
const fns = normalizeHandlersToArray(handlerFn);
|
|
134
|
-
const wrapped = fns.map(wrapHandler);
|
|
135
|
-
app[m](subPath, ...wrapped);
|
|
136
|
-
}
|
|
119
|
+
addRoute(app, subPath, value);
|
|
137
120
|
continue;
|
|
138
121
|
}
|
|
139
122
|
|
package/index.js
CHANGED
package/index.mjs
ADDED
package/package.json
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kaelum",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.3",
|
|
4
4
|
"description": "A minimalist Node.js framework for building web pages and APIs with simplicity and speed.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"exports": {
|
|
7
|
-
".":
|
|
7
|
+
".": {
|
|
8
|
+
"import": "./index.mjs",
|
|
9
|
+
"require": "./index.js"
|
|
10
|
+
}
|
|
8
11
|
},
|
|
9
12
|
"bin": {
|
|
10
13
|
"kaelum": "cli/index.js"
|
|
11
14
|
},
|
|
12
15
|
"scripts": {
|
|
13
|
-
"test": "jest --verbose"
|
|
16
|
+
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js --verbose"
|
|
14
17
|
},
|
|
15
18
|
"keywords": [
|
|
16
19
|
"framework",
|
|
File without changes
|