kaelum 1.7.0 → 1.8.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/cli/create.js +102 -57
- package/cli/index.js +97 -10
- package/cli/templates/js/api/app.js +30 -0
- package/cli/templates/{api → js/api}/package.json +2 -5
- package/cli/templates/{api → js/api}/routes.js +7 -7
- package/cli/templates/js/web/app.js +30 -0
- package/cli/templates/{web → js/web}/controllers/pagesController.js +2 -2
- package/cli/templates/{web → js/web}/middlewares/logger.js +2 -1
- package/cli/templates/{web → js/web}/package.json +2 -4
- package/cli/templates/{web → js/web}/public/style.css +2 -0
- package/cli/templates/{web → js/web}/routes.js +4 -5
- package/cli/templates/{web → js/web}/views/index.html +14 -10
- package/cli/templates/ts/api/package.json +24 -0
- package/cli/templates/ts/api/src/app.ts +32 -0
- package/cli/templates/ts/api/src/controllers/usersController.ts +41 -0
- package/cli/templates/ts/api/src/middlewares/authMock.ts +16 -0
- package/cli/templates/ts/api/src/routes.ts +35 -0
- package/cli/templates/ts/api/tsconfig.json +19 -0
- package/cli/templates/ts/web/package.json +24 -0
- package/cli/templates/ts/web/public/style.css +63 -0
- package/cli/templates/ts/web/src/app.ts +32 -0
- package/cli/templates/ts/web/src/controllers/pagesController.ts +26 -0
- package/cli/templates/ts/web/src/middlewares/logger.ts +9 -0
- package/cli/templates/ts/web/src/routes.ts +34 -0
- package/cli/templates/ts/web/tsconfig.json +19 -0
- package/cli/templates/ts/web/views/index.html +49 -0
- package/cli/utils.js +33 -7
- package/core/plugin.js +82 -82
- package/package.json +1 -1
- package/cli/templates/api/app.js +0 -25
- package/cli/templates/web/app.js +0 -26
- /package/cli/templates/{api → js/api}/controllers/usersController.js +0 -0
- /package/cli/templates/{api → js/api}/middlewares/authMock.js +0 -0
package/cli/create.js
CHANGED
|
@@ -18,11 +18,10 @@ function runInstall(cwd) {
|
|
|
18
18
|
const cmd = "npm";
|
|
19
19
|
const args = lockExists ? ["ci"] : ["install"];
|
|
20
20
|
|
|
21
|
-
// Spawn child process and inherit stdio so user sees progress
|
|
22
21
|
const child = spawn(cmd, args, {
|
|
23
22
|
cwd,
|
|
24
23
|
stdio: "inherit",
|
|
25
|
-
shell: process.platform === "win32",
|
|
24
|
+
shell: process.platform === "win32",
|
|
26
25
|
});
|
|
27
26
|
|
|
28
27
|
child.on("error", (err) => {
|
|
@@ -38,103 +37,149 @@ function runInstall(cwd) {
|
|
|
38
37
|
|
|
39
38
|
/**
|
|
40
39
|
* createProject - create project from template
|
|
41
|
-
* @param {Object} defaults - optional { projectName, template, autoInstall }
|
|
40
|
+
* @param {Object} defaults - optional { projectName, language, template, autoInstall }
|
|
42
41
|
*/
|
|
43
42
|
async function createProject(defaults = {}) {
|
|
44
|
-
console.log("🚀
|
|
43
|
+
console.log("🚀 Welcome to Kaelum CLI!\n");
|
|
45
44
|
|
|
46
45
|
try {
|
|
47
|
-
//
|
|
46
|
+
// Ensure templates dir exists
|
|
48
47
|
const templatesExists = await fs.pathExists(templatesDir);
|
|
49
48
|
if (!templatesExists) {
|
|
50
|
-
console.error("❌
|
|
49
|
+
console.error("❌ Templates directory not found in CLI.");
|
|
51
50
|
return;
|
|
52
51
|
}
|
|
53
52
|
|
|
54
|
-
//
|
|
55
|
-
const
|
|
56
|
-
|
|
53
|
+
// Gather answers (use defaults when present)
|
|
54
|
+
const questions = [];
|
|
55
|
+
|
|
56
|
+
// Project name
|
|
57
|
+
if (!defaults.projectName) {
|
|
58
|
+
questions.push({
|
|
57
59
|
type: "input",
|
|
58
60
|
name: "projectName",
|
|
59
|
-
message: "
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
message: "What is your project name?",
|
|
62
|
+
validate: (input) => (input ? true : "Project name cannot be empty."),
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Language selection
|
|
67
|
+
if (!defaults.language) {
|
|
68
|
+
questions.push({
|
|
69
|
+
type: "list",
|
|
70
|
+
name: "language",
|
|
71
|
+
message: "Choose your language:",
|
|
72
|
+
choices: [
|
|
73
|
+
{ name: "JavaScript", value: "js" },
|
|
74
|
+
{ name: "TypeScript", value: "ts" },
|
|
75
|
+
],
|
|
76
|
+
default: "js",
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Template selection
|
|
81
|
+
if (!defaults.template) {
|
|
82
|
+
questions.push({
|
|
64
83
|
type: "list",
|
|
65
84
|
name: "template",
|
|
66
|
-
message: "
|
|
67
|
-
choices:
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const
|
|
85
|
+
message: "Choose your template:",
|
|
86
|
+
choices: [
|
|
87
|
+
{ name: "web — MVC with views & static files", value: "web" },
|
|
88
|
+
{ name: "api — REST API ready", value: "api" },
|
|
89
|
+
],
|
|
90
|
+
default: "web",
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Auto install
|
|
95
|
+
questions.push({
|
|
96
|
+
type: "confirm",
|
|
97
|
+
name: "autoInstall",
|
|
98
|
+
message: "Install dependencies now? (recommended)",
|
|
99
|
+
default:
|
|
100
|
+
typeof defaults.autoInstall === "boolean"
|
|
101
|
+
? defaults.autoInstall
|
|
102
|
+
: true,
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
const answers = await inq.prompt(questions);
|
|
106
|
+
|
|
107
|
+
// Merge defaults with answers
|
|
108
|
+
const projectName = defaults.projectName || answers.projectName;
|
|
109
|
+
const language = defaults.language || answers.language;
|
|
110
|
+
const template = defaults.template || answers.template;
|
|
111
|
+
const autoInstall = answers.autoInstall;
|
|
112
|
+
|
|
93
113
|
const targetDir = path.resolve(process.cwd(), projectName);
|
|
94
|
-
const templateDir = path.join(templatesDir, template);
|
|
114
|
+
const templateDir = path.join(templatesDir, language, template);
|
|
95
115
|
|
|
96
|
-
//
|
|
116
|
+
// Template existence check
|
|
97
117
|
const templateExists = await fs.pathExists(templateDir);
|
|
98
118
|
if (!templateExists) {
|
|
99
|
-
console.error(`\n❌ Template "${template}"
|
|
119
|
+
console.error(`\n❌ Template "${language}/${template}" not found.`);
|
|
100
120
|
return;
|
|
101
121
|
}
|
|
102
122
|
|
|
103
123
|
if (await fs.pathExists(targetDir)) {
|
|
104
124
|
console.error(
|
|
105
|
-
`\n❌
|
|
125
|
+
`\n❌ Folder "${projectName}" already exists. Choose a different name or delete the existing folder.`
|
|
106
126
|
);
|
|
107
127
|
return;
|
|
108
128
|
}
|
|
109
129
|
|
|
110
|
-
//
|
|
111
|
-
const
|
|
130
|
+
// Copy template, update package.json, generate .env and .gitignore
|
|
131
|
+
const isTypeScript = language === "ts";
|
|
132
|
+
const result = await copyTemplate(templateDir, targetDir, projectName, {
|
|
133
|
+
isTypeScript,
|
|
134
|
+
});
|
|
112
135
|
if (!result.ok) {
|
|
113
|
-
console.error(`\n❌
|
|
136
|
+
console.error(`\n❌ Error copying template: ${result.error}`);
|
|
114
137
|
return;
|
|
115
138
|
}
|
|
116
139
|
|
|
117
|
-
|
|
118
|
-
|
|
140
|
+
// Post-creation summary
|
|
141
|
+
const langLabel = language === "ts" ? "TypeScript" : "JavaScript";
|
|
142
|
+
console.log(`\n✅ Project "${projectName}" created successfully!`);
|
|
143
|
+
console.log(` Language: ${langLabel}`);
|
|
144
|
+
console.log(` Template: ${template}`);
|
|
145
|
+
console.log(`\n📁 cd ${projectName}`);
|
|
119
146
|
|
|
120
147
|
if (autoInstall) {
|
|
121
|
-
console.log("
|
|
148
|
+
console.log("📦 Installing dependencies... (this may take a few minutes)\n");
|
|
122
149
|
try {
|
|
123
150
|
await runInstall(targetDir);
|
|
124
|
-
console.log("\n✅
|
|
125
|
-
|
|
151
|
+
console.log("\n✅ Dependencies installed successfully!");
|
|
152
|
+
if (isTypeScript) {
|
|
153
|
+
console.log("\n📌 Next steps:");
|
|
154
|
+
console.log(` npm run dev Start development server (tsx watch)`);
|
|
155
|
+
console.log(` npm run build Compile TypeScript to JavaScript`);
|
|
156
|
+
console.log(` npm start Run compiled output\n`);
|
|
157
|
+
} else {
|
|
158
|
+
console.log("\n📌 Next steps:");
|
|
159
|
+
console.log(` npm start Start the server`);
|
|
160
|
+
console.log(` npm run dev Start with file watching\n`);
|
|
161
|
+
}
|
|
126
162
|
} catch (installErr) {
|
|
127
163
|
console.error(
|
|
128
|
-
"\n❌
|
|
164
|
+
"\n❌ Failed to install dependencies automatically:",
|
|
129
165
|
installErr.message || installErr
|
|
130
166
|
);
|
|
131
|
-
console.log(`➡️
|
|
167
|
+
console.log(`➡️ Try manually: cd ${projectName} && npm install`);
|
|
132
168
|
}
|
|
133
169
|
} else {
|
|
134
|
-
|
|
170
|
+
if (isTypeScript) {
|
|
171
|
+
console.log(`\n📌 Next steps:`);
|
|
172
|
+
console.log(` cd ${projectName} && npm install`);
|
|
173
|
+
console.log(` npm run dev Start development server (tsx watch)`);
|
|
174
|
+
console.log(` npm run build Compile TypeScript to JavaScript`);
|
|
175
|
+
console.log(` npm start Run compiled output\n`);
|
|
176
|
+
} else {
|
|
177
|
+
console.log(`\n📌 Next steps:`);
|
|
178
|
+
console.log(` cd ${projectName} && npm install && npm start\n`);
|
|
179
|
+
}
|
|
135
180
|
}
|
|
136
181
|
} catch (err) {
|
|
137
|
-
console.error("❌
|
|
182
|
+
console.error("❌ Unexpected error:", err.message || err);
|
|
138
183
|
}
|
|
139
184
|
}
|
|
140
185
|
|
package/cli/index.js
CHANGED
|
@@ -1,20 +1,91 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
const { createProject } = require("./create");
|
|
3
|
+
const path = require("path");
|
|
3
4
|
const argv = process.argv.slice(2);
|
|
4
5
|
|
|
6
|
+
function getVersion() {
|
|
7
|
+
const pkg = require(path.join(__dirname, "..", "package.json"));
|
|
8
|
+
return pkg.version;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function printVersion() {
|
|
12
|
+
console.log(`kaelum v${getVersion()}`);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function printInfo() {
|
|
16
|
+
const os = require("os");
|
|
17
|
+
console.log(`Kaelum CLI`);
|
|
18
|
+
console.log(` Kaelum: v${getVersion()}`);
|
|
19
|
+
console.log(` Node.js: ${process.version}`);
|
|
20
|
+
console.log(` OS: ${os.type()} ${os.release()} (${os.arch()})`);
|
|
21
|
+
console.log(` Platform: ${os.platform()}`);
|
|
22
|
+
}
|
|
23
|
+
|
|
5
24
|
function printHelp() {
|
|
6
|
-
console.log(`
|
|
25
|
+
console.log(`
|
|
26
|
+
Kaelum CLI v${getVersion()}
|
|
27
|
+
|
|
7
28
|
Usage:
|
|
8
|
-
kaelum create
|
|
9
|
-
kaelum create <name>
|
|
10
|
-
kaelum create <name> --template
|
|
11
|
-
|
|
29
|
+
kaelum create Interactive mode
|
|
30
|
+
kaelum create <name> Interactive template choice
|
|
31
|
+
kaelum create <name> --template <template> Non-interactive
|
|
32
|
+
|
|
33
|
+
Templates:
|
|
34
|
+
js-web JavaScript + MVC with views & static files
|
|
35
|
+
js-api JavaScript + REST API
|
|
36
|
+
ts-web TypeScript + MVC with views & static files
|
|
37
|
+
ts-api TypeScript + REST API
|
|
38
|
+
web Alias for js-web
|
|
39
|
+
api Alias for js-api
|
|
40
|
+
|
|
41
|
+
Commands:
|
|
42
|
+
kaelum help Show this help message
|
|
43
|
+
kaelum --version, -v Show installed version
|
|
44
|
+
kaelum info Show environment information
|
|
45
|
+
|
|
46
|
+
Examples:
|
|
47
|
+
kaelum create my-app --template ts-web
|
|
48
|
+
kaelum create my-api --template js-api
|
|
12
49
|
`);
|
|
13
50
|
}
|
|
14
51
|
|
|
52
|
+
/**
|
|
53
|
+
* Resolve legacy template aliases for backward compatibility.
|
|
54
|
+
* "web" -> "js-web", "api" -> "js-api"
|
|
55
|
+
*/
|
|
56
|
+
function resolveTemplateAlias(template) {
|
|
57
|
+
const aliases = { web: "js-web", api: "js-api" };
|
|
58
|
+
return aliases[template] || template;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Parse a combined template value like "js-web" into { language, template }.
|
|
63
|
+
* Returns null if invalid.
|
|
64
|
+
*/
|
|
65
|
+
function parseTemplate(value) {
|
|
66
|
+
const resolved = resolveTemplateAlias(value);
|
|
67
|
+
const valid = {
|
|
68
|
+
"js-web": { language: "js", template: "web" },
|
|
69
|
+
"js-api": { language: "js", template: "api" },
|
|
70
|
+
"ts-web": { language: "ts", template: "web" },
|
|
71
|
+
"ts-api": { language: "ts", template: "api" },
|
|
72
|
+
};
|
|
73
|
+
return valid[resolved] || null;
|
|
74
|
+
}
|
|
75
|
+
|
|
15
76
|
async function main() {
|
|
16
77
|
const [command, maybeName, maybeFlag, maybeTemplate] = argv;
|
|
17
78
|
|
|
79
|
+
// Version flag
|
|
80
|
+
if (
|
|
81
|
+
command === "--version" ||
|
|
82
|
+
command === "-v"
|
|
83
|
+
) {
|
|
84
|
+
printVersion();
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Help or no command
|
|
18
89
|
if (
|
|
19
90
|
!command ||
|
|
20
91
|
command === "help" ||
|
|
@@ -25,25 +96,41 @@ async function main() {
|
|
|
25
96
|
return;
|
|
26
97
|
}
|
|
27
98
|
|
|
99
|
+
// Info command
|
|
100
|
+
if (command === "info") {
|
|
101
|
+
printInfo();
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
|
|
28
105
|
if (command === "create") {
|
|
29
|
-
//
|
|
106
|
+
// Non-interactive shorthand: kaelum create my-app --template ts-web
|
|
30
107
|
if (maybeName && maybeFlag === "--template" && maybeTemplate) {
|
|
31
|
-
|
|
108
|
+
const parsed = parseTemplate(maybeTemplate);
|
|
109
|
+
if (!parsed) {
|
|
110
|
+
console.log(`Unknown template: "${maybeTemplate}"`);
|
|
111
|
+
console.log(`Available templates: js-web, js-api, ts-web, ts-api (or aliases: web, api)`);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
await createProject({
|
|
115
|
+
projectName: maybeName,
|
|
116
|
+
language: parsed.language,
|
|
117
|
+
template: parsed.template,
|
|
118
|
+
});
|
|
32
119
|
return;
|
|
33
120
|
}
|
|
34
121
|
|
|
35
|
-
//
|
|
122
|
+
// Semi-interactive: kaelum create my-app (will ask language + template)
|
|
36
123
|
if (maybeName && !maybeFlag) {
|
|
37
124
|
await createProject({ projectName: maybeName });
|
|
38
125
|
return;
|
|
39
126
|
}
|
|
40
127
|
|
|
41
|
-
//
|
|
128
|
+
// Fully interactive
|
|
42
129
|
await createProject();
|
|
43
130
|
return;
|
|
44
131
|
}
|
|
45
132
|
|
|
46
|
-
console.log(`
|
|
133
|
+
console.log(`Unknown command: "${command}"`);
|
|
47
134
|
printHelp();
|
|
48
135
|
}
|
|
49
136
|
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const kaelum = require("kaelum");
|
|
2
|
+
|
|
3
|
+
const app = kaelum();
|
|
4
|
+
|
|
5
|
+
// Configure security and logging
|
|
6
|
+
app.setConfig({
|
|
7
|
+
cors: true,
|
|
8
|
+
helmet: true,
|
|
9
|
+
logs: true,
|
|
10
|
+
bodyParser: true,
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
// Mount routes
|
|
14
|
+
const routes = require("./routes");
|
|
15
|
+
routes(app);
|
|
16
|
+
|
|
17
|
+
// Health check endpoint
|
|
18
|
+
app.healthCheck("/health");
|
|
19
|
+
|
|
20
|
+
// Graceful shutdown hook
|
|
21
|
+
app.onShutdown(() => {
|
|
22
|
+
console.log("Cleaning up resources...");
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// Error handler (JSON responses)
|
|
26
|
+
app.useErrorHandler({ exposeStack: false });
|
|
27
|
+
|
|
28
|
+
// Start server
|
|
29
|
+
const PORT = process.env.PORT || 4000;
|
|
30
|
+
app.start(PORT);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kaelum-api-app",
|
|
3
3
|
"version": "0.1.0",
|
|
4
|
-
"description": "
|
|
4
|
+
"description": "REST API application generated by Kaelum CLI (api template)",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"start": "node app.js",
|
|
7
7
|
"dev": "node --watch app.js"
|
|
@@ -13,10 +13,7 @@
|
|
|
13
13
|
"author": "",
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"kaelum": "^1.
|
|
17
|
-
"cors": "^2.8.5",
|
|
18
|
-
"helmet": "^6.0.0",
|
|
19
|
-
"morgan": "^1.10.0"
|
|
16
|
+
"kaelum": "^1.8.0"
|
|
20
17
|
},
|
|
21
18
|
"devDependencies": {}
|
|
22
19
|
}
|
|
@@ -5,29 +5,29 @@ const auth = require("./middlewares/authMock");
|
|
|
5
5
|
module.exports = (app) => {
|
|
6
6
|
// Global middleware for /users path
|
|
7
7
|
app.setMiddleware("/users", (req, res, next) => {
|
|
8
|
-
//
|
|
8
|
+
// Require auth on POST requests
|
|
9
9
|
if (req.method === "POST") return auth(req, res, next);
|
|
10
10
|
next();
|
|
11
11
|
});
|
|
12
12
|
|
|
13
|
-
//
|
|
13
|
+
// RESTful nested routing example
|
|
14
14
|
app.apiRoute("users", {
|
|
15
|
-
get: users.list,
|
|
16
|
-
post: users.create,
|
|
15
|
+
get: users.list,
|
|
16
|
+
post: users.create,
|
|
17
17
|
|
|
18
18
|
// Nested parameter: /users/:id
|
|
19
19
|
"/:id": {
|
|
20
|
-
get: users.get,
|
|
20
|
+
get: users.get,
|
|
21
21
|
|
|
22
22
|
// Nested resource: /users/:id/posts
|
|
23
23
|
"/posts": {
|
|
24
|
-
get: users.posts,
|
|
24
|
+
get: users.posts,
|
|
25
25
|
},
|
|
26
26
|
},
|
|
27
27
|
});
|
|
28
28
|
|
|
29
29
|
// Metadata endpoint
|
|
30
30
|
app.addRoute("/meta", {
|
|
31
|
-
get: (req, res) => res.json({ version: "1.
|
|
31
|
+
get: (req, res) => res.json({ version: "1.8.0", framework: "Kaelum" }),
|
|
32
32
|
});
|
|
33
33
|
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const kaelum = require("kaelum");
|
|
2
|
+
|
|
3
|
+
const app = kaelum();
|
|
4
|
+
|
|
5
|
+
// Configure security, static files, and body parsing
|
|
6
|
+
app.setConfig({
|
|
7
|
+
cors: true,
|
|
8
|
+
helmet: true,
|
|
9
|
+
static: "public",
|
|
10
|
+
bodyParser: true,
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
// Register routes
|
|
14
|
+
const routes = require("./routes");
|
|
15
|
+
routes(app);
|
|
16
|
+
|
|
17
|
+
// Health check endpoint
|
|
18
|
+
app.healthCheck("/health");
|
|
19
|
+
|
|
20
|
+
// Graceful shutdown hook
|
|
21
|
+
app.onShutdown(() => {
|
|
22
|
+
console.log("Cleaning up resources...");
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// Error handler (returns JSON on errors)
|
|
26
|
+
app.useErrorHandler({ exposeStack: false });
|
|
27
|
+
|
|
28
|
+
// Start server
|
|
29
|
+
const PORT = process.env.PORT || 3000;
|
|
30
|
+
app.start(PORT);
|
|
@@ -8,11 +8,11 @@ exports.home = (req, res) => {
|
|
|
8
8
|
};
|
|
9
9
|
|
|
10
10
|
exports.about = (req, res) => {
|
|
11
|
-
res.send("<h1>About Kaelum</h1><p>A minimalist framework.</p>");
|
|
11
|
+
res.send("<h1>About Kaelum</h1><p>A minimalist Node.js framework.</p>");
|
|
12
12
|
};
|
|
13
13
|
|
|
14
14
|
exports.team = (req, res) => {
|
|
15
|
-
res.send("<h1>Our Team</h1><p>Built by open
|
|
15
|
+
res.send("<h1>Our Team</h1><p>Built by open-source contributors.</p>");
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
exports.dashboard = (req, res) => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kaelum-web-app",
|
|
3
3
|
"version": "0.1.0",
|
|
4
|
-
"description": "
|
|
4
|
+
"description": "Web application generated by Kaelum CLI (web template)",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"start": "node app.js",
|
|
7
7
|
"dev": "node --watch app.js"
|
|
@@ -13,9 +13,7 @@
|
|
|
13
13
|
"author": "",
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"kaelum": "^1.
|
|
17
|
-
"cors": "^2.8.5",
|
|
18
|
-
"helmet": "^6.0.0"
|
|
16
|
+
"kaelum": "^1.8.0"
|
|
19
17
|
},
|
|
20
18
|
"devDependencies": {}
|
|
21
19
|
}
|
|
@@ -44,6 +44,7 @@ header h1 {
|
|
|
44
44
|
display: flex;
|
|
45
45
|
gap: 16px;
|
|
46
46
|
margin-top: 12px;
|
|
47
|
+
flex-wrap: wrap;
|
|
47
48
|
}
|
|
48
49
|
|
|
49
50
|
.card {
|
|
@@ -52,6 +53,7 @@ header h1 {
|
|
|
52
53
|
padding: 16px;
|
|
53
54
|
box-shadow: 0 6px 18px rgba(37, 57, 99, 0.06);
|
|
54
55
|
flex: 1;
|
|
56
|
+
min-width: 200px;
|
|
55
57
|
}
|
|
56
58
|
|
|
57
59
|
.small {
|
|
@@ -4,16 +4,15 @@ const logger = require("./middlewares/logger");
|
|
|
4
4
|
|
|
5
5
|
// Mock auth middleware
|
|
6
6
|
const auth = (req, res, next) => {
|
|
7
|
-
|
|
8
|
-
req.user = "Admin";
|
|
7
|
+
req.user = "Admin";
|
|
9
8
|
next();
|
|
10
9
|
};
|
|
11
10
|
|
|
12
11
|
module.exports = (app) => {
|
|
13
|
-
// Home
|
|
12
|
+
// Home page
|
|
14
13
|
app.addRoute("/", pages.home);
|
|
15
14
|
|
|
16
|
-
// Nested
|
|
15
|
+
// Nested route example: /about and /about/team
|
|
17
16
|
app.addRoute("/about", {
|
|
18
17
|
get: pages.about,
|
|
19
18
|
"/team": {
|
|
@@ -21,7 +20,7 @@ module.exports = (app) => {
|
|
|
21
20
|
},
|
|
22
21
|
});
|
|
23
22
|
|
|
24
|
-
// Middleware
|
|
23
|
+
// Middleware chain example
|
|
25
24
|
const secureSection = [logger, auth];
|
|
26
25
|
|
|
27
26
|
// Dashboard with nested settings, protected by middleware chain
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
|
-
<html lang="
|
|
2
|
+
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="utf-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
|
@@ -11,33 +11,37 @@
|
|
|
11
11
|
<header>
|
|
12
12
|
<h1>Kaelum.js</h1>
|
|
13
13
|
<p class="subtitle">
|
|
14
|
-
|
|
14
|
+
Minimalist framework for Web Apps & APIs — Demo Template
|
|
15
15
|
</p>
|
|
16
16
|
</header>
|
|
17
17
|
|
|
18
18
|
<section class="content">
|
|
19
|
-
<h2>
|
|
19
|
+
<h2>Welcome 👋</h2>
|
|
20
20
|
<p>
|
|
21
|
-
|
|
22
|
-
<strong>Kaelum</strong
|
|
21
|
+
This template was automatically generated by the
|
|
22
|
+
<strong>Kaelum</strong> CLI.
|
|
23
23
|
</p>
|
|
24
24
|
|
|
25
25
|
<div class="cards">
|
|
26
26
|
<div class="card">
|
|
27
|
-
<h3>
|
|
27
|
+
<h3>Routes</h3>
|
|
28
28
|
<p>
|
|
29
|
-
|
|
29
|
+
Available routes: <code>/</code>, <code>/about</code>, <code>/about/team</code>,
|
|
30
30
|
<code>/dashboard</code>, <code>/dashboard/settings</code>.
|
|
31
31
|
</p>
|
|
32
32
|
</div>
|
|
33
33
|
<div class="card">
|
|
34
|
-
<h3>
|
|
35
|
-
<p>CORS
|
|
34
|
+
<h3>Security</h3>
|
|
35
|
+
<p>CORS and Helmet are enabled via <code>app.setConfig</code>.</p>
|
|
36
|
+
</div>
|
|
37
|
+
<div class="card">
|
|
38
|
+
<h3>Health Check</h3>
|
|
39
|
+
<p>Built-in health endpoint at <code>/health</code>.</p>
|
|
36
40
|
</div>
|
|
37
41
|
</div>
|
|
38
42
|
|
|
39
43
|
<p class="small">
|
|
40
|
-
|
|
44
|
+
Generated by Kaelum CLI • Kaelum v1.8.0
|
|
41
45
|
</p>
|
|
42
46
|
</section>
|
|
43
47
|
</main>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "kaelum-api-app",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "REST API application generated by Kaelum CLI (TypeScript api template)",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"start": "node dist/app.js",
|
|
7
|
+
"dev": "tsx watch src/app.ts",
|
|
8
|
+
"build": "tsc"
|
|
9
|
+
},
|
|
10
|
+
"keywords": [
|
|
11
|
+
"kaelum",
|
|
12
|
+
"api",
|
|
13
|
+
"typescript"
|
|
14
|
+
],
|
|
15
|
+
"author": "",
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"kaelum": "^1.8.0"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"typescript": "^5.8.0",
|
|
22
|
+
"tsx": "^4.19.0"
|
|
23
|
+
}
|
|
24
|
+
}
|