create-colonel 0.1.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/package.json +15 -0
- package/src/cli.ts +53 -0
- package/template/README.md +12 -0
- package/template/package.json +18 -0
- package/template/public/favicon.png +0 -0
- package/template/resources/views/base/index.ejs +1 -0
- package/template/resources/views/base/layouts/main.ejs +13 -0
- package/template/resources/views/base/partials/footer.ejs +3 -0
- package/template/resources/views/base/partials/title.ejs +3 -0
- package/template/resources/views/users/index.ejs +13 -0
- package/template/src/app/Http/Controllers/AppController.ts +17 -0
- package/template/src/app/Http/Controllers/Controller.ts +9 -0
- package/template/src/app/Http/Controllers/UserController.ts +19 -0
- package/template/src/bootstrap/server.ts +78 -0
- package/template/src/config/acceptedStaticContentTypes.ts +16 -0
- package/template/src/config/app.ts +0 -0
- package/template/src/config/database.ts +0 -0
- package/template/src/config/routes/api.ts +0 -0
- package/template/src/config/routes/web.ts +21 -0
- package/template/src/config/staticPaths.ts +9 -0
- package/template/src/index.ts +3 -0
- package/template/tsconfig.json +17 -0
package/package.json
ADDED
package/src/cli.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
import { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { basename, resolve } from "node:path";
|
|
5
|
+
|
|
6
|
+
const targetArg = process.argv[2];
|
|
7
|
+
|
|
8
|
+
if (!targetArg) {
|
|
9
|
+
console.error("Usage: bun create colonel <project-name>");
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const targetDir = resolve(process.cwd(), targetArg);
|
|
14
|
+
const templateDir = resolve(import.meta.dir, "..", "template");
|
|
15
|
+
|
|
16
|
+
if (existsSync(targetDir)) {
|
|
17
|
+
const hasFiles = readdirSync(targetDir).length > 0;
|
|
18
|
+
if (hasFiles) {
|
|
19
|
+
console.error(`Target directory is not empty: ${targetDir}`);
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
} else {
|
|
23
|
+
mkdirSync(targetDir, { recursive: true });
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
cpSync(templateDir, targetDir, { recursive: true });
|
|
27
|
+
|
|
28
|
+
const packageJsonPath = resolve(targetDir, "package.json");
|
|
29
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
|
|
30
|
+
packageJson.name = basename(targetDir);
|
|
31
|
+
|
|
32
|
+
const localFrameworkPath = resolve(import.meta.dir, "..", "..", "framework");
|
|
33
|
+
if (existsSync(resolve(localFrameworkPath, "package.json"))) {
|
|
34
|
+
packageJson.dependencies["@coloneldev/framework"] = `file:${localFrameworkPath}`;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`);
|
|
38
|
+
|
|
39
|
+
console.log("Installing dependencies...");
|
|
40
|
+
const install = Bun.spawnSync(["bun", "install"], {
|
|
41
|
+
cwd: targetDir,
|
|
42
|
+
stdout: "inherit",
|
|
43
|
+
stderr: "inherit",
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
if (install.exitCode !== 0) {
|
|
47
|
+
console.error("Project was created, but dependency installation failed.");
|
|
48
|
+
process.exit(install.exitCode);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
console.log("\nColonel app created successfully.\n");
|
|
52
|
+
console.log(` cd ${targetArg}`);
|
|
53
|
+
console.log(" bun run start\n");
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "colonel-app",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"private": true,
|
|
6
|
+
"scripts": {
|
|
7
|
+
"start": "bun --watch src/index.ts"
|
|
8
|
+
},
|
|
9
|
+
"dependencies": {
|
|
10
|
+
"@coloneldev/framework": "^0.1.0",
|
|
11
|
+
"ejs": "^5.0.1"
|
|
12
|
+
},
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"@types/bun": "latest",
|
|
15
|
+
"@types/ejs": "^3.1.5",
|
|
16
|
+
"typescript": "^5.9.3"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<h1>Welcome to Colonel</h1>
|
|
@@ -0,0 +1,13 @@
|
|
|
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.0">
|
|
6
|
+
<link rel="icon" href="/favicon.png" sizes="any">
|
|
7
|
+
<%- title %>
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<%- body %>
|
|
11
|
+
</body>
|
|
12
|
+
<%- footer %>
|
|
13
|
+
</html>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export default class Controller {
|
|
2
|
+
constructor() {
|
|
3
|
+
// Base constructor logic can be added here if needed
|
|
4
|
+
}
|
|
5
|
+
// Base controller logic can be added here, such as common response formatting, error handling, etc.
|
|
6
|
+
health(): Record<string, string> {
|
|
7
|
+
return { status: "ok" };
|
|
8
|
+
}
|
|
9
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { HttpRequest } from "@coloneldev/framework";
|
|
2
|
+
import Controller from "./Controller";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
export class UserController extends Controller {
|
|
6
|
+
index(): Array<string | Record<string, any>> {
|
|
7
|
+
return [
|
|
8
|
+
'users/index',
|
|
9
|
+
{ users: [{ id: 1, name: "John Doe" }, { id: 2, name: "Jane Doe" }] }
|
|
10
|
+
]}
|
|
11
|
+
|
|
12
|
+
show(req: HttpRequest): Record<string, string> {
|
|
13
|
+
const id = req.params("id");
|
|
14
|
+
|
|
15
|
+
return {
|
|
16
|
+
"message": `Hello from UserController@show with id ${id}`
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { Kernel } from "@coloneldev/framework";
|
|
2
|
+
import webRouter from "../config/routes/web";
|
|
3
|
+
import { existsSync } from "fs";
|
|
4
|
+
import { extensions } from "../config/acceptedStaticContentTypes";
|
|
5
|
+
import { isStaticPath, contentTypeFor, toPublicFilePath } from "@coloneldev/framework";
|
|
6
|
+
import { staticPaths } from "../config/staticPaths";
|
|
7
|
+
import path, { extname } from "path";
|
|
8
|
+
|
|
9
|
+
const viewsRoot = path.resolve(import.meta.dir, "..", "..", "resources", "views");
|
|
10
|
+
const publicRoot = path.resolve(import.meta.dir, "..", "..", "public");
|
|
11
|
+
const controllerRoot = path.resolve(import.meta.dir, "..", "app", "Http", "Controllers");
|
|
12
|
+
|
|
13
|
+
export const server = () => {
|
|
14
|
+
const Colonel = new Kernel(webRouter, [], {
|
|
15
|
+
viewsRoot,
|
|
16
|
+
controllerResolver: async (name: string) => {
|
|
17
|
+
const modulePath = `${controllerRoot}/${name}.ts`;
|
|
18
|
+
const mod = await import(modulePath);
|
|
19
|
+
const controller = mod[name];
|
|
20
|
+
|
|
21
|
+
if (!controller) {
|
|
22
|
+
throw new Error(`Controller not found: ${name}`);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return controller;
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
const PORT = Number(process.env.PORT) || 5000;
|
|
29
|
+
|
|
30
|
+
console.log(`Server running at http://localhost:${PORT}/`);
|
|
31
|
+
|
|
32
|
+
const addHeadersForStaticFiles = (path:string) => {
|
|
33
|
+
const headers: Record<string, string> = {};
|
|
34
|
+
const ct = contentTypeFor(path, extensions, extname);
|
|
35
|
+
|
|
36
|
+
if (ct) headers["Content-Type"] = ct;
|
|
37
|
+
headers["Cache-Control"] = "public, max-age=31536000, immutable";
|
|
38
|
+
return headers;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const createStaticResponseWithHeaders = (filePath: string) => {
|
|
42
|
+
if (!existsSync(filePath)) {
|
|
43
|
+
console.warn(`Static file not found: ${filePath}`);
|
|
44
|
+
return new Response("Not Found", { status: 404 });
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
console.info(`Serving static file: ${filePath}`);
|
|
48
|
+
|
|
49
|
+
const headers = addHeadersForStaticFiles(filePath);
|
|
50
|
+
|
|
51
|
+
return new Response(Bun.file(filePath), { headers });
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
return Bun.serve({
|
|
55
|
+
port: PORT,
|
|
56
|
+
|
|
57
|
+
fetch: async (request) => {
|
|
58
|
+
const url = new URL(request.url);
|
|
59
|
+
|
|
60
|
+
console.info(`Received ${request.method} request for ${url.pathname}`);
|
|
61
|
+
|
|
62
|
+
if (isStaticPath(url.pathname, staticPaths)) {
|
|
63
|
+
let filePath: string;
|
|
64
|
+
|
|
65
|
+
try {
|
|
66
|
+
filePath = toPublicFilePath(url.pathname, path, publicRoot);
|
|
67
|
+
} catch {
|
|
68
|
+
console.warn(`Invalid static file path: ${url.pathname}`);
|
|
69
|
+
return new Response("Not Found", { status: 404 });
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return createStaticResponseWithHeaders(filePath);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return Colonel.handle(request);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const extensions = {
|
|
2
|
+
html: "text/html",
|
|
3
|
+
css: "text/css",
|
|
4
|
+
js: "application/javascript",
|
|
5
|
+
json: "application/json",
|
|
6
|
+
png: "image/png",
|
|
7
|
+
jpg: "image/jpeg",
|
|
8
|
+
jpeg: "image/jpeg",
|
|
9
|
+
gif: "image/gif",
|
|
10
|
+
svg: "image/svg+xml",
|
|
11
|
+
ico: "image/x-icon",
|
|
12
|
+
woff: "font/woff",
|
|
13
|
+
woff2: "font/woff2",
|
|
14
|
+
ttf: "font/ttf",
|
|
15
|
+
eot: "application/vnd.ms-fontobject"
|
|
16
|
+
};
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Router, redirect } from '@coloneldev/framework';
|
|
2
|
+
|
|
3
|
+
const web = new Router();
|
|
4
|
+
|
|
5
|
+
// Define any redirects here
|
|
6
|
+
web.get('/favicon.ico', () => redirect('/favicon.png', 301));
|
|
7
|
+
|
|
8
|
+
// Define your web routes here
|
|
9
|
+
//web.get('/health', 'AppController@health');
|
|
10
|
+
web.get('/health', () => new Response("OK", { status: 200 }));
|
|
11
|
+
|
|
12
|
+
web.get('/', 'AppController@index');
|
|
13
|
+
web.get('/users', 'UserController@index');
|
|
14
|
+
web.get('/users/:id', 'UserController@show');
|
|
15
|
+
//router.get('/users', 'UserController@index');
|
|
16
|
+
//router.post('/users', 'UserController@store');
|
|
17
|
+
//router.get('/users/:id', 'UserController@show');
|
|
18
|
+
//router.put('/users/:id', 'UserController@update');
|
|
19
|
+
//router.delete('/users/:id', 'UserController@destroy');
|
|
20
|
+
|
|
21
|
+
export default web;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"lib": ["ESNext"],
|
|
4
|
+
"target": "ESNext",
|
|
5
|
+
"module": "Preserve",
|
|
6
|
+
"moduleDetection": "force",
|
|
7
|
+
"moduleResolution": "bundler",
|
|
8
|
+
"allowImportingTsExtensions": true,
|
|
9
|
+
"verbatimModuleSyntax": true,
|
|
10
|
+
"noEmit": true,
|
|
11
|
+
"strict": true,
|
|
12
|
+
"skipLibCheck": true,
|
|
13
|
+
"noFallthroughCasesInSwitch": true,
|
|
14
|
+
"noUncheckedIndexedAccess": true,
|
|
15
|
+
"noImplicitOverride": true
|
|
16
|
+
}
|
|
17
|
+
}
|